From 7b3392326c40c3c20697816acae597ba7b3144eb Mon Sep 17 00:00:00 2001 From: dim Date: Thu, 20 Oct 2011 21:10:27 +0000 Subject: [PATCH] Vendor import of llvm release_30 branch r142614: http://llvm.org/svn/llvm-project/llvm/branches/release_30@142614 --- .gitignore | 1 + CMakeLists.txt | 19 +- CREDITS.TXT | 10 + Makefile | 14 +- Makefile.config.in | 35 - Makefile.rules | 117 +- README.txt | 1 - autoconf/AutoRegen.sh | 4 +- autoconf/config.guess | 249 +- autoconf/config.sub | 186 +- autoconf/configure.ac | 247 +- bindings/ocaml/llvm/META.llvm.in | 63 + bindings/ocaml/llvm/Makefile | 21 + bindings/ocaml/llvm/llvm.ml | 254 +- bindings/ocaml/llvm/llvm.mli | 213 +- bindings/ocaml/llvm/llvm_ocaml.c | 292 +- bindings/ocaml/target/llvm_target.ml | 2 - bindings/ocaml/target/llvm_target.mli | 7 - bindings/ocaml/target/target_ocaml.c | 7 - bindings/ocaml/transforms/Makefile | 2 +- bindings/ocaml/transforms/ipo/Makefile | 20 + bindings/ocaml/transforms/ipo/ipo_ocaml.c | 104 + bindings/ocaml/transforms/ipo/llvm_ipo.ml | 65 + bindings/ocaml/transforms/ipo/llvm_ipo.mli | 65 + .../transforms/scalar/llvm_scalar_opts.ml | 39 + .../transforms/scalar/llvm_scalar_opts.mli | 46 + .../transforms/scalar/scalar_opts_ocaml.c | 57 +- cmake/config-ix.cmake | 9 +- cmake/modules/AddLLVM.cmake | 28 +- cmake/modules/CMakeLists.txt | 9 +- cmake/modules/CheckAtomic.cmake | 4 +- cmake/modules/CrossCompileLLVM.cmake | 26 - cmake/modules/FindBison.cmake | 52 - cmake/modules/HandleLLVMOptions.cmake | 4 +- cmake/modules/LLVM-Config.cmake | 43 +- cmake/modules/LLVMConfig.cmake.in | 2 + cmake/modules/LLVMLibDeps.cmake | 83 - cmake/modules/TableGen.cmake | 85 +- configure | 8086 +- docs/Atomics.html | 569 + docs/Bugpoint.html | 14 +- docs/CMake.html | 7 +- docs/CodeGenerator.html | 208 +- docs/CodingStandards.html | 10 +- docs/CommandGuide/index.html | 24 +- docs/CommandGuide/llvm-extract.pod | 12 + docs/CommandGuide/llvmc.pod | 190 - docs/CommandGuide/llvmgcc.pod | 76 - docs/CommandGuide/llvmgxx.pod | 85 - docs/CompilerDriver.html | 687 - docs/CompilerDriverTutorial.html | 125 - docs/DeveloperPolicy.html | 13 +- docs/ExceptionHandling.html | 468 +- docs/FAQ.html | 20 +- docs/GarbageCollection.html | 32 +- docs/GettingStarted.html | 181 +- docs/GoldPlugin.html | 63 +- docs/HowToReleaseLLVM.html | 175 +- docs/LangRef.html | 772 +- docs/Lexicon.html | 14 +- docs/LinkTimeOptimization.html | 59 +- docs/Passes.html | 32 +- docs/ProgrammersManual.html | 242 +- docs/ReleaseNotes.html | 767 +- docs/SegmentedStacks.html | 99 + docs/SourceLevelDebugging.html | 48 +- docs/TableGenFundamentals.html | 2 +- docs/WritingAnLLVMPass.html | 120 +- docs/doxygen.cfg.in | 1465 +- docs/index.html | 16 +- docs/llvm.css | 8 + docs/tutorial/LangImpl2.html | 10 +- docs/tutorial/LangImpl3.html | 90 +- docs/tutorial/LangImpl4.html | 66 +- docs/tutorial/LangImpl5.html | 71 +- docs/tutorial/LangImpl6.html | 68 +- docs/tutorial/LangImpl7.html | 166 +- docs/tutorial/Makefile | 2 + examples/BrainF/BrainF.cpp | 7 +- examples/BrainF/BrainFDriver.cpp | 2 +- examples/ExceptionDemo/ExceptionDemo.cpp | 299 +- examples/Fibonacci/fibonacci.cpp | 2 +- examples/HowToUseJIT/HowToUseJIT.cpp | 2 +- examples/Kaleidoscope/Chapter4/toy.cpp | 2 +- examples/Kaleidoscope/Chapter5/toy.cpp | 2 +- examples/Kaleidoscope/Chapter6/toy.cpp | 2 +- examples/Kaleidoscope/Chapter7/toy.cpp | 2 +- examples/ParallelJIT/ParallelJIT.cpp | 2 +- include/llvm-c/Core.h | 75 +- include/llvm-c/Disassembler.h | 32 +- include/llvm-c/Object.h | 8 +- include/llvm-c/Target.h | 20 +- include/llvm-c/Transforms/IPO.h | 9 +- .../llvm-c/Transforms/PassManagerBuilder.h | 90 + include/llvm-c/Transforms/Scalar.h | 3 + include/llvm/ADT/APInt.h | 30 +- include/llvm/ADT/ArrayRef.h | 48 +- include/llvm/ADT/DenseMap.h | 6 + include/llvm/ADT/DenseMapInfo.h | 14 +- include/llvm/ADT/DenseSet.h | 2 +- include/llvm/ADT/ImmutableMap.h | 157 + include/llvm/ADT/ImmutableSet.h | 134 + include/llvm/ADT/IntervalMap.h | 3 + include/llvm/ADT/PointerUnion.h | 6 +- include/llvm/ADT/PostOrderIterator.h | 10 + include/llvm/ADT/SCCIterator.h | 10 +- include/llvm/ADT/STLExtras.h | 30 +- include/llvm/ADT/SmallVector.h | 25 +- include/llvm/ADT/Statistic.h | 18 +- include/llvm/ADT/StringExtras.h | 1 + include/llvm/ADT/TinyPtrVector.h | 133 + include/llvm/ADT/Triple.h | 37 +- include/llvm/ADT/Twine.h | 108 +- include/llvm/Analysis/AliasAnalysis.h | 42 +- include/llvm/Analysis/AliasSetTracker.h | 34 +- include/llvm/Analysis/BlockFrequencyImpl.h | 76 +- ...{BlockFrequency.h => BlockFrequencyInfo.h} | 26 +- include/llvm/Analysis/BranchProbabilityInfo.h | 14 +- include/llvm/Analysis/CodeMetrics.h | 17 +- include/llvm/Analysis/ConstantFolding.h | 14 +- include/llvm/Analysis/DIBuilder.h | 25 + include/llvm/Analysis/DebugInfo.h | 80 +- include/llvm/Analysis/FindUsedTypes.h | 6 +- include/llvm/Analysis/IVUsers.h | 2 + include/llvm/Analysis/InlineCost.h | 9 +- include/llvm/Analysis/InstructionSimplify.h | 11 +- include/llvm/Analysis/LoopInfo.h | 78 +- include/llvm/Analysis/LoopIterator.h | 186 + include/llvm/Analysis/LoopPass.h | 2 +- include/llvm/Analysis/MemoryBuiltins.h | 4 +- .../llvm/Analysis/MemoryDependenceAnalysis.h | 61 +- include/llvm/Analysis/RegionPass.h | 2 +- include/llvm/Analysis/ScalarEvolution.h | 234 +- .../llvm/Analysis/ScalarEvolutionExpander.h | 53 +- .../Analysis/ScalarEvolutionExpressions.h | 28 +- include/llvm/Argument.h | 2 +- include/llvm/Attributes.h | 7 +- include/llvm/AutoUpgrade.h | 4 + include/llvm/BasicBlock.h | 17 + include/llvm/Bitcode/LLVMBitCodes.h | 48 +- include/llvm/CMakeLists.txt | 2 +- include/llvm/CodeGen/Analysis.h | 6 +- include/llvm/CodeGen/CalcSpillWeights.h | 5 - include/llvm/CodeGen/FastISel.h | 20 +- include/llvm/CodeGen/FunctionLoweringInfo.h | 16 +- include/llvm/CodeGen/ISDOpcodes.h | 66 +- include/llvm/CodeGen/LexicalScopes.h | 248 + include/llvm/CodeGen/LiveInterval.h | 18 +- include/llvm/CodeGen/LiveStackAnalysis.h | 2 + include/llvm/CodeGen/LiveVariables.h | 2 + include/llvm/CodeGen/MachineBasicBlock.h | 2 +- ...requency.h => MachineBlockFrequencyInfo.h} | 25 +- include/llvm/CodeGen/MachineConstantPool.h | 10 +- include/llvm/CodeGen/MachineFrameInfo.h | 10 + include/llvm/CodeGen/MachineInstr.h | 30 +- include/llvm/CodeGen/MachineModuleInfo.h | 92 +- include/llvm/CodeGen/MachineOperand.h | 28 +- include/llvm/CodeGen/MachineRegisterInfo.h | 43 +- include/llvm/CodeGen/Passes.h | 25 +- include/llvm/CodeGen/SelectionDAG.h | 48 +- include/llvm/CodeGen/SelectionDAGNodes.h | 53 +- include/llvm/CodeGen/SlotIndexes.h | 2 +- .../CodeGen/TargetLoweringObjectFileImpl.h | 116 +- include/llvm/CodeGen/ValueTypes.h | 26 +- include/llvm/CompilerDriver/Action.h | 54 - include/llvm/CompilerDriver/AutoGenerated.h | 40 - include/llvm/CompilerDriver/BuiltinOptions.h | 39 - include/llvm/CompilerDriver/Common.td | 127 - .../llvm/CompilerDriver/CompilationGraph.h | 330 - include/llvm/CompilerDriver/Error.h | 29 - include/llvm/CompilerDriver/Main.h | 21 - include/llvm/CompilerDriver/Main.inc | 23 - include/llvm/CompilerDriver/Tool.h | 100 - include/llvm/Config/config.h.cmake | 124 +- include/llvm/Config/config.h.in | 15 +- include/llvm/Config/llvm-config.h.cmake | 22 +- include/llvm/Config/llvm-config.h.in | 25 +- include/llvm/Constant.h | 12 +- include/llvm/Constants.h | 179 +- include/llvm/DebugInfo/DIContext.h | 68 + include/llvm/DerivedTypes.h | 104 +- .../llvm/ExecutionEngine/ExecutionEngine.h | 35 +- include/llvm/Function.h | 4 +- include/llvm/GlobalAlias.h | 11 +- include/llvm/GlobalValue.h | 2 +- include/llvm/GlobalVariable.h | 4 +- include/llvm/InitializePasses.h | 6 +- include/llvm/InlineAsm.h | 35 +- include/llvm/InstrTypes.h | 80 +- include/llvm/Instruction.def | 120 +- include/llvm/Instruction.h | 11 +- include/llvm/Instructions.h | 901 +- include/llvm/IntrinsicInst.h | 2 +- include/llvm/Intrinsics.h | 2 +- include/llvm/Intrinsics.td | 93 +- include/llvm/IntrinsicsXCore.td | 23 +- include/llvm/LinkAllPasses.h | 4 +- include/llvm/Linker.h | 12 +- include/llvm/MC/EDInstInfo.h | 2 +- .../TargetAsmBackend.h => MC/MCAsmBackend.h} | 18 +- include/llvm/MC/MCAsmInfo.h | 76 +- include/llvm/MC/MCAsmInfoDarwin.h | 5 - include/llvm/MC/MCAssembler.h | 12 +- include/llvm/MC/MCAtom.h | 68 + include/llvm/MC/MCCodeGenInfo.h | 41 + include/llvm/MC/MCContext.h | 16 +- include/llvm/MC/MCDirectives.h | 5 +- include/llvm/MC/MCDisassembler.h | 58 +- include/llvm/MC/MCDwarf.h | 7 +- include/llvm/MC/MCInst.h | 10 + include/llvm/MC/MCInstPrinter.h | 6 +- include/llvm/MC/MCInstrAnalysis.h | 61 + include/llvm/MC/MCInstrDesc.h | 121 +- include/llvm/MC/MCModule.h | 58 + include/llvm/MC/MCObjectFileInfo.h | 294 + include/llvm/MC/MCObjectStreamer.h | 6 +- include/llvm/MC/MCParser/AsmLexer.h | 2 + include/llvm/MC/MCParser/MCAsmLexer.h | 3 +- include/llvm/MC/MCParser/MCAsmParser.h | 11 +- include/llvm/MC/MCRegisterInfo.h | 184 +- include/llvm/MC/MCStreamer.h | 76 +- .../MCTargetAsmLexer.h} | 18 +- .../MCTargetAsmParser.h} | 44 +- include/llvm/MC/MCValue.h | 10 - .../llvm/{CodeGen => MC}/MachineLocation.h | 12 +- include/llvm/Module.h | 38 +- include/llvm/Object/Archive.h | 90 + include/llvm/Object/COFF.h | 32 + include/llvm/Object/MachO.h | 106 + include/llvm/Object/MachOFormat.h | 12 +- include/llvm/Object/MachOObject.h | 4 + include/llvm/Object/ObjectFile.h | 252 +- include/llvm/OperandTraits.h | 41 +- include/llvm/Operator.h | 4 +- include/llvm/PassManagers.h | 7 +- include/llvm/Support/BlockFrequency.h | 63 + include/llvm/Support/BranchProbability.h | 6 +- include/llvm/Support/CallSite.h | 2 +- include/llvm/Support/Capacity.h | 30 + include/llvm/Support/CodeGen.h | 32 + include/llvm/Support/CommandLine.h | 31 + include/llvm/Support/ConstantFolder.h | 56 +- include/llvm/Support/DataExtractor.h | 352 + include/llvm/Support/DataTypes.h.cmake | 12 +- include/llvm/Support/DataTypes.h.in | 92 +- include/llvm/Support/Dwarf.h | 53 +- include/llvm/Support/DynamicLibrary.h | 75 +- include/llvm/Support/ELF.h | 347 +- include/llvm/Support/FileSystem.h | 162 +- include/llvm/Support/Format.h | 62 + include/llvm/Support/GCOV.h | 224 + .../llvm/Support/GetElementPtrTypeIterator.h | 34 +- include/llvm/Support/IRBuilder.h | 148 +- include/llvm/Support/InstVisitor.h | 5 + include/llvm/Support/MachO.h | 11 + include/llvm/Support/MemoryBuffer.h | 6 +- include/llvm/Support/NoFolder.h | 44 +- include/llvm/Support/PassManagerBuilder.h | 331 - include/llvm/Support/PathV1.h | 1 + include/llvm/Support/PathV2.h | 13 +- include/llvm/Support/Process.h | 3 + include/llvm/Support/SMLoc.h | 10 +- include/llvm/Support/SourceMgr.h | 11 +- include/llvm/Support/TargetFolder.h | 54 +- .../llvm/{Target => Support}/TargetRegistry.h | 459 +- .../llvm/{Target => Support}/TargetSelect.h | 52 +- include/llvm/Support/TypeBuilder.h | 101 +- {utils => include/llvm}/TableGen/Error.h | 6 +- include/llvm/TableGen/Main.h | 26 + {utils => include/llvm}/TableGen/Record.h | 497 +- include/llvm/TableGen/TableGenAction.h | 34 + .../llvm}/TableGen/TableGenBackend.h | 6 +- include/llvm/Target/Target.td | 7 +- include/llvm/Target/TargetAsmInfo.h | 103 - include/llvm/Target/TargetData.h | 44 +- include/llvm/Target/TargetFrameLowering.h | 17 +- include/llvm/Target/TargetInstrInfo.h | 55 +- include/llvm/Target/TargetIntrinsicInfo.h | 4 +- include/llvm/Target/TargetLowering.h | 246 +- .../llvm/Target/TargetLoweringObjectFile.h | 124 +- include/llvm/Target/TargetMachine.h | 44 +- include/llvm/Target/TargetOptions.h | 2 + include/llvm/Target/TargetRegisterInfo.h | 208 +- include/llvm/Target/TargetSelectionDAG.td | 44 +- include/llvm/Transforms/IPO.h | 9 +- .../llvm/Transforms/IPO/PassManagerBuilder.h | 133 + include/llvm/Transforms/Scalar.h | 7 - .../llvm/Transforms/Utils/AddrModeMatcher.h | 6 +- .../llvm/Transforms/Utils/BasicBlockUtils.h | 46 +- include/llvm/Transforms/Utils/FunctionUtils.h | 14 +- include/llvm/Transforms/Utils/SSAUpdater.h | 4 +- .../llvm/Transforms/Utils/SimplifyIndVar.h | 58 + include/llvm/Transforms/Utils/UnrollLoop.h | 3 +- include/llvm/Transforms/Utils/ValueMapper.h | 4 +- include/llvm/Type.h | 12 +- include/llvm/User.h | 2 +- include/llvm/Value.h | 4 +- lib/Analysis/AliasAnalysis.cpp | 50 +- lib/Analysis/AliasAnalysisEvaluator.cpp | 6 +- lib/Analysis/AliasSetTracker.cpp | 107 +- lib/Analysis/Analysis.cpp | 3 +- lib/Analysis/BasicAliasAnalysis.cpp | 136 +- lib/Analysis/BlockFrequency.cpp | 59 - lib/Analysis/BlockFrequencyInfo.cpp | 63 + lib/Analysis/BranchProbabilityInfo.cpp | 276 +- lib/Analysis/CMakeLists.txt | 8 +- lib/Analysis/ConstantFolding.cpp | 126 +- lib/Analysis/DIBuilder.cpp | 286 +- lib/Analysis/DbgInfoPrinter.cpp | 2 +- lib/Analysis/DebugInfo.cpp | 275 +- lib/Analysis/IPA/CMakeLists.txt | 6 + lib/Analysis/IPA/CallGraphSCCPass.cpp | 7 +- lib/Analysis/IPA/FindUsedTypes.cpp | 4 +- lib/Analysis/IVUsers.cpp | 3 +- lib/Analysis/InlineCost.cpp | 124 +- lib/Analysis/InstructionSimplify.cpp | 173 +- lib/Analysis/LazyValueInfo.cpp | 6 +- lib/Analysis/Lint.cpp | 8 +- lib/Analysis/Loads.cpp | 12 +- lib/Analysis/LoopDependenceAnalysis.cpp | 8 +- lib/Analysis/LoopInfo.cpp | 296 +- lib/Analysis/LoopPass.cpp | 108 +- lib/Analysis/MemDepPrinter.cpp | 80 +- lib/Analysis/MemoryBuiltins.cpp | 16 +- lib/Analysis/MemoryDependenceAnalysis.cpp | 48 +- lib/Analysis/PHITransAddr.cpp | 8 +- lib/Analysis/PathNumbering.cpp | 2 +- lib/Analysis/RegionPass.cpp | 6 +- lib/Analysis/ScalarEvolution.cpp | 852 +- lib/Analysis/ScalarEvolutionExpander.cpp | 393 +- lib/Analysis/ScalarEvolutionNormalization.cpp | 101 +- lib/Analysis/ValueTracking.cpp | 39 +- lib/Archive/CMakeLists.txt | 6 + lib/AsmParser/CMakeLists.txt | 5 + lib/AsmParser/LLLexer.cpp | 30 +- lib/AsmParser/LLParser.cpp | 352 +- lib/AsmParser/LLParser.h | 26 +- lib/AsmParser/LLToken.h | 15 +- lib/Bitcode/Reader/BitcodeReader.cpp | 316 +- lib/Bitcode/Reader/BitcodeReader.h | 8 +- lib/Bitcode/Reader/CMakeLists.txt | 5 + lib/Bitcode/Writer/BitcodeWriter.cpp | 156 +- lib/Bitcode/Writer/CMakeLists.txt | 5 + lib/Bitcode/Writer/ValueEnumerator.cpp | 6 +- lib/Bitcode/Writer/ValueEnumerator.h | 8 +- lib/CMakeLists.txt | 4 +- lib/CodeGen/Analysis.cpp | 16 +- lib/CodeGen/AsmPrinter/ARMException.cpp | 2 - lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 153 +- lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp | 2 +- .../AsmPrinter/AsmPrinterInlineAsm.cpp | 15 +- lib/CodeGen/AsmPrinter/CMakeLists.txt | 9 + lib/CodeGen/AsmPrinter/DIE.cpp | 2 +- lib/CodeGen/AsmPrinter/DwarfCFIException.cpp | 5 +- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 407 +- lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 20 +- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 1399 +- lib/CodeGen/AsmPrinter/DwarfDebug.h | 133 +- lib/CodeGen/AsmPrinter/DwarfException.cpp | 102 +- lib/CodeGen/AsmPrinter/Win64Exception.cpp | 1 - lib/CodeGen/BranchFolding.cpp | 29 +- lib/CodeGen/CMakeLists.txt | 17 +- lib/CodeGen/CalcSpillWeights.cpp | 32 - lib/CodeGen/CodeGen.cpp | 1 + lib/CodeGen/DwarfEHPrepare.cpp | 67 +- lib/CodeGen/ELFCodeEmitter.cpp | 2 +- lib/CodeGen/ELFCodeEmitter.h | 4 +- lib/CodeGen/ELFWriter.cpp | 12 +- .../ExecutionDepsFix.cpp} | 99 +- ...werSubregs.cpp => ExpandPostRAPseudos.cpp} | 118 +- lib/CodeGen/IfConversion.cpp | 37 +- lib/CodeGen/InlineSpiller.cpp | 434 +- lib/CodeGen/InterferenceCache.cpp | 5 +- lib/CodeGen/InterferenceCache.h | 3 +- lib/CodeGen/IntrinsicLowering.cpp | 10 +- lib/CodeGen/LLVMTargetMachine.cpp | 96 +- lib/CodeGen/LexicalScopes.cpp | 335 + lib/CodeGen/LiveDebugVariables.cpp | 71 +- lib/CodeGen/LiveInterval.cpp | 35 +- lib/CodeGen/LiveIntervalAnalysis.cpp | 29 +- lib/CodeGen/LiveIntervalUnion.cpp | 238 +- lib/CodeGen/LiveIntervalUnion.h | 78 +- lib/CodeGen/LiveRangeCalc.cpp | 270 + lib/CodeGen/LiveRangeCalc.h | 226 + lib/CodeGen/LiveRangeEdit.cpp | 5 +- lib/CodeGen/LiveRangeEdit.h | 2 +- lib/CodeGen/LiveStackAnalysis.cpp | 5 +- lib/CodeGen/LiveVariables.cpp | 2 +- lib/CodeGen/MachineBasicBlock.cpp | 5 + ...ency.cpp => MachineBlockFrequencyInfo.cpp} | 32 +- lib/CodeGen/MachineCSE.cpp | 11 + lib/CodeGen/MachineFunction.cpp | 2 +- lib/CodeGen/MachineInstr.cpp | 362 +- lib/CodeGen/MachineLICM.cpp | 156 +- lib/CodeGen/MachineModuleInfo.cpp | 37 +- lib/CodeGen/MachineRegisterInfo.cpp | 44 +- lib/CodeGen/MachineSink.cpp | 31 + lib/CodeGen/MachineVerifier.cpp | 70 +- lib/CodeGen/PHIElimination.cpp | 3 + lib/CodeGen/PeepholeOptimizer.cpp | 17 +- lib/CodeGen/ProcessImplicitDefs.cpp | 6 + lib/CodeGen/PrologEpilogInserter.cpp | 14 +- lib/CodeGen/RegAllocBasic.cpp | 10 +- lib/CodeGen/RegAllocGreedy.cpp | 521 +- lib/CodeGen/RegAllocLinearScan.cpp | 3 +- lib/CodeGen/RegAllocPBQP.cpp | 2 +- lib/CodeGen/RegisterClassInfo.cpp | 7 +- lib/CodeGen/RegisterClassInfo.h | 15 +- lib/CodeGen/RegisterCoalescer.cpp | 630 +- lib/CodeGen/RegisterCoalescer.h | 205 +- lib/CodeGen/RegisterScavenging.cpp | 1 + lib/CodeGen/ScheduleDAG.cpp | 3 +- lib/CodeGen/ScheduleDAGInstrs.cpp | 3 +- lib/CodeGen/ScheduleDAGInstrs.h | 7 +- lib/CodeGen/ScoreboardHazardRecognizer.cpp | 1 - lib/CodeGen/SelectionDAG/CMakeLists.txt | 10 + lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 123 +- lib/CodeGen/SelectionDAG/FastISel.cpp | 48 +- .../SelectionDAG/FunctionLoweringInfo.cpp | 47 +- lib/CodeGen/SelectionDAG/InstrEmitter.cpp | 186 +- lib/CodeGen/SelectionDAG/InstrEmitter.h | 6 + lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 333 +- .../SelectionDAG/LegalizeFloatTypes.cpp | 27 +- .../SelectionDAG/LegalizeIntegerTypes.cpp | 184 +- lib/CodeGen/SelectionDAG/LegalizeTypes.cpp | 33 +- lib/CodeGen/SelectionDAG/LegalizeTypes.h | 33 +- .../SelectionDAG/LegalizeTypesGeneric.cpp | 44 +- .../SelectionDAG/LegalizeVectorOps.cpp | 48 +- .../SelectionDAG/LegalizeVectorTypes.cpp | 118 +- .../SelectionDAG/ScheduleDAGRRList.cpp | 36 +- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 184 +- .../SelectionDAG/SelectionDAGBuilder.cpp | 526 +- .../SelectionDAG/SelectionDAGBuilder.h | 39 +- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 37 +- lib/CodeGen/SelectionDAG/TargetLowering.cpp | 48 +- lib/CodeGen/ShadowStackGC.cpp | 52 +- lib/CodeGen/SjLjEHPrepare.cpp | 514 +- lib/CodeGen/SpillPlacement.cpp | 17 + lib/CodeGen/SpillPlacement.h | 14 + lib/CodeGen/SplitKit.cpp | 718 +- lib/CodeGen/SplitKit.h | 171 +- lib/CodeGen/Splitter.cpp | 4 +- lib/CodeGen/StackProtector.cpp | 4 +- lib/CodeGen/StrongPHIElimination.cpp | 3 +- lib/CodeGen/TailDuplication.cpp | 1 + lib/CodeGen/TargetInstrInfoImpl.cpp | 76 +- lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 535 - lib/CodeGen/TwoAddressInstructionPass.cpp | 13 +- lib/CodeGen/VirtRegMap.cpp | 32 +- lib/CompilerDriver/Action.cpp | 134 - lib/CompilerDriver/BuiltinOptions.cpp | 61 - lib/CompilerDriver/CMakeLists.txt | 12 - lib/CompilerDriver/CompilationGraph.cpp | 655 - lib/CompilerDriver/Main.cpp | 146 - lib/CompilerDriver/Makefile | 20 - lib/CompilerDriver/Tool.cpp | 95 - lib/DebugInfo/CMakeLists.txt | 16 + lib/DebugInfo/DIContext.cpp | 24 + .../DWARFAbbreviationDeclaration.cpp | 83 + lib/DebugInfo/DWARFAbbreviationDeclaration.h | 54 + lib/DebugInfo/DWARFAttribute.h | 30 + lib/DebugInfo/DWARFCompileUnit.cpp | 238 + lib/DebugInfo/DWARFCompileUnit.h | 111 + lib/DebugInfo/DWARFContext.cpp | 167 + lib/DebugInfo/DWARFContext.h | 118 + lib/DebugInfo/DWARFDebugAbbrev.cpp | 106 + lib/DebugInfo/DWARFDebugAbbrev.h | 73 + lib/DebugInfo/DWARFDebugArangeSet.cpp | 150 + lib/DebugInfo/DWARFDebugArangeSet.h | 75 + lib/DebugInfo/DWARFDebugAranges.cpp | 223 + lib/DebugInfo/DWARFDebugAranges.h | 98 + lib/DebugInfo/DWARFDebugInfoEntry.cpp | 444 + lib/DebugInfo/DWARFDebugInfoEntry.h | 135 + lib/DebugInfo/DWARFDebugLine.cpp | 475 + lib/DebugInfo/DWARFDebugLine.h | 190 + lib/DebugInfo/DWARFFormValue.cpp | 427 + lib/DebugInfo/DWARFFormValue.h | 78 + .../llvmc/examples => lib/DebugInfo}/Makefile | 8 +- lib/ExecutionEngine/CMakeLists.txt | 7 + lib/ExecutionEngine/ExecutionEngine.cpp | 34 +- .../Interpreter/CMakeLists.txt | 8 + lib/ExecutionEngine/Interpreter/Execution.cpp | 133 +- .../Interpreter/ExternalFunctions.cpp | 34 +- lib/ExecutionEngine/Interpreter/Interpreter.h | 30 +- lib/ExecutionEngine/JIT/CMakeLists.txt | 8 + lib/ExecutionEngine/JIT/Intercept.cpp | 1 + lib/ExecutionEngine/JIT/JIT.cpp | 8 +- lib/ExecutionEngine/JIT/JIT.h | 5 +- lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp | 10 +- lib/ExecutionEngine/JIT/JITDwarfEmitter.h | 4 +- lib/ExecutionEngine/JIT/JITEmitter.cpp | 5 +- lib/ExecutionEngine/MCJIT/CMakeLists.txt | 8 + lib/ExecutionEngine/MCJIT/Intercept.cpp | 1 + lib/ExecutionEngine/MCJIT/MCJIT.cpp | 7 +- .../RuntimeDyld/CMakeLists.txt | 5 + .../RuntimeDyld/RuntimeDyldImpl.h | 2 +- lib/ExecutionEngine/TargetSelect.cpp | 15 +- lib/Linker/CMakeLists.txt | 8 + lib/Linker/LinkModules.cpp | 112 +- lib/Linker/Linker.cpp | 8 + lib/MC/CMakeLists.txt | 19 +- lib/MC/ELFObjectWriter.cpp | 124 +- lib/MC/ELFObjectWriter.h | 32 + ...{TargetAsmBackend.cpp => MCAsmBackend.cpp} | 10 +- lib/MC/MCAsmInfo.cpp | 12 +- lib/MC/MCAsmInfoCOFF.cpp | 7 +- lib/MC/MCAsmInfoDarwin.cpp | 8 + lib/MC/MCAsmStreamer.cpp | 57 +- lib/MC/MCAssembler.cpp | 6 +- lib/MC/MCAtom.cpp | 97 + lib/MC/MCCodeGenInfo.cpp | 21 + lib/MC/MCContext.cpp | 13 +- lib/MC/MCDisassembler/CMakeLists.txt | 24 +- lib/MC/MCDisassembler/Disassembler.cpp | 82 +- lib/MC/MCDisassembler/Disassembler.h | 25 +- lib/MC/MCDisassembler/EDDisassembler.cpp | 70 +- lib/MC/MCDisassembler/EDDisassembler.h | 19 +- lib/MC/MCDisassembler/EDInst.h | 2 +- lib/MC/MCDisassembler/EDToken.cpp | 8 +- lib/MC/MCDisassembler/EDToken.h | 2 +- lib/MC/MCDwarf.cpp | 95 +- lib/MC/MCELF.cpp | 1 - lib/MC/MCELFStreamer.cpp | 17 +- lib/MC/MCELFStreamer.h | 7 +- lib/MC/MCExpr.cpp | 1 - lib/MC/MCInstPrinter.cpp | 11 + lib/MC/MCInstrAnalysis.cpp | 21 + lib/MC/MCLoggingStreamer.cpp | 5 +- lib/MC/MCMachOStreamer.cpp | 20 +- lib/MC/MCModule.cpp | 45 + lib/MC/MCNullStreamer.cpp | 4 +- lib/MC/MCObjectFileInfo.cpp | 554 + lib/MC/MCObjectStreamer.cpp | 6 +- lib/MC/MCParser/AsmLexer.cpp | 32 +- lib/MC/MCParser/AsmParser.cpp | 198 +- lib/MC/MCParser/CMakeLists.txt | 7 +- lib/MC/MCParser/COFFAsmParser.cpp | 47 +- lib/MC/MCParser/ELFAsmParser.cpp | 59 +- lib/MC/MCParser/MCAsmParser.cpp | 6 +- ...getAsmParser.cpp => MCTargetAsmParser.cpp} | 8 +- lib/MC/MCPureStreamer.cpp | 9 +- lib/MC/MCStreamer.cpp | 113 +- .../MCTargetAsmLexer.cpp} | 10 +- lib/MC/MCWin64EH.cpp | 34 +- lib/MC/MachObjectWriter.cpp | 25 +- lib/MC/WinCOFFObjectWriter.cpp | 2 +- lib/MC/WinCOFFStreamer.cpp | 22 +- lib/Makefile | 2 +- lib/Object/Archive.cpp | 172 + lib/Object/Binary.cpp | 11 +- lib/Object/CMakeLists.txt | 6 + lib/Object/COFFObjectFile.cpp | 239 +- lib/Object/ELFObjectFile.cpp | 773 +- lib/Object/MachOObject.cpp | 38 + lib/Object/MachOObjectFile.cpp | 334 +- lib/Object/Object.cpp | 4 +- lib/Object/ObjectFile.cpp | 1 + lib/Support/APFloat.cpp | 31 +- lib/Support/APInt.cpp | 56 +- lib/Support/Atomic.cpp | 10 +- lib/Support/BlockFrequency.cpp | 126 + lib/Support/BranchProbability.cpp | 3 +- lib/Support/CMakeLists.txt | 4 +- lib/Support/CommandLine.cpp | 66 +- lib/Support/ConstantRange.cpp | 25 +- lib/Support/CrashRecoveryContext.cpp | 68 +- lib/Support/DataExtractor.cpp | 175 + lib/Support/Disassembler.cpp | 2 +- lib/Support/Dwarf.cpp | 49 + lib/Support/DynamicLibrary.cpp | 99 +- lib/Support/FoldingSet.cpp | 6 +- lib/Support/Host.cpp | 4 +- lib/Support/IncludeFile.cpp | 2 +- lib/Support/Memory.cpp | 6 + lib/Support/MemoryBuffer.cpp | 8 +- lib/Support/MemoryObject.cpp | 7 +- lib/Support/Mutex.cpp | 2 +- lib/Support/Path.cpp | 2 +- lib/Support/PathV2.cpp | 36 +- lib/Support/PrettyStackTrace.cpp | 2 +- lib/Support/RWMutex.cpp | 2 +- .../SearchForAddressOfSpecialSymbol.cpp | 15 - lib/Support/StringExtras.cpp | 9 +- lib/Support/StringRef.cpp | 19 +- lib/Support/TargetRegistry.cpp | 32 +- lib/Support/ThreadLocal.cpp | 2 +- lib/Support/Threading.cpp | 43 +- lib/Support/Triple.cpp | 44 +- lib/Support/Twine.cpp | 60 +- lib/Support/Unix/Host.inc | 1 + lib/Support/Unix/Path.inc | 4 +- lib/Support/Unix/PathV2.inc | 22 +- lib/Support/Unix/Process.inc | 4 + lib/Support/Windows/DynamicLibrary.inc | 76 +- lib/Support/Windows/Memory.inc | 61 +- lib/Support/Windows/PathV2.inc | 51 +- lib/Support/Windows/Process.inc | 5 + lib/Support/Windows/RWMutex.inc | 98 +- lib/Support/Windows/Signals.inc | 224 +- lib/Support/Windows/Windows.h | 6 +- lib/Support/raw_ostream.cpp | 7 +- lib/TableGen/CMakeLists.txt | 16 + {utils => lib}/TableGen/Error.cpp | 2 +- lib/TableGen/Main.cpp | 124 + lib/TableGen/Makefile | 18 + {utils => lib}/TableGen/Record.cpp | 784 +- {utils => lib}/TableGen/TGLexer.cpp | 54 +- {utils => lib}/TableGen/TGLexer.h | 0 {utils => lib}/TableGen/TGParser.cpp | 314 +- {utils => lib}/TableGen/TGParser.h | 19 +- {utils => lib}/TableGen/TableGenBackend.cpp | 4 +- lib/Target/ARM/ARM.h | 21 +- lib/Target/ARM/ARM.td | 23 +- lib/Target/ARM/ARMAsmPrinter.cpp | 194 +- lib/Target/ARM/ARMBaseInstrInfo.cpp | 522 +- lib/Target/ARM/ARMBaseInstrInfo.h | 161 +- lib/Target/ARM/ARMBaseRegisterInfo.cpp | 279 +- lib/Target/ARM/ARMBaseRegisterInfo.h | 19 +- lib/Target/ARM/ARMCodeEmitter.cpp | 35 +- lib/Target/ARM/ARMConstantIslandPass.cpp | 23 +- lib/Target/ARM/ARMConstantPoolValue.cpp | 315 +- lib/Target/ARM/ARMConstantPoolValue.h | 191 +- lib/Target/ARM/ARMExpandPseudoInsts.cpp | 61 +- lib/Target/ARM/ARMFastISel.cpp | 93 +- lib/Target/ARM/ARMFrameLowering.cpp | 31 +- lib/Target/ARM/ARMGlobalMerge.cpp | 10 +- lib/Target/ARM/ARMISelDAGToDAG.cpp | 338 +- lib/Target/ARM/ARMISelLowering.cpp | 1301 +- lib/Target/ARM/ARMISelLowering.h | 47 +- lib/Target/ARM/ARMInstrFormats.td | 341 +- lib/Target/ARM/ARMInstrInfo.cpp | 26 +- lib/Target/ARM/ARMInstrInfo.td | 2742 +- lib/Target/ARM/ARMInstrNEON.td | 153 +- lib/Target/ARM/ARMInstrThumb.td | 487 +- lib/Target/ARM/ARMInstrThumb2.td | 1949 +- lib/Target/ARM/ARMInstrVFP.td | 113 +- lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 49 +- lib/Target/ARM/ARMMCInstLower.cpp | 2 +- lib/Target/ARM/ARMRegisterInfo.td | 24 +- lib/Target/ARM/ARMSelectionDAGInfo.cpp | 15 +- lib/Target/ARM/ARMSelectionDAGInfo.h | 17 + lib/Target/ARM/ARMSubtarget.cpp | 5 + lib/Target/ARM/ARMSubtarget.h | 18 + lib/Target/ARM/ARMTargetMachine.cpp | 91 +- lib/Target/ARM/ARMTargetMachine.h | 16 +- lib/Target/ARM/AsmParser/ARMAsmLexer.cpp | 37 +- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 4087 +- lib/Target/ARM/AsmParser/CMakeLists.txt | 9 + lib/Target/ARM/CMakeLists.txt | 48 +- .../ARM/Disassembler/ARMDisassembler.cpp | 4595 +- lib/Target/ARM/Disassembler/ARMDisassembler.h | 99 - .../ARM/Disassembler/ARMDisassemblerCore.cpp | 3818 - .../ARM/Disassembler/ARMDisassemblerCore.h | 336 - lib/Target/ARM/Disassembler/CMakeLists.txt | 11 +- .../ARM/Disassembler/ThumbDisassemblerCore.h | 2459 - lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 405 +- lib/Target/ARM/InstPrinter/ARMInstPrinter.h | 34 +- lib/Target/ARM/InstPrinter/CMakeLists.txt | 8 +- .../{ => MCTargetDesc}/ARMAddressingModes.h | 104 +- .../ARM/{ => MCTargetDesc}/ARMAsmBackend.cpp | 77 +- .../ARM/{ => MCTargetDesc}/ARMBaseInfo.h | 163 +- .../ARM/{ => MCTargetDesc}/ARMFixupKinds.h | 0 lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp | 13 +- .../{ => MCTargetDesc}/ARMMCCodeEmitter.cpp | 384 +- .../ARM/{ => MCTargetDesc}/ARMMCExpr.cpp | 0 lib/Target/ARM/{ => MCTargetDesc}/ARMMCExpr.h | 0 .../ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 179 +- lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h | 21 +- .../ARMMachObjectWriter.cpp | 5 +- lib/Target/ARM/MCTargetDesc/CMakeLists.txt | 14 +- lib/Target/ARM/Makefile | 5 +- lib/Target/ARM/NEONMoveFix.cpp | 149 - lib/Target/ARM/TargetInfo/ARMTargetInfo.cpp | 2 +- lib/Target/ARM/TargetInfo/CMakeLists.txt | 8 +- lib/Target/ARM/Thumb1FrameLowering.cpp | 11 +- lib/Target/ARM/Thumb1RegisterInfo.cpp | 34 +- lib/Target/ARM/Thumb2ITBlockPass.cpp | 21 + lib/Target/ARM/Thumb2InstrInfo.cpp | 13 +- lib/Target/ARM/Thumb2SizeReduction.cpp | 21 +- lib/Target/Alpha/AlphaAsmPrinter.cpp | 2 +- lib/Target/Alpha/AlphaISelDAGToDAG.cpp | 7 +- lib/Target/Alpha/AlphaISelLowering.cpp | 8 +- lib/Target/Alpha/AlphaISelLowering.h | 2 +- lib/Target/Alpha/AlphaInstrInfo.cpp | 1 - lib/Target/Alpha/AlphaInstrInfo.td | 2 + lib/Target/Alpha/AlphaRegisterInfo.cpp | 18 +- lib/Target/Alpha/AlphaRegisterInfo.h | 4 - lib/Target/Alpha/AlphaSubtarget.cpp | 1 - lib/Target/Alpha/AlphaTargetMachine.cpp | 12 +- lib/Target/Alpha/AlphaTargetMachine.h | 5 +- lib/Target/Alpha/CMakeLists.txt | 25 +- .../Alpha/MCTargetDesc/AlphaMCTargetDesc.cpp | 37 +- lib/Target/Alpha/MCTargetDesc/CMakeLists.txt | 7 + .../Alpha/TargetInfo/AlphaTargetInfo.cpp | 2 +- lib/Target/Alpha/TargetInfo/CMakeLists.txt | 8 +- lib/Target/Blackfin/BlackfinAsmPrinter.cpp | 2 +- lib/Target/Blackfin/BlackfinFrameLowering.h | 4 +- lib/Target/Blackfin/BlackfinISelLowering.cpp | 4 +- lib/Target/Blackfin/BlackfinISelLowering.h | 2 +- lib/Target/Blackfin/BlackfinInstrInfo.cpp | 2 +- lib/Target/Blackfin/BlackfinIntrinsicInfo.cpp | 8 +- lib/Target/Blackfin/BlackfinIntrinsicInfo.h | 4 +- lib/Target/Blackfin/BlackfinRegisterInfo.cpp | 18 +- lib/Target/Blackfin/BlackfinRegisterInfo.h | 4 - lib/Target/Blackfin/BlackfinSubtarget.cpp | 2 +- lib/Target/Blackfin/BlackfinTargetMachine.cpp | 12 +- lib/Target/Blackfin/BlackfinTargetMachine.h | 5 +- lib/Target/Blackfin/CMakeLists.txt | 27 +- .../MCTargetDesc/BlackfinMCTargetDesc.cpp | 41 +- .../Blackfin/MCTargetDesc/CMakeLists.txt | 7 + .../TargetInfo/BlackfinTargetInfo.cpp | 2 +- lib/Target/Blackfin/TargetInfo/CMakeLists.txt | 8 +- lib/Target/CBackend/CBackend.cpp | 180 +- lib/Target/CBackend/CMakeLists.txt | 12 + lib/Target/CBackend/CTargetMachine.h | 5 +- .../TargetInfo/CBackendTargetInfo.cpp | 4 +- lib/Target/CBackend/TargetInfo/CMakeLists.txt | 5 + lib/Target/CMakeLists.txt | 8 +- lib/Target/CellSPU/CMakeLists.txt | 27 +- .../CellSPU/MCTargetDesc/CMakeLists.txt | 7 + .../CellSPU/MCTargetDesc/SPUMCTargetDesc.cpp | 52 +- .../CellSPU/MCTargetDesc/SPUMCTargetDesc.h | 4 +- lib/Target/CellSPU/SPUAsmPrinter.cpp | 2 +- lib/Target/CellSPU/SPUFrameLowering.cpp | 20 - lib/Target/CellSPU/SPUFrameLowering.h | 14 - lib/Target/CellSPU/SPUISelLowering.cpp | 16 +- lib/Target/CellSPU/SPUISelLowering.h | 6 +- lib/Target/CellSPU/SPUInstrInfo.cpp | 4 +- lib/Target/CellSPU/SPUInstrInfo.td | 10 +- lib/Target/CellSPU/SPURegisterInfo.cpp | 19 +- lib/Target/CellSPU/SPURegisterInfo.h | 6 - lib/Target/CellSPU/SPUSubtarget.cpp | 2 +- lib/Target/CellSPU/SPUTargetMachine.cpp | 25 +- lib/Target/CellSPU/SPUTargetMachine.h | 5 +- lib/Target/CellSPU/TargetInfo/CMakeLists.txt | 8 +- .../CellSPU/TargetInfo/CellSPUTargetInfo.cpp | 2 +- lib/Target/CppBackend/CMakeLists.txt | 7 + lib/Target/CppBackend/CPPBackend.cpp | 141 +- lib/Target/CppBackend/CPPTargetMachine.h | 5 +- .../CppBackend/TargetInfo/CMakeLists.txt | 4 + .../TargetInfo/CppBackendTargetInfo.cpp | 4 +- lib/Target/MBlaze/AsmParser/CMakeLists.txt | 8 + .../MBlaze/AsmParser/MBlazeAsmLexer.cpp | 27 +- .../MBlaze/AsmParser/MBlazeAsmParser.cpp | 24 +- lib/Target/MBlaze/AsmParser/Makefile | 2 +- lib/Target/MBlaze/CMakeLists.txt | 36 +- lib/Target/MBlaze/Disassembler/CMakeLists.txt | 10 +- .../Disassembler/MBlazeDisassembler.cpp | 76 +- .../MBlaze/Disassembler/MBlazeDisassembler.h | 9 +- lib/Target/MBlaze/InstPrinter/CMakeLists.txt | 9 +- .../MBlaze/InstPrinter/MBlazeInstPrinter.cpp | 4 +- .../MBlaze/InstPrinter/MBlazeInstPrinter.h | 2 +- lib/Target/MBlaze/MBlaze.h | 12 +- lib/Target/MBlaze/MBlazeAsmPrinter.cpp | 21 +- lib/Target/MBlaze/MBlazeFrameLowering.cpp | 2 +- lib/Target/MBlaze/MBlazeISelLowering.cpp | 13 +- lib/Target/MBlaze/MBlazeISelLowering.h | 2 +- lib/Target/MBlaze/MBlazeInstrInfo.cpp | 5 +- lib/Target/MBlaze/MBlazeInstrInfo.h | 56 - lib/Target/MBlaze/MBlazeInstrInfo.td | 21 +- lib/Target/MBlaze/MBlazeIntrinsicInfo.cpp | 8 +- lib/Target/MBlaze/MBlazeIntrinsicInfo.h | 4 +- lib/Target/MBlaze/MBlazeRegisterInfo.cpp | 172 +- lib/Target/MBlaze/MBlazeRegisterInfo.h | 12 - lib/Target/MBlaze/MBlazeSubtarget.cpp | 2 +- lib/Target/MBlaze/MBlazeTargetMachine.cpp | 50 +- lib/Target/MBlaze/MBlazeTargetMachine.h | 5 +- lib/Target/MBlaze/MBlazeTargetObjectFile.cpp | 2 +- lib/Target/MBlaze/MCTargetDesc/CMakeLists.txt | 13 +- .../{ => MCTargetDesc}/MBlazeAsmBackend.cpp | 17 +- .../MBlaze/MCTargetDesc/MBlazeBaseInfo.h | 240 + .../MBlazeMCCodeEmitter.cpp | 8 +- .../MCTargetDesc/MBlazeMCTargetDesc.cpp | 95 +- .../MBlaze/MCTargetDesc/MBlazeMCTargetDesc.h | 11 + lib/Target/MBlaze/TargetInfo/CMakeLists.txt | 8 +- .../MBlaze/TargetInfo/MBlazeTargetInfo.cpp | 2 +- lib/Target/MSP430/CMakeLists.txt | 26 +- lib/Target/MSP430/InstPrinter/CMakeLists.txt | 8 +- .../MSP430/InstPrinter/MSP430InstPrinter.cpp | 4 +- .../MSP430/InstPrinter/MSP430InstPrinter.h | 4 +- lib/Target/MSP430/MCTargetDesc/CMakeLists.txt | 8 + .../MCTargetDesc/MSP430MCTargetDesc.cpp | 53 +- .../MSP430/MCTargetDesc/MSP430MCTargetDesc.h | 4 +- lib/Target/MSP430/MSP430AsmPrinter.cpp | 14 +- lib/Target/MSP430/MSP430ISelLowering.cpp | 7 +- lib/Target/MSP430/MSP430ISelLowering.h | 4 +- lib/Target/MSP430/MSP430InstrInfo.cpp | 2 +- lib/Target/MSP430/MSP430RegisterInfo.cpp | 16 +- lib/Target/MSP430/MSP430RegisterInfo.h | 5 - lib/Target/MSP430/MSP430Subtarget.cpp | 2 +- lib/Target/MSP430/MSP430TargetMachine.cpp | 11 +- lib/Target/MSP430/MSP430TargetMachine.h | 5 +- lib/Target/MSP430/TargetInfo/CMakeLists.txt | 8 +- .../MSP430/TargetInfo/MSP430TargetInfo.cpp | 2 +- lib/Target/Mangler.cpp | 4 +- lib/Target/Mips/CMakeLists.txt | 28 +- lib/Target/Mips/InstPrinter/CMakeLists.txt | 8 +- lib/Target/Mips/InstPrinter/Makefile | 2 +- .../Mips/InstPrinter/MipsInstPrinter.cpp | 6 +- lib/Target/Mips/InstPrinter/MipsInstPrinter.h | 4 +- lib/Target/Mips/MCTargetDesc/CMakeLists.txt | 13 +- .../Mips/MCTargetDesc/MipsAsmBackend.cpp | 117 + lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h | 113 + lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h | 90 + .../Mips/MCTargetDesc/MipsMCAsmInfo.cpp | 3 +- .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 52 + .../Mips/MCTargetDesc/MipsMCTargetDesc.cpp | 124 +- .../Mips/MCTargetDesc/MipsMCTargetDesc.h | 21 +- lib/Target/Mips/Mips.h | 3 + lib/Target/Mips/Mips.td | 32 +- lib/Target/Mips/Mips64InstrInfo.td | 214 + lib/Target/Mips/MipsAsmPrinter.cpp | 42 +- lib/Target/Mips/MipsCallingConv.td | 55 +- lib/Target/Mips/MipsCodeEmitter.cpp | 245 + lib/Target/Mips/MipsDelaySlotFiller.cpp | 204 +- lib/Target/Mips/MipsFrameLowering.cpp | 19 +- lib/Target/Mips/MipsFrameLowering.h | 5 +- lib/Target/Mips/MipsISelDAGToDAG.cpp | 185 +- lib/Target/Mips/MipsISelLowering.cpp | 862 +- lib/Target/Mips/MipsISelLowering.h | 16 +- lib/Target/Mips/MipsInstrFPU.td | 232 +- lib/Target/Mips/MipsInstrFormats.td | 44 +- lib/Target/Mips/MipsInstrInfo.cpp | 210 +- lib/Target/Mips/MipsInstrInfo.h | 37 +- lib/Target/Mips/MipsInstrInfo.td | 814 +- lib/Target/Mips/MipsJITInfo.cpp | 230 + lib/Target/Mips/MipsJITInfo.h | 70 + lib/Target/Mips/MipsMCInstLower.cpp | 64 +- lib/Target/Mips/MipsMCInstLower.h | 5 +- lib/Target/Mips/MipsMCSymbolRefExpr.cpp | 9 +- lib/Target/Mips/MipsMCSymbolRefExpr.h | 7 +- lib/Target/Mips/MipsMachineFunction.h | 9 +- lib/Target/Mips/MipsRegisterInfo.cpp | 203 +- lib/Target/Mips/MipsRegisterInfo.h | 4 - lib/Target/Mips/MipsRegisterInfo.td | 119 +- lib/Target/Mips/MipsRelocations.h | 41 + lib/Target/Mips/MipsSubtarget.cpp | 38 +- lib/Target/Mips/MipsSubtarget.h | 15 +- lib/Target/Mips/MipsTargetMachine.cpp | 73 +- lib/Target/Mips/MipsTargetMachine.h | 48 +- lib/Target/Mips/MipsTargetObjectFile.cpp | 2 +- lib/Target/Mips/TargetInfo/CMakeLists.txt | 8 +- lib/Target/Mips/TargetInfo/MipsTargetInfo.cpp | 16 +- lib/Target/PTX/CMakeLists.txt | 32 +- lib/Target/PTX/InstPrinter/CMakeLists.txt | 13 + lib/Target/PTX/InstPrinter/Makefile | 16 + lib/Target/PTX/InstPrinter/PTXInstPrinter.cpp | 192 + lib/Target/PTX/InstPrinter/PTXInstPrinter.h | 47 + lib/Target/PTX/MCTargetDesc/CMakeLists.txt | 9 + lib/Target/PTX/MCTargetDesc/PTXBaseInfo.h | 63 + .../PTX/MCTargetDesc/PTXMCTargetDesc.cpp | 53 +- lib/Target/PTX/Makefile | 3 +- lib/Target/PTX/PTX.h | 28 +- lib/Target/PTX/PTX.td | 28 +- lib/Target/PTX/PTXAsmPrinter.cpp | 502 +- lib/Target/PTX/PTXAsmPrinter.h | 57 + lib/Target/PTX/PTXCallingConv.td | 29 - lib/Target/PTX/PTXFPRoundingModePass.cpp | 179 + lib/Target/PTX/PTXISelDAGToDAG.cpp | 182 +- lib/Target/PTX/PTXISelLowering.cpp | 289 +- lib/Target/PTX/PTXISelLowering.h | 19 +- lib/Target/PTX/PTXInstrFormats.td | 31 +- lib/Target/PTX/PTXInstrInfo.cpp | 82 +- lib/Target/PTX/PTXInstrInfo.td | 1219 +- lib/Target/PTX/PTXInstrLoadStore.td | 278 + lib/Target/PTX/PTXIntrinsicInstrInfo.td | 78 +- lib/Target/PTX/PTXMCAsmStreamer.cpp | 15 +- lib/Target/PTX/PTXMCInstLower.cpp | 32 + lib/Target/PTX/PTXMFInfoExtract.cpp | 36 +- lib/Target/PTX/PTXMachineFunctionInfo.h | 167 +- lib/Target/PTX/PTXParamManager.cpp | 73 + lib/Target/PTX/PTXParamManager.h | 86 + lib/Target/PTX/PTXRegAlloc.cpp | 58 + lib/Target/PTX/PTXRegisterInfo.cpp | 29 +- lib/Target/PTX/PTXRegisterInfo.h | 18 +- lib/Target/PTX/PTXRegisterInfo.td | 540 +- lib/Target/PTX/PTXSelectionDAGInfo.cpp | 149 + lib/Target/PTX/PTXSelectionDAGInfo.h | 53 + lib/Target/PTX/PTXSubtarget.cpp | 2 +- lib/Target/PTX/PTXSubtarget.h | 11 +- lib/Target/PTX/PTXTargetMachine.cpp | 320 +- lib/Target/PTX/PTXTargetMachine.h | 60 +- lib/Target/PTX/TargetInfo/CMakeLists.txt | 8 +- lib/Target/PTX/TargetInfo/PTXTargetInfo.cpp | 2 +- lib/Target/PTX/generate-register-td.py | 163 - lib/Target/PowerPC/CMakeLists.txt | 34 +- lib/Target/PowerPC/InstPrinter/CMakeLists.txt | 8 +- .../PowerPC/InstPrinter/PPCInstPrinter.cpp | 11 +- .../PowerPC/InstPrinter/PPCInstPrinter.h | 2 +- .../PowerPC/MCTargetDesc/CMakeLists.txt | 12 + .../{ => MCTargetDesc}/PPCAsmBackend.cpp | 88 +- lib/Target/PowerPC/MCTargetDesc/PPCBaseInfo.h | 70 + .../{ => MCTargetDesc}/PPCFixupKinds.h | 0 .../PowerPC/MCTargetDesc/PPCMCAsmInfo.cpp | 6 +- .../{ => MCTargetDesc}/PPCMCCodeEmitter.cpp | 9 +- .../PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp | 115 +- .../PowerPC/MCTargetDesc/PPCMCTargetDesc.h | 10 + .../{ => MCTargetDesc}/PPCPredicates.cpp | 0 .../{ => MCTargetDesc}/PPCPredicates.h | 2 - lib/Target/PowerPC/PPC.h | 11 +- lib/Target/PowerPC/PPC.td | 4 +- lib/Target/PowerPC/PPCAsmPrinter.cpp | 14 +- lib/Target/PowerPC/PPCBranchSelector.cpp | 2 +- lib/Target/PowerPC/PPCCodeEmitter.cpp | 4 +- lib/Target/PowerPC/PPCFrameLowering.cpp | 17 +- lib/Target/PowerPC/PPCFrameLowering.h | 1 - lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 2 +- lib/Target/PowerPC/PPCISelLowering.cpp | 65 +- lib/Target/PowerPC/PPCISelLowering.h | 17 +- lib/Target/PowerPC/PPCInstrInfo.cpp | 36 +- lib/Target/PowerPC/PPCInstrInfo.td | 6 + lib/Target/PowerPC/PPCRegisterInfo.cpp | 79 +- lib/Target/PowerPC/PPCRegisterInfo.h | 8 - lib/Target/PowerPC/PPCSubtarget.cpp | 2 +- lib/Target/PowerPC/PPCTargetMachine.cpp | 71 +- lib/Target/PowerPC/PPCTargetMachine.h | 16 +- lib/Target/PowerPC/TargetInfo/CMakeLists.txt | 8 +- .../PowerPC/TargetInfo/PowerPCTargetInfo.cpp | 2 +- lib/Target/README.txt | 10 + lib/Target/Sparc/CMakeLists.txt | 25 +- lib/Target/Sparc/MCTargetDesc/CMakeLists.txt | 8 + .../Sparc/MCTargetDesc/SparcMCTargetDesc.cpp | 40 +- lib/Target/Sparc/SparcAsmPrinter.cpp | 2 +- lib/Target/Sparc/SparcISelLowering.cpp | 8 +- lib/Target/Sparc/SparcInstrInfo.cpp | 2 +- lib/Target/Sparc/SparcRegisterInfo.cpp | 15 +- lib/Target/Sparc/SparcRegisterInfo.h | 4 - lib/Target/Sparc/SparcSubtarget.cpp | 2 +- lib/Target/Sparc/SparcTargetMachine.cpp | 27 +- lib/Target/Sparc/SparcTargetMachine.h | 16 +- lib/Target/Sparc/TargetInfo/CMakeLists.txt | 8 +- .../Sparc/TargetInfo/SparcTargetInfo.cpp | 2 +- lib/Target/SystemZ/CMakeLists.txt | 25 +- .../SystemZ/MCTargetDesc/CMakeLists.txt | 7 + .../MCTargetDesc/SystemZMCTargetDesc.cpp | 41 +- lib/Target/SystemZ/SystemZAsmPrinter.cpp | 4 +- lib/Target/SystemZ/SystemZISelLowering.cpp | 1 + lib/Target/SystemZ/SystemZInstrInfo.cpp | 2 +- lib/Target/SystemZ/SystemZInstrInfo.td | 2 +- lib/Target/SystemZ/SystemZRegisterInfo.cpp | 17 +- lib/Target/SystemZ/SystemZRegisterInfo.h | 4 - lib/Target/SystemZ/SystemZSubtarget.cpp | 2 +- lib/Target/SystemZ/SystemZTargetMachine.cpp | 13 +- lib/Target/SystemZ/SystemZTargetMachine.h | 5 +- lib/Target/SystemZ/TargetInfo/CMakeLists.txt | 8 +- .../SystemZ/TargetInfo/SystemZTargetInfo.cpp | 2 +- lib/Target/Target.cpp | 10 +- lib/Target/TargetAsmInfo.cpp | 23 - lib/Target/TargetData.cpp | 53 +- lib/Target/TargetFrameLowering.cpp | 8 - lib/Target/TargetLoweringObjectFile.cpp | 59 +- lib/Target/TargetMachine.cpp | 67 +- lib/Target/TargetRegisterInfo.cpp | 47 +- lib/Target/X86/AsmParser/CMakeLists.txt | 11 +- lib/Target/X86/AsmParser/X86AsmLexer.cpp | 20 +- lib/Target/X86/AsmParser/X86AsmParser.cpp | 84 +- lib/Target/X86/CMakeLists.txt | 41 +- lib/Target/X86/Disassembler/CMakeLists.txt | 10 +- .../X86/Disassembler/X86Disassembler.cpp | 77 +- lib/Target/X86/Disassembler/X86Disassembler.h | 26 +- .../X86/Disassembler/X86DisassemblerDecoder.c | 165 +- .../X86DisassemblerDecoderCommon.h | 8 +- lib/Target/X86/InstPrinter/CMakeLists.txt | 9 +- .../X86/InstPrinter/X86ATTInstPrinter.cpp | 10 +- .../X86/InstPrinter/X86ATTInstPrinter.h | 2 +- .../X86/InstPrinter/X86InstComments.cpp | 31 +- .../X86/InstPrinter/X86IntelInstPrinter.cpp | 7 +- .../X86/InstPrinter/X86IntelInstPrinter.h | 2 +- lib/Target/X86/MCTargetDesc/CMakeLists.txt | 13 + .../X86/{ => MCTargetDesc}/X86AsmBackend.cpp | 29 +- lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 548 + .../X86/{ => MCTargetDesc}/X86FixupKinds.h | 0 .../{ => MCTargetDesc}/X86MCCodeEmitter.cpp | 198 +- .../X86/MCTargetDesc/X86MCTargetDesc.cpp | 340 +- lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h | 45 +- .../X86MachObjectWriter.cpp | 6 +- lib/Target/X86/README-SSE.txt | 2 +- lib/Target/X86/README.txt | 38 +- lib/Target/X86/TargetInfo/CMakeLists.txt | 8 +- lib/Target/X86/TargetInfo/X86TargetInfo.cpp | 2 +- lib/Target/X86/Utils/CMakeLists.txt | 8 +- lib/Target/X86/Utils/X86ShuffleDecode.cpp | 75 +- lib/Target/X86/Utils/X86ShuffleDecode.h | 20 + lib/Target/X86/X86.h | 30 +- lib/Target/X86/X86.td | 78 +- lib/Target/X86/X86AsmPrinter.cpp | 23 +- lib/Target/X86/X86CodeEmitter.cpp | 36 +- lib/Target/X86/X86ELFWriterInfo.cpp | 2 +- lib/Target/X86/X86FastISel.cpp | 93 +- lib/Target/X86/X86FloatingPoint.cpp | 34 + lib/Target/X86/X86FrameLowering.cpp | 655 +- lib/Target/X86/X86FrameLowering.h | 7 +- lib/Target/X86/X86ISelDAGToDAG.cpp | 16 +- lib/Target/X86/X86ISelLowering.cpp | 2948 +- lib/Target/X86/X86ISelLowering.h | 62 +- lib/Target/X86/X86InstrArithmetic.td | 96 +- lib/Target/X86/X86InstrCompiler.td | 102 +- lib/Target/X86/X86InstrExtension.td | 4 +- lib/Target/X86/X86InstrFormats.td | 8 +- lib/Target/X86/X86InstrFragmentsSIMD.td | 84 +- lib/Target/X86/X86InstrInfo.cpp | 1836 +- lib/Target/X86/X86InstrInfo.h | 553 +- lib/Target/X86/X86InstrInfo.td | 209 +- lib/Target/X86/X86InstrSSE.td | 4100 +- lib/Target/X86/X86InstrSystem.td | 114 +- lib/Target/X86/X86InstrVMX.td | 10 +- lib/Target/X86/X86MCInstLower.cpp | 23 +- lib/Target/X86/X86MachineFunctionInfo.h | 20 +- lib/Target/X86/X86RegisterInfo.cpp | 163 +- lib/Target/X86/X86RegisterInfo.h | 25 +- lib/Target/X86/X86RegisterInfo.td | 11 +- lib/Target/X86/X86SelectionDAGInfo.cpp | 2 +- lib/Target/X86/X86Subtarget.cpp | 78 +- lib/Target/X86/X86Subtarget.h | 36 +- lib/Target/X86/X86TargetMachine.cpp | 173 +- lib/Target/X86/X86TargetMachine.h | 22 +- lib/Target/X86/X86TargetObjectFile.cpp | 76 - lib/Target/X86/X86TargetObjectFile.h | 22 - lib/Target/X86/X86VZeroUpper.cpp | 105 + lib/Target/XCore/CMakeLists.txt | 25 +- lib/Target/XCore/MCTargetDesc/CMakeLists.txt | 7 + .../XCore/MCTargetDesc/XCoreMCTargetDesc.cpp | 48 +- lib/Target/XCore/TargetInfo/CMakeLists.txt | 8 +- .../XCore/TargetInfo/XCoreTargetInfo.cpp | 2 +- lib/Target/XCore/XCoreAsmPrinter.cpp | 60 +- lib/Target/XCore/XCoreFrameLowering.cpp | 11 +- lib/Target/XCore/XCoreFrameLowering.h | 2 - lib/Target/XCore/XCoreISelDAGToDAG.cpp | 11 +- lib/Target/XCore/XCoreISelLowering.cpp | 37 +- lib/Target/XCore/XCoreISelLowering.h | 5 +- lib/Target/XCore/XCoreInstrInfo.cpp | 12 +- lib/Target/XCore/XCoreInstrInfo.h | 5 + lib/Target/XCore/XCoreInstrInfo.td | 81 +- lib/Target/XCore/XCoreRegisterInfo.cpp | 15 +- lib/Target/XCore/XCoreRegisterInfo.h | 5 - lib/Target/XCore/XCoreSubtarget.cpp | 2 +- lib/Target/XCore/XCoreTargetMachine.cpp | 10 +- lib/Target/XCore/XCoreTargetMachine.h | 5 +- lib/Transforms/IPO/ArgumentPromotion.cpp | 43 +- lib/Transforms/IPO/CMakeLists.txt | 12 +- lib/Transforms/IPO/ConstantMerge.cpp | 49 +- .../IPO/DeadArgumentElimination.cpp | 12 +- lib/Transforms/IPO/FunctionAttrs.cpp | 4 +- lib/Transforms/IPO/GlobalOpt.cpp | 125 +- lib/Transforms/IPO/IPConstantPropagation.cpp | 2 +- lib/Transforms/IPO/IPO.cpp | 15 +- lib/Transforms/IPO/InlineAlways.cpp | 15 +- lib/Transforms/IPO/InlineSimple.cpp | 26 +- lib/Transforms/IPO/Inliner.cpp | 4 +- lib/Transforms/IPO/LoopExtractor.cpp | 73 +- lib/Transforms/IPO/LowerSetJmp.cpp | 547 - lib/Transforms/IPO/MergeFunctions.cpp | 70 +- lib/Transforms/IPO/PassManagerBuilder.cpp | 343 + lib/Transforms/IPO/PruneEH.cpp | 5 +- lib/Transforms/IPO/StripSymbols.cpp | 2 +- lib/Transforms/InstCombine/CMakeLists.txt | 8 + lib/Transforms/InstCombine/InstCombine.h | 15 +- .../InstCombine/InstCombineAddSub.cpp | 8 +- .../InstCombine/InstCombineAndOrXor.cpp | 53 +- .../InstCombine/InstCombineCalls.cpp | 192 +- .../InstCombine/InstCombineCasts.cpp | 112 +- .../InstCombine/InstCombineCompares.cpp | 495 +- .../InstCombineLoadStoreAlloca.cpp | 99 +- .../InstCombine/InstCombineMulDivRem.cpp | 13 +- lib/Transforms/InstCombine/InstCombinePHI.cpp | 20 +- .../InstCombine/InstCombineSelect.cpp | 20 +- .../InstCombine/InstCombineShifts.cpp | 49 +- .../InstCombineSimplifyDemanded.cpp | 24 +- .../InstCombine/InstCombineVectorOps.cpp | 8 +- .../InstCombine/InstructionCombining.cpp | 626 +- lib/Transforms/Instrumentation/CMakeLists.txt | 7 + .../Instrumentation/EdgeProfiling.cpp | 2 +- .../Instrumentation/GCOVProfiling.cpp | 370 +- .../Instrumentation/OptimalEdgeProfiling.cpp | 4 +- .../Instrumentation/PathProfiling.cpp | 29 +- .../Instrumentation/ProfilingUtils.cpp | 13 +- lib/Transforms/Scalar/ADCE.cpp | 2 +- lib/Transforms/Scalar/CMakeLists.txt | 10 +- lib/Transforms/Scalar/CodeGenPrepare.cpp | 108 +- .../Scalar/DeadStoreElimination.cpp | 182 +- lib/Transforms/Scalar/EarlyCSE.cpp | 8 +- lib/Transforms/Scalar/GVN.cpp | 274 +- lib/Transforms/Scalar/IndVarSimplify.cpp | 1144 +- lib/Transforms/Scalar/JumpThreading.cpp | 4 +- lib/Transforms/Scalar/LICM.cpp | 64 +- lib/Transforms/Scalar/LoopIdiomRecognize.cpp | 10 +- lib/Transforms/Scalar/LoopStrengthReduce.cpp | 215 +- lib/Transforms/Scalar/LoopUnrollPass.cpp | 61 +- lib/Transforms/Scalar/LoopUnswitch.cpp | 28 +- lib/Transforms/Scalar/LowerAtomic.cpp | 181 +- lib/Transforms/Scalar/MemCpyOptimizer.cpp | 14 +- lib/Transforms/Scalar/ObjCARC.cpp | 440 +- lib/Transforms/Scalar/Reassociate.cpp | 2 +- lib/Transforms/Scalar/SCCP.cpp | 250 +- lib/Transforms/Scalar/Scalar.cpp | 5 +- .../Scalar/ScalarReplAggregates.cpp | 598 +- lib/Transforms/Scalar/SimplifyLibCalls.cpp | 111 +- lib/Transforms/Scalar/Sink.cpp | 13 +- lib/Transforms/Scalar/TailDuplication.cpp | 373 - lib/Transforms/Utils/AddrModeMatcher.cpp | 4 +- lib/Transforms/Utils/BasicBlockUtils.cpp | 356 +- lib/Transforms/Utils/BreakCriticalEdges.cpp | 56 +- lib/Transforms/Utils/BuildLibCalls.cpp | 10 +- lib/Transforms/Utils/CMakeLists.txt | 8 + lib/Transforms/Utils/CloneFunction.cpp | 11 +- lib/Transforms/Utils/CloneModule.cpp | 27 +- lib/Transforms/Utils/CodeExtractor.cpp | 45 +- lib/Transforms/Utils/InlineFunction.cpp | 178 +- lib/Transforms/Utils/Local.cpp | 25 +- lib/Transforms/Utils/LoopSimplify.cpp | 47 +- lib/Transforms/Utils/LoopUnroll.cpp | 186 +- lib/Transforms/Utils/LowerExpectIntrinsic.cpp | 4 +- lib/Transforms/Utils/LowerInvoke.cpp | 37 +- lib/Transforms/Utils/LowerSwitch.cpp | 4 +- .../Utils/PromoteMemoryToRegister.cpp | 4 + lib/Transforms/Utils/SSAUpdater.cpp | 8 +- lib/Transforms/Utils/SimplifyCFG.cpp | 155 +- lib/Transforms/Utils/SimplifyIndVar.cpp | 432 + lib/Transforms/Utils/ValueMapper.cpp | 5 +- lib/VMCore/AsmWriter.cpp | 252 +- lib/VMCore/Attributes.cpp | 6 +- lib/VMCore/AutoUpgrade.cpp | 395 +- lib/VMCore/BasicBlock.cpp | 34 +- lib/VMCore/CMakeLists.txt | 5 +- lib/VMCore/ConstantFold.cpp | 209 +- lib/VMCore/ConstantFold.h | 6 +- lib/VMCore/Constants.cpp | 265 +- lib/VMCore/ConstantsContext.h | 32 +- lib/VMCore/Core.cpp | 183 +- lib/VMCore/DebugLoc.cpp | 4 +- lib/VMCore/Function.cpp | 43 +- lib/VMCore/GCOV.cpp | 281 + lib/VMCore/Globals.cpp | 8 +- lib/VMCore/IRBuilder.cpp | 2 +- lib/VMCore/InlineAsm.cpp | 8 +- lib/VMCore/Instruction.cpp | 68 +- lib/VMCore/Instructions.cpp | 686 +- lib/VMCore/LLVMContextImpl.h | 4 +- lib/VMCore/Makefile | 4 +- lib/VMCore/Module.cpp | 48 +- lib/VMCore/PassManager.cpp | 59 +- lib/VMCore/PassRegistry.cpp | 1 + lib/VMCore/Type.cpp | 99 +- lib/VMCore/Value.cpp | 8 +- lib/VMCore/ValueTypes.cpp | 16 +- lib/VMCore/Verifier.cpp | 284 +- runtime/libprofile/CommonProfiling.c | 17 +- runtime/libprofile/GCDAProfiling.c | 6 +- runtime/libprofile/Makefile | 4 + .../BasicAA/2009-10-13-AtomicModRef.ll | 4 +- test/Analysis/BasicAA/cas.ll | 4 +- test/Analysis/BasicAA/gep-alias.ll | 32 + test/Analysis/BasicAA/memset_pattern.ll | 21 + test/Analysis/BasicAA/modref.ll | 17 +- test/Analysis/BlockFrequencyInfo/basic.ll | 92 + .../BlockFrequencyInfo}/dg.exp | 0 .../ScalarEvolution/2011-10-04-ConstEvolve.ll | 50 + .../ScalarEvolution/SolveQuadraticEquation.ll | 56 +- test/Analysis/ScalarEvolution/avoid-smax-1.ll | 7 +- .../ScalarEvolution/max-trip-count.ll | 28 + .../Assembler/2003-06-17-InvokeDisassemble.ll | 10 +- test/Assembler/AutoUpgradeIntrinsics.ll | 13 + test/Assembler/atomic.ll | 26 + test/Bindings/Ocaml/ipo_opts.ml | 73 + test/Bindings/Ocaml/scalar_opts.ml | 10 + test/Bindings/Ocaml/target.ml | 1 - test/Bindings/Ocaml/vmcore.ml | 165 +- test/CMakeLists.txt | 2 +- test/CodeGen/ARM/2009-10-16-Scope.ll | 4 +- test/CodeGen/ARM/2010-11-30-reloc-movt.ll | 16 +- test/CodeGen/ARM/2010-12-15-elf-lcomm.ll | 21 +- test/CodeGen/ARM/2011-06-09-TailCallByVal.ll | 1 + .../CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll | 124 + .../CodeGen/ARM/2011-08-12-vmovqqqq-pseudo.ll | 12 + test/CodeGen/ARM/2011-08-25-ldmia_ret.ll | 100 + test/CodeGen/ARM/2011-08-29-SchedCycle.ll | 45 + test/CodeGen/ARM/2011-08-29-ldr_pre_imm.ll | 34 + .../ARM/2011-09-09-OddVectorDivision.ll | 23 + test/CodeGen/ARM/2011-09-19-cpsr.ll | 54 + test/CodeGen/ARM/2011-09-28-CMovCombineBug.ll | 30 + test/CodeGen/ARM/atomic-64bit.ll | 128 + test/CodeGen/ARM/atomic-cmp.ll | 8 +- test/CodeGen/ARM/atomic-load-store.ll | 56 + test/CodeGen/ARM/atomic-op.ll | 48 +- test/CodeGen/ARM/avoid-cpsr-rmw.ll | 6 +- test/CodeGen/ARM/call-tc.ll | 4 + test/CodeGen/ARM/carry.ll | 10 + test/CodeGen/ARM/crash-greedy-v6.ll | 32 + test/CodeGen/ARM/crash.ll | 44 +- test/CodeGen/ARM/debug-info-arg.ll | 65 + test/CodeGen/ARM/debug-info-blocks.ll | 2 +- test/CodeGen/ARM/debug-info-sreg2.ll | 6 +- test/CodeGen/ARM/divmod.ll | 58 + test/CodeGen/ARM/elf-lcomm-align.ll | 14 + test/CodeGen/ARM/fabss.ll | 4 +- test/CodeGen/ARM/fast-isel.ll | 4 +- test/CodeGen/ARM/fp_convert.ll | 6 +- test/CodeGen/ARM/fpmem.ll | 18 + test/CodeGen/ARM/hidden-vis-2.ll | 2 +- test/CodeGen/ARM/hidden-vis-3.ll | 2 +- test/CodeGen/ARM/iabs.ll | 8 +- test/CodeGen/ARM/ifcvt4.ll | 10 +- test/CodeGen/ARM/indirectbr.ll | 1 - test/CodeGen/ARM/inlineasm3.ll | 12 + test/CodeGen/ARM/inlineasm4.ll | 17 + test/CodeGen/ARM/lsr-on-unrolled-loops.ll | 495 +- test/CodeGen/ARM/lsr-unfolded-offset.ll | 3 +- test/CodeGen/ARM/mulhi.ll | 44 +- test/CodeGen/ARM/select.ll | 12 +- test/CodeGen/ARM/shifter_operand.ll | 9 +- test/CodeGen/ARM/str_pre-2.ll | 4 +- test/CodeGen/ARM/subreg-remat.ll | 52 + test/CodeGen/ARM/sxt_rot.ll | 41 +- test/CodeGen/ARM/tail-opts.ll | 2 +- test/CodeGen/ARM/thumb2-it-block.ll | 20 + test/CodeGen/ARM/va_arg.ll | 1 + test/CodeGen/ARM/vext.ll | 17 + test/CodeGen/ARM/widen-vmovs.ll | 35 + test/CodeGen/Alpha/2006-04-04-zextload.ll | 4 - test/CodeGen/Alpha/mb.ll | 4 +- test/CodeGen/Alpha/wmb.ll | 8 - test/CodeGen/CBackend/X86/dg.exp | 2 +- test/CodeGen/CellSPU/jumptable.ll | 12 +- test/CodeGen/CellSPU/or_ops.ll | 13 +- .../Generic/2004-02-08-UnwindSupport.ll | 17 - test/CodeGen/Generic/2007-02-25-invoke.ll | 6 +- .../2007-04-30-LandingPadBranchFolding.ll | 6 +- test/CodeGen/Generic/2007-12-17-InvokeAsm.ll | 12 +- .../Generic/2007-12-31-UnusedSelector.ll | 5 +- .../Generic/2009-06-03-UnreachableSplitPad.ll | 4 + .../Generic/2009-11-16-BadKillsCrash.ll | 8 +- .../Generic/2011-07-07-ScheduleDAGCrash.ll | 3 + test/CodeGen/Generic/exception-handling.ll | 29 + ...e-return-values-cross-block-with-invoke.ll | 3 + test/CodeGen/Generic/promote-integers.ll | 15 - test/CodeGen/Mips/2008-07-05-ByVal.ll | 18 - test/CodeGen/Mips/2008-07-06-fadd64.ll | 6 +- test/CodeGen/Mips/2008-07-07-FPExtend.ll | 6 +- .../Mips/2008-07-07-IntDoubleConvertions.ll | 17 +- .../Mips/2008-07-15-InternalConstant.ll | 19 +- test/CodeGen/Mips/2008-07-15-SmallSection.ll | 23 +- test/CodeGen/Mips/2008-07-16-SignExtInReg.ll | 8 +- test/CodeGen/Mips/2008-08-03-fabs64.ll | 8 +- test/CodeGen/Mips/2008-08-07-FPRound.ll | 6 +- test/CodeGen/Mips/2008-08-08-bswap.ll | 5 +- test/CodeGen/Mips/2010-07-20-Select.ll | 22 - test/CodeGen/Mips/2010-11-09-CountLeading.ll | 2 +- test/CodeGen/Mips/2010-11-09-Mul.ll | 2 +- test/CodeGen/Mips/alloca.ll | 2 +- test/CodeGen/Mips/atomic.ll | 125 +- test/CodeGen/Mips/brdelayslot.ll | 15 + test/CodeGen/Mips/cmov.ll | 4 +- test/CodeGen/Mips/constantfp0.ll | 11 + test/CodeGen/Mips/cprestore.ll | 20 + test/CodeGen/Mips/double2int.ll | 2 +- test/CodeGen/Mips/eh.ll | 15 +- test/CodeGen/Mips/extins.ll | 21 + test/CodeGen/Mips/fcopysign.ll | 4 +- test/CodeGen/Mips/fpcmp.ll | 15 +- test/CodeGen/Mips/frame-address.ll | 2 +- test/CodeGen/Mips/i64arg.ll | 2 +- test/CodeGen/Mips/inlineasmmemop.ll | 2 +- test/CodeGen/Mips/internalfunc.ll | 2 +- test/CodeGen/Mips/largeimmprinting.ll | 6 +- test/CodeGen/Mips/madd-msub.ll | 14 +- test/CodeGen/Mips/mips64fpldst.ll | 58 + test/CodeGen/Mips/mips64instrs.ll | 143 + test/CodeGen/Mips/mips64intldst.ll | 157 + test/CodeGen/Mips/mips64shift.ll | 104 + test/CodeGen/Mips/mipslopat.ll | 19 + test/CodeGen/Mips/o32_cc.ll | 2 +- test/CodeGen/Mips/o32_cc_byval.ll | 2 +- test/CodeGen/Mips/o32_cc_vararg.ll | 2 +- test/CodeGen/Mips/rotate.ll | 2 +- test/CodeGen/Mips/select.ll | 96 +- test/CodeGen/Mips/tls.ll | 4 +- test/CodeGen/Mips/unalignedload.ll | 41 + test/CodeGen/PTX/20110926-sitofp.ll | 24 + test/CodeGen/PTX/add.ll | 40 +- test/CodeGen/PTX/aggregates.ll | 1 + test/CodeGen/PTX/bitwise.ll | 6 +- test/CodeGen/PTX/bra.ll | 8 +- test/CodeGen/PTX/cvt.ll | 186 +- test/CodeGen/PTX/fdiv-sm10.ll | 8 +- test/CodeGen/PTX/fdiv-sm13.ll | 8 +- test/CodeGen/PTX/fneg.ll | 8 +- test/CodeGen/PTX/intrinsic.ll | 134 +- test/CodeGen/PTX/ld.ll | 255 +- test/CodeGen/PTX/llvm-intrinsic.ll | 24 +- test/CodeGen/PTX/mad.ll | 8 +- test/CodeGen/PTX/mov.ll | 24 +- test/CodeGen/PTX/mul.ll | 16 +- test/CodeGen/PTX/parameter-order.ll | 4 +- test/CodeGen/PTX/selp.ll | 8 +- test/CodeGen/PTX/setp.ll | 136 +- test/CodeGen/PTX/shl.ll | 6 +- test/CodeGen/PTX/shr.ll | 12 +- test/CodeGen/PTX/simple-call.ll | 27 + test/CodeGen/PTX/st.ll | 235 +- test/CodeGen/PTX/stack-object.ll | 19 + test/CodeGen/PTX/sub.ll | 40 +- .../PowerPC/2007-11-16-landingpad-split.ll | 17 +- .../PowerPC/2009-01-16-DeclareISelBug.ll | 7 - .../PowerPC/2009-08-23-linkerprivate.ll | 2 +- test/CodeGen/PowerPC/Atomics-32.ll | 1392 +- test/CodeGen/PowerPC/Atomics-64.ll | 1423 +- test/CodeGen/PowerPC/atomic-1.ll | 25 +- test/CodeGen/PowerPC/atomic-2.ll | 25 +- test/CodeGen/PowerPC/cr1eq.ll | 18 + test/CodeGen/PowerPC/trampoline.ll | 6 +- test/CodeGen/Thumb/2011-05-11-DAGLegalizer.ll | 6 +- test/CodeGen/Thumb/barrier.ll | 14 +- test/CodeGen/Thumb/iabs.ll | 11 +- test/CodeGen/Thumb2/2009-12-01-LoopIVUsers.ll | 4 +- .../CodeGen/Thumb2/2010-06-21-TailMergeBug.ll | 18 +- test/CodeGen/Thumb2/machine-licm.ll | 2 +- test/CodeGen/Thumb2/thumb2-barrier.ll | 31 - test/CodeGen/Thumb2/thumb2-bcc.ll | 23 +- test/CodeGen/Thumb2/thumb2-branch.ll | 18 +- test/CodeGen/Thumb2/thumb2-ifcvt1.ll | 8 +- test/CodeGen/Thumb2/thumb2-ldm.ll | 2 +- test/CodeGen/Thumb2/thumb2-mls.ll | 2 +- test/CodeGen/Thumb2/thumb2-mul.ll | 2 +- test/CodeGen/Thumb2/thumb2-sxt-uxt.ll | 29 + test/CodeGen/X86/2006-05-11-InstrSched.ll | 2 +- test/CodeGen/X86/2006-07-19-ATTAsm.ll | 49 - test/CodeGen/X86/2007-05-07-InvokeSRet.ll | 4 + test/CodeGen/X86/2008-01-08-SchedulerCrash.ll | 10 +- test/CodeGen/X86/2008-04-17-CoalescerBug.ll | 6 + .../X86/2008-05-28-LocalRegAllocBug.ll | 6 +- test/CodeGen/X86/2008-08-19-SubAndFetch.ll | 4 +- test/CodeGen/X86/2008-09-18-inline-asm-2.ll | 2 +- test/CodeGen/X86/2008-10-02-Atomics32-2.ll | 969 - test/CodeGen/X86/2009-03-13-PHIElimBug.ll | 4 + test/CodeGen/X86/2009-03-16-PHIElimInLPad.ll | 4 + .../X86/2009-06-05-ScalarToVectorByteMMX.ll | 2 +- .../X86/2009-06-18-movlp-shuffle-register.ll | 3 +- test/CodeGen/X86/2009-09-10-LoadFoldingBug.ll | 4 + test/CodeGen/X86/2009-10-16-Scope.ll | 4 +- .../X86/2009-10-19-atomic-cmp-eflags.ll | 6 +- test/CodeGen/X86/2009-11-25-ImpDefBug.ll | 4 + test/CodeGen/X86/2010-01-08-Atomic64Bug.ll | 8 +- .../X86/2010-04-06-SSEDomainFixCrash.ll | 4 + .../X86/2010-04-30-LocalAlloc-LandingPad.ll | 2 - test/CodeGen/X86/2010-10-08-cmpxchg8b.ll | 4 +- .../X86/2011-08-23-PerformSubCombine128.ll | 18 + test/CodeGen/X86/2011-08-23-Trampoline.ll | 16 + test/CodeGen/X86/2011-08-29-BlockConstant.ll | 34 + test/CodeGen/X86/2011-08-29-InitOrder.ll | 28 + test/CodeGen/X86/2011-09-14-valcoalesce.ll | 174 + test/CodeGen/X86/2011-09-18-sse2cmp.ll | 12 + test/CodeGen/X86/2011-09-21-setcc-bug.ll | 27 + test/CodeGen/X86/2011-10-11-SpillDead.ll | 19 + test/CodeGen/X86/2011-10-11-srl.ll | 11 + test/CodeGen/X86/2011-10-12-MachineCSE.ll | 116 + test/CodeGen/X86/Atomics-32.ll | 818 - test/CodeGen/X86/Atomics-64.ll | 1909 +- test/CodeGen/X86/MachineSink-DbgValue.ll | 49 + test/CodeGen/X86/MachineSink-eflags.ll | 74 + test/CodeGen/X86/SIMD/dg.exp | 5 - test/CodeGen/X86/SIMD/notvunpcklpd.ll | 20 - test/CodeGen/X86/SIMD/notvunpcklps.ll | 20 - test/CodeGen/X86/SIMD/vunpcklpd.ll | 20 - test/CodeGen/X86/SIMD/vunpcklps.ll | 20 - test/CodeGen/X86/alignment-2.ll | 28 + test/CodeGen/X86/alignment.ll | 2 +- test/CodeGen/X86/asm-label2.ll | 4 + test/CodeGen/X86/atomic-load-store-wide.ll | 19 + test/CodeGen/X86/atomic-load-store.ll | 23 + test/CodeGen/X86/atomic-or.ll | 12 +- test/CodeGen/X86/atomic_add.ll | 116 +- test/CodeGen/X86/atomic_op.ll | 62 +- test/CodeGen/X86/avx-256-arith.s | 0 test/CodeGen/X86/avx-256.ll | 15 - .../X86/{avx-256-arith.ll => avx-arith.ll} | 145 + test/CodeGen/X86/avx-basic.ll | 107 + test/CodeGen/X86/avx-bitcast.ll | 10 + test/CodeGen/X86/avx-blend.ll | 104 + test/CodeGen/X86/avx-cast.ll | 47 + test/CodeGen/X86/avx-cmp.ll | 150 + test/CodeGen/X86/{avx-128.ll => avx-cvt.ll} | 63 +- test/CodeGen/X86/avx-load-store.ll | 85 +- .../X86/{avx-256-logic.ll => avx-logic.ll} | 18 + test/CodeGen/X86/avx-minmax.ll | 65 + test/CodeGen/X86/avx-movdup.ll | 34 + test/CodeGen/X86/avx-select.ll | 22 + test/CodeGen/X86/avx-shift.ll | 75 + test/CodeGen/X86/avx-shuffle.ll | 10 + test/CodeGen/X86/avx-splat.ll | 103 + test/CodeGen/X86/avx-unpack.ll | 89 + test/CodeGen/X86/avx-vbroadcast.ll | 94 + test/CodeGen/X86/avx-vextractf128.ll | 18 + test/CodeGen/X86/avx-vinsertf128.ll | 58 + test/CodeGen/X86/avx-vmovddup.ll | 14 + test/CodeGen/X86/avx-vperm2f128.ll | 62 + test/CodeGen/X86/avx-vpermil.ll | 45 + test/CodeGen/X86/avx-vshufp.ll | 29 + test/CodeGen/X86/avx-vzeroupper.ll | 26 + test/CodeGen/X86/barrier-sse.ll | 18 +- test/CodeGen/X86/barrier.ll | 5 +- test/CodeGen/X86/bmi.ll | 53 + test/CodeGen/X86/bswap.ll | 2 +- test/CodeGen/X86/change-compare-stride-0.ll | 5 +- test/CodeGen/X86/change-compare-stride-1.ll | 5 +- test/CodeGen/X86/cmov.ll | 4 +- test/CodeGen/X86/cmpxchg16b.ll | 13 + test/CodeGen/X86/coalescer-dce.ll | 80 + test/CodeGen/X86/coalescer-remat.ll | 12 +- test/CodeGen/X86/code_placement_eh.ll | 10 +- test/CodeGen/X86/crash-nosse.ll | 27 + test/CodeGen/X86/crash.ll | 75 + test/CodeGen/X86/dbg-at-specficiation.ll | 20 + test/CodeGen/X86/dbg-inline.ll | 140 + test/CodeGen/X86/dbg-large-unsigned-const.ll | 61 + test/CodeGen/X86/dbg-value-isel.ll | 4 +- test/CodeGen/X86/extractelement-load.ll | 20 +- test/CodeGen/X86/fast-isel-atomic.ll | 6 +- test/CodeGen/X86/fast-isel-cmp-branch.ll | 4 + test/CodeGen/X86/fast-isel-gep.ll | 30 + test/CodeGen/X86/fast-isel-tls.ll | 18 +- test/CodeGen/X86/fast-isel-x86-64.ll | 25 +- test/CodeGen/X86/fp-stack-O0-crash.ll | 21 +- test/CodeGen/X86/global-sections.ll | 2 +- test/CodeGen/X86/haddsub.ll | 194 + test/CodeGen/X86/hidden-vis.ll | 19 +- test/CodeGen/X86/inline-asm-fpstack.ll | 11 + test/CodeGen/X86/iv-users-in-other-loops.ll | 6 +- test/CodeGen/X86/lfence.ll | 6 +- test/CodeGen/X86/licm-dominance.ll | 36 + test/CodeGen/X86/licm-nested.ll | 2 +- test/CodeGen/X86/lock-inst-encoding.ll | 43 +- test/CodeGen/X86/loop-strength-reduce3.ll | 4 +- test/CodeGen/X86/lzcnt.ll | 38 + test/CodeGen/X86/membarrier.ll | 9 +- test/CodeGen/X86/mfence.ll | 16 +- test/CodeGen/X86/movbe.ll | 36 + test/CodeGen/X86/movgs.ll | 2 +- .../X86/{2011-05-31-movmsk.ll => movmsk.ll} | 31 + test/CodeGen/X86/nofence.ll | 27 - test/CodeGen/X86/norex-subreg.ll | 80 + test/CodeGen/X86/opt-shuff-tstore.ll | 39 + test/CodeGen/X86/or-address.ll | 8 +- test/CodeGen/X86/palignr.ll | 31 +- test/CodeGen/X86/personality.ll | 10 +- test/CodeGen/X86/pr10420.ll | 21 + test/CodeGen/X86/pr3495.ll | 8 +- test/CodeGen/X86/pr3522.ll | 4 + test/CodeGen/X86/ptr-rotate.ll | 11 + test/CodeGen/X86/scev-interchange.ll | 44 + test/CodeGen/X86/segmented-stacks.ll | 87 + test/CodeGen/X86/sfence.ll | 6 +- test/CodeGen/X86/sink-hoist.ll | 10 +- test/CodeGen/X86/split-eh-lpad-edges.ll | 4 + test/CodeGen/X86/split-vector-bitcast.ll | 12 + test/CodeGen/X86/sse-minmax.ll | 38 +- test/CodeGen/X86/sse2-blend.ll | 55 + test/CodeGen/X86/sse41-blend.ll | 82 + test/CodeGen/X86/sub.ll | 11 + test/CodeGen/X86/tail-call-got.ll | 24 + test/CodeGen/X86/tlv-1.ll | 17 + test/CodeGen/X86/trunc-ext-ld-st.ll | 82 + test/CodeGen/X86/twoaddr-sink-terminator.ll | 43 + test/CodeGen/X86/uint64-to-float.ll | 33 +- test/CodeGen/X86/uint_to_fp-2.ll | 31 +- test/CodeGen/X86/v2f32.ll | 2 +- test/CodeGen/X86/vec_compare-sse4.ll | 35 + test/CodeGen/X86/vec_set-C.ll | 6 +- test/CodeGen/X86/vec_shuffle-37.ll | 24 +- test/CodeGen/X86/vec_shuffle-38.ll | 59 + test/CodeGen/X86/widen_shuffle-1.ll | 8 + .../XCore/2011-08-01-DynamicAllocBug.ll | 20 + test/CodeGen/XCore/2011-08-01-VarargsBug.ll | 17 + test/CodeGen/XCore/licm-ldwcp.ll | 18 + test/CodeGen/XCore/misc-intrinsics.ll | 48 + test/CodeGen/XCore/resources.ll | 41 + test/CodeGen/XCore/trampoline.ll | 6 +- test/DebugInfo/2009-01-15-member.ll | 30 - ...2009-10-08-DebugInfo-NullGlobalVariable.ll | 72 - .../2009-11-05-DeadGlobalVariable.ll | 29 +- .../2009-11-06-InvalidDerivedType.ll | 13 - .../2009-11-06-NamelessGlobalVariable.ll | 15 +- test/DebugInfo/2009-11-10-CurrentFn.ll | 42 +- test/DebugInfo/2009-11-10-ParentScope.ll | 26 - test/DebugInfo/2010-01-05-DbgScope.ll | 2 +- .../DebugInfo/2010-06-29-InlinedFnLocalVar.ll | 5 +- test/DebugInfo/2011-09-26-GlobalVarContext.ll | 47 + .../ExecutionEngine/2003-01-04-ArgumentBug.ll | 1 + test/ExecutionEngine/2003-01-04-LoopTest.ll | 1 + .../2003-01-15-AlignmentTest.ll | 1 + .../2003-05-06-LivenessClobber.ll | 1 + .../2003-05-07-ArgumentTest.ll | 1 + .../2003-08-15-AllocaAssertion.ll | 1 + .../2003-08-21-EnvironmentTest.ll | 1 + .../2003-08-23-RegisterAllocatePhysReg.ll | 1 + ...8-PHINode-ConstantExpr-CondCode-Failure.ll | 1 + test/ExecutionEngine/hello.ll | 1 + test/ExecutionEngine/hello2.ll | 1 + test/ExecutionEngine/simpletest.ll | 1 + test/ExecutionEngine/stubs.ll | 1 + test/ExecutionEngine/test-loadstore.ll | 1 + test/Feature/callingconventions.ll | 31 +- test/Feature/calltest.ll | 30 +- test/Feature/exception.ll | 27 + test/FrontendAda/Support/element_copy.ads | 8 - test/FrontendAda/Support/fat_fields.ads | 6 - test/FrontendAda/Support/global_constant.ads | 4 - test/FrontendAda/Support/non_lvalue.ads | 11 - test/FrontendAda/Support/real_cst.ads | 4 - test/FrontendAda/Support/unc_constructor.ads | 8 - test/FrontendAda/Support/var_offset.ads | 9 - test/FrontendAda/Support/var_size.ads | 7 - test/FrontendAda/array_constructor.adb | 6 - test/FrontendAda/array_range_ref.adb | 7 - test/FrontendAda/array_ref.adb | 11 - test/FrontendAda/array_size.adb | 10 - test/FrontendAda/asm.adb | 6 - test/FrontendAda/constant_fold.ads | 4 - test/FrontendAda/debug_var_size.ads | 8 - test/FrontendAda/dg.exp | 6 - test/FrontendAda/element_copy.adb | 8 - test/FrontendAda/emit_var.ads | 5 - test/FrontendAda/fat_fields.adb | 10 - test/FrontendAda/field_order.ads | 7 - test/FrontendAda/global_constant.adb | 5 - test/FrontendAda/init_size.ads | 12 - test/FrontendAda/negative_field_offset.adb | 16 - test/FrontendAda/non_bitfield.ads | 12 - test/FrontendAda/non_lvalue.adb | 7 - test/FrontendAda/placeholder.adb | 12 - test/FrontendAda/real_cst.adb | 8 - test/FrontendAda/switch.adb | 12 - test/FrontendAda/unc_constructor.adb | 9 - test/FrontendAda/var_offset.adb | 7 - test/FrontendAda/var_size.adb | 7 - test/FrontendAda/vce.adb | 7 - test/FrontendAda/vce_lv.adb | 9 - test/FrontendC++/2003-11-02-WeakLinkage.cpp | 13 - .../2003-11-18-PtrMemConstantInitializer.cpp | 14 - .../2003-11-25-ReturningOpaqueByValue.cpp | 12 - .../2003-11-27-MultipleInheritanceThunk.cpp | 28 - .../2003-11-29-DuplicatedCleanupTest.cpp | 41 - .../2003-12-08-ArrayOfPtrToMemberFunc.cpp | 12 - .../2004-01-11-DynamicInitializedConstant.cpp | 6 - .../2004-03-08-ReinterpretCastCopy.cpp | 21 - .../2004-03-09-UnmangledBuiltinMethods.cpp | 8 - .../2004-03-15-CleanupsAndGotos.cpp | 14 - .../2004-06-08-LateTemplateInstantiation.cpp | 19 - test/FrontendC++/2004-09-27-CompilerCrash.cpp | 13 - .../2004-09-27-DidntEmitTemplate.cpp | 23 - .../2004-11-27-EmitsUnusedInlineFunctions.cpp | 7 - .../2004-11-27-ExceptionCleanupAssertion.cpp | 14 - .../2004-11-27-FriendDefaultArgCrash.cpp | 9 - ...04-11-27-InlineAsmFunctionRedefinition.cpp | 26 - .../2005-01-03-StaticInitializers.cpp | 8 - .../FrontendC++/2005-02-11-AnonymousUnion.cpp | 32 - .../FrontendC++/2005-02-13-BadDynamicInit.cpp | 9 - .../FrontendC++/2005-02-14-BitFieldOffset.cpp | 11 - .../2005-02-19-BitfieldStructCrash.cpp | 14 - ...2005-02-19-UnnamedVirtualThunkArgument.cpp | 22 - .../2005-02-20-BrokenReferenceTest.cpp | 11 - .../2005-02-27-PlacementArrayNewCrash.cpp | 8 - .../2005-07-21-VirtualBaseAccess.cpp | 14 - test/FrontendC++/2006-03-01-GimplifyCrash.cpp | 14 - .../2006-03-06-C++RecurseCrash.cpp | 24 - test/FrontendC++/2006-09-08-powi.cpp | 7 - .../2006-09-12-OpaqueStructCrash.cpp | 28 - .../2006-09-27-Debug-Protection.cpp | 12 - test/FrontendC++/2006-10-30-ClassBitfield.cpp | 16 - test/FrontendC++/2006-11-06-StackTrace.cpp | 38 - test/FrontendC++/2006-11-20-GlobalSymbols.cpp | 10 - .../2006-11-30-ConstantExprCrash.cpp | 27 - test/FrontendC++/2006-11-30-Pubnames.cpp | 22 - .../FrontendC++/2007-01-02-UnboundedArray.cpp | 14 - .../2007-01-06-ELF-Thunk-Sections.cpp | 49 - test/FrontendC++/2007-01-06-PtrMethodInit.cpp | 75 - .../2007-03-27-FunctionVarRename.cpp | 17 - .../2007-04-05-PackedBitFields-1.cpp | 23 - .../2007-04-05-PackedBitFieldsOverlap-2.cpp | 24 - .../2007-04-05-PackedBitFieldsOverlap.cpp | 24 - .../2007-04-05-PackedBitFieldsSmall.cpp | 27 - .../2007-04-05-StructPackedFieldUnpacked.cpp | 25 - test/FrontendC++/2007-04-10-PackedUnion.cpp | 41 - .../2007-04-11-InlineStorageClassC++.cpp | 44 - test/FrontendC++/2007-04-14-FNoBuiltin.cpp | 7 - test/FrontendC++/2007-04-31-TryCatch.cpp | 12 - test/FrontendC++/2007-05-03-VectorInit.cpp | 17 - .../2007-05-16-ReverseBitFieldCrash.cpp | 24 - test/FrontendC++/2007-05-23-TryFinally.cpp | 16 - test/FrontendC++/2007-07-04-NestedCatches.cpp | 32 - .../FrontendC++/2007-07-29-RestrictPtrArg.cpp | 6 - .../FrontendC++/2007-07-29-RestrictRefArg.cpp | 6 - .../FrontendC++/2007-08-01-RestrictMethod.cpp | 13 - .../2007-09-10-RecursiveTypeResolution.cpp | 88 - test/FrontendC++/2007-10-01-StructResize.cpp | 14 - test/FrontendC++/2008-01-11-BadWarning.cpp | 6 - test/FrontendC++/2008-01-12-VecInit.cpp | 6 - test/FrontendC++/2008-05-07-CrazyOffsetOf.cpp | 8 - test/FrontendC++/2008-10-29-WrongOffset.cpp | 489 - .../2009-02-07-VolatileArrayRefHack.cpp | 7 - test/FrontendC++/2009-02-16-CtorNames-dbg.cpp | 10 - test/FrontendC++/2009-03-17-dbg.cpp | 16 - test/FrontendC++/2009-04-21-DtorNames-dbg.cpp | 32 - test/FrontendC++/2009-04-23-bool2.cpp | 15 - .../2009-05-04-PureConstNounwind.cpp | 8 - .../FrontendC++/2009-06-16-DebugInfoCrash.cpp | 10 - .../2009-06-20-DarwinPPCLayout.cpp | 32 - test/FrontendC++/2009-06-30-ByrefBlock.cpp | 11 - .../2009-07-16-PrivateCopyConstructor.cpp | 15 - test/FrontendC++/2009-07-16-Using.cpp | 8 - test/FrontendC++/2009-08-05-ZeroInitWidth.cpp | 12 - test/FrontendC++/2009-08-11-VectorRetTy.cpp | 13 - test/FrontendC++/2009-09-04-modify-crash.cpp | 7 - test/FrontendC++/2009-09-09-packed-layout.cpp | 18 - test/FrontendC++/2009-10-27-crash.cpp | 43 - test/FrontendC++/2009-12-23-MissingSext.cpp | 16 - .../2010-02-17-DbgArtificialArg.cpp | 16 - .../2010-03-22-empty-baseclass.cpp | 134 - .../2010-04-30-OptimizedMethod-Dbg.cpp | 18 - test/FrontendC++/2010-05-10-Var-DbgInfo.cpp | 43 - .../2010-05-11-alwaysinlineinstantiation.cpp | 31 - .../2010-05-12-PtrToMember-Dbg.cpp | 17 - test/FrontendC++/2010-06-21-LocalVarDbg.cpp | 13 - test/FrontendC++/2010-06-22-BitfieldInit.cpp | 20 - test/FrontendC++/2010-06-22-ZeroBitfield.cpp | 5 - test/FrontendC++/2010-07-19-nowarn.cpp | 21 - test/FrontendC++/2010-07-23-DeclLoc.cpp | 86 - test/FrontendC++/2010-08-31-ByValArg.cpp | 53 - test/FrontendC++/alignstack.cpp | 23 - test/FrontendC++/dg.exp | 5 - test/FrontendC++/integration-O2.cpp | 19 - test/FrontendC++/m64-ptr.cpp | 19 - test/FrontendC++/member-alignment.cpp | 20 - test/FrontendC++/ptr-to-method-devirt.cpp | 14 - test/FrontendC++/thunk-linkonce-odr.cpp | 33 - test/FrontendC++/varargs.cpp | 19 - test/FrontendC++/weak-external.cpp | 17 - .../x86-64-abi-sret-vs-2word-struct-param.cpp | 27 - .../2002-01-23-LoadQISIReloadFailure.c | 11 - .../FrontendC/2002-01-24-ComplexSpaceInType.c | 11 - .../FrontendC/2002-01-24-HandleCallInsnSEGV.c | 9 - test/FrontendC/2002-02-13-ConditionalInCall.c | 11 - test/FrontendC/2002-02-13-ReloadProblem.c | 18 - .../2002-02-13-TypeVarNameCollision.c | 16 - test/FrontendC/2002-02-13-UnnamedLocal.c | 21 - test/FrontendC/2002-02-14-EntryNodePreds.c | 37 - test/FrontendC/2002-02-16-RenamingTest.c | 18 - test/FrontendC/2002-02-17-ArgumentAddress.c | 39 - test/FrontendC/2002-02-18-64bitConstant.c | 10 - test/FrontendC/2002-02-18-StaticData.c | 13 - test/FrontendC/2002-03-11-LargeCharInString.c | 10 - .../2002-03-12-ArrayInitialization.c | 19 - test/FrontendC/2002-03-12-StructInitialize.c | 14 - test/FrontendC/2002-03-12-StructInitializer.c | 18 - test/FrontendC/2002-03-14-BrokenPHINode.c | 19 - test/FrontendC/2002-03-14-BrokenSSA.c | 17 - test/FrontendC/2002-03-14-QuotesInStrConst.c | 10 - test/FrontendC/2002-04-07-SwitchStmt.c | 22 - test/FrontendC/2002-04-08-LocalArray.c | 14 - test/FrontendC/2002-04-09-StructRetVal.c | 12 - test/FrontendC/2002-04-10-StructParameters.c | 25 - test/FrontendC/2002-05-23-StaticValues.c | 15 - test/FrontendC/2002-05-23-TypeNameCollision.c | 19 - test/FrontendC/2002-05-24-Alloca.c | 11 - .../2002-06-25-FWriteInterfaceFailure.c | 7 - test/FrontendC/2002-07-14-MiscListTests.c | 71 - test/FrontendC/2002-07-14-MiscTests.c | 57 - test/FrontendC/2002-07-14-MiscTests2.c | 13 - test/FrontendC/2002-07-14-MiscTests3.c | 187 - test/FrontendC/2002-07-16-HardStringInit.c | 8 - test/FrontendC/2002-07-17-StringConstant.c | 4 - test/FrontendC/2002-07-29-Casts.c | 86 - .../FrontendC/2002-07-30-SubregSetAssertion.c | 12 - test/FrontendC/2002-07-30-UnionTest.c | 22 - .../FrontendC/2002-07-30-VarArgsCallFailure.c | 8 - test/FrontendC/2002-07-31-BadAssert.c | 16 - test/FrontendC/2002-07-31-SubregFailure.c | 14 - test/FrontendC/2002-08-02-UnionTest.c | 19 - test/FrontendC/2002-08-19-RecursiveLocals.c | 18 - test/FrontendC/2002-09-08-PointerShifts.c | 6 - test/FrontendC/2002-09-18-UnionProblem.c | 26 - test/FrontendC/2002-09-19-StarInLabel.c | 9 - test/FrontendC/2002-10-12-TooManyArguments.c | 8 - test/FrontendC/2002-12-15-GlobalBoolTest.c | 5 - .../FrontendC/2002-12-15-GlobalConstantTest.c | 8 - .../FrontendC/2002-12-15-GlobalRedefinition.c | 5 - test/FrontendC/2002-12-15-StructParameters.c | 18 - test/FrontendC/2003-01-30-UnionInit.c | 8 - test/FrontendC/2003-03-03-DeferredType.c | 12 - test/FrontendC/2003-06-22-UnionCrash.c | 13 - .../2003-06-23-GCC-fold-infinite-recursion.c | 6 - test/FrontendC/2003-06-26-CFECrash.c | 19 - .../2003-06-29-MultipleFunctionDefinition.c | 8 - .../2003-07-22-ArrayAccessTypeSafety.c | 7 - .../2003-08-06-BuiltinSetjmpLongjmp.c | 14 - .../2003-08-17-DeadCodeShortCircuit.c | 7 - test/FrontendC/2003-08-18-SigSetJmp.c | 10 - test/FrontendC/2003-08-18-StructAsValue.c | 11 - test/FrontendC/2003-08-20-BadBitfieldRef.c | 8 - test/FrontendC/2003-08-20-PrototypeMismatch.c | 15 - test/FrontendC/2003-08-20-vfork-bug.c | 6 - .../2003-08-21-BinOp-Type-Mismatch.c | 10 - test/FrontendC/2003-08-21-StmtExpr.c | 12 - test/FrontendC/2003-08-21-WideString.c | 7 - test/FrontendC/2003-08-23-LocalUnionTest.c | 11 - test/FrontendC/2003-08-29-BitFieldStruct.c | 13 - test/FrontendC/2003-08-29-HugeCharConst.c | 5 - test/FrontendC/2003-08-29-StructLayoutBug.c | 10 - .../2003-08-30-AggregateInitializer.c | 16 - .../2003-08-30-LargeIntegerBitfieldMember.c | 9 - test/FrontendC/2003-09-18-BitfieldTests.c | 30 - test/FrontendC/2003-09-30-StructLayout.c | 18 - test/FrontendC/2003-10-02-UnionLValueError.c | 13 - test/FrontendC/2003-10-06-NegateExprType.c | 8 - .../2003-10-09-UnionInitializerBug.c | 17 - test/FrontendC/2003-10-28-ident.c | 4 - test/FrontendC/2003-10-29-AsmRename.c | 22 - .../2003-11-01-C99-CompoundLiteral.c | 8 - test/FrontendC/2003-11-01-EmptyStructCrash.c | 6 - test/FrontendC/2003-11-01-GlobalUnionInit.c | 7 - test/FrontendC/2003-11-03-AddrArrayElement.c | 11 - test/FrontendC/2003-11-04-EmptyStruct.c | 6 - test/FrontendC/2003-11-04-OutOfMemory.c | 9 - .../2003-11-08-PointerSubNotGetelementptr.c | 9 - test/FrontendC/2003-11-12-VoidString.c | 4 - test/FrontendC/2003-11-13-TypeSafety.c | 5 - test/FrontendC/2003-11-16-StaticArrayInit.c | 8 - test/FrontendC/2003-11-18-CondExprLValue.c | 9 - test/FrontendC/2003-11-19-AddressOfRegister.c | 12 - test/FrontendC/2003-11-19-BitFieldArray.c | 12 - test/FrontendC/2003-11-20-Bitfields.c | 12 - test/FrontendC/2003-11-20-ComplexDivision.c | 7 - test/FrontendC/2003-11-20-UnionBitfield.c | 12 - test/FrontendC/2003-11-26-PointerShift.c | 6 - test/FrontendC/2003-11-27-ConstructorCast.c | 14 - .../2003-11-27-UnionCtorInitialization.c | 16 - .../2003-12-14-ExternInlineSupport.c | 3 - test/FrontendC/2004-01-01-UnknownInitSize.c | 14 - .../2004-01-08-ExternInlineRedefine.c | 14 - .../FrontendC/2004-02-12-LargeAggregateCopy.c | 8 - .../2004-02-13-BuiltinFrameReturnAddress.c | 8 - test/FrontendC/2004-02-13-IllegalVararg.c | 13 - test/FrontendC/2004-02-13-Memset.c | 9 - test/FrontendC/2004-02-14-ZeroInitializer.c | 4 - test/FrontendC/2004-02-20-Builtins.c | 8 - test/FrontendC/2004-03-07-ComplexDivEquals.c | 6 - test/FrontendC/2004-03-07-ExternalConstant.c | 7 - .../2004-03-09-LargeArrayInitializers.c | 32 - .../FrontendC/2004-03-15-SimpleIndirectGoto.c | 23 - test/FrontendC/2004-03-16-AsmRegisterCrash.c | 10 - test/FrontendC/2004-05-07-VarArrays.c | 5 - test/FrontendC/2004-05-21-IncompleteEnum.c | 5 - test/FrontendC/2004-06-08-OpaqueStructArg.c | 7 - test/FrontendC/2004-06-17-UnorderedBuiltins.c | 24 - test/FrontendC/2004-06-17-UnorderedCompares.c | 21 - ...04-06-18-VariableLengthArrayOfStructures.c | 10 - test/FrontendC/2004-07-06-FunctionCast.c | 10 - test/FrontendC/2004-08-06-LargeStructTest.c | 19 - .../2004-11-25-UnnamedBitfieldPadding.c | 8 - .../2004-11-27-InvalidConstantExpr.c | 10 - .../2004-11-27-StaticFunctionRedeclare.c | 15 - .../2004-11-27-VariableSizeInStructure.c | 11 - test/FrontendC/2005-01-02-ConstantInits.c | 24 - test/FrontendC/2005-01-02-PointerDifference.c | 3 - test/FrontendC/2005-01-02-VAArgError-ICE.c | 10 - test/FrontendC/2005-02-20-AggregateSAVEEXPR.c | 19 - .../FrontendC/2005-02-27-MarkGlobalConstant.c | 10 - test/FrontendC/2005-03-05-OffsetOfHack.c | 12 - .../2005-03-06-OffsetOfStructCrash.c | 14 - test/FrontendC/2005-03-11-Prefetch.c | 6 - test/FrontendC/2005-04-09-ComplexOps.c | 9 - test/FrontendC/2005-05-06-CountBuiltins.c | 17 - test/FrontendC/2005-05-10-GlobalUnionInit.c | 6 - .../2005-06-15-ExpandGotoInternalProblem.c | 14 - test/FrontendC/2005-07-20-SqrtNoErrno.c | 11 - test/FrontendC/2005-07-26-UnionInitCrash.c | 3 - .../2005-07-28-IncorrectWeakGlobal.c | 5 - test/FrontendC/2005-09-20-ComplexConstants.c | 4 - test/FrontendC/2005-09-24-AsmUserPrefix.c | 8 - test/FrontendC/2005-09-24-BitFieldCrash.c | 33 - .../2005-10-18-VariableSizedElementCrash.c | 9 - test/FrontendC/2005-12-04-AttributeUsed.c | 8 - .../2005-12-04-DeclarationLineNumbers.c | 23 - test/FrontendC/2006-01-13-Includes.c | 8 - test/FrontendC/2006-01-13-StackSave.c | 11 - .../2006-01-16-BitCountIntrinsicsUnsigned.c | 9 - test/FrontendC/2006-01-23-FileScopeAsm.c | 8 - .../FrontendC/2006-03-03-MissingInitializer.c | 11 - test/FrontendC/2006-03-16-VectorCtor.c | 10 - test/FrontendC/2006-03-17-KnRMismatch.c | 8 - .../2006-05-01-AppleAlignmentPragma.c | 12 - test/FrontendC/2006-05-19-SingleEltReturn.c | 23 - test/FrontendC/2006-07-31-PR854.c | 11 - test/FrontendC/2006-09-11-BitfieldRefCrash.c | 12 - test/FrontendC/2006-09-18-fwrite-cast-crash.c | 15 - .../2006-09-21-IncompleteElementType.c | 3 - test/FrontendC/2006-09-25-DebugFilename.c | 6 - test/FrontendC/2006-09-25-DebugFilename.h | 6 - test/FrontendC/2006-09-28-SimpleAsm.c | 10 - test/FrontendC/2006-10-30-ArrayCrash.c | 17 - test/FrontendC/2006-12-14-ordered_expr.c | 6 - test/FrontendC/2007-01-06-KNR-Proto.c | 10 - test/FrontendC/2007-01-20-VectorICE.c | 11 - .../FrontendC/2007-01-24-InlineAsmCModifier.c | 10 - test/FrontendC/2007-02-04-AddrLValue-2.c | 13 - test/FrontendC/2007-02-04-AddrLValue.c | 23 - test/FrontendC/2007-02-04-EmptyStruct.c | 9 - test/FrontendC/2007-02-04-WITH_SIZE_EXPR.c | 21 - test/FrontendC/2007-02-05-nested.c | 54 - test/FrontendC/2007-02-07-AddrLabel.c | 10 - .../2007-02-16-VariableSizeStructArg.c | 7 - test/FrontendC/2007-02-16-VoidPtrDiff.c | 5 - test/FrontendC/2007-02-16-WritableStrings.c | 7 - test/FrontendC/2007-02-25-C-DotDotDot.c | 12 - test/FrontendC/2007-03-01-VarSizeArrayIdx.c | 7 - test/FrontendC/2007-03-05-DataLayout.c | 53 - test/FrontendC/2007-03-06-VarSizeInStruct1.c | 8 - test/FrontendC/2007-03-06-VarSizeInStruct2.c | 8 - .../2007-03-26-BitfieldAfterZeroWidth.c | 6 - test/FrontendC/2007-03-26-ZeroWidthBitfield.c | 2 - test/FrontendC/2007-03-27-ArrayCompatible.c | 10 - test/FrontendC/2007-03-27-VarLengthArray.c | 7 - test/FrontendC/2007-04-05-PackedBitFields-2.c | 16 - test/FrontendC/2007-04-05-PackedBitFields.c | 16 - test/FrontendC/2007-04-05-PackedStruct.c | 18 - .../2007-04-05-PadBeforeZeroLengthField.c | 9 - test/FrontendC/2007-04-05-UnPackedStruct.c | 16 - test/FrontendC/2007-04-11-InlineAsmStruct.c | 9 - test/FrontendC/2007-04-11-InlineAsmUnion.c | 7 - .../2007-04-11-InlineStorageClassC89.c | 46 - .../2007-04-11-InlineStorageClassC99.c | 46 - test/FrontendC/2007-04-11-PR1321.c | 12 - test/FrontendC/2007-04-13-InlineAsmStruct2.c | 9 - test/FrontendC/2007-04-13-InlineAsmUnion2.c | 7 - test/FrontendC/2007-04-14-FNoBuiltin.c | 7 - test/FrontendC/2007-04-17-ZeroSizeBitFields.c | 4 - .../FrontendC/2007-04-24-VolatileStructCopy.c | 10 - test/FrontendC/2007-04-24-bit-not-expr.c | 7 - test/FrontendC/2007-04-24-str-const.c | 17 - .../FrontendC/2007-05-07-NestedStructReturn.c | 13 - test/FrontendC/2007-05-07-PaddingElements.c | 12 - test/FrontendC/2007-05-08-PCH.c | 7 - test/FrontendC/2007-05-11-str-const.c | 5 - test/FrontendC/2007-05-15-PaddingElement.c | 23 - test/FrontendC/2007-05-16-EmptyStruct.c | 5 - test/FrontendC/2007-05-29-UnionCopy.c | 18 - test/FrontendC/2007-06-05-NoInlineAttribute.c | 13 - test/FrontendC/2007-06-15-AnnotateAttribute.c | 24 - test/FrontendC/2007-06-18-SextAttrAggregate.c | 11 - test/FrontendC/2007-07-29-RestrictPtrArg.c | 6 - test/FrontendC/2007-08-01-LoadStoreAlign.c | 17 - test/FrontendC/2007-08-21-ComplexCst.c | 3 - test/FrontendC/2007-08-22-CTTZ.c | 6 - test/FrontendC/2007-09-05-ConstCtor.c | 14 - test/FrontendC/2007-09-12-PragmaPack.c | 30 - test/FrontendC/2007-09-14-NegatePointer.c | 7 - test/FrontendC/2007-09-17-WeakRef.c | 10 - test/FrontendC/2007-09-20-GcrootAttribute.c | 29 - test/FrontendC/2007-09-26-Alignment.c | 7 - test/FrontendC/2007-09-27-ComplexIntCompare.c | 17 - test/FrontendC/2007-09-28-PackedUnionMember.c | 38 - test/FrontendC/2007-10-01-BuildArrayRef.c | 20 - test/FrontendC/2007-10-02-VolatileArray.c | 7 - test/FrontendC/2007-10-15-VoidPtr.c | 4 - test/FrontendC/2007-10-30-Volatile.c | 6 - test/FrontendC/2007-11-07-AlignedMemcpy.c | 4 - .../FrontendC/2007-11-07-CopyAggregateAlign.c | 3 - .../FrontendC/2007-11-07-ZeroAggregateAlign.c | 3 - test/FrontendC/2007-11-27-SExtZExt.c | 12 - test/FrontendC/2007-11-28-GlobalInitializer.c | 8 - test/FrontendC/2007-12-16-AsmNoUnwind.c | 3 - test/FrontendC/2007-12-VarArrayDebug.c | 18 - test/FrontendC/2008-01-04-WideBitfield.c | 13 - test/FrontendC/2008-01-07-UnusualIntSize.c | 11 - test/FrontendC/2008-01-11-ChainConsistency.c | 3 - test/FrontendC/2008-01-21-PackedBitFields.c | 7 - test/FrontendC/2008-01-21-PackedStructField.c | 18 - .../2008-01-24-StructAlignAndBitFields.c | 4 - test/FrontendC/2008-01-25-ByValReadNone.c | 15 - .../FrontendC/2008-01-25-ZeroSizedAggregate.c | 39 - test/FrontendC/2008-01-28-PragmaMark.c | 6 - test/FrontendC/2008-01-28-UnionSize.c | 24 - test/FrontendC/2008-02-11-AnnotateBuiltin.c | 7 - test/FrontendC/2008-03-03-CtorAttrType.c | 6 - test/FrontendC/2008-03-05-syncPtr.c | 27 - .../2008-03-24-BitField-And-Alloca.c | 89 - test/FrontendC/2008-03-26-PackedBitFields.c | 7 - test/FrontendC/2008-04-08-NoExceptions.c | 7 - test/FrontendC/2008-05-06-CFECrash.c | 4 - test/FrontendC/2008-05-12-TempUsedBeforeDef.c | 10 - test/FrontendC/2008-05-19-AlwaysInline.c | 12 - test/FrontendC/2008-07-08-FAbsAttributes.c | 4 - test/FrontendC/2008-08-07-AlignPadding1.c | 29 - test/FrontendC/2008-08-07-AlignPadding2.c | 18 - test/FrontendC/2008-08-07-GEPIntToPtr.c | 14 - test/FrontendC/2008-09-03-WeakAlias.c | 9 - test/FrontendC/2008-10-13-FrontendCrash.c | 9 - test/FrontendC/2008-10-30-ZeroPlacement.c | 9 - test/FrontendC/2008-11-02-WeakAlias.c | 5 - test/FrontendC/2008-11-08-InstCombineSelect.c | 17 - .../2008-11-11-AnnotateStructFieldAttribute.c | 18 - test/FrontendC/2008-12-23-AsmIntPointerTie.c | 9 - test/FrontendC/2009-01-05-BlockInlining.c | 28 - test/FrontendC/2009-01-20-k8.c | 4 - test/FrontendC/2009-01-21-InvalidIterator.c | 74 - .../2009-02-13-zerosize-union-field-ppc.c | 14 - .../2009-02-13-zerosize-union-field.c | 14 - test/FrontendC/2009-02-17-BitField-dbg.c | 14 - test/FrontendC/2009-03-01-MallocNoAlias.c | 3 - .../FrontendC/2009-03-08-ZeroEltStructCrash.c | 14 - .../FrontendC/2009-03-09-WeakDeclarations-1.c | 22 - test/FrontendC/2009-03-13-dbg.c | 5 - test/FrontendC/2009-04-22-UnknownSize.c | 4 - test/FrontendC/2009-04-28-UnionArrayCrash.c | 11 - test/FrontendC/2009-05-04-EnumInreg.c | 18 - test/FrontendC/2009-05-17-AlwaysInline.c | 17 - test/FrontendC/2009-06-14-HighlyAligned.c | 8 - .../2009-06-18-StaticInitTailPadPack.c | 26 - test/FrontendC/2009-07-14-VoidPtr.c | 6 - test/FrontendC/2009-07-15-pad-wchar_t-array.c | 7 - test/FrontendC/2009-07-17-VoidParameter.c | 4 - test/FrontendC/2009-07-22-StructLayout.c | 34 - .../2009-08-11-AsmBlocksComplexJumpTarget.c | 10 - test/FrontendC/2009-09-24-SqrtErrno.c | 12 - test/FrontendC/2009-12-07-BitFieldAlignment.c | 15 - test/FrontendC/2010-01-05-LinkageName.c | 15 - test/FrontendC/2010-01-13-MemBarrier.c | 11 - test/FrontendC/2010-01-14-FnType-DebugInfo.c | 4 - test/FrontendC/2010-01-14-StaticVariable.c | 12 - test/FrontendC/2010-01-18-Inlined-Debug.c | 12 - test/FrontendC/2010-02-10-PointerName.c | 7 - test/FrontendC/2010-02-15-DbgStaticVar.c | 13 - test/FrontendC/2010-02-16-DbgVarScope.c | 30 - test/FrontendC/2010-02-18-Dbg-VectorType.c | 9 - test/FrontendC/2010-03-10-arm-asmreg.c | 15 - test/FrontendC/2010-03-5-LexicalScope.c | 10 - test/FrontendC/2010-05-14-Optimized-VarType.c | 23 - test/FrontendC/2010-05-18-asmsched.c | 18 - test/FrontendC/2010-05-18-palignr.c | 24 - test/FrontendC/2010-05-26-AsmSideEffect.c | 12 - test/FrontendC/2010-05-31-palignr.c | 24 - test/FrontendC/2010-06-11-SaveExpr.c | 8 - test/FrontendC/2010-06-17-asmcrash.c | 16 - test/FrontendC/2010-06-28-DbgLocalVar.c | 14 - test/FrontendC/2010-06-28-nowarn.c | 21 - test/FrontendC/2010-07-08-DeclDebugLineNo.c | 10 - .../2010-07-14-overconservative-align.c | 14 - test/FrontendC/2010-07-14-ref-off-end.c | 27 - test/FrontendC/2010-07-27-MinNoFoldConst.c | 18 - test/FrontendC/2010-08-12-asm-aggr-arg.c | 16 - test/FrontendC/2010-11-16-asmblock.c | 16 - test/FrontendC/2010-12-01-CommonGlobal.c | 7 - test/FrontendC/2011-02-21-DATA-common.c | 5 - test/FrontendC/2011-03-02-UnionInitializer.c | 2 - .../2011-03-08-ZeroFieldUnionInitializer.c | 7 - test/FrontendC/2011-03-31-ArrayRefFolding.c | 15 - test/FrontendC/ARM/dg.exp | 5 - test/FrontendC/ARM/inline-asm-multichar.c | 11 - test/FrontendC/Atomics-no64bit.c | 190 - test/FrontendC/Atomics.c | 236 - test/FrontendC/BasicInstrs.c | 26 - test/FrontendC/alignstack.c | 23 - test/FrontendC/always-inline.c | 12 - test/FrontendC/arrayderef.c | 17 - test/FrontendC/asm-reg-var-local.c | 32 - test/FrontendC/attribute_constructor.c | 6 - test/FrontendC/block-copy.c | 20 - test/FrontendC/crash-invalid-array.c | 17 - test/FrontendC/dg.exp | 5 - test/FrontendC/exact-div-expr.c | 6 - test/FrontendC/extern-weak.c | 12 - test/FrontendC/fp-logical.c | 15 - test/FrontendC/func-aligned.c | 7 - test/FrontendC/funccall.c | 17 - test/FrontendC/hidden-visibility.c | 3 - test/FrontendC/implicit-arg.c | 10 - test/FrontendC/inline-asm-function.c | 6 - test/FrontendC/inline-asm-mrv.c | 12 - test/FrontendC/libcalls-d.c | 14 - test/FrontendC/libcalls-ld.c | 17 - test/FrontendC/libcalls.c | 14 - test/FrontendC/misaligned-param.c | 15 - test/FrontendC/mmx-inline-asm.c | 24 - test/FrontendC/nested-functions.c | 18 - test/FrontendC/pr2394.c | 6 - test/FrontendC/pr3518.c | 24 - test/FrontendC/pr4349.c | 38 - test/FrontendC/pr5406.c | 20 - test/FrontendC/ptr-rotate.c | 7 - test/FrontendC/redef-ext-inline.c | 6 - test/FrontendC/sret.c | 15 - test/FrontendC/sret2.c | 9 - test/FrontendC/struct-matching-constraint.c | 19 - test/FrontendC/unaligned-memcpy.c | 5 - test/FrontendC/union-align.c | 17 - test/FrontendC/vla-1.c | 9 - test/FrontendC/vla-2.c | 10 - test/FrontendC/vla-3.c | 11 - test/FrontendC/wchar-const.c | 9 - test/FrontendC/weak_constant.c | 12 - .../2008-11-03-OptionOverride.f90 | 4 - .../2009-02-09-FloorDivExpr.f90 | 32 - test/FrontendFortran/cpow.f90 | 18 - test/FrontendFortran/dg.exp | 6 - .../2007-10-03-MetadataPointers.mm | 7 - .../2010-08-02-NonPODObjectValue.mm | 27 - test/FrontendObjC++/2010-08-04-Template.mm | 10 - test/FrontendObjC++/2010-08-06-X.Y-syntax.mm | 16 - test/FrontendObjC++/dg.exp | 5 - test/FrontendObjC/2007-04-03-ObjcEH.m | 29 - test/FrontendObjC/2007-05-02-Strong.m | 23 - test/FrontendObjC/2007-09-25-EH.m | 27 - test/FrontendObjC/2007-10-17-SJLJExceptions.m | 24 - test/FrontendObjC/2007-10-18-ProDescriptor.m | 19 - .../FrontendObjC/2007-10-23-GC-WriteBarrier.m | 9 - test/FrontendObjC/2008-10-3-EhValue.m | 50 - test/FrontendObjC/2008-11-12-Metadata.m | 14 - test/FrontendObjC/2008-11-24-ConstCFStrings.m | 11 - test/FrontendObjC/2008-11-25-Blocks.m | 17 - test/FrontendObjC/2009-01-26-WriteBarrier-2.m | 14 - test/FrontendObjC/2009-02-05-VolatileProp.m | 11 - test/FrontendObjC/2009-04-14-AsmSection.m | 9 - .../2009-04-27-bitfield-vs-ivar.m | 44 - .../FrontendObjC/2009-04-28-bitfield-vs-vbc.m | 127 - test/FrontendObjC/2009-08-05-utf16.m | 5 - test/FrontendObjC/2009-08-17-DebugInfo.m | 28 - test/FrontendObjC/2009-11-30-Objc-ID.m | 14 - .../FrontendObjC/2010-02-01-utf16-with-null.m | 5 - .../2010-02-11-fwritable-stringsBug.m | 17 - test/FrontendObjC/2010-02-23-DbgInheritance.m | 9 - test/FrontendObjC/2010-03-17-StructRef.m | 43 - .../2010-06-04-UnnamedCFString-dbg.m | 6 - .../2011-03-02-ConstCFStringLiteralAlign.m | 11 - test/FrontendObjC/2011-03-08-IVarLookup.m | 32 - test/FrontendObjC/dg.exp | 5 - test/LLVMC/Alias.td | 24 - test/LLVMC/AppendCmdHook.td | 29 - test/LLVMC/C++/dash-x.cpp | 10 - test/LLVMC/C++/dg.exp | 5 - test/LLVMC/C++/filelist.cpp | 3 - test/LLVMC/C++/hello.cpp | 9 - test/LLVMC/C++/just-compile.cpp | 10 - test/LLVMC/C++/together.cpp | 10 - test/LLVMC/C++/unknown_suffix.unk | 9 - test/LLVMC/C/dg.exp | 5 - test/LLVMC/C/emit-llvm-opt.c | 9 - test/LLVMC/C/emit-llvm.c | 8 - test/LLVMC/C/hello.c | 13 - test/LLVMC/C/include.c | 10 - test/LLVMC/C/opt-test.c | 13 - test/LLVMC/C/sink.c | 13 - test/LLVMC/C/wall.c | 13 - test/LLVMC/EmptyCompilationGraph.td | 8 - test/LLVMC/EnvParentheses.td | 18 - test/LLVMC/ForwardAs.td | 21 - test/LLVMC/ForwardTransformedValue.td | 27 - test/LLVMC/ForwardValue.td | 24 - test/LLVMC/HookWithArguments.td | 20 - test/LLVMC/HookWithInFile.td | 16 - test/LLVMC/Init.td | 25 - test/LLVMC/LanguageMap.td | 29 - test/LLVMC/MultiValuedOption.td | 24 - test/LLVMC/MultipleCompilationGraphs.td | 10 - test/LLVMC/MultipleOutputLanguages.td | 27 - test/LLVMC/NoActions.td | 16 - test/LLVMC/NoCompilationGraph.td | 6 - test/LLVMC/ObjC++/dg.exp | 5 - test/LLVMC/ObjC++/hello.mm | 8 - test/LLVMC/ObjC/dg.exp | 5 - test/LLVMC/ObjC/hello.m | 12 - test/LLVMC/OneOrMore.td | 25 - test/LLVMC/OptionPreprocessor.td | 67 - test/LLVMC/OutputSuffixHook.td | 24 - test/LLVMC/TestWarnings.td | 8 - test/LLVMC/dg.exp | 3 - test/LLVMC/test_data/false.c | 10 - test/LLVMC/test_data/false.cpp | 16 - test/LLVMC/test_data/false2.cpp | 5 - test/LLVMC/test_data/together.c | 5 - test/Linker/2003-01-30-LinkerTypeRename.ll | 6 +- test/Linker/2003-04-26-NullPtrLinkProblem.ll | 2 +- test/Linker/2003-06-02-TypeResolveProblem.ll | 2 +- test/Linker/2003-06-02-TypeResolveProblem2.ll | 2 +- test/Linker/2003-08-23-GlobalVarLinking.ll | 2 +- test/Linker/2003-11-18-TypeResolution.ll | 2 +- test/Linker/2011-08-04-DebugLoc.ll | 26 + test/Linker/2011-08-04-DebugLoc2.ll | 23 + test/Linker/2011-08-04-Metadata.ll | 29 + test/Linker/2011-08-04-Metadata2.ll | 29 + test/Linker/2011-08-18-unique-class-type.ll | 35 + test/Linker/2011-08-18-unique-class-type2.ll | 35 + test/Linker/2011-08-18-unique-debug-type.ll | 26 + test/Linker/2011-08-18-unique-debug-type2.ll | 25 + test/Linker/2011-08-22-ResolveAlias.ll | 89 + test/Linker/2011-08-22-ResolveAlias2.ll | 92 + test/MC/ARM/arm-memory-instructions.s | 479 + test/MC/ARM/arm_addrmode3.s | 8 +- test/MC/ARM/arm_fixups.s | 22 +- test/MC/ARM/arm_instructions.s | 135 +- test/MC/ARM/basic-arm-instructions.s | 2438 +- test/MC/ARM/basic-thumb-instructions.s | 623 + test/MC/ARM/basic-thumb2-instructions.s | 3213 + test/MC/ARM/diagnostics.s | 227 + test/MC/ARM/elf-movt.s | 8 +- test/MC/ARM/elf-reloc-01.ll | 8 +- test/MC/ARM/elf-reloc-02.ll | 8 +- test/MC/ARM/elf-reloc-03.ll | 8 +- test/MC/ARM/elf-thumbfunc-reloc.ll | 10 +- test/MC/ARM/elf-thumbfunc.s | 6 +- test/MC/ARM/mode-switch.s | 14 +- test/MC/ARM/neon-bitwise-encoding.s | 58 +- test/MC/ARM/neon-cmp-encoding.s | 124 +- test/MC/ARM/neon-dup-encoding.s | 36 +- test/MC/ARM/neon-mov-encoding.s | 138 +- test/MC/ARM/neon-mul-accum-encoding.s | 3 +- test/MC/ARM/neon-mul-encoding.s | 134 +- test/MC/ARM/neon-vld-encoding.s | 195 +- test/MC/ARM/neont2-absdiff-encoding.s | 87 +- test/MC/ARM/neont2-bitcount-encoding.s | 34 +- test/MC/ARM/neont2-bitwise-encoding.s | 56 +- test/MC/ARM/neont2-dup-encoding.s | 66 +- test/MC/ARM/neont2-mul-accum-encoding.s | 81 +- test/MC/ARM/neont2-pairwise-encoding.s | 181 +- test/MC/ARM/nop-armv4-padding.s | 10 + test/MC/ARM/nop-armv6t2-padding.s | 10 + test/MC/ARM/nop-thumb-padding.s | 12 + test/MC/ARM/nop-thumb2-padding.s | 12 + test/MC/ARM/reg-list.s | 8 - test/MC/ARM/simple-encoding.ll | 236 - test/MC/ARM/simple-fp-encoding.s | 43 +- test/MC/ARM/thumb-diagnostics.s | 139 + test/MC/ARM/thumb-nop.s | 9 + test/MC/ARM/thumb.s | 48 +- test/MC/ARM/thumb2-diagnostics.s | 44 + test/MC/ARM/thumb2-mclass.s | 74 + test/MC/ARM/thumb2.s | 355 - test/MC/ARM/thumb2_instructions.s | 12 - test/MC/ARM/xscale-attributes.ll | 2 +- test/MC/AsmParser/2011-09-06-NoNewline.s | 6 + test/MC/AsmParser/exprs.s | 15 +- test/MC/AsmParser/labels.s | 3 - test/MC/AsmParser/line_with_hash.s | 15 + test/MC/Disassembler/ARM/arm-tests.txt | 50 +- .../ARM/basic-arm-instructions.txt | 2362 + test/MC/Disassembler/ARM/fp-encoding.txt | 213 + test/MC/Disassembler/ARM/invalid-BFI-arm.txt | 2 +- .../MC/Disassembler/ARM/invalid-Bcc-thumb.txt | 4 +- .../MC/Disassembler/ARM/invalid-CPS3p-arm.txt | 2 +- .../MC/Disassembler/ARM/invalid-DMB-thumb.txt | 4 +- test/MC/Disassembler/ARM/invalid-DSB-arm.txt | 4 +- .../ARM/invalid-IT-CBNZ-thumb.txt | 5 + test/MC/Disassembler/ARM/invalid-IT-thumb.txt | 3 + .../Disassembler/ARM/invalid-LDC-form-arm.txt | 2 +- .../MC/Disassembler/ARM/invalid-LDM-thumb.txt | 5 + .../ARM/invalid-LDRB_POST-arm.txt | 6 +- test/MC/Disassembler/ARM/invalid-LDRD-arm.txt | 10 + .../ARM/invalid-LDRD_PRE-thumb.txt | 2 +- test/MC/Disassembler/ARM/invalid-LDRT-arm.txt | 2 +- .../Disassembler/ARM/invalid-LDR_POST-arm.txt | 1 + .../Disassembler/ARM/invalid-LDR_PRE-arm.txt | 6 +- .../Disassembler/ARM/invalid-LSL-regform.txt | 2 +- test/MC/Disassembler/ARM/invalid-MCR-arm.txt | 2 +- .../Disassembler/ARM/invalid-MOVTi16-arm.txt | 4 +- test/MC/Disassembler/ARM/invalid-MOVr-arm.txt | 2 +- .../Disassembler/ARM/invalid-MOVs-LSL-arm.txt | 2 +- test/MC/Disassembler/ARM/invalid-MOVs-arm.txt | 2 +- test/MC/Disassembler/ARM/invalid-MSRi-arm.txt | 2 +- .../ARM/invalid-RFEorLDMIA-arm.txt | 2 +- test/MC/Disassembler/ARM/invalid-RSC-arm.txt | 2 +- test/MC/Disassembler/ARM/invalid-SBFX-arm.txt | 2 +- .../MC/Disassembler/ARM/invalid-SMLAD-arm.txt | 2 +- test/MC/Disassembler/ARM/invalid-SRS-arm.txt | 2 +- test/MC/Disassembler/ARM/invalid-SSAT-arm.txt | 2 +- .../ARM/invalid-STMIA_UPD-thumb.txt | 4 +- .../Disassembler/ARM/invalid-STRBrs-arm.txt | 4 +- test/MC/Disassembler/ARM/invalid-SXTB-arm.txt | 2 +- .../MC/Disassembler/ARM/invalid-UMAAL-arm.txt | 4 +- .../Disassembler/ARM/invalid-UQADD8-arm.txt | 4 +- .../ARM/invalid-VLD1DUPq8_UPD-arm.txt | 3 +- .../ARM/invalid-VLD3DUPd32_UPD-thumb.txt | 4 +- .../MC/Disassembler/ARM/invalid-VQADD-arm.txt | 3 +- .../ARM/invalid-VST2b32_UPD-arm.txt | 5 +- .../Disassembler/ARM/invalid-t2Bcc-thumb.txt | 4 +- .../ARM/invalid-t2LDRBT-thumb.txt | 4 +- .../ARM/invalid-t2LDREXD-thumb.txt | 3 +- .../ARM/invalid-t2LDRSHi12-thumb.txt | 4 +- .../ARM/invalid-t2LDRSHi8-thumb.txt | 4 +- .../Disassembler/ARM/invalid-t2PUSH-thumb.txt | 5 + .../ARM/invalid-t2STRD_PRE-thumb.txt | 3 +- .../ARM/invalid-t2STREXB-thumb.txt | 3 +- .../ARM/invalid-t2STREXD-thumb.txt | 4 +- .../ARM/invalid-t2STR_POST-thumb.txt | 4 +- .../ARM/memory-arm-instructions.txt | 470 + test/MC/Disassembler/ARM/neon-tests.txt | 6 +- test/MC/Disassembler/ARM/neon.txt | 1858 + test/MC/Disassembler/ARM/neont2.txt | 1586 + test/MC/Disassembler/ARM/thumb-MSR-MClass.txt | 7 + test/MC/Disassembler/ARM/thumb-printf.txt | 2 +- test/MC/Disassembler/ARM/thumb-tests.txt | 56 +- test/MC/Disassembler/ARM/thumb1.txt | 530 + test/MC/Disassembler/ARM/thumb2.txt | 2558 + test/MC/Disassembler/X86/enhanced.txt | 4 + test/MC/Disassembler/X86/intel-syntax.txt | 79 + test/MC/Disassembler/X86/invalid-VEX-vvvv.txt | 4 + test/MC/Disassembler/X86/simple-tests.txt | 446 + test/MC/Disassembler/X86/x86-32.txt | 471 + test/MC/ELF/abs.s | 10 +- test/MC/ELF/alias-reloc.s | 32 +- test/MC/ELF/alias.s | 76 +- test/MC/ELF/align-bss.s | 12 +- test/MC/ELF/align-nops.s | 16 +- test/MC/ELF/align-size.s | 8 +- test/MC/ELF/align-text.s | 12 +- test/MC/ELF/align.s | 28 +- test/MC/ELF/basic-elf-32.s | 42 +- test/MC/ELF/basic-elf-64.s | 50 +- test/MC/ELF/call-abs.s | 6 +- test/MC/ELF/cfi-adjust-cfa-offset.s | 34 +- test/MC/ELF/cfi-advance-loc2.s | 30 +- test/MC/ELF/cfi-def-cfa-offset.s | 34 +- test/MC/ELF/cfi-def-cfa-register.s | 30 +- test/MC/ELF/cfi-def-cfa.s | 30 +- test/MC/ELF/cfi-offset.s | 30 +- test/MC/ELF/cfi-rel-offset.s | 34 +- test/MC/ELF/cfi-rel-offset2.s | 34 +- test/MC/ELF/cfi-remember.s | 34 +- test/MC/ELF/cfi-same-value.s | 34 +- test/MC/ELF/cfi-sections.s | 12 +- test/MC/ELF/cfi-zero-addr-delta.s | 30 +- test/MC/ELF/cfi.s | 460 +- test/MC/ELF/comdat.s | 72 +- test/MC/ELF/common.s | 48 +- test/MC/ELF/common2.s | 2 +- test/MC/ELF/debug-line.s | 12 +- test/MC/ELF/debug-loc.s | 14 +- test/MC/ELF/diff.s | 6 +- test/MC/ELF/empty-dwarf-lines.s | 14 +- test/MC/ELF/empty.s | 68 +- test/MC/ELF/entsize.ll | 16 +- test/MC/ELF/entsize.s | 30 +- test/MC/ELF/file.s | 20 +- test/MC/ELF/global-offset.s | 5 +- test/MC/ELF/got.s | 6 +- test/MC/ELF/ident.s | 12 +- test/MC/ELF/leb128.s | 12 +- test/MC/ELF/local-reloc.s | 14 +- test/MC/ELF/many-section.s | 93319 ++++++++++++++++ test/MC/ELF/merge.s | 32 +- test/MC/ELF/n_bytes.s | 14 +- test/MC/ELF/noexec.s | 24 +- test/MC/ELF/norelocation.s | 12 +- test/MC/ELF/org.s | 2 +- test/MC/ELF/pic-diff.s | 16 +- test/MC/ELF/plt.s | 2 +- test/MC/ELF/pr9292.s | 18 +- test/MC/ELF/relax.s | 14 +- test/MC/ELF/relocation-386.s | 164 +- test/MC/ELF/relocation-pc.s | 26 +- test/MC/ELF/relocation.s | 90 +- test/MC/ELF/rename.s | 30 +- test/MC/ELF/section.s | 78 +- test/MC/ELF/set.s | 16 +- test/MC/ELF/symref.s | 150 +- test/MC/ELF/tls-i386.s | 68 +- test/MC/ELF/tls.s | 38 +- test/MC/ELF/type.s | 20 +- test/MC/ELF/undef.s | 24 +- test/MC/ELF/undef2.s | 2 +- test/MC/ELF/weak-relocation.s | 6 +- test/MC/ELF/weak.s | 20 +- test/MC/ELF/weakref-plt.s | 4 +- test/MC/ELF/weakref-reloc.s | 42 +- test/MC/ELF/weakref.s | 180 +- test/MC/ELF/x86_64-reloc-sizetest.s | 13 + test/MC/ELF/zero.s | 12 +- test/MC/MachO/darwin-x86_64-nobase-relocs.s | 58 + test/MC/MachO/debug_frame.s | 15 +- test/MC/MachO/x86_64-reloc-arithmetic.s | 21 + test/MC/X86/3DNow.s | 6 +- test/MC/X86/x86-32-avx.s | 30 + test/MC/X86/x86-32-coverage.s | 21 +- test/MC/X86/x86-32.s | 16 + test/MC/X86/x86-64.s | 21 + test/MC/X86/x86_64-avx-encoding.s | 30 + test/MC/X86/x86_errors.s | 16 +- .../TestObjectFiles/archive-test.a-bitcode | Bin 0 -> 790 bytes .../TestObjectFiles/archive-test.a-coff-i386 | Bin 0 -> 658 bytes test/Object/nm-archive.test | 17 + ...ect.test-broken => nm-trivial-object.test} | 0 ...bjdump-disassembly-inline-relocations.test | 32 + test/Object/objdump-relocations.test | 28 + test/Object/objdump-sectionheaders.test | 16 + ...est-broken => objdump-trivial-object.test} | 0 test/Other/2008-10-15-MissingSpace.ll | 7 +- test/Scripts/common_dump.py | 6 +- test/Scripts/elf-dump | 98 +- test/TableGen/2003-08-03-PassCode.td | 2 +- test/TableGen/2006-09-18-LargeInt.td | 2 +- test/TableGen/2010-03-24-PrematureDefaults.td | 2 +- test/TableGen/AnonDefinitionOnDemand.td | 2 +- test/TableGen/BitsInitOverflow.td | 2 +- test/TableGen/CStyleComment.td | 3 +- test/TableGen/Dag.td | 2 +- test/TableGen/DefmInherit.td | 2 +- test/TableGen/DefmInsideMultiClass.td | 2 +- test/TableGen/FieldAccess.td | 2 +- test/TableGen/ForwardRef.td | 2 +- test/TableGen/GeneralList.td | 2 +- test/TableGen/Include.td | 3 +- test/TableGen/IntBitInit.td | 2 +- test/TableGen/LazyChange.td | 2 +- test/TableGen/LetInsideMultiClasses.td | 2 +- test/TableGen/ListArgs.td | 2 +- test/TableGen/ListArgsSimple.td | 2 +- test/TableGen/ListConversion.td | 2 +- test/TableGen/ListManip.td | 2 +- test/TableGen/ListOfList.td | 14 + test/TableGen/ListSlices.td | 2 +- test/TableGen/LoLoL.td | 18 + test/TableGen/MultiClass.td | 2 +- test/TableGen/MultiClassDefName.td | 2 +- test/TableGen/MultiClassInherit.td | 2 +- test/TableGen/MultiPat.td | 121 + test/TableGen/SetTheory.td | 2 +- test/TableGen/Slice.td | 4 +- test/TableGen/String.td | 2 +- test/TableGen/SuperSubclassSameName.td | 2 +- test/TableGen/TargetInstrInfo.td | 2 +- test/TableGen/TargetInstrSpec.td | 4 +- test/TableGen/TemplateArgRename.td | 2 +- test/TableGen/Tree.td | 2 +- test/TableGen/TreeNames.td | 2 +- test/TableGen/UnsetBitInit.td | 2 +- test/TableGen/UnterminatedComment.td | 2 +- test/TableGen/cast.td | 2 +- test/TableGen/defmclass.td | 2 +- test/TableGen/eq.td | 2 +- test/TableGen/eqbit.td | 2 +- test/TableGen/foreach.td | 6 +- test/TableGen/if.td | 2 +- test/TableGen/ifbit.td | 2 +- test/TableGen/lisp.td | 2 +- test/TableGen/nested-comment.td | 3 +- test/TableGen/strconcat.td | 2 +- test/TableGen/subst.td | 12 +- test/TableGen/subst2.td | 2 +- test/TableGen/usevalname.td | 2 +- .../ADCE/2003-09-10-UnwindInstFail.ll | 5 +- .../ADCE/2004-05-04-UnreachableBlock.ll | 2 +- .../ADCE/2005-02-17-PHI-Invoke-Crash.ll | 9 +- test/Transforms/ADCE/dce_pure_invoke.ll | 4 + .../2004-03-18-InvokeHandling.ll | 4 + .../CodeExtractor/2004-11-12-InvokeExtract.ll | 5 +- test/Transforms/ConstantMerge/merge-both.ll | 17 +- .../DeadArgElim/2009-03-17-MRE-Invoke.ll | 6 + test/Transforms/DeadArgElim/deadexternal.ll | 2 +- .../2011-09-06-EndOfFunction.ll | 27 + .../DeadStoreElimination/2011-09-06-MemCpy.ll | 85 + .../Transforms/DeadStoreElimination/atomic.ll | 107 + .../Transforms/DeadStoreElimination/simple.ll | 8 +- test/Transforms/EarlyCSE/basic.ll | 10 +- .../FunctionAttrs/2008-12-31-NoCapture.ll | 4 + test/Transforms/FunctionAttrs/atomic.ll | 21 + test/Transforms/GVN/2010-05-08-OneBit.ll | 4 + test/Transforms/GVN/2011-09-07-TypeIdFor.ll | 81 + test/Transforms/GVN/atomic.ll | 80 + test/Transforms/GVN/condprop.ll | 83 +- test/Transforms/GVN/phi-translate.ll | 2 +- test/Transforms/GVN/pr10820.ll | 18 + .../GlobalOpt/2008-01-29-VolatileGlobal.ll | 2 +- test/Transforms/IPConstantProp/global.ll | 26 + .../IPConstantProp/return-argument.ll | 10 +- .../IPConstantProp/return-constant.ll | 4 + .../IndVarSimplify/2003-09-12-MultiplePred.ll | 15 - .../IndVarSimplify/2003-12-21-IndVarSize.ll | 15 - .../2004-04-05-InvokeCastCrash.ll | 8 + .../IndVarSimplify/2005-02-11-InvokeCrash.ll | 10 +- .../2005-02-17-TruncateExprCrash.ll | 6 + .../2009-04-14-shorten_iv_vars.ll | 2 +- .../2009-04-15-shorten-iv-vars-2.ll | 2 +- .../IndVarSimplify/2011-09-10-widen-nsw.ll | 30 + .../IndVarSimplify/2011-09-19-vectoriv.ll | 16 + .../IndVarSimplify/2011-09-27-hoistsext.ll | 28 + test/Transforms/IndVarSimplify/ada-loops.ll | 9 +- test/Transforms/IndVarSimplify/addrec-gep.ll | 12 +- .../IndVarSimplify/ashr-tripcount.ll | 2 +- .../Transforms/IndVarSimplify/complex-scev.ll | 4 +- test/Transforms/IndVarSimplify/crash.ll | 34 + test/Transforms/IndVarSimplify/elim-extend.ll | 2 +- .../IndVarSimplify/floating-point-iv.ll | 8 +- .../IndVarSimplify/gep-with-mul-base.ll | 17 +- .../IndVarSimplify/interesting-invoke-use.ll | 4 + test/Transforms/IndVarSimplify/iv-fold.ll | 56 + test/Transforms/IndVarSimplify/iv-sext.ll | 2 +- test/Transforms/IndVarSimplify/iv-zext.ll | 4 +- test/Transforms/IndVarSimplify/lftr-reuse.ll | 230 + test/Transforms/IndVarSimplify/max-pointer.ll | 39 - .../IndVarSimplify/no-iv-rewrite.ll | 84 +- .../IndVarSimplify/pointer-indvars.ll | 15 - test/Transforms/IndVarSimplify/pointer.ll | 38 - .../preserve-gep-loop-variant.ll | 10 +- .../IndVarSimplify/preserve-gep-nested.ll | 23 +- .../IndVarSimplify/preserve-gep-remainder.ll | 6 +- .../Transforms/IndVarSimplify/preserve-gep.ll | 10 +- .../IndVarSimplify/preserve-signed-wrap.ll | 2 +- test/Transforms/IndVarSimplify/subtract.ll | 15 - .../IndVarSimplify/variable-stride-ivs-0.ll | 2 +- .../Inline/2003-09-14-InlineValue.ll | 4 + .../2003-09-22-PHINodesInExceptionDest.ll | 9 +- ...2003-10-26-InlineInvokeExceptionDestPhi.ll | 20 - .../Inline/2004-04-15-InlineDeletesCall.ll | 2 +- .../2004-10-17-InlineFunctionWithoutReturn.ll | 2 +- .../Inline/2006-11-09-InlineCGUpdate-2.ll | 20 +- .../Inline/2006-11-09-InlineCGUpdate.ll | 12 +- test/Transforms/Inline/2007-04-15-InlineEH.ll | 6 +- .../Inline/2007-12-19-InlineNoUnwind.ll | 2 +- test/Transforms/Inline/callgraph-update.ll | 3 + test/Transforms/Inline/crash.ll | 10 +- test/Transforms/Inline/inline_invoke.ll | 122 +- test/Transforms/Inline/invoke_test-1.ll | 4 + test/Transforms/Inline/invoke_test-2.ll | 6 + test/Transforms/Inline/invoke_test-3.ll | 8 +- .../InstCombine/2003-10-29-CallSiteResolve.ll | 3 + .../2004-01-13-InstCombineInvokePHI.ll | 3 + .../2008-01-14-VarArgTrampoline.ll | 6 +- .../InstCombine/2008-04-28-VolatileStore.ll | 2 +- .../2008-04-29-VolatileLoadDontMerge.ll | 2 +- .../2008-04-29-VolatileLoadMerge.ll | 2 +- .../InstCombine/2008-05-09-SinkOfInvoke.ll | 4 + .../2008-07-08-VolatileLoadMerge.ll | 2 +- .../InstCombine/2011-09-03-Trampoline.ll | 87 + .../InstCombine/2011-10-07-AlignPromotion.ll | 20 + .../InstCombine/LandingPadClauses.ll | 181 + test/Transforms/InstCombine/and2.ll | 7 + test/Transforms/InstCombine/atomic.ll | 24 + test/Transforms/InstCombine/bitcast.ll | 34 + test/Transforms/InstCombine/call.ll | 20 +- .../InstCombine/canonicalize_branch.ll | 31 +- test/Transforms/InstCombine/cast.ll | 47 + test/Transforms/InstCombine/crash.ll | 4 + test/Transforms/InstCombine/deadcode.ll | 11 +- test/Transforms/InstCombine/devirt.ll | 39 + test/Transforms/InstCombine/extractvalue.ll | 2 +- test/Transforms/InstCombine/fcmp.ll | 11 + test/Transforms/InstCombine/getelementptr.ll | 20 + test/Transforms/InstCombine/intrinsics.ll | 12 +- .../InstCombine/malloc-free-delete.ll | 25 +- test/Transforms/InstCombine/nsw.ll | 44 + test/Transforms/InstCombine/ptr-int-cast.ll | 14 +- test/Transforms/InstCombine/select.ll | 10 + test/Transforms/InstCombine/shift.ll | 17 +- .../InstCombine/vec_demanded_elts.ll | 11 + test/Transforms/InstCombine/vector-casts.ll | 2 +- test/Transforms/InstCombine/volatile_store.ll | 4 +- .../2011-09-05-InsertExtractValue.ll | 29 + test/Transforms/InstSimplify/compare.ll | 11 - .../JumpThreading/no-irreducible-loops.ll | 2 +- test/Transforms/LCSSA/invoke-dest.ll | 8 + .../LICM/2007-05-22-VolatileSink.ll | 2 +- .../LICM/2011-04-06-HoistMissedASTUpdate.ll | 2 +- test/Transforms/LICM/atomics.ll | 79 + .../LICM/scalar-promote-memmodel.ll | 37 + test/Transforms/LICM/scalar_promote.ll | 2 +- .../Transforms/LoopDeletion/2008-05-06-Phi.ll | 2 +- test/Transforms/LoopIdiom/basic.ll | 4 +- .../LoopSimplify/2003-08-15-PreheadersFail.ll | 2 +- .../LoopSimplify/2007-10-28-InvokeCrash.ll | 889 +- test/Transforms/LoopSimplify/merge-exits.ll | 2 +- test/Transforms/LoopSimplify/preserve-scev.ll | 88 + .../LoopSimplify/single-backedge.ll | 9 +- .../2011-07-19-CritEdgeBreakCrash.ll | 52 + .../LoopStrengthReduce/2011-07-20-DoubleIV.ll | 43 + .../2011-10-03-CritEdgeMerge.ll | 43 + .../LoopStrengthReduce/2011-10-06-ReusePhi.ll | 53 + .../2011-10-13-SCEVChain.ll | 111 + .../LoopStrengthReduce/2011-10-14-IntPtr.ll | 27 + .../invariant_value_first.ll | 2 +- .../invariant_value_first_arg.ll | 2 +- .../LoopStrengthReduce/ops_after_indvar.ll | 2 +- .../LoopStrengthReduce/post-inc-icmpzero.ll | 14 +- .../var_stride_used_by_compare.ll | 2 +- .../LoopUnroll/2011-08-08-PhiUpdate.ll | 103 + .../LoopUnroll/2011-08-09-IVSimplify.ll | 41 + .../LoopUnroll/2011-08-09-PhiUpdate.ll | 62 + .../LoopUnroll/2011-10-01-NoopTrunc.ll | 36 + test/Transforms/LoopUnroll/pr10813.ll | 29 + test/Transforms/LoopUnroll/scevunroll.ll | 172 + test/Transforms/LoopUnroll/unloop.ll | 429 + .../LoopUnswitch/2011-09-26-EHCrash.ll | 67 + test/Transforms/LowerAtomic/atomic-load.ll | 10 +- test/Transforms/LowerAtomic/atomic-swap.ll | 7 +- test/Transforms/LowerAtomic/barrier.ll | 4 +- .../2003-11-05-DominanceProperties.ll | 16 - test/Transforms/LowerSetJmp/simpletest.ll | 31 - .../Mem2Reg/2007-08-27-VolatileLoadsStores.ll | 2 +- test/Transforms/Mem2Reg/atomic.ll | 12 + test/Transforms/Mem2Reg/crash.ll | 3 + test/Transforms/MemCpyOpt/atomic.ll | 41 + test/Transforms/ObjCARC/basic.ll | 110 +- test/Transforms/ObjCARC/cfg-hazards.ll | 329 +- .../ObjCARC/contract-storestrong.ll | 4 +- test/Transforms/ObjCARC/empty-block.ll | 59 + test/Transforms/ObjCARC/invoke.ll | 6 + test/Transforms/ObjCARC/nested.ll | 620 + .../Transforms/ObjCARC/retain-block-alloca.ll | 54 + .../ObjCARC/retain-block-side-effects.ll | 39 + .../Transforms/ObjCARC/retain-not-declared.ll | 54 +- test/Transforms/ObjCARC/rv.ll | 11 + .../2010-03-22-empty-baseclass.ll | 162 + .../PruneEH/2003-09-14-ExternalCall.ll | 3 + .../SCCP/2003-08-26-InvokeHandling.ll | 9 +- test/Transforms/SCCP/2004-11-16-DeadInvoke.ll | 9 +- .../Transforms/SCCP/2007-05-16-InvokeCrash.ll | 6 +- .../SCCP/2009-01-14-IPSCCP-Invoke.ll | 2 + test/Transforms/SCCP/atomic-load-store.ll | 30 + test/Transforms/SCCP/ipsccp-basic.ll | 23 + test/Transforms/SCCP/switch.ll | 13 + test/Transforms/SCCP/undef-resolve.ll | 66 + .../ScalarRepl/2003-10-29-ArrayProblem.ll | 2 +- .../2011-09-22-PHISpeculateInvoke.ll | 40 + .../ScalarRepl/2011-10-11-VectorMemset.ll | 22 + test/Transforms/ScalarRepl/lifetime.ll | 139 + test/Transforms/ScalarRepl/vector_promote.ll | 174 +- .../vectors-with-mismatched-elements.ll | 27 + test/Transforms/ScalarRepl/volatile.ll | 4 +- .../SimplifyCFG/2003-08-05-InvokeCrash.ll | 3 + .../SimplifyCFG/2003-08-05-MishandleInvoke.ll | 3 + .../SimplifyCFG/2005-10-02-InvokeSimplify.ll | 3 + .../SimplifyCFG/2006-10-29-InvokeCrash.ll | 14 +- ...01-19-UnconditionalTrappingConstantExpr.ll | 4 +- .../SimplifyCFG/2009-06-15-InvokeCrash.ll | 14 +- .../SimplifyCFG/2010-03-30-InvokeCrash.ll | 6 +- .../SimplifyCFG/2011-09-05-TrivialLPad.ll | 22 + test/Transforms/SimplifyCFG/BrUnwind.ll | 2 +- test/Transforms/SimplifyCFG/invoke_unwind.ll | 20 +- .../SimplifyCFG/phi-undef-loadstore.ll | 87 + .../SimplifyCFG/trapping-load-unreachable.ll | 51 +- test/Transforms/SimplifyLibCalls/StrCmp.ll | 73 +- test/Transforms/SimplifyLibCalls/StrNCmp.ll | 91 +- test/Transforms/SimplifyLibCalls/memcmp.ll | 22 +- .../SimplifyLibCalls/pow-to-sqrt.ll | 12 +- test/Transforms/Sink/basic.ll | 16 + test/Transforms/StripSymbols/block-address.ll | 23 + .../TailCallElim/dont_reorder_load.ll | 2 +- test/Transforms/TailCallElim/reorder_load.ll | 4 +- test/Transforms/TailCallElim/setjmp.ll | 19 +- .../TailDup/2003-06-24-Simpleloop.ll | 15 - .../TailDup/2003-07-22-InfiniteLoop.ll | 11 - .../TailDup/2003-08-23-InvalidatedPointers.ll | 29 - .../TailDup/2003-08-31-UnreachableBlocks.ll | 17 - .../TailDup/2004-04-01-DemoteRegToStack.ll | 20 - .../TailDup/2008-05-13-InfiniteLoop.ll | 26 - .../Transforms/TailDup/2009-07-31-phicrash.ll | 14 - test/Transforms/TailDup/MergeTest.ll | 27 - test/Transforms/TailDup/PHIUpdateTest.ll | 16 - test/Transforms/TailDup/X86/if-tail-dup.ll | 49 - test/Transforms/TailDup/basictest.ll | 20 - test/Transforms/TailDup/basictest2.ll | 15 - test/lib/llvm.exp | 30 +- test/lit.cfg | 13 +- tools/CMakeLists.txt | 3 +- tools/Makefile | 5 +- tools/bugpoint/BugDriver.cpp | 3 +- tools/bugpoint/ExtractFunction.cpp | 2 +- tools/bugpoint/Miscompilation.cpp | 21 +- tools/bugpoint/bugpoint.cpp | 3 +- tools/edis/CMakeLists.txt | 29 +- tools/edis/EnhancedDisassembly.exports | 36 - tools/edis/Makefile | 1 - tools/gold/gold-plugin.cpp | 41 +- tools/llc/llc.cpp | 47 +- tools/lli/lli.cpp | 36 +- tools/llvm-config/CMakeLists.txt | 24 - tools/llvm-cov/CMakeLists.txt | 5 + .../examples/Hello => llvm-cov}/Makefile | 14 +- tools/llvm-cov/llvm-cov.cpp | 78 + tools/llvm-diff/DifferenceEngine.cpp | 4 +- tools/llvm-dwarfdump/CMakeLists.txt | 8 + .../mcc16 => llvm-dwarfdump}/Makefile | 10 +- tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 116 + tools/llvm-extract/llvm-extract.cpp | 77 +- tools/llvm-ld/Optimize.cpp | 6 +- tools/llvm-link/llvm-link.cpp | 3 +- tools/llvm-mc/Disassembler.cpp | 38 +- tools/llvm-mc/Disassembler.h | 2 + tools/llvm-mc/llvm-mc.cpp | 178 +- tools/llvm-nm/llvm-nm.cpp | 45 +- tools/llvm-objdump/CMakeLists.txt | 3 + tools/llvm-objdump/MCFunction.cpp | 138 + tools/llvm-objdump/MCFunction.h | 100 + tools/llvm-objdump/MachODump.cpp | 617 + tools/llvm-objdump/Makefile | 3 +- tools/llvm-objdump/llvm-objdump.cpp | 328 +- tools/llvm-objdump/llvm-objdump.h | 46 + tools/llvm-shlib/Makefile | 5 +- tools/llvm-size/CMakeLists.txt | 5 + .../examples/Simple => llvm-size}/Makefile | 10 +- tools/llvm-size/llvm-size.cpp | 311 + tools/llvmc/CMakeLists.txt | 4 - tools/llvmc/Makefile | 18 - tools/llvmc/doc/LLVMC-Reference.rst | 747 - tools/llvmc/doc/LLVMC-Tutorial.rst | 127 - tools/llvmc/doc/Makefile | 33 - tools/llvmc/doc/img/lines.gif | Bin 91 -> 0 bytes tools/llvmc/examples/Hello/Hello.cpp | 29 - tools/llvmc/examples/Simple/Simple.cpp | 2 - tools/llvmc/examples/Simple/Simple.td | 41 - .../llvmc/examples/Skeleton/AutoGenerated.td | 7 - tools/llvmc/examples/Skeleton/Hooks.cpp | 12 - tools/llvmc/examples/Skeleton/Main.cpp | 15 - tools/llvmc/examples/Skeleton/Makefile | 20 - tools/llvmc/examples/Skeleton/README | 6 - tools/llvmc/examples/mcc16/Hooks.cpp | 109 - tools/llvmc/examples/mcc16/Main.cpp | 57 - tools/llvmc/examples/mcc16/PIC16.td | 234 - tools/llvmc/examples/mcc16/README | 75 - tools/llvmc/src/AutoGenerated.td | 17 - tools/llvmc/src/Base.td.in | 461 - tools/llvmc/src/Clang.td | 87 - tools/llvmc/src/Hooks.cpp | 193 - tools/llvmc/src/Main.cpp | 16 - tools/llvmc/src/Makefile | 14 - tools/lto/LTOCodeGenerator.cpp | 30 +- tools/lto/LTOModule.cpp | 37 +- tools/lto/LTOModule.h | 5 +- tools/macho-dump/macho-dump.cpp | 28 + tools/opt/opt.cpp | 4 +- unittests/ADT/APFloatTest.cpp | 15 +- unittests/ADT/APIntTest.cpp | 38 +- unittests/ADT/DAGDeltaAlgorithmTest.cpp | 17 - unittests/ADT/SCCIteratorTest.cpp | 346 + unittests/ADT/SmallVectorTest.cpp | 2 +- unittests/ADT/StringRefTest.cpp | 6 + unittests/ADT/TwineTest.cpp | 8 +- unittests/Analysis/ScalarEvolutionTest.cpp | 170 +- .../ExecutionEngine/ExecutionEngineTest.cpp | 2 +- .../JIT/JITEventListenerTest.cpp | 4 +- .../JIT/JITMemoryManagerTest.cpp | 2 +- unittests/ExecutionEngine/JIT/JITTest.cpp | 20 +- .../ExecutionEngine/JIT/MultiJITTest.cpp | 4 + unittests/Support/BlockFrequencyTest.cpp | 56 + unittests/Support/DataExtractorTest.cpp | 111 + unittests/Support/TypeBuilderTest.cpp | 14 +- unittests/Transforms/Utils/Cloning.cpp | 2 +- unittests/VMCore/ConstantsTest.cpp | 8 +- unittests/VMCore/InstructionsTest.cpp | 60 +- unittests/VMCore/MetadataTest.cpp | 2 +- unittests/VMCore/VerifierTest.cpp | 2 +- utils/TableGen/ARMDecoderEmitter.cpp | 20 +- utils/TableGen/ARMDecoderEmitter.h | 3 +- utils/TableGen/AsmMatcherEmitter.cpp | 69 +- utils/TableGen/AsmMatcherEmitter.h | 2 +- utils/TableGen/AsmWriterEmitter.cpp | 14 +- utils/TableGen/AsmWriterEmitter.h | 2 +- utils/TableGen/AsmWriterInst.cpp | 2 +- utils/TableGen/CMakeLists.txt | 26 +- utils/TableGen/CallingConvEmitter.cpp | 2 +- utils/TableGen/CallingConvEmitter.h | 2 +- utils/TableGen/ClangASTNodesEmitter.cpp | 168 - utils/TableGen/ClangASTNodesEmitter.h | 84 - utils/TableGen/ClangAttrEmitter.cpp | 756 - utils/TableGen/ClangAttrEmitter.h | 101 - utils/TableGen/ClangDiagnosticsEmitter.cpp | 362 - utils/TableGen/ClangDiagnosticsEmitter.h | 54 - utils/TableGen/ClangSACheckersEmitter.cpp | 319 - utils/TableGen/ClangSACheckersEmitter.h | 31 - utils/TableGen/CodeEmitterGen.cpp | 14 +- utils/TableGen/CodeEmitterGen.h | 2 +- utils/TableGen/CodeGenDAGPatterns.cpp | 25 +- utils/TableGen/CodeGenInstruction.cpp | 21 +- utils/TableGen/CodeGenInstruction.h | 1 + utils/TableGen/CodeGenRegisters.cpp | 294 +- utils/TableGen/CodeGenRegisters.h | 112 +- utils/TableGen/CodeGenTarget.cpp | 12 +- utils/TableGen/CodeGenTarget.h | 6 +- utils/TableGen/DAGISelEmitter.cpp | 2 +- utils/TableGen/DAGISelEmitter.h | 2 +- utils/TableGen/DAGISelMatcher.cpp | 2 +- utils/TableGen/DAGISelMatcherEmitter.cpp | 2 +- utils/TableGen/DAGISelMatcherGen.cpp | 6 +- utils/TableGen/DisassemblerEmitter.cpp | 20 +- utils/TableGen/DisassemblerEmitter.h | 2 +- utils/TableGen/EDEmitter.cpp | 76 +- utils/TableGen/EDEmitter.h | 2 +- utils/TableGen/FastISelEmitter.cpp | 6 +- utils/TableGen/FastISelEmitter.h | 2 +- utils/TableGen/FixedLenDecoderEmitter.cpp | 490 +- utils/TableGen/FixedLenDecoderEmitter.h | 47 +- utils/TableGen/InstrEnumEmitter.cpp | 2 +- utils/TableGen/InstrEnumEmitter.h | 2 +- utils/TableGen/InstrInfoEmitter.cpp | 4 +- utils/TableGen/InstrInfoEmitter.h | 2 +- utils/TableGen/IntrinsicEmitter.cpp | 2 +- utils/TableGen/IntrinsicEmitter.h | 2 +- utils/TableGen/LLVMCConfigurationEmitter.cpp | 3134 - utils/TableGen/LLVMCConfigurationEmitter.h | 34 - utils/TableGen/Makefile | 4 +- utils/TableGen/NeonEmitter.cpp | 1558 - utils/TableGen/NeonEmitter.h | 176 - utils/TableGen/OptParserEmitter.cpp | 194 - utils/TableGen/OptParserEmitter.h | 34 - utils/TableGen/PseudoLoweringEmitter.cpp | 4 +- utils/TableGen/PseudoLoweringEmitter.h | 2 +- utils/TableGen/RegisterInfoEmitter.cpp | 566 +- utils/TableGen/RegisterInfoEmitter.h | 9 +- utils/TableGen/SetTheory.cpp | 4 +- utils/TableGen/SubtargetEmitter.cpp | 2 +- utils/TableGen/SubtargetEmitter.h | 2 +- utils/TableGen/TableGen.cpp | 289 +- utils/TableGen/X86DisassemblerTables.cpp | 99 +- utils/TableGen/X86DisassemblerTables.h | 6 +- utils/TableGen/X86RecognizableInstr.cpp | 100 +- utils/TableGen/X86RecognizableInstr.h | 8 +- utils/buildit/build_llvm | 68 +- utils/lit/lit/LitConfig.py | 3 +- utils/lit/lit/TestFormats.py | 4 + utils/lit/lit/TestRunner.py | 11 +- utils/lit/lit/TestingConfig.py | 13 +- utils/lit/lit/main.py | 2 + utils/llvm.grm | 2 +- utils/llvmbuild | 29 +- utils/release/findRegressions.py | 139 +- utils/release/test-release.sh | 294 +- utils/unittest/CMakeLists.txt | 1 + utils/unittest/googletest/README.LLVM | 6 +- utils/unittest/googletest/gtest-death-test.cc | 206 +- utils/unittest/googletest/gtest-filepath.cc | 36 +- utils/unittest/googletest/gtest-port.cc | 103 +- utils/unittest/googletest/gtest-printers.cc | 356 + utils/unittest/googletest/gtest-test-part.cc | 2 +- utils/unittest/googletest/gtest-typed-test.cc | 6 +- utils/unittest/googletest/gtest.cc | 1142 +- .../include/gtest/gtest-death-test.h | 44 +- .../googletest/include/gtest/gtest-message.h | 30 +- .../include/gtest/gtest-param-test.h | 65 +- .../googletest/include/gtest/gtest-printers.h | 796 + .../googletest/include/gtest/gtest-spi.h | 6 +- .../include/gtest/gtest-test-part.h | 4 +- .../include/gtest/gtest-typed-test.h | 30 +- .../unittest/googletest/include/gtest/gtest.h | 395 +- .../include/gtest/gtest_pred_impl.h | 84 +- .../internal/gtest-death-test-internal.h | 45 +- .../include/gtest/internal/gtest-filepath.h | 2 +- .../gtest/internal/gtest-internal-inl.h | 192 +- .../include/gtest/internal/gtest-internal.h | 531 +- .../include/gtest/internal/gtest-linked_ptr.h | 12 +- .../internal/gtest-param-util-generated.h | 16 +- .../include/gtest/internal/gtest-param-util.h | 42 +- .../include/gtest/internal/gtest-port.h | 628 +- .../include/gtest/internal/gtest-string.h | 10 +- .../include/gtest/internal/gtest-tuple.h | 4 +- .../include/gtest/internal/gtest-type-util.h | 77 +- utils/valgrind/x86_64-pc-linux-gnu.supp | 11 + utils/vim/llvm.vim | 4 +- utils/vim/tablegen.vim | 2 +- website/index.html | 26 - 2755 files changed, 213827 insertions(+), 82031 deletions(-) create mode 100644 bindings/ocaml/llvm/META.llvm.in create mode 100644 bindings/ocaml/transforms/ipo/Makefile create mode 100644 bindings/ocaml/transforms/ipo/ipo_ocaml.c create mode 100644 bindings/ocaml/transforms/ipo/llvm_ipo.ml create mode 100644 bindings/ocaml/transforms/ipo/llvm_ipo.mli delete mode 100644 cmake/modules/CrossCompileLLVM.cmake delete mode 100755 cmake/modules/FindBison.cmake delete mode 100644 cmake/modules/LLVMLibDeps.cmake create mode 100644 docs/Atomics.html delete mode 100644 docs/CommandGuide/llvmc.pod delete mode 100644 docs/CommandGuide/llvmgcc.pod delete mode 100644 docs/CommandGuide/llvmgxx.pod delete mode 100644 docs/CompilerDriver.html delete mode 100644 docs/CompilerDriverTutorial.html create mode 100644 docs/SegmentedStacks.html create mode 100644 include/llvm-c/Transforms/PassManagerBuilder.h create mode 100644 include/llvm/ADT/TinyPtrVector.h rename include/llvm/Analysis/{BlockFrequency.h => BlockFrequencyInfo.h} (58%) create mode 100644 include/llvm/Analysis/LoopIterator.h create mode 100644 include/llvm/CodeGen/LexicalScopes.h rename include/llvm/CodeGen/{MachineBlockFrequency.h => MachineBlockFrequencyInfo.h} (60%) delete mode 100644 include/llvm/CompilerDriver/Action.h delete mode 100644 include/llvm/CompilerDriver/AutoGenerated.h delete mode 100644 include/llvm/CompilerDriver/BuiltinOptions.h delete mode 100644 include/llvm/CompilerDriver/Common.td delete mode 100644 include/llvm/CompilerDriver/CompilationGraph.h delete mode 100644 include/llvm/CompilerDriver/Error.h delete mode 100644 include/llvm/CompilerDriver/Main.h delete mode 100644 include/llvm/CompilerDriver/Main.inc delete mode 100644 include/llvm/CompilerDriver/Tool.h create mode 100644 include/llvm/DebugInfo/DIContext.h rename include/llvm/{Target/TargetAsmBackend.h => MC/MCAsmBackend.h} (90%) create mode 100644 include/llvm/MC/MCAtom.h create mode 100644 include/llvm/MC/MCCodeGenInfo.h create mode 100644 include/llvm/MC/MCInstrAnalysis.h create mode 100644 include/llvm/MC/MCModule.h create mode 100644 include/llvm/MC/MCObjectFileInfo.h rename include/llvm/{Target/TargetAsmLexer.h => MC/MCTargetAsmLexer.h} (81%) rename include/llvm/{Target/TargetAsmParser.h => MC/MCTargetAsmParser.h} (75%) rename include/llvm/{CodeGen => MC}/MachineLocation.h (91%) create mode 100644 include/llvm/Object/Archive.h create mode 100644 include/llvm/Object/MachO.h create mode 100644 include/llvm/Support/BlockFrequency.h create mode 100644 include/llvm/Support/Capacity.h create mode 100644 include/llvm/Support/CodeGen.h create mode 100644 include/llvm/Support/DataExtractor.h create mode 100644 include/llvm/Support/GCOV.h delete mode 100644 include/llvm/Support/PassManagerBuilder.h rename include/llvm/{Target => Support}/TargetRegistry.h (66%) rename include/llvm/{Target => Support}/TargetSelect.h (75%) rename {utils => include/llvm}/TableGen/Error.h (89%) create mode 100644 include/llvm/TableGen/Main.h rename {utils => include/llvm}/TableGen/Record.h (80%) create mode 100644 include/llvm/TableGen/TableGenAction.h rename {utils => include/llvm}/TableGen/TableGenBackend.h (88%) delete mode 100644 include/llvm/Target/TargetAsmInfo.h create mode 100644 include/llvm/Transforms/IPO/PassManagerBuilder.h create mode 100644 include/llvm/Transforms/Utils/SimplifyIndVar.h delete mode 100644 lib/Analysis/BlockFrequency.cpp create mode 100644 lib/Analysis/BlockFrequencyInfo.cpp rename lib/{Target/X86/SSEDomainFix.cpp => CodeGen/ExecutionDepsFix.cpp} (84%) rename lib/CodeGen/{LowerSubregs.cpp => ExpandPostRAPseudos.cpp} (69%) create mode 100644 lib/CodeGen/LexicalScopes.cpp create mode 100644 lib/CodeGen/LiveRangeCalc.cpp create mode 100644 lib/CodeGen/LiveRangeCalc.h rename lib/CodeGen/{MachineBlockFrequency.cpp => MachineBlockFrequencyInfo.cpp} (51%) delete mode 100644 lib/CompilerDriver/Action.cpp delete mode 100644 lib/CompilerDriver/BuiltinOptions.cpp delete mode 100644 lib/CompilerDriver/CMakeLists.txt delete mode 100644 lib/CompilerDriver/CompilationGraph.cpp delete mode 100644 lib/CompilerDriver/Main.cpp delete mode 100644 lib/CompilerDriver/Makefile delete mode 100644 lib/CompilerDriver/Tool.cpp create mode 100644 lib/DebugInfo/CMakeLists.txt create mode 100644 lib/DebugInfo/DIContext.cpp create mode 100644 lib/DebugInfo/DWARFAbbreviationDeclaration.cpp create mode 100644 lib/DebugInfo/DWARFAbbreviationDeclaration.h create mode 100644 lib/DebugInfo/DWARFAttribute.h create mode 100644 lib/DebugInfo/DWARFCompileUnit.cpp create mode 100644 lib/DebugInfo/DWARFCompileUnit.h create mode 100644 lib/DebugInfo/DWARFContext.cpp create mode 100644 lib/DebugInfo/DWARFContext.h create mode 100644 lib/DebugInfo/DWARFDebugAbbrev.cpp create mode 100644 lib/DebugInfo/DWARFDebugAbbrev.h create mode 100644 lib/DebugInfo/DWARFDebugArangeSet.cpp create mode 100644 lib/DebugInfo/DWARFDebugArangeSet.h create mode 100644 lib/DebugInfo/DWARFDebugAranges.cpp create mode 100644 lib/DebugInfo/DWARFDebugAranges.h create mode 100644 lib/DebugInfo/DWARFDebugInfoEntry.cpp create mode 100644 lib/DebugInfo/DWARFDebugInfoEntry.h create mode 100644 lib/DebugInfo/DWARFDebugLine.cpp create mode 100644 lib/DebugInfo/DWARFDebugLine.h create mode 100644 lib/DebugInfo/DWARFFormValue.cpp create mode 100644 lib/DebugInfo/DWARFFormValue.h rename {tools/llvmc/examples => lib/DebugInfo}/Makefile (70%) rename lib/MC/{TargetAsmBackend.cpp => MCAsmBackend.cpp} (78%) create mode 100644 lib/MC/MCAtom.cpp create mode 100644 lib/MC/MCCodeGenInfo.cpp create mode 100644 lib/MC/MCInstrAnalysis.cpp create mode 100644 lib/MC/MCModule.cpp create mode 100644 lib/MC/MCObjectFileInfo.cpp rename lib/MC/MCParser/{TargetAsmParser.cpp => MCTargetAsmParser.cpp} (64%) rename lib/{Target/TargetAsmLexer.cpp => MC/MCTargetAsmLexer.cpp} (56%) create mode 100644 lib/Object/Archive.cpp create mode 100644 lib/Support/BlockFrequency.cpp create mode 100644 lib/Support/DataExtractor.cpp create mode 100644 lib/TableGen/CMakeLists.txt rename {utils => lib}/TableGen/Error.cpp (96%) create mode 100644 lib/TableGen/Main.cpp create mode 100644 lib/TableGen/Makefile rename {utils => lib}/TableGen/Record.cpp (68%) rename {utils => lib}/TableGen/TGLexer.cpp (90%) rename {utils => lib}/TableGen/TGLexer.h (100%) rename {utils => lib}/TableGen/TGParser.cpp (88%) rename {utils => lib}/TableGen/TGParser.h (82%) rename {utils => lib}/TableGen/TableGenBackend.cpp (92%) delete mode 100644 lib/Target/ARM/Disassembler/ARMDisassembler.h delete mode 100644 lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp delete mode 100644 lib/Target/ARM/Disassembler/ARMDisassemblerCore.h delete mode 100644 lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h rename lib/Target/ARM/{ => MCTargetDesc}/ARMAddressingModes.h (87%) rename lib/Target/ARM/{ => MCTargetDesc}/ARMAsmBackend.cpp (88%) rename lib/Target/ARM/{ => MCTargetDesc}/ARMBaseInfo.h (65%) rename lib/Target/ARM/{ => MCTargetDesc}/ARMFixupKinds.h (100%) rename lib/Target/ARM/{ => MCTargetDesc}/ARMMCCodeEmitter.cpp (82%) rename lib/Target/ARM/{ => MCTargetDesc}/ARMMCExpr.cpp (100%) rename lib/Target/ARM/{ => MCTargetDesc}/ARMMCExpr.h (100%) rename lib/Target/ARM/{ => MCTargetDesc}/ARMMachObjectWriter.cpp (99%) delete mode 100644 lib/Target/ARM/NEONMoveFix.cpp rename lib/Target/MBlaze/{ => MCTargetDesc}/MBlazeAsmBackend.cpp (91%) create mode 100644 lib/Target/MBlaze/MCTargetDesc/MBlazeBaseInfo.h rename lib/Target/MBlaze/{ => MCTargetDesc}/MBlazeMCCodeEmitter.cpp (97%) create mode 100644 lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp create mode 100644 lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h create mode 100644 lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h create mode 100644 lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp create mode 100644 lib/Target/Mips/Mips64InstrInfo.td create mode 100644 lib/Target/Mips/MipsCodeEmitter.cpp create mode 100644 lib/Target/Mips/MipsJITInfo.cpp create mode 100644 lib/Target/Mips/MipsJITInfo.h create mode 100644 lib/Target/Mips/MipsRelocations.h create mode 100644 lib/Target/PTX/InstPrinter/CMakeLists.txt create mode 100644 lib/Target/PTX/InstPrinter/Makefile create mode 100644 lib/Target/PTX/InstPrinter/PTXInstPrinter.cpp create mode 100644 lib/Target/PTX/InstPrinter/PTXInstPrinter.h create mode 100644 lib/Target/PTX/MCTargetDesc/PTXBaseInfo.h create mode 100644 lib/Target/PTX/PTXAsmPrinter.h delete mode 100644 lib/Target/PTX/PTXCallingConv.td create mode 100644 lib/Target/PTX/PTXFPRoundingModePass.cpp create mode 100644 lib/Target/PTX/PTXInstrLoadStore.td create mode 100644 lib/Target/PTX/PTXMCInstLower.cpp create mode 100644 lib/Target/PTX/PTXParamManager.cpp create mode 100644 lib/Target/PTX/PTXParamManager.h create mode 100644 lib/Target/PTX/PTXRegAlloc.cpp create mode 100644 lib/Target/PTX/PTXSelectionDAGInfo.cpp create mode 100644 lib/Target/PTX/PTXSelectionDAGInfo.h delete mode 100755 lib/Target/PTX/generate-register-td.py rename lib/Target/PowerPC/{ => MCTargetDesc}/PPCAsmBackend.cpp (56%) create mode 100644 lib/Target/PowerPC/MCTargetDesc/PPCBaseInfo.h rename lib/Target/PowerPC/{ => MCTargetDesc}/PPCFixupKinds.h (100%) rename lib/Target/PowerPC/{ => MCTargetDesc}/PPCMCCodeEmitter.cpp (97%) rename lib/Target/PowerPC/{ => MCTargetDesc}/PPCPredicates.cpp (100%) rename lib/Target/PowerPC/{ => MCTargetDesc}/PPCPredicates.h (98%) delete mode 100644 lib/Target/TargetAsmInfo.cpp rename lib/Target/X86/{ => MCTargetDesc}/X86AsmBackend.cpp (94%) create mode 100644 lib/Target/X86/MCTargetDesc/X86BaseInfo.h rename lib/Target/X86/{ => MCTargetDesc}/X86FixupKinds.h (100%) rename lib/Target/X86/{ => MCTargetDesc}/X86MCCodeEmitter.cpp (89%) rename lib/Target/X86/{ => MCTargetDesc}/X86MachObjectWriter.cpp (99%) create mode 100644 lib/Target/X86/X86VZeroUpper.cpp delete mode 100644 lib/Transforms/IPO/LowerSetJmp.cpp create mode 100644 lib/Transforms/IPO/PassManagerBuilder.cpp delete mode 100644 lib/Transforms/Scalar/TailDuplication.cpp create mode 100644 lib/Transforms/Utils/SimplifyIndVar.cpp create mode 100644 lib/VMCore/GCOV.cpp create mode 100644 test/Analysis/BasicAA/memset_pattern.ll create mode 100644 test/Analysis/BlockFrequencyInfo/basic.ll rename test/{Transforms/LowerSetJmp => Analysis/BlockFrequencyInfo}/dg.exp (100%) create mode 100644 test/Analysis/ScalarEvolution/2011-10-04-ConstEvolve.ll create mode 100644 test/Assembler/atomic.ll create mode 100644 test/Bindings/Ocaml/ipo_opts.ml create mode 100644 test/CodeGen/ARM/2011-08-02-MergedGlobalDbg.ll create mode 100644 test/CodeGen/ARM/2011-08-12-vmovqqqq-pseudo.ll create mode 100644 test/CodeGen/ARM/2011-08-25-ldmia_ret.ll create mode 100644 test/CodeGen/ARM/2011-08-29-SchedCycle.ll create mode 100644 test/CodeGen/ARM/2011-08-29-ldr_pre_imm.ll create mode 100644 test/CodeGen/ARM/2011-09-09-OddVectorDivision.ll create mode 100644 test/CodeGen/ARM/2011-09-19-cpsr.ll create mode 100644 test/CodeGen/ARM/2011-09-28-CMovCombineBug.ll create mode 100644 test/CodeGen/ARM/atomic-64bit.ll create mode 100644 test/CodeGen/ARM/atomic-load-store.ll create mode 100644 test/CodeGen/ARM/crash-greedy-v6.ll create mode 100644 test/CodeGen/ARM/debug-info-arg.ll create mode 100644 test/CodeGen/ARM/divmod.ll create mode 100644 test/CodeGen/ARM/elf-lcomm-align.ll create mode 100644 test/CodeGen/ARM/inlineasm4.ll create mode 100644 test/CodeGen/ARM/subreg-remat.ll create mode 100644 test/CodeGen/ARM/thumb2-it-block.ll create mode 100644 test/CodeGen/ARM/widen-vmovs.ll delete mode 100644 test/CodeGen/Alpha/wmb.ll delete mode 100644 test/CodeGen/Generic/2004-02-08-UnwindSupport.ll create mode 100644 test/CodeGen/Generic/exception-handling.ll delete mode 100644 test/CodeGen/Generic/promote-integers.ll delete mode 100644 test/CodeGen/Mips/2008-07-05-ByVal.ll delete mode 100644 test/CodeGen/Mips/2010-07-20-Select.ll create mode 100644 test/CodeGen/Mips/brdelayslot.ll create mode 100644 test/CodeGen/Mips/constantfp0.ll create mode 100644 test/CodeGen/Mips/cprestore.ll create mode 100644 test/CodeGen/Mips/extins.ll create mode 100644 test/CodeGen/Mips/mips64fpldst.ll create mode 100644 test/CodeGen/Mips/mips64instrs.ll create mode 100644 test/CodeGen/Mips/mips64intldst.ll create mode 100644 test/CodeGen/Mips/mips64shift.ll create mode 100644 test/CodeGen/Mips/mipslopat.ll create mode 100644 test/CodeGen/Mips/unalignedload.ll create mode 100644 test/CodeGen/PTX/20110926-sitofp.ll create mode 100644 test/CodeGen/PTX/simple-call.ll create mode 100644 test/CodeGen/PTX/stack-object.ll create mode 100644 test/CodeGen/PowerPC/cr1eq.ll delete mode 100644 test/CodeGen/Thumb2/thumb2-barrier.ll create mode 100644 test/CodeGen/Thumb2/thumb2-sxt-uxt.ll delete mode 100644 test/CodeGen/X86/2006-07-19-ATTAsm.ll delete mode 100644 test/CodeGen/X86/2008-10-02-Atomics32-2.ll create mode 100644 test/CodeGen/X86/2011-08-23-PerformSubCombine128.ll create mode 100644 test/CodeGen/X86/2011-08-23-Trampoline.ll create mode 100644 test/CodeGen/X86/2011-08-29-BlockConstant.ll create mode 100644 test/CodeGen/X86/2011-08-29-InitOrder.ll create mode 100644 test/CodeGen/X86/2011-09-14-valcoalesce.ll create mode 100644 test/CodeGen/X86/2011-09-18-sse2cmp.ll create mode 100644 test/CodeGen/X86/2011-09-21-setcc-bug.ll create mode 100644 test/CodeGen/X86/2011-10-11-SpillDead.ll create mode 100644 test/CodeGen/X86/2011-10-11-srl.ll create mode 100644 test/CodeGen/X86/2011-10-12-MachineCSE.ll delete mode 100644 test/CodeGen/X86/Atomics-32.ll create mode 100644 test/CodeGen/X86/MachineSink-DbgValue.ll create mode 100644 test/CodeGen/X86/MachineSink-eflags.ll delete mode 100644 test/CodeGen/X86/SIMD/dg.exp delete mode 100644 test/CodeGen/X86/SIMD/notvunpcklpd.ll delete mode 100644 test/CodeGen/X86/SIMD/notvunpcklps.ll delete mode 100644 test/CodeGen/X86/SIMD/vunpcklpd.ll delete mode 100644 test/CodeGen/X86/SIMD/vunpcklps.ll create mode 100644 test/CodeGen/X86/alignment-2.ll create mode 100644 test/CodeGen/X86/atomic-load-store-wide.ll create mode 100644 test/CodeGen/X86/atomic-load-store.ll delete mode 100644 test/CodeGen/X86/avx-256-arith.s delete mode 100644 test/CodeGen/X86/avx-256.ll rename test/CodeGen/X86/{avx-256-arith.ll => avx-arith.ll} (51%) create mode 100644 test/CodeGen/X86/avx-basic.ll create mode 100644 test/CodeGen/X86/avx-bitcast.ll create mode 100644 test/CodeGen/X86/avx-blend.ll create mode 100644 test/CodeGen/X86/avx-cast.ll create mode 100644 test/CodeGen/X86/avx-cmp.ll rename test/CodeGen/X86/{avx-128.ll => avx-cvt.ll} (53%) rename test/CodeGen/X86/{avx-256-logic.ll => avx-logic.ll} (93%) create mode 100644 test/CodeGen/X86/avx-minmax.ll create mode 100644 test/CodeGen/X86/avx-movdup.ll create mode 100644 test/CodeGen/X86/avx-select.ll create mode 100644 test/CodeGen/X86/avx-shift.ll create mode 100644 test/CodeGen/X86/avx-shuffle.ll create mode 100644 test/CodeGen/X86/avx-splat.ll create mode 100644 test/CodeGen/X86/avx-unpack.ll create mode 100644 test/CodeGen/X86/avx-vbroadcast.ll create mode 100644 test/CodeGen/X86/avx-vextractf128.ll create mode 100644 test/CodeGen/X86/avx-vinsertf128.ll create mode 100644 test/CodeGen/X86/avx-vmovddup.ll create mode 100644 test/CodeGen/X86/avx-vperm2f128.ll create mode 100644 test/CodeGen/X86/avx-vpermil.ll create mode 100644 test/CodeGen/X86/avx-vshufp.ll create mode 100644 test/CodeGen/X86/avx-vzeroupper.ll create mode 100644 test/CodeGen/X86/bmi.ll create mode 100644 test/CodeGen/X86/cmpxchg16b.ll create mode 100644 test/CodeGen/X86/coalescer-dce.ll create mode 100644 test/CodeGen/X86/crash-nosse.ll create mode 100644 test/CodeGen/X86/dbg-at-specficiation.ll create mode 100644 test/CodeGen/X86/dbg-inline.ll create mode 100644 test/CodeGen/X86/dbg-large-unsigned-const.ll create mode 100644 test/CodeGen/X86/haddsub.ll create mode 100644 test/CodeGen/X86/licm-dominance.ll create mode 100644 test/CodeGen/X86/lzcnt.ll create mode 100644 test/CodeGen/X86/movbe.ll rename test/CodeGen/X86/{2011-05-31-movmsk.ll => movmsk.ll} (71%) delete mode 100644 test/CodeGen/X86/nofence.ll create mode 100644 test/CodeGen/X86/norex-subreg.ll create mode 100644 test/CodeGen/X86/opt-shuff-tstore.ll create mode 100644 test/CodeGen/X86/pr10420.ll create mode 100644 test/CodeGen/X86/ptr-rotate.ll create mode 100644 test/CodeGen/X86/segmented-stacks.ll create mode 100644 test/CodeGen/X86/split-vector-bitcast.ll create mode 100644 test/CodeGen/X86/sse2-blend.ll create mode 100644 test/CodeGen/X86/sse41-blend.ll create mode 100644 test/CodeGen/X86/sub.ll create mode 100644 test/CodeGen/X86/tail-call-got.ll create mode 100644 test/CodeGen/X86/trunc-ext-ld-st.ll create mode 100644 test/CodeGen/X86/twoaddr-sink-terminator.ll create mode 100644 test/CodeGen/X86/vec_compare-sse4.ll create mode 100644 test/CodeGen/X86/vec_shuffle-38.ll create mode 100644 test/CodeGen/XCore/2011-08-01-DynamicAllocBug.ll create mode 100644 test/CodeGen/XCore/2011-08-01-VarargsBug.ll create mode 100644 test/CodeGen/XCore/licm-ldwcp.ll delete mode 100644 test/DebugInfo/2009-01-15-member.ll delete mode 100644 test/DebugInfo/2009-10-08-DebugInfo-NullGlobalVariable.ll delete mode 100644 test/DebugInfo/2009-11-06-InvalidDerivedType.ll delete mode 100644 test/DebugInfo/2009-11-10-ParentScope.ll create mode 100644 test/DebugInfo/2011-09-26-GlobalVarContext.ll create mode 100644 test/Feature/exception.ll delete mode 100644 test/FrontendAda/Support/element_copy.ads delete mode 100644 test/FrontendAda/Support/fat_fields.ads delete mode 100644 test/FrontendAda/Support/global_constant.ads delete mode 100644 test/FrontendAda/Support/non_lvalue.ads delete mode 100644 test/FrontendAda/Support/real_cst.ads delete mode 100644 test/FrontendAda/Support/unc_constructor.ads delete mode 100644 test/FrontendAda/Support/var_offset.ads delete mode 100644 test/FrontendAda/Support/var_size.ads delete mode 100644 test/FrontendAda/array_constructor.adb delete mode 100644 test/FrontendAda/array_range_ref.adb delete mode 100644 test/FrontendAda/array_ref.adb delete mode 100644 test/FrontendAda/array_size.adb delete mode 100644 test/FrontendAda/asm.adb delete mode 100644 test/FrontendAda/constant_fold.ads delete mode 100644 test/FrontendAda/debug_var_size.ads delete mode 100644 test/FrontendAda/dg.exp delete mode 100644 test/FrontendAda/element_copy.adb delete mode 100644 test/FrontendAda/emit_var.ads delete mode 100644 test/FrontendAda/fat_fields.adb delete mode 100644 test/FrontendAda/field_order.ads delete mode 100644 test/FrontendAda/global_constant.adb delete mode 100644 test/FrontendAda/init_size.ads delete mode 100644 test/FrontendAda/negative_field_offset.adb delete mode 100644 test/FrontendAda/non_bitfield.ads delete mode 100644 test/FrontendAda/non_lvalue.adb delete mode 100644 test/FrontendAda/placeholder.adb delete mode 100644 test/FrontendAda/real_cst.adb delete mode 100644 test/FrontendAda/switch.adb delete mode 100644 test/FrontendAda/unc_constructor.adb delete mode 100644 test/FrontendAda/var_offset.adb delete mode 100644 test/FrontendAda/var_size.adb delete mode 100644 test/FrontendAda/vce.adb delete mode 100644 test/FrontendAda/vce_lv.adb delete mode 100644 test/FrontendC++/2003-11-02-WeakLinkage.cpp delete mode 100644 test/FrontendC++/2003-11-18-PtrMemConstantInitializer.cpp delete mode 100644 test/FrontendC++/2003-11-25-ReturningOpaqueByValue.cpp delete mode 100644 test/FrontendC++/2003-11-27-MultipleInheritanceThunk.cpp delete mode 100644 test/FrontendC++/2003-11-29-DuplicatedCleanupTest.cpp delete mode 100644 test/FrontendC++/2003-12-08-ArrayOfPtrToMemberFunc.cpp delete mode 100644 test/FrontendC++/2004-01-11-DynamicInitializedConstant.cpp delete mode 100644 test/FrontendC++/2004-03-08-ReinterpretCastCopy.cpp delete mode 100644 test/FrontendC++/2004-03-09-UnmangledBuiltinMethods.cpp delete mode 100644 test/FrontendC++/2004-03-15-CleanupsAndGotos.cpp delete mode 100644 test/FrontendC++/2004-06-08-LateTemplateInstantiation.cpp delete mode 100644 test/FrontendC++/2004-09-27-CompilerCrash.cpp delete mode 100644 test/FrontendC++/2004-09-27-DidntEmitTemplate.cpp delete mode 100644 test/FrontendC++/2004-11-27-EmitsUnusedInlineFunctions.cpp delete mode 100644 test/FrontendC++/2004-11-27-ExceptionCleanupAssertion.cpp delete mode 100644 test/FrontendC++/2004-11-27-FriendDefaultArgCrash.cpp delete mode 100644 test/FrontendC++/2004-11-27-InlineAsmFunctionRedefinition.cpp delete mode 100644 test/FrontendC++/2005-01-03-StaticInitializers.cpp delete mode 100644 test/FrontendC++/2005-02-11-AnonymousUnion.cpp delete mode 100644 test/FrontendC++/2005-02-13-BadDynamicInit.cpp delete mode 100644 test/FrontendC++/2005-02-14-BitFieldOffset.cpp delete mode 100644 test/FrontendC++/2005-02-19-BitfieldStructCrash.cpp delete mode 100644 test/FrontendC++/2005-02-19-UnnamedVirtualThunkArgument.cpp delete mode 100644 test/FrontendC++/2005-02-20-BrokenReferenceTest.cpp delete mode 100644 test/FrontendC++/2005-02-27-PlacementArrayNewCrash.cpp delete mode 100644 test/FrontendC++/2005-07-21-VirtualBaseAccess.cpp delete mode 100644 test/FrontendC++/2006-03-01-GimplifyCrash.cpp delete mode 100644 test/FrontendC++/2006-03-06-C++RecurseCrash.cpp delete mode 100644 test/FrontendC++/2006-09-08-powi.cpp delete mode 100644 test/FrontendC++/2006-09-12-OpaqueStructCrash.cpp delete mode 100644 test/FrontendC++/2006-09-27-Debug-Protection.cpp delete mode 100644 test/FrontendC++/2006-10-30-ClassBitfield.cpp delete mode 100644 test/FrontendC++/2006-11-06-StackTrace.cpp delete mode 100644 test/FrontendC++/2006-11-20-GlobalSymbols.cpp delete mode 100644 test/FrontendC++/2006-11-30-ConstantExprCrash.cpp delete mode 100644 test/FrontendC++/2006-11-30-Pubnames.cpp delete mode 100644 test/FrontendC++/2007-01-02-UnboundedArray.cpp delete mode 100644 test/FrontendC++/2007-01-06-ELF-Thunk-Sections.cpp delete mode 100644 test/FrontendC++/2007-01-06-PtrMethodInit.cpp delete mode 100644 test/FrontendC++/2007-03-27-FunctionVarRename.cpp delete mode 100644 test/FrontendC++/2007-04-05-PackedBitFields-1.cpp delete mode 100644 test/FrontendC++/2007-04-05-PackedBitFieldsOverlap-2.cpp delete mode 100644 test/FrontendC++/2007-04-05-PackedBitFieldsOverlap.cpp delete mode 100644 test/FrontendC++/2007-04-05-PackedBitFieldsSmall.cpp delete mode 100644 test/FrontendC++/2007-04-05-StructPackedFieldUnpacked.cpp delete mode 100644 test/FrontendC++/2007-04-10-PackedUnion.cpp delete mode 100644 test/FrontendC++/2007-04-11-InlineStorageClassC++.cpp delete mode 100644 test/FrontendC++/2007-04-14-FNoBuiltin.cpp delete mode 100644 test/FrontendC++/2007-04-31-TryCatch.cpp delete mode 100644 test/FrontendC++/2007-05-03-VectorInit.cpp delete mode 100644 test/FrontendC++/2007-05-16-ReverseBitFieldCrash.cpp delete mode 100644 test/FrontendC++/2007-05-23-TryFinally.cpp delete mode 100644 test/FrontendC++/2007-07-04-NestedCatches.cpp delete mode 100644 test/FrontendC++/2007-07-29-RestrictPtrArg.cpp delete mode 100644 test/FrontendC++/2007-07-29-RestrictRefArg.cpp delete mode 100644 test/FrontendC++/2007-08-01-RestrictMethod.cpp delete mode 100644 test/FrontendC++/2007-09-10-RecursiveTypeResolution.cpp delete mode 100644 test/FrontendC++/2007-10-01-StructResize.cpp delete mode 100644 test/FrontendC++/2008-01-11-BadWarning.cpp delete mode 100644 test/FrontendC++/2008-01-12-VecInit.cpp delete mode 100644 test/FrontendC++/2008-05-07-CrazyOffsetOf.cpp delete mode 100644 test/FrontendC++/2008-10-29-WrongOffset.cpp delete mode 100644 test/FrontendC++/2009-02-07-VolatileArrayRefHack.cpp delete mode 100644 test/FrontendC++/2009-02-16-CtorNames-dbg.cpp delete mode 100644 test/FrontendC++/2009-03-17-dbg.cpp delete mode 100644 test/FrontendC++/2009-04-21-DtorNames-dbg.cpp delete mode 100644 test/FrontendC++/2009-04-23-bool2.cpp delete mode 100644 test/FrontendC++/2009-05-04-PureConstNounwind.cpp delete mode 100644 test/FrontendC++/2009-06-16-DebugInfoCrash.cpp delete mode 100644 test/FrontendC++/2009-06-20-DarwinPPCLayout.cpp delete mode 100644 test/FrontendC++/2009-06-30-ByrefBlock.cpp delete mode 100644 test/FrontendC++/2009-07-16-PrivateCopyConstructor.cpp delete mode 100644 test/FrontendC++/2009-07-16-Using.cpp delete mode 100644 test/FrontendC++/2009-08-05-ZeroInitWidth.cpp delete mode 100644 test/FrontendC++/2009-08-11-VectorRetTy.cpp delete mode 100644 test/FrontendC++/2009-09-04-modify-crash.cpp delete mode 100644 test/FrontendC++/2009-09-09-packed-layout.cpp delete mode 100644 test/FrontendC++/2009-10-27-crash.cpp delete mode 100644 test/FrontendC++/2009-12-23-MissingSext.cpp delete mode 100644 test/FrontendC++/2010-02-17-DbgArtificialArg.cpp delete mode 100644 test/FrontendC++/2010-03-22-empty-baseclass.cpp delete mode 100644 test/FrontendC++/2010-04-30-OptimizedMethod-Dbg.cpp delete mode 100644 test/FrontendC++/2010-05-10-Var-DbgInfo.cpp delete mode 100644 test/FrontendC++/2010-05-11-alwaysinlineinstantiation.cpp delete mode 100644 test/FrontendC++/2010-05-12-PtrToMember-Dbg.cpp delete mode 100644 test/FrontendC++/2010-06-21-LocalVarDbg.cpp delete mode 100644 test/FrontendC++/2010-06-22-BitfieldInit.cpp delete mode 100644 test/FrontendC++/2010-06-22-ZeroBitfield.cpp delete mode 100644 test/FrontendC++/2010-07-19-nowarn.cpp delete mode 100644 test/FrontendC++/2010-07-23-DeclLoc.cpp delete mode 100644 test/FrontendC++/2010-08-31-ByValArg.cpp delete mode 100644 test/FrontendC++/alignstack.cpp delete mode 100644 test/FrontendC++/dg.exp delete mode 100644 test/FrontendC++/integration-O2.cpp delete mode 100644 test/FrontendC++/m64-ptr.cpp delete mode 100644 test/FrontendC++/member-alignment.cpp delete mode 100644 test/FrontendC++/ptr-to-method-devirt.cpp delete mode 100644 test/FrontendC++/thunk-linkonce-odr.cpp delete mode 100644 test/FrontendC++/varargs.cpp delete mode 100644 test/FrontendC++/weak-external.cpp delete mode 100644 test/FrontendC++/x86-64-abi-sret-vs-2word-struct-param.cpp delete mode 100644 test/FrontendC/2002-01-23-LoadQISIReloadFailure.c delete mode 100644 test/FrontendC/2002-01-24-ComplexSpaceInType.c delete mode 100644 test/FrontendC/2002-01-24-HandleCallInsnSEGV.c delete mode 100644 test/FrontendC/2002-02-13-ConditionalInCall.c delete mode 100644 test/FrontendC/2002-02-13-ReloadProblem.c delete mode 100644 test/FrontendC/2002-02-13-TypeVarNameCollision.c delete mode 100644 test/FrontendC/2002-02-13-UnnamedLocal.c delete mode 100644 test/FrontendC/2002-02-14-EntryNodePreds.c delete mode 100644 test/FrontendC/2002-02-16-RenamingTest.c delete mode 100644 test/FrontendC/2002-02-17-ArgumentAddress.c delete mode 100644 test/FrontendC/2002-02-18-64bitConstant.c delete mode 100644 test/FrontendC/2002-02-18-StaticData.c delete mode 100644 test/FrontendC/2002-03-11-LargeCharInString.c delete mode 100644 test/FrontendC/2002-03-12-ArrayInitialization.c delete mode 100644 test/FrontendC/2002-03-12-StructInitialize.c delete mode 100644 test/FrontendC/2002-03-12-StructInitializer.c delete mode 100644 test/FrontendC/2002-03-14-BrokenPHINode.c delete mode 100644 test/FrontendC/2002-03-14-BrokenSSA.c delete mode 100644 test/FrontendC/2002-03-14-QuotesInStrConst.c delete mode 100644 test/FrontendC/2002-04-07-SwitchStmt.c delete mode 100644 test/FrontendC/2002-04-08-LocalArray.c delete mode 100644 test/FrontendC/2002-04-09-StructRetVal.c delete mode 100644 test/FrontendC/2002-04-10-StructParameters.c delete mode 100644 test/FrontendC/2002-05-23-StaticValues.c delete mode 100644 test/FrontendC/2002-05-23-TypeNameCollision.c delete mode 100644 test/FrontendC/2002-05-24-Alloca.c delete mode 100644 test/FrontendC/2002-06-25-FWriteInterfaceFailure.c delete mode 100644 test/FrontendC/2002-07-14-MiscListTests.c delete mode 100644 test/FrontendC/2002-07-14-MiscTests.c delete mode 100644 test/FrontendC/2002-07-14-MiscTests2.c delete mode 100644 test/FrontendC/2002-07-14-MiscTests3.c delete mode 100644 test/FrontendC/2002-07-16-HardStringInit.c delete mode 100644 test/FrontendC/2002-07-17-StringConstant.c delete mode 100644 test/FrontendC/2002-07-29-Casts.c delete mode 100644 test/FrontendC/2002-07-30-SubregSetAssertion.c delete mode 100644 test/FrontendC/2002-07-30-UnionTest.c delete mode 100644 test/FrontendC/2002-07-30-VarArgsCallFailure.c delete mode 100644 test/FrontendC/2002-07-31-BadAssert.c delete mode 100644 test/FrontendC/2002-07-31-SubregFailure.c delete mode 100644 test/FrontendC/2002-08-02-UnionTest.c delete mode 100644 test/FrontendC/2002-08-19-RecursiveLocals.c delete mode 100644 test/FrontendC/2002-09-08-PointerShifts.c delete mode 100644 test/FrontendC/2002-09-18-UnionProblem.c delete mode 100644 test/FrontendC/2002-09-19-StarInLabel.c delete mode 100644 test/FrontendC/2002-10-12-TooManyArguments.c delete mode 100644 test/FrontendC/2002-12-15-GlobalBoolTest.c delete mode 100644 test/FrontendC/2002-12-15-GlobalConstantTest.c delete mode 100644 test/FrontendC/2002-12-15-GlobalRedefinition.c delete mode 100644 test/FrontendC/2002-12-15-StructParameters.c delete mode 100644 test/FrontendC/2003-01-30-UnionInit.c delete mode 100644 test/FrontendC/2003-03-03-DeferredType.c delete mode 100644 test/FrontendC/2003-06-22-UnionCrash.c delete mode 100644 test/FrontendC/2003-06-23-GCC-fold-infinite-recursion.c delete mode 100644 test/FrontendC/2003-06-26-CFECrash.c delete mode 100644 test/FrontendC/2003-06-29-MultipleFunctionDefinition.c delete mode 100644 test/FrontendC/2003-07-22-ArrayAccessTypeSafety.c delete mode 100644 test/FrontendC/2003-08-06-BuiltinSetjmpLongjmp.c delete mode 100644 test/FrontendC/2003-08-17-DeadCodeShortCircuit.c delete mode 100644 test/FrontendC/2003-08-18-SigSetJmp.c delete mode 100644 test/FrontendC/2003-08-18-StructAsValue.c delete mode 100644 test/FrontendC/2003-08-20-BadBitfieldRef.c delete mode 100644 test/FrontendC/2003-08-20-PrototypeMismatch.c delete mode 100644 test/FrontendC/2003-08-20-vfork-bug.c delete mode 100644 test/FrontendC/2003-08-21-BinOp-Type-Mismatch.c delete mode 100644 test/FrontendC/2003-08-21-StmtExpr.c delete mode 100644 test/FrontendC/2003-08-21-WideString.c delete mode 100644 test/FrontendC/2003-08-23-LocalUnionTest.c delete mode 100644 test/FrontendC/2003-08-29-BitFieldStruct.c delete mode 100644 test/FrontendC/2003-08-29-HugeCharConst.c delete mode 100644 test/FrontendC/2003-08-29-StructLayoutBug.c delete mode 100644 test/FrontendC/2003-08-30-AggregateInitializer.c delete mode 100644 test/FrontendC/2003-08-30-LargeIntegerBitfieldMember.c delete mode 100644 test/FrontendC/2003-09-18-BitfieldTests.c delete mode 100644 test/FrontendC/2003-09-30-StructLayout.c delete mode 100644 test/FrontendC/2003-10-02-UnionLValueError.c delete mode 100644 test/FrontendC/2003-10-06-NegateExprType.c delete mode 100644 test/FrontendC/2003-10-09-UnionInitializerBug.c delete mode 100644 test/FrontendC/2003-10-28-ident.c delete mode 100644 test/FrontendC/2003-10-29-AsmRename.c delete mode 100644 test/FrontendC/2003-11-01-C99-CompoundLiteral.c delete mode 100644 test/FrontendC/2003-11-01-EmptyStructCrash.c delete mode 100644 test/FrontendC/2003-11-01-GlobalUnionInit.c delete mode 100644 test/FrontendC/2003-11-03-AddrArrayElement.c delete mode 100644 test/FrontendC/2003-11-04-EmptyStruct.c delete mode 100644 test/FrontendC/2003-11-04-OutOfMemory.c delete mode 100644 test/FrontendC/2003-11-08-PointerSubNotGetelementptr.c delete mode 100644 test/FrontendC/2003-11-12-VoidString.c delete mode 100644 test/FrontendC/2003-11-13-TypeSafety.c delete mode 100644 test/FrontendC/2003-11-16-StaticArrayInit.c delete mode 100644 test/FrontendC/2003-11-18-CondExprLValue.c delete mode 100644 test/FrontendC/2003-11-19-AddressOfRegister.c delete mode 100644 test/FrontendC/2003-11-19-BitFieldArray.c delete mode 100644 test/FrontendC/2003-11-20-Bitfields.c delete mode 100644 test/FrontendC/2003-11-20-ComplexDivision.c delete mode 100644 test/FrontendC/2003-11-20-UnionBitfield.c delete mode 100644 test/FrontendC/2003-11-26-PointerShift.c delete mode 100644 test/FrontendC/2003-11-27-ConstructorCast.c delete mode 100644 test/FrontendC/2003-11-27-UnionCtorInitialization.c delete mode 100644 test/FrontendC/2003-12-14-ExternInlineSupport.c delete mode 100644 test/FrontendC/2004-01-01-UnknownInitSize.c delete mode 100644 test/FrontendC/2004-01-08-ExternInlineRedefine.c delete mode 100644 test/FrontendC/2004-02-12-LargeAggregateCopy.c delete mode 100644 test/FrontendC/2004-02-13-BuiltinFrameReturnAddress.c delete mode 100644 test/FrontendC/2004-02-13-IllegalVararg.c delete mode 100644 test/FrontendC/2004-02-13-Memset.c delete mode 100644 test/FrontendC/2004-02-14-ZeroInitializer.c delete mode 100644 test/FrontendC/2004-02-20-Builtins.c delete mode 100644 test/FrontendC/2004-03-07-ComplexDivEquals.c delete mode 100644 test/FrontendC/2004-03-07-ExternalConstant.c delete mode 100644 test/FrontendC/2004-03-09-LargeArrayInitializers.c delete mode 100644 test/FrontendC/2004-03-15-SimpleIndirectGoto.c delete mode 100644 test/FrontendC/2004-03-16-AsmRegisterCrash.c delete mode 100644 test/FrontendC/2004-05-07-VarArrays.c delete mode 100644 test/FrontendC/2004-05-21-IncompleteEnum.c delete mode 100644 test/FrontendC/2004-06-08-OpaqueStructArg.c delete mode 100644 test/FrontendC/2004-06-17-UnorderedBuiltins.c delete mode 100644 test/FrontendC/2004-06-17-UnorderedCompares.c delete mode 100644 test/FrontendC/2004-06-18-VariableLengthArrayOfStructures.c delete mode 100644 test/FrontendC/2004-07-06-FunctionCast.c delete mode 100644 test/FrontendC/2004-08-06-LargeStructTest.c delete mode 100644 test/FrontendC/2004-11-25-UnnamedBitfieldPadding.c delete mode 100644 test/FrontendC/2004-11-27-InvalidConstantExpr.c delete mode 100644 test/FrontendC/2004-11-27-StaticFunctionRedeclare.c delete mode 100644 test/FrontendC/2004-11-27-VariableSizeInStructure.c delete mode 100644 test/FrontendC/2005-01-02-ConstantInits.c delete mode 100644 test/FrontendC/2005-01-02-PointerDifference.c delete mode 100644 test/FrontendC/2005-01-02-VAArgError-ICE.c delete mode 100644 test/FrontendC/2005-02-20-AggregateSAVEEXPR.c delete mode 100644 test/FrontendC/2005-02-27-MarkGlobalConstant.c delete mode 100644 test/FrontendC/2005-03-05-OffsetOfHack.c delete mode 100644 test/FrontendC/2005-03-06-OffsetOfStructCrash.c delete mode 100644 test/FrontendC/2005-03-11-Prefetch.c delete mode 100644 test/FrontendC/2005-04-09-ComplexOps.c delete mode 100644 test/FrontendC/2005-05-06-CountBuiltins.c delete mode 100644 test/FrontendC/2005-05-10-GlobalUnionInit.c delete mode 100644 test/FrontendC/2005-06-15-ExpandGotoInternalProblem.c delete mode 100644 test/FrontendC/2005-07-20-SqrtNoErrno.c delete mode 100644 test/FrontendC/2005-07-26-UnionInitCrash.c delete mode 100644 test/FrontendC/2005-07-28-IncorrectWeakGlobal.c delete mode 100644 test/FrontendC/2005-09-20-ComplexConstants.c delete mode 100644 test/FrontendC/2005-09-24-AsmUserPrefix.c delete mode 100644 test/FrontendC/2005-09-24-BitFieldCrash.c delete mode 100644 test/FrontendC/2005-10-18-VariableSizedElementCrash.c delete mode 100644 test/FrontendC/2005-12-04-AttributeUsed.c delete mode 100644 test/FrontendC/2005-12-04-DeclarationLineNumbers.c delete mode 100644 test/FrontendC/2006-01-13-Includes.c delete mode 100644 test/FrontendC/2006-01-13-StackSave.c delete mode 100644 test/FrontendC/2006-01-16-BitCountIntrinsicsUnsigned.c delete mode 100644 test/FrontendC/2006-01-23-FileScopeAsm.c delete mode 100644 test/FrontendC/2006-03-03-MissingInitializer.c delete mode 100644 test/FrontendC/2006-03-16-VectorCtor.c delete mode 100644 test/FrontendC/2006-03-17-KnRMismatch.c delete mode 100644 test/FrontendC/2006-05-01-AppleAlignmentPragma.c delete mode 100644 test/FrontendC/2006-05-19-SingleEltReturn.c delete mode 100644 test/FrontendC/2006-07-31-PR854.c delete mode 100644 test/FrontendC/2006-09-11-BitfieldRefCrash.c delete mode 100644 test/FrontendC/2006-09-18-fwrite-cast-crash.c delete mode 100644 test/FrontendC/2006-09-21-IncompleteElementType.c delete mode 100644 test/FrontendC/2006-09-25-DebugFilename.c delete mode 100644 test/FrontendC/2006-09-25-DebugFilename.h delete mode 100644 test/FrontendC/2006-09-28-SimpleAsm.c delete mode 100644 test/FrontendC/2006-10-30-ArrayCrash.c delete mode 100644 test/FrontendC/2006-12-14-ordered_expr.c delete mode 100644 test/FrontendC/2007-01-06-KNR-Proto.c delete mode 100644 test/FrontendC/2007-01-20-VectorICE.c delete mode 100644 test/FrontendC/2007-01-24-InlineAsmCModifier.c delete mode 100644 test/FrontendC/2007-02-04-AddrLValue-2.c delete mode 100644 test/FrontendC/2007-02-04-AddrLValue.c delete mode 100644 test/FrontendC/2007-02-04-EmptyStruct.c delete mode 100644 test/FrontendC/2007-02-04-WITH_SIZE_EXPR.c delete mode 100644 test/FrontendC/2007-02-05-nested.c delete mode 100644 test/FrontendC/2007-02-07-AddrLabel.c delete mode 100644 test/FrontendC/2007-02-16-VariableSizeStructArg.c delete mode 100644 test/FrontendC/2007-02-16-VoidPtrDiff.c delete mode 100644 test/FrontendC/2007-02-16-WritableStrings.c delete mode 100644 test/FrontendC/2007-02-25-C-DotDotDot.c delete mode 100644 test/FrontendC/2007-03-01-VarSizeArrayIdx.c delete mode 100644 test/FrontendC/2007-03-05-DataLayout.c delete mode 100644 test/FrontendC/2007-03-06-VarSizeInStruct1.c delete mode 100644 test/FrontendC/2007-03-06-VarSizeInStruct2.c delete mode 100644 test/FrontendC/2007-03-26-BitfieldAfterZeroWidth.c delete mode 100644 test/FrontendC/2007-03-26-ZeroWidthBitfield.c delete mode 100644 test/FrontendC/2007-03-27-ArrayCompatible.c delete mode 100644 test/FrontendC/2007-03-27-VarLengthArray.c delete mode 100644 test/FrontendC/2007-04-05-PackedBitFields-2.c delete mode 100644 test/FrontendC/2007-04-05-PackedBitFields.c delete mode 100644 test/FrontendC/2007-04-05-PackedStruct.c delete mode 100644 test/FrontendC/2007-04-05-PadBeforeZeroLengthField.c delete mode 100644 test/FrontendC/2007-04-05-UnPackedStruct.c delete mode 100644 test/FrontendC/2007-04-11-InlineAsmStruct.c delete mode 100644 test/FrontendC/2007-04-11-InlineAsmUnion.c delete mode 100644 test/FrontendC/2007-04-11-InlineStorageClassC89.c delete mode 100644 test/FrontendC/2007-04-11-InlineStorageClassC99.c delete mode 100644 test/FrontendC/2007-04-11-PR1321.c delete mode 100644 test/FrontendC/2007-04-13-InlineAsmStruct2.c delete mode 100644 test/FrontendC/2007-04-13-InlineAsmUnion2.c delete mode 100644 test/FrontendC/2007-04-14-FNoBuiltin.c delete mode 100644 test/FrontendC/2007-04-17-ZeroSizeBitFields.c delete mode 100644 test/FrontendC/2007-04-24-VolatileStructCopy.c delete mode 100644 test/FrontendC/2007-04-24-bit-not-expr.c delete mode 100644 test/FrontendC/2007-04-24-str-const.c delete mode 100644 test/FrontendC/2007-05-07-NestedStructReturn.c delete mode 100644 test/FrontendC/2007-05-07-PaddingElements.c delete mode 100644 test/FrontendC/2007-05-08-PCH.c delete mode 100644 test/FrontendC/2007-05-11-str-const.c delete mode 100644 test/FrontendC/2007-05-15-PaddingElement.c delete mode 100644 test/FrontendC/2007-05-16-EmptyStruct.c delete mode 100644 test/FrontendC/2007-05-29-UnionCopy.c delete mode 100644 test/FrontendC/2007-06-05-NoInlineAttribute.c delete mode 100644 test/FrontendC/2007-06-15-AnnotateAttribute.c delete mode 100644 test/FrontendC/2007-06-18-SextAttrAggregate.c delete mode 100644 test/FrontendC/2007-07-29-RestrictPtrArg.c delete mode 100644 test/FrontendC/2007-08-01-LoadStoreAlign.c delete mode 100644 test/FrontendC/2007-08-21-ComplexCst.c delete mode 100644 test/FrontendC/2007-08-22-CTTZ.c delete mode 100644 test/FrontendC/2007-09-05-ConstCtor.c delete mode 100644 test/FrontendC/2007-09-12-PragmaPack.c delete mode 100644 test/FrontendC/2007-09-14-NegatePointer.c delete mode 100644 test/FrontendC/2007-09-17-WeakRef.c delete mode 100644 test/FrontendC/2007-09-20-GcrootAttribute.c delete mode 100644 test/FrontendC/2007-09-26-Alignment.c delete mode 100644 test/FrontendC/2007-09-27-ComplexIntCompare.c delete mode 100644 test/FrontendC/2007-09-28-PackedUnionMember.c delete mode 100644 test/FrontendC/2007-10-01-BuildArrayRef.c delete mode 100644 test/FrontendC/2007-10-02-VolatileArray.c delete mode 100644 test/FrontendC/2007-10-15-VoidPtr.c delete mode 100644 test/FrontendC/2007-10-30-Volatile.c delete mode 100644 test/FrontendC/2007-11-07-AlignedMemcpy.c delete mode 100644 test/FrontendC/2007-11-07-CopyAggregateAlign.c delete mode 100644 test/FrontendC/2007-11-07-ZeroAggregateAlign.c delete mode 100644 test/FrontendC/2007-11-27-SExtZExt.c delete mode 100644 test/FrontendC/2007-11-28-GlobalInitializer.c delete mode 100644 test/FrontendC/2007-12-16-AsmNoUnwind.c delete mode 100644 test/FrontendC/2007-12-VarArrayDebug.c delete mode 100644 test/FrontendC/2008-01-04-WideBitfield.c delete mode 100644 test/FrontendC/2008-01-07-UnusualIntSize.c delete mode 100644 test/FrontendC/2008-01-11-ChainConsistency.c delete mode 100644 test/FrontendC/2008-01-21-PackedBitFields.c delete mode 100644 test/FrontendC/2008-01-21-PackedStructField.c delete mode 100644 test/FrontendC/2008-01-24-StructAlignAndBitFields.c delete mode 100644 test/FrontendC/2008-01-25-ByValReadNone.c delete mode 100644 test/FrontendC/2008-01-25-ZeroSizedAggregate.c delete mode 100644 test/FrontendC/2008-01-28-PragmaMark.c delete mode 100644 test/FrontendC/2008-01-28-UnionSize.c delete mode 100644 test/FrontendC/2008-02-11-AnnotateBuiltin.c delete mode 100644 test/FrontendC/2008-03-03-CtorAttrType.c delete mode 100644 test/FrontendC/2008-03-05-syncPtr.c delete mode 100644 test/FrontendC/2008-03-24-BitField-And-Alloca.c delete mode 100644 test/FrontendC/2008-03-26-PackedBitFields.c delete mode 100644 test/FrontendC/2008-04-08-NoExceptions.c delete mode 100644 test/FrontendC/2008-05-06-CFECrash.c delete mode 100644 test/FrontendC/2008-05-12-TempUsedBeforeDef.c delete mode 100644 test/FrontendC/2008-05-19-AlwaysInline.c delete mode 100644 test/FrontendC/2008-07-08-FAbsAttributes.c delete mode 100644 test/FrontendC/2008-08-07-AlignPadding1.c delete mode 100644 test/FrontendC/2008-08-07-AlignPadding2.c delete mode 100644 test/FrontendC/2008-08-07-GEPIntToPtr.c delete mode 100644 test/FrontendC/2008-09-03-WeakAlias.c delete mode 100644 test/FrontendC/2008-10-13-FrontendCrash.c delete mode 100644 test/FrontendC/2008-10-30-ZeroPlacement.c delete mode 100644 test/FrontendC/2008-11-02-WeakAlias.c delete mode 100644 test/FrontendC/2008-11-08-InstCombineSelect.c delete mode 100644 test/FrontendC/2008-11-11-AnnotateStructFieldAttribute.c delete mode 100644 test/FrontendC/2008-12-23-AsmIntPointerTie.c delete mode 100644 test/FrontendC/2009-01-05-BlockInlining.c delete mode 100644 test/FrontendC/2009-01-20-k8.c delete mode 100644 test/FrontendC/2009-01-21-InvalidIterator.c delete mode 100644 test/FrontendC/2009-02-13-zerosize-union-field-ppc.c delete mode 100644 test/FrontendC/2009-02-13-zerosize-union-field.c delete mode 100644 test/FrontendC/2009-02-17-BitField-dbg.c delete mode 100644 test/FrontendC/2009-03-01-MallocNoAlias.c delete mode 100644 test/FrontendC/2009-03-08-ZeroEltStructCrash.c delete mode 100644 test/FrontendC/2009-03-09-WeakDeclarations-1.c delete mode 100644 test/FrontendC/2009-03-13-dbg.c delete mode 100644 test/FrontendC/2009-04-22-UnknownSize.c delete mode 100644 test/FrontendC/2009-04-28-UnionArrayCrash.c delete mode 100644 test/FrontendC/2009-05-04-EnumInreg.c delete mode 100644 test/FrontendC/2009-05-17-AlwaysInline.c delete mode 100644 test/FrontendC/2009-06-14-HighlyAligned.c delete mode 100644 test/FrontendC/2009-06-18-StaticInitTailPadPack.c delete mode 100644 test/FrontendC/2009-07-14-VoidPtr.c delete mode 100644 test/FrontendC/2009-07-15-pad-wchar_t-array.c delete mode 100644 test/FrontendC/2009-07-17-VoidParameter.c delete mode 100644 test/FrontendC/2009-07-22-StructLayout.c delete mode 100644 test/FrontendC/2009-08-11-AsmBlocksComplexJumpTarget.c delete mode 100644 test/FrontendC/2009-09-24-SqrtErrno.c delete mode 100644 test/FrontendC/2009-12-07-BitFieldAlignment.c delete mode 100644 test/FrontendC/2010-01-05-LinkageName.c delete mode 100644 test/FrontendC/2010-01-13-MemBarrier.c delete mode 100644 test/FrontendC/2010-01-14-FnType-DebugInfo.c delete mode 100644 test/FrontendC/2010-01-14-StaticVariable.c delete mode 100644 test/FrontendC/2010-01-18-Inlined-Debug.c delete mode 100644 test/FrontendC/2010-02-10-PointerName.c delete mode 100644 test/FrontendC/2010-02-15-DbgStaticVar.c delete mode 100644 test/FrontendC/2010-02-16-DbgVarScope.c delete mode 100644 test/FrontendC/2010-02-18-Dbg-VectorType.c delete mode 100644 test/FrontendC/2010-03-10-arm-asmreg.c delete mode 100644 test/FrontendC/2010-03-5-LexicalScope.c delete mode 100644 test/FrontendC/2010-05-14-Optimized-VarType.c delete mode 100644 test/FrontendC/2010-05-18-asmsched.c delete mode 100644 test/FrontendC/2010-05-18-palignr.c delete mode 100644 test/FrontendC/2010-05-26-AsmSideEffect.c delete mode 100644 test/FrontendC/2010-05-31-palignr.c delete mode 100644 test/FrontendC/2010-06-11-SaveExpr.c delete mode 100644 test/FrontendC/2010-06-17-asmcrash.c delete mode 100644 test/FrontendC/2010-06-28-DbgLocalVar.c delete mode 100644 test/FrontendC/2010-06-28-nowarn.c delete mode 100644 test/FrontendC/2010-07-08-DeclDebugLineNo.c delete mode 100644 test/FrontendC/2010-07-14-overconservative-align.c delete mode 100644 test/FrontendC/2010-07-14-ref-off-end.c delete mode 100644 test/FrontendC/2010-07-27-MinNoFoldConst.c delete mode 100644 test/FrontendC/2010-08-12-asm-aggr-arg.c delete mode 100644 test/FrontendC/2010-11-16-asmblock.c delete mode 100644 test/FrontendC/2010-12-01-CommonGlobal.c delete mode 100644 test/FrontendC/2011-02-21-DATA-common.c delete mode 100644 test/FrontendC/2011-03-02-UnionInitializer.c delete mode 100644 test/FrontendC/2011-03-08-ZeroFieldUnionInitializer.c delete mode 100644 test/FrontendC/2011-03-31-ArrayRefFolding.c delete mode 100644 test/FrontendC/ARM/dg.exp delete mode 100644 test/FrontendC/ARM/inline-asm-multichar.c delete mode 100644 test/FrontendC/Atomics-no64bit.c delete mode 100644 test/FrontendC/Atomics.c delete mode 100644 test/FrontendC/BasicInstrs.c delete mode 100644 test/FrontendC/alignstack.c delete mode 100644 test/FrontendC/always-inline.c delete mode 100644 test/FrontendC/arrayderef.c delete mode 100644 test/FrontendC/asm-reg-var-local.c delete mode 100644 test/FrontendC/attribute_constructor.c delete mode 100644 test/FrontendC/block-copy.c delete mode 100644 test/FrontendC/crash-invalid-array.c delete mode 100644 test/FrontendC/dg.exp delete mode 100644 test/FrontendC/exact-div-expr.c delete mode 100644 test/FrontendC/extern-weak.c delete mode 100644 test/FrontendC/fp-logical.c delete mode 100644 test/FrontendC/func-aligned.c delete mode 100644 test/FrontendC/funccall.c delete mode 100644 test/FrontendC/hidden-visibility.c delete mode 100644 test/FrontendC/implicit-arg.c delete mode 100644 test/FrontendC/inline-asm-function.c delete mode 100644 test/FrontendC/inline-asm-mrv.c delete mode 100644 test/FrontendC/libcalls-d.c delete mode 100644 test/FrontendC/libcalls-ld.c delete mode 100644 test/FrontendC/libcalls.c delete mode 100644 test/FrontendC/misaligned-param.c delete mode 100644 test/FrontendC/mmx-inline-asm.c delete mode 100644 test/FrontendC/nested-functions.c delete mode 100644 test/FrontendC/pr2394.c delete mode 100644 test/FrontendC/pr3518.c delete mode 100644 test/FrontendC/pr4349.c delete mode 100644 test/FrontendC/pr5406.c delete mode 100644 test/FrontendC/ptr-rotate.c delete mode 100644 test/FrontendC/redef-ext-inline.c delete mode 100644 test/FrontendC/sret.c delete mode 100644 test/FrontendC/sret2.c delete mode 100644 test/FrontendC/struct-matching-constraint.c delete mode 100644 test/FrontendC/unaligned-memcpy.c delete mode 100644 test/FrontendC/union-align.c delete mode 100644 test/FrontendC/vla-1.c delete mode 100644 test/FrontendC/vla-2.c delete mode 100644 test/FrontendC/vla-3.c delete mode 100644 test/FrontendC/wchar-const.c delete mode 100644 test/FrontendC/weak_constant.c delete mode 100644 test/FrontendFortran/2008-11-03-OptionOverride.f90 delete mode 100644 test/FrontendFortran/2009-02-09-FloorDivExpr.f90 delete mode 100644 test/FrontendFortran/cpow.f90 delete mode 100644 test/FrontendFortran/dg.exp delete mode 100644 test/FrontendObjC++/2007-10-03-MetadataPointers.mm delete mode 100644 test/FrontendObjC++/2010-08-02-NonPODObjectValue.mm delete mode 100644 test/FrontendObjC++/2010-08-04-Template.mm delete mode 100644 test/FrontendObjC++/2010-08-06-X.Y-syntax.mm delete mode 100644 test/FrontendObjC++/dg.exp delete mode 100644 test/FrontendObjC/2007-04-03-ObjcEH.m delete mode 100644 test/FrontendObjC/2007-05-02-Strong.m delete mode 100644 test/FrontendObjC/2007-09-25-EH.m delete mode 100644 test/FrontendObjC/2007-10-17-SJLJExceptions.m delete mode 100644 test/FrontendObjC/2007-10-18-ProDescriptor.m delete mode 100644 test/FrontendObjC/2007-10-23-GC-WriteBarrier.m delete mode 100644 test/FrontendObjC/2008-10-3-EhValue.m delete mode 100644 test/FrontendObjC/2008-11-12-Metadata.m delete mode 100644 test/FrontendObjC/2008-11-24-ConstCFStrings.m delete mode 100644 test/FrontendObjC/2008-11-25-Blocks.m delete mode 100644 test/FrontendObjC/2009-01-26-WriteBarrier-2.m delete mode 100644 test/FrontendObjC/2009-02-05-VolatileProp.m delete mode 100644 test/FrontendObjC/2009-04-14-AsmSection.m delete mode 100644 test/FrontendObjC/2009-04-27-bitfield-vs-ivar.m delete mode 100644 test/FrontendObjC/2009-04-28-bitfield-vs-vbc.m delete mode 100644 test/FrontendObjC/2009-08-05-utf16.m delete mode 100644 test/FrontendObjC/2009-08-17-DebugInfo.m delete mode 100644 test/FrontendObjC/2009-11-30-Objc-ID.m delete mode 100644 test/FrontendObjC/2010-02-01-utf16-with-null.m delete mode 100644 test/FrontendObjC/2010-02-11-fwritable-stringsBug.m delete mode 100644 test/FrontendObjC/2010-02-23-DbgInheritance.m delete mode 100644 test/FrontendObjC/2010-03-17-StructRef.m delete mode 100644 test/FrontendObjC/2010-06-04-UnnamedCFString-dbg.m delete mode 100644 test/FrontendObjC/2011-03-02-ConstCFStringLiteralAlign.m delete mode 100644 test/FrontendObjC/2011-03-08-IVarLookup.m delete mode 100644 test/FrontendObjC/dg.exp delete mode 100644 test/LLVMC/Alias.td delete mode 100644 test/LLVMC/AppendCmdHook.td delete mode 100644 test/LLVMC/C++/dash-x.cpp delete mode 100644 test/LLVMC/C++/dg.exp delete mode 100644 test/LLVMC/C++/filelist.cpp delete mode 100644 test/LLVMC/C++/hello.cpp delete mode 100644 test/LLVMC/C++/just-compile.cpp delete mode 100644 test/LLVMC/C++/together.cpp delete mode 100644 test/LLVMC/C++/unknown_suffix.unk delete mode 100644 test/LLVMC/C/dg.exp delete mode 100644 test/LLVMC/C/emit-llvm-opt.c delete mode 100644 test/LLVMC/C/emit-llvm.c delete mode 100644 test/LLVMC/C/hello.c delete mode 100644 test/LLVMC/C/include.c delete mode 100644 test/LLVMC/C/opt-test.c delete mode 100644 test/LLVMC/C/sink.c delete mode 100644 test/LLVMC/C/wall.c delete mode 100644 test/LLVMC/EmptyCompilationGraph.td delete mode 100644 test/LLVMC/EnvParentheses.td delete mode 100644 test/LLVMC/ForwardAs.td delete mode 100644 test/LLVMC/ForwardTransformedValue.td delete mode 100644 test/LLVMC/ForwardValue.td delete mode 100644 test/LLVMC/HookWithArguments.td delete mode 100644 test/LLVMC/HookWithInFile.td delete mode 100644 test/LLVMC/Init.td delete mode 100644 test/LLVMC/LanguageMap.td delete mode 100644 test/LLVMC/MultiValuedOption.td delete mode 100644 test/LLVMC/MultipleCompilationGraphs.td delete mode 100644 test/LLVMC/MultipleOutputLanguages.td delete mode 100644 test/LLVMC/NoActions.td delete mode 100644 test/LLVMC/NoCompilationGraph.td delete mode 100644 test/LLVMC/ObjC++/dg.exp delete mode 100644 test/LLVMC/ObjC++/hello.mm delete mode 100644 test/LLVMC/ObjC/dg.exp delete mode 100644 test/LLVMC/ObjC/hello.m delete mode 100644 test/LLVMC/OneOrMore.td delete mode 100644 test/LLVMC/OptionPreprocessor.td delete mode 100644 test/LLVMC/OutputSuffixHook.td delete mode 100644 test/LLVMC/TestWarnings.td delete mode 100644 test/LLVMC/dg.exp delete mode 100644 test/LLVMC/test_data/false.c delete mode 100644 test/LLVMC/test_data/false.cpp delete mode 100644 test/LLVMC/test_data/false2.cpp delete mode 100644 test/LLVMC/test_data/together.c create mode 100644 test/Linker/2011-08-04-DebugLoc.ll create mode 100644 test/Linker/2011-08-04-DebugLoc2.ll create mode 100644 test/Linker/2011-08-04-Metadata.ll create mode 100644 test/Linker/2011-08-04-Metadata2.ll create mode 100644 test/Linker/2011-08-18-unique-class-type.ll create mode 100644 test/Linker/2011-08-18-unique-class-type2.ll create mode 100644 test/Linker/2011-08-18-unique-debug-type.ll create mode 100644 test/Linker/2011-08-18-unique-debug-type2.ll create mode 100644 test/Linker/2011-08-22-ResolveAlias.ll create mode 100644 test/Linker/2011-08-22-ResolveAlias2.ll create mode 100644 test/MC/ARM/arm-memory-instructions.s create mode 100644 test/MC/ARM/basic-thumb-instructions.s create mode 100644 test/MC/ARM/basic-thumb2-instructions.s create mode 100644 test/MC/ARM/nop-armv4-padding.s create mode 100644 test/MC/ARM/nop-armv6t2-padding.s create mode 100644 test/MC/ARM/nop-thumb-padding.s create mode 100644 test/MC/ARM/nop-thumb2-padding.s delete mode 100644 test/MC/ARM/reg-list.s delete mode 100644 test/MC/ARM/simple-encoding.ll create mode 100644 test/MC/ARM/thumb-diagnostics.s create mode 100644 test/MC/ARM/thumb-nop.s create mode 100644 test/MC/ARM/thumb2-diagnostics.s create mode 100644 test/MC/ARM/thumb2-mclass.s delete mode 100644 test/MC/ARM/thumb2.s delete mode 100644 test/MC/ARM/thumb2_instructions.s create mode 100644 test/MC/AsmParser/2011-09-06-NoNewline.s create mode 100644 test/MC/AsmParser/line_with_hash.s create mode 100644 test/MC/Disassembler/ARM/basic-arm-instructions.txt create mode 100644 test/MC/Disassembler/ARM/fp-encoding.txt create mode 100644 test/MC/Disassembler/ARM/invalid-IT-CBNZ-thumb.txt create mode 100644 test/MC/Disassembler/ARM/invalid-IT-thumb.txt create mode 100644 test/MC/Disassembler/ARM/invalid-LDM-thumb.txt create mode 100644 test/MC/Disassembler/ARM/invalid-LDRD-arm.txt create mode 100644 test/MC/Disassembler/ARM/invalid-t2PUSH-thumb.txt create mode 100644 test/MC/Disassembler/ARM/memory-arm-instructions.txt create mode 100644 test/MC/Disassembler/ARM/neon.txt create mode 100644 test/MC/Disassembler/ARM/neont2.txt create mode 100644 test/MC/Disassembler/ARM/thumb-MSR-MClass.txt create mode 100644 test/MC/Disassembler/ARM/thumb1.txt create mode 100644 test/MC/Disassembler/ARM/thumb2.txt create mode 100644 test/MC/Disassembler/X86/intel-syntax.txt create mode 100644 test/MC/Disassembler/X86/invalid-VEX-vvvv.txt create mode 100644 test/MC/ELF/many-section.s create mode 100644 test/MC/ELF/x86_64-reloc-sizetest.s create mode 100644 test/MC/MachO/darwin-x86_64-nobase-relocs.s create mode 100644 test/MC/MachO/x86_64-reloc-arithmetic.s create mode 100644 test/Object/TestObjectFiles/archive-test.a-bitcode create mode 100644 test/Object/TestObjectFiles/archive-test.a-coff-i386 create mode 100644 test/Object/nm-archive.test rename test/Object/{nm-trivial-object.test-broken => nm-trivial-object.test} (100%) create mode 100644 test/Object/objdump-disassembly-inline-relocations.test create mode 100644 test/Object/objdump-relocations.test create mode 100644 test/Object/objdump-sectionheaders.test rename test/Object/{objdump-trivial-object.test-broken => objdump-trivial-object.test} (100%) create mode 100644 test/TableGen/ListOfList.td create mode 100644 test/TableGen/LoLoL.td create mode 100644 test/TableGen/MultiPat.td create mode 100644 test/Transforms/DeadStoreElimination/2011-09-06-EndOfFunction.ll create mode 100644 test/Transforms/DeadStoreElimination/2011-09-06-MemCpy.ll create mode 100644 test/Transforms/DeadStoreElimination/atomic.ll create mode 100644 test/Transforms/FunctionAttrs/atomic.ll create mode 100644 test/Transforms/GVN/2011-09-07-TypeIdFor.ll create mode 100644 test/Transforms/GVN/atomic.ll create mode 100644 test/Transforms/GVN/pr10820.ll create mode 100644 test/Transforms/IPConstantProp/global.ll delete mode 100644 test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll delete mode 100644 test/Transforms/IndVarSimplify/2003-12-21-IndVarSize.ll create mode 100644 test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll create mode 100644 test/Transforms/IndVarSimplify/2011-09-19-vectoriv.ll create mode 100644 test/Transforms/IndVarSimplify/2011-09-27-hoistsext.ll create mode 100644 test/Transforms/IndVarSimplify/iv-fold.ll create mode 100644 test/Transforms/IndVarSimplify/lftr-reuse.ll delete mode 100644 test/Transforms/IndVarSimplify/max-pointer.ll delete mode 100644 test/Transforms/IndVarSimplify/pointer-indvars.ll delete mode 100644 test/Transforms/IndVarSimplify/pointer.ll delete mode 100644 test/Transforms/IndVarSimplify/subtract.ll delete mode 100644 test/Transforms/Inline/2003-10-26-InlineInvokeExceptionDestPhi.ll create mode 100644 test/Transforms/InstCombine/2011-09-03-Trampoline.ll create mode 100644 test/Transforms/InstCombine/2011-10-07-AlignPromotion.ll create mode 100644 test/Transforms/InstCombine/LandingPadClauses.ll create mode 100644 test/Transforms/InstCombine/atomic.ll create mode 100644 test/Transforms/InstCombine/devirt.ll create mode 100644 test/Transforms/InstSimplify/2011-09-05-InsertExtractValue.ll create mode 100644 test/Transforms/LICM/atomics.ll create mode 100644 test/Transforms/LICM/scalar-promote-memmodel.ll create mode 100644 test/Transforms/LoopStrengthReduce/2011-07-19-CritEdgeBreakCrash.ll create mode 100644 test/Transforms/LoopStrengthReduce/2011-07-20-DoubleIV.ll create mode 100644 test/Transforms/LoopStrengthReduce/2011-10-03-CritEdgeMerge.ll create mode 100644 test/Transforms/LoopStrengthReduce/2011-10-06-ReusePhi.ll create mode 100644 test/Transforms/LoopStrengthReduce/2011-10-13-SCEVChain.ll create mode 100644 test/Transforms/LoopStrengthReduce/2011-10-14-IntPtr.ll create mode 100644 test/Transforms/LoopUnroll/2011-08-08-PhiUpdate.ll create mode 100644 test/Transforms/LoopUnroll/2011-08-09-IVSimplify.ll create mode 100644 test/Transforms/LoopUnroll/2011-08-09-PhiUpdate.ll create mode 100644 test/Transforms/LoopUnroll/2011-10-01-NoopTrunc.ll create mode 100644 test/Transforms/LoopUnroll/pr10813.ll create mode 100644 test/Transforms/LoopUnroll/scevunroll.ll create mode 100644 test/Transforms/LoopUnroll/unloop.ll create mode 100644 test/Transforms/LoopUnswitch/2011-09-26-EHCrash.ll delete mode 100644 test/Transforms/LowerSetJmp/2003-11-05-DominanceProperties.ll delete mode 100644 test/Transforms/LowerSetJmp/simpletest.ll create mode 100644 test/Transforms/Mem2Reg/atomic.ll create mode 100644 test/Transforms/MemCpyOpt/atomic.ll create mode 100644 test/Transforms/ObjCARC/empty-block.ll create mode 100644 test/Transforms/ObjCARC/nested.ll create mode 100644 test/Transforms/ObjCARC/retain-block-alloca.ll create mode 100644 test/Transforms/ObjCARC/retain-block-side-effects.ll create mode 100644 test/Transforms/PhaseOrdering/2010-03-22-empty-baseclass.ll create mode 100644 test/Transforms/SCCP/atomic-load-store.ll create mode 100644 test/Transforms/SCCP/switch.ll create mode 100644 test/Transforms/ScalarRepl/2011-09-22-PHISpeculateInvoke.ll create mode 100644 test/Transforms/ScalarRepl/2011-10-11-VectorMemset.ll create mode 100644 test/Transforms/ScalarRepl/lifetime.ll create mode 100644 test/Transforms/ScalarRepl/vectors-with-mismatched-elements.ll create mode 100644 test/Transforms/SimplifyCFG/2011-09-05-TrivialLPad.ll create mode 100644 test/Transforms/SimplifyCFG/phi-undef-loadstore.ll create mode 100644 test/Transforms/StripSymbols/block-address.ll delete mode 100644 test/Transforms/TailDup/2003-06-24-Simpleloop.ll delete mode 100644 test/Transforms/TailDup/2003-07-22-InfiniteLoop.ll delete mode 100644 test/Transforms/TailDup/2003-08-23-InvalidatedPointers.ll delete mode 100644 test/Transforms/TailDup/2003-08-31-UnreachableBlocks.ll delete mode 100644 test/Transforms/TailDup/2004-04-01-DemoteRegToStack.ll delete mode 100644 test/Transforms/TailDup/2008-05-13-InfiniteLoop.ll delete mode 100644 test/Transforms/TailDup/2009-07-31-phicrash.ll delete mode 100644 test/Transforms/TailDup/MergeTest.ll delete mode 100644 test/Transforms/TailDup/PHIUpdateTest.ll delete mode 100644 test/Transforms/TailDup/X86/if-tail-dup.ll delete mode 100644 test/Transforms/TailDup/basictest.ll delete mode 100644 test/Transforms/TailDup/basictest2.ll delete mode 100644 tools/edis/EnhancedDisassembly.exports create mode 100644 tools/llvm-cov/CMakeLists.txt rename tools/{llvmc/examples/Hello => llvm-cov}/Makefile (58%) create mode 100644 tools/llvm-cov/llvm-cov.cpp create mode 100644 tools/llvm-dwarfdump/CMakeLists.txt rename tools/{llvmc/examples/mcc16 => llvm-dwarfdump}/Makefile (59%) create mode 100644 tools/llvm-dwarfdump/llvm-dwarfdump.cpp create mode 100644 tools/llvm-objdump/MCFunction.cpp create mode 100644 tools/llvm-objdump/MCFunction.h create mode 100644 tools/llvm-objdump/MachODump.cpp create mode 100644 tools/llvm-objdump/llvm-objdump.h create mode 100644 tools/llvm-size/CMakeLists.txt rename tools/{llvmc/examples/Simple => llvm-size}/Makefile (61%) create mode 100644 tools/llvm-size/llvm-size.cpp delete mode 100644 tools/llvmc/CMakeLists.txt delete mode 100644 tools/llvmc/Makefile delete mode 100644 tools/llvmc/doc/LLVMC-Reference.rst delete mode 100644 tools/llvmc/doc/LLVMC-Tutorial.rst delete mode 100644 tools/llvmc/doc/Makefile delete mode 100644 tools/llvmc/doc/img/lines.gif delete mode 100644 tools/llvmc/examples/Hello/Hello.cpp delete mode 100644 tools/llvmc/examples/Simple/Simple.cpp delete mode 100644 tools/llvmc/examples/Simple/Simple.td delete mode 100644 tools/llvmc/examples/Skeleton/AutoGenerated.td delete mode 100644 tools/llvmc/examples/Skeleton/Hooks.cpp delete mode 100644 tools/llvmc/examples/Skeleton/Main.cpp delete mode 100644 tools/llvmc/examples/Skeleton/Makefile delete mode 100644 tools/llvmc/examples/Skeleton/README delete mode 100644 tools/llvmc/examples/mcc16/Hooks.cpp delete mode 100644 tools/llvmc/examples/mcc16/Main.cpp delete mode 100644 tools/llvmc/examples/mcc16/PIC16.td delete mode 100644 tools/llvmc/examples/mcc16/README delete mode 100644 tools/llvmc/src/AutoGenerated.td delete mode 100644 tools/llvmc/src/Base.td.in delete mode 100644 tools/llvmc/src/Clang.td delete mode 100644 tools/llvmc/src/Hooks.cpp delete mode 100644 tools/llvmc/src/Main.cpp delete mode 100644 tools/llvmc/src/Makefile create mode 100644 unittests/ADT/SCCIteratorTest.cpp create mode 100644 unittests/Support/BlockFrequencyTest.cpp create mode 100644 unittests/Support/DataExtractorTest.cpp delete mode 100644 utils/TableGen/ClangASTNodesEmitter.cpp delete mode 100644 utils/TableGen/ClangASTNodesEmitter.h delete mode 100644 utils/TableGen/ClangAttrEmitter.cpp delete mode 100644 utils/TableGen/ClangAttrEmitter.h delete mode 100644 utils/TableGen/ClangDiagnosticsEmitter.cpp delete mode 100644 utils/TableGen/ClangDiagnosticsEmitter.h delete mode 100644 utils/TableGen/ClangSACheckersEmitter.cpp delete mode 100644 utils/TableGen/ClangSACheckersEmitter.h delete mode 100644 utils/TableGen/LLVMCConfigurationEmitter.cpp delete mode 100644 utils/TableGen/LLVMCConfigurationEmitter.h delete mode 100644 utils/TableGen/NeonEmitter.cpp delete mode 100644 utils/TableGen/NeonEmitter.h delete mode 100644 utils/TableGen/OptParserEmitter.cpp delete mode 100644 utils/TableGen/OptParserEmitter.h create mode 100644 utils/unittest/googletest/gtest-printers.cc create mode 100644 utils/unittest/googletest/include/gtest/gtest-printers.h delete mode 100644 website/index.html diff --git a/.gitignore b/.gitignore index d7dcc54d080c..5dae4342984f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ # Explicit files to ignore (only matches one). #==============================================================================# .gitusers +autom4te.cache cscope.files cscope.out autoconf/aclocal.m4 diff --git a/CMakeLists.txt b/CMakeLists.txt index e0404cf4b8bf..039f619ff971 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,7 @@ set(LLVM_ALL_TARGETS ) # List of targets with JIT support: -set(LLVM_TARGETS_WITH_JIT X86 PowerPC ARM) +set(LLVM_TARGETS_WITH_JIT X86 PowerPC ARM Mips) if( MSVC ) set(LLVM_TARGETS_TO_BUILD X86 @@ -181,12 +181,16 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories( ${LLVM_BINARY_DIR}/include ${LLVM_MAIN_INCLUDE_DIR}) if( ${CMAKE_SYSTEM_NAME} MATCHES SunOS ) - SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-include llvm/Support/Solaris.h") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -include llvm/Support/Solaris.h") endif( ${CMAKE_SYSTEM_NAME} MATCHES SunOS ) include(AddLLVM) include(TableGen) +macro(llvm_tablegen) + tablegen(LLVM ${ARGN}) +endmacro() + if( MINGW ) # People report that -O3 is unreliable on MinGW. The traditional # build also uses -O2 for that reason: @@ -195,19 +199,10 @@ endif() # Put this before tblgen. Else we have a circular dependence. add_subdirectory(lib/Support) - -set(LLVM_TABLEGEN "tblgen" CACHE - STRING "Native TableGen executable. Saves building one when cross-compiling.") -# Effective tblgen executable to be used: -set(LLVM_TABLEGEN_EXE ${LLVM_TABLEGEN}) +add_subdirectory(lib/TableGen) add_subdirectory(utils/TableGen) -if( CMAKE_CROSSCOMPILING ) - # This adds a dependency on target `tblgen', so must go after utils/TableGen - include( CrossCompileLLVM ) -endif( CMAKE_CROSSCOMPILING ) - add_subdirectory(include/llvm) add_subdirectory(lib) diff --git a/CREDITS.TXT b/CREDITS.TXT index 5ec33be1b0c4..f20152796ae1 100644 --- a/CREDITS.TXT +++ b/CREDITS.TXT @@ -32,6 +32,10 @@ E: dberlin@dberlin.org D: ET-Forest implementation. D: Sparse bitmap +N: David Blaikie +E: dblaikie@gmail.com +D: General bug fixing/fit & finish, mostly in Clang + N: Neil Booth E: neil@daikokuya.co.uk D: APFloat implementation. @@ -241,6 +245,10 @@ E: duraid@octopus.com.au W: http://kinoko.c.u-tokyo.ac.jp/~duraid/ D: IA64 backend, BigBlock register allocator +N: John McCall +E: rjmccall@apple.com +D: Clang semantic analysis and IR generation + N: Michael McCracken E: michael.mccracken@gmail.com D: Line number support for llvmgcc @@ -274,6 +282,8 @@ N: Jakob Stoklund Olesen E: stoklund@2pi.dk D: Machine code verifier D: Blackfin backend +D: Fast register allocator +D: Greedy register allocator N: Richard Osborne E: richard@xmos.com diff --git a/Makefile b/Makefile index 88e63e9c0245..a350cb19d2a9 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ LEVEL := . # Top-Level LLVM Build Stages: -# 1. Build lib/Support, which is used by utils (tblgen). +# 1. Build lib/Support and lib/TableGen, which are used by utils (tblgen). # 2. Build utils, which is used by VMCore. # 3. Build VMCore, which builds the Intrinsics.inc file used by libs. # 4. Build libs, which are needed by llvm-config. @@ -27,10 +27,10 @@ LEVEL := . ifneq ($(findstring llvmCore, $(RC_ProjectName)),llvmCore) # Normal build (not "Apple-style"). ifeq ($(BUILD_DIRS_ONLY),1) - DIRS := lib/Support utils - OPTIONAL_DIRS := + DIRS := lib/Support lib/TableGen utils + OPTIONAL_DIRS := tools/clang/utils/TableGen else - DIRS := lib/Support utils lib/VMCore lib tools/llvm-shlib \ + DIRS := lib/Support lib/TableGen utils lib/VMCore lib tools/llvm-shlib \ tools/llvm-config tools runtime docs unittests OPTIONAL_DIRS := projects bindings endif @@ -118,7 +118,8 @@ cross-compile-build-tools: unset CFLAGS ; \ unset CXXFLAGS ; \ $(PROJ_SRC_DIR)/configure --build=$(BUILD_TRIPLE) \ - --host=$(BUILD_TRIPLE) --target=$(BUILD_TRIPLE); \ + --host=$(BUILD_TRIPLE) --target=$(BUILD_TRIPLE) \ + --disable-polly ; \ cd .. ; \ fi; \ (unset SDKROOT; \ @@ -187,8 +188,7 @@ FilesToConfig := \ include/llvm/Config/AsmPrinters.def \ include/llvm/Config/AsmParsers.def \ include/llvm/Config/Disassemblers.def \ - include/llvm/Support/DataTypes.h \ - tools/llvmc/src/Base.td + include/llvm/Support/DataTypes.h FilesToConfigPATH := $(addprefix $(LLVM_OBJ_ROOT)/,$(FilesToConfig)) all-local:: $(FilesToConfigPATH) diff --git a/Makefile.config.in b/Makefile.config.in index 9bdb07563f54..fff482e77748 100644 --- a/Makefile.config.in +++ b/Makefile.config.in @@ -188,30 +188,6 @@ LIBS := @LIBS@ # Targets that we should build TARGETS_TO_BUILD=@TARGETS_TO_BUILD@ -# Path to location for LLVM C/C++ front-end. You can modify this if you -# want to override the value set by configure. -LLVMGCCDIR := @LLVMGCCDIR@ - -# Full pathnames of LLVM C/C++ front-end 'cc1' and 'cc1plus' binaries: -LLVMGCC := @LLVMGCC@ -LLVMGXX := @LLVMGXX@ -LLVMCC1 := @LLVMCC1@ -LLVMCC1PLUS := @LLVMCC1PLUS@ -LLVMGCC_LANGS := @LLVMGCC_LANGS@ -LLVMGCC_DRAGONEGG := @LLVMGCC_DRAGONEGG@ - -# Information on Clang, if configured. -CLANGPATH := @CLANGPATH@ -CLANGXXPATH := @CLANGXXPATH@ -ENABLE_BUILT_CLANG := @ENABLE_BUILT_CLANG@ - -# The LLVM capable compiler to use. -LLVMCC_OPTION := @LLVMCC_OPTION@ - -# The flag used to emit LLVM IR. -LLVMCC_EMITIR_FLAG = @LLVMCC_EMITIR_FLAG@ -LLVMCC_DISABLEOPT_FLAGS := @LLVMCC_DISABLEOPT_FLAGS@ - # Path to directory where object files should be stored during a build. # Set OBJ_ROOT to "." if you do not want to use a separate place for # object files. @@ -338,17 +314,6 @@ endif # Location of the plugin header file for gold. BINUTILS_INCDIR := @BINUTILS_INCDIR@ -# When ENABLE_LLVMC_DYNAMIC is enabled, LLVMC will link libCompilerDriver -# dynamically. This is needed to make dynamic plugins work on some targets -# (Windows). -ENABLE_LLVMC_DYNAMIC = 0 -#@ENABLE_LLVMC_DYNAMIC@ - -# When ENABLE_LLVMC_DYNAMIC_PLUGINS is enabled, LLVMC will have dynamic plugin -# support (via the -load option). -ENABLE_LLVMC_DYNAMIC_PLUGINS = 1 -#@ENABLE_LLVMC_DYNAMIC_PLUGINS@ - # Optional flags supported by the compiler # -Wno-missing-field-initializers NO_MISSING_FIELD_INITIALIZERS = @NO_MISSING_FIELD_INITIALIZERS@ diff --git a/Makefile.rules b/Makefile.rules index 228fd733e7ed..d057f043ff64 100644 --- a/Makefile.rules +++ b/Makefile.rules @@ -190,19 +190,6 @@ uninstall:: uninstall-local install-local:: all-local install-bytecode:: install-bytecode-local -############################################################################### -# LLVMC: Provide rules for compiling llvmc-based driver -############################################################################### - -ifdef LLVMC_BASED_DRIVER - -TOOLNAME = $(LLVMC_BASED_DRIVER) - -LLVMLIBS = CompilerDriver.a -LINK_COMPONENTS = support - -endif # LLVMC_BASED_DRIVER - ############################################################################### # VARIABLES: Set up various variables based on configuration data ############################################################################### @@ -463,11 +450,11 @@ Echo = @$(EchoCmd) ifndef LLVMAS LLVMAS := $(LLVMToolDir)/llvm-as$(EXEEXT) endif -ifndef TBLGEN +ifndef LLVM_TBLGEN ifeq ($(LLVM_CROSS_COMPILING),1) - TBLGEN := $(BuildLLVMToolDir)/tblgen$(BUILD_EXEEXT) + LLVM_TBLGEN := $(BuildLLVMToolDir)/llvm-tblgen$(BUILD_EXEEXT) else - TBLGEN := $(LLVMToolDir)/tblgen$(EXEEXT) + LLVM_TBLGEN := $(LLVMToolDir)/llvm-tblgen$(EXEEXT) endif endif LLVM_CONFIG := $(LLVMToolDir)/llvm-config @@ -636,7 +623,7 @@ CPP.BaseFlags += -include llvm/Support/Solaris.h endif # !HOST_OS - AuroraUX. LD.Flags += -L$(LibDir) -L$(LLVMLibDir) -CPP.BaseFlags += -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS +CPP.BaseFlags += -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS # All -I flags should go here, so that they don't confuse llvm-config. CPP.Flags += $(sort -I$(PROJ_OBJ_DIR) -I$(PROJ_SRC_DIR) \ $(patsubst %,-I%/include,\ @@ -697,10 +684,11 @@ DataInstall = $(INSTALL) -m 0644 # When compiling under Mingw/Cygwin, the tblgen tool expects Windows # paths. In this case, the SYSPATH function (defined in # Makefile.config) transforms Unix paths into Windows paths. -TableGen = $(TBLGEN) -I $(call SYSPATH, $(PROJ_SRC_DIR)) \ +TableGen.Flags= -I $(call SYSPATH, $(PROJ_SRC_DIR)) \ -I $(call SYSPATH, $(LLVM_SRC_ROOT)/include) \ -I $(call SYSPATH, $(PROJ_SRC_ROOT)/include) \ -I $(call SYSPATH, $(PROJ_SRC_ROOT)/lib/Target) +LLVMTableGen = $(LLVM_TBLGEN) $(TableGen.Flags) Archive = $(AR) $(AR.Flags) LArchive = $(LLVMToolDir)/llvm-ar rcsf @@ -1686,10 +1674,6 @@ ifdef TARGET TABLEGEN_INC_FILES_COMMON = 1 endif -ifdef LLVMC_BASED_DRIVER -TABLEGEN_INC_FILES_COMMON = 1 -endif - ifdef TABLEGEN_INC_FILES_COMMON INCFiles := $(filter %.inc,$(BUILT_SOURCES)) @@ -1717,87 +1701,87 @@ TDFiles := $(strip $(wildcard $(PROJ_SRC_DIR)/*.td) \ $(LLVM_SRC_ROOT)/include/llvm/CodeGen/ValueTypes.td) \ $(wildcard $(LLVM_SRC_ROOT)/include/llvm/Intrinsics*.td) -# All of these files depend on tblgen and the .td files. -$(INCTMPFiles) : $(TBLGEN) $(TDFiles) +# All .inc.tmp files depend on the .td files. +$(INCTMPFiles) : $(TDFiles) $(TARGET:%=$(ObjDir)/%GenRegisterInfo.inc.tmp): \ -$(ObjDir)/%GenRegisterInfo.inc.tmp : %.td $(ObjDir)/.dir +$(ObjDir)/%GenRegisterInfo.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN) $(Echo) "Building $(/dev/null 2>&1; then IBM_ARCH=rs6000 @@ -595,52 +598,52 @@ EOF 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac + esac ;; + esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + sed 's/^ //' << EOF >$dummy.c - #define _HPUX_SOURCE - #include - #include + #define _HPUX_SOURCE + #include + #include - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa @@ -731,22 +734,22 @@ EOF exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd - exit ;; + exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit ;; + exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd - exit ;; + exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd - exit ;; + exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd - exit ;; + exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; @@ -770,14 +773,14 @@ EOF exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} @@ -789,8 +792,8 @@ EOF echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_MACHINE} in + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) @@ -804,18 +807,18 @@ EOF echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; - *:Interix*:[3456]*) - case ${UNAME_MACHINE} in + *:Interix*:*) + case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; - EM64T | authenticamd | genuineintel) + authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) @@ -866,7 +869,7 @@ EOF EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; - esac + esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} @@ -878,7 +881,13 @@ EOF then echo ${UNAME_MACHINE}-unknown-linux-gnu else - echo ${UNAME_MACHINE}-unknown-linux-gnueabi + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi fi exit ;; avr32*:Linux:*:*) @@ -891,10 +900,18 @@ EOF echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) - echo frv-unknown-linux-gnu + echo frv-unknown-linux-gnu exit ;; i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-gnu + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu @@ -921,11 +938,7 @@ EOF #endif #endif EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) @@ -955,7 +968,7 @@ EOF echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu @@ -963,6 +976,9 @@ EOF sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; @@ -970,7 +986,7 @@ EOF echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -979,11 +995,11 @@ EOF echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. + # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) @@ -1015,7 +1031,7 @@ EOF fi exit ;; i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. + # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; @@ -1043,13 +1059,13 @@ EOF exit ;; pc:*:*:*) # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp - exit ;; + exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; @@ -1084,8 +1100,8 @@ EOF /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ @@ -1128,10 +1144,10 @@ EOF echo ns32k-sni-sysv fi exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm @@ -1157,11 +1173,11 @@ EOF exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv${UNAME_RELEASE} else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv${UNAME_RELEASE} fi - exit ;; + exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; @@ -1226,6 +1242,9 @@ EOF *:QNX:*:4*) echo i386-pc-qnx exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; @@ -1271,13 +1290,13 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` + UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; @@ -1317,11 +1336,11 @@ main () #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else - "" + "" #endif - ); exit (0); + ); exit (0); #endif #endif diff --git a/autoconf/config.sub b/autoconf/config.sub index 183976a066a9..da19a880e5f1 100755 --- a/autoconf/config.sub +++ b/autoconf/config.sub @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -# Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011 Free Software Foundation, Inc. -timestamp='2009-08-19' +timestamp='2011-08-23' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -75,8 +75,9 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free +Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -123,8 +124,9 @@ esac # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ - uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os @@ -156,8 +158,8 @@ case $os in os= basic_machine=$1 ;; - -bluegene*) - os=-cnk + -bluegene*) + os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= @@ -173,10 +175,10 @@ case $os in os=-chorusos basic_machine=$1 ;; - -chorusrdb) - os=-chorusrdb + -chorusrdb) + os=-chorusrdb basic_machine=$1 - ;; + ;; -hiux*) os=-hiuxwe2 ;; @@ -249,6 +251,7 @@ case $basic_machine in | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ @@ -256,6 +259,7 @@ case $basic_machine in | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ + | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ @@ -281,26 +285,39 @@ case $basic_machine in | moxie \ | mt \ | msp430 \ + | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ + | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ + | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ - | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; - m6811 | m68hc11 | m6812 | m68hc12) + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none @@ -311,6 +328,18 @@ case $basic_machine in basic_machine=mt-unknown ;; + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. @@ -330,8 +359,9 @@ case $basic_machine in | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | be32-* | be64-* \ | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ @@ -340,6 +370,7 @@ case $basic_machine in | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ + | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ @@ -365,24 +396,29 @@ case $basic_machine in | mmix-* \ | mt-* \ | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ - | romp-* | rs6000-* \ + | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ | tron-* \ - | v850-* | v850e-* | vax-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) @@ -407,7 +443,7 @@ case $basic_machine in basic_machine=a29k-amd os=-udi ;; - abacus) + abacus) basic_machine=abacus-unknown ;; adobe68k) @@ -477,11 +513,20 @@ case $basic_machine in basic_machine=powerpc-ibm os=-cnk ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; c90) basic_machine=c90-cray os=-unicos ;; - cegcc) + cegcc) basic_machine=arm-unknown os=-cegcc ;; @@ -513,7 +558,7 @@ case $basic_machine in basic_machine=craynv-cray os=-unicosmp ;; - cr16) + cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; @@ -729,7 +774,7 @@ case $basic_machine in basic_machine=ns32k-utek os=-sysv ;; - microblaze) + microblaze) basic_machine=microblaze-xilinx ;; mingw32) @@ -772,6 +817,10 @@ case $basic_machine in basic_machine=i370-ibm os=-mvs ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 @@ -836,6 +885,12 @@ case $basic_machine in np1) basic_machine=np1-gould ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; nsr-tandem) basic_machine=nsr-tandem ;; @@ -918,9 +973,10 @@ case $basic_machine in ;; power) basic_machine=power-ibm ;; - ppc) basic_machine=powerpc-unknown + ppc | ppcbe) basic_machine=powerpc-unknown ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown @@ -1014,6 +1070,9 @@ case $basic_machine in basic_machine=i860-stratus os=-sysv4 ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; sun2) basic_machine=m68000-sun ;; @@ -1070,20 +1129,8 @@ case $basic_machine in basic_machine=t90-cray os=-unicos ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; tile*) - basic_machine=tile-unknown + basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) @@ -1153,6 +1200,9 @@ case $basic_machine in xps | xps100) basic_machine=xps100-honeywell ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; ymp) basic_machine=ymp-cray os=-unicos @@ -1250,15 +1300,15 @@ esac if [ x"$os" != x"" ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. + # First match some system type aliases + # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; -auroraux) os=-auroraux ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; -solaris) os=-solaris2 ;; @@ -1277,8 +1327,8 @@ case $os in # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* | -sym* \ - | -kopensolaris* \ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ @@ -1291,7 +1341,8 @@ case $os in | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ @@ -1299,7 +1350,7 @@ case $os in | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1338,7 +1389,7 @@ case $os in -opened*) os=-openedition ;; - -os400*) + -os400*) os=-os400 ;; -wince*) @@ -1387,7 +1438,7 @@ case $os in -sinix*) os=-sysv4 ;; - -tpf*) + -tpf*) os=-tpf ;; -triton*) @@ -1432,6 +1483,8 @@ case $os in -dicos*) os=-dicos ;; + -nacl*) + ;; -none) ;; *) @@ -1454,10 +1507,10 @@ else # system, and we'll never get to this point. case $basic_machine in - score-*) + score-*) os=-elf ;; - spu-*) + spu-*) os=-elf ;; *-acorn) @@ -1469,8 +1522,17 @@ case $basic_machine in arm*-semi) os=-aout ;; - c4x-* | tic4x-*) - os=-coff + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff ;; # This must come before the *-dec entry. pdp10-*) @@ -1497,7 +1559,7 @@ case $basic_machine in m68*-cisco) os=-aout ;; - mep-*) + mep-*) os=-elf ;; mips*-cisco) @@ -1524,7 +1586,7 @@ case $basic_machine in *-ibm) os=-aix ;; - *-knuth) + *-knuth) os=-mmixware ;; *-wec) diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 3c3ddaa66616..a4ccfcd64315 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -31,16 +31,15 @@ dnl=== dnl===-----------------------------------------------------------------------=== dnl Initialize autoconf and define the package name, version number and dnl email address for reporting bugs. -AC_INIT([[llvm]],[[3.0svn]],[llvmbugs@cs.uiuc.edu]) +AC_INIT([[llvm]],[[3.0]],[llvmbugs@cs.uiuc.edu]) dnl Provide a copyright substitution and ensure the copyright notice is included dnl in the output of --version option of the generated configure script. AC_SUBST(LLVM_COPYRIGHT,["Copyright (c) 2003-2011 University of Illinois at Urbana-Champaign."]) AC_COPYRIGHT([Copyright (c) 2003-2011 University of Illinois at Urbana-Champaign.]) -dnl Indicate that we require autoconf 2.59 or later. Ths is needed because we -dnl use some autoconf macros only available in 2.59. -AC_PREREQ(2.59) +dnl Indicate that we require autoconf 2.60 or later. +AC_PREREQ(2.60) dnl Verify that the source directory is valid. This makes sure that we are dnl configuring LLVM and not some other package (it validates --srcdir argument) @@ -58,6 +57,12 @@ if test ${srcdir} != "." ; then fi fi +dnl We need to check for the compiler up here to avoid anything else +dnl starting with a different one. +AC_PROG_CC(clang llvm-gcc gcc) +AC_PROG_CXX(clang++ llvm-g++ g++) +AC_PROG_CPP + dnl Configure all of the projects present in our source tree. While we could dnl just AC_CONFIG_SUBDIRS on the set of directories in projects that have a dnl configure script, that usage of the AC_CONFIG_SUBDIRS macro is deprecated. @@ -299,6 +304,8 @@ AC_CACHE_CHECK([type of operating system we're going to target], llvm_cv_target_os_type="Haiku" ;; *-*-rtems*) llvm_cv_target_os_type="RTEMS" ;; + *-*-nacl*) + llvm_cv_target_os_type="NativeClient" ;; *-unknown-eabi*) llvm_cv_target_os_type="Freestanding" ;; *) @@ -413,7 +420,7 @@ dnl===-----------------------------------------------------------------------=== dnl --enable-optimized : check whether they want to do an optimized build: AC_ARG_ENABLE(optimized, AS_HELP_STRING( - --enable-optimized,[Compile with optimizations enabled (default is NO)]),,enableval=$optimize) + --enable-optimized,[Compile with optimizations enabled (default is YES)]),,enableval=$optimize) if test ${enableval} = "no" ; then AC_SUBST(ENABLE_OPTIMIZED,[[]]) else @@ -431,7 +438,7 @@ fi dnl --enable-assertions : check whether they want to turn on assertions or not: AC_ARG_ENABLE(assertions,AS_HELP_STRING( - --enable-assertions,[Compile with assertion checks enabled (default is YES)]),, enableval="yes") + --enable-assertions,[Compile with assertion checks enabled (default is NO)]),, enableval="no") if test ${enableval} = "yes" ; then AC_SUBST(DISABLE_ASSERTIONS,[[]]) else @@ -484,7 +491,7 @@ else x86_64) AC_SUBST(TARGET_HAS_JIT,1) ;; Alpha) AC_SUBST(TARGET_HAS_JIT,0) ;; ARM) AC_SUBST(TARGET_HAS_JIT,1) ;; - Mips) AC_SUBST(TARGET_HAS_JIT,0) ;; + Mips) AC_SUBST(TARGET_HAS_JIT,1) ;; XCore) AC_SUBST(TARGET_HAS_JIT,0) ;; MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;; SystemZ) AC_SUBST(TARGET_HAS_JIT,0) ;; @@ -573,12 +580,12 @@ esac dnl Allow libstdc++ is embedded in LLVM.dll. AC_ARG_ENABLE(embed-stdcxx, AS_HELP_STRING([--enable-embed-stdcxx], - [Build a shared library with embedded libstdc++ for Win32 DLL (default is YES)]),, + [Build a shared library with embedded libstdc++ for Win32 DLL (default is NO)]),, enableval=default) case "$enableval" in yes) AC_SUBST(ENABLE_EMBED_STDCXX,[1]) ;; no) AC_SUBST(ENABLE_EMBED_STDCXX,[0]) ;; - default) AC_SUBST(ENABLE_EMBED_STDCXX,[1]) ;; + default) AC_SUBST(ENABLE_EMBED_STDCXX,[0]) ;; *) AC_MSG_ERROR([Invalid setting for --enable-embed-stdcxx. Use "yes" or "no"]) ;; esac @@ -658,7 +665,7 @@ for a_target in $TARGETS_TO_BUILD; do [LLVM architecture name for the native architecture, if available]) LLVM_NATIVE_TARGET="LLVMInitialize${LLVM_NATIVE_ARCH}Target" LLVM_NATIVE_TARGETINFO="LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo" - LLVM_NATIVE_MCASMINFO="LLVMInitialize${LLVM_NATIVE_ARCH}MCAsmInfo" + LLVM_NATIVE_TARGETMC="LLVMInitialize${LLVM_NATIVE_ARCH}TargetMC" LLVM_NATIVE_ASMPRINTER="LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter" if test -f ${srcdir}/lib/Target/${LLVM_NATIVE_ARCH}/AsmParser/Makefile ; then LLVM_NATIVE_ASMPARSER="LLVMInitialize${LLVM_NATIVE_ARCH}AsmParser" @@ -667,8 +674,8 @@ for a_target in $TARGETS_TO_BUILD; do [LLVM name for the native Target init function, if available]) AC_DEFINE_UNQUOTED(LLVM_NATIVE_TARGETINFO, $LLVM_NATIVE_TARGETINFO, [LLVM name for the native TargetInfo init function, if available]) - AC_DEFINE_UNQUOTED(LLVM_NATIVE_MCASMINFO, $LLVM_NATIVE_MCASMINFO, - [LLVM name for the native MCAsmInfo init function, if available]) + AC_DEFINE_UNQUOTED(LLVM_NATIVE_TARGETMC, $LLVM_NATIVE_TARGETMC, + [LLVM name for the native target MC init function, if available]) AC_DEFINE_UNQUOTED(LLVM_NATIVE_ASMPRINTER, $LLVM_NATIVE_ASMPRINTER, [LLVM name for the native AsmPrinter init function, if available]) if test -f ${srcdir}/lib/Target/${LLVM_NATIVE_ARCH}/AsmParser/Makefile ; then @@ -716,97 +723,6 @@ esac AC_DEFINE_UNQUOTED([ENABLE_CBE_PRINTF_A],$ENABLE_CBE_PRINTF_A, [Define if CBE is enabled for printf %a output]) -dnl Allow a specific llvm-gcc/llvm-g++ pair to be used with this LLVM config. -AC_ARG_WITH(llvmgccdir, - AS_HELP_STRING([--with-llvmgccdir], - [Specify location of llvm-gcc install dir (default searches PATH)]),, - withval=default) -case "$withval" in - default) WITH_LLVMGCCDIR=default ;; - /* | [[A-Za-z]]:[[\\/]]*) WITH_LLVMGCCDIR=$withval ;; - *) AC_MSG_ERROR([Invalid path for --with-llvmgccdir. Provide full path]) ;; -esac - -dnl Allow a specific llvm-gcc compiler to be used with this LLVM config. -AC_ARG_WITH(llvmgcc, - AS_HELP_STRING([--with-llvmgcc], - [Specify location of llvm-gcc driver (default searches PATH)]), - LLVMGCC=$with_llvmgcc - WITH_LLVMGCCDIR="",) - -dnl Allow a specific llvm-g++ compiler to be used with this LLVM config. -AC_ARG_WITH(llvmgxx, - AS_HELP_STRING([--with-llvmgxx], - [Specify location of llvm-g++ driver (default searches PATH)]), - LLVMGXX=$with_llvmgxx - WITH_LLVMGCCDIR="",) - -if test -n "$LLVMGCC"; then - LLVMGCCCOMMAND="$LLVMGCC" -fi - -if test -n "$LLVMGXX"; then - LLVMGXXCOMMAND="$LLVMGXX" -fi - -if test -n "$LLVMGCC" && test -z "$LLVMGXX"; then - AC_MSG_ERROR([Invalid llvm-g++. Use --with-llvmgxx when --with-llvmgcc is used]); -fi - -if test -n "$LLVMGXX" && test -z "$LLVMGCC"; then - AC_MSG_ERROR([Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is used]); -fi - -dnl Allow a specific Clang compiler to be used with this LLVM config. -AC_ARG_WITH(clang, - AS_HELP_STRING([--with-clang], - [Specify location of clang compiler (default is --with-built-clang)]), - [],[with_clang=default]) - -dnl Enable use of the built Clang. -AC_ARG_WITH(built-clang, - AS_HELP_STRING([--with-built-clang], - [Use the compiled Clang as the LLVM compiler (default=check)]), - [],[with_built_clang=check]) - -dnl Select the Clang compiler option. -dnl -dnl If --with-clang is given, always honor that; otherwise honor -dnl --with-built-clang, or check if we have the clang sources. -AC_MSG_CHECKING([clang compiler]) -WITH_CLANGPATH="" -WITH_BUILT_CLANG=0 -if test "$with_clang" != "default"; then - WITH_CLANGPATH="$with_clang" - if ! test -x "$WITH_CLANGPATH"; then - AC_MSG_ERROR([invalid --with-clang, path does not specify an executable]) - fi -elif test "$with_built_clang" = "yes"; then - WITH_BUILT_CLANG=1 -elif test "$with_built_clang" = "no"; then - WITH_BUILT_CLANG=0 -else - if test "$with_built_clang" != "check"; then - AC_MSG_ERROR([invalid value for --with-built-clang.]) - fi - - if test -f ${srcdir}/tools/clang/README.txt; then - WITH_BUILT_CLANG=1 - fi -fi - -if ! test -z "$WITH_CLANGPATH"; then - AC_MSG_RESULT([$WITH_CLANGPATH]) - WITH_CLANGXXPATH=`"$WITH_CLANGPATH" --print-prog-name=clang++` -elif test "$WITH_BUILT_CLANG" = "1"; then - AC_MSG_RESULT([built]) -else - AC_MSG_RESULT([none]) -fi -AC_SUBST(CLANGPATH,$WITH_CLANGPATH) -AC_SUBST(CLANGXXPATH,$WITH_CLANGXXPATH) -AC_SUBST(ENABLE_BUILT_CLANG,$WITH_BUILT_CLANG) - dnl Override the option to use for optimized builds. AC_ARG_WITH(optimize-option, AS_HELP_STRING([--with-optimize-option], @@ -942,8 +858,8 @@ fi dnl Specify the URL where bug reports should be submitted. AC_ARG_WITH(bug-report-url, AS_HELP_STRING([--with-bug-report-url], - [Specify the URL where bug reports should be submitted (default=http://llvm.org)]),, - withval="http://llvm.org") + [Specify the URL where bug reports should be submitted (default=http://llvm.org/bugs/)]),, + withval="http://llvm.org/bugs/") AC_DEFINE_UNQUOTED(BUG_REPORT_URL,"$withval", [Bug report URL.]) @@ -963,11 +879,6 @@ dnl=== SECTION 4: Check for programs we need and that they are the right version dnl=== dnl===-----------------------------------------------------------------------=== -dnl Check for compilation tools -AC_PROG_CPP -AC_PROG_CC(gcc) -AC_PROG_CXX(g++) - AC_PROG_NM AC_SUBST(NM) @@ -1139,55 +1050,6 @@ dnl libtool). AC_LIBTOOL_DLOPEN AC_LIB_LTDL -if test "$WITH_LLVMGCCDIR" = "default" ; then - LLVMGCC="llvm-gcc${EXEEXT}" - LLVMGXX="llvm-g++${EXEEXT}" - LLVMGCCCOMMAND="$LLVMGCC" - LLVMGXXCOMMAND="$LLVMGXX" - AC_SUBST(LLVMGCCCOMMAND,$LLVMGCCCOMMAND) - AC_SUBST(LLVMGXXCOMMAND,$LLVMGXXCOMMAND) - AC_PATH_PROG(LLVMGCC, $LLVMGCC, []) - AC_PATH_PROG(LLVMGXX, $LLVMGXX, []) -else - if test -z "$LLVMGCC"; then - LLVMGCC="$WITH_LLVMGCCDIR/bin/llvm-gcc${EXEEXT}" - LLVMGCCCOMMAND="$LLVMGCC" - fi - if test -z "$LLVMGXX"; then - LLVMGXX="$WITH_LLVMGCCDIR/bin/llvm-g++${EXEEXT}" - LLVMGXXCOMMAND="$LLVMGXX" - fi - - AC_SUBST(LLVMGCC,$LLVMGCC) - AC_SUBST(LLVMGXX,$LLVMGXX) - AC_SUBST(LLVMGCCCOMMAND,$LLVMGCCCOMMAND) - AC_SUBST(LLVMGXXCOMMAND,$LLVMGXXCOMMAND) -fi - -dnl Select the LLVM capable compiler to use, we default to using llvm-gcc if -dnl found, otherwise clang if available. -AC_ARG_WITH(llvmcc, - AS_HELP_STRING([--with-llvmcc=], - [Choose the LLVM capable compiler to use (llvm-gcc, clang, or none; default=check)]), - [],[with_llvmcc=check]) -AC_MSG_CHECKING([LLVM capable compiler]) -if test "$with_llvmcc" != "check"; then - if (test "$with_llvmcc" != "llvm-gcc" && - test "$with_llvmcc" != "clang" && - test "$with_llvmcc" != "none"); then - AC_MSG_ERROR([invalid value for --with-llvmcc, expected 'llvm-gcc', 'clang', or 'none'.]) - fi - WITH_LLVMCC="$with_llvmcc" -elif test -n "$LLVMGCC"; then - WITH_LLVMCC=llvm-gcc -elif test -n "$WITH_CLANGPATH" || test "$WITH_BUILT_CLANG" -ne "0"; then - WITH_LLVMCC=clang -else - WITH_LLVMCC=none -fi -AC_MSG_RESULT([$WITH_LLVMCC]) -AC_SUBST(LLVMCC_OPTION,$WITH_LLVMCC) - AC_MSG_CHECKING([tool compatibility]) dnl Ensure that compilation tools are GCC or a GNU compatible compiler such as @@ -1352,7 +1214,6 @@ dnl Generally we're looking for POSIX headers. AC_HEADER_DIRENT AC_HEADER_MMAP_ANONYMOUS AC_HEADER_STAT -AC_HEADER_STDC AC_HEADER_SYS_WAIT AC_HEADER_TIME @@ -1512,9 +1373,9 @@ AC_LINK_IFELSE( ]]), AC_LANG_POP([C++]) AC_MSG_RESULT(yes) - AC_DEFINE(LLVM_MULTITHREADED, 1, Build multithreading support into LLVM), + AC_DEFINE(LLVM_HAS_ATOMICS, 1, Has gcc/MSVC atomic intrinsics), AC_MSG_RESULT(no) - AC_DEFINE(LLVM_MULTITHREADED, 0, Build multithreading support into LLVM) + AC_DEFINE(LLVM_HAS_ATOMICS, 0, Has gcc/MSVC atomic intrinsics) AC_MSG_WARN([LLVM will be built thread-unsafe because atomic builtins are missing])) dnl===-----------------------------------------------------------------------=== @@ -1533,63 +1394,9 @@ if test "$llvm_cv_os_type" = "Linux" -a "$llvm_cv_target_arch" = "x86_64" ; then fi fi -dnl Check, whether __dso_handle is present +dnl Check whether __dso_handle is present AC_CHECK_FUNCS([__dso_handle]) -dnl Check wether llvm-gcc is based on dragonegg -AC_CACHE_CHECK([whether llvm-gcc is dragonegg],[llvm_cv_llvmgcc_dragonegg], -[llvm_cv_llvmgcc_dragonegg="no" -if test -n "$LLVMGCC" ; then - cp /dev/null conftest.c - $LLVMGCC -fplugin-arg-dragonegg-emit-ir -S -o - conftest.c > /dev/null 2>&1 - if test $? -eq 0 ; then - llvm_cv_llvmgcc_dragonegg="yes" - fi - rm conftest.c -fi]) - -dnl Set the flags needed to emit LLVM IR and to disable optimizations -dnl in llvmgcc -if test "$llvm_cv_llvmgcc_dragonegg" = "yes" ; then - LLVMCC_EMITIR_FLAG="-fplugin-arg-dragonegg-emit-ir" - LLVMCC_DISABLEOPT_FLAGS="-fplugin-arg-dragonegg-llvm-ir-optimize=0" -else - LLVMCC_EMITIR_FLAG="-emit-llvm" - LLVMCC_DISABLEOPT_FLAGS="-mllvm -disable-llvm-optzns" -fi - -AC_SUBST(LLVMCC_EMITIR_FLAG) - -dnl See if the llvm-gcc executable can compile to LLVM assembly -AC_CACHE_CHECK([whether llvm-gcc is sane],[llvm_cv_llvmgcc_sanity], -[llvm_cv_llvmgcc_sanity="no" -if test -n "$LLVMGCC" ; then - cp /dev/null conftest.c - $LLVMGCC "$LLVMCC_EMITIR_FLAG" -S -o - conftest.c | \ - grep 'target datalayout =' > /dev/null 2>&1 - if test $? -eq 0 ; then - llvm_cv_llvmgcc_sanity="yes" - fi - rm conftest.c -fi]) - -dnl Since we have a sane llvm-gcc, identify it and its sub-tools -dnl Furthermore, add some information about the tools -if test "$llvm_cv_llvmgcc_sanity" = "yes" ; then - AC_MSG_CHECKING([llvm-gcc component support]) - llvmcc1path=`$LLVMGCC --print-prog-name=cc1` - AC_SUBST(LLVMCC1,$llvmcc1path) - llvmcc1pluspath=`$LLVMGCC --print-prog-name=cc1plus` - AC_SUBST(LLVMCC1PLUS,$llvmcc1pluspath) - llvmgccdir=`echo "$llvmcc1path" | sed 's,/libexec/.*,,'` - AC_SUBST(LLVMGCCDIR,$llvmgccdir) - llvmgcclangs=[`$LLVMGCC -v --help 2>&1 | grep '^Configured with:' | sed 's/^.*--enable-languages=\([^ ]*\).*/\1/'`] - AC_SUBST(LLVMGCC_LANGS,$llvmgcclangs) - AC_SUBST(LLVMGCC_DRAGONEGG,$llvm_cv_llvmgcc_dragonegg) - AC_SUBST(LLVMCC_DISABLEOPT_FLAGS) - AC_MSG_RESULT([ok]) -fi - dnl Propagate the shared library extension that the libltdl checks did to dnl the Makefiles so we can use it there too AC_SUBST(SHLIBEXT,$libltdl_cv_shlibext) @@ -1753,12 +1560,12 @@ if test -f ${srcdir}/tools/clang/README.txt; then AC_CONFIG_FILES([tools/clang/docs/doxygen.cfg]) fi -dnl Configure llvmc's Base plugin -AC_CONFIG_FILES([tools/llvmc/src/Base.td]) - dnl Do the first stage of configuration for llvm-config.in. AC_CONFIG_FILES([tools/llvm-config/llvm-config.in]) +dnl OCaml findlib META file +AC_CONFIG_FILES([bindings/ocaml/llvm/META.llvm]) + dnl Do special configuration of Makefiles AC_CONFIG_COMMANDS([setup],,[llvm_src="${srcdir}"]) AC_CONFIG_MAKEFILE(Makefile) diff --git a/bindings/ocaml/llvm/META.llvm.in b/bindings/ocaml/llvm/META.llvm.in new file mode 100644 index 000000000000..29e7eb418efc --- /dev/null +++ b/bindings/ocaml/llvm/META.llvm.in @@ -0,0 +1,63 @@ +name = "llvm" +version = "@PACKAGE_VERSION@" +description = "Low Level Virtual Machine OCaml bindings" +archive(byte) = "llvm.cma" +archive(native) = "llvm.cmxa" +directory = "." +linkopts = "-ccopt -lstdc++" + +package "analysis" ( + requires = "llvm" + version = "@PACKAGE_VERSION@" + description = "Intermediate representation analysis for LLVM" + archive(byte) = "llvm_analysis.cma" + archive(native) = "llvm_analysis.cmxa" +) + +package "bitreader" ( + requires = "llvm" + version = "@PACKAGE_VERSION@" + description = "Bitcode reader for LLVM" + archive(byte) = "llvm_bitreader.cma" + archive(native) = "llvm_bitreader.cmxa" +) + +package "bitwriter" ( + requires = "llvm,unix" + version = "@PACKAGE_VERSION@" + description = "Bitcode writer for LLVM" + archive(byte) = "llvm_bitwriter.cma" + archive(native) = "llvm_bitwriter.cmxa" +) + +package "executionengine" ( + requires = "llvm,llvm.target" + version = "@PACKAGE_VERSION@" + description = "JIT and Interpreter for LLVM" + archive(byte) = "llvm_executionengine.cma" + archive(native) = "llvm_executionengine.cmxa" +) + +package "ipo" ( + requires = "llvm" + version = "@PACKAGE_VERSION@" + description = "IPO Transforms for LLVM" + archive(byte) = "llvm_ipo.cma" + archive(native) = "llvm_ipo.cmxa" +) + +package "scalar_opts" ( + requires = "llvm" + version = "@PACKAGE_VERSION@" + description = "Scalar Transforms for LLVM" + archive(byte) = "llvm_scalar_opts.cma" + archive(native) = "llvm_scalar_opts.cmxa" +) + +package "target" ( + requires = "llvm" + version = "@PACKAGE_VERSION@" + description = "Target Information for LLVM" + archive(byte) = "llvm_target.cma" + archive(native) = "llvm_target.cmxa" +) diff --git a/bindings/ocaml/llvm/Makefile b/bindings/ocaml/llvm/Makefile index 99e347bc1312..673eaa2e35a9 100644 --- a/bindings/ocaml/llvm/Makefile +++ b/bindings/ocaml/llvm/Makefile @@ -17,3 +17,24 @@ UsedComponents := core UsedOcamLibs := llvm include ../Makefile.ocaml + +all-local:: copy-meta +install-local:: install-meta +uninstall-local:: uninstall-meta + +DestMETA := $(PROJ_libocamldir)/META.llvm + +# Easy way of generating META in the objdir +copy-meta: $(OcamlDir)/META.llvm + +$(OcamlDir)/META.llvm: META.llvm + $(Verb) $(CP) -f $< $@ + +install-meta:: $(ObjDir)/META.llvm + $(Echo) "Install $(BuildMode) $(DestMETA)" + $(Verb) $(MKDIR) $(PROJ_libocamldir) + $(Verb) $(DataInstall) META.llvm "$(DestMETA)" + +uninstall-meta:: + $(Echo) "Uninstalling $(DestMETA)" + -$(Verb) $(RM) -f "$(DestMETA)" diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml index a62ba377079c..40b013863667 100644 --- a/bindings/ocaml/llvm/llvm.ml +++ b/bindings/ocaml/llvm/llvm.ml @@ -94,6 +94,9 @@ module Attribute = struct | Naked | Inlinehint | Stackalignment of int + | ReturnsTwice + | UWTable + | NonLazyBind end module Icmp = struct @@ -130,6 +133,101 @@ module Fcmp = struct | True end +module Opcode = struct + type t = + | Invalid (* not an instruction *) + (* Terminator Instructions *) + | Ret + | Br + | Switch + | IndirectBr + | Invoke + | Invalid2 + | Unreachable + (* Standard Binary Operators *) + | Add + | FAdd + | Sub + | FSub + | Mul + | FMul + | UDiv + | SDiv + | FDiv + | URem + | SRem + | FRem + (* Logical Operators *) + | Shl + | LShr + | AShr + | And + | Or + | Xor + (* Memory Operators *) + | Alloca + | Load + | Store + | GetElementPtr + (* Cast Operators *) + | Trunc + | ZExt + | SExt + | FPToUI + | FPToSI + | UIToFP + | SIToFP + | FPTrunc + | FPExt + | PtrToInt + | IntToPtr + | BitCast + (* Other Operators *) + | ICmp + | FCmp + | PHI + | Call + | Select + | UserOp1 + | UserOp2 + | VAArg + | ExtractElement + | InsertElement + | ShuffleVector + | ExtractValue + | InsertValue + | Fence + | AtomicCmpXchg + | AtomicRMW + | Resume + | LandingPad + | Unwind +end + +module ValueKind = struct + type t = + | NullValue + | Argument + | BasicBlock + | InlineAsm + | MDNode + | MDString + | BlockAddress + | ConstantAggregateZero + | ConstantArray + | ConstantExpr + | ConstantFP + | ConstantInt + | ConstantPointerNull + | ConstantStruct + | ConstantVector + | Function + | GlobalAlias + | GlobalVariable + | UndefValue + | Instruction of Opcode.t +end + exception IoError of string external register_exns : exn -> unit = "llvm_register_core_exns" @@ -163,10 +261,12 @@ external set_data_layout: string -> llmodule -> unit external dump_module : llmodule -> unit = "llvm_dump_module" external set_module_inline_asm : llmodule -> string -> unit = "llvm_set_module_inline_asm" +external module_context : llmodule -> llcontext = "LLVMGetModuleContext" (*===-- Types -------------------------------------------------------------===*) external classify_type : lltype -> TypeKind.t = "llvm_classify_type" external type_context : lltype -> llcontext = "llvm_type_context" +external type_is_sized : lltype -> bool = "llvm_type_is_sized" (*--... Operations on integer types ........................................--*) external i1_type : llcontext -> lltype = "llvm_i1_type" @@ -197,9 +297,15 @@ external param_types : lltype -> lltype array = "llvm_param_types" external struct_type : llcontext -> lltype array -> lltype = "llvm_struct_type" external packed_struct_type : llcontext -> lltype array -> lltype = "llvm_packed_struct_type" +external struct_name : lltype -> string option = "llvm_struct_name" +external named_struct_type : llcontext -> string -> lltype = + "llvm_named_struct_type" +external struct_set_body : lltype -> lltype array -> bool -> unit = + "llvm_struct_set_body" external struct_element_types : lltype -> lltype array = "llvm_struct_element_types" external is_packed : lltype -> bool = "llvm_is_packed" +external is_opaque : lltype -> bool = "llvm_is_opaque" (*--... Operations on pointer, vector, and array types .....................--*) external array_type : lltype -> int -> lltype = "llvm_array_type" @@ -216,7 +322,9 @@ external vector_size : lltype -> int = "llvm_vector_size" (*--... Operations on other types ..........................................--*) external void_type : llcontext -> lltype = "llvm_void_type" external label_type : llcontext -> lltype = "llvm_label_type" +external type_by_name : llmodule -> string -> lltype option = "llvm_type_by_name" +external classify_value : llvalue -> ValueKind.t = "llvm_classify_value" (*===-- Values ------------------------------------------------------------===*) external type_of : llvalue -> lltype = "llvm_type_of" external value_name : llvalue -> string = "llvm_value_name" @@ -270,6 +378,7 @@ external const_pointer_null : lltype -> llvalue = "LLVMConstPointerNull" external undef : lltype -> llvalue = "LLVMGetUndef" external is_null : llvalue -> bool = "llvm_is_null" external is_undef : llvalue -> bool = "llvm_is_undef" +external constexpr_opcode : llvalue -> Opcode.t = "llvm_constexpr_get_opcode" (*--... Operations on instructions .........................................--*) external has_metadata : llvalue -> bool = "llvm_has_metadata" @@ -280,11 +389,15 @@ external clear_metadata : llvalue -> int -> unit = "llvm_clear_metadata" (*--... Operations on metadata .......,.....................................--*) external mdstring : llcontext -> string -> llvalue = "llvm_mdstring" external mdnode : llcontext -> llvalue array -> llvalue = "llvm_mdnode" +external get_mdstring : llvalue -> string option = "llvm_get_mdstring" +external get_named_metadata : llmodule -> string -> llvalue array = "llvm_get_namedmd" (*--... Operations on scalar constants .....................................--*) external const_int : lltype -> int -> llvalue = "llvm_const_int" external const_of_int64 : lltype -> Int64.t -> bool -> llvalue = "llvm_const_of_int64" +external int64_of_const : llvalue -> Int64.t option + = "llvm_int64_of_const" external const_int_of_string : lltype -> string -> int -> llvalue = "llvm_const_int_of_string" external const_float : lltype -> float -> llvalue = "llvm_const_float" @@ -297,6 +410,8 @@ external const_stringz : llcontext -> string -> llvalue = "llvm_const_stringz" external const_array : lltype -> llvalue array -> llvalue = "llvm_const_array" external const_struct : llcontext -> llvalue array -> llvalue = "llvm_const_struct" +external const_named_struct : lltype -> llvalue array -> llvalue + = "llvm_const_named_struct" external const_packed_struct : llcontext -> llvalue array -> llvalue = "llvm_const_packed_struct" external const_vector : llvalue array -> llvalue = "llvm_const_vector" @@ -530,36 +645,81 @@ let rec fold_right_function_range f i e init = let fold_right_functions f m init = fold_right_function_range f (function_end m) (At_start m) init -external llvm_add_function_attr : llvalue -> int -> unit +external llvm_add_function_attr : llvalue -> int32 -> unit = "llvm_add_function_attr" -external llvm_remove_function_attr : llvalue -> int -> unit +external llvm_remove_function_attr : llvalue -> int32 -> unit = "llvm_remove_function_attr" +external llvm_function_attr : llvalue -> int32 = "llvm_function_attr" -let pack_attr (attr:Attribute.t) : int = +let pack_attr (attr:Attribute.t) : int32 = match attr with - Attribute.Zext -> 1 lsl 0 - | Attribute.Sext -> 1 lsl 1 - | Attribute.Noreturn -> 1 lsl 2 - | Attribute.Inreg -> 1 lsl 3 - | Attribute.Structret -> 1 lsl 4 - | Attribute.Nounwind -> 1 lsl 5 - | Attribute.Noalias -> 1 lsl 6 - | Attribute.Byval -> 1 lsl 7 - | Attribute.Nest -> 1 lsl 8 - | Attribute.Readnone -> 1 lsl 9 - | Attribute.Readonly -> 1 lsl 10 - | Attribute.Noinline -> 1 lsl 11 - | Attribute.Alwaysinline -> 1 lsl 12 - | Attribute.Optsize -> 1 lsl 13 - | Attribute.Ssp -> 1 lsl 14 - | Attribute.Sspreq -> 1 lsl 15 - | Attribute.Alignment n -> n lsl 16 - | Attribute.Nocapture -> 1 lsl 21 - | Attribute.Noredzone -> 1 lsl 22 - | Attribute.Noimplicitfloat -> 1 lsl 23 - | Attribute.Naked -> 1 lsl 24 - | Attribute.Inlinehint -> 1 lsl 25 - | Attribute.Stackalignment n -> n lsl 26 + Attribute.Zext -> Int32.shift_left 1l 0 + | Attribute.Sext -> Int32.shift_left 1l 1 + | Attribute.Noreturn -> Int32.shift_left 1l 2 + | Attribute.Inreg -> Int32.shift_left 1l 3 + | Attribute.Structret -> Int32.shift_left 1l 4 + | Attribute.Nounwind -> Int32.shift_left 1l 5 + | Attribute.Noalias -> Int32.shift_left 1l 6 + | Attribute.Byval -> Int32.shift_left 1l 7 + | Attribute.Nest -> Int32.shift_left 1l 8 + | Attribute.Readnone -> Int32.shift_left 1l 9 + | Attribute.Readonly -> Int32.shift_left 1l 10 + | Attribute.Noinline -> Int32.shift_left 1l 11 + | Attribute.Alwaysinline -> Int32.shift_left 1l 12 + | Attribute.Optsize -> Int32.shift_left 1l 13 + | Attribute.Ssp -> Int32.shift_left 1l 14 + | Attribute.Sspreq -> Int32.shift_left 1l 15 + | Attribute.Alignment n -> Int32.shift_left (Int32.of_int n) 16 + | Attribute.Nocapture -> Int32.shift_left 1l 21 + | Attribute.Noredzone -> Int32.shift_left 1l 22 + | Attribute.Noimplicitfloat -> Int32.shift_left 1l 23 + | Attribute.Naked -> Int32.shift_left 1l 24 + | Attribute.Inlinehint -> Int32.shift_left 1l 25 + | Attribute.Stackalignment n -> Int32.shift_left (Int32.of_int n) 26 + | Attribute.ReturnsTwice -> Int32.shift_left 1l 29 + | Attribute.UWTable -> Int32.shift_left 1l 30 + | Attribute.NonLazyBind -> Int32.shift_left 1l 31 + +let unpack_attr (a : int32) : Attribute.t list = + let l = ref [] in + let check attr = + Int32.logand (pack_attr attr) a in + let checkattr attr = + if (check attr) <> 0l then begin + l := attr :: !l + end + in + checkattr Attribute.Zext; + checkattr Attribute.Sext; + checkattr Attribute.Noreturn; + checkattr Attribute.Inreg; + checkattr Attribute.Structret; + checkattr Attribute.Nounwind; + checkattr Attribute.Noalias; + checkattr Attribute.Byval; + checkattr Attribute.Nest; + checkattr Attribute.Readnone; + checkattr Attribute.Readonly; + checkattr Attribute.Noinline; + checkattr Attribute.Alwaysinline; + checkattr Attribute.Optsize; + checkattr Attribute.Ssp; + checkattr Attribute.Sspreq; + let align = Int32.logand (Int32.shift_right_logical a 16) 31l in + if align <> 0l then + l := Attribute.Alignment (Int32.to_int align) :: !l; + checkattr Attribute.Nocapture; + checkattr Attribute.Noredzone; + checkattr Attribute.Noimplicitfloat; + checkattr Attribute.Naked; + checkattr Attribute.Inlinehint; + let stackalign = Int32.logand (Int32.shift_right_logical a 26) 7l in + if stackalign <> 0l then + l := Attribute.Stackalignment (Int32.to_int stackalign) :: !l; + checkattr Attribute.ReturnsTwice; + checkattr Attribute.UWTable; + checkattr Attribute.NonLazyBind; + !l;; let add_function_attr llval attr = llvm_add_function_attr llval (pack_attr attr) @@ -567,9 +727,13 @@ let add_function_attr llval attr = let remove_function_attr llval attr = llvm_remove_function_attr llval (pack_attr attr) +let function_attr f = unpack_attr (llvm_function_attr f) + (*--... Operations on params ...............................................--*) external params : llvalue -> llvalue array = "llvm_params" external param : llvalue -> int -> llvalue = "llvm_param" +external llvm_param_attr : llvalue -> int32 = "llvm_param_attr" +let param_attr p = unpack_attr (llvm_param_attr p) external param_parent : llvalue -> llvalue = "LLVMGetParamParent" external param_begin : llvalue -> (llvalue, llvalue) llpos = "llvm_param_begin" external param_succ : llvalue -> (llvalue, llvalue) llpos = "llvm_param_succ" @@ -616,9 +780,9 @@ let rec fold_right_param_range f init i e = let fold_right_params f fn init = fold_right_param_range f init (param_end fn) (At_start fn) -external llvm_add_param_attr : llvalue -> int -> unit +external llvm_add_param_attr : llvalue -> int32 -> unit = "llvm_add_param_attr" -external llvm_remove_param_attr : llvalue -> int -> unit +external llvm_remove_param_attr : llvalue -> int32 -> unit = "llvm_remove_param_attr" let add_param_attr llval attr = @@ -650,6 +814,8 @@ external block_end : llvalue -> (llvalue, llbasicblock) llrev_pos = "llvm_block_end" external block_pred : llbasicblock -> (llvalue, llbasicblock) llrev_pos = "llvm_block_pred" +external block_terminator : llbasicblock -> llvalue option = + "llvm_block_terminator" let rec iter_block_range f i e = if i = e then () else @@ -702,6 +868,11 @@ external instr_end : llbasicblock -> (llbasicblock, llvalue) llrev_pos external instr_pred : llvalue -> (llbasicblock, llvalue) llrev_pos = "llvm_instr_pred" +external instr_opcode : llvalue -> Opcode.t = "llvm_instr_get_opcode" +external icmp_predicate : llvalue -> Icmp.t option = "llvm_instr_icmp_predicate" + +external icmp_predicate : llvalue -> Icmp.t option = "llvm_instr_icmp_predicate" + let rec iter_instrs_range f i e = if i = e then () else match i with @@ -749,9 +920,9 @@ external instruction_call_conv: llvalue -> int external set_instruction_call_conv: int -> llvalue -> unit = "llvm_set_instruction_call_conv" -external llvm_add_instruction_param_attr : llvalue -> int -> int -> unit +external llvm_add_instruction_param_attr : llvalue -> int -> int32 -> unit = "llvm_add_instruction_param_attr" -external llvm_remove_instruction_param_attr : llvalue -> int -> int -> unit +external llvm_remove_instruction_param_attr : llvalue -> int -> int32 -> unit = "llvm_remove_instruction_param_attr" let add_instruction_param_attr llval i attr = @@ -769,6 +940,7 @@ external add_incoming : (llvalue * llbasicblock) -> llvalue -> unit = "llvm_add_incoming" external incoming : llvalue -> (llvalue * llbasicblock) list = "llvm_incoming" +external delete_instruction : llvalue -> unit = "llvm_delete_instruction" (*===-- Instruction builders ----------------------------------------------===*) external builder : llcontext -> llbuilder = "llvm_builder" @@ -811,8 +983,15 @@ external build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder -> llvalue = "llvm_build_cond_br" external build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue = "llvm_build_switch" +external build_malloc : lltype -> string -> llbuilder -> llvalue = + "llvm_build_malloc" +external build_array_malloc : lltype -> llvalue -> string -> llbuilder -> + llvalue = "llvm_build_array_malloc" +external build_free : llvalue -> llbuilder -> llvalue = "llvm_build_free" external add_case : llvalue -> llvalue -> llbasicblock -> unit = "llvm_add_case" +external switch_default_dest : llvalue -> llbasicblock = + "LLVMGetSwitchDefaultDest" external build_indirect_br : llvalue -> int -> llbuilder -> llvalue = "llvm_build_indirect_br" external add_destination : llvalue -> llbasicblock -> unit @@ -820,7 +999,11 @@ external add_destination : llvalue -> llbasicblock -> unit external build_invoke : llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string -> llbuilder -> llvalue = "llvm_build_invoke_bc" "llvm_build_invoke_nat" -external build_unwind : llbuilder -> llvalue = "llvm_build_unwind" +external build_landingpad : lltype -> llvalue -> int -> string -> llbuilder -> + llvalue = "llvm_build_landingpad" +external set_cleanup : llvalue -> bool -> unit = "llvm_set_cleanup" +external add_clause : llvalue -> llvalue -> unit = "llvm_add_clause" +external build_resume : llvalue -> llbuilder -> llvalue = "llvm_build_resume" external build_unreachable : llbuilder -> llvalue = "llvm_build_unreachable" (*--... Arithmetic .........................................................--*) @@ -1022,7 +1205,14 @@ let rec string_of_lltype ty = (* FIXME: stop infinite recursion! :) *) match classify_type ty with TypeKind.Integer -> "i" ^ string_of_int (integer_bitwidth ty) - | TypeKind.Pointer -> (string_of_lltype (element_type ty)) ^ "*" + | TypeKind.Pointer -> + (let ety = element_type ty in + match classify_type ety with + | TypeKind.Struct -> + (match struct_name ety with + | None -> (string_of_lltype ety) + | Some s -> s) ^ "*" + | _ -> (string_of_lltype (element_type ty)) ^ "*") | TypeKind.Struct -> let s = "{ " ^ (concat2 ", " ( Array.map string_of_lltype (struct_element_types ty) diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli index 44f345f1b09e..33bbc74deb1b 100644 --- a/bindings/ocaml/llvm/llvm.mli +++ b/bindings/ocaml/llvm/llvm.mli @@ -139,6 +139,9 @@ module Attribute : sig | Naked | Inlinehint | Stackalignment of int + | ReturnsTwice + | UWTable + | NonLazyBind end (** The predicate for an integer comparison ([icmp]) instruction. @@ -179,6 +182,103 @@ module Fcmp : sig | True end +(** The opcodes for LLVM instructions and constant expressions. *) +module Opcode : sig + type t = + | Invalid (* not an instruction *) + (* Terminator Instructions *) + | Ret + | Br + | Switch + | IndirectBr + | Invoke + | Invalid2 + | Unreachable + (* Standard Binary Operators *) + | Add + | FAdd + | Sub + | FSub + | Mul + | FMul + | UDiv + | SDiv + | FDiv + | URem + | SRem + | FRem + (* Logical Operators *) + | Shl + | LShr + | AShr + | And + | Or + | Xor + (* Memory Operators *) + | Alloca + | Load + | Store + | GetElementPtr + (* Cast Operators *) + | Trunc + | ZExt + | SExt + | FPToUI + | FPToSI + | UIToFP + | SIToFP + | FPTrunc + | FPExt + | PtrToInt + | IntToPtr + | BitCast + (* Other Operators *) + | ICmp + | FCmp + | PHI + | Call + | Select + | UserOp1 + | UserOp2 + | VAArg + | ExtractElement + | InsertElement + | ShuffleVector + | ExtractValue + | InsertValue + | Fence + | AtomicCmpXchg + | AtomicRMW + | Resume + | LandingPad + | Unwind +end + +(** The kind of an [llvalue], the result of [classify_value v]. + * See the various [LLVMIsA*] functions. *) +module ValueKind : sig + type t = + | NullValue + | Argument + | BasicBlock + | InlineAsm + | MDNode + | MDString + | BlockAddress + | ConstantAggregateZero + | ConstantArray + | ConstantExpr + | ConstantFP + | ConstantInt + | ConstantPointerNull + | ConstantStruct + | ConstantVector + | Function + | GlobalAlias + | GlobalVariable + | UndefValue + | Instruction of Opcode.t +end (** {6 Iteration} *) @@ -263,7 +363,9 @@ val dump_module : llmodule -> unit the method [llvm::Module::setModuleInlineAsm]. *) val set_module_inline_asm : llmodule -> string -> unit - +(** [module_context m] returns the context of the specified module. + * See the method [llvm::Module::getContext] *) +val module_context : llmodule -> llcontext (** {6 Types} *) @@ -271,6 +373,11 @@ val set_module_inline_asm : llmodule -> string -> unit See the method [llvm::Type::getTypeID]. *) val classify_type : lltype -> TypeKind.t +(** [type_is_sized ty] returns whether the type has a size or not. + * If it doesn't then it is not safe to call the [TargetData::] methods on it. + * *) +val type_is_sized : lltype -> bool + (** [type_context ty] returns the {!llcontext} corresponding to the type [ty]. See the method [llvm::Type::getContext]. *) val type_context : lltype -> llcontext @@ -339,7 +446,7 @@ val ppc_fp128_type : llcontext -> lltype See the method [llvm::FunctionType::get]. *) val function_type : lltype -> lltype array -> lltype -(** [va_arg_function_type ret_ty param_tys] is just like +(** [var_arg_function_type ret_ty param_tys] is just like [function_type ret_ty param_tys] except that it returns the function type which also takes a variable number of arguments. See the method [llvm::FunctionType::get]. *) @@ -372,6 +479,19 @@ val struct_type : llcontext -> lltype array -> lltype [llvm::StructType::get]. *) val packed_struct_type : llcontext -> lltype array -> lltype +(** [struct_name ty] returns the name of the named structure type [ty], + * or None if the structure type is not named *) +val struct_name : lltype -> string option + +(** [named_struct_type context name] returns the named structure type [name] + * in the context [context]. + * See the method [llvm::StructType::get]. *) +val named_struct_type : llcontext -> string -> lltype + +(** [struct_set_body ty elts ispacked] sets the body of the named struct [ty] + * to the [elts] elements. + * See the moethd [llvm::StructType::setBody]. *) +val struct_set_body : lltype -> lltype array -> bool -> unit (** [struct_element_types sty] returns the constituent types of the struct type [sty]. See the method [llvm::StructType::getElementType]. *) @@ -382,6 +502,9 @@ val struct_element_types : lltype -> lltype array [false] otherwise. See the method [llvm::StructType::isPacked]. *) val is_packed : lltype -> bool +(** [is_opaque sty] returns [true] if the structure type [sty] is opaque. + [false] otherwise. See the method [llvm::StructType::isOpaque]. *) +val is_opaque : lltype -> bool (** {7 Operations on pointer, vector, and array types} *) @@ -431,12 +554,19 @@ val void_type : llcontext -> lltype [llvm::Type::LabelTy]. *) val label_type : llcontext -> lltype +(** [type_by_name m name] returns the specified type from the current module + * if it exists. + * See the method [llvm::Module::getTypeByName] *) +val type_by_name : llmodule -> string -> lltype option + (* {6 Values} *) (** [type_of v] returns the type of the value [v]. See the method [llvm::Value::getType]. *) val type_of : llvalue -> lltype +val classify_value : llvalue -> ValueKind.t + (** [value_name v] returns the name of the value [v]. For global values, this is the symbol name. For instructions and basic blocks, it is the SSA register name. It is meaningless for constants. @@ -534,7 +664,7 @@ val is_null : llvalue -> bool otherwise. Similar to [llvm::isa]. *) val is_undef : llvalue -> bool - +val constexpr_opcode : llvalue -> Opcode.t (** {7 Operations on instructions} *) (** [has_metadata i] returns whether or not the instruction [i] has any @@ -567,6 +697,14 @@ val mdstring : llcontext -> string -> llvalue See the method [llvm::MDNode::get]. *) val mdnode : llcontext -> llvalue array -> llvalue +(** [get_mdstring v] returns the MDString. + * See the method [llvm::MDString::getString] *) +val get_mdstring : llvalue -> string option + +(** [get_named_metadata m name] return all the MDNodes belonging to the named + * metadata (if any). + * See the method [llvm::NamedMDNode::getOperand]. *) +val get_named_metadata : llmodule -> string -> llvalue array (** {7 Operations on scalar constants} *) @@ -578,6 +716,10 @@ val const_int : lltype -> int -> llvalue [i]. See the method [llvm::ConstantInt::get]. *) val const_of_int64 : lltype -> Int64.t -> bool -> llvalue +(** [int64_of_const c] returns the int64 value of the [c] constant integer. + * None is returned if this is not an integer constant, or bitwidth exceeds 64. + * See the method [llvm::ConstantInt::getSExtValue].*) +val int64_of_const : llvalue -> Int64.t option (** [const_int_of_string ty s r] returns the integer constant of type [ty] and * value [s], with the radix [r]. See the method [llvm::ConstantInt::get]. *) @@ -618,9 +760,14 @@ val const_array : lltype -> llvalue array -> llvalue (** [const_struct context elts] returns the structured constant of type [struct_type (Array.map type_of elts)] and containing the values [elts] in the context [context]. This value can in turn be used as the initializer - for a global variable. See the method [llvm::ConstantStruct::get]. *) + for a global variable. See the method [llvm::ConstantStruct::getAnon]. *) val const_struct : llcontext -> llvalue array -> llvalue +(** [const_named_struct namedty elts] returns the structured constant of type + [namedty] (which must be a named structure type) and containing the values [elts]. + This value can in turn be used as the initializer + for a global variable. See the method [llvm::ConstantStruct::get]. *) +val const_named_struct : lltype -> llvalue array -> llvalue (** [const_packed_struct context elts] returns the structured constant of type {!packed_struct_type} [(Array.map type_of elts)] and containing the @@ -1231,6 +1378,10 @@ val set_gc : string option -> llvalue -> unit [f]. *) val add_function_attr : llvalue -> Attribute.t -> unit +(** [function_attr f] returns the function attribute for the function [f]. + * See the method [llvm::Function::getAttributes] *) +val function_attr : llvalue -> Attribute.t list + (** [remove_function_attr f a] removes attribute [a] from the return type of function [f]. *) val remove_function_attr : llvalue -> Attribute.t -> unit @@ -1245,6 +1396,11 @@ val params : llvalue -> llvalue array See the method [llvm::Function::getArgumentList]. *) val param : llvalue -> int -> llvalue +(** [param_attr p] returns the attributes of parameter [p]. + * See the methods [llvm::Function::getAttributes] and + * [llvm::Attributes::getParamAttributes] *) +val param_attr : llvalue -> Attribute.t list + (** [param_parent p] returns the parent function that owns the parameter. See the method [llvm::Argument::getParent]. *) val param_parent : llvalue -> llvalue @@ -1359,6 +1515,7 @@ val block_end : llvalue -> (llvalue, llbasicblock) llrev_pos See the method [llvm::Function::iterator::operator--]. *) val block_pred : llbasicblock -> (llvalue, llbasicblock) llrev_pos +val block_terminator : llbasicblock -> llvalue option (** [rev_iter_blocks f fn] applies function [f] to each of the basic blocks of function [fn] in reverse order. Tail recursive. *) @@ -1422,6 +1579,9 @@ val instr_pred : llvalue -> (llbasicblock, llvalue) llrev_pos [f1,...,fN] are the instructions of basic block [bb]. Tail recursive. *) val fold_right_instrs: (llvalue -> 'a -> 'a) -> llbasicblock -> 'a -> 'a +val instr_opcode : llvalue -> Opcode.t + +val icmp_predicate : llvalue -> Icmp.t option (** {7 Operations on call sites} *) @@ -1473,7 +1633,9 @@ val add_incoming : (llvalue * llbasicblock) -> llvalue -> unit See the method [llvm::PHINode::getIncomingValue]. *) val incoming : llvalue -> (llvalue * llbasicblock) list - +(** [delete_instruction i] deletes the instruction [i]. + * See the method [llvm::Instruction::eraseFromParent]. *) +val delete_instruction : llvalue -> unit (** {6 Instruction builders} *) @@ -1587,12 +1749,30 @@ val build_cond_br : llvalue -> llbasicblock -> llbasicblock -> llbuilder -> See the method [llvm::LLVMBuilder::CreateSwitch]. *) val build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue +(** [build_malloc ty name b] creates an [malloc] + instruction at the position specified by the instruction builder [b]. + See the method [llvm::CallInst::CreateMalloc]. *) +val build_malloc : lltype -> string -> llbuilder -> llvalue + +(** [build_array_malloc ty val name b] creates an [array malloc] + instruction at the position specified by the instruction builder [b]. + See the method [llvm::CallInst::CreateArrayMalloc]. *) +val build_array_malloc : lltype -> llvalue -> string -> llbuilder -> llvalue + +(** [build_free p b] creates a [free] + instruction at the position specified by the instruction builder [b]. + See the method [llvm::LLVMBuilder::CreateFree]. *) +val build_free : llvalue -> llbuilder -> llvalue (** [add_case sw onval bb] causes switch instruction [sw] to branch to [bb] when its input matches the constant [onval]. See the method [llvm::SwitchInst::addCase]. **) val add_case : llvalue -> llvalue -> llbasicblock -> unit +(** [switch_default_dest sw] returns the default destination of the [switch] + * instruction. + * See the method [llvm:;SwitchInst::getDefaultDest]. **) +val switch_default_dest : llvalue -> llbasicblock (** [build_indirect_br addr count b] creates a [indirectbr %addr] @@ -1615,12 +1795,25 @@ val add_destination : llvalue -> llbasicblock -> unit val build_invoke : llvalue -> llvalue array -> llbasicblock -> llbasicblock -> string -> llbuilder -> llvalue - -(** [build_unwind b] creates an - [unwind] +(** [build_landingpad ty persfn numclauses name b] creates an + [landingpad] instruction at the position specified by the instruction builder [b]. - See the method [llvm::LLVMBuilder::CreateUnwind]. *) -val build_unwind : llbuilder -> llvalue + See the method [llvm::LLVMBuilder::CreateLandingPad]. *) +val build_landingpad : lltype -> llvalue -> int -> string -> llbuilder -> + llvalue + +(** [set_cleanup lp] sets the cleanup flag in the [landingpad]instruction. + See the method [llvm::LandingPadInst::setCleanup]. *) +val set_cleanup : llvalue -> bool -> unit + +(** [add_clause lp clause] adds the clause to the [landingpad]instruction. + See the method [llvm::LandingPadInst::addClause]. *) +val add_clause : llvalue -> llvalue -> unit + +(* [build_resume exn b] builds a [resume exn] instruction + * at the position specified by the instruction builder [b]. + * See the method [llvm::LLVMBuilder::CreateResume] *) +val build_resume : llvalue -> llbuilder -> llvalue (** [build_unreachable b] creates an [unreachable] diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c index 455e191d5227..86cc4bd01436 100644 --- a/bindings/ocaml/llvm/llvm_ocaml.c +++ b/bindings/ocaml/llvm/llvm_ocaml.c @@ -24,6 +24,7 @@ #include "llvm/Config/config.h" #include #include +#include /* Can't use the recommended caml_named_value mechanism for backwards @@ -171,6 +172,10 @@ CAMLprim value llvm_classify_type(LLVMTypeRef Ty) { return Val_int(LLVMGetTypeKind(Ty)); } +CAMLprim value llvm_type_is_sized(LLVMTypeRef Ty) { + return Val_bool(LLVMTypeIsSized(Ty)); +} + /* lltype -> llcontext */ CAMLprim LLVMContextRef llvm_type_context(LLVMTypeRef Ty) { return LLVMGetTypeContext(Ty); @@ -287,6 +292,34 @@ CAMLprim LLVMTypeRef llvm_packed_struct_type(LLVMContextRef C, Wosize_val(ElementTypes), 1); } +/* llcontext -> string -> lltype */ +CAMLprim LLVMTypeRef llvm_named_struct_type(LLVMContextRef C, + value Name) { + return LLVMStructCreateNamed(C, String_val(Name)); +} + +CAMLprim value llvm_struct_set_body(LLVMTypeRef Ty, + value ElementTypes, + value Packed) { + LLVMStructSetBody(Ty, (LLVMTypeRef *) ElementTypes, + Wosize_val(ElementTypes), Bool_val(Packed)); + return Val_unit; +} + +/* lltype -> string option */ +CAMLprim value llvm_struct_name(LLVMTypeRef Ty) +{ + CAMLparam0(); + const char *C = LLVMGetStructName(Ty); + if (C) { + CAMLlocal1(result); + result = caml_alloc_small(1, 0); + Store_field(result, 0, caml_copy_string(C)); + CAMLreturn(result); + } + CAMLreturn(Val_int(0)); +} + /* lltype -> lltype array */ CAMLprim value llvm_struct_element_types(LLVMTypeRef StructTy) { value Tys = alloc(LLVMCountStructElementTypes(StructTy), 0); @@ -299,6 +332,11 @@ CAMLprim value llvm_is_packed(LLVMTypeRef StructTy) { return Val_bool(LLVMIsPackedStruct(StructTy)); } +/* lltype -> bool */ +CAMLprim value llvm_is_opaque(LLVMTypeRef StructTy) { + return Val_bool(LLVMIsOpaqueStruct(StructTy)); +} + /*--... Operations on array, pointer, and vector types .....................--*/ /* lltype -> int -> lltype */ @@ -349,6 +387,18 @@ CAMLprim LLVMTypeRef llvm_label_type(LLVMContextRef Context) { return LLVMLabelTypeInContext(Context); } +CAMLprim value llvm_type_by_name(LLVMModuleRef M, value Name) +{ + CAMLparam1(Name); + LLVMTypeRef Ty = LLVMGetTypeByName(M, String_val(Name)); + if (Ty) { + value Option = alloc(1, 0); + Field(Option, 0) = (value) Ty; + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + /*===-- VALUES ------------------------------------------------------------===*/ /* llvalue -> lltype */ @@ -356,6 +406,69 @@ CAMLprim LLVMTypeRef llvm_type_of(LLVMValueRef Val) { return LLVMTypeOf(Val); } +/* keep in sync with ValueKind.t */ +enum ValueKind { + NullValue=0, + Argument, + BasicBlock, + InlineAsm, + MDNode, + MDString, + BlockAddress, + ConstantAggregateZero, + ConstantArray, + ConstantExpr, + ConstantFP, + ConstantInt, + ConstantPointerNull, + ConstantStruct, + ConstantVector, + Function, + GlobalAlias, + GlobalVariable, + UndefValue, + Instruction +}; + +/* llvalue -> ValueKind.t */ +#define DEFINE_CASE(Val, Kind) \ + do {if (LLVMIsA##Kind(Val)) CAMLreturn(Val_int(Kind));} while(0) + +CAMLprim value llvm_classify_value(LLVMValueRef Val) { + CAMLparam0(); + if (!Val) + CAMLreturn(Val_int(NullValue)); + if (LLVMIsAConstant(Val)) { + DEFINE_CASE(Val, BlockAddress); + DEFINE_CASE(Val, ConstantAggregateZero); + DEFINE_CASE(Val, ConstantArray); + DEFINE_CASE(Val, ConstantExpr); + DEFINE_CASE(Val, ConstantFP); + DEFINE_CASE(Val, ConstantInt); + DEFINE_CASE(Val, ConstantPointerNull); + DEFINE_CASE(Val, ConstantStruct); + DEFINE_CASE(Val, ConstantVector); + } + if (LLVMIsAInstruction(Val)) { + CAMLlocal1(result); + result = caml_alloc_small(1, 0); + Store_field(result, 0, Val_int(LLVMGetInstructionOpcode(Val))); + CAMLreturn(result); + } + if (LLVMIsAGlobalValue(Val)) { + DEFINE_CASE(Val, Function); + DEFINE_CASE(Val, GlobalAlias); + DEFINE_CASE(Val, GlobalVariable); + } + DEFINE_CASE(Val, Argument); + DEFINE_CASE(Val, BasicBlock); + DEFINE_CASE(Val, InlineAsm); + DEFINE_CASE(Val, MDNode); + DEFINE_CASE(Val, MDString); + DEFINE_CASE(Val, UndefValue); + failwith("Unknown Value class"); +} + /* llvalue -> string */ CAMLprim value llvm_value_name(LLVMValueRef Val) { return copy_string(LLVMGetValueName(Val)); @@ -408,6 +521,12 @@ CAMLprim value llvm_is_undef(LLVMValueRef Val) { return Val_bool(LLVMIsUndef(Val)); } +/* llvalue -> Opcode.t */ +CAMLprim value llvm_constexpr_get_opcode(LLVMValueRef Val) { + return LLVMIsAConstantExpr(Val) ? + Val_int(LLVMGetConstOpcode(Val)) : Val_int(0); +} + /*--... Operations on instructions .........................................--*/ /* llvalue -> bool */ @@ -454,6 +573,32 @@ CAMLprim LLVMValueRef llvm_mdnode(LLVMContextRef C, value ElementVals) { Wosize_val(ElementVals)); } +/* llvalue -> string option */ +CAMLprim value llvm_get_mdstring(LLVMValueRef V) { + CAMLparam0(); + const char *S; + unsigned Len; + + if ((S = LLVMGetMDString(V, &Len))) { + CAMLlocal2(Option, Str); + + Str = caml_alloc_string(Len); + memcpy(String_val(Str), S, Len); + Option = alloc(1,0); + Store_field(Option, 0, Str); + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + +CAMLprim value llvm_get_namedmd(LLVMModuleRef M, value name) +{ + CAMLparam1(name); + CAMLlocal1(Nodes); + Nodes = alloc(LLVMGetNamedMetadataNumOperands(M, String_val(name)), 0); + LLVMGetNamedMetadataOperands(M, String_val(name), (LLVMValueRef *) Nodes); + CAMLreturn(Nodes); +} /*--... Operations on scalar constants .....................................--*/ /* lltype -> int -> llvalue */ @@ -467,6 +612,19 @@ CAMLprim LLVMValueRef llvm_const_of_int64(LLVMTypeRef IntTy, value N, return LLVMConstInt(IntTy, Int64_val(N), Bool_val(SExt)); } +/* llvalue -> Int64.t */ +CAMLprim value llvm_int64_of_const(LLVMValueRef Const) +{ + CAMLparam0(); + if (LLVMIsAConstantInt(Const) && + LLVMGetIntTypeWidth(LLVMTypeOf(Const)) <= 64) { + value Option = alloc(1, 0); + Field(Option, 0) = caml_copy_int64(LLVMConstIntGetSExtValue(Const)); + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + /* lltype -> string -> int -> llvalue */ CAMLprim LLVMValueRef llvm_const_int_of_string(LLVMTypeRef IntTy, value S, value Radix) { @@ -514,6 +672,11 @@ CAMLprim LLVMValueRef llvm_const_struct(LLVMContextRef C, value ElementVals) { Wosize_val(ElementVals), 0); } +/* lltype -> llvalue array -> llvalue */ +CAMLprim LLVMValueRef llvm_const_named_struct(LLVMTypeRef Ty, value ElementVals) { + return LLVMConstNamedStruct(Ty, (LLVMValueRef *) Op_val(ElementVals), Wosize_val(ElementVals)); +} + /* llcontext -> llvalue array -> llvalue */ CAMLprim LLVMValueRef llvm_const_packed_struct(LLVMContextRef C, value ElementVals) { @@ -883,15 +1046,22 @@ CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) { return Val_unit; } -/* llvalue -> Attribute.t -> unit */ +/* llvalue -> int32 -> unit */ CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) { - LLVMAddFunctionAttr(Arg, Int_val(PA)); + LLVMAddFunctionAttr(Arg, Int32_val(PA)); return Val_unit; } -/* llvalue -> Attribute.t -> unit */ +/* llvalue -> int32 */ +CAMLprim value llvm_function_attr(LLVMValueRef Fn) +{ + CAMLparam0(); + CAMLreturn(caml_copy_int32(LLVMGetFunctionAttr(Fn))); +} + +/* llvalue -> int32 -> unit */ CAMLprim value llvm_remove_function_attr(LLVMValueRef Arg, value PA) { - LLVMRemoveFunctionAttr(Arg, Int_val(PA)); + LLVMRemoveFunctionAttr(Arg, Int32_val(PA)); return Val_unit; } /*--... Operations on parameters ...........................................--*/ @@ -903,6 +1073,13 @@ CAMLprim LLVMValueRef llvm_param(LLVMValueRef Fn, value Index) { return LLVMGetParam(Fn, Int_val(Index)); } +/* llvalue -> int */ +CAMLprim value llvm_param_attr(LLVMValueRef Param) +{ + CAMLparam0(); + CAMLreturn(caml_copy_int32(LLVMGetAttribute(Param))); +} + /* llvalue -> llvalue */ CAMLprim value llvm_params(LLVMValueRef Fn) { value Params = alloc(LLVMCountParams(Fn), 0); @@ -910,15 +1087,15 @@ CAMLprim value llvm_params(LLVMValueRef Fn) { return Params; } -/* llvalue -> Attribute.t -> unit */ +/* llvalue -> int32 -> unit */ CAMLprim value llvm_add_param_attr(LLVMValueRef Arg, value PA) { - LLVMAddAttribute(Arg, Int_val(PA)); + LLVMAddAttribute(Arg, Int32_val(PA)); return Val_unit; } -/* llvalue -> Attribute.t -> unit */ +/* llvalue -> int32 -> unit */ CAMLprim value llvm_remove_param_attr(LLVMValueRef Arg, value PA) { - LLVMRemoveAttribute(Arg, Int_val(PA)); + LLVMRemoveAttribute(Arg, Int32_val(PA)); return Val_unit; } @@ -933,6 +1110,19 @@ CAMLprim value llvm_set_param_alignment(LLVMValueRef Arg, value align) { DEFINE_ITERATORS( block, BasicBlock, LLVMValueRef, LLVMBasicBlockRef, LLVMGetBasicBlockParent) +/* llbasicblock -> llvalue option */ +CAMLprim value llvm_block_terminator(LLVMBasicBlockRef Block) +{ + CAMLparam0(); + LLVMValueRef Term = LLVMGetBasicBlockTerminator(Block); + if (Term) { + value Option = alloc(1, 0); + Field(Option, 0) = (value) Term; + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + /* llvalue -> llbasicblock array */ CAMLprim value llvm_basic_blocks(LLVMValueRef Fn) { value MLArray = alloc(LLVMCountBasicBlocks(Fn), 0); @@ -968,6 +1158,28 @@ CAMLprim value llvm_value_is_block(LLVMValueRef Val) { DEFINE_ITERATORS(instr, Instruction, LLVMBasicBlockRef, LLVMValueRef, LLVMGetInstructionParent) +/* llvalue -> Opcode.t */ +CAMLprim value llvm_instr_get_opcode(LLVMValueRef Inst) { + LLVMOpcode o; + if (!LLVMIsAInstruction(Inst)) + failwith("Not an instruction"); + o = LLVMGetInstructionOpcode(Inst); + assert (o <= LLVMUnwind ); + return Val_int(o); +} + +/* llvalue -> ICmp.t */ +CAMLprim value llvm_instr_icmp_predicate(LLVMValueRef Val) { + CAMLparam0(); + int x = LLVMGetICmpPredicate(Val); + if (x) { + value Option = alloc(1, 0); + Field(Option, 0) = Val_int(x - LLVMIntEQ); + CAMLreturn(Option); + } + CAMLreturn(Val_int(0)); +} + /*--... Operations on call sites ...........................................--*/ @@ -982,19 +1194,19 @@ CAMLprim value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) { return Val_unit; } -/* llvalue -> int -> Attribute.t -> unit */ +/* llvalue -> int -> int32 -> unit */ CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr, value index, value PA) { - LLVMAddInstrAttribute(Instr, Int_val(index), Int_val(PA)); + LLVMAddInstrAttribute(Instr, Int_val(index), Int32_val(PA)); return Val_unit; } -/* llvalue -> int -> Attribute.t -> unit */ +/* llvalue -> int -> int32 -> unit */ CAMLprim value llvm_remove_instruction_param_attr(LLVMValueRef Instr, value index, value PA) { - LLVMRemoveInstrAttribute(Instr, Int_val(index), Int_val(PA)); + LLVMRemoveInstrAttribute(Instr, Int_val(index), Int32_val(PA)); return Val_unit; } @@ -1045,6 +1257,11 @@ CAMLprim value llvm_incoming(LLVMValueRef PhiNode) { CAMLreturn(Tl); } +/* llvalue -> unit */ +CAMLprim value llvm_delete_instruction(LLVMValueRef Instruction) { + LLVMInstructionEraseFromParent(Instruction); + return Val_unit; +} /*===-- Instruction builders ----------------------------------------------===*/ @@ -1172,6 +1389,27 @@ CAMLprim LLVMValueRef llvm_build_switch(LLVMValueRef Of, return LLVMBuildSwitch(Builder_val(B), Of, Else, Int_val(EstimatedCount)); } +/* lltype -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_malloc(LLVMTypeRef Ty, value Name, + value B) +{ + return LLVMBuildMalloc(Builder_val(B), Ty, String_val(Name)); +} + +/* lltype -> llvalue -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_array_malloc(LLVMTypeRef Ty, + LLVMValueRef Val, + value Name, value B) +{ + return LLVMBuildArrayMalloc(Builder_val(B), Ty, Val, String_val(Name)); +} + +/* llvalue -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_free(LLVMValueRef P, value B) +{ + return LLVMBuildFree(Builder_val(B), P); +} + /* llvalue -> llvalue -> llbasicblock -> unit */ CAMLprim value llvm_add_case(LLVMValueRef Switch, LLVMValueRef OnVal, LLVMBasicBlockRef Dest) { @@ -1212,9 +1450,33 @@ CAMLprim LLVMValueRef llvm_build_invoke_bc(value Args[], int NumArgs) { Args[4], Args[5]); } -/* llbuilder -> llvalue */ -CAMLprim LLVMValueRef llvm_build_unwind(value B) { - return LLVMBuildUnwind(Builder_val(B)); +/* lltype -> llvalue -> int -> string -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_landingpad(LLVMTypeRef Ty, LLVMValueRef PersFn, + value NumClauses, value Name, + value B) { + return LLVMBuildLandingPad(Builder_val(B), Ty, PersFn, Int_val(NumClauses), + String_val(Name)); +} + +/* llvalue -> llvalue -> unit */ +CAMLprim value llvm_add_clause(LLVMValueRef LandingPadInst, LLVMValueRef ClauseVal) +{ + LLVMAddClause(LandingPadInst, ClauseVal); + return Val_unit; +} + + +/* llvalue -> bool -> unit */ +CAMLprim value llvm_set_cleanup(LLVMValueRef LandingPadInst, value flag) +{ + LLVMSetCleanup(LandingPadInst, Bool_val(flag)); + return Val_unit; +} + +/* llvalue -> llbuilder -> llvalue */ +CAMLprim LLVMValueRef llvm_build_resume(LLVMValueRef Exn, value B) +{ + return LLVMBuildResume(Builder_val(B), Exn); } /* llbuilder -> llvalue */ diff --git a/bindings/ocaml/target/llvm_target.ml b/bindings/ocaml/target/llvm_target.ml index ea5341d5e8b2..49940eec4800 100644 --- a/bindings/ocaml/target/llvm_target.ml +++ b/bindings/ocaml/target/llvm_target.ml @@ -20,8 +20,6 @@ module TargetData = struct external add : t -> [ unit = "llvm_targetdata_add" external as_string : t -> string = "llvm_targetdata_as_string" - external invalidate_struct_layout : t -> Llvm.lltype -> unit - = "llvm_targetdata_invalidate_struct_layout" external dispose : t -> unit = "llvm_targetdata_dispose" end diff --git a/bindings/ocaml/target/llvm_target.mli b/bindings/ocaml/target/llvm_target.mli index a82e1b684fad..c288b9ac2d9c 100644 --- a/bindings/ocaml/target/llvm_target.mli +++ b/bindings/ocaml/target/llvm_target.mli @@ -35,13 +35,6 @@ module TargetData : sig See the constructor llvm::TargetData::TargetData. *) external as_string : t -> string = "llvm_targetdata_as_string" - (** Struct layouts are speculatively cached. If a TargetDataRef is alive when - types are being refined and removed, this method must be called whenever a - struct type is removed to avoid a dangling pointer in this cache. - See the method llvm::TargetData::InvalidateStructLayoutInfo. *) - external invalidate_struct_layout : t -> Llvm.lltype -> unit - = "llvm_targetdata_invalidate_struct_layout" - (** Deallocates a TargetData. See the destructor llvm::TargetData::~TargetData. *) external dispose : t -> unit = "llvm_targetdata_dispose" diff --git a/bindings/ocaml/target/target_ocaml.c b/bindings/ocaml/target/target_ocaml.c index cc20e8187a7a..ca01e7786b68 100644 --- a/bindings/ocaml/target/target_ocaml.c +++ b/bindings/ocaml/target/target_ocaml.c @@ -37,13 +37,6 @@ CAMLprim value llvm_targetdata_as_string(LLVMTargetDataRef TD) { return Copy; } -/* TargetData.t -> Llvm.lltype -> unit */ -CAMLprim value llvm_targetdata_invalidate_struct_layout(LLVMTargetDataRef TD, - LLVMTypeRef Ty) { - LLVMInvalidateStructLayout(TD, Ty); - return Val_unit; -} - /* TargetData.t -> unit */ CAMLprim value llvm_targetdata_dispose(LLVMTargetDataRef TD) { LLVMDisposeTargetData(TD); diff --git a/bindings/ocaml/transforms/Makefile b/bindings/ocaml/transforms/Makefile index 95b00c8d74aa..05fcd90097fe 100644 --- a/bindings/ocaml/transforms/Makefile +++ b/bindings/ocaml/transforms/Makefile @@ -8,7 +8,7 @@ ##===----------------------------------------------------------------------===## LEVEL := ../../.. -DIRS = scalar +DIRS = scalar ipo ocamldoc: $(Verb) for i in $(DIRS) ; do \ diff --git a/bindings/ocaml/transforms/ipo/Makefile b/bindings/ocaml/transforms/ipo/Makefile new file mode 100644 index 000000000000..130d74c90607 --- /dev/null +++ b/bindings/ocaml/transforms/ipo/Makefile @@ -0,0 +1,20 @@ +##===- bindings/ocaml/transforms/scalar/Makefile -----------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +# +# This is the makefile for the Objective Caml Llvm_scalar_opts interface. +# +##===----------------------------------------------------------------------===## + +LEVEL := ../../../.. +LIBRARYNAME := llvm_ipo +DONT_BUILD_RELINKED := 1 +UsedComponents := ipo +UsedOcamlInterfaces := llvm + +include ../../Makefile.ocaml diff --git a/bindings/ocaml/transforms/ipo/ipo_ocaml.c b/bindings/ocaml/transforms/ipo/ipo_ocaml.c new file mode 100644 index 000000000000..612015c099a7 --- /dev/null +++ b/bindings/ocaml/transforms/ipo/ipo_ocaml.c @@ -0,0 +1,104 @@ +/*===-- ipo_ocaml.c - LLVM Ocaml Glue -------------------*- C++ -*-===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file glues LLVM's ocaml interface to its C interface. These functions *| +|* are by and large transparent wrappers to the corresponding C functions. *| +|* *| +|* Note that these functions intentionally take liberties with the CAMLparamX *| +|* macros, since most of the parameters are not GC heap objects. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#include "llvm-c/Transforms/IPO.h" +#include "caml/mlvalues.h" +#include "caml/misc.h" + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_argument_promotion(LLVMPassManagerRef PM) { + LLVMAddArgumentPromotionPass(PM); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_constant_merge(LLVMPassManagerRef PM) { + LLVMAddConstantMergePass(PM); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_dead_arg_elimination(LLVMPassManagerRef PM) { + LLVMAddDeadArgEliminationPass(PM); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_function_attrs(LLVMPassManagerRef PM) { + LLVMAddFunctionAttrsPass(PM); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_function_inlining(LLVMPassManagerRef PM) { + LLVMAddFunctionInliningPass(PM); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_always_inliner_pass(LLVMPassManagerRef PM) { + LLVMAddAlwaysInlinerPass(PM); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_global_dce(LLVMPassManagerRef PM) { + LLVMAddGlobalDCEPass(PM); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_global_optimizer(LLVMPassManagerRef PM) { + LLVMAddGlobalOptimizerPass(PM); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_ipc_propagation(LLVMPassManagerRef PM) { + LLVMAddIPConstantPropagationPass(PM); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_prune_eh(LLVMPassManagerRef PM) { + LLVMAddPruneEHPass(PM); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_ipsccp(LLVMPassManagerRef PM) { + LLVMAddIPSCCPPass(PM); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> bool -> unit */ +CAMLprim value llvm_add_internalize(LLVMPassManagerRef PM, value AllButMain) { + LLVMAddInternalizePass(PM, Bool_val(AllButMain)); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_strip_dead_prototypes(LLVMPassManagerRef PM) { + LLVMAddStripDeadPrototypesPass(PM); + return Val_unit; +} + +/* [`Module] Llvm.PassManager.t -> unit */ +CAMLprim value llvm_add_strip_symbols(LLVMPassManagerRef PM) { + LLVMAddStripSymbolsPass(PM); + return Val_unit; +} diff --git a/bindings/ocaml/transforms/ipo/llvm_ipo.ml b/bindings/ocaml/transforms/ipo/llvm_ipo.ml new file mode 100644 index 000000000000..1562d10ae16e --- /dev/null +++ b/bindings/ocaml/transforms/ipo/llvm_ipo.ml @@ -0,0 +1,65 @@ +(*===-- llvm_ipo.mli - LLVM Ocaml Interface ------------*- OCaml -*-===* + * + * The LLVM Compiler Infrastructure + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------===*) + +(** IPO Transforms. + + This interface provides an ocaml API for LLVM interprocedural optimizations, the + classes in the [LLVMIPO] library. *) + +(** See llvm::createAddArgumentPromotionPass *) +external add_argument_promotion : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_argument_promotion" + +(** See llvm::createConstantMergePass function. *) +external add_constant_merge : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_constant_merge" + +(** See llvm::createDeadArgEliminationPass function. *) +external add_dead_arg_elimination : + [ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_dead_arg_elimination" + +(** See llvm::createFunctionAttrsPass function. *) +external add_function_attrs : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_function_attrs" + +(** See llvm::createFunctionInliningPass function. *) +external add_function_inlining : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_function_inlining" + +(** See llvm::createGlobalDCEPass function. *) +external add_global_dce : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_global_dce" + +(** See llvm::createGlobalOptimizerPass function. *) +external add_global_optimizer : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_global_optimizer" + +(** See llvm::createIPConstantPropagationPass function. *) +external add_ipc_propagation : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_ipc_propagation" + +(** See llvm::createPruneEHPass function. *) +external add_prune_eh : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_prune_eh" + +(** See llvm::createIPSCCPPass function. *) +external add_ipsccp : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_ipsccp" + +(** See llvm::createInternalizePass function. *) +external add_internalize : [ | `Module ] Llvm.PassManager.t -> bool -> unit = + "llvm_add_internalize" + +(** See llvm::createStripDeadPrototypesPass function. *) +external add_strip_dead_prototypes : + [ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_strip_dead_prototypes" + +(** See llvm::createStripSymbolsPass function. *) +external add_strip_symbols : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_strip_symbols" diff --git a/bindings/ocaml/transforms/ipo/llvm_ipo.mli b/bindings/ocaml/transforms/ipo/llvm_ipo.mli new file mode 100644 index 000000000000..636103d4f8cd --- /dev/null +++ b/bindings/ocaml/transforms/ipo/llvm_ipo.mli @@ -0,0 +1,65 @@ +(*===-- llvm_ipo.mli - LLVM Ocaml Interface ------------*- OCaml -*-===* + * + * The LLVM Compiler Infrastructure + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + *===----------------------------------------------------------------------===*) + +(** IPO Transforms. + + This interface provides an ocaml API for LLVM interprocedural optimizations, the + classes in the [LLVMIPO] library. *) + +(** See llvm::createAddArgumentPromotionPass *) +external add_argument_promotion : [ | `Module ] Llvm.PassManager.t -> unit = + + "llvm_add_argument_promotion" +(** See llvm::createConstantMergePass function. *) +external add_constant_merge : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_constant_merge" + +(** See llvm::createDeadArgEliminationPass function. *) +external add_dead_arg_elimination : + [ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_dead_arg_elimination" + +(** See llvm::createFunctionAttrsPass function. *) +external add_function_attrs : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_function_attrs" + +(** See llvm::createFunctionInliningPass function. *) +external add_function_inlining : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_function_inlining" + +(** See llvm::createGlobalDCEPass function. *) +external add_global_dce : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_global_dce" + +(** See llvm::createGlobalOptimizerPass function. *) +external add_global_optimizer : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_global_optimizer" + +(** See llvm::createIPConstantPropagationPass function. *) +external add_ipc_propagation : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_ipc_propagation" + +(** See llvm::createPruneEHPass function. *) +external add_prune_eh : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_prune_eh" + +(** See llvm::createIPSCCPPass function. *) +external add_ipsccp : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_ipsccp" + +(** See llvm::createInternalizePass function. *) +external add_internalize : [ | `Module ] Llvm.PassManager.t -> bool -> unit = + "llvm_add_internalize" + +(** See llvm::createStripDeadPrototypesPass function. *) +external add_strip_dead_prototypes : + [ | `Module ] Llvm.PassManager.t -> unit = "llvm_add_strip_dead_prototypes" + +(** See llvm::createStripSymbolsPass function. *) +external add_strip_symbols : [ | `Module ] Llvm.PassManager.t -> unit = + "llvm_add_strip_symbols" diff --git a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml b/bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml index 276e1182d054..93ab1de25823 100644 --- a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml +++ b/bindings/ocaml/transforms/scalar/llvm_scalar_opts.ml @@ -20,6 +20,15 @@ external add_aggressive_dce : [ unit external add_scalar_repl_aggregation : [ unit = "llvm_add_scalar_repl_aggregation" + +external +add_scalar_repl_aggregation_ssa : [ unit + = "llvm_add_scalar_repl_aggregation_ssa" + +external +add_scalar_repl_aggregation_with_threshold : int -> [ unit + = "llvm_add_scalar_repl_aggregation_with_threshold" external add_ind_var_simplification : [ unit = "llvm_add_ind_var_simplification" @@ -67,6 +76,36 @@ external add_memcpy_opt : [ unit = "llvm_add_loop_deletion" + +external add_loop_idiom : [ unit + = "llvm_add_loop_idiom" + external add_lib_call_simplification : [ unit = "llvm_add_lib_call_simplification" + +external +add_verifier : [ unit + = "llvm_add_verifier" + +external +add_correlated_value_propagation : [ unit + = "llvm_add_correlated_value_propagation" + +external +add_early_cse : [ unit + = "llvm_add_early_cse" + +external +add_lower_expect_intrinsic : [ unit + = "llvm_add_lower_expect_intrinsic" + +external +add_type_based_alias_analysis : [ unit + = "llvm_add_type_based_alias_analysis" + +external +add_basic_alias_analysis : [ unit + = "llvm_add_basic_alias_analysis" + diff --git a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli b/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli index d7162c769e43..121b3761282a 100644 --- a/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli +++ b/bindings/ocaml/transforms/scalar/llvm_scalar_opts.mli @@ -35,6 +35,17 @@ external add_scalar_repl_aggregation : [ unit = "llvm_add_scalar_repl_aggregation" +(** See the [llvm::createScalarReplAggregatesPassSSA] function. *) +external +add_scalar_repl_aggregation_ssa : [ unit + = "llvm_add_scalar_repl_aggregation_ssa" + +(** See the [llvm::createScalarReplAggregatesWithThreshold] function. *) +external +add_scalar_repl_aggregation_with_threshold : int -> [ unit + = "llvm_add_scalar_repl_aggregation_with_threshold" + (** See the [llvm::createIndVarSimplifyPass] function. *) external add_ind_var_simplification : [ unit @@ -112,7 +123,42 @@ external add_loop_deletion : [ unit = "llvm_add_loop_deletion" +external add_loop_idiom : [ unit + = "llvm_add_loop_idiom" + (** See the [llvm::createSimplifyLibCallsPass] function. *) external add_lib_call_simplification : [ unit = "llvm_add_lib_call_simplification" + +(** See the [llvm::createVerifierPass] function. *) +external +add_verifier : [ unit + = "llvm_add_verifier" + +(** See the [llvm::createCorrelatedValuePropagationPass] function. *) +external +add_correlated_value_propagation : [ unit + = "llvm_add_correlated_value_propagation" + +(** See the [llvm::createEarlyCSE] function. *) +external +add_early_cse : [ unit + = "llvm_add_early_cse" + +(** See the [llvm::createLowerExpectIntrinsicPass] function. *) +external +add_lower_expect_intrinsic : [ unit + = "llvm_add_lower_expect_intrinsic" + +(** See the [llvm::createTypeBasedAliasAnalysisPass] function. *) +external +add_type_based_alias_analysis : [ unit + = "llvm_add_type_based_alias_analysis" + +(** See the [llvm::createBasicAliasAnalysisPass] function. *) +external +add_basic_alias_analysis : [ unit + = "llvm_add_basic_alias_analysis" + diff --git a/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c b/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c index df44807859c8..2db645624a7e 100644 --- a/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c +++ b/bindings/ocaml/transforms/scalar/scalar_opts_ocaml.c @@ -49,6 +49,19 @@ CAMLprim value llvm_add_scalar_repl_aggregation(LLVMPassManagerRef PM) { return Val_unit; } +/* [ unit */ +CAMLprim value llvm_add_scalar_repl_aggregation_ssa(LLVMPassManagerRef PM) { + LLVMAddScalarReplAggregatesPassSSA(PM); + return Val_unit; +} + +/* [ int -> unit */ +CAMLprim value llvm_add_scalar_repl_aggregation_with_threshold(value threshold, + LLVMPassManagerRef PM) { + LLVMAddScalarReplAggregatesPassWithThreshold(PM, Int_val(threshold)); + return Val_unit; +} + /* [ unit */ CAMLprim value llvm_add_ind_var_simplification(LLVMPassManagerRef PM) { LLVMAddIndVarSimplifyPass(PM); @@ -69,7 +82,7 @@ CAMLprim value llvm_add_licm(LLVMPassManagerRef PM) { /* [ unit */ CAMLprim value llvm_add_loop_unswitch(LLVMPassManagerRef PM) { - LLVMAddLoopUnrollPass(PM); + LLVMAddLoopUnswitchPass(PM); return Val_unit; } @@ -139,8 +152,50 @@ CAMLprim value llvm_add_loop_deletion(LLVMPassManagerRef PM) { return Val_unit; } +/* [ unit */ +CAMLprim value llvm_add_loop_idiom(LLVMPassManagerRef PM) { + LLVMAddLoopIdiomPass(PM); + return Val_unit; +} + /* [ unit */ CAMLprim value llvm_add_lib_call_simplification(LLVMPassManagerRef PM) { LLVMAddSimplifyLibCallsPass(PM); return Val_unit; } + +/* [ unit */ +CAMLprim value llvm_add_verifier(LLVMPassManagerRef PM) { + LLVMAddVerifierPass(PM); + return Val_unit; +} + +/* [ unit */ +CAMLprim value llvm_add_correlated_value_propagation(LLVMPassManagerRef PM) { + LLVMAddCorrelatedValuePropagationPass(PM); + return Val_unit; +} + +/* [ unit */ +CAMLprim value llvm_add_early_cse(LLVMPassManagerRef PM) { + LLVMAddEarlyCSEPass(PM); + return Val_unit; +} + +/* [ unit */ +CAMLprim value llvm_add_lower_expect_intrinsic(LLVMPassManagerRef PM) { + LLVMAddLowerExpectIntrinsicPass(PM); + return Val_unit; +} + +/* [ unit */ +CAMLprim value llvm_add_type_based_alias_analysis(LLVMPassManagerRef PM) { + LLVMAddTypeBasedAliasAnalysisPass(PM); + return Val_unit; +} + +/* [ unit */ +CAMLprim value llvm_add_basic_alias_analysis(LLVMPassManagerRef PM) { + LLVMAddBasicAliasAnalysisPass(PM); + return Val_unit; +} diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index 46f33de8d7f5..0381dbf49635 100755 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -198,11 +198,6 @@ if( LLVM_USING_GLIBC ) add_llvm_definitions( -D_GNU_SOURCE ) endif() -# Type checks -check_type_exists(std::bidirectional_iterator "iterator;iostream" HAVE_BI_ITERATOR) -check_type_exists(std::iterator iterator HAVE_STD_ITERATOR) -check_type_exists(std::forward_iterator iterator HAVE_FWD_ITERATOR) - set(headers "") if (HAVE_SYS_TYPES_H) set(headers ${headers} "sys/types.h") @@ -277,7 +272,7 @@ else() unset(HAVE_FFI_CALL CACHE) endif( LLVM_ENABLE_FFI ) -# Define LLVM_MULTITHREADED if gcc atomic builtins exists. +# Define LLVM_HAS_ATOMICS if gcc or MSVC atomic builtins are supported. include(CheckAtomic) if( LLVM_ENABLE_PIC ) @@ -336,7 +331,7 @@ else () message(STATUS "Native target architecture is ${LLVM_NATIVE_ARCH}") set(LLVM_NATIVE_TARGET LLVMInitialize${LLVM_NATIVE_ARCH}Target) set(LLVM_NATIVE_TARGETINFO LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo) - set(LLVM_NATIVE_MCASMINFO LLVMInitialize${LLVM_NATIVE_ARCH}MCAsmInfo) + set(LLVM_NATIVE_TARGETMC LLVMInitialize${LLVM_NATIVE_ARCH}TargetMC) set(LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter) endif () diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake index c13143bb0d47..b486fe4d8214 100755 --- a/cmake/modules/AddLLVM.cmake +++ b/cmake/modules/AddLLVM.cmake @@ -24,16 +24,17 @@ macro(add_llvm_library name) LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}) endif() - # The LLVM Target library shall be built before its sublibraries - # (asmprinter, etc) because those may use tablegenned files which - # generation is triggered by the main LLVM target library. Necessary - # for parallel builds: - if( CURRENT_LLVM_TARGET ) - add_dependencies(${name} ${CURRENT_LLVM_TARGET}) - endif() set_target_properties(${name} PROPERTIES FOLDER "Libraries") endmacro(add_llvm_library name) +macro(add_llvm_library_dependencies name) + # Save the dependencies of the LLVM library in a variable so that we can + # query it when resolve llvm-config-style component -> library mappings. + set_property(GLOBAL PROPERTY LLVM_LIB_DEPS_${name} ${ARGN}) + + # Then add the actual dependencies to the library target. + target_link_libraries(${name} ${ARGN}) +endmacro(add_llvm_library_dependencies name) macro(add_llvm_loadable_module name) if( NOT LLVM_ON_UNIX OR CYGWIN ) @@ -124,16 +125,9 @@ endmacro(add_llvm_utility name) macro(add_llvm_target target_name) - if( TABLEGEN_OUTPUT ) - add_custom_target(${target_name}Table_gen - DEPENDS ${TABLEGEN_OUTPUT}) - add_dependencies(${target_name}Table_gen ${LLVM_COMMON_DEPENDS}) - endif( TABLEGEN_OUTPUT ) - include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) + include_directories(BEFORE + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}) add_llvm_library(LLVM${target_name} ${ARGN} ${TABLEGEN_OUTPUT}) - if ( TABLEGEN_OUTPUT ) - add_dependencies(LLVM${target_name} ${target_name}Table_gen) - set_target_properties(${target_name}Table_gen PROPERTIES FOLDER "Tablegenning") - endif (TABLEGEN_OUTPUT) set( CURRENT_LLVM_TARGET LLVM${target_name} ) endmacro(add_llvm_target) diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt index 257deb6d4c7a..2dcfa141026e 100644 --- a/cmake/modules/CMakeLists.txt +++ b/cmake/modules/CMakeLists.txt @@ -3,6 +3,12 @@ set(LLVM_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) get_property(llvm_libs GLOBAL PROPERTY LLVM_LIBS) +foreach(lib ${llvm_libs}) + get_property(llvm_lib_deps GLOBAL PROPERTY LLVM_LIB_DEPS_${lib}) + set(all_llvm_lib_deps + "${all_llvm_lib_deps}\nset_property(GLOBAL PROPERTY LLVM_LIB_DEPS_${lib} ${llvm_lib_deps})") +endforeach(lib) + configure_file( LLVMConfig.cmake.in ${llvm_cmake_builddir}/LLVMConfig.cmake @@ -17,7 +23,6 @@ install(FILES ${llvm_cmake_builddir}/LLVMConfig.cmake ${llvm_cmake_builddir}/LLVMConfigVersion.cmake LLVM-Config.cmake - LLVMLibDeps.cmake DESTINATION share/llvm/cmake) install(DIRECTORY . @@ -27,8 +32,6 @@ install(DIRECTORY . PATTERN LLVMConfig.cmake EXCLUDE PATTERN LLVMConfigVersion.cmake EXCLUDE PATTERN LLVM-Config.cmake EXCLUDE - PATTERN LLVMLibDeps.cmake EXCLUDE - PATTERN FindBison.cmake EXCLUDE PATTERN GetTargetTriple.cmake EXCLUDE PATTERN VersionFromVCS.cmake EXCLUDE PATTERN CheckAtomic.cmake EXCLUDE) diff --git a/cmake/modules/CheckAtomic.cmake b/cmake/modules/CheckAtomic.cmake index f40ff4dfbd31..0d63a82b97a0 100644 --- a/cmake/modules/CheckAtomic.cmake +++ b/cmake/modules/CheckAtomic.cmake @@ -22,8 +22,8 @@ int main() { #endif return 0; } -" LLVM_MULTITHREADED) +" LLVM_HAS_ATOMICS) -if( NOT LLVM_MULTITHREADED ) +if( NOT LLVM_HAS_ATOMICS ) message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing") endif() diff --git a/cmake/modules/CrossCompileLLVM.cmake b/cmake/modules/CrossCompileLLVM.cmake deleted file mode 100644 index 98e60a54366f..000000000000 --- a/cmake/modules/CrossCompileLLVM.cmake +++ /dev/null @@ -1,26 +0,0 @@ - -if( ${LLVM_TABLEGEN} STREQUAL "tblgen" ) - set(CX_NATIVE_TG_DIR "${CMAKE_BINARY_DIR}/native") - set(LLVM_TABLEGEN_EXE "${CX_NATIVE_TG_DIR}/bin/tblgen") - - add_custom_command(OUTPUT ${CX_NATIVE_TG_DIR} - COMMAND ${CMAKE_COMMAND} -E make_directory ${CX_NATIVE_TG_DIR} - COMMENT "Creating ${CX_NATIVE_TG_DIR}...") - - add_custom_command(OUTPUT ${CX_NATIVE_TG_DIR}/CMakeCache.txt - COMMAND ${CMAKE_COMMAND} -UMAKE_TOOLCHAIN_FILE -DCMAKE_BUILD_TYPE=Release ${CMAKE_SOURCE_DIR} - WORKING_DIRECTORY ${CX_NATIVE_TG_DIR} - DEPENDS ${CX_NATIVE_TG_DIR} - COMMENT "Configuring native TableGen...") - - add_custom_command(OUTPUT ${LLVM_TABLEGEN_EXE} - COMMAND ${CMAKE_BUILD_TOOL} - DEPENDS ${CX_NATIVE_TG_DIR}/CMakeCache.txt - WORKING_DIRECTORY ${CX_NATIVE_TG_DIR}/utils/TableGen - COMMENT "Building native TableGen...") - add_custom_target(NativeTableGen DEPENDS ${LLVM_TABLEGEN_EXE}) - - add_dependencies(tblgen NativeTableGen) - - set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CX_NATIVE_TG_DIR}) -endif() diff --git a/cmake/modules/FindBison.cmake b/cmake/modules/FindBison.cmake deleted file mode 100755 index 0320ae3ce142..000000000000 --- a/cmake/modules/FindBison.cmake +++ /dev/null @@ -1,52 +0,0 @@ -# - Try to find Bison -# Once done this will define -# -# BISON_FOUND - system has Bison -# BISON_EXECUTABLE - path of the bison executable -# BISON_VERSION - the version string, like "2.5.31" -# - -MACRO(FIND_BISON) - FIND_PROGRAM(BISON_EXECUTABLE NAMES bison) - - IF(BISON_EXECUTABLE) - SET(BISON_FOUND TRUE) - - EXECUTE_PROCESS(COMMAND ${BISON_EXECUTABLE} --version - OUTPUT_VARIABLE _BISON_VERSION - ) - string (REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" BISON_VERSION "${_bison_VERSION}") - ENDIF(BISON_EXECUTABLE) - - IF(BISON_FOUND) - IF(NOT Bison_FIND_QUIETLY) - MESSAGE(STATUS "Found Bison: ${BISON_EXECUTABLE}") - ENDIF(NOT Bison_FIND_QUIETLY) - ELSE(BISON_FOUND) - IF(Bison_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find Bison") - ENDIF(Bison_FIND_REQUIRED) - ENDIF(BISON_FOUND) -ENDMACRO(FIND_BISON) - -MACRO(BISON_GENERATOR _PREFIX _Y_INPUT _H_OUTPUT _CPP_OUTPUT) - IF(BISON_EXECUTABLE) - GET_FILENAME_COMPONENT(_Y_DIR ${_Y_INPUT} PATH) - ADD_CUSTOM_COMMAND( - OUTPUT ${_CPP_OUTPUT} - OUTPUT ${_H_OUTPUT} - DEPENDS ${_Y_INPUT} - COMMAND ${BISON_EXECUTABLE} - ARGS - -p ${_PREFIX} -o"${_CPP_OUTPUT}" - --defines="${_H_OUTPUT}" ${_Y_INPUT} - WORKING_DIRECTORY ${_Y_DIR} - ) - SET_SOURCE_FILES_PROPERTIES( - ${_CPP_OUTPUT} ${_H_OUTPUT} - GENERATED - ) - ELSE(BISON_EXECUTABLE) - MESSAGE(SEND_ERROR "Can't find bison program, and it's required") - ENDIF(BISON_EXECUTABLE) -ENDMACRO(BISON_GENERATOR) diff --git a/cmake/modules/HandleLLVMOptions.cmake b/cmake/modules/HandleLLVMOptions.cmake index d0427acbd5dc..9dc1624f446c 100644 --- a/cmake/modules/HandleLLVMOptions.cmake +++ b/cmake/modules/HandleLLVMOptions.cmake @@ -155,6 +155,7 @@ if( MSVC ) -wd4351 # Suppress 'new behavior: elements of array 'array' will be default initialized' -wd4355 # Suppress ''this' : used in base member initializer list' -wd4503 # Suppress ''identifier' : decorated name length exceeded, name was truncated' + -wd4551 # Suppress 'function call missing argument list' -wd4624 # Suppress ''derived class' : destructor could not be generated because a base class destructor is inaccessible' -wd4715 # Suppress ''function' : not all control paths return a value' -wd4800 # Suppress ''type' : forcing value to bool 'true' or 'false' (performance warning)' @@ -185,7 +186,8 @@ elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE ) endif (LLVM_ENABLE_WERROR) endif( MSVC ) -add_llvm_definitions( -D__STDC_LIMIT_MACROS ) add_llvm_definitions( -D__STDC_CONSTANT_MACROS ) +add_llvm_definitions( -D__STDC_FORMAT_MACROS ) +add_llvm_definitions( -D__STDC_LIMIT_MACROS ) option(LLVM_INCLUDE_TESTS "Generate build targets for the LLVM unit tests." ON) diff --git a/cmake/modules/LLVM-Config.cmake b/cmake/modules/LLVM-Config.cmake index a6286fee6856..b5f262a24da8 100755 --- a/cmake/modules/LLVM-Config.cmake +++ b/cmake/modules/LLVM-Config.cmake @@ -135,14 +135,14 @@ function(explicit_map_components_to_libraries out_libs) string(TOUPPER "${c}" capitalized) list(FIND capitalized_libs LLVM${capitalized} lib_idx) if( lib_idx LESS 0 ) - # The component is unknown. Maybe is an omitted target? - is_llvm_target_library(${c} iltl_result) - if( NOT iltl_result ) - message(FATAL_ERROR "Library `${c}' not found in list of llvm libraries.") - endif() + # The component is unknown. Maybe is an omitted target? + is_llvm_target_library(${c} iltl_result) + if( NOT iltl_result ) + message(FATAL_ERROR "Library `${c}' not found in list of llvm libraries.") + endif() else( lib_idx LESS 0 ) - list(GET llvm_libs ${lib_idx} canonical_lib) - list(APPEND expanded_components ${canonical_lib}) + list(GET llvm_libs ${lib_idx} canonical_lib) + list(APPEND expanded_components ${canonical_lib}) endif( lib_idx LESS 0 ) endif( NOT idx LESS 0 ) endforeach(c) @@ -152,7 +152,8 @@ function(explicit_map_components_to_libraries out_libs) set(processed) while( cursor LESS lst_size ) list(GET expanded_components ${cursor} lib) - list(APPEND expanded_components ${MSVC_LIB_DEPS_${lib}}) + get_property(lib_deps GLOBAL PROPERTY LLVM_LIB_DEPS_${lib}) + list(APPEND expanded_components ${lib_deps}) # Remove duplicates at the front: list(REVERSE expanded_components) list(REMOVE_DUPLICATES expanded_components) @@ -175,29 +176,3 @@ function(explicit_map_components_to_libraries out_libs) endforeach(c) set(${out_libs} ${result} PARENT_SCOPE) endfunction(explicit_map_components_to_libraries) - - -# The library dependency data is contained in the file -# LLVMLibDeps.cmake on this directory. It is automatically generated -# by tools/llvm-config/CMakeLists.txt when the build comprises all the -# targets and we are on a environment Posix enough to build the -# llvm-config script. This, in practice, just excludes MSVC. - -# When you remove or rename a library from the build, be sure to -# remove its file from lib/ as well, or the GenLibDeps.pl script will -# include it on its analysis! - -# The format generated by GenLibDeps.pl - -# LLVMARMAsmPrinter.o: LLVMARMCodeGen.o libLLVMAsmPrinter.a libLLVMCodeGen.a libLLVMCore.a libLLVMSupport.a libLLVMTarget.a - -# is translated to: - -# set(MSVC_LIB_DEPS_LLVMARMAsmPrinter LLVMARMCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMSupport LLVMTarget) - -# It is necessary to remove the `lib' prefix and the `.a'. - -# This 'sed' script should do the trick: -# sed -e s'#\.a##g' -e 's#libLLVM#LLVM#g' -e 's#: # #' -e 's#\(.*\)#set(MSVC_LIB_DEPS_\1)#' ~/llvm/tools/llvm-config/LibDeps.txt - -include(LLVMLibDeps) diff --git a/cmake/modules/LLVMConfig.cmake.in b/cmake/modules/LLVMConfig.cmake.in index 5a048b714b57..6b202b2e7e87 100644 --- a/cmake/modules/LLVMConfig.cmake.in +++ b/cmake/modules/LLVMConfig.cmake.in @@ -12,6 +12,8 @@ set(LLVM_TARGETS_TO_BUILD @LLVM_TARGETS_TO_BUILD@) set(LLVM_TARGETS_WITH_JIT @LLVM_TARGETS_WITH_JIT@) +@all_llvm_lib_deps@ + set(TARGET_TRIPLE "@TARGET_TRIPLE@") set(LLVM_TOOLS_BINARY_DIR @LLVM_TOOLS_BINARY_DIR@) diff --git a/cmake/modules/LLVMLibDeps.cmake b/cmake/modules/LLVMLibDeps.cmake deleted file mode 100644 index 14575e5de5f3..000000000000 --- a/cmake/modules/LLVMLibDeps.cmake +++ /dev/null @@ -1,83 +0,0 @@ -set(MSVC_LIB_DEPS_LLVMARMAsmParser LLVMARMCodeGen LLVMARMInfo LLVMMC LLVMMCParser LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMARMAsmPrinter LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMARMCodeGen LLVMARMAsmPrinter LLVMARMDesc LLVMARMInfo LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMARMDesc LLVMARMInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMARMDisassembler LLVMARMCodeGen LLVMARMDesc LLVMARMInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMARMInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMAlphaCodeGen LLVMAlphaDesc LLVMAlphaInfo LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMAlphaDesc LLVMAlphaInfo LLVMMC) -set(MSVC_LIB_DEPS_LLVMAlphaInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMAnalysis LLVMCore LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMArchive LLVMBitReader LLVMCore LLVMSupport) -set(MSVC_LIB_DEPS_LLVMAsmParser LLVMCore LLVMSupport) -set(MSVC_LIB_DEPS_LLVMAsmPrinter LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMMCParser LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMBitReader LLVMCore LLVMSupport) -set(MSVC_LIB_DEPS_LLVMBitWriter LLVMCore LLVMSupport) -set(MSVC_LIB_DEPS_LLVMBlackfinCodeGen LLVMAsmPrinter LLVMBlackfinDesc LLVMBlackfinInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMBlackfinDesc LLVMBlackfinInfo LLVMMC) -set(MSVC_LIB_DEPS_LLVMBlackfinInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMCBackend LLVMAnalysis LLVMCBackendInfo LLVMCodeGen LLVMCore LLVMMC LLVMScalarOpts LLVMSupport LLVMTarget LLVMTransformUtils) -set(MSVC_LIB_DEPS_LLVMCBackendInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMCellSPUCodeGen LLVMAsmPrinter LLVMCellSPUDesc LLVMCellSPUInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMCellSPUDesc LLVMCellSPUInfo LLVMMC) -set(MSVC_LIB_DEPS_LLVMCellSPUInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMCodeGen LLVMAnalysis LLVMCore LLVMMC LLVMScalarOpts LLVMSupport LLVMTarget LLVMTransformUtils) -set(MSVC_LIB_DEPS_LLVMCore LLVMSupport) -set(MSVC_LIB_DEPS_LLVMCppBackend LLVMCore LLVMCppBackendInfo LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMCppBackendInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMExecutionEngine LLVMCore LLVMMC LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMInstCombine LLVMAnalysis LLVMCore LLVMSupport LLVMTarget LLVMTransformUtils) -set(MSVC_LIB_DEPS_LLVMInstrumentation LLVMAnalysis LLVMCore LLVMSupport LLVMTransformUtils) -set(MSVC_LIB_DEPS_LLVMInterpreter LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMJIT LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMMC LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMLinker LLVMArchive LLVMBitReader LLVMCore LLVMSupport LLVMTransformUtils) -set(MSVC_LIB_DEPS_LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMMBlazeAsmPrinter LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMBlazeCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMBlazeAsmPrinter LLVMMBlazeDesc LLVMMBlazeInfo LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMMBlazeDesc LLVMMBlazeInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMBlazeDisassembler LLVMMBlazeCodeGen LLVMMBlazeDesc LLVMMBlazeInfo LLVMMC) -set(MSVC_LIB_DEPS_LLVMMBlazeInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen LLVMARMDesc LLVMARMDisassembler LLVMARMInfo LLVMAlphaCodeGen LLVMAlphaDesc LLVMAlphaInfo LLVMBlackfinCodeGen LLVMBlackfinDesc LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUCodeGen LLVMCellSPUDesc LLVMCellSPUInfo LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmParser LLVMMBlazeCodeGen LLVMMBlazeDesc LLVMMBlazeDisassembler LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen LLVMMSP430Desc LLVMMSP430Info LLVMMipsCodeGen LLVMMipsDesc LLVMMipsInfo LLVMPTXCodeGen LLVMPTXDesc LLVMPTXInfo LLVMPowerPCCodeGen LLVMPowerPCDesc LLVMPowerPCInfo LLVMSparcCodeGen LLVMSparcDesc LLVMSparcInfo LLVMSupport LLVMSystemZCodeGen LLVMSystemZDesc LLVMSystemZInfo LLVMTarget LLVMX86AsmParser LLVMX86CodeGen LLVMX86Desc LLVMX86Disassembler LLVMX86Info LLVMXCoreCodeGen LLVMXCoreDesc LLVMXCoreInfo) -set(MSVC_LIB_DEPS_LLVMMCJIT LLVMCore LLVMExecutionEngine LLVMRuntimeDyld LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMMCParser LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMSP430CodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMSP430AsmPrinter LLVMMSP430Desc LLVMMSP430Info LLVMSelectionDAG LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMMSP430Desc LLVMMC LLVMMSP430Info) -set(MSVC_LIB_DEPS_LLVMMSP430Info LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMipsAsmPrinter LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMipsCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMipsAsmPrinter LLVMMipsDesc LLVMMipsInfo LLVMSelectionDAG LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMMipsDesc LLVMMC LLVMMipsInfo LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMipsInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMObject LLVMSupport) -set(MSVC_LIB_DEPS_LLVMPTXCodeGen LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPTXDesc LLVMPTXInfo LLVMSelectionDAG LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMPTXDesc LLVMMC LLVMPTXInfo LLVMSupport) -set(MSVC_LIB_DEPS_LLVMPTXInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMPowerPCAsmPrinter LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMPowerPCCodeGen LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPowerPCAsmPrinter LLVMPowerPCDesc LLVMPowerPCInfo LLVMSelectionDAG LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMPowerPCDesc LLVMMC LLVMPowerPCInfo LLVMSupport) -set(MSVC_LIB_DEPS_LLVMPowerPCInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMRuntimeDyld LLVMObject LLVMSupport) -set(MSVC_LIB_DEPS_LLVMScalarOpts LLVMAnalysis LLVMCore LLVMInstCombine LLVMSupport LLVMTarget LLVMTransformUtils) -set(MSVC_LIB_DEPS_LLVMSelectionDAG LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMTarget LLVMTransformUtils) -set(MSVC_LIB_DEPS_LLVMSparcCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSparcDesc LLVMSparcInfo LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMSparcDesc LLVMMC LLVMSparcInfo LLVMSupport) -set(MSVC_LIB_DEPS_LLVMSparcInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMSupport ) -set(MSVC_LIB_DEPS_LLVMSystemZCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystemZDesc LLVMSystemZInfo LLVMTarget) -set(MSVC_LIB_DEPS_LLVMSystemZDesc LLVMMC LLVMSystemZInfo) -set(MSVC_LIB_DEPS_LLVMSystemZInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMTarget LLVMCore LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMTransformUtils LLVMAnalysis LLVMCore LLVMSupport LLVMTarget LLVMipa) -set(MSVC_LIB_DEPS_LLVMX86AsmParser LLVMMC LLVMMCParser LLVMSupport LLVMTarget LLVMX86Info) -set(MSVC_LIB_DEPS_LLVMX86AsmPrinter LLVMMC LLVMSupport LLVMX86Utils) -set(MSVC_LIB_DEPS_LLVMX86CodeGen LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget LLVMX86AsmPrinter LLVMX86Desc LLVMX86Info LLVMX86Utils) -set(MSVC_LIB_DEPS_LLVMX86Desc LLVMMC LLVMSupport LLVMX86Info) -set(MSVC_LIB_DEPS_LLVMX86Disassembler LLVMMC LLVMSupport LLVMX86Info) -set(MSVC_LIB_DEPS_LLVMX86Info LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMX86Utils LLVMCore LLVMSupport) -set(MSVC_LIB_DEPS_LLVMXCoreCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget LLVMXCoreDesc LLVMXCoreInfo) -set(MSVC_LIB_DEPS_LLVMXCoreDesc LLVMMC LLVMXCoreInfo) -set(MSVC_LIB_DEPS_LLVMXCoreInfo LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMipa LLVMAnalysis LLVMCore LLVMSupport) -set(MSVC_LIB_DEPS_LLVMipo LLVMAnalysis LLVMCore LLVMScalarOpts LLVMSupport LLVMTarget LLVMTransformUtils LLVMipa) diff --git a/cmake/modules/TableGen.cmake b/cmake/modules/TableGen.cmake index 9d67137bb42a..3dc820b4abfa 100644 --- a/cmake/modules/TableGen.cmake +++ b/cmake/modules/TableGen.cmake @@ -2,7 +2,7 @@ # Extra parameters for `tblgen' may come after `ofn' parameter. # Adds the name of the generated file to TABLEGEN_OUTPUT. -macro(tablegen ofn) +macro(tablegen project ofn) file(GLOB local_tds "*.td") file(GLOB_RECURSE global_tds "${LLVM_MAIN_SRC_DIR}/include/llvm/*.td") @@ -14,14 +14,14 @@ macro(tablegen ofn) endif() add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp # Generate tablegen output in a temporary file. - COMMAND ${LLVM_TABLEGEN_EXE} ${ARGN} -I ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${${project}_TABLEGEN_EXE} ${ARGN} -I ${CMAKE_CURRENT_SOURCE_DIR} -I ${LLVM_MAIN_SRC_DIR}/lib/Target -I ${LLVM_MAIN_INCLUDE_DIR} ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} -o ${CMAKE_CURRENT_BINARY_DIR}/${ofn}.tmp # The file in LLVM_TARGET_DEFINITIONS may be not in the current # directory and local_tds may not contain it, so we must # explicitly list it here: - DEPENDS ${LLVM_TABLEGEN_EXE} ${local_tds} ${global_tds} + DEPENDS ${${project}_TABLEGEN_EXE} ${local_tds} ${global_tds} ${LLVM_TARGET_DEFINITIONS_ABSOLUTE} COMMENT "Building ${ofn}..." ) @@ -44,3 +44,82 @@ macro(tablegen ofn) set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${ofn} PROPERTIES GENERATED 1) endmacro(tablegen) + +function(add_public_tablegen_target target) + # Creates a target for publicly exporting tablegen dependencies. + if( TABLEGEN_OUTPUT ) + add_custom_target(${target} + DEPENDS ${TABLEGEN_OUTPUT}) + add_dependencies(${target} ${LLVM_COMMON_DEPENDS}) + endif( TABLEGEN_OUTPUT ) +endfunction() + +if(CMAKE_CROSSCOMPILING) + set(CX_NATIVE_TG_DIR "${CMAKE_BINARY_DIR}/native") + + add_custom_command(OUTPUT ${CX_NATIVE_TG_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${CX_NATIVE_TG_DIR} + COMMENT "Creating ${CX_NATIVE_TG_DIR}...") + + add_custom_command(OUTPUT ${CX_NATIVE_TG_DIR}/CMakeCache.txt + COMMAND ${CMAKE_COMMAND} -UMAKE_TOOLCHAIN_FILE -DCMAKE_BUILD_TYPE=Release + -DLLVM_BUILD_POLLY=OFF ${CMAKE_SOURCE_DIR} + WORKING_DIRECTORY ${CX_NATIVE_TG_DIR} + DEPENDS ${CX_NATIVE_TG_DIR} + COMMENT "Configuring native TableGen...") + + add_custom_target(ConfigureNativeTableGen DEPENDS ${CX_NATIVE_TG_DIR}/CMakeCache.txt) + + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${CX_NATIVE_TG_DIR}) +endif() + +macro(add_tablegen target project) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_TOOLS_BINARY_DIR}) + + add_llvm_utility(${target} ${ARGN}) + + set(${project}_TABLEGEN "${target}" CACHE + STRING "Native TableGen executable. Saves building one when cross-compiling.") + + # Upgrade existing LLVM_TABLEGEN setting. + if(${project} STREQUAL LLVM) + if(${LLVM_TABLEGEN} STREQUAL tblgen) + set(LLVM_TABLEGEN "${target}" CACHE + STRING "Native TableGen executable. Saves building one when cross-compiling." + FORCE) + endif() + endif() + + # Effective tblgen executable to be used: + set(${project}_TABLEGEN_EXE ${${project}_TABLEGEN} PARENT_SCOPE) + + if(CMAKE_CROSSCOMPILING) + if( ${${project}_TABLEGEN} STREQUAL "${target}" ) + set(${project}_TABLEGEN_EXE "${CX_NATIVE_TG_DIR}/bin/${target}") + set(${project}_TABLEGEN_EXE ${${project}_TABLEGEN_EXE} PARENT_SCOPE) + + add_custom_command(OUTPUT ${${project}_TABLEGEN_EXE} + COMMAND ${CMAKE_BUILD_TOOL} ${target} + DEPENDS ${CX_NATIVE_TG_DIR}/CMakeCache.txt + WORKING_DIRECTORY ${CX_NATIVE_TG_DIR} + COMMENT "Building native TableGen...") + add_custom_target(${project}NativeTableGen DEPENDS ${${project}_TABLEGEN_EXE}) + add_dependencies(${project}NativeTableGen ConfigureNativeTableGen) + + add_dependencies(${target} ${project}NativeTableGen) + endif() + endif() + + target_link_libraries(${target} LLVMSupport LLVMTableGen) + if( MINGW ) + target_link_libraries(${target} imagehlp psapi) + if(CMAKE_SIZEOF_VOID_P MATCHES "8") + set_target_properties(${target} PROPERTIES LINK_FLAGS -Wl,--stack,16777216) + endif(CMAKE_SIZEOF_VOID_P MATCHES "8") + endif( MINGW ) + if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD AND NOT BEOS ) + target_link_libraries(${target} pthread) + endif() + + install(TARGETS ${target} RUNTIME DESTINATION bin) +endmacro() diff --git a/configure b/configure index ae7fcd77a95c..fbd95ca78915 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.60 for llvm 3.0svn. +# Generated by GNU Autoconf 2.61 for llvm 3.0. # # Report bugs to . # @@ -14,7 +14,8 @@ ## M4sh Initialization. ## ## --------------------- ## -# Be Bourne compatible +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -23,10 +24,13 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + + # PATH needs CR @@ -219,7 +223,7 @@ test \$exitcode = 0) || { (exit 1); exit 1; } else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. @@ -237,7 +241,6 @@ IFS=$as_save_IFS # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF -# Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -246,10 +249,12 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + : _ASEOF @@ -257,7 +262,6 @@ _ASEOF CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF -# Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -266,10 +270,12 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + : (as_func_return () { @@ -516,19 +522,28 @@ else as_mkdir_p=false fi -# Find out whether ``test -x'' works. Don't use a zero-byte file, as -# systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - as_executable_p="test -x" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' else - as_executable_p=: + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' fi -rm -f conf$$.file +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -561,44 +576,44 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='llvm' PACKAGE_TARNAME='-llvm-' -PACKAGE_VERSION='3.0svn' -PACKAGE_STRING='llvm 3.0svn' +PACKAGE_VERSION='3.0' +PACKAGE_STRING='llvm 3.0' PACKAGE_BUGREPORT='llvmbugs@cs.uiuc.edu' ac_unique_file="lib/VMCore/Module.cpp" # Factoring default headers for most tests. ac_includes_default="\ #include -#if HAVE_SYS_TYPES_H +#ifdef HAVE_SYS_TYPES_H # include #endif -#if HAVE_SYS_STAT_H +#ifdef HAVE_SYS_STAT_H # include #endif -#if STDC_HEADERS +#ifdef STDC_HEADERS # include # include #else -# if HAVE_STDLIB_H +# ifdef HAVE_STDLIB_H # include # endif #endif -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif -#if HAVE_STRINGS_H +#ifdef HAVE_STRINGS_H # include #endif -#if HAVE_INTTYPES_H +#ifdef HAVE_INTTYPES_H # include #endif -#if HAVE_STDINT_H +#ifdef HAVE_STDINT_H # include #endif -#if HAVE_UNISTD_H +#ifdef HAVE_UNISTD_H # include #endif" @@ -640,6 +655,17 @@ build_alias host_alias target_alias LLVM_COPYRIGHT +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +CXX +CXXFLAGS +ac_ct_CXX +CPP subdirs ENABLE_POLLY LLVM_HAS_POLLY @@ -664,14 +690,6 @@ LLVM_ON_UNIX LLVM_ON_WIN32 ARCH ENDIAN -CC -CFLAGS -LDFLAGS -CPPFLAGS -ac_ct_CC -EXEEXT -OBJEXT -CPP GREP EGREP LLVM_CROSS_COMPILING @@ -702,16 +720,10 @@ LLVM_ENUM_ASM_PRINTERS LLVM_ENUM_ASM_PARSERS LLVM_ENUM_DISASSEMBLERS ENABLE_CBE_PRINTF_A -CLANGPATH -CLANGXXPATH -ENABLE_BUILT_CLANG OPTIMIZE_OPTION EXTRA_OPTIONS EXTRA_LD_OPTIONS BINUTILS_INCDIR -CXX -CXXFLAGS -ac_ct_CXX NM ifGNUmake LN_S @@ -763,11 +775,6 @@ INSTALL_LTDL_FALSE CONVENIENCE_LTDL_TRUE CONVENIENCE_LTDL_FALSE LIBADD_DL -LLVMGCCCOMMAND -LLVMGXXCOMMAND -LLVMGCC -LLVMGXX -LLVMCC_OPTION NO_VARIADIC_MACROS NO_MISSING_FIELD_INITIALIZERS USE_UDIS86 @@ -775,13 +782,6 @@ USE_OPROFILE HAVE_PTHREAD HUGE_VAL_SANITY MMAP_FILE -LLVMCC_EMITIR_FLAG -LLVMCC1 -LLVMCC1PLUS -LLVMGCCDIR -LLVMGCC_LANGS -LLVMGCC_DRAGONEGG -LLVMCC_DISABLEOPT_FLAGS SHLIBEXT SHLIBPATH_VAR LLVM_PREFIX @@ -809,11 +809,12 @@ target_alias CC CFLAGS LDFLAGS +LIBS CPPFLAGS -CPP CXX CXXFLAGS -CCC' +CCC +CPP' ac_subdirs_all='projects/llvm-gcc projects/test-suite projects/llvm-test @@ -932,10 +933,10 @@ do -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) @@ -951,10 +952,10 @@ do -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ @@ -1148,19 +1149,19 @@ do -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=no ;; --x) @@ -1329,7 +1330,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures llvm 3.0svn to adapt to many kinds of systems. +\`configure' configures llvm 3.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1395,7 +1396,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of llvm 3.0svn:";; + short | recursive ) echo "Configuration of llvm 3.0:";; esac cat <<\_ACEOF @@ -1403,10 +1404,10 @@ Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-polly Use polly if available (default is YES) - --enable-optimized Compile with optimizations enabled (default is NO) + --enable-optimized Compile with optimizations enabled (default is YES) --enable-profiling Compile with profiling enabled (default is NO) --enable-assertions Compile with assertion checks enabled (default is - YES) + NO) --enable-expensive-checks Compile with expensive debug checks enabled (default is NO) @@ -1424,7 +1425,7 @@ Optional Features: --enable-shared Build a shared library and link tools against it (default is NO) --enable-embed-stdcxx Build a shared library with embedded libstdc++ for - Win32 DLL (default is YES) + Win32 DLL (default is NO) --enable-timestamps Enable embedding timestamp information in build (default is YES) --enable-targets Build specific host targets: all or @@ -1442,16 +1443,6 @@ Optional Features: Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-llvmgccdir Specify location of llvm-gcc install dir (default - searches PATH) - --with-llvmgcc Specify location of llvm-gcc driver (default - searches PATH) - --with-llvmgxx Specify location of llvm-g++ driver (default - searches PATH) - --with-clang Specify location of clang compiler (default is - --with-built-clang) - --with-built-clang Use the compiled Clang as the LLVM compiler - (default=check) --with-optimize-option Select the compiler options to use for optimized builds --with-extra-options Specify additional options to compile LLVM with @@ -1471,9 +1462,9 @@ Optional Packages: 64 bit multilib directory. --with-binutils-include Specify path to binutils/include/ containing plugin-api.h file for gold plugin. + --with-bug-report-url Specify the URL where bug reports should be + submitted (default=http://llvm.org/bugs/) --with-tclinclude directory where tcl headers are - --with-llvmcc= Choose the LLVM capable compiler to use (llvm-gcc, - clang, or none; default=check) --with-udis86= Use udis86 external x86 disassembler library --with-oprofile= Tell OProfile >= 0.9.4 how to symbolize JIT output @@ -1483,11 +1474,12 @@ Some influential environment variables: CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory + LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory - CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags + CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1553,8 +1545,8 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -llvm configure 3.0svn -generated by GNU Autoconf 2.60 +llvm configure 3.0 +generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. @@ -1569,8 +1561,8 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by llvm $as_me 3.0svn, which was -generated by GNU Autoconf 2.60. Invocation command line was +It was created by llvm $as_me 3.0, which was +generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -1971,6 +1963,1324 @@ echo "$as_me: error: Already configured in ${srcdir}" >&2;} 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 +if test -n "$ac_tool_prefix"; then + for ac_prog in clang llvm-gcc gcc + 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_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # 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_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$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 +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in clang llvm-gcc gcc +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_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # 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_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$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_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + 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 + CC=$ac_ct_CC + fi +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C 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); } + +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 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +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_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (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 + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +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); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+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. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +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>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+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. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + 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); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; 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_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + 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 +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); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + 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 +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); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + 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 +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); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +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_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + 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); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +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 + +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 +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in clang++ llvm-g++ g++ + 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_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # 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_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$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 +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in clang++ llvm-g++ g++ +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_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + 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 + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C++ 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); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } +if test "${ac_cv_cxx_compiler_gnu+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. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + 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); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; 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_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + 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 +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); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + 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 +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); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + 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 +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); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +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_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + 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 + +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 +{ 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; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # 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 +#else +# include +#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 && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.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 +_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 && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.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_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # 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 +#else +# include +#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 && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.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 +_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 && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.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 \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +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 + + if test -d ${srcdir}/projects/llvm-gcc ; then @@ -2339,6 +3649,8 @@ else llvm_cv_target_os_type="Haiku" ;; *-*-rtems*) llvm_cv_target_os_type="RTEMS" ;; + *-*-nacl*) + llvm_cv_target_os_type="NativeClient" ;; *-unknown-eabi*) llvm_cv_target_os_type="Freestanding" ;; *) @@ -2431,1264 +3743,6 @@ esac ARCH=$llvm_cv_target_arch -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 -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; 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_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # 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_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; 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_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # 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_CC="gcc" - 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_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - 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 - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; 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_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # 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_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; 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_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -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 - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - 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_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # 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_CC="$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 -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -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_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # 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_CC="$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_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - 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 - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO: checking for C 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); } - -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 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -# -# List of possible output files, starting from the most likely. -# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) -# only as a last resort. b.out is created by i960 compilers. -ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' -# -# The IRIX 6 linker writes into existing files which may not be -# executable, retaining their permissions. Remove them first so a -# subsequent execution test works. -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { (ac_try="$ac_link_default" -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_default") 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi - -ac_exeext=$ac_cv_exeext -{ echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6; } - -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (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 - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -{ echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - -rm -f a.out a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } -{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6; } - -{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } -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); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest$ac_cv_exeext -{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } -if test "${ac_cv_objext+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. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -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>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } -if test "${ac_cv_c_compiler_gnu+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. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - 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_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_c_compiler_gnu=$ac_compiler_gnu - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - 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 -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_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CFLAGS="" - 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 -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 - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - 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 -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_prog_cc_g=yes -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_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 -echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - 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_prog_cc_c89=$ac_arg -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6; } ;; - xno) - { echo "$as_me:$LINENO: result: unsupported" >&5 -echo "${ECHO_T}unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; -esac - - -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 - - -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 -{ 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; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # 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 -#else -# include -#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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_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 -_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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_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_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # 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 -#else -# include -#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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_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 -_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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_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 \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -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 { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 @@ -3712,7 +3766,7 @@ do for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -3794,7 +3848,7 @@ do for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -3890,27 +3944,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 @@ -3938,7 +3975,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -3959,7 +3996,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | else ac_cv_header_stdc=no fi -rm -f conftest* +rm -f -r conftest* fi @@ -4086,27 +4123,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 @@ -4148,7 +4168,8 @@ cat >>conftest.$ac_ext <<_ACEOF int main () { -#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \ + && BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN) bogus endian macros #endif @@ -4169,27 +4190,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -4224,27 +4228,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 @@ -4295,27 +4282,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi @@ -4445,7 +4415,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_BUILD_CC="${ac_build_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4483,7 +4453,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_BUILD_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4522,7 +4492,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -4612,7 +4582,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_BUILD_CXX="${ac_build_prefix}g++" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4650,7 +4620,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_BUILD_CXX="g++" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4689,7 +4659,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/c++"; then ac_prog_rejected=yes continue @@ -4778,7 +4748,7 @@ fi if test "${enable_assertions+set}" = set; then enableval=$enable_assertions; else - enableval="yes" + enableval="no" fi if test ${enableval} = "yes" ; then @@ -4863,7 +4833,7 @@ else ;; ARM) TARGET_HAS_JIT=1 ;; - Mips) TARGET_HAS_JIT=0 + Mips) TARGET_HAS_JIT=1 ;; XCore) TARGET_HAS_JIT=0 ;; @@ -5018,7 +4988,7 @@ case "$enableval" in ;; no) ENABLE_EMBED_STDCXX=0 ;; - default) ENABLE_EMBED_STDCXX=1 + default) ENABLE_EMBED_STDCXX=0 ;; *) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-embed-stdcxx. Use \"yes\" or \"no\"" >&5 echo "$as_me: error: Invalid setting for --enable-embed-stdcxx. Use \"yes\" or \"no\"" >&2;} @@ -5120,7 +5090,7 @@ _ACEOF LLVM_NATIVE_TARGET="LLVMInitialize${LLVM_NATIVE_ARCH}Target" LLVM_NATIVE_TARGETINFO="LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo" - LLVM_NATIVE_MCASMINFO="LLVMInitialize${LLVM_NATIVE_ARCH}MCAsmInfo" + LLVM_NATIVE_TARGETMC="LLVMInitialize${LLVM_NATIVE_ARCH}TargetMC" LLVM_NATIVE_ASMPRINTER="LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter" if test -f ${srcdir}/lib/Target/${LLVM_NATIVE_ARCH}/AsmParser/Makefile ; then LLVM_NATIVE_ASMPARSER="LLVMInitialize${LLVM_NATIVE_ARCH}AsmParser" @@ -5137,7 +5107,7 @@ _ACEOF cat >>confdefs.h <<_ACEOF -#define LLVM_NATIVE_MCASMINFO $LLVM_NATIVE_MCASMINFO +#define LLVM_NATIVE_TARGETMC $LLVM_NATIVE_TARGETMC _ACEOF @@ -5203,121 +5173,6 @@ _ACEOF -# Check whether --with-llvmgccdir was given. -if test "${with_llvmgccdir+set}" = set; then - withval=$with_llvmgccdir; -else - withval=default -fi - -case "$withval" in - default) WITH_LLVMGCCDIR=default ;; - /* | [A-Za-z]:[\\/]*) WITH_LLVMGCCDIR=$withval ;; - *) { { echo "$as_me:$LINENO: error: Invalid path for --with-llvmgccdir. Provide full path" >&5 -echo "$as_me: error: Invalid path for --with-llvmgccdir. Provide full path" >&2;} - { (exit 1); exit 1; }; } ;; -esac - - -# Check whether --with-llvmgcc was given. -if test "${with_llvmgcc+set}" = set; then - withval=$with_llvmgcc; LLVMGCC=$with_llvmgcc - WITH_LLVMGCCDIR="" -fi - - - -# Check whether --with-llvmgxx was given. -if test "${with_llvmgxx+set}" = set; then - withval=$with_llvmgxx; LLVMGXX=$with_llvmgxx - WITH_LLVMGCCDIR="" -fi - - -if test -n "$LLVMGCC"; then - LLVMGCCCOMMAND="$LLVMGCC" -fi - -if test -n "$LLVMGXX"; then - LLVMGXXCOMMAND="$LLVMGXX" -fi - -if test -n "$LLVMGCC" && test -z "$LLVMGXX"; then - { { echo "$as_me:$LINENO: error: Invalid llvm-g++. Use --with-llvmgxx when --with-llvmgcc is used" >&5 -echo "$as_me: error: Invalid llvm-g++. Use --with-llvmgxx when --with-llvmgcc is used" >&2;} - { (exit 1); exit 1; }; }; -fi - -if test -n "$LLVMGXX" && test -z "$LLVMGCC"; then - { { echo "$as_me:$LINENO: error: Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is used" >&5 -echo "$as_me: error: Invalid llvm-gcc. Use --with-llvmgcc when --with-llvmgxx is used" >&2;} - { (exit 1); exit 1; }; }; -fi - - -# Check whether --with-clang was given. -if test "${with_clang+set}" = set; then - withval=$with_clang; -else - with_clang=default -fi - - - -# Check whether --with-built-clang was given. -if test "${with_built_clang+set}" = set; then - withval=$with_built_clang; -else - with_built_clang=check -fi - - -{ echo "$as_me:$LINENO: checking clang compiler" >&5 -echo $ECHO_N "checking clang compiler... $ECHO_C" >&6; } -WITH_CLANGPATH="" -WITH_BUILT_CLANG=0 -if test "$with_clang" != "default"; then - WITH_CLANGPATH="$with_clang" - if ! test -x "$WITH_CLANGPATH"; then - { { echo "$as_me:$LINENO: error: invalid --with-clang, path does not specify an executable" >&5 -echo "$as_me: error: invalid --with-clang, path does not specify an executable" >&2;} - { (exit 1); exit 1; }; } - fi -elif test "$with_built_clang" = "yes"; then - WITH_BUILT_CLANG=1 -elif test "$with_built_clang" = "no"; then - WITH_BUILT_CLANG=0 -else - if test "$with_built_clang" != "check"; then - { { echo "$as_me:$LINENO: error: invalid value for --with-built-clang." >&5 -echo "$as_me: error: invalid value for --with-built-clang." >&2;} - { (exit 1); exit 1; }; } - fi - - if test -f ${srcdir}/tools/clang/README.txt; then - WITH_BUILT_CLANG=1 - fi -fi - -if ! test -z "$WITH_CLANGPATH"; then - { echo "$as_me:$LINENO: result: $WITH_CLANGPATH" >&5 -echo "${ECHO_T}$WITH_CLANGPATH" >&6; } - WITH_CLANGXXPATH=`"$WITH_CLANGPATH" --print-prog-name=clang++` -elif test "$WITH_BUILT_CLANG" = "1"; then - { echo "$as_me:$LINENO: result: built" >&5 -echo "${ECHO_T}built" >&6; } -else - { echo "$as_me:$LINENO: result: none" >&5 -echo "${ECHO_T}none" >&6; } -fi -CLANGPATH=$WITH_CLANGPATH - -CLANGXXPATH=$WITH_CLANGXXPATH - -ENABLE_BUILT_CLANG=$WITH_BUILT_CLANG - - - # Check whether --with-optimize-option was given. if test "${with_optimize_option+set}" = set; then withval=$with_optimize_option; @@ -5520,6 +5375,20 @@ echo "$as_me: error: Invalid path to directory containing plugin-api.h." >&2;} fi fi + +# Check whether --with-bug-report-url was given. +if test "${with_bug_report_url+set}" = set; then + withval=$with_bug_report_url; +else + withval="http://llvm.org/bugs/" +fi + + +cat >>confdefs.h <<_ACEOF +#define BUG_REPORT_URL "$withval" +_ACEOF + + # Check whether --enable-libffi was given. if test "${enable_libffi+set}" = set; then enableval=$enable_libffi; case "$enableval" in @@ -5535,1262 +5404,6 @@ 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 -{ 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; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # 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 -#else -# include -#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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_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 -_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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_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_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # 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 -#else -# include -#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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_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 -_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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_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 \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -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 - -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 -if test -n "$ac_tool_prefix"; then - for ac_prog in gcc - 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_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # 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_CC="$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 -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in gcc -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_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # 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_CC="$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_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - 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 - CC=$ac_ct_CC - fi -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO: checking for C 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); } - -{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } -if test "${ac_cv_c_compiler_gnu+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. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - 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_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_c_compiler_gnu=$ac_compiler_gnu - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - 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 -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_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CFLAGS="" - 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 -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 - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - 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 -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_prog_cc_g=yes -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_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 -echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - 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_prog_cc_c89=$ac_arg -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6; } ;; - xno) - { echo "$as_me:$LINENO: result: unsupported" >&5 -echo "${ECHO_T}unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; -esac - - -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 - -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 -if test -z "$CXX"; then - if test -n "$CCC"; then - CXX=$CCC - else - if test -n "$ac_tool_prefix"; then - for ac_prog in g++ - 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_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # 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_CXX="$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 -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - { echo "$as_me:$LINENO: result: $CXX" >&5 -echo "${ECHO_T}$CXX" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in g++ -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_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 -echo "${ECHO_T}$ac_ct_CXX" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - test -n "$ac_ct_CXX" && break -done - - if test "x$ac_ct_CXX" = x; then - CXX="g++" - 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 - CXX=$ac_ct_CXX - fi -fi - - fi -fi -# Provide some information about the compiler. -echo "$as_me:$LINENO: checking for C++ 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); } - -{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } -if test "${ac_cv_cxx_compiler_gnu+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. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - 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_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_cxx_compiler_gnu=$ac_compiler_gnu - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } -GXX=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CXXFLAGS=${CXXFLAGS+set} -ac_save_CXXFLAGS=$CXXFLAGS -{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 -echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } -if test "${ac_cv_prog_cxx_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_save_cxx_werror_flag=$ac_cxx_werror_flag - ac_cxx_werror_flag=yes - ac_cv_prog_cxx_g=no - CXXFLAGS="-g" - 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 -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_prog_cxx_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - CXXFLAGS="" - 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 -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 - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g" - 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 -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_prog_cxx_g=yes -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_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cxx_werror_flag=$ac_save_cxx_werror_flag -fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6; } -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - 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 - - { echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5 echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6; } if test "${lt_cv_path_NM+set}" = set; then @@ -6901,7 +5514,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CMP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6942,7 +5555,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6983,7 +5596,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DATE="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7024,7 +5637,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_FIND="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7065,7 +5678,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7106,7 +5719,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MKDIR="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7147,7 +5760,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MV="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7187,7 +5800,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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 @@ -7227,7 +5840,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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 @@ -7283,7 +5896,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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 @@ -7323,7 +5936,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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 @@ -7380,7 +5993,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7421,7 +6034,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7462,7 +6075,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TAR="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7503,7 +6116,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_BINPWD="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7545,7 +6158,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GRAPHVIZ="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7601,7 +6214,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DOT="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7657,7 +6270,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_FDP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7713,7 +6326,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_NEATO="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7769,7 +6382,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TWOPI="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7825,7 +6438,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CIRCO="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7883,7 +6496,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GV="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7942,7 +6555,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DOTTY="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7998,7 +6611,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_XDOT_PY="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8056,7 +6669,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8140,7 +6753,7 @@ case $as_dir/ in # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. @@ -8207,7 +6820,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_BZIP2="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8247,7 +6860,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CAT="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8287,7 +6900,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8327,7 +6940,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GROFF="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8367,7 +6980,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GZIPBIN="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8407,7 +7020,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_POD2HTML="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8447,7 +7060,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_POD2MAN="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8487,7 +7100,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PDFROFF="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8527,7 +7140,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_RUNTEST="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8602,7 +7215,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TCLSH="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8657,7 +7270,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ZIP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8699,7 +7312,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OCAMLC="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8744,7 +7357,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OCAMLOPT="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8789,7 +7402,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OCAMLDEP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8834,7 +7447,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OCAMLDOC="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8879,7 +7492,7 @@ 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 + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GAS="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -8971,27 +7584,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then llvm_cv_link_use_r=yes else echo "$as_me: failed program was:" >&5 @@ -9000,7 +7597,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 llvm_cv_link_use_r=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$oldcflags" ac_ext=c @@ -9063,27 +7660,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then llvm_cv_link_use_export_dynamic=yes else echo "$as_me: failed program was:" >&5 @@ -9092,7 +7673,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 llvm_cv_link_use_export_dynamic=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$oldcflags" ac_ext=c @@ -9177,27 +7758,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then llvm_cv_link_use_version_script=yes else echo "$as_me: failed program was:" >&5 @@ -9206,7 +7771,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 llvm_cv_link_use_version_script=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext rm "$tmp/export.map" rmdir "$tmp" @@ -9248,10 +7813,10 @@ main () #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; - const charset x; + const charset cs; /* SunOS 4.1.1 cc rejects this. */ - char const *const *ccp; - char **p; + char const *const *pcpcc; + char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; @@ -9260,11 +7825,11 @@ main () an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; - ccp = &g + (g ? g-g : 0); + pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ - ++ccp; - p = (char**) ccp; - ccp = (char const *const *) p; + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; @@ -9291,7 +7856,7 @@ main () const int foo = 10; if (!foo) return 0; } - return !x[0] && !zero.x; + return !cs[0] && !zero.x; #endif ; @@ -9311,27 +7876,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 @@ -9396,27 +7944,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 @@ -9489,27 +8020,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 @@ -9518,7 +8033,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break @@ -9589,27 +8104,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 @@ -9618,7 +8117,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break @@ -9681,27 +8180,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -9737,17 +8219,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -9817,9 +8292,7 @@ if test "${enable_ltdl_install+set}" = set; then fi - - -if test x"${enable_ltdl_install-no}" != xno; then + if test x"${enable_ltdl_install-no}" != xno; then INSTALL_LTDL_TRUE= INSTALL_LTDL_FALSE='#' else @@ -9827,9 +8300,7 @@ else INSTALL_LTDL_FALSE= fi - - -if test x"${enable_ltdl_convenience-no}" != xno; then + if test x"${enable_ltdl_convenience-no}" != xno; then CONVENIENCE_LTDL_TRUE= CONVENIENCE_LTDL_FALSE='#' else @@ -10841,27 +9312,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_func_shl_load=yes else echo "$as_me: failed program was:" >&5 @@ -10870,7 +9325,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 @@ -10924,27 +9379,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 @@ -10953,7 +9392,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -11009,27 +9448,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -11038,7 +9461,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -11083,27 +9506,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then cat >>confdefs.h <<\_ACEOF #define HAVE_LIBDL 1 @@ -11155,27 +9562,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_svld_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -11184,7 +9575,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_svld_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -11240,27 +9631,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_dld_dld_link=yes else echo "$as_me: failed program was:" >&5 @@ -11269,7 +9644,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_dld_link=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -11346,27 +9721,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_func__dyld_func_lookup=yes else echo "$as_me: failed program was:" >&5 @@ -11375,7 +9734,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func__dyld_func_lookup=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func__dyld_func_lookup" >&5 @@ -11397,7 +9756,7 @@ fi fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi @@ -11480,27 +9839,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -11509,7 +9852,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -11596,7 +9939,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -11881,17 +10207,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -11996,27 +10315,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_error_t=yes else echo "$as_me: failed program was:" >&5 @@ -12116,27 +10418,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -12145,7 +10431,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -12225,27 +10511,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -12281,17 +10550,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -12397,27 +10659,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -12453,17 +10698,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -12567,27 +10805,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -12623,17 +10844,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -12766,27 +10980,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -12795,7 +10993,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -12877,27 +11075,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -12906,7 +11088,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -12988,27 +11170,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -13017,7 +11183,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -13099,27 +11265,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -13128,7 +11278,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -13211,27 +11361,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -13240,7 +11374,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -13256,146 +11390,6 @@ done -if test "$WITH_LLVMGCCDIR" = "default" ; then - LLVMGCC="llvm-gcc${EXEEXT}" - LLVMGXX="llvm-g++${EXEEXT}" - LLVMGCCCOMMAND="$LLVMGCC" - LLVMGXXCOMMAND="$LLVMGXX" - LLVMGCCCOMMAND=$LLVMGCCCOMMAND - - LLVMGXXCOMMAND=$LLVMGXXCOMMAND - - # Extract the first word of "$LLVMGCC", so it can be a program name with args. -set dummy $LLVMGCC; 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_path_LLVMGCC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $LLVMGCC in - [\\/]* | ?:[\\/]*) - ac_cv_path_LLVMGCC="$LLVMGCC" # Let the user override the test with a path. - ;; - *) - 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_path_LLVMGCC="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - ;; -esac -fi -LLVMGCC=$ac_cv_path_LLVMGCC -if test -n "$LLVMGCC"; then - { echo "$as_me:$LINENO: result: $LLVMGCC" >&5 -echo "${ECHO_T}$LLVMGCC" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - - # Extract the first word of "$LLVMGXX", so it can be a program name with args. -set dummy $LLVMGXX; 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_path_LLVMGXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $LLVMGXX in - [\\/]* | ?:[\\/]*) - ac_cv_path_LLVMGXX="$LLVMGXX" # Let the user override the test with a path. - ;; - *) - 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_path_LLVMGXX="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done -IFS=$as_save_IFS - - ;; -esac -fi -LLVMGXX=$ac_cv_path_LLVMGXX -if test -n "$LLVMGXX"; then - { echo "$as_me:$LINENO: result: $LLVMGXX" >&5 -echo "${ECHO_T}$LLVMGXX" >&6; } -else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - - -else - if test -z "$LLVMGCC"; then - LLVMGCC="$WITH_LLVMGCCDIR/bin/llvm-gcc${EXEEXT}" - LLVMGCCCOMMAND="$LLVMGCC" - fi - if test -z "$LLVMGXX"; then - LLVMGXX="$WITH_LLVMGCCDIR/bin/llvm-g++${EXEEXT}" - LLVMGXXCOMMAND="$LLVMGXX" - fi - - LLVMGCC=$LLVMGCC - - LLVMGXX=$LLVMGXX - - LLVMGCCCOMMAND=$LLVMGCCCOMMAND - - LLVMGXXCOMMAND=$LLVMGXXCOMMAND - -fi - - -# Check whether --with-llvmcc was given. -if test "${with_llvmcc+set}" = set; then - withval=$with_llvmcc; -else - with_llvmcc=check -fi - -{ echo "$as_me:$LINENO: checking LLVM capable compiler" >&5 -echo $ECHO_N "checking LLVM capable compiler... $ECHO_C" >&6; } -if test "$with_llvmcc" != "check"; then - if (test "$with_llvmcc" != "llvm-gcc" && - test "$with_llvmcc" != "clang" && - test "$with_llvmcc" != "none"); then - { { echo "$as_me:$LINENO: error: invalid value for --with-llvmcc, expected 'llvm-gcc', 'clang', or 'none'." >&5 -echo "$as_me: error: invalid value for --with-llvmcc, expected 'llvm-gcc', 'clang', or 'none'." >&2;} - { (exit 1); exit 1; }; } - fi - WITH_LLVMCC="$with_llvmcc" -elif test -n "$LLVMGCC"; then - WITH_LLVMCC=llvm-gcc -elif test -n "$WITH_CLANGPATH" || test "$WITH_BUILT_CLANG" -ne "0"; then - WITH_LLVMCC=clang -else - WITH_LLVMCC=none -fi -{ echo "$as_me:$LINENO: result: $WITH_LLVMCC" >&5 -echo "${ECHO_T}$WITH_LLVMCC" >&6; } -LLVMCC_OPTION=$WITH_LLVMCC - - { echo "$as_me:$LINENO: checking tool compatibility" >&5 echo $ECHO_N "checking tool compatibility... $ECHO_C" >&6; } @@ -13445,27 +11439,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 @@ -13542,27 +11519,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_m_sin=yes else echo "$as_me: failed program was:" >&5 @@ -13571,7 +11532,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_m_sin=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -13624,27 +11585,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_imagehlp_main=yes else echo "$as_me: failed program was:" >&5 @@ -13653,7 +11598,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_imagehlp_main=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -13705,27 +11650,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_psapi_main=yes else echo "$as_me: failed program was:" >&5 @@ -13734,7 +11663,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_psapi_main=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -13799,27 +11728,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_dlopen=$ac_res else echo "$as_me: failed program was:" >&5 @@ -13828,7 +11741,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_dlopen+set}" = set; then break @@ -13907,27 +11820,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_ffi_call=$ac_res else echo "$as_me: failed program was:" >&5 @@ -13936,7 +11833,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_ffi_call+set}" = set; then break @@ -14016,27 +11913,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_mallinfo=$ac_res else echo "$as_me: failed program was:" >&5 @@ -14045,7 +11926,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_mallinfo+set}" = set; then break @@ -14116,27 +11997,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_pthread_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 @@ -14145,7 +12010,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_mutex_init=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -14208,27 +12073,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_pthread_mutex_lock=$ac_res else echo "$as_me: failed program was:" >&5 @@ -14237,7 +12086,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_pthread_mutex_lock+set}" = set; then break @@ -14311,27 +12160,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_pthread_rwlock_init=$ac_res else echo "$as_me: failed program was:" >&5 @@ -14340,7 +12173,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_pthread_rwlock_init+set}" = set; then break @@ -14414,27 +12247,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_pthread_getspecific=$ac_res else echo "$as_me: failed program was:" >&5 @@ -14443,7 +12260,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_pthread_getspecific+set}" = set; then break @@ -14524,27 +12341,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_udis86_ud_init=yes else echo "$as_me: failed program was:" >&5 @@ -14553,7 +12354,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_udis86_ud_init=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -14649,27 +12450,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_bfd_init=$ac_res else echo "$as_me: failed program was:" >&5 @@ -14678,7 +12463,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_bfd_init+set}" = set; then break @@ -14748,27 +12533,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_op_open_agent=$ac_res else echo "$as_me: failed program was:" >&5 @@ -14777,7 +12546,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_op_open_agent+set}" = set; then break @@ -14838,27 +12607,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -14894,17 +12646,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -15028,27 +12773,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 @@ -15121,27 +12849,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 @@ -15150,7 +12862,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break @@ -15221,27 +12933,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 @@ -15250,7 +12946,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break @@ -15315,27 +13011,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_mmap_anon=yes else echo "$as_me: failed program was:" >&5 @@ -15378,72 +13057,21 @@ cat >>conftest.$ac_ext <<_ACEOF #include #if defined S_ISBLK && defined S_IFDIR -# if S_ISBLK (S_IFDIR) -You lose. -# endif +extern char c1[S_ISBLK (S_IFDIR) ? -1 : 1]; #endif #if defined S_ISBLK && defined S_IFCHR -# if S_ISBLK (S_IFCHR) -You lose. -# endif +extern char c2[S_ISBLK (S_IFCHR) ? -1 : 1]; #endif #if defined S_ISLNK && defined S_IFREG -# if S_ISLNK (S_IFREG) -You lose. -# endif +extern char c3[S_ISLNK (S_IFREG) ? -1 : 1]; #endif #if defined S_ISSOCK && defined S_IFREG -# if S_ISSOCK (S_IFREG) -You lose. -# endif +extern char c4[S_ISSOCK (S_IFREG) ? -1 : 1]; #endif -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "You lose" >/dev/null 2>&1; then - ac_cv_header_stat_broken=yes -else - ac_cv_header_stat_broken=no -fi -rm -f conftest* - -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_stat_broken" >&5 -echo "${ECHO_T}$ac_cv_header_stat_broken" >&6; } -if test $ac_cv_header_stat_broken = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STAT_MACROS_BROKEN 1 -_ACEOF - -fi - -{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } -if test "${ac_cv_header_stdc+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 -#include -#include -#include - -int -main () -{ - - ; - return 0; -} _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" @@ -15458,156 +13086,26 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_header_stdc=yes + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stat_broken=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_cv_header_stdc=no + ac_cv_header_stat_broken=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 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 - : -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_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - -fi -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then +{ echo "$as_me:$LINENO: result: $ac_cv_header_stat_broken" >&5 +echo "${ECHO_T}$ac_cv_header_stat_broken" >&6; } +if test $ac_cv_header_stat_broken = yes; then cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 +#define STAT_MACROS_BROKEN 1 _ACEOF fi @@ -15655,27 +13153,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_sys_wait_h=yes else echo "$as_me: failed program was:" >&5 @@ -15733,27 +13214,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_header_time=yes else echo "$as_me: failed program was:" >&5 @@ -15819,27 +13283,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -15875,17 +13322,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -15993,27 +13433,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -16049,17 +13472,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -16163,27 +13579,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -16219,17 +13618,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -16336,27 +13728,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -16392,17 +13767,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -16508,27 +13876,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -16564,17 +13915,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -16677,27 +14021,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -16733,17 +14060,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -16846,27 +14166,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -16902,17 +14205,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -17016,27 +14312,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -17072,17 +14351,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -17196,27 +14468,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -17252,17 +14507,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -17367,27 +14615,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -17423,17 +14654,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -17526,27 +14750,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } @@ -17567,7 +14775,7 @@ _ACEOF fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext @@ -17689,27 +14897,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_pid_t=yes else echo "$as_me: failed program was:" >&5 @@ -17769,27 +14960,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 @@ -17834,7 +15008,9 @@ cat >>conftest.$ac_ext <<_ACEOF int main () { -struct tm *tp; tp->tm_sec; +struct tm tm; + int *p = &tm.tm_sec; + return !p; ; return 0; } @@ -17852,27 +15028,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_struct_tm=time.h else echo "$as_me: failed program was:" >&5 @@ -17930,27 +15089,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_int64_t=yes else echo "$as_me: failed program was:" >&5 @@ -18013,27 +15155,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_uint64_t=yes else echo "$as_me: failed program was:" >&5 @@ -18091,27 +15216,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_type_u_int64_t=yes else echo "$as_me: failed program was:" >&5 @@ -18214,27 +15322,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -18243,7 +15335,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -18327,27 +15419,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -18356,7 +15432,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -18441,27 +15517,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -18470,7 +15530,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -18553,27 +15613,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -18582,7 +15626,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -18668,27 +15712,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -18697,7 +15725,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -18780,27 +15808,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -18809,7 +15821,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -18893,27 +15905,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -18922,7 +15918,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -19007,27 +16003,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -19036,7 +16016,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -19184,27 +16164,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_rand48=yes else echo "$as_me: failed program was:" >&5 @@ -19249,8 +16212,7 @@ int main () { #ifndef strerror_s - char *p = (char *) strerror_s; - return !p; + (void) strerror_s; #endif ; @@ -19270,27 +16232,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_have_decl_strerror_s=yes else echo "$as_me: failed program was:" >&5 @@ -19363,27 +16308,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc__alloca=yes else echo "$as_me: failed program was:" >&5 @@ -19392,7 +16321,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc__alloca=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -19448,27 +16377,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___alloca=yes else echo "$as_me: failed program was:" >&5 @@ -19477,7 +16390,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___alloca=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -19533,27 +16446,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___chkstk=yes else echo "$as_me: failed program was:" >&5 @@ -19562,7 +16459,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___chkstk=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -19618,27 +16515,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc____chkstk=yes else echo "$as_me: failed program was:" >&5 @@ -19647,7 +16528,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc____chkstk=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -19704,27 +16585,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___ashldi3=yes else echo "$as_me: failed program was:" >&5 @@ -19733,7 +16598,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___ashldi3=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -19789,27 +16654,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___ashrdi3=yes else echo "$as_me: failed program was:" >&5 @@ -19818,7 +16667,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___ashrdi3=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -19874,27 +16723,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___divdi3=yes else echo "$as_me: failed program was:" >&5 @@ -19903,7 +16736,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___divdi3=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -19959,27 +16792,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___fixdfdi=yes else echo "$as_me: failed program was:" >&5 @@ -19988,7 +16805,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___fixdfdi=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -20044,27 +16861,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___fixsfdi=yes else echo "$as_me: failed program was:" >&5 @@ -20073,7 +16874,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___fixsfdi=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -20129,27 +16930,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___floatdidf=yes else echo "$as_me: failed program was:" >&5 @@ -20158,7 +16943,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___floatdidf=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -20214,27 +16999,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___lshrdi3=yes else echo "$as_me: failed program was:" >&5 @@ -20243,7 +17012,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___lshrdi3=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -20299,27 +17068,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___moddi3=yes else echo "$as_me: failed program was:" >&5 @@ -20328,7 +17081,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___moddi3=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -20384,27 +17137,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___udivdi3=yes else echo "$as_me: failed program was:" >&5 @@ -20413,7 +17150,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___udivdi3=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -20469,27 +17206,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___umoddi3=yes else echo "$as_me: failed program was:" >&5 @@ -20498,7 +17219,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___umoddi3=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -20555,27 +17276,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___main=yes else echo "$as_me: failed program was:" >&5 @@ -20584,7 +17289,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___main=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -20640,27 +17345,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_cv_lib_gcc___cmpdi2=yes else echo "$as_me: failed program was:" >&5 @@ -20669,7 +17358,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gcc___cmpdi2=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -20707,27 +17396,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } @@ -20792,27 +17464,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_isnan_in_math_h=yes else echo "$as_me: failed program was:" >&5 @@ -20880,27 +17535,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_isnan_in_cmath=yes else echo "$as_me: failed program was:" >&5 @@ -20967,27 +17605,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_std_isnan_in_cmath=yes else echo "$as_me: failed program was:" >&5 @@ -21055,27 +17676,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_isinf_in_math_h=yes else echo "$as_me: failed program was:" >&5 @@ -21142,27 +17746,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_isinf_in_cmath=yes else echo "$as_me: failed program was:" >&5 @@ -21229,27 +17816,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_std_isinf_in_cmath=yes else echo "$as_me: failed program was:" >&5 @@ -21316,27 +17886,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_cv_func_finite_in_ieeefp_h=yes else echo "$as_me: failed program was:" >&5 @@ -21407,27 +17960,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -21463,17 +17999,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -21604,27 +18133,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -21633,7 +18146,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -21690,21 +18203,21 @@ $ac_includes_default #include #include -#if !STDC_HEADERS && !HAVE_STDLIB_H +#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H char *malloc (); #endif /* This mess was copied from the GNU getpagesize.h. */ -#if !HAVE_GETPAGESIZE +#ifndef HAVE_GETPAGESIZE /* Assume that all systems that can run configure have sys/param.h. */ -# if !HAVE_SYS_PARAM_H +# ifndef HAVE_SYS_PARAM_H # define HAVE_SYS_PARAM_H 1 # endif # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ -# if HAVE_SYS_PARAM_H +# ifdef HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE @@ -21996,27 +18509,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -22027,7 +18524,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu echo "${ECHO_T}yes" >&6; } cat >>confdefs.h <<\_ACEOF -#define LLVM_MULTITHREADED 1 +#define LLVM_HAS_ATOMICS 1 _ACEOF else @@ -22038,14 +18535,14 @@ sed 's/^/| /' conftest.$ac_ext >&5 echo "${ECHO_T}no" >&6; } cat >>confdefs.h <<\_ACEOF -#define LLVM_MULTITHREADED 0 +#define LLVM_HAS_ATOMICS 0 _ACEOF { echo "$as_me:$LINENO: WARNING: LLVM will be built thread-unsafe because atomic builtins are missing" >&5 echo "$as_me: WARNING: LLVM will be built thread-unsafe because atomic builtins are missing" >&2;} fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext @@ -22092,27 +18589,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then llvm_cv_linux_mixed=no else echo "$as_me: failed program was:" >&5 @@ -22206,27 +18686,11 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -22235,7 +18699,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -22250,75 +18714,6 @@ fi done -{ echo "$as_me:$LINENO: checking whether llvm-gcc is dragonegg" >&5 -echo $ECHO_N "checking whether llvm-gcc is dragonegg... $ECHO_C" >&6; } -if test "${llvm_cv_llvmgcc_dragonegg+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - llvm_cv_llvmgcc_dragonegg="no" -if test -n "$LLVMGCC" ; then - cp /dev/null conftest.c - $LLVMGCC -fplugin-arg-dragonegg-emit-ir -S -o - conftest.c > /dev/null 2>&1 - if test $? -eq 0 ; then - llvm_cv_llvmgcc_dragonegg="yes" - fi - rm conftest.c -fi -fi -{ echo "$as_me:$LINENO: result: $llvm_cv_llvmgcc_dragonegg" >&5 -echo "${ECHO_T}$llvm_cv_llvmgcc_dragonegg" >&6; } - -if test "$llvm_cv_llvmgcc_dragonegg" = "yes" ; then - LLVMCC_EMITIR_FLAG="-fplugin-arg-dragonegg-emit-ir" - LLVMCC_DISABLEOPT_FLAGS="-fplugin-arg-dragonegg-llvm-ir-optimize=0" -else - LLVMCC_EMITIR_FLAG="-emit-llvm" - LLVMCC_DISABLEOPT_FLAGS="-mllvm -disable-llvm-optzns" -fi - - - -{ echo "$as_me:$LINENO: checking whether llvm-gcc is sane" >&5 -echo $ECHO_N "checking whether llvm-gcc is sane... $ECHO_C" >&6; } -if test "${llvm_cv_llvmgcc_sanity+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - llvm_cv_llvmgcc_sanity="no" -if test -n "$LLVMGCC" ; then - cp /dev/null conftest.c - $LLVMGCC "$LLVMCC_EMITIR_FLAG" -S -o - conftest.c | \ - grep 'target datalayout =' > /dev/null 2>&1 - if test $? -eq 0 ; then - llvm_cv_llvmgcc_sanity="yes" - fi - rm conftest.c -fi -fi -{ echo "$as_me:$LINENO: result: $llvm_cv_llvmgcc_sanity" >&5 -echo "${ECHO_T}$llvm_cv_llvmgcc_sanity" >&6; } - -if test "$llvm_cv_llvmgcc_sanity" = "yes" ; then - { echo "$as_me:$LINENO: checking llvm-gcc component support" >&5 -echo $ECHO_N "checking llvm-gcc component support... $ECHO_C" >&6; } - llvmcc1path=`$LLVMGCC --print-prog-name=cc1` - LLVMCC1=$llvmcc1path - - llvmcc1pluspath=`$LLVMGCC --print-prog-name=cc1plus` - LLVMCC1PLUS=$llvmcc1pluspath - - llvmgccdir=`echo "$llvmcc1path" | sed 's,/libexec/.*,,'` - LLVMGCCDIR=$llvmgccdir - - llvmgcclangs=`$LLVMGCC -v --help 2>&1 | grep '^Configured with:' | sed 's/^.*--enable-languages=\([^ ]*\).*/\1/'` - LLVMGCC_LANGS=$llvmgcclangs - - LLVMGCC_DRAGONEGG=$llvm_cv_llvmgcc_dragonegg - - - { echo "$as_me:$LINENO: result: ok" >&5 -echo "${ECHO_T}ok" >&6; } -fi - SHLIBEXT=$libltdl_cv_shlibext @@ -22510,27 +18905,10 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 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 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then llvm_cv_cxx_visibility_inlines_hidden=yes else echo "$as_me: failed program was:" >&5 @@ -22606,12 +18984,12 @@ if test -f ${srcdir}/tools/clang/README.txt; then fi -ac_config_files="$ac_config_files tools/llvmc/src/Base.td" - - ac_config_files="$ac_config_files tools/llvm-config/llvm-config.in" +ac_config_files="$ac_config_files bindings/ocaml/llvm/META.llvm" + + ac_config_commands="$ac_config_commands setup" ac_config_commands="$ac_config_commands Makefile" @@ -22788,7 +19166,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF ## M4sh Initialization. ## ## --------------------- ## -# Be Bourne compatible +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -22797,10 +19176,13 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh + + # PATH needs CR @@ -23024,19 +19406,28 @@ else as_mkdir_p=false fi -# Find out whether ``test -x'' works. Don't use a zero-byte file, as -# systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - as_executable_p="test -x" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' else - as_executable_p=: + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' fi -rm -f conf$$.file +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -23051,8 +19442,8 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by llvm $as_me 3.0svn, which was -generated by GNU Autoconf 2.60. Invocation command line was +This file was extended by llvm $as_me 3.0, which was +generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -23081,7 +19472,7 @@ current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit - -V, --version print version number, then exit + -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions @@ -23104,8 +19495,8 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -llvm config.status 3.0svn -configured by $0, generated by GNU Autoconf 2.60, +llvm config.status 3.0 +configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. @@ -23228,8 +19619,8 @@ do "llvm.spec") CONFIG_FILES="$CONFIG_FILES llvm.spec" ;; "docs/doxygen.cfg") CONFIG_FILES="$CONFIG_FILES docs/doxygen.cfg" ;; "tools/clang/docs/doxygen.cfg") CONFIG_FILES="$CONFIG_FILES tools/clang/docs/doxygen.cfg" ;; - "tools/llvmc/src/Base.td") CONFIG_FILES="$CONFIG_FILES tools/llvmc/src/Base.td" ;; "tools/llvm-config/llvm-config.in") CONFIG_FILES="$CONFIG_FILES tools/llvm-config/llvm-config.in" ;; + "bindings/ocaml/llvm/META.llvm") CONFIG_FILES="$CONFIG_FILES bindings/ocaml/llvm/META.llvm" ;; "setup") CONFIG_COMMANDS="$CONFIG_COMMANDS setup" ;; "Makefile") CONFIG_COMMANDS="$CONFIG_COMMANDS Makefile" ;; "Makefile.common") CONFIG_COMMANDS="$CONFIG_COMMANDS Makefile.common" ;; @@ -23344,6 +19735,17 @@ build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim LLVM_COPYRIGHT!$LLVM_COPYRIGHT$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +CXX!$CXX$ac_delim +CXXFLAGS!$CXXFLAGS$ac_delim +ac_ct_CXX!$ac_ct_CXX$ac_delim +CPP!$CPP$ac_delim subdirs!$subdirs$ac_delim ENABLE_POLLY!$ENABLE_POLLY$ac_delim LLVM_HAS_POLLY!$LLVM_HAS_POLLY$ac_delim @@ -23368,14 +19770,6 @@ LLVM_ON_UNIX!$LLVM_ON_UNIX$ac_delim LLVM_ON_WIN32!$LLVM_ON_WIN32$ac_delim ARCH!$ARCH$ac_delim ENDIAN!$ENDIAN$ac_delim -CC!$CC$ac_delim -CFLAGS!$CFLAGS$ac_delim -LDFLAGS!$LDFLAGS$ac_delim -CPPFLAGS!$CPPFLAGS$ac_delim -ac_ct_CC!$ac_ct_CC$ac_delim -EXEEXT!$EXEEXT$ac_delim -OBJEXT!$OBJEXT$ac_delim -CPP!$CPP$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim LLVM_CROSS_COMPILING!$LLVM_CROSS_COMPILING$ac_delim @@ -23400,9 +19794,6 @@ ENABLE_PIC!$ENABLE_PIC$ac_delim ENABLE_SHARED!$ENABLE_SHARED$ac_delim ENABLE_EMBED_STDCXX!$ENABLE_EMBED_STDCXX$ac_delim ENABLE_TIMESTAMPS!$ENABLE_TIMESTAMPS$ac_delim -TARGETS_TO_BUILD!$TARGETS_TO_BUILD$ac_delim -LLVM_ENUM_TARGETS!$LLVM_ENUM_TARGETS$ac_delim -LLVM_ENUM_ASM_PRINTERS!$LLVM_ENUM_ASM_PRINTERS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -23444,19 +19835,16 @@ _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +TARGETS_TO_BUILD!$TARGETS_TO_BUILD$ac_delim +LLVM_ENUM_TARGETS!$LLVM_ENUM_TARGETS$ac_delim +LLVM_ENUM_ASM_PRINTERS!$LLVM_ENUM_ASM_PRINTERS$ac_delim LLVM_ENUM_ASM_PARSERS!$LLVM_ENUM_ASM_PARSERS$ac_delim LLVM_ENUM_DISASSEMBLERS!$LLVM_ENUM_DISASSEMBLERS$ac_delim ENABLE_CBE_PRINTF_A!$ENABLE_CBE_PRINTF_A$ac_delim -CLANGPATH!$CLANGPATH$ac_delim -CLANGXXPATH!$CLANGXXPATH$ac_delim -ENABLE_BUILT_CLANG!$ENABLE_BUILT_CLANG$ac_delim OPTIMIZE_OPTION!$OPTIMIZE_OPTION$ac_delim EXTRA_OPTIONS!$EXTRA_OPTIONS$ac_delim EXTRA_LD_OPTIONS!$EXTRA_LD_OPTIONS$ac_delim BINUTILS_INCDIR!$BINUTILS_INCDIR$ac_delim -CXX!$CXX$ac_delim -CXXFLAGS!$CXXFLAGS$ac_delim -ac_ct_CXX!$ac_ct_CXX$ac_delim NM!$NM$ac_delim ifGNUmake!$ifGNUmake$ac_delim LN_S!$LN_S$ac_delim @@ -23508,11 +19896,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 -LLVMGCCCOMMAND!$LLVMGCCCOMMAND$ac_delim -LLVMGXXCOMMAND!$LLVMGXXCOMMAND$ac_delim -LLVMGCC!$LLVMGCC$ac_delim -LLVMGXX!$LLVMGXX$ac_delim -LLVMCC_OPTION!$LLVMCC_OPTION$ac_delim NO_VARIADIC_MACROS!$NO_VARIADIC_MACROS$ac_delim NO_MISSING_FIELD_INITIALIZERS!$NO_MISSING_FIELD_INITIALIZERS$ac_delim USE_UDIS86!$USE_UDIS86$ac_delim @@ -23520,13 +19903,6 @@ USE_OPROFILE!$USE_OPROFILE$ac_delim HAVE_PTHREAD!$HAVE_PTHREAD$ac_delim HUGE_VAL_SANITY!$HUGE_VAL_SANITY$ac_delim MMAP_FILE!$MMAP_FILE$ac_delim -LLVMCC_EMITIR_FLAG!$LLVMCC_EMITIR_FLAG$ac_delim -LLVMCC1!$LLVMCC1$ac_delim -LLVMCC1PLUS!$LLVMCC1PLUS$ac_delim -LLVMGCCDIR!$LLVMGCCDIR$ac_delim -LLVMGCC_LANGS!$LLVMGCC_LANGS$ac_delim -LLVMGCC_DRAGONEGG!$LLVMGCC_DRAGONEGG$ac_delim -LLVMCC_DISABLEOPT_FLAGS!$LLVMCC_DISABLEOPT_FLAGS$ac_delim SHLIBEXT!$SHLIBEXT$ac_delim SHLIBPATH_VAR!$SHLIBPATH_VAR$ac_delim LLVM_PREFIX!$LLVM_PREFIX$ac_delim @@ -23541,9 +19917,15 @@ LLVM_MANDIR!$LLVM_MANDIR$ac_delim LLVM_CONFIGTIME!$LLVM_CONFIGTIME$ac_delim BINDINGS_TO_BUILD!$BINDINGS_TO_BUILD$ac_delim ALL_BINDINGS!$ALL_BINDINGS$ac_delim +OCAML_LIBDIR!$OCAML_LIBDIR$ac_delim +ENABLE_VISIBILITY_INLINES_HIDDEN!$ENABLE_VISIBILITY_INLINES_HIDDEN$ac_delim +RPATH!$RPATH$ac_delim +RDYNAMIC!$RDYNAMIC$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; 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 @@ -23562,53 +19944,6 @@ fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -_ACEOF -sed ' -s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g -s/^/s,@/; s/!/@,|#_!!_#|/ -:n -t n -s/'"$ac_delim"'$/,g/; t -s/$/\\/; p -N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n -' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF -CEOF$ac_eof -_ACEOF - - -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - cat >conf$$subs.sed <<_ACEOF -OCAML_LIBDIR!$OCAML_LIBDIR$ac_delim -ENABLE_VISIBILITY_INLINES_HIDDEN!$ENABLE_VISIBILITY_INLINES_HIDDEN$ac_delim -RPATH!$RPATH$ac_delim -RDYNAMIC!$RDYNAMIC$ac_delim -LIBOBJS!$LIBOBJS$ac_delim -LTLIBOBJS!$LTLIBOBJS$ac_delim -_ACEOF - - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 6; then - break - elif $ac_last_try; then - { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} - { (exit 1); exit 1; }; } - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` -if test -n "$ac_eof"; then - ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` - ac_eof=`expr $ac_eof + 1` -fi - -cat >>$CONFIG_STATUS <<_ACEOF -cat >"\$tmp/subs-3.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' @@ -23871,7 +20206,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 -f "$tmp/subs-3.sed" >$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"; } && @@ -23951,7 +20286,7 @@ do cat >>$CONFIG_STATUS <<_ACEOF # First, check the format of the line: cat >"\$tmp/defines.sed" <<\\CEOF -/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*/b def /^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def b :def @@ -24099,7 +20434,12 @@ if test "$no_recursion" != yes; then case $ac_arg in *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac - ac_sub_configure_args="$ac_arg $ac_sub_configure_args" + ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" + + # Pass --silent + if test "$silent" = yes; then + ac_sub_configure_args="--silent $ac_sub_configure_args" + fi ac_popdir=`pwd` for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue diff --git a/docs/Atomics.html b/docs/Atomics.html new file mode 100644 index 000000000000..fc15e27c39cd --- /dev/null +++ b/docs/Atomics.html @@ -0,0 +1,569 @@ + + + + LLVM Atomic Instructions and Concurrency Guide + + + + + +

+ LLVM Atomic Instructions and Concurrency Guide +

+ +
    +
  1. Introduction
  2. +
  3. Optimization outside atomic
  4. +
  5. Atomic instructions
  6. +
  7. Atomic orderings
  8. +
  9. Atomics and IR optimization
  10. +
  11. Atomics and Codegen
  12. +
+ +
+

Written by Eli Friedman

+
+ + +

+ Introduction +

+ + +
+ +

Historically, LLVM has not had very strong support for concurrency; some +minimal intrinsics were provided, and volatile was used in some +cases to achieve rough semantics in the presence of concurrency. However, this +is changing; there are now new instructions which are well-defined in the +presence of threads and asynchronous signals, and the model for existing +instructions has been clarified in the IR.

+ +

The atomic instructions are designed specifically to provide readable IR and + optimized code generation for the following:

+ + +

Atomic and volatile in the IR are orthogonal; "volatile" is the C/C++ + volatile, which ensures that every volatile load and store happens and is + performed in the stated order. A couple examples: if a + SequentiallyConsistent store is immediately followed by another + SequentiallyConsistent store to the same address, the first store can + be erased. This transformation is not allowed for a pair of volatile + stores. On the other hand, a non-volatile non-atomic load can be moved + across a volatile load freely, but not an Acquire load.

+ +

This document is intended to provide a guide to anyone either writing a + frontend for LLVM or working on optimization passes for LLVM with a guide + for how to deal with instructions with special semantics in the presence of + concurrency. This is not intended to be a precise guide to the semantics; + the details can get extremely complicated and unreadable, and are not + usually necessary.

+ +
+ + +

+ Optimization outside atomic +

+ + +
+ +

The basic 'load' and 'store' allow a variety of + optimizations, but can lead to undefined results in a concurrent environment; + see NonAtomic. This section specifically goes + into the one optimizer restriction which applies in concurrent environments, + which gets a bit more of an extended description because any optimization + dealing with stores needs to be aware of it.

+ +

From the optimizer's point of view, the rule is that if there + are not any instructions with atomic ordering involved, concurrency does + not matter, with one exception: if a variable might be visible to another + thread or signal handler, a store cannot be inserted along a path where it + might not execute otherwise. Take the following example:

+ +
+/* C code, for readability; run through clang -O2 -S -emit-llvm to get
+   equivalent IR */
+int x;
+void f(int* a) {
+  for (int i = 0; i < 100; i++) {
+    if (a[i])
+      x += 1;
+  }
+}
+
+ +

The following is equivalent in non-concurrent situations:

+ +
+int x;
+void f(int* a) {
+  int xtemp = x;
+  for (int i = 0; i < 100; i++) {
+    if (a[i])
+      xtemp += 1;
+  }
+  x = xtemp;
+}
+
+ +

However, LLVM is not allowed to transform the former to the latter: it could + indirectly introduce undefined behavior if another thread can access x at + the same time. (This example is particularly of interest because before the + concurrency model was implemented, LLVM would perform this + transformation.)

+ +

Note that speculative loads are allowed; a load which + is part of a race returns undef, but does not have undefined + behavior.

+ + +
+ + +

+ Atomic instructions +

+ + +
+ +

For cases where simple loads and stores are not sufficient, LLVM provides + various atomic instructions. The exact guarantees provided depend on the + ordering; see Atomic orderings

+ +

load atomic and store atomic provide the same + basic functionality as non-atomic loads and stores, but provide additional + guarantees in situations where threads and signals are involved.

+ +

cmpxchg and atomicrmw are essentially like an + atomic load followed by an atomic store (where the store is conditional for + cmpxchg), but no other memory operation can happen on any thread + between the load and store. Note that LLVM's cmpxchg does not provide quite + as many options as the C++0x version.

+ +

A fence provides Acquire and/or Release ordering which is not + part of another operation; it is normally used along with Monotonic memory + operations. A Monotonic load followed by an Acquire fence is roughly + equivalent to an Acquire load.

+ +

Frontends generating atomic instructions generally need to be aware of the + target to some degree; atomic instructions are guaranteed to be lock-free, + and therefore an instruction which is wider than the target natively supports + can be impossible to generate.

+ +
+ + +

+ Atomic orderings +

+ + +
+ +

In order to achieve a balance between performance and necessary guarantees, + there are six levels of atomicity. They are listed in order of strength; + each level includes all the guarantees of the previous level except for + Acquire/Release. (See also LangRef.)

+ + +

+ NotAtomic +

+ +
+ +

NotAtomic is the obvious, a load or store which is not atomic. (This isn't + really a level of atomicity, but is listed here for comparison.) This is + essentially a regular load or store. If there is a race on a given memory + location, loads from that location return undef.

+ +
+
Relevant standard
+
This is intended to match shared variables in C/C++, and to be used + in any other context where memory access is necessary, and + a race is impossible. (The precise definition is in + LangRef.) +
Notes for frontends
+
The rule is essentially that all memory accessed with basic loads and + stores by multiple threads should be protected by a lock or other + synchronization; otherwise, you are likely to run into undefined + behavior. If your frontend is for a "safe" language like Java, + use Unordered to load and store any shared variable. Note that NotAtomic + volatile loads and stores are not properly atomic; do not try to use + them as a substitute. (Per the C/C++ standards, volatile does provide + some limited guarantees around asynchronous signals, but atomics are + generally a better solution.) +
Notes for optimizers
+
Introducing loads to shared variables along a codepath where they would + not otherwise exist is allowed; introducing stores to shared variables + is not. See Optimization outside + atomic.
+
Notes for code generation
+
The one interesting restriction here is that it is not allowed to write + to bytes outside of the bytes relevant to a store. This is mostly + relevant to unaligned stores: it is not allowed in general to convert + an unaligned store into two aligned stores of the same width as the + unaligned store. Backends are also expected to generate an i8 store + as an i8 store, and not an instruction which writes to surrounding + bytes. (If you are writing a backend for an architecture which cannot + satisfy these restrictions and cares about concurrency, please send an + email to llvmdev.)
+
+ +
+ + + +

+ Unordered +

+ +
+ +

Unordered is the lowest level of atomicity. It essentially guarantees that + races produce somewhat sane results instead of having undefined behavior. + It also guarantees the operation to be lock-free, so it do not depend on + the data being part of a special atomic structure or depend on a separate + per-process global lock. Note that code generation will fail for + unsupported atomic operations; if you need such an operation, use explicit + locking.

+ +
+
Relevant standard
+
This is intended to match the Java memory model for shared + variables.
+
Notes for frontends
+
This cannot be used for synchronization, but is useful for Java and + other "safe" languages which need to guarantee that the generated + code never exhibits undefined behavior. Note that this guarantee + is cheap on common platforms for loads of a native width, but can + be expensive or unavailable for wider loads, like a 64-bit store + on ARM. (A frontend for Java or other "safe" languages would normally + split a 64-bit store on ARM into two 32-bit unordered stores.) +
Notes for optimizers
+
In terms of the optimizer, this prohibits any transformation that + transforms a single load into multiple loads, transforms a store + into multiple stores, narrows a store, or stores a value which + would not be stored otherwise. Some examples of unsafe optimizations + are narrowing an assignment into a bitfield, rematerializing + a load, and turning loads and stores into a memcpy call. Reordering + unordered operations is safe, though, and optimizers should take + advantage of that because unordered operations are common in + languages that need them.
+
Notes for code generation
+
These operations are required to be atomic in the sense that if you + use unordered loads and unordered stores, a load cannot see a value + which was never stored. A normal load or store instruction is usually + sufficient, but note that an unordered load or store cannot + be split into multiple instructions (or an instruction which + does multiple memory operations, like LDRD on ARM).
+
+ +
+ + +

+ Monotonic +

+ +
+ +

Monotonic is the weakest level of atomicity that can be used in + synchronization primitives, although it does not provide any general + synchronization. It essentially guarantees that if you take all the + operations affecting a specific address, a consistent ordering exists. + +

+
Relevant standard
+
This corresponds to the C++0x/C1x memory_order_relaxed; + see those standards for the exact definition. +
Notes for frontends
+
If you are writing a frontend which uses this directly, use with caution. + The guarantees in terms of synchronization are very weak, so make + sure these are only used in a pattern which you know is correct. + Generally, these would either be used for atomic operations which + do not protect other memory (like an atomic counter), or along with + a fence.
+
Notes for optimizers
+
In terms of the optimizer, this can be treated as a read+write on the + relevant memory location (and alias analysis will take advantage of + that). In addition, it is legal to reorder non-atomic and Unordered + loads around Monotonic loads. CSE/DSE and a few other optimizations + are allowed, but Monotonic operations are unlikely to be used in ways + which would make those optimizations useful.
+
Notes for code generation
+
Code generation is essentially the same as that for unordered for loads + and stores. No fences are required. cmpxchg and + atomicrmw are required to appear as a single operation.
+
+ +
+ + +

+ Acquire +

+ +
+ +

Acquire provides a barrier of the sort necessary to acquire a lock to access + other memory with normal loads and stores. + +

+
Relevant standard
+
This corresponds to the C++0x/C1x memory_order_acquire. It + should also be used for C++0x/C1x memory_order_consume. +
Notes for frontends
+
If you are writing a frontend which uses this directly, use with caution. + Acquire only provides a semantic guarantee when paired with a Release + operation.
+
Notes for optimizers
+
Optimizers not aware of atomics can treat this like a nothrow call. + It is also possible to move stores from before an Acquire load + or read-modify-write operation to after it, and move non-Acquire + loads from before an Acquire operation to after it.
+
Notes for code generation
+
Architectures with weak memory ordering (essentially everything relevant + today except x86 and SPARC) require some sort of fence to maintain + the Acquire semantics. The precise fences required varies widely by + architecture, but for a simple implementation, most architectures provide + a barrier which is strong enough for everything (dmb on ARM, + sync on PowerPC, etc.). Putting such a fence after the + equivalent Monotonic operation is sufficient to maintain Acquire + semantics for a memory operation.
+
+ +
+ + +

+ Release +

+ +
+ +

Release is similar to Acquire, but with a barrier of the sort necessary to + release a lock. + +

+
Relevant standard
+
This corresponds to the C++0x/C1x memory_order_release.
+
Notes for frontends
+
If you are writing a frontend which uses this directly, use with caution. + Release only provides a semantic guarantee when paired with a Acquire + operation.
+
Notes for optimizers
+
Optimizers not aware of atomics can treat this like a nothrow call. + It is also possible to move loads from after a Release store + or read-modify-write operation to before it, and move non-Release + stores from after an Release operation to before it.
+
Notes for code generation
+
See the section on Acquire; a fence before the relevant operation is + usually sufficient for Release. Note that a store-store fence is not + sufficient to implement Release semantics; store-store fences are + generally not exposed to IR because they are extremely difficult to + use correctly.
+
+ +
+ + +

+ AcquireRelease +

+ +
+ +

AcquireRelease (acq_rel in IR) provides both an Acquire and a + Release barrier (for fences and operations which both read and write memory). + +

+
Relevant standard
+
This corresponds to the C++0x/C1x memory_order_acq_rel. +
Notes for frontends
+
If you are writing a frontend which uses this directly, use with caution. + Acquire only provides a semantic guarantee when paired with a Release + operation, and vice versa.
+
Notes for optimizers
+
In general, optimizers should treat this like a nothrow call; the + the possible optimizations are usually not interesting.
+
Notes for code generation
+
This operation has Acquire and Release semantics; see the sections on + Acquire and Release.
+
+ +
+ + +

+ SequentiallyConsistent +

+ +
+ +

SequentiallyConsistent (seq_cst in IR) provides + Acquire semantics for loads and Release semantics for + stores. Additionally, it guarantees that a total ordering exists + between all SequentiallyConsistent operations. + +

+
Relevant standard
+
This corresponds to the C++0x/C1x memory_order_seq_cst, + Java volatile, and the gcc-compatible __sync_* builtins + which do not specify otherwise. +
Notes for frontends
+
If a frontend is exposing atomic operations, these are much easier to + reason about for the programmer than other kinds of operations, and using + them is generally a practical performance tradeoff.
+
Notes for optimizers
+
Optimizers not aware of atomics can treat this like a nothrow call. + For SequentiallyConsistent loads and stores, the same reorderings are + allowed as for Acquire loads and Release stores, except that + SequentiallyConsistent operations may not be reordered.
+
Notes for code generation
+
SequentiallyConsistent loads minimally require the same barriers + as Acquire operations and SequentiallyConsistent stores require + Release barriers. Additionally, the code generator must enforce + ordering between SequentiallyConsistent stores followed by + SequentiallyConsistent loads. This is usually done by emitting + either a full fence before the loads or a full fence after the + stores; which is preferred varies by architecture.
+
+ +
+ +
+ + +

+ Atomics and IR optimization +

+ + +
+ +

Predicates for optimizer writers to query: +

    +
  • isSimple(): A load or store which is not volatile or atomic. This is + what, for example, memcpyopt would check for operations it might + transform.
  • +
  • isUnordered(): A load or store which is not volatile and at most + Unordered. This would be checked, for example, by LICM before hoisting + an operation.
  • +
  • mayReadFromMemory()/mayWriteToMemory(): Existing predicate, but note + that they return true for any operation which is volatile or at least + Monotonic.
  • +
  • Alias analysis: Note that AA will return ModRef for anything Acquire or + Release, and for the address accessed by any Monotonic operation.
  • +
+ +

To support optimizing around atomic operations, make sure you are using + the right predicates; everything should work if that is done. If your + pass should optimize some atomic operations (Unordered operations in + particular), make sure it doesn't replace an atomic load or store with + a non-atomic operation.

+ +

Some examples of how optimizations interact with various kinds of atomic + operations: +

    +
  • memcpyopt: An atomic operation cannot be optimized into part of a + memcpy/memset, including unordered loads/stores. It can pull operations + across some atomic operations. +
  • LICM: Unordered loads/stores can be moved out of a loop. It just treats + monotonic operations like a read+write to a memory location, and anything + stricter than that like a nothrow call. +
  • DSE: Unordered stores can be DSE'ed like normal stores. Monotonic stores + can be DSE'ed in some cases, but it's tricky to reason about, and not + especially important. +
  • Folding a load: Any atomic load from a constant global can be + constant-folded, because it cannot be observed. Similar reasoning allows + scalarrepl with atomic loads and stores. +
+ +
+ + +

+ Atomics and Codegen +

+ + +
+ +

Atomic operations are represented in the SelectionDAG with + ATOMIC_* opcodes. On architectures which use barrier + instructions for all atomic ordering (like ARM), appropriate fences are + split out as the DAG is built.

+ +

The MachineMemOperand for all atomic operations is currently marked as + volatile; this is not correct in the IR sense of volatile, but CodeGen + handles anything marked volatile very conservatively. This should get + fixed at some point.

+ +

Common architectures have some way of representing at least a pointer-sized + lock-free cmpxchg; such an operation can be used to implement + all the other atomic operations which can be represented in IR up to that + size. Backends are expected to implement all those operations, but not + operations which cannot be implemented in a lock-free manner. It is + expected that backends will give an error when given an operation which + cannot be implemented. (The LLVM code generator is not very helpful here + at the moment, but hopefully that will change.)

+ +

The implementation of atomics on LL/SC architectures (like ARM) is currently + a bit of a mess; there is a lot of copy-pasted code across targets, and + the representation is relatively unsuited to optimization (it would be nice + to be able to optimize loops involving cmpxchg etc.).

+ +

On x86, all atomic loads generate a MOV. + SequentiallyConsistent stores generate an XCHG, other stores + generate a MOV. SequentiallyConsistent fences generate an + MFENCE, other fences do not cause any code to be generated. + cmpxchg uses the LOCK CMPXCHG instruction. + atomicrmw xchg uses XCHG, + atomicrmw add and atomicrmw sub use + XADD, and all other atomicrmw operations generate + a loop with LOCK CMPXCHG. Depending on the users of the + result, some atomicrmw operations can be translated into + operations like LOCK AND, but that does not work in + general.

+ +

On ARM, MIPS, and many other RISC architectures, Acquire, Release, and + SequentiallyConsistent semantics require barrier instructions + for every such operation. Loads and stores generate normal instructions. + cmpxchg and atomicrmw can be represented using + a loop with LL/SC-style instructions which take some sort of exclusive + lock on a cache line (LDREX and STREX on + ARM, etc.). At the moment, the IR does not provide any way to represent a + weak cmpxchg which would not require a loop.

+
+ + + +
+
+ Valid CSS + Valid HTML 4.01 + + LLVM Compiler Infrastructure
+ Last modified: $Date: 2011-08-09 02:07:00 -0700 (Tue, 09 Aug 2011) $ +
+ + + diff --git a/docs/Bugpoint.html b/docs/Bugpoint.html index 05c867bcb08c..bc78933fed6d 100644 --- a/docs/Bugpoint.html +++ b/docs/Bugpoint.html @@ -216,18 +216,6 @@ non-obvious ways. Here are some hints and tips:

the list of specified optimizations to be randomized and applied to the program. This process will repeat until a bug is found or the user kills bugpoint. - -

  • bugpoint does not understand the -O option - that is used to specify optimization level to opt. You - can use e.g.

    - -
    -

    opt -O2 -debug-pass=Arguments foo.bc -disable-output

    -
    - -

    to get a list of passes that are used with -O2 and - then pass this list to bugpoint.

    - @@ -243,7 +231,7 @@ non-obvious ways. Here are some hints and tips:

    Chris Lattner
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-08-30 20:26:11 +0200 (Tue, 30 Aug 2011) $ diff --git a/docs/CMake.html b/docs/CMake.html index 0d8cf62e33c4..6389c7f22afd 100644 --- a/docs/CMake.html +++ b/docs/CMake.html @@ -340,7 +340,7 @@ on Visual C++ and Xcode, "-sv" on others. -

    LLVM_LIT_TOOLS_DIR:STRING
    +
    LLVM_LIT_TOOLS_DIR:PATH
    The path to GnuWin32 tools for tests. Valid on Windows host. Defaults to "", then Lit seeks tools according to %PATH%. Lit can find tools(eg. grep, sort, &c) on LLVM_LIT_TOOLS_DIR at first, @@ -423,8 +423,9 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${LLVM_ROOT}/share/llvm/cmake") include(LLVMConfig) # Now set the header and library paths: - include_directories( ${LLVM_ROOT}/include ) - link_directories( ${LLVM_ROOT}/lib ) + include_directories( ${LLVM_INCLUDE_DIRS} ) + link_directories( ${LLVM_LIBRARY_DIRS} ) + add_definitions( ${LLVM_DEFINITIONS} ) # Let's suppose we want to build a JIT compiler with support for # binary code (no interpreter): llvm_map_components_to_libraries(REQ_LLVM_LIBRARIES jit native) diff --git a/docs/CodeGenerator.html b/docs/CodeGenerator.html index 29a2cce7a391..e693a22369ec 100644 --- a/docs/CodeGenerator.html +++ b/docs/CodeGenerator.html @@ -114,6 +114,7 @@
  • Prolog/Epilog
  • Dynamic Allocation
  • +
  • The PTX backend
  • @@ -1768,22 +1769,28 @@ bool RegMapping_Fer::compatible_class(MachineFunction &mf, different register allocators:

      -
    • Linear ScanThe default allocator. This is the - well-know linear scan register allocator. Whereas the - Simple and Local algorithms use a direct mapping - implementation technique, the Linear Scan implementation - uses a spiller in order to place load and stores.
    • -
    • Fast — This register allocator is the default for debug builds. It allocates registers on a basic block level, attempting to keep values in registers and reusing registers as appropriate.
    • +
    • Basic — This is an incremental approach to register + allocation. Live ranges are assigned to registers one at a time in + an order that is driven by heuristics. Since code can be rewritten + on-the-fly during allocation, this framework allows interesting + allocators to be developed as extensions. It is not itself a + production register allocator but is a potentially useful + stand-alone mode for triaging bugs and as a performance baseline. + +
    • GreedyThe default allocator. This is a + highly tuned implementation of the Basic allocator that + incorporates global live range splitting. This allocator works hard + to minimize the cost of spill code. +
    • PBQP — A Partitioned Boolean Quadratic Programming (PBQP) based register allocator. This allocator works by constructing a PBQP problem representing the register allocation problem under consideration, solving this using a PBQP solver, and mapping the solution back to a register assignment.
    • -

    The type of register allocator used in llc can be chosen with the @@ -1805,7 +1812,121 @@ $ llc -regalloc=pbqp file.bc -o pbqp.s;

    Prolog/Epilog Code Insertion

    -

    To Be Written

    + + +

    + Compact Unwind +

    + +
    + +

    Throwing an exception requires unwinding out of a function. The + information on how to unwind a given function is traditionally expressed in + DWARF unwind (a.k.a. frame) info. But that format was originally developed + for debuggers to backtrace, and each Frame Description Entry (FDE) requires + ~20-30 bytes per function. There is also the cost of mapping from an address + in a function to the corresponding FDE at runtime. An alternative unwind + encoding is called compact unwind and requires just 4-bytes per + function.

    + +

    The compact unwind encoding is a 32-bit value, which is encoded in an + architecture-specific way. It specifies which registers to restore and from + where, and how to unwind out of the function. When the linker creates a final + linked image, it will create a __TEXT,__unwind_info + section. This section is a small and fast way for the runtime to access + unwind info for any given function. If we emit compact unwind info for the + function, that compact unwind info will be encoded in + the __TEXT,__unwind_info section. If we emit DWARF unwind info, + the __TEXT,__unwind_info section will contain the offset of the + FDE in the __TEXT,__eh_frame section in the final linked + image.

    + +

    For X86, there are three modes for the compact unwind encoding:

    + +
    +
    Function with a Frame Pointer (EBP or RBP)
    +

    EBP/RBP-based frame, where EBP/RBP is pushed + onto the stack immediately after the return address, + then ESP/RSP is moved to EBP/RBP. Thus to + unwind, ESP/RSP is restored with the + current EBP/RBP value, then EBP/RBP is restored + by popping the stack, and the return is done by popping the stack once + more into the PC. All non-volatile registers that need to be restored must + have been saved in a small range on the stack that + starts EBP-4 to EBP-1020 (RBP-8 + to RBP-1020). The offset (divided by 4 in 32-bit mode and 8 + in 64-bit mode) is encoded in bits 16-23 (mask: 0x00FF0000). + The registers saved are encoded in bits 0-14 + (mask: 0x00007FFF) as five 3-bit entries from the following + table:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Compact Numberi386 Registerx86-64 Regiser
    1EBXRBX
    2ECXR12
    3EDXR13
    4EDIR14
    5ESIR15
    6EBPRBP
    + +
    + +
    Frameless with a Small Constant Stack Size (EBP + or RBP is not used as a frame pointer)
    +

    To return, a constant (encoded in the compact unwind encoding) is added + to the ESP/RSP. Then the return is done by popping the stack + into the PC. All non-volatile registers that need to be restored must have + been saved on the stack immediately after the return address. The stack + size (divided by 4 in 32-bit mode and 8 in 64-bit mode) is encoded in bits + 16-23 (mask: 0x00FF0000). There is a maximum stack size of + 1024 bytes in 32-bit mode and 2048 in 64-bit mode. The number of registers + saved is encoded in bits 9-12 (mask: 0x00001C00). Bits 0-9 + (mask: 0x000003FF) contain which registers were saved and + their order. (See + the encodeCompactUnwindRegistersWithoutFrame() function + in lib/Target/X86FrameLowering.cpp for the encoding + algorithm.)

    + +
    Frameless with a Large Constant Stack Size (EBP + or RBP is not used as a frame pointer)
    +

    This case is like the "Frameless with a Small Constant Stack Size" + case, but the stack size is too large to encode in the compact unwind + encoding. Instead it requires that the function contains "subl + $nnnnnn, %esp" in its prolog. The compact encoding contains the + offset to the $nnnnnn value in the function in bits 9-12 + (mask: 0x00001C00).

    +
    + +
    +

    Late Machine Code Optimizations @@ -2165,7 +2286,7 @@ is the key:

    - * + @@ -2261,9 +2382,6 @@ disassembling machine opcode bytes into MCInst's.

    This box indicates whether the target supports most popular inline assembly constraints and modifiers.

    -

    X86 lacks reliable support for inline assembly -constraints relating to the X86 floating point stack.

    - @@ -2792,6 +2910,70 @@ MOVSX32rm16 -> movsx, 32-bit register, 16-bit memory + + + +

    + The PTX backend +

    + +
    + +

    The PTX code generator lives in the lib/Target/PTX directory. It is + currently a work-in-progress, but already supports most of the code + generation functionality needed to generate correct PTX kernels for + CUDA devices.

    + +

    The code generator can target PTX 2.0+, and shader model 1.0+. The + PTX ISA Reference Manual is used as the primary source of ISA + information, though an effort is made to make the output of the code + generator match the output of the NVidia nvcc compiler, whenever + possible.

    + +

    Code Generator Options:

    + + + + + + + + + + + + + + + + + +
    OptionDescription
    doubleIf enabled, the map_f64_to_f32 directive is + disabled in the PTX output, allowing native double-precision + arithmetic
    no-fmaDisable generation of Fused-Multiply Add + instructions, which may be beneficial for some devices
    smxy / computexySet shader model/compute capability to x.y, + e.g. sm20 or compute13
    + +

    Working:

    +
      +
    • Arithmetic instruction selection (including combo FMA)
    • +
    • Bitwise instruction selection
    • +
    • Control-flow instruction selection
    • +
    • Function calls (only on SM 2.0+ and no return arguments)
    • +
    • Addresses spaces (0 = global, 1 = constant, 2 = local, 4 = + shared)
    • +
    • Thread synchronization (bar.sync)
    • +
    • Special register reads ([N]TID, [N]CTAID, PMx, CLOCK, etc.)
    • +
    + +

    In Progress:

    +
      +
    • Robust call instruction selection
    • +
    • Stack frame allocation
    • +
    • Device-specific instruction scheduling optimizations
    • +
    + +
    @@ -2806,7 +2988,7 @@ MOVSX32rm16 -> movsx, 32-bit register, 16-bit memory Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-05-23 00:28:47 +0200 (Mon, 23 May 2011) $ + Last modified: $Date: 2011-09-19 20:15:46 +0200 (Mon, 19 Sep 2011) $ diff --git a/docs/CodingStandards.html b/docs/CodingStandards.html index 139bbdb24902..3153a6e10ccf 100644 --- a/docs/CodingStandards.html +++ b/docs/CodingStandards.html @@ -854,8 +854,12 @@ rules:

    • Type names (including classes, structs, enums, typedefs, etc) - should be nouns and start with an upper-case letter (e.g. - TextFileReader).

    • + should be nouns and start with an upper-case letter (e.g. + TextFileReader).

      + +
    • Variable names should be nouns (as they represent state). The + name should be camel case, and start with an upper case letter (e.g. + Leader or Boats).

    • Function names should be verb phrases (as they represent actions), and command-like function should be imperative. The name should @@ -1522,7 +1526,7 @@ something.

      Chris Lattner
      LLVM Compiler Infrastructure
      - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-08-12 21:49:16 +0200 (Fri, 12 Aug 2011) $ diff --git a/docs/CommandGuide/index.html b/docs/CommandGuide/index.html index cb5438f58baa..3e4e2200c95b 100644 --- a/docs/CommandGuide/index.html +++ b/docs/CommandGuide/index.html @@ -69,9 +69,6 @@ options) arguments to the tool you are interested in.

    • llvm-config - print out LLVM compilation options, libraries, etc. as configured
    • -
    • llvmc - - a generic customizable compiler driver
    • -
    • llvm-diff - structurally compare two modules
    • @@ -79,25 +76,6 @@ options) arguments to the tool you are interested in.

      - -

      - C and C++ Front-end Commands -

      - - -
      -
        - -
      • llvm-gcc - - GCC-based C front-end for LLVM - -
      • llvm-g++ - - GCC-based C++ front-end for LLVM
      • - -
      - -
      -

      Debugging Tools @@ -151,7 +129,7 @@ options) arguments to the tool you are interested in.

      src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"> LLVM Compiler Infrastructure
      - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-09-20 20:24:04 +0200 (Tue, 20 Sep 2011) $ diff --git a/docs/CommandGuide/llvm-extract.pod b/docs/CommandGuide/llvm-extract.pod index 797e79d128d4..67f00f0b8615 100644 --- a/docs/CommandGuide/llvm-extract.pod +++ b/docs/CommandGuide/llvm-extract.pod @@ -37,11 +37,23 @@ B will write raw bitcode regardless of the output device. Extract the function named I from the LLVM bitcode. May be specified multiple times to extract multiple functions at once. +=item B<--rfunc> I + +Extract the function(s) matching I from the LLVM bitcode. +All functions matching the regular expression will be extracted. May be +specified multiple times. + =item B<--glob> I Extract the global variable named I from the LLVM bitcode. May be specified multiple times to extract multiple global variables at once. +=item B<--rglob> I + +Extract the global variable(s) matching I from the LLVM +bitcode. All global variables matching the regular expression will be extracted. +May be specified multiple times. + =item B<-help> Print a summary of command line options. diff --git a/docs/CommandGuide/llvmc.pod b/docs/CommandGuide/llvmc.pod deleted file mode 100644 index 95a9e5ef3611..000000000000 --- a/docs/CommandGuide/llvmc.pod +++ /dev/null @@ -1,190 +0,0 @@ -=pod - -=head1 NAME - -llvmc - The LLVM Compiler Driver (WIP) - -=head1 SYNOPSIS - -B [I] I - -=head1 DESCRIPTION - -B is a configurable driver for invoking other LLVM (and non-LLVM) tools -in order to compile, optimize and link software for multiple languages. For -those familiar with FSF's B tool, it is very similar. Please note that -B is considered an experimental tool. - -=head1 OPTIONS - -=head2 Built-in Options - -LLVMC has some built-in options that can't be overridden in the -configuration libraries. - -=over - -=item B<-o> I - -Output file name. - -=item B<-x> I - -Specify the language of the following input files until the next B<-x> -option. - -=item B<-load> I - -Load the specified plugin DLL. Example: -S<-load $LLVM_DIR/Release/lib/LLVMCSimple.so>. - -=item B<-v> or B<--verbose> - -Enable verbose mode, i.e. print out all executed commands. - -=item B<--check-graph> - -Check the compilation for common errors like mismatched output/input language -names, multiple default edges and cycles. Because of plugins, these checks can't -be performed at compile-time. Exit with code zero if no errors were found, and -return the number of found errors otherwise. Hidden option, useful for debugging -LLVMC plugins. - -=item B<--view-graph> - -Show a graphical representation of the compilation graph and exit. Requires that -you have I and I programs installed. Hidden option, useful for -debugging LLVMC plugins. - -=item B<--write-graph> - -Write a I file in the current directory with the -compilation graph description in Graphviz format (identical to the file used by -the B<--view-graph> option). The B<-o> option can be used to set the output file -name. Hidden option, useful for debugging LLVMC plugins. - -=item B<--save-temps> - -Write temporary files to the current directory and do not delete them on -exit. This option can also take an argument: the I<--save-temps=obj> switch will -write files into the directory specified with the I<-o> option. The -I<--save-temps=cwd> and I<--save-temps> switches are both synonyms for the -default behaviour. - -=item B<--temp-dir> I - -Store temporary files in the given directory. This directory is deleted on exit -unless I<--save-temps> is specified. If I<--save-temps=obj> is also specified, -I<--temp-dir> is given the precedence. - -=item B<-help> - -Print a summary of command-line options and exit. - -=item B<-help-hidden> - -Print a summary of command-line options and exit. Print help even for -options intended for developers. - -=item B<--version> - -Print version information and exit. - -=item B<@>I - -Read command-line options from I. The options read are inserted -in place of the original @I option. If I does not exist, or -cannot be read, then the option will be treated literally, and not -removed. - -Options in I are separated by whitespace. A whitespace character -may be included in an option by surrounding the entire option in -either single or double quotes. Any character (including a backslash) -may be included by prefixing the character to be included with a -backslash. The file may itself contain additional @I options; -any such options will be processed recursively. - - -=back - - -=head2 Control Options - -By default, LLVMC is built with some standard configuration libraries -that define the following options: - -=over - -=item B<-clang> - -Use Clang instead of llvm-gcc. - -=item B<-opt> - -Enable optimization passes with B. To pass options to the B program -use the B<-Wo,> option. - -=item B<-I> I - -Add a directory to the header file search path. - -=item B<-L> I - -Add I to the library search path. - -=item B<-F> I - -Add I to the framework search path. - -=item B<-l>I - -Link in the library libI.[bc | a | so]. This library should -be a bitcode library. - -=item B<-framework> I - -Link in the library libI.[bc | a | so]. This library should -be a bitcode library. - -=item B<-emit-llvm> - -Output LLVM bitcode (with B<-c>) or assembly (with B<-S>) instead of native -object (or assembly). If B<-emit-llvm> is given without either B<-c> or B<-S> -it has no effect. - -=item B<-Wa> - -Pass options to assembler. - -=item B<-Wl> - -Pass options to linker. - -=item B<-Wo> - -Pass options to opt. - -=item B<-Wllc> - -Pass options to llc (code generator). - -=back - -=head1 EXIT STATUS - -If B succeeds, it will exit with code 0. Otherwise, if an -error occurs, it will exit with a non-zero value. If one of the -compilation tools returns a non-zero status, pending actions will be -discarded and B will return the same result code as the failing -compilation tool. - -=head1 SEE ALSO - -L, L, L, -L, L, L - -=head1 AUTHORS - -Maintained by the LLVM Team (L). - -=cut diff --git a/docs/CommandGuide/llvmgcc.pod b/docs/CommandGuide/llvmgcc.pod deleted file mode 100644 index 30af0a06e06f..000000000000 --- a/docs/CommandGuide/llvmgcc.pod +++ /dev/null @@ -1,76 +0,0 @@ -=pod - -=head1 NAME - -llvm-gcc - LLVM C front-end - -=head1 SYNOPSIS - -B [I] I - -=head1 DESCRIPTION - -The B command is the LLVM C front end. It is a modified -version of gcc that compiles C/ObjC programs into native objects, LLVM -bitcode or LLVM assembly language, depending upon the options. - -By default, B compiles to native objects just like GCC does. If the -B<-emit-llvm> and B<-c> options are given then it will generate LLVM bitcode files -instead. If B<-emit-llvm> and B<-S> are given, then it will generate LLVM -assembly. - -Being derived from the GNU Compiler Collection, B has many -of gcc's features and accepts most of gcc's options. It handles a -number of gcc's extensions to the C programming language. See the gcc -documentation for details. - -=head1 OPTIONS - -=over - -=item B<--help> - -Print a summary of command line options. - -=item B<-o> I - -Specify the output file to be I. - -=item B<-I> I - -Add a directory to the header file search path. This option can be -repeated. - -=item B<-L> I - -Add I to the library search path. This option can be -repeated. - -=item B<-l>I - -Link in the library libI.[bc | a | so]. This library should -be a bitcode library. - -=item B<-emit-llvm> - -Make the output be LLVM bitcode (with B<-c>) or assembly (with B<-s>) instead -of native object (or assembly). If B<-emit-llvm> is given without either B<-c> -or B<-S> it has no effect. - -=back - -=head1 EXIT STATUS - -If B succeeds, it will exit with 0. Otherwise, if an error -occurs, it will exit with a non-zero value. - -=head1 SEE ALSO - -L - -=head1 AUTHORS - -Maintained by the LLVM Team (L). - -=cut - diff --git a/docs/CommandGuide/llvmgxx.pod b/docs/CommandGuide/llvmgxx.pod deleted file mode 100644 index 1ea3d4967006..000000000000 --- a/docs/CommandGuide/llvmgxx.pod +++ /dev/null @@ -1,85 +0,0 @@ -=pod - -=head1 NAME - -llvm-g++ - LLVM C++ front-end - -=head1 SYNOPSIS - -B [I] I - -=head1 DESCRIPTION - -The B command is the LLVM C++ front end. It is a modified -version of g++ that compiles C++/ObjC++ programs into native code, -LLVM bitcode or assembly language, depending upon the options. - -By default, B compiles to native objects just like GCC does. If the -B<-emit-llvm> option is given then it will generate LLVM bitcode files instead. -If B<-S> (assembly) is also given, then it will generate LLVM assembly. - -Being derived from the GNU Compiler Collection, B has many -of g++'s features and accepts most of g++'s options. It handles a -number of g++'s extensions to the C++ programming language. - -=head1 OPTIONS - -=over - -=item B<--help> - -Print a summary of command line options. - -=item B<-S> - -Do not generate an LLVM bitcode file. Rather, compile the source -file into an LLVM assembly language file. - -=item B<-c> - -Do not generate a linked executable. Rather, compile the source -file into an LLVM bitcode file. This bitcode file can then be -linked with other bitcode files later on to generate a full LLVM -executable. - -=item B<-o> I - -Specify the output file to be I. - -=item B<-I> I - -Add a directory to the header file search path. This option can be -repeated. - -=item B<-L> I - -Add I to the library search path. This option can be -repeated. - -=item B<-l>I - -Link in the library libI.[bc | a | so]. This library should -be a bitcode library. - -=item B<-emit-llvm> - -Make the output be LLVM bitcode (or assembly) instead of native object (or -assembly). - -=back - -=head1 EXIT STATUS - -If B succeeds, it will exit with 0. Otherwise, if an error -occurs, it will exit with a non-zero value. - -=head1 SEE ALSO - -L - -=head1 AUTHORS - -Maintained by the LLVM Team (L). - -=cut - diff --git a/docs/CompilerDriver.html b/docs/CompilerDriver.html deleted file mode 100644 index 1b2f808cbf70..000000000000 --- a/docs/CompilerDriver.html +++ /dev/null @@ -1,687 +0,0 @@ - - - - - - -Customizing LLVMC: Reference Manual - - - -
      -

      Customizing LLVMC: Reference Manual

      - - - -
      -

      Written by Mikhail Glushenkov

      -
      -

      Introduction

      -

      LLVMC is a generic compiler driver, designed to be customizable and -extensible. It plays the same role for LLVM as the gcc program does for -GCC - LLVMC's job is essentially to transform a set of input files into a set of -targets depending on configuration rules and user options. What makes LLVMC -different is that these transformation rules are completely customizable - in -fact, LLVMC knows nothing about the specifics of transformation (even the -command-line options are mostly not hard-coded) and regards the transformation -structure as an abstract graph. The structure of this graph is described in -high-level TableGen code, from which an efficient C++ representation is -automatically derived. This makes it possible to adapt LLVMC for other -purposes - for example, as a build tool for game resources.

      -

      Because LLVMC employs TableGen as its configuration language, you -need to be familiar with it to customize LLVMC.

      -
      -
      -

      Compiling with llvmc

      -

      LLVMC tries hard to be as compatible with gcc as possible, -although there are some small differences. Most of the time, however, -you shouldn't be able to notice them:

      -
      -$ # This works as expected:
      -$ llvmc -O3 -Wall hello.cpp
      -$ ./a.out
      -hello
      -
      -

      One nice feature of LLVMC is that one doesn't have to distinguish between -different compilers for different languages (think g++ vs. gcc) - the -right toolchain is chosen automatically based on input language names (which -are, in turn, determined from file extensions). If you want to force files -ending with ".c" to compile as C++, use the -x option, just like you would -do it with gcc:

      -
      -$ # hello.c is really a C++ file
      -$ llvmc -x c++ hello.c
      -$ ./a.out
      -hello
      -
      -

      On the other hand, when using LLVMC as a linker to combine several C++ -object files you should provide the --linker option since it's -impossible for LLVMC to choose the right linker in that case:

      -
      -$ llvmc -c hello.cpp
      -$ llvmc hello.o
      -[A lot of link-time errors skipped]
      -$ llvmc --linker=c++ hello.o
      -$ ./a.out
      -hello
      -
      -

      By default, LLVMC uses llvm-gcc to compile the source code. It is also -possible to choose the clang compiler with the -clang option.

      -
      -
      -

      Predefined options

      -

      LLVMC has some built-in options that can't be overridden in the TableGen code:

      -
        -
      • -o FILE - Output file name.
      • -
      • -x LANGUAGE - Specify the language of the following input files -until the next -x option.
      • -
      • -v - Enable verbose mode, i.e. print out all executed commands.
      • -
      • --save-temps - Write temporary files to the current directory and do not -delete them on exit. This option can also take an argument: the ---save-temps=obj switch will write files into the directory specified with -the -o option. The --save-temps=cwd and --save-temps switches are -both synonyms for the default behaviour.
      • -
      • --temp-dir DIRECTORY - Store temporary files in the given directory. This -directory is deleted on exit unless --save-temps is specified. If ---save-temps=obj is also specified, --temp-dir is given the -precedence.
      • -
      • --check-graph - Check the compilation for common errors like mismatched -output/input language names, multiple default edges and cycles. Exit with code -zero if no errors were found, and return the number of found errors -otherwise. Hidden option, useful for debugging.
      • -
      • --view-graph - Show a graphical representation of the compilation graph -and exit. Requires that you have dot and gv programs installed. Hidden -option, useful for debugging.
      • -
      • --write-graph - Write a compilation-graph.dot file in the current -directory with the compilation graph description in Graphviz format (identical -to the file used by the --view-graph option). The -o option can be -used to set the output file name. Hidden option, useful for debugging.
      • -
      • --help, --help-hidden, --version - These options have -their standard meaning.
      • -
      -
      -
      -

      Compiling LLVMC-based drivers

      -

      It's easiest to start working on your own LLVMC driver by copying the skeleton -project which lives under $LLVMC_DIR/examples/Skeleton:

      -
      -$ cd $LLVMC_DIR/examples
      -$ cp -r Skeleton MyDriver
      -$ cd MyDriver
      -$ ls
      -AutoGenerated.td  Hooks.cpp  Main.cpp  Makefile
      -
      -

      As you can see, our basic driver consists of only three files (not counting the -build script). AutoGenerated.td contains TableGen description of the -compilation graph; its format is documented in the following -sections. Hooks.cpp is an empty file that should be used for hook -definitions (see below). Main.cpp is just a helper used to compile the -auto-generated C++ code produced from TableGen source.

      -

      The first thing that you should do is to change the LLVMC_BASED_DRIVER -variable in the Makefile:

      -
      -LLVMC_BASED_DRIVER=MyDriver
      -
      -

      It can also be a good idea to put your TableGen code into a file with a less -generic name:

      -
      -$ touch MyDriver.td
      -$ vim AutoGenerated.td
      -[...]
      -include "MyDriver.td"
      -
      -

      If you have more than one TableGen source file, they all should be included from -AutoGenerated.td, since this file is used by the build system to generate -C++ code.

      -

      To build your driver, just cd to its source directory and run make. The -resulting executable will be put into $LLVM_OBJ_DIR/$(BuildMode)/bin.

      -

      If you're compiling LLVM with different source and object directories, then you -must perform the following additional steps before running make:

      -
      -# LLVMC_SRC_DIR = $LLVM_SRC_DIR/tools/llvmc/
      -# LLVMC_OBJ_DIR = $LLVM_OBJ_DIR/tools/llvmc/
      -$ mkdir $LLVMC_OBJ_DIR/examples/MyDriver/
      -$ cp $LLVMC_SRC_DIR/examples/MyDriver/Makefile \
      -  $LLVMC_OBJ_DIR/examples/MyDriver/
      -$ cd $LLVMC_OBJ_DIR/examples/MyDriver
      -$ make
      -
      -
      -
      -

      Customizing LLVMC: the compilation graph

      -

      Each TableGen configuration file should include the common definitions:

      -
      -include "llvm/CompilerDriver/Common.td"
      -
      -

      Internally, LLVMC stores information about possible source transformations in -form of a graph. Nodes in this graph represent tools, and edges between two -nodes represent a transformation path. A special "root" node is used to mark -entry points for the transformations. LLVMC also assigns a weight to each edge -(more on this later) to choose between several alternative edges.

      -

      The definition of the compilation graph (see file llvmc/src/Base.td for an -example) is just a list of edges:

      -
      -def CompilationGraph : CompilationGraph<[
      -    Edge<"root", "llvm_gcc_c">,
      -    Edge<"root", "llvm_gcc_assembler">,
      -    ...
      -
      -    Edge<"llvm_gcc_c", "llc">,
      -    Edge<"llvm_gcc_cpp", "llc">,
      -    ...
      -
      -    OptionalEdge<"llvm_gcc_c", "opt", (case (switch_on "opt"),
      -                                      (inc_weight))>,
      -    OptionalEdge<"llvm_gcc_cpp", "opt", (case (switch_on "opt"),
      -                                              (inc_weight))>,
      -    ...
      -
      -    OptionalEdge<"llvm_gcc_assembler", "llvm_gcc_cpp_linker",
      -        (case (input_languages_contain "c++"), (inc_weight),
      -              (or (parameter_equals "linker", "g++"),
      -                  (parameter_equals "linker", "c++")), (inc_weight))>,
      -    ...
      -
      -    ]>;
      -
      -

      As you can see, the edges can be either default or optional, where optional -edges are differentiated by an additional case expression used to calculate -the weight of this edge. Notice also that we refer to tools via their names (as -strings). This makes it possible to add edges to an existing compilation graph -without having to know about all tool definitions used in the graph.

      -

      The default edges are assigned a weight of 1, and optional edges get a weight of -0 + 2*N where N is the number of tests that evaluated to true in the case -expression. It is also possible to provide an integer parameter to -inc_weight and dec_weight - in this case, the weight is increased (or -decreased) by the provided value instead of the default 2. Default weight of an -optional edge can be changed by using the default clause of the case -construct.

      -

      When passing an input file through the graph, LLVMC picks the edge with the -maximum weight. To avoid ambiguity, there should be only one default edge -between two nodes (with the exception of the root node, which gets a special -treatment - there you are allowed to specify one default edge per language).

      -

      When multiple compilation graphs are defined, they are merged together. Multiple -edges with the same end nodes are not allowed (i.e. the graph is not a -multigraph), and will lead to a compile-time error.

      -

      To get a visual representation of the compilation graph (useful for debugging), -run llvmc --view-graph. You will need dot and gsview installed for -this to work properly.

      -
      -
      -

      Describing options

      -

      Command-line options supported by the driver are defined by using an -OptionList:

      -
      -def Options : OptionList<[
      -(switch_option "E", (help "Help string")),
      -(alias_option "quiet", "q")
      -...
      -]>;
      -
      -

      As you can see, the option list is just a list of DAGs, where each DAG is an -option description consisting of the option name and some properties. More than -one option list can be defined (they are all merged together in the end), which -can be handy if one wants to separate option groups syntactically.

      -
        -
      • Possible option types:

        -
        -
          -
        • switch_option - a simple boolean switch without arguments, for example --O2 or -time. At most one occurrence is allowed by default.
        • -
        • parameter_option - option that takes one argument, for example --std=c99. It is also allowed to use spaces instead of the equality -sign: -std c99. At most one occurrence is allowed.
        • -
        • parameter_list_option - same as the above, but more than one option -occurrence is allowed.
        • -
        • prefix_option - same as the parameter_option, but the option name and -argument do not have to be separated. Example: -ofile. This can be also -specified as -o file; however, -o=file will be parsed incorrectly -(=file will be interpreted as option value). At most one occurrence is -allowed.
        • -
        • prefix_list_option - same as the above, but more than one occurrence of -the option is allowed; example: -lm -lpthread.
        • -
        • alias_option - a special option type for creating aliases. Unlike other -option types, aliases are not allowed to have any properties besides the -aliased option name. -Usage example: (alias_option "preprocess", "E")
        • -
        • switch_list_option - like switch_option with the zero_or_more -property, but remembers how many times the switch was turned on. Useful -mostly for forwarding. Example: when -foo is a switch option (with the -zero_or_more property), the command driver -foo -foo is forwarded -as some-tool -foo, but when -foo is a switch list, the same command -is forwarded as some-tool -foo -foo.
        • -
        -
        -
      • -
      • Possible option properties:

        -
        -
          -
        • help - help string associated with this option. Used for --help -output.
        • -
        • required - this option must be specified exactly once (or, in case of -the list options without the multi_val property, at least -once). Incompatible with optional and one_or_more.
        • -
        • optional - the option can be specified either zero times or exactly -once. The default for switch options. Useful only for list options in -conjunction with multi_val. Incompatible with required, -zero_or_more and one_or_more.
        • -
        • one_or_more - the option must be specified at least once. Can be useful -to allow switch options be both obligatory and be specified multiple -times. For list options is useful only in conjunction with multi_val; -for ordinary it is synonymous with required. Incompatible with -required, optional and zero_or_more.
        • -
        • zero_or_more - the option can be specified zero or more times. Useful -to allow a single switch option to be specified more than -once. Incompatible with required, optional and one_or_more.
        • -
        • hidden - the description of this option will not appear in -the --help output (but will appear in the --help-hidden -output).
        • -
        • really_hidden - the option will not be mentioned in any help -output.
        • -
        • comma_separated - Indicates that any commas specified for an option's -value should be used to split the value up into multiple values for the -option. This property is valid only for list options. In conjunction with -forward_value can be used to implement option forwarding in style of -gcc's -Wa,.
        • -
        • multi_val n - this option takes n arguments (can be useful in some -special cases). Usage example: (parameter_list_option "foo", (multi_val -3)); the command-line syntax is '-foo a b c'. Only list options can have -this attribute; you can, however, use the one_or_more, optional -and required properties.
        • -
        • init - this option has a default value, either a string (if it is a -parameter), or a boolean (if it is a switch; as in C++, boolean constants -are called true and false). List options can't have init -attribute. -Usage examples: (switch_option "foo", (init true)); (prefix_option -"bar", (init "baz")).
        • -
        -
        -
      • -
      -
      -
      -

      Conditional evaluation

      -

      The 'case' construct is the main means by which programmability is achieved in -LLVMC. It can be used to calculate edge weights, program actions and modify the -shell commands to be executed. The 'case' expression is designed after the -similarly-named construct in functional languages and takes the form (case -(test_1), statement_1, (test_2), statement_2, ... (test_N), statement_N). The -statements are evaluated only if the corresponding tests evaluate to true.

      -

      Examples:

      -
      -// Edge weight calculation
      -
      -// Increases edge weight by 5 if "-A" is provided on the
      -// command-line, and by 5 more if "-B" is also provided.
      -(case
      -    (switch_on "A"), (inc_weight 5),
      -    (switch_on "B"), (inc_weight 5))
      -
      -
      -// Tool command line specification
      -
      -// Evaluates to "cmdline1" if the option "-A" is provided on the
      -// command line; to "cmdline2" if "-B" is provided;
      -// otherwise to "cmdline3".
      -
      -(case
      -    (switch_on "A"), "cmdline1",
      -    (switch_on "B"), "cmdline2",
      -    (default), "cmdline3")
      -
      -

      Note the slight difference in 'case' expression handling in contexts of edge -weights and command line specification - in the second example the value of the -"B" switch is never checked when switch "A" is enabled, and the whole -expression always evaluates to "cmdline1" in that case.

      -

      Case expressions can also be nested, i.e. the following is legal:

      -
      -(case (switch_on "E"), (case (switch_on "o"), ..., (default), ...)
      -      (default), ...)
      -
      -

      You should, however, try to avoid doing that because it hurts readability. It is -usually better to split tool descriptions and/or use TableGen inheritance -instead.

      -
        -
      • Possible tests are:
          -
        • switch_on - Returns true if a given command-line switch is provided by -the user. Can be given multiple arguments, in that case (switch_on "foo", -"bar", "baz") is equivalent to (and (switch_on "foo"), (switch_on -"bar"), (switch_on "baz")). -Example: (switch_on "opt").
        • -
        • any_switch_on - Given a number of switch options, returns true if any of -the switches is turned on. -Example: (any_switch_on "foo", "bar", "baz") is equivalent to (or -(switch_on "foo"), (switch_on "bar"), (switch_on "baz")).
        • -
        • parameter_equals - Returns true if a command-line parameter (first -argument) equals a given value (second argument). -Example: (parameter_equals "W", "all").
        • -
        • element_in_list - Returns true if a command-line parameter list (first -argument) contains a given value (second argument). -Example: (element_in_list "l", "pthread").
        • -
        • input_languages_contain - Returns true if a given language -belongs to the current input language set. -Example: (input_languages_contain "c++").
        • -
        • in_language - Evaluates to true if the input file language is equal to -the argument. At the moment works only with command and actions (on -non-join nodes). -Example: (in_language "c++").
        • -
        • not_empty - Returns true if a given option (which should be either a -parameter or a parameter list) is set by the user. Like switch_on, can -be also given multiple arguments. -Examples: (not_empty "o"), (not_empty "o", "l").
        • -
        • any_not_empty - Returns true if not_empty returns true for any of -the provided options. -Example: (any_not_empty "foo", "bar", "baz") is equivalent to (or -(not_empty "foo"), (not_empty "bar"), (not_empty "baz")).
        • -
        • empty - The opposite of not_empty. Equivalent to (not (not_empty -X)). Can be given multiple arguments.
        • -
        • any_not_empty - Returns true if not_empty returns true for any of -the provided options. -Example: (any_empty "foo", "bar", "baz") is equivalent to (or -(not_empty "foo"), (not_empty "bar"), (not_empty "baz")).
        • -
        • single_input_file - Returns true if there was only one input file -provided on the command-line. Used without arguments: -(single_input_file).
        • -
        • multiple_input_files - Equivalent to (not (single_input_file)) (the -case of zero input files is considered an error).
        • -
        • default - Always evaluates to true. Should always be the last -test in the case expression.
        • -
        • and - A standard logical combinator that returns true iff all of -its arguments return true. Used like this: (and (test1), (test2), -... (testN)). Nesting of and and or is allowed, but not -encouraged.
        • -
        • or - A logical combinator that returns true iff any of its arguments -return true. -Example: (or (test1), (test2), ... (testN)).
        • -
        • not - Standard unary logical combinator that negates its -argument. -Example: (not (or (test1), (test2), ... (testN))).
        • -
        -
      • -
      -
      -
      -

      Writing a tool description

      -

      As was said earlier, nodes in the compilation graph represent tools, which are -described separately. A tool definition looks like this (taken from the -llvmc/src/Base.td file):

      -
      -def llvm_gcc_cpp : Tool<[
      -    (in_language "c++"),
      -    (out_language "llvm-assembler"),
      -    (output_suffix "bc"),
      -    (command "llvm-g++ -c -emit-llvm"),
      -    (sink)
      -    ]>;
      -
      -

      This defines a new tool called llvm_gcc_cpp, which is an alias for -llvm-g++. As you can see, a tool definition is just a list of properties; -most of them should be self-explanatory. The sink property means that this -tool should be passed all command-line options that aren't mentioned in the -option list.

      -

      The complete list of all currently implemented tool properties follows.

      -
        -
      • Possible tool properties:
          -
        • in_language - input language name. Can be given multiple arguments, in -case the tool supports multiple input languages. Used for typechecking and -mapping file extensions to tools.
        • -
        • out_language - output language name. Multiple output languages are -allowed. Used for typechecking the compilation graph.
        • -
        • output_suffix - output file suffix. Can also be changed dynamically, see -documentation on actions.
        • -
        -
      • -
      -
      -
        -
      • command - the actual command used to run the tool. You can use output -redirection with >, hook invocations ($CALL), environment variables -(via $ENV) and the case construct.
      • -
      • join - this tool is a "join node" in the graph, i.e. it gets a list of -input files and joins them together. Used for linkers.
      • -
      • sink - all command-line options that are not handled by other tools are -passed to this tool.
      • -
      • actions - A single big case expression that specifies how this tool -reacts on command-line options (described in more detail below).
      • -
      -
      -
      -
        -
      • out_file_option, in_file_option - Options appended to the -command string to designate output and input files. Default values are -"-o" and "", respectively.
      • -
      -
      -
      -

      Actions

      -

      A tool often needs to react to command-line options, and this is precisely what -the actions property is for. The next example illustrates this feature:

      -
      -def llvm_gcc_linker : Tool<[
      -    (in_language "object-code"),
      -    (out_language "executable"),
      -    (output_suffix "out"),
      -    (command "llvm-gcc"),
      -    (join),
      -    (actions (case (not_empty "L"), (forward "L"),
      -                   (not_empty "l"), (forward "l"),
      -                   (not_empty "dummy"),
      -                             [(append_cmd "-dummy1"), (append_cmd "-dummy2")])
      -    ]>;
      -
      -

      The actions tool property is implemented on top of the omnipresent case -expression. It associates one or more different actions with given -conditions - in the example, the actions are forward, which forwards a given -option unchanged, and append_cmd, which appends a given string to the tool -execution command. Multiple actions can be associated with a single condition by -using a list of actions (used in the example to append some dummy options). The -same case construct can also be used in the cmd_line property to modify -the tool command line.

      -

      The "join" property used in the example means that this tool behaves like a -linker.

      -

      The list of all possible actions follows.

      -
        -
      • Possible actions:

        -
        -
          -
        • append_cmd - Append a string to the tool invocation command. -Example: (case (switch_on "pthread"), (append_cmd "-lpthread")).
        • -
        • error - Exit with error. -Example: (error "Mixing -c and -S is not allowed!").
        • -
        • warning - Print a warning. -Example: (warning "Specifying both -O1 and -O2 is meaningless!").
        • -
        • forward - Forward the option unchanged. -Example: (forward "Wall").
        • -
        • forward_as - Change the option's name, but forward the argument -unchanged. -Example: (forward_as "O0", "--disable-optimization").
        • -
        • forward_value - Forward only option's value. Cannot be used with switch -options (since they don't have values), but works fine with lists. -Example: (forward_value "Wa,").
        • -
        • forward_transformed_value - As above, but applies a hook to the -option's value before forwarding (see below). When -forward_transformed_value is applied to a list -option, the hook must have signature -std::string hooks::HookName (const std::vector<std::string>&). -Example: (forward_transformed_value "m", "ConvertToMAttr").
        • -
        • output_suffix - Modify the output suffix of this tool. -Example: (output_suffix "i").
        • -
        • stop_compilation - Stop compilation after this tool processes its -input. Used without arguments. -Example: (stop_compilation).
        • -
        -
        -
      • -
      -
      -
      -
      -

      Language map

      -

      If you are adding support for a new language to LLVMC, you'll need to modify the -language map, which defines mappings from file extensions to language names. It -is used to choose the proper toolchain(s) for a given input file set. Language -map definition looks like this:

      -
      -def LanguageMap : LanguageMap<
      -    [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>,
      -     LangToSuffixes<"c", ["c"]>,
      -     ...
      -    ]>;
      -
      -

      For example, without those definitions the following command wouldn't work:

      -
      -$ llvmc hello.cpp
      -llvmc: Unknown suffix: cpp
      -
      -

      The language map entries are needed only for the tools that are linked from the -root node. A tool can have multiple output languages.

      -
      -
      -

      Option preprocessor

      -

      It is sometimes useful to run error-checking code before processing the -compilation graph. For example, if optimization options "-O1" and "-O2" are -implemented as switches, we might want to output a warning if the user invokes -the driver with both of these options enabled.

      -

      The OptionPreprocessor feature is reserved specially for these -occasions. Example (adapted from llvm/src/Base.td.in):

      -
      -def Preprocess : OptionPreprocessor<
      -(case (not (any_switch_on "O0", "O1", "O2", "O3")),
      -           (set_option "O2"),
      -      (and (switch_on "O3"), (any_switch_on "O0", "O1", "O2")),
      -           (unset_option "O0", "O1", "O2"),
      -      (and (switch_on "O2"), (any_switch_on "O0", "O1")),
      -           (unset_option "O0", "O1"),
      -      (and (switch_on "O1"), (switch_on "O0")),
      -           (unset_option "O0"))
      ->;
      -
      -

      Here, OptionPreprocessor is used to unset all spurious -O options so -that they are not forwarded to the compiler. If no optimization options are -specified, -O2 is enabled.

      -

      OptionPreprocessor is basically a single big case expression, which is -evaluated only once right after the driver is started. The only allowed actions -in OptionPreprocessor are error, warning, and two special actions: -unset_option and set_option. As their names suggest, they can be used to -set or unset a given option. To set an option with set_option, use the -two-argument form: (set_option "parameter", VALUE). Here, VALUE can be -either a string, a string list, or a boolean constant.

      -

      For convenience, set_option and unset_option also work with multiple -arguments. That is, instead of [(unset_option "A"), (unset_option "B")] you -can use (unset_option "A", "B"). Obviously, (set_option "A", "B") is -only valid if both A and B are switches.

      -
      -
      -

      More advanced topics

      -
      -

      Hooks and environment variables

      -

      Normally, LLVMC searches for programs in the system PATH. Sometimes, this is -not sufficient: for example, we may want to specify tool paths or names in the -configuration file. This can be achieved via the hooks mechanism. To write your -own hooks, add their definitions to the Hooks.cpp or drop a .cpp file -into your driver directory. Hooks should live in the hooks namespace and -have the signature std::string hooks::MyHookName ([const char* Arg0 [ const -char* Arg2 [, ...]]]). They can be used from the command tool property:

      -
      -(command "$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)")
      -
      -

      To pass arguments to hooks, use the following syntax:

      -
      -(command "$CALL(MyHook, 'Arg1', 'Arg2', 'Arg # 3')/path/to/file -o1 -o2")
      -
      -

      It is also possible to use environment variables in the same manner:

      -
      -(command "$ENV(VAR1)/path/to/file -o $ENV(VAR2)")
      -
      -

      To change the command line string based on user-provided options use -the case expression (documented above):

      -
      -(command
      -  (case
      -    (switch_on "E"),
      -       "llvm-g++ -E -x c $INFILE -o $OUTFILE",
      -    (default),
      -       "llvm-g++ -c -x c $INFILE -o $OUTFILE -emit-llvm"))
      -
      -
      -
      -

      Debugging

      -

      When writing LLVMC-based drivers, it can be useful to get a visual view of the -resulting compilation graph. This can be achieved via the command line option ---view-graph (which assumes that Graphviz and Ghostview are -installed). There is also a --write-graph option that creates a Graphviz -source file (compilation-graph.dot) in the current directory.

      -

      Another useful llvmc option is --check-graph. It checks the compilation -graph for common errors like mismatched output/input language names, multiple -default edges and cycles. When invoked with --check-graph, llvmc doesn't -perform any compilation tasks and returns the number of encountered errors as -its status code. In the future, these checks will be performed at compile-time -and this option will disappear.

      -
      -
      -

      Conditioning on the executable name

      -

      For now, the executable name (the value passed to the driver in argv[0]) is -accessible only in the C++ code (i.e. hooks). Use the following code:

      -
      -namespace llvmc {
      -extern const char* ProgramName;
      -}
      -
      -namespace hooks {
      -
      -std::string MyHook() {
      -//...
      -if (strcmp(ProgramName, "mydriver") == 0) {
      -   //...
      -
      -}
      -
      -} // end namespace hooks
      -
      -

      In general, you're encouraged not to make the behaviour dependent on the -executable file name, and use command-line switches instead. See for example how -the llvmc program behaves when it needs to choose the correct linker options -(think g++ vs. gcc).

      -
      -
      - -Valid CSS - -Valid XHTML 1.0 Transitional - -Mikhail Glushenkov
      -LLVM Compiler Infrastructure
      - -Last modified: $Date: 2011-05-07 00:11:29 +0200 (Sat, 07 May 2011) $ -
      -
      -
      - - diff --git a/docs/CompilerDriverTutorial.html b/docs/CompilerDriverTutorial.html deleted file mode 100644 index 4ed373aa160a..000000000000 --- a/docs/CompilerDriverTutorial.html +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - -Tutorial - Using LLVMC - - - -
      -

      Tutorial - Using LLVMC

      - - - -
      -

      Written by Mikhail Glushenkov

      -
      -

      Introduction

      -

      LLVMC is a generic compiler driver, which plays the same role for LLVM as the -gcc program does for GCC - the difference being that LLVMC is designed to be -more adaptable and easier to customize. Most of LLVMC functionality is -implemented via high-level TableGen code, from which a corresponding C++ source -file is automatically generated. This tutorial describes the basic usage and -configuration of LLVMC.

      -
      -
      -

      Using the llvmc program

      -

      In general, llvmc tries to be command-line compatible with gcc as much -as possible, so most of the familiar options work:

      -
      -$ llvmc -O3 -Wall hello.cpp
      -$ ./a.out
      -hello
      -
      -

      This will invoke llvm-g++ under the hood (you can see which commands are -executed by using the -v option). For further help on command-line LLVMC -usage, refer to the llvmc --help output.

      -
      -
      -

      Using LLVMC to generate toolchain drivers

      -

      LLVMC-based drivers are written mostly using TableGen, so you need to be -familiar with it to get anything done.

      -

      Start by compiling example/Simple, which is a primitive wrapper for -gcc:

      -
      -$ cd $LLVM_OBJ_DIR/tools/examples/Simple
      -$ make
      -$ cat > hello.c
      -#include <stdio.h>
      -int main() { printf("Hello\n"); }
      -$ $LLVM_BIN_DIR/Simple -v hello.c
      -gcc hello.c -o hello.out
      -$ ./hello.out
      -Hello
      -
      -

      We have thus produced a simple driver called, appropriately, Simple, from -the input TableGen file Simple.td. The llvmc program itself is generated -using a similar process (see llvmc/src). Contents of the file Simple.td -look like this:

      -
      -// Include common definitions
      -include "llvm/CompilerDriver/Common.td"
      -
      -// Tool descriptions
      -def gcc : Tool<
      -[(in_language "c"),
      - (out_language "executable"),
      - (output_suffix "out"),
      - (command "gcc"),
      - (sink),
      -
      - // -o is what is used by default, out_file_option here is included for
      - // instructive purposes.
      - (out_file_option "-o")
      -]>;
      -
      -// Language map
      -def LanguageMap : LanguageMap<[(lang_to_suffixes "c", "c")]>;
      -
      -// Compilation graph
      -def CompilationGraph : CompilationGraph<[(edge "root", "gcc")]>;
      -
      -

      As you can see, this file consists of three parts: tool descriptions, language -map, and the compilation graph definition.

      -

      At the heart of LLVMC is the idea of a compilation graph: vertices in this graph -are tools, and edges represent a transformation path between two tools (for -example, assembly source produced by the compiler can be transformed into -executable code by an assembler). The compilation graph is basically a list of -edges; a special node named root is used to mark graph entry points.

      -

      Tool descriptions are represented as property lists: most properties in the -example above should be self-explanatory; the sink property means that all -options lacking an explicit description should be forwarded to this tool.

      -

      The LanguageMap associates a language name with a list of suffixes and is -used for deciding which toolchain corresponds to a given input file.

      -

      To learn more about writing your own drivers with LLVMC, refer to the reference -manual and examples in the examples directory. Of a particular interest is -the Skeleton example, which can serve as a template for your LLVMC-based -drivers.

      -
      -
      - -Valid CSS - -Valid XHTML 1.0 Transitional - -Mikhail Glushenkov
      -LLVM Compiler Infrastructure
      - -Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $ -
      -
      - - diff --git a/docs/DeveloperPolicy.html b/docs/DeveloperPolicy.html index c12165750668..7c78016693f7 100644 --- a/docs/DeveloperPolicy.html +++ b/docs/DeveloperPolicy.html @@ -207,7 +207,11 @@
    • Chris Lattner: Everything not covered by someone else.
    • -
    • Duncan Sands: llvm-gcc 4.2.
    • +
    • John McCall: Clang LLVM IR generation.
    • + +
    • Jakob Olesen: Register allocators and TableGen.
    • + +
    • Duncan Sands: dragonegg and llvm-gcc 4.2.
    • Note that code ownership is completely different than reviewers: anyone can @@ -492,8 +496,9 @@

      This section addresses the issues of copyright, license and patents for the - LLVM project. Currently, the University of Illinois is the LLVM copyright - holder and the terms of its license to LLVM users and developers is the + LLVM project. The copyright holder for the code is held by the individual + contributors of the code and the terms of its license to LLVM users and + developers is the University of Illinois/NCSA Open Source License.

      @@ -611,7 +616,7 @@ Written by the LLVM Oversight Group
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-10-07 19:26:38 +0200 (Fri, 07 Oct 2011) $ diff --git a/docs/ExceptionHandling.html b/docs/ExceptionHandling.html index c0f50e33382a..85ab796938e7 100644 --- a/docs/ExceptionHandling.html +++ b/docs/ExceptionHandling.html @@ -33,9 +33,6 @@
    • Exception Handling Intrinsics
        -
      1. llvm.eh.exception
      2. -
      3. llvm.eh.selector
      4. -
      5. llvm.eh.resume
      6. llvm.eh.typeid.for
      7. llvm.eh.sjlj.setjmp
      8. llvm.eh.sjlj.longjmp
      9. @@ -48,7 +45,6 @@
      10. Exception Handling Frame
      11. Exception Tables
    • -
    • ToDo
    @@ -69,7 +65,7 @@ handling information takes, which is useful for those interested in creating front-ends or dealing directly with the information. Further, this document provides specific examples of what exception handling information is used for - in C/C++.

    + in C and C++.

    @@ -96,8 +92,8 @@ Exception Handling. A description of the exception frame format can be found at Exception - Frames, with details of the DWARF 3 specification at - DWARF 3 Standard. + Frames, with details of the DWARF 4 specification at + DWARF 4 Standard. A description for the C++ exception table formats can be found at Exception Handling Tables.

    @@ -116,10 +112,10 @@ llvm.eh.sjlj.longjmp to handle control flow for exception handling.

    -

    For each function which does exception processing, be it try/catch blocks - or cleanups, that function registers itself on a global frame list. When - exceptions are being unwound, the runtime uses this list to identify which - functions need processing.

    +

    For each function which does exception processing — be + it try/catch blocks or cleanups — that function + registers itself on a global frame list. When exceptions are unwinding, the + runtime uses this list to identify which functions need processing.

    Landing pad selection is encoded in the call site entry of the function context. The runtime returns to the function via @@ -134,6 +130,7 @@ exceptions are thrown. As exceptions are, by their nature, intended for uncommon code paths, DWARF exception handling is generally preferred to SJLJ.

    + @@ -148,19 +145,19 @@

    The runtime first attempts to find an exception frame corresponding to the function where the exception was thrown. If the programming language - (e.g. C++) supports exception handling, the exception frame contains a + supports exception handling (e.g. C++), the exception frame contains a reference to an exception table describing how to process the exception. If - the language (e.g. C) does not support exception handling, or if the + the language does not support exception handling (e.g. C), or if the exception needs to be forwarded to a prior activation, the exception frame contains information about how to unwind the current activation and restore the state of the prior activation. This process is repeated until the - exception is handled. If the exception is not handled and no activations + exception is handled. If the exception is not handled and no activations remain, then the application is terminated with an appropriate error message.

    Because different programming languages have different behaviors when handling exceptions, the exception handling ABI provides a mechanism for - supplying personalities. An exception handling personality is defined + supplying personalities. An exception handling personality is defined by way of a personality function (e.g. __gxx_personality_v0 in C++), which receives the context of the exception, an exception structure containing the exception object type and value, and a reference @@ -168,19 +165,20 @@ for the current compile unit is specified in a common exception frame.

    -

    The organization of an exception table is language dependent. For C++, an +

    The organization of an exception table is language dependent. For C++, an exception table is organized as a series of code ranges defining what to do - if an exception occurs in that range. Typically, the information associated + if an exception occurs in that range. Typically, the information associated with a range defines which types of exception objects (using C++ type info) that are handled in that range, and an associated action that - should take place. Actions typically pass control to a landing + should take place. Actions typically pass control to a landing pad.

    -

    A landing pad corresponds to the code found in the catch portion of - a try/catch sequence. When execution resumes at a landing - pad, it receives the exception structure and a selector corresponding to - the type of exception thrown. The selector is then used to determine - which catch should actually process the exception.

    +

    A landing pad corresponds roughly to the code found in the catch + portion of a try/catch sequence. When execution resumes at + a landing pad, it receives an exception structure and a + selector value corresponding to the type of exception + thrown. The selector is then used to determine which catch should + actually process the exception.

    @@ -193,11 +191,8 @@
    -

    At the time of this writing, only C++ exception handling support is available - in LLVM. So the remainder of this document will be somewhat C++-centric.

    - -

    From the C++ developers perspective, exceptions are defined in terms of the - throw and try/catch statements. In this section +

    From a C++ developer's perspective, exceptions are defined in terms of the + throw and try/catch statements. In this section we will describe the implementation of LLVM exception handling in terms of C++ examples.

    @@ -209,17 +204,22 @@

    Languages that support exception handling typically provide a throw - operation to initiate the exception process. Internally, a throw operation - breaks down into two steps. First, a request is made to allocate exception - space for an exception structure. This structure needs to survive beyond the - current activation. This structure will contain the type and value of the - object being thrown. Second, a call is made to the runtime to raise the - exception, passing the exception structure as an argument.

    + operation to initiate the exception process. Internally, a throw + operation breaks down into two steps.

    -

    In C++, the allocation of the exception structure is done by - the __cxa_allocate_exception runtime function. The exception - raising is handled by __cxa_throw. The type of the exception is - represented using a C++ RTTI structure.

    +
      +
    1. A request is made to allocate exception space for an exception structure. + This structure needs to survive beyond the current activation. This + structure will contain the type and value of the object being thrown.
    2. + +
    3. A call is made to the runtime to raise the exception, passing the + exception structure as an argument.
    4. +
    + +

    In C++, the allocation of the exception structure is done by the + __cxa_allocate_exception runtime function. The exception raising is + handled by __cxa_throw. The type of the exception is represented + using a C++ RTTI structure.

    @@ -231,81 +231,68 @@

    A call within the scope of a try statement can potentially raise an - exception. In those circumstances, the LLVM C++ front-end replaces the call - with an invoke instruction. Unlike a call, the invoke has - two potential continuation points: where to continue when the call succeeds - as per normal; and where to continue if the call raises an exception, either - by a throw or the unwinding of a throw.

    + exception. In those circumstances, the LLVM C++ front-end replaces the call + with an invoke instruction. Unlike a call, the invoke has + two potential continuation points:

    + +
      +
    1. where to continue when the call succeeds as per normal, and
    2. + +
    3. where to continue if the call raises an exception, either by a throw or + the unwinding of a throw
    4. +

    The term used to define a the place where an invoke continues after - an exception is called a landing pad. LLVM landing pads are + an exception is called a landing pad. LLVM landing pads are conceptually alternative function entry points where an exception structure - reference and a type info index are passed in as arguments. The landing pad + reference and a type info index are passed in as arguments. The landing pad saves the exception structure reference and then proceeds to select the catch block that corresponds to the type info of the exception object.

    -

    Two LLVM intrinsic functions are used to convey information about the landing - pad to the back end.

    +

    The LLVM landingpad + instruction is used to convey information about the landing pad to the + back end. For C++, the landingpad instruction returns a pointer and + integer pair corresponding to the pointer to the exception structure + and the selector value respectively.

    -
      -
    1. llvm.eh.exception takes no - arguments and returns a pointer to the exception structure. This only - returns a sensible value if called after an invoke has branched - to a landing pad. Due to code generation limitations, it must currently - be called in the landing pad itself.
    2. - -
    3. llvm.eh.selector takes a minimum - of three arguments. The first argument is the reference to the exception - structure. The second argument is a reference to the personality function - to be used for this try/catch sequence. Each of the - remaining arguments is either a reference to the type info for - a catch statement, a filter - expression, or the number zero (0) representing - a cleanup. The exception is tested against the - arguments sequentially from first to last. The result of - the llvm.eh.selector is a - positive number if the exception matched a type info, a negative number if - it matched a filter, and zero if it matched a cleanup. If nothing is - matched, the behaviour of the program - is undefined. This only returns a sensible - value if called after an invoke has branched to a landing pad. - Due to codegen limitations, it must currently be called in the landing pad - itself. If a type info matched, then the selector value is the index of - the type info in the exception table, which can be obtained using the - llvm.eh.typeid.for - intrinsic.
    4. -
    +

    The landingpad instruction takes a reference to the personality + function to be used for this try/catch sequence. The + remainder of the instruction is a list of cleanup, catch, + and filter clauses. The exception is tested against the clauses + sequentially from first to last. The selector value is a positive number if + the exception matched a type info, a negative number if it matched a filter, + and zero if it matched a cleanup. If nothing is matched, the behavior of + the program is undefined. If a type info matched, + then the selector value is the index of the type info in the exception table, + which can be obtained using the + llvm.eh.typeid.for intrinsic.

    Once the landing pad has the type info selector, the code branches to the - code for the first catch. The catch then checks the value of the type info + code for the first catch. The catch then checks the value of the type info selector against the index of type info for that catch. Since the type info - index is not known until all the type info have been gathered in the backend, - the catch code will call the - llvm.eh.typeid.for intrinsic - to determine the index for a given type info. If the catch fails to match - the selector then control is passed on to the next catch. Note: Since the - landing pad will not be used if there is no match in the list of type info on - the call to llvm.eh.selector, then - neither the last catch nor catch all need to perform the check - against the selector.

    + index is not known until all the type infos have been gathered in the + backend, the catch code must call the + llvm.eh.typeid.for intrinsic to + determine the index for a given type info. If the catch fails to match the + selector then control is passed on to the next catch.

    -

    Finally, the entry and exit of catch code is bracketed with calls - to __cxa_begin_catch and __cxa_end_catch.

    +

    Finally, the entry and exit of catch code is bracketed with calls to + __cxa_begin_catch and __cxa_end_catch.

      -
    • __cxa_begin_catch takes a exception structure reference as an +
    • __cxa_begin_catch takes an exception structure reference as an argument and returns the value of the exception object.
    • __cxa_end_catch takes no arguments. This function:

      1. Locates the most recently caught exception and decrements its handler count,
      2. -
      3. Removes the exception from the "caught" stack if the handler count - goes to zero, and
      4. -
      5. Destroys the exception if the handler count goes to zero, and the +
      6. Removes the exception from the caught stack if the handler + count goes to zero, and
      7. +
      8. Destroys the exception if the handler count goes to zero and the exception was not re-thrown by throw.
      -

      Note: a rethrow from within the catch may replace this call with +

      Note: a rethrow from within the catch may replace this call with a __cxa_rethrow.

    @@ -318,28 +305,26 @@
    -

    A cleanup is extra code which needs to be run as part of unwinding - a scope. C++ destructors are a prominent example, but other - languages and language extensions provide a variety of different - kinds of cleanup. In general, a landing pad may need to run - arbitrary amounts of cleanup code before actually entering a catch - block. To indicate the presence of cleanups, a landing pad's call - to llvm.eh.selector should - end with the argument i32 0; otherwise, the unwinder will - not stop at the landing pad if there are no catches or filters that - require it to.

    +

    A cleanup is extra code which needs to be run as part of unwinding a scope. + C++ destructors are a typical example, but other languages and language + extensions provide a variety of different kinds of cleanups. In general, a + landing pad may need to run arbitrary amounts of cleanup code before actually + entering a catch block. To indicate the presence of cleanups, a + landingpad instruction + should have a cleanup clause. Otherwise, the unwinder will not stop at + the landing pad if there are no catches or filters that require it to.

    -

    Do not allow a new exception to propagate out of the execution of a - cleanup. This can corrupt the internal state of the unwinder. - Different languages describe different high-level semantics for - these situations: for example, C++ requires that the process be - terminated, whereas Ada cancels both exceptions and throws a third.

    +

    Note: Do not allow a new exception to propagate out of the execution + of a cleanup. This can corrupt the internal state of the unwinder. + Different languages describe different high-level semantics for these + situations: for example, C++ requires that the process be terminated, whereas + Ada cancels both exceptions and throws a third.

    -

    When all cleanups have completed, if the exception is not handled - by the current function, resume unwinding by calling the - llvm.eh.resume intrinsic, - passing in the results of llvm.eh.exception and - llvm.eh.selector for the original landing pad.

    +

    When all cleanups are finished, if the exception is not handled by the + current function, resume unwinding by calling the + resume instruction, passing in + the result of the landingpad instruction for the original landing + pad.

    @@ -350,23 +335,21 @@
    -

    C++ allows the specification of which exception types can be thrown from a - function. To represent this a top level landing pad may exist to filter out - invalid types. To express this in LLVM code the landing pad will - call llvm.eh.selector. The - arguments are a reference to the exception structure, a reference to the - personality function, the length of the filter expression (the number of type - infos plus one), followed by the type infos themselves. - llvm.eh.selector will return a - negative value if the exception does not match any of the type infos. If no - match is found then a call to __cxa_call_unexpected should be made, - otherwise _Unwind_Resume. Each of these functions requires a - reference to the exception structure. Note that the most general form of an - llvm.eh.selector call can contain - any number of type infos, filter expressions and cleanups (though having more - than one cleanup is pointless). The LLVM C++ front-end can generate such - llvm.eh.selector calls due to - inlining creating nested exception handling scopes.

    +

    C++ allows the specification of which exception types may be thrown from a + function. To represent this, a top level landing pad may exist to filter out + invalid types. To express this in LLVM code the + landingpad instruction will + have a filter clause. The clause consists of an array of type infos. + landingpad will return a negative value if the exception does not + match any of the type infos. If no match is found then a call + to __cxa_call_unexpected should be made, otherwise + _Unwind_Resume. Each of these functions requires a reference to the + exception structure. Note that the most general form of a + landingpad instruction can + have any number of catch, cleanup, and filter clauses (though having more + than one cleanup is pointless). The LLVM C++ front-end can generate such + landingpad instructions due + to inlining creating nested exception handling scopes.

    @@ -377,29 +360,23 @@
    -

    The unwinder delegates the decision of whether to stop in a call - frame to that call frame's language-specific personality function. - Not all personalities functions guarantee that they will stop to - perform cleanups: for example, the GNU C++ personality doesn't do - so unless the exception is actually caught somewhere further up the - stack. When using this personality to implement EH for a language - that guarantees that cleanups will always be run, be sure to - indicate a catch-all in the - llvm.eh.selector call - rather than just cleanups.

    +

    The unwinder delegates the decision of whether to stop in a call frame to + that call frame's language-specific personality function. Not all unwinders + guarantee that they will stop to perform cleanups. For example, the GNU C++ + unwinder doesn't do so unless the exception is actually caught somewhere + further up the stack.

    -

    In order for inlining to behave correctly, landing pads must be - prepared to handle selector results that they did not originally - advertise. Suppose that a function catches exceptions of - type A, and it's inlined into a function that catches - exceptions of type B. The inliner will update the - selector for the inlined landing pad to include the fact - that B is caught. If that landing pad assumes that it - will only be entered to catch an A, it's in for a rude - surprise. Consequently, landing pads must test for the selector - results they understand and then resume exception propagation - with the llvm.eh.resume - intrinsic if none of the conditions match.

    +

    In order for inlining to behave correctly, landing pads must be prepared to + handle selector results that they did not originally advertise. Suppose that + a function catches exceptions of type A, and it's inlined into a + function that catches exceptions of type B. The inliner will update + the landingpad instruction for the inlined landing pad to include + the fact that B is also caught. If that landing pad assumes that it + will only be entered to catch an A, it's in for a rude awakening. + Consequently, landing pads must test for the selector results they understand + and then resume exception propagation with the + resume instruction if none of + the conditions match.

    @@ -412,67 +389,13 @@
    -

    LLVM uses several intrinsic functions (name prefixed with "llvm.eh") to +

    In addition to the + landingpad and + resume instructions, LLVM uses + several intrinsic functions (name prefixed with llvm.eh) to provide exception handling information at various points in generated code.

    - -

    - llvm.eh.exception -

    - -
    - -
    -  i8* %llvm.eh.exception()
    -
    - -

    This intrinsic returns a pointer to the exception structure.

    - -
    - - -

    - llvm.eh.selector -

    - -
    - -
    -  i32 %llvm.eh.selector(i8*, i8*, ...)
    -
    - -

    This intrinsic is used to compare the exception with the given type infos, - filters and cleanups.

    - -

    llvm.eh.selector takes a - minimum of three arguments. The first argument is the reference to - the exception structure. The second argument is a reference to the - personality function to be used for this try catch sequence. Each - of the remaining arguments is either a reference to the type info - for a catch statement, a filter - expression, or the number zero representing - a cleanup. The exception is tested against - the arguments sequentially from first to last. The result of - the llvm.eh.selector is a - positive number if the exception matched a type info, a negative - number if it matched a filter, and zero if it matched a cleanup. - If nothing is matched, or if only a cleanup is matched, different - personality functions may or may not cause control to stop at the - landing pad; see the restrictions for - more information. If a type info matched then the selector value - is the index of the type info in the exception table, which can be - obtained using the - llvm.eh.typeid.for intrinsic.

    - -

    If a landing pad containing a call to llvm.eh.selector is - inlined into an invoke instruction, the selector arguments - for the outer landing pad are appended to those of the inlined - landing pad. Consequently, landing pads must be written to ignore - selector values that they did not originally advertise.

    - -
    -

    llvm.eh.typeid.for @@ -481,40 +404,13 @@
    -  i32 %llvm.eh.typeid.for(i8*)
    +  i32 @llvm.eh.typeid.for(i8* %type_info)
     

    This intrinsic returns the type info index in the exception table of the current function. This value can be used to compare against the result - of llvm.eh.selector. The single - argument is a reference to a type info.

    - -
    - - -

    - llvm.eh.resume -

    - -
    - -
    -  void %llvm.eh.resume(i8*, i32) noreturn
    -
    - -

    This intrinsic is used to resume propagation of an exception after - landing at a landing pad. The first argument should be the result - of llvm.eh.exception for that - landing pad, and the second argument should be the result of - llvm.eh.selector. When a call to - this intrinsic is inlined into an invoke, the call is transformed - into a branch to the invoke's unwind destination, using its - arguments in place of the calls - to llvm.eh.exception and - llvm.eh.selector there.

    - -

    This intrinsic is not implicitly nounwind; calls to it - will always throw. It may not be invoked.

    + of landingpad instruction. + The single argument is a reference to a type info.

    @@ -526,16 +422,16 @@
    -  i32 %llvm.eh.sjlj.setjmp(i8*)
    +  i32 @llvm.eh.sjlj.setjmp(i8* %setjmp_buf)
     
    -

    The SJLJ exception handling uses this intrinsic to force register saving for - the current function and to store the address of the following instruction - for use as a destination address by - llvm.eh.sjlj.longjmp. The buffer format and the overall - functioning of this intrinsic is compatible with the GCC - __builtin_setjmp implementation, allowing code built with the - two compilers to interoperate.

    +

    For SJLJ based exception handling, this intrinsic forces register saving for + the current function and stores the address of the following instruction for + use as a destination address + by llvm.eh.sjlj.longjmp. The + buffer format and the overall functioning of this intrinsic is compatible + with the GCC __builtin_setjmp implementation allowing code built + with the clang and GCC to interoperate.

    The single parameter is a pointer to a five word buffer in which the calling context is saved. The front end places the frame pointer in the first word, @@ -555,16 +451,15 @@

    -  void %llvm.eh.sjlj.setjmp(i8*)
    +  void @llvm.eh.sjlj.longjmp(i8* %setjmp_buf)
     
    -

    The llvm.eh.sjlj.longjmp - intrinsic is used to implement __builtin_longjmp() for SJLJ - style exception handling. The single parameter is a pointer to a - buffer populated by - llvm.eh.sjlj.setjmp. The frame pointer and stack pointer - are restored from the buffer, then control is transferred to the - destination address.

    +

    For SJLJ based exception handling, the llvm.eh.sjlj.longjmp + intrinsic is used to implement __builtin_longjmp(). The single + parameter is a pointer to a buffer populated + by llvm.eh.sjlj.setjmp. The frame + pointer and stack pointer are restored from the buffer, then control is + transferred to the destination address.

    @@ -575,14 +470,13 @@
    -  i8* %llvm.eh.sjlj.lsda()
    +  i8* @llvm.eh.sjlj.lsda()
     
    -

    Used for SJLJ based exception handling, the - llvm.eh.sjlj.lsda intrinsic returns the address of the Language - Specific Data Area (LSDA) for the current function. The SJLJ front-end code - stores this address in the exception handling function context for use by the - runtime.

    +

    For SJLJ based exception handling, the llvm.eh.sjlj.lsda intrinsic + returns the address of the Language Specific Data Area (LSDA) for the current + function. The SJLJ front-end code stores this address in the exception + handling function context for use by the runtime.

    @@ -594,13 +488,13 @@
    -  void %llvm.eh.sjlj.callsite(i32)
    +  void @llvm.eh.sjlj.callsite(i32 %call_site_num)
     
    -

    For SJLJ based exception handling, the - llvm.eh.sjlj.callsite 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.

    +

    For SJLJ based exception handling, the llvm.eh.sjlj.callsite + 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 matching order.

    @@ -612,12 +506,12 @@
    -  void %llvm.eh.sjlj.dispatchsetup(i32)
    +  void @llvm.eh.sjlj.dispatchsetup(i32 %dispatch_value)
     
    -

    For SJLJ based exception handling, the - llvm.eh.sjlj.dispatchsetup intrinsic is used by targets to do - any unwind-edge setup they need. By default, no action is taken.

    +

    For SJLJ based exception handling, the llvm.eh.sjlj.dispatchsetup + intrinsic is used by targets to do any unwind edge setup they need. By + default, no action is taken.

    @@ -631,7 +525,7 @@

    There are two tables that are used by the exception handling runtime to - determine which actions should take place when an exception is thrown.

    + determine which actions should be taken when an exception is thrown.

    @@ -641,13 +535,13 @@

    An exception handling frame eh_frame is very similar to the unwind - frame used by dwarf debug info. The frame contains all the information + frame used by DWARF debug info. The frame contains all the information necessary to tear down the current frame and restore the state of the prior - frame. There is an exception handling frame for each function in a compile + frame. There is an exception handling frame for each function in a compile unit, plus a common exception handling frame that defines information common to all functions in the unit.

    -

    Todo - Table details here.

    +
    @@ -659,31 +553,17 @@

    An exception table contains information about what actions to take when an - exception is thrown in a particular part of a function's code. There is one - exception table per function except leaf routines and functions that have - only calls to non-throwing functions will not need an exception table.

    + exception is thrown in a particular part of a function's code. There is one + exception table per function, except leaf functions and functions that have + calls only to non-throwing functions. They do not need an exception + table.

    -

    Todo - Table details here.

    +

    - -

    - ToDo -

    - -
    - -
      - -
    1. Testing/Testing/Testing.
    2. - -
    - -
    -
    @@ -695,7 +575,7 @@ Chris Lattner
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-05-28 09:45:59 +0200 (Sat, 28 May 2011) $ + Last modified: $Date: 2011-09-27 22:16:57 +0200 (Tue, 27 Sep 2011) $ diff --git a/docs/FAQ.html b/docs/FAQ.html index 20ba1d5d2912..341f1c977a9d 100644 --- a/docs/FAQ.html +++ b/docs/FAQ.html @@ -72,9 +72,6 @@
  • After Subversion update, rebuilding gives the error "No rule to make target".
  • -
  • The llvmc program gives me errors/doesn't - work.
  • -
  • When I compile LLVM-GCC with srcdir == objdir, it fails. Why?
  • @@ -419,16 +416,6 @@ Stop. rebuilding.

    - - -
    -

    llvmc is experimental and isn't really supported. We suggest - using llvm-gcc instead.

    -
    -

    When I compile LLVM-GCC with srcdir == objdir, it fails. Why?

    @@ -540,10 +527,7 @@ Stop.

    Currently, there isn't much. LLVM supports an intermediate representation which is useful for code representation but will not support the high level (abstract syntax tree) representation needed by most compilers. There are no - facilities for lexical nor semantic analysis. There is, however, a mostly - implemented configuration-driven - compiler driver which simplifies the task - of running optimizations, linking, and executable generation.

    + facilities for lexical nor semantic analysis.

    @@ -933,7 +917,7 @@ F.i: src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"> LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-19 01:59:50 +0200 (Tue, 19 Apr 2011) $ + Last modified: $Date: 2011-09-20 02:42:28 +0200 (Tue, 20 Sep 2011) $ diff --git a/docs/GarbageCollection.html b/docs/GarbageCollection.html index 13a3714e8233..10bc6632c59f 100644 --- a/docs/GarbageCollection.html +++ b/docs/GarbageCollection.html @@ -290,10 +290,8 @@ doing so is very simple. (This code is heavily commented to help you understand the data structure, but there are only 20 lines of meaningful code.)

    -
    - -
    /// @brief The map for a single function's stack frame. One of these is
    +
    +/// @brief The map for a single function's stack frame. One of these is
     ///        compiled as constant data into the executable for each function.
     /// 
     /// Storage of metadata values is elided if the %metadata parameter to
    @@ -338,7 +336,9 @@ void visitGCRoots(void (*Visitor)(void **Root, const void *Meta)) {
         for (unsigned e = R->Map->NumRoots; i != e; ++i)
           Visitor(&R->Roots[i], NULL);
       }
    -}
    +} + +

    @@ -395,12 +395,12 @@ program.

    Specifying GC code generation: gc "..."

    +
    +
    define ty @name(...) gc "name" { ...
    -
    -

    The gc function attribute is used to specify the desired GC style to the compiler. Its programmatic equivalent is the setGC method of Function.

    @@ -420,12 +420,12 @@ programs that use different garbage collection algorithms (or none at all).

    Identifying GC roots on the stack: llvm.gcroot

    +
    +
    void @llvm.gcroot(i8** %ptrloc, i8* %metadata)
    -
    -

    The llvm.gcroot intrinsic is used to inform LLVM that a stack variable references an object on the heap and is to be tracked for garbage collection. The exact impact on generated code is specified by a

    Consider the following fragment of Java code:

    -
    +
            {
              Object X;   // A null-initialized reference to an object
              ...
    @@ -463,7 +463,7 @@ the stack frame.

    This block (which may be located in the middle of a function or in a loop nest), could be compiled to this LLVM code:

    -
    +
     Entry:
        ;; In the entry block for the function, allocate the
        ;; stack space for X, which is an LLVM pointer.
    @@ -537,12 +537,12 @@ are used.

    Write barrier: llvm.gcwrite +
    +
    void @llvm.gcwrite(i8* %value, i8* %object, i8** %derived)
    -
    -

    For write barriers, LLVM provides the llvm.gcwrite intrinsic function. It has exactly the same semantics as a non-volatile store to the derived pointer (the third argument). The exact code generated is specified @@ -559,12 +559,12 @@ implement reference counting.

    Read barrier: llvm.gcread +
    +
    i8* @llvm.gcread(i8* %object, i8** %derived)
    -
    -

    For read barriers, LLVM provides the llvm.gcread intrinsic function. It has exactly the same semantics as a non-volatile load from the derived pointer (the second argument). The exact code generated is specified by @@ -1379,7 +1379,7 @@ Fergus Henderson. International Symposium on Memory Management 2002.

    Chris Lattner
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-08-12 08:17:17 +0200 (Fri, 12 Aug 2011) $ diff --git a/docs/GettingStarted.html b/docs/GettingStarted.html index cc5c59e78f66..e198e0277196 100644 --- a/docs/GettingStarted.html +++ b/docs/GettingStarted.html @@ -441,13 +441,13 @@ href="GCCFEBuildInstrs.html">try to compile it on your platform.

    GNU Autoconf - 2.60 + 2.61 Configuration script builder4 GNU Automake - 1.9.6 + 1.10 aclocal macro generator4 @@ -471,8 +471,8 @@ href="GCCFEBuildInstrs.html">try to compile it on your platform.

  • Only needed if you want to run the automated test suite in the llvm/test directory.
  • If you want to make changes to the configure scripts, - you will need GNU autoconf (2.60), and consequently, GNU M4 (version 1.4 - or higher). You will also need automake (1.9.6). We only use aclocal + you will need GNU autoconf (2.61), and consequently, GNU M4 (version 1.4 + or higher). You will also need automake (1.10). We only use aclocal from that package.
  • @@ -747,6 +747,7 @@ revision), you can checkout it from the 'tags' directory (instead of subdirectories of the 'tags' directory:

      +
    • Release 3.0: RELEASE_30/final
    • Release 2.9: RELEASE_29/final
    • Release 2.8: RELEASE_28
    • Release 2.7: RELEASE_27
    • @@ -802,10 +803,150 @@ instructions to successfully get and build the LLVM GCC front-end.

      now mirrors reflect only trunk for each project. You can do the read-only GIT clone of LLVM via:

      -
      -% git clone http://llvm.org/git/llvm.git
      +
      +git clone http://llvm.org/git/llvm.git
       
      +

      If you want to check out clang too, run:

      + +
      +git clone http://llvm.org/git/llvm.git
      +cd llvm/tools
      +git clone http://llvm.org/git/clang.git
      +
      + +

      +Since the upstream repository is in Subversion, you should use +"git pull --rebase" +instead of "git pull" to avoid generating a non-linear +history in your clone. +To configure "git pull" to pass --rebase by default +on the master branch, run the following command: +

      + +
      +git config branch.master.rebase true
      +
      + +

      Sending patches with Git

      +
      +

      +Please read Developer Policy, too. +

      + +

      +Assume master points the upstream and mybranch points your +working branch, and mybranch is rebased onto master. +At first you may check sanity of whitespaces: +

      + +
      +git diff --check master..mybranch
      +
      + +

      +The easiest way to generate a patch is as below: +

      + +
      +git diff master..mybranch > /path/to/mybranch.diff
      +
      + +

      +It is a little different from svn-generated diff. git-diff-generated diff has +prefixes like a/ and b/. Don't worry, most developers might +know it could be accepted with patch -p1 -N. +

      + +

      +But you may generate patchset with git-format-patch. It generates +by-each-commit patchset. To generate patch files to attach to your article: +

      + +
      +git format-patch --no-attach master..mybranch -o /path/to/your/patchset
      +
      + +

      +If you would like to send patches directly, you may use git-send-email or +git-imap-send. Here is an example to generate the patchset in Gmail's [Drafts]. +

      + +
      +git format-patch --attach master..mybranch --stdout | git imap-send
      +
      + +

      +Then, your .git/config should have [imap] sections. +

      + +
      +[imap]
      +        host = imaps://imap.gmail.com
      +        user = your.gmail.account@gmail.com
      +        pass = himitsu!
      +        port = 993
      +        sslverify = false
      +; in English
      +        folder = "[Gmail]/Drafts"
      +; example for Japanese, "Modified UTF-7" encoded.
      +        folder = "[Gmail]/&Tgtm+DBN-"
      +
      + +
      + +

      For developers to work with git-svn

      +
      + +

      To set up clone from which you can submit code using + git-svn, run:

      + +
      +git clone http://llvm.org/git/llvm.git
      +cd llvm
      +git svn init https://llvm.org/svn/llvm-project/llvm/trunk --username=<username>
      +git config svn-remote.svn.fetch :refs/remotes/origin/master
      +git svn rebase -l  # -l avoids fetching ahead of the git mirror.
      +
      +# If you have clang too:
      +cd tools
      +git clone http://llvm.org/git/clang.git
      +cd clang
      +git svn init https://llvm.org/svn/llvm-project/cfe/trunk --username=<username>
      +git config svn-remote.svn.fetch :refs/remotes/origin/master
      +git svn rebase -l
      +
      + +

      To update this clone without generating git-svn tags that conflict +with the upstream git repo, run:

      + +
      +git fetch && (cd tools/clang && git fetch)  # Get matching revisions of both trees.
      +git checkout master
      +git svn rebase -l
      +(cd tools/clang &&
      + git checkout master &&
      + git svn rebase -l)
      +
      + +

      This leaves your working directories on their master branches, so +you'll need to checkout each working branch individually and +rebase it on top of its parent branch. (Note: This script is +intended for relative newbies to git. If you have more experience, +you can likely improve on it.)

      + +

      The git-svn metadata can get out of sync after you mess around with +branches and dcommit. When that happens, git svn +dcommit stops working, complaining about files with uncommitted +changes. The fix is to rebuild the metadata:

      + +
      +rm -rf .git/svn
      +git svn rebase -l
      +
      + +
      +
    @@ -1362,13 +1503,9 @@ different tools.

    at runtime in both interpreted and JIT compiled fashions.
    llvm/lib/Support/
    -
    This directory contains the source code that corresponds to the header - files located in llvm/include/Support/.
    - - -
    llvm/lib/System/
    -
    This directory contains the operating system abstraction layer that - shields LLVM from platform-specific coding.
    +
    This directory contains the source code that corresponds to the header + files located in llvm/include/ADT/ + and llvm/include/Support/.
    @@ -1455,16 +1592,6 @@ information is in the Command Guide.

    href="HowToSubmitABug.html">HowToSubmitABug.html for more information on using bugpoint. -
    llvmc
    -
    The LLVM Compiler Driver. This program can - be configured to utilize both LLVM and non-LLVM compilation tools to enable - pre-processing, translation, optimization, assembly, and linking of programs - all from one command line. llvmc also takes care of processing the - dependent libraries found in bitcode. This reduces the need to get the - traditional -l<name> options right on the command line. Please - note that this tool, while functional, is still experimental and not feature - complete.
    -
    llvm-ar
    The archiver produces an archive containing the given LLVM bitcode files, optionally with an index for faster @@ -1480,9 +1607,9 @@ information is in the Command Guide.

    llvm-ld
    llvm-ld is a general purpose and extensible linker for LLVM. - This is the linker invoked by llvmc. It performs standard link time - optimizations and allows optimization modules to be loaded and run so that - language specific optimizations can be applied at link time.
    + It performs standard link time optimizations and allows optimization + modules to be loaded and run so that language specific optimizations can + be applied at link time.
    llvm-link
    llvm-link, not surprisingly, links multiple LLVM modules into @@ -1743,7 +1870,7 @@ out:

    Chris Lattner
    Reid Spencer
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-10-17 08:31:32 +0200 (Mon, 17 Oct 2011) $ diff --git a/docs/GoldPlugin.html b/docs/GoldPlugin.html index e25c45751929..92ba4116a071 100644 --- a/docs/GoldPlugin.html +++ b/docs/GoldPlugin.html @@ -75,6 +75,7 @@ placed.

    Usage

    +

    The linker takes a -plugin option that points to the path of the plugin .so file. To find out what link command gcc would run in a given situation, run gcc -v [...] and look @@ -82,19 +83,21 @@ placed. ld-new -plugin /path/to/LLVMgold.so to test it out. Once you're ready to switch to using gold, backup your existing /usr/bin/ld then replace it with ld-new.

    -

    You can produce bitcode files from llvm-gcc using + +

    You can produce bitcode files from clang using -emit-llvm or -flto, or the -O4 flag which is synonymous with -O3 -flto.

    -

    llvm-gcc has a -use-gold-plugin option which looks - for the gold plugin in the same directories as it looks for cc1 and - passes the -plugin option to ld. It will not look for an alternate + +

    Clang has a -use-gold-plugin option which looks for the + gold plugin in the same directories as it looks for cc1 and passes + the -plugin option to ld. It will not look for an alternate linker, which is why you need gold to be the installed system linker in your path.

    +

    If you want ar and nm to work seamlessly as well, install LLVMgold.so to /usr/lib/bfd-plugins. If you built your own gold, be sure to install the ar and nm-new you built to - /usr/bin. -

    + /usr/bin.

    @@ -137,11 +140,12 @@ void foo4(void) { } --- command lines --- -$ llvm-gcc -flto a.c -c -o a.o # <-- a.o is LLVM bitcode file +$ clang -flto a.c -c -o a.o # <-- a.o is LLVM bitcode file $ ar q a.a a.o # <-- a.a is an archive with LLVM bitcode -$ llvm-gcc b.c -c -o b.o # <-- b.o is native object file -$ llvm-gcc -use-gold-plugin a.a b.o -o main # <-- link with LLVMgold plugin +$ clang b.c -c -o b.o # <-- b.o is native object file +$ clang -use-gold-plugin a.a b.o -o main # <-- link with LLVMgold plugin

    +

    Gold informs the plugin that foo3 is never referenced outside the IR, leading LLVM to delete that function. However, unlike in the libLTO @@ -158,20 +162,21 @@ $ llvm-gcc -use-gold-plugin a.a b.o -o main # <-- link with LLVMgold plugin

    -

    Once your system ld, ar and nm all support LLVM - bitcode, everything is in place for an easy to use LTO build of autotooled - projects:

    +

    Once your system ld, ar, and nm all support LLVM + bitcode, everything is in place for an easy to use LTO build of autotooled + projects:

    +
    • Follow the instructions on how to build LLVMgold.so.
    • Install the newly built binutils to $PREFIX
    • Copy Release/lib/LLVMgold.so to - $PREFIX/libexec/gcc/x86_64-unknown-linux-gnu/4.2.1/ and - $PREFIX/lib/bfd-plugins/
    • -
    • Set environment variables ($PREFIX is where you installed llvm-gcc and - binutils): -
      -export CC="$PREFIX/bin/llvm-gcc -use-gold-plugin"
      -export CXX="$PREFIX/bin/llvm-g++ -use-gold-plugin"
      +        $PREFIX/libexec/gcc/x86_64-unknown-linux-gnu/4.2.1/ and
      +        $PREFIX/lib/bfd-plugins/
    • +
    • Set environment variables ($PREFIX is where you installed clang and + binutils): +
      +export CC="$PREFIX/bin/clang -use-gold-plugin"
      +export CXX="$PREFIX/bin/clang++ -use-gold-plugin"
       export AR="$PREFIX/bin/ar"
       export NM="$PREFIX/bin/nm"
       export RANLIB=/bin/true #ranlib is not needed, and doesn't support .bc files in .a
      @@ -179,18 +184,22 @@ export CFLAGS="-O4"
       
    • Or you can just set your path: -
      +
       export PATH="$PREFIX/bin:$PATH"
      -export CC="llvm-gcc -use-gold-plugin"
      -export CXX="llvm-g++ -use-gold-plugin"
      +export CC="clang -use-gold-plugin"
      +export CXX="clang++ -use-gold-plugin"
       export RANLIB=/bin/true
       export CFLAGS="-O4"
      -
      -
    • -
    • Configure & build the project as usual: ./configure && make && make check
    • +
    +
  • Configure & build the project as usual: +
    +% ./configure && make && make check
    +
  • -

    The environment variable settings may work for non-autotooled projects - too, but you may need to set the LD environment variable as well.

    + +

    The environment variable settings may work for non-autotooled projects + too, but you may need to set the LD environment variable as + well.

    diff --git a/docs/HowToReleaseLLVM.html b/docs/HowToReleaseLLVM.html index f52f326eef62..c46ed5aa4a76 100644 --- a/docs/HowToReleaseLLVM.html +++ b/docs/HowToReleaseLLVM.html @@ -29,7 +29,7 @@

    This document contains information about successfully releasing LLVM — - including subprojects: e.g., llvm-gcc and clang — to + including subprojects: e.g., clang and dragonegg — to the public. It is the Release Manager's responsibility to ensure that a high quality build of LLVM is released.

    @@ -92,7 +92,6 @@
    1. Build the LLVM Source Distributions
    2. Build LLVM
    3. -
    4. Build the LLVM-GCC Binary Distribution
    5. Build the Clang Binary Distribution
    6. Target Specific Build Details
    @@ -100,7 +99,6 @@
  • Release Qualification Criteria
    1. Qualify LLVM
    2. -
    3. Qualify LLVM-GCC
    4. Qualify Clang
    5. Specific Target Qualification Details
    @@ -149,25 +147,25 @@
  • Verify that the current Subversion trunk is in decent shape by examining nightly tester and buildbot results.

  • -
  • Create the release branch for llvm, llvm-gcc-4.2, - clang, and the test-suite from the last known good - revision. The branch's name is release_XY, where X is - the major and Y the minor release numbers. The branches should be - created using the following commands:

    +
  • Create the release branch for llvm, clang, + the test-suite, and dragonegg from the last known good + revision. The branch's name is release_XY, + where X is the major and Y the minor release + numbers. The branches should be created using the following commands:

     $ svn copy https://llvm.org/svn/llvm-project/llvm/trunk \
                https://llvm.org/svn/llvm-project/llvm/branches/release_XY
     
    -$ svn copy https://llvm.org/svn/llvm-project/llvm-gcc-4.2/trunk \
    -           https://llvm.org/svn/llvm-project/llvm-gcc-4.2/branches/release_XY
    +$ svn copy https://llvm.org/svn/llvm-project/cfe/trunk \
    +           https://llvm.org/svn/llvm-project/cfe/branches/release_XY
    +
    +$ svn copy https://llvm.org/svn/llvm-project/dragonegg/trunk \
    +           https://llvm.org/svn/llvm-project/dragonegg/branches/release_XY
     
     $ svn copy https://llvm.org/svn/llvm-project/test-suite/trunk \
                https://llvm.org/svn/llvm-project/test-suite/branches/release_XY
    -
    -$ svn copy https://llvm.org/svn/llvm-project/cfe/trunk \
    -           https://llvm.org/svn/llvm-project/cfe/branches/release_XY
     
  • @@ -182,11 +180,11 @@ $ svn copy https://llvm.org/svn/llvm-project/cfe/trunk \
     $ svn co https://llvm.org/svn/llvm-project/llvm/branches/release_XY llvm-X.Y
     
    -$ svn co https://llvm.org/svn/llvm-project/llvm-gcc-4.2/branches/release_XY llvm-gcc-4.2-X.Y
    +$ svn co https://llvm.org/svn/llvm-project/cfe/branches/release_XY clang-X.Y
    +
    +$ svn co https://llvm.org/svn/llvm-project/dragonegg/branches/release_XY dragonegg-X.Y
     
     $ svn co https://llvm.org/svn/llvm-project/test-suite/branches/release_XY test-suite-X.Y
    -
    -$ svn co https://llvm.org/svn/llvm-project/cfe/branches/release_XY clang-X.Y
     
    @@ -214,10 +212,10 @@ $ svn co https://llvm.org/svn/llvm-project/cfe/branches/release_XY clang-
    -

    Create release candidates for llvm, llvm-gcc, - clang, and the LLVM test-suite by tagging the branch with - the respective release candidate number. For instance, to create Release - Candidate 1 you would issue the following commands:

    +

    Create release candidates for llvm, clang, + dragonegg, and the LLVM test-suite by tagging the branch + with the respective release candidate number. For instance, to + create Release Candidate 1 you would issue the following commands:

    @@ -225,17 +223,17 @@ $ svn mkdir https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_XY
     $ svn copy https://llvm.org/svn/llvm-project/llvm/branches/release_XY \
                https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_XY/rc1
     
    -$ svn mkdir https://llvm.org/svn/llvm-project/llvm-gcc-4.2/tags/RELEASE_XY
    -$ svn copy https://llvm.org/svn/llvm-project/llvm-gcc-4.2/branches/release_XY \
    -           https://llvm.org/svn/llvm-project/llvm-gcc-4.2/tags/RELEASE_XY/rc1
    +$ svn mkdir https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XY
    +$ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \
    +           https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XY/rc1
    +
    +$ svn mkdir https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_XY
    +$ svn copy https://llvm.org/svn/llvm-project/dragonegg/branches/release_XY \
    +           https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_XY/rc1
     
     $ svn mkdir https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XY
     $ svn copy https://llvm.org/svn/llvm-project/test-suite/branches/release_XY \
                https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XY/rc1
    -
    -$ svn mkdir https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XY
    -$ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \
    -           https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XY/rc1
     
    @@ -251,14 +249,14 @@ $ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \
     $ svn export https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_XY/rc1 llvm-X.Yrc1
    -$ svn export https://llvm.org/svn/llvm-project/llvm-gcc-4.2/tags/RELEASE_XY/rc1 llvm-gcc4.2-X.Yrc1
    -$ svn export https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XY/rc1 llvm-test-X.Yrc1
     $ svn export https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XY/rc1 clang-X.Yrc1
    +$ svn export https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_XY/rc1 dragonegg-X.Yrc1
    +$ svn export https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XY/rc1 llvm-test-X.Yrc1
     
     $ tar -cvf - llvm-X.Yrc1        | gzip > llvm-X.Yrc1.src.tar.gz
    -$ tar -cvf - llvm-test-X.Yrc1   | gzip > llvm-test-X.Yrc1.src.tar.gz
    -$ tar -cvf - llvm-gcc4.2-X.Yrc1 | gzip > llvm-gcc-4.2-X.Yrc1.src.tar.gz
     $ tar -cvf - clang-X.Yrc1       | gzip > clang-X.Yrc1.src.tar.gz
    +$ tar -cvf - dragonegg-X.Yrc1   | gzip > dragonegg-X.Yrc1.src.tar.gz
    +$ tar -cvf - llvm-test-X.Yrc1   | gzip > llvm-test-X.Yrc1.src.tar.gz
     
    @@ -271,7 +269,7 @@ $ tar -cvf - clang-X.Yrc1 | gzip > clang-X.Yrc1.src.tar.g
    -

    The builds of llvm, llvm-gcc, and clang +

    The builds of llvm, clang, and dragonegg must be free of errors and warnings in Debug, Release+Asserts, and Release builds. If all builds are clean, then the release passes Build Qualification.

    @@ -292,35 +290,7 @@ $ tar -cvf - clang-X.Yrc1 | gzip > clang-X.Yrc1.src.tar.g

    Build Debug, Release+Asserts, and Release versions of llvm on all supported platforms. Directions to build - llvm are - here.

    - -
    - - -

    Build the LLVM GCC Binary Distribution

    - -
    - -

    Creating the llvm-gcc binary distribution (Release/Optimized) - requires performing the following steps for each supported platform:

    - -
      -
    1. Build the llvm-gcc front-end by following the directions in - the README.LLVM file. The front-end must be compiled with C, C++, - Objective-C (Mac only), Objective-C++ (Mac only), and Fortran - support.

    2. - -
    3. Boostrapping must be enabled.

    4. - -
    5. Be sure to build with LLVM_VERSION_INFO=X.Y, where X - is the major and Y is the minor release numbers.

    6. - -
    7. Copy the installation directory to a directory named for the specific - target. For example on Red Hat Enterprise Linux, the directory would be - named llvm-gcc4.2-2.6-x86-linux-RHEL4. Archive and compress the - new directory.

    8. -
    + llvm are here.

    @@ -337,8 +307,8 @@ $ tar -cvf - clang-X.Yrc1 | gzip > clang-X.Yrc1.src.tar.g
  • Build clang according to the directions here.
  • -
  • Build both a debug and release version of clang. The binary will be the - release build.
  • +
  • Build both a Debug and Release version of clang. The binary will be the + Release build.
  • Package clang (details to follow).
  • @@ -351,18 +321,18 @@ $ tar -cvf - clang-X.Yrc1 | gzip > clang-X.Yrc1.src.tar.g

    The table below specifies which compilers are used for each Arch/OS - combination when qualifying the build of llvm, llvm-gcc, - and clang.

    + combination when qualifying the build of llvm, clang, + and dragonegg.

    - - - - - - - - + + + + + + + +
    ArchitectureOScompiler
    x86-32Mac OS 10.5gcc 4.0.1
    x86-32Linuxgcc 4.2.X, gcc 4.3.X
    x86-32FreeBSDgcc 4.2.X
    x86-32mingwgcc 3.4.5
    x86-64Mac OS 10.5gcc 4.0.1
    x86-64Linuxgcc 4.2.X, gcc 4.3.X
    x86-64FreeBSDgcc 4.2.X
    Architecture OS compiler
    x86-32 Mac OS 10.5 gcc 4.0.1
    x86-32 Linux gcc 4.2.X, gcc 4.3.X
    x86-32 FreeBSD gcc 4.2.X
    x86-32 mingw gcc 3.4.5
    x86-64 Mac OS 10.5 gcc 4.0.1
    x86-64 Linux gcc 4.2.X, gcc 4.3.X
    x86-64 FreeBSD gcc 4.2.X
    @@ -394,21 +364,8 @@ $ tar -cvf - clang-X.Yrc1 | gzip > clang-X.Yrc1.src.tar.g

    LLVM is qualified when it has a clean test run without a front-end. And it - has no regressions when using either llvm-gcc or clang with - the test-suite from the previous release.

    - -
    - - -

    Qualify LLVM-GCC

    - -
    - -

    LLVM-GCC is qualified when front-end specific tests in the - llvm regression test suite all pass and there are no regressions in - the test-suite.

    - -

    We do not use the GCC DejaGNU test suite as release criteria.

    + has no regressions when using either clang or dragonegg + with the test-suite from the previous release.

    @@ -429,13 +386,13 @@ $ tar -cvf - clang-X.Yrc1 | gzip > clang-X.Yrc1.src.tar.g
    - - - - - - - + + + + + + +
    ArchitectureOSllvm-gcc baselineclang baselinetests
    x86-32Linuxlast releaselast releasellvm dejagnu, clang tests, test-suite (including spec)
    x86-32FreeBSDnonelast releasellvm dejagnu, clang tests, test-suite
    x86-32mingwlast releasenoneQT
    x86-64Mac OS 10.Xlast releaselast releasellvm dejagnu, clang tests, test-suite (including spec)
    x86-64Linuxlast releaselast releasellvm dejagnu, clang tests, test-suite (including spec)
    x86-64FreeBSDnonelast releasellvm dejagnu, clang tests, test-suite
    Architecture OS clang baseline tests
    x86-32 Linux last release llvm dejagnu, clang tests, test-suite (including spec)
    x86-32 FreeBSD last release llvm dejagnu, clang tests, test-suite
    x86-32 mingw none QT
    x86-64 Mac OS 10.X last release llvm dejagnu, clang tests, test-suite (including spec)
    x86-64 Linux last release llvm dejagnu, clang tests, test-suite (including spec)
    x86-64 FreeBSD last release llvm dejagnu, clang tests, test-suite
    @@ -452,14 +409,12 @@ $ tar -cvf - clang-X.Yrc1 | gzip > clang-X.Yrc1.src.tar.g
    1. Download llvm-X.Y, llvm-test-X.Y, and the - appropriate llvm-gcc and/or clang binary. Build - LLVM. Run make check and the full LLVM test suite (make - TEST=nightly report).
    2. + appropriate clang binary. Build LLVM. Run make check and + the full LLVM test suite (make TEST=nightly report).
    3. Download llvm-X.Y, llvm-test-X.Y, and the - llvm-gcc and/or clang source. Compile everything. Run - make check and the full LLVM test suite (make TEST=nightly - report).
    4. + clang sources. Compile everything. Run make check and + the full LLVM test suite (make TEST=nightly report).

    Ask LLVM developers to submit the test suite report and make check @@ -538,14 +493,14 @@ $ tar -cvf - clang-X.Yrc1 | gzip > clang-X.Yrc1.src.tar.g $ svn copy https://llvm.org/svn/llvm-project/llvm/branches/release_XY \ https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_XY/Final -$ svn copy https://llvm.org/svn/llvm-project/llvm-gcc-4.2/branches/release_XY \ - https://llvm.org/svn/llvm-project/llvm-gcc-4.2/tags/RELEASE_XY/Final +$ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \ + https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XY/Final + +$ svn copy https://llvm.org/svn/llvm-project/dragonegg/branches/release_XY \ + https://llvm.org/svn/llvm-project/dragonegg/tags/RELEASE_XY/Final $ svn copy https://llvm.org/svn/llvm-project/test-suite/branches/release_XY \ https://llvm.org/svn/llvm-project/test-suite/tags/RELEASE_XY/Final - -$ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \ - https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_XY/Final

    @@ -559,7 +514,7 @@ $ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \

    The LLVM demo page must be updated to use the new release. This consists of - using the new llvm-gcc binary and building LLVM.

    + using the new clang binary and building LLVM.

    Update the LLVM Website

    @@ -574,8 +529,8 @@ $ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \
  • Create a new subdirectory X.Y in the releases directory.
  • -
  • Commit the llvm, test-suite, llvm-gcc source, - clang source, clang binaries, and llvm-gcc +
  • Commit the llvm, test-suite, clang source, + clang binaries, dragonegg source, and dragonegg binaries in this new directory.
  • Copy and commit the llvm/docs and LICENSE.txt files @@ -619,7 +574,7 @@ $ svn copy https://llvm.org/svn/llvm-project/cfe/branches/release_XY \ src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"> The LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-10-17 22:32:14 +0200 (Mon, 17 Oct 2011) $ diff --git a/docs/LangRef.html b/docs/LangRef.html index 8e172438cc42..71e606d304cf 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -35,7 +35,7 @@
  • 'extern_weak' Linkage
  • 'linkonce_odr' Linkage
  • 'weak_odr' Linkage
  • -
  • 'externally visible' Linkage
  • +
  • 'external' Linkage
  • 'dllimport' Linkage
  • 'dllexport' Linkage
  • @@ -53,6 +53,8 @@
  • Data Layout
  • Pointer Aliasing Rules
  • Volatile Memory Accesses
  • +
  • Memory Model for Concurrent Operations
  • +
  • Atomic Memory Ordering Constraints
  • Type System @@ -74,7 +76,7 @@
    1. Array Type
    2. Structure Type
    3. -
    4. Opaque Type
    5. +
    6. Opaque Structure Types
    7. Vector Type
  • @@ -122,6 +124,7 @@
  • 'indirectbr' Instruction
  • 'invoke' Instruction
  • 'unwind' Instruction
  • +
  • 'resume' Instruction
  • 'unreachable' Instruction
  • @@ -166,9 +169,12 @@
  • Memory Access and Addressing Operations
      -
    1. 'alloca' Instruction
    2. -
    3. 'load' Instruction
    4. -
    5. 'store' Instruction
    6. +
    7. 'alloca' Instruction
    8. +
    9. 'load' Instruction
    10. +
    11. 'store' Instruction
    12. +
    13. 'fence' Instruction
    14. +
    15. 'cmpxchg' Instruction
    16. +
    17. 'atomicrmw' Instruction
    18. 'getelementptr' Instruction
  • @@ -196,6 +202,7 @@
  • 'select' Instruction
  • 'call' Instruction
  • 'va_arg' Instruction
  • +
  • 'landingpad' Instruction
  • @@ -268,9 +275,10 @@
  • Debugger intrinsics
  • Exception Handling intrinsics
  • -
  • Trampoline Intrinsic +
  • Trampoline Intrinsics
    1. 'llvm.init.trampoline' Intrinsic
    2. +
    3. 'llvm.adjust.trampoline' Intrinsic
  • Atomic intrinsics @@ -639,7 +647,7 @@ define i32 @main() { ; i32()*   be merged with equivalent globals. These linkage types are otherwise the same as their non-odr versions. -
    externally visible:
    +
    external:
    If none of the above identifiers are used, the global is externally visible, meaning that it participates in linkage and can be used to resolve external symbol references.
    @@ -672,8 +680,8 @@ define i32 @main() { ; i32()*   declarations), they are accessible outside of the current module.

    It is illegal for a function declaration to have any linkage type - other than "externally visible", dllimport - or extern_weak.

    + other than external, dllimport + or extern_weak.

    Aliases can have only external, internal, weak or weak_odr linkages.

    @@ -1155,14 +1163,6 @@ define void @f() optsize { ... } function into callers whenever possible, ignoring any active inlining size threshold for this caller. -
    hotpatch
    -
    This attribute indicates that the function should be 'hotpatchable', - meaning the function can be patched and/or hooked even while it is - loaded into memory. On x86, the function prologue will be preceded - by six bytes of padding and will begin with a two-byte instruction. - Most of the functions in the Windows system DLLs in Windows XP SP2 or - higher were compiled in this fashion.
    -
    nonlazybind
    This attribute suppresses lazy symbol binding for the function. This may make calls to the function faster, at the cost of extra program @@ -1246,6 +1246,19 @@ define void @f() optsize { ... } function that doesn't have an sspreq attribute or which has an ssp attribute, then the resulting function will have an sspreq attribute.
    + +
    uwtable
    +
    This attribute indicates that the ABI being targeted requires that + an unwind table entry be produce for this function even if we can + show that no exceptions passes by it. This is normally the case for + the ELF x86-64 abi, but it can be disabled for some compilation + units.
    + +
    returns_twice
    +
    This attribute indicates that this function can return + twice. The C setjmp is an example of such a function. + The compiler disables some optimizations (like tail calls) in the caller of + these functions.
  • @@ -1306,6 +1319,13 @@ target datalayout = "layout specification" the bits with the least significance have the lowest address location. +
    Ssize
    +
    Specifies the natural alignment of the stack in bits. Alignment promotion + of stack variables is limited to the natural stack alignment to avoid + dynamic stack realignment. The stack alignment must be a multiple of + 8-bits. If omitted, the natural stack alignment defaults to "unspecified", + which does not prevent any alignment promotions.
    +
    p:size:abi:pref
    This specifies the size of a pointer and its abi and preferred alignments. All sizes are in bits. Specifying @@ -1386,6 +1406,22 @@ target datalayout = "layout specification" implemented in terms of 64 <2 x double>, for example. +

    The function of the data layout string may not be what you expect. Notably, + this is not a specification from the frontend of what alignment the code + generator should use.

    + +

    Instead, if specified, the target data layout is required to match what the + ultimate code generator expects. This string is used by the + mid-level optimizers to + improve code, and this only works if it matches what the ultimate code + generator uses. If you would like to generate IR that does not embed this + target-specific detail into the IR, then you don't have to specify the + string. This will disable some optimizations that require precise layout + information, but this also prevents those optimizations from introducing + target specificity into the IR.

    + + +
    @@ -1470,6 +1506,185 @@ synchronization behavior.

    + +

    + Memory Model for Concurrent Operations +

    + +
    + +

    The LLVM IR does not define any way to start parallel threads of execution +or to register signal handlers. Nonetheless, there are platform-specific +ways to create them, and we define LLVM IR's behavior in their presence. This +model is inspired by the C++0x memory model.

    + +

    For a more informal introduction to this model, see the +LLVM Atomic Instructions and Concurrency Guide. + +

    We define a happens-before partial order as the least partial order +that

    +
      +
    • Is a superset of single-thread program order, and
    • +
    • When a synchronizes-with b, includes an edge from + a to b. Synchronizes-with pairs are introduced + by platform-specific techniques, like pthread locks, thread + creation, thread joining, etc., and by atomic instructions. + (See also Atomic Memory Ordering Constraints). +
    • +
    + +

    Note that program order does not introduce happens-before edges +between a thread and signals executing inside that thread.

    + +

    Every (defined) read operation (load instructions, memcpy, atomic +loads/read-modify-writes, etc.) R reads a series of bytes written by +(defined) write operations (store instructions, atomic +stores/read-modify-writes, memcpy, etc.). For the purposes of this section, +initialized globals are considered to have a write of the initializer which is +atomic and happens before any other read or write of the memory in question. +For each byte of a read R, Rbyte may see +any write to the same byte, except:

    + +
      +
    • If write1 happens before + write2, and write2 happens + before Rbyte, then Rbyte + does not see write1. +
    • If Rbyte happens before + write3, then Rbyte does not + see write3. +
    + +

    Given that definition, Rbyte is defined as follows: +

      +
    • If R is volatile, the result is target-dependent. (Volatile + is supposed to give guarantees which can support + sig_atomic_t in C/C++, and may be used for accesses to + addresses which do not behave like normal memory. It does not generally + provide cross-thread synchronization.) +
    • Otherwise, if there is no write to the same byte that happens before + Rbyte, Rbyte returns + undef for that byte. +
    • Otherwise, if Rbyte may see exactly one write, + Rbyte returns the value written by that + write.
    • +
    • Otherwise, if R is atomic, and all the writes + Rbyte may see are atomic, it chooses one of the + values written. See the Atomic Memory Ordering + Constraints section for additional constraints on how the choice + is made. +
    • Otherwise Rbyte returns undef.
    • +
    + +

    R returns the value composed of the series of bytes it read. +This implies that some bytes within the value may be undef +without the entire value being undef. Note that this only +defines the semantics of the operation; it doesn't mean that targets will +emit more than one instruction to read the series of bytes.

    + +

    Note that in cases where none of the atomic intrinsics are used, this model +places only one restriction on IR transformations on top of what is required +for single-threaded execution: introducing a store to a byte which might not +otherwise be stored is not allowed in general. (Specifically, in the case +where another thread might write to and read from an address, introducing a +store can change a load that may see exactly one write into a load that may +see multiple writes.)

    + + + +
    + + +

    + Atomic Memory Ordering Constraints +

    + +
    + +

    Atomic instructions (cmpxchg, +atomicrmw, +fence, +atomic load, and +atomic store) take an ordering parameter +that determines which other atomic instructions on the same address they +synchronize with. These semantics are borrowed from Java and C++0x, +but are somewhat more colloquial. If these descriptions aren't precise enough, +check those specs (see spec references in the +atomics guide). +fence instructions +treat these orderings somewhat differently since they don't take an address. +See that instruction's documentation for details.

    + +

    For a simpler introduction to the ordering constraints, see the +LLVM Atomic Instructions and Concurrency Guide.

    + +
    +
    unordered
    +
    The set of values that can be read is governed by the happens-before +partial order. A value cannot be read unless some operation wrote it. +This is intended to provide a guarantee strong enough to model Java's +non-volatile shared variables. This ordering cannot be specified for +read-modify-write operations; it is not strong enough to make them atomic +in any interesting way.
    +
    monotonic
    +
    In addition to the guarantees of unordered, there is a single +total order for modifications by monotonic operations on each +address. All modification orders must be compatible with the happens-before +order. There is no guarantee that the modification orders can be combined to +a global total order for the whole program (and this often will not be +possible). The read in an atomic read-modify-write operation +(cmpxchg and +atomicrmw) +reads the value in the modification order immediately before the value it +writes. If one atomic read happens before another atomic read of the same +address, the later read must see the same value or a later value in the +address's modification order. This disallows reordering of +monotonic (or stronger) operations on the same address. If an +address is written monotonically by one thread, and other threads +monotonically read that address repeatedly, the other threads must +eventually see the write. This corresponds to the C++0x/C1x +memory_order_relaxed.
    +
    acquire
    +
    In addition to the guarantees of monotonic, +a synchronizes-with edge may be formed with a release +operation. This is intended to model C++'s memory_order_acquire.
    +
    release
    +
    In addition to the guarantees of monotonic, if this operation +writes a value which is subsequently read by an acquire operation, +it synchronizes-with that operation. (This isn't a complete +description; see the C++0x definition of a release sequence.) This corresponds +to the C++0x/C1x memory_order_release.
    +
    acq_rel (acquire+release)
    Acts as both an +acquire and release operation on its address. +This corresponds to the C++0x/C1x memory_order_acq_rel.
    +
    seq_cst (sequentially consistent)
    +
    In addition to the guarantees of acq_rel +(acquire for an operation which only reads, release +for an operation which only writes), there is a global total order on all +sequentially-consistent operations on all addresses, which is consistent with +the happens-before partial order and with the modification orders of +all the affected addresses. Each sequentially-consistent read sees the last +preceding write to the same address in this global order. This corresponds +to the C++0x/C1x memory_order_seq_cst and Java volatile.
    +
    + +

    If an atomic operation is marked singlethread, +it only synchronizes with or participates in modification and seq_cst +total orderings with other operations running in the same thread (for example, +in signal handlers).

    + +
    + @@ -1852,20 +2067,22 @@ synchronization behavior.

    Structures may optionally be "packed" structures, which indicate that the alignment of the struct is one byte, and that there is no padding between - the elements. In non-packed structs, padding between field types is defined - by the target data string to match the underlying processor.

    + the elements. In non-packed structs, padding between field types is inserted + as defined by the TargetData string in the module, which is required to match + what the underlying code generator expects.

    -

    Structures can either be "anonymous" or "named". An anonymous structure is - defined inline with other types (e.g. {i32, i32}*) and a named types - are always defined at the top level with a name. Anonmyous types are uniqued - by their contents and can never be recursive since there is no way to write - one. Named types can be recursive. +

    Structures can either be "literal" or "identified". A literal structure is + defined inline with other types (e.g. {i32, i32}*) whereas identified + types are always defined at the top level with a name. Literal types are + uniqued by their contents and can never be recursive or opaque since there is + no way to write one. Identified types can be recursive, can be opaqued, and are + never uniqued.

    Syntax:
    -  %T1 = type { <type list> }     ; Named normal struct type
    -  %T2 = type <{ <type list> }>   ; Named packed struct type
    +  %T1 = type { <type list> }     ; Identified normal struct type
    +  %T2 = type <{ <type list> }>   ; Identified packed struct type
     
    Examples:
    @@ -1891,15 +2108,15 @@ synchronization behavior.

    - Opaque Type + Opaque Structure Types

    Overview:
    -

    Opaque types are used to represent named structure types that do not have a - body specified. This corresponds (for example) to the C notion of a forward - declared structure.

    +

    Opaque structure types are used to represent named structure types that do + not have a body specified. This corresponds (for example) to the C notion of + a forward declared structure.

    Syntax:
    @@ -2006,6 +2223,8 @@ synchronization behavior.

    + +

    Constants

    @@ -2361,7 +2580,7 @@ b: unreachable

    Whenever a trap value is generated, all values which depend on it evaluate - to trap. If they have side effects, the evoke their side effects as if each + to trap. If they have side effects, they evoke their side effects as if each operand with a trap value were undef. If they have externally-visible side effects, the behavior is undefined.

    @@ -2844,14 +3063,15 @@ should not be exposed to source languages.

    control flow, not values (the one exception being the 'invoke' instruction).

    -

    There are seven different terminator instructions: the - 'ret' instruction, the - 'br' instruction, the - 'switch' instruction, the - ''indirectbr' Instruction, the - 'invoke' instruction, the - 'unwind' instruction, and the - 'unreachable' instruction.

    +

    The terminator instructions are: + 'ret', + 'br', + 'switch', + 'indirectbr', + 'invoke', + 'unwind', + 'resume', and + 'unreachable'.

    @@ -2912,7 +3132,8 @@ should not be exposed to source languages.

    Syntax:
    -  br i1 <cond>, label <iftrue>, label <iffalse>
    br label <dest> ; Unconditional branch + br i1 <cond>, label <iftrue>, label <iffalse> + br label <dest> ; Unconditional branch
    Overview:
    @@ -3072,6 +3293,17 @@ IfUnequal: instruction, control is interrupted and continued at the dynamically nearest "exception" label.

    +

    The 'exception' label is a + landing pad for the + exception. As such, 'exception' label is required to have the + "landingpad" instruction, which contains + the information about about the behavior of the program after unwinding + happens, as its first non-PHI instruction. The restrictions on the + "landingpad" instruction's tightly couples it to the + "invoke" instruction, so that the important information contained + within the "landingpad" instruction can't be lost through normal + code motion.

    +
    Arguments:

    This instruction requires several arguments:

    @@ -3168,6 +3400,40 @@ that the invoke/unwind semantics are likely to change in future versions.

    Note that the code generator does not yet completely support unwind, and that the invoke/unwind semantics are likely to change in future versions.

    + + + + +

    + 'resume' Instruction +

    + +
    + +
    Syntax:
    +
    +  resume <type> <value>
    +
    + +
    Overview:
    +

    The 'resume' instruction is a terminator instruction that has no + successors.

    + +
    Arguments:
    +

    The 'resume' instruction requires one argument, which must have the + same type as the result of any 'landingpad' instruction in the same + function.

    + +
    Semantics:
    +

    The 'resume' instruction resumes propagation of an existing + (in-flight) exception whose unwinding was interrupted with + a landingpad instruction.

    + +
    Example:
    +
    +  resume { i8*, i32 } %exn
    +
    +
    @@ -4237,7 +4503,7 @@ that the invoke/unwind semantics are likely to change in future versions.

    Syntax:
    -  <result> = insertvalue <aggregate type> <val>, <ty> <elt>, <idx>{, }*    ; yields <aggregate type>
    +  <result> = insertvalue <aggregate type> <val>, <ty> <elt>, <idx>{, <idx>}*    ; yields <aggregate type>
     
    Overview:
    @@ -4342,8 +4608,8 @@ that the invoke/unwind semantics are likely to change in future versions.

    Syntax:
    -  <result> = load <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>]
    -  <result> = volatile load <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>]
    +  <result> = load [volatile] <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>]
    +  <result> = load atomic [volatile] <ty>* <pointer> [singlethread] <ordering>, align <alignment>
       !<index> = !{ i32 1 }
     
    @@ -4358,6 +4624,19 @@ that the invoke/unwind semantics are likely to change in future versions.

    number or order of execution of this load with other volatile operations.

    +

    If the load is marked as atomic, it takes an extra + ordering and optional singlethread + argument. The release and acq_rel orderings are + not valid on load instructions. Atomic loads produce defined results when they may see multiple atomic + stores. The type of the pointee must be an integer type whose bit width + is a power of two greater than or equal to eight and less than or equal + to a target-specific size limit. align must be explicitly + specified on atomic loads, and the load has undefined behavior if the + alignment is not set to a value which is at least the size in bytes of + the pointee. !nontemporal does not have any defined semantics + for atomic loads.

    +

    The optional constant align argument specifies the alignment of the operation (that is, the alignment of the memory address). A value of 0 or an omitted align argument means that the operation has the preferential @@ -4401,8 +4680,8 @@ that the invoke/unwind semantics are likely to change in future versions.

    Syntax:
    -  store <ty> <value>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>]                   ; yields {void}
    -  volatile store <ty> <value>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>]          ; yields {void}
    +  store [volatile] <ty> <value>, <ty>* <pointer>[, align <alignment>][, !nontemporal !<index>]                   ; yields {void}
    +  store atomic [volatile] <ty> <value>, <ty>* <pointer> [singlethread] <ordering>, align <alignment>             ; yields {void}
     
    Overview:
    @@ -4418,6 +4697,19 @@ that the invoke/unwind semantics are likely to change in future versions.

    order of execution of this store with other volatile operations.

    +

    If the store is marked as atomic, it takes an extra + ordering and optional singlethread + argument. The acquire and acq_rel orderings aren't + valid on store instructions. Atomic loads produce defined results when they may see multiple atomic + stores. The type of the pointee must be an integer type whose bit width + is a power of two greater than or equal to eight and less than or equal + to a target-specific size limit. align must be explicitly + specified on atomic stores, and the store has undefined behavior if the + alignment is not set to a value which is at least the size in bytes of + the pointee. !nontemporal does not have any defined semantics + for atomic stores.

    +

    The optional constant "align" argument specifies the alignment of the operation (that is, the alignment of the memory address). A value of 0 or an omitted "align" argument means that the operation has the preferential @@ -4454,6 +4746,215 @@ that the invoke/unwind semantics are likely to change in future versions.

    + +

    +'fence' Instruction +

    + +
    + +
    Syntax:
    +
    +  fence [singlethread] <ordering>                   ; yields {void}
    +
    + +
    Overview:
    +

    The 'fence' instruction is used to introduce happens-before edges +between operations.

    + +
    Arguments:

    'fence' instructions take an ordering argument which defines what +synchronizes-with edges they add. They can only be given +acquire, release, acq_rel, and +seq_cst orderings.

    + +
    Semantics:
    +

    A fence A which has (at least) release ordering +semantics synchronizes with a fence B with (at least) +acquire ordering semantics if and only if there exist atomic +operations X and Y, both operating on some atomic object +M, such that A is sequenced before X, +X modifies M (either directly or through some side effect +of a sequence headed by X), Y is sequenced before +B, and Y observes M. This provides a +happens-before dependency between A and B. Rather +than an explicit fence, one (but not both) of the atomic operations +X or Y might provide a release or +acquire (resp.) ordering constraint and still +synchronize-with the explicit fence and establish the +happens-before edge.

    + +

    A fence which has seq_cst ordering, in addition to +having both acquire and release semantics specified +above, participates in the global program order of other seq_cst +operations and/or fences.

    + +

    The optional "singlethread" argument +specifies that the fence only synchronizes with other fences in the same +thread. (This is useful for interacting with signal handlers.)

    + +
    Example:
    +
    +  fence acquire                          ; yields {void}
    +  fence singlethread seq_cst             ; yields {void}
    +
    + +
    + + +

    +'cmpxchg' Instruction +

    + +
    + +
    Syntax:
    +
    +  cmpxchg [volatile] <ty>* <pointer>, <ty> <cmp>, <ty> <new> [singlethread] <ordering>                   ; yields {ty}
    +
    + +
    Overview:
    +

    The 'cmpxchg' instruction is used to atomically modify memory. +It loads a value in memory and compares it to a given value. If they are +equal, it stores a new value into the memory.

    + +
    Arguments:
    +

    There are three arguments to the 'cmpxchg' instruction: an +address to operate on, a value to compare to the value currently be at that +address, and a new value to place at that address if the compared values are +equal. The type of '<cmp>' must be an integer type whose +bit width is a power of two greater than or equal to eight and less than +or equal to a target-specific size limit. '<cmp>' and +'<new>' must have the same type, and the type of +'<pointer>' must be a pointer to that type. If the +cmpxchg is marked as volatile, then the +optimizer is not allowed to modify the number or order of execution +of this cmpxchg with other volatile +operations.

    + + + +

    The ordering argument specifies how this +cmpxchg synchronizes with other atomic operations.

    + +

    The optional "singlethread" argument declares that the +cmpxchg is only atomic with respect to code (usually signal +handlers) running in the same thread as the cmpxchg. Otherwise the +cmpxchg is atomic with respect to all other code in the system.

    + +

    The pointer passed into cmpxchg must have alignment greater than or equal to +the size in memory of the operand. + +

    Semantics:
    +

    The contents of memory at the location specified by the +'<pointer>' operand is read and compared to +'<cmp>'; if the read value is the equal, +'<new>' is written. The original value at the location +is returned. + +

    A successful cmpxchg is a read-modify-write instruction for the +purpose of identifying release sequences. A +failed cmpxchg is equivalent to an atomic load with an ordering +parameter determined by dropping any release part of the +cmpxchg's ordering.

    + + + +
    Example:
    +
    +entry:
    +  %orig = atomic load i32* %ptr unordered                       ; yields {i32}
    +  br label %loop
    +
    +loop:
    +  %cmp = phi i32 [ %orig, %entry ], [%old, %loop]
    +  %squared = mul i32 %cmp, %cmp
    +  %old = cmpxchg i32* %ptr, i32 %cmp, i32 %squared                       ; yields {i32}
    +  %success = icmp eq i32 %cmp, %old
    +  br i1 %success, label %done, label %loop
    +
    +done:
    +  ...
    +
    + +
    + + +

    +'atomicrmw' Instruction +

    + +
    + +
    Syntax:
    +
    +  atomicrmw [volatile] <operation> <ty>* <pointer>, <ty> <value> [singlethread] <ordering>                   ; yields {ty}
    +
    + +
    Overview:
    +

    The 'atomicrmw' instruction is used to atomically modify memory.

    + +
    Arguments:
    +

    There are three arguments to the 'atomicrmw' instruction: an +operation to apply, an address whose value to modify, an argument to the +operation. The operation must be one of the following keywords:

    +
      +
    • xchg
    • +
    • add
    • +
    • sub
    • +
    • and
    • +
    • nand
    • +
    • or
    • +
    • xor
    • +
    • max
    • +
    • min
    • +
    • umax
    • +
    • umin
    • +
    + +

    The type of '<value>' must be an integer type whose +bit width is a power of two greater than or equal to eight and less than +or equal to a target-specific size limit. The type of the +'<pointer>' operand must be a pointer to that type. +If the atomicrmw is marked as volatile, then the +optimizer is not allowed to modify the number or order of execution of this +atomicrmw with other volatile + operations.

    + + + +
    Semantics:
    +

    The contents of memory at the location specified by the +'<pointer>' operand are atomically read, modified, and written +back. The original value at the location is returned. The modification is +specified by the operation argument:

    + +
      +
    • xchg: *ptr = val
    • +
    • add: *ptr = *ptr + val
    • +
    • sub: *ptr = *ptr - val
    • +
    • and: *ptr = *ptr & val
    • +
    • nand: *ptr = ~(*ptr & val)
    • +
    • or: *ptr = *ptr | val
    • +
    • xor: *ptr = *ptr ^ val
    • +
    • max: *ptr = *ptr > val ? *ptr : val (using a signed comparison)
    • +
    • min: *ptr = *ptr < val ? *ptr : val (using a signed comparison)
    • +
    • umax: *ptr = *ptr > val ? *ptr : val (using an unsigned comparison)
    • +
    • umin: *ptr = *ptr < val ? *ptr : val (using an unsigned comparison)
    • +
    + +
    Example:
    +
    +  %old = atomicrmw add i32* %ptr, i32 1 acquire                        ; yields {i32}
    +
    + +
    +

    'getelementptr' Instruction @@ -4489,7 +4990,7 @@ that the invoke/unwind semantics are likely to change in future versions.

    When indexing into a (optionally packed) structure, only i32 integer constants are allowed. When indexing into an array, pointer or vector, integers of any width are allowed, and they are not required to be - constant.

    + constant. These integers are treated as signed values where relevant.

    For example, let's consider a C code fragment and how it gets compiled to LLVM:

    @@ -4555,18 +5056,20 @@ entry: base pointer is not an in bounds address of an allocated object, or if any of the addresses that would be formed by successive addition of the offsets implied by the indices to the base address with infinitely - precise arithmetic are not an in bounds address of that allocated - object. The in bounds addresses for an allocated object are all - the addresses that point into the object, plus the address one byte past - the end.

    + precise signed arithmetic are not an in bounds address of that + allocated object. The in bounds addresses for an allocated object + are all the addresses that point into the object, plus the address one + byte past the end.

    If the inbounds keyword is not present, the offsets are added to - the base address with silently-wrapping two's complement arithmetic, and - the result value of the getelementptr may be outside the object - pointed to by the base pointer. The result value may not necessarily be - used to access memory though, even if it happens to point into allocated - storage. See the Pointer Aliasing Rules - section for more information.

    + the base address with silently-wrapping two's complement arithmetic. If the + offsets have a different width from the pointer, they are sign-extended or + truncated to the width of the pointer. The result value of the + getelementptr may be outside the object pointed to by the base + pointer. The result value may not necessarily be used to access memory + though, even if it happens to point into allocated storage. See the + Pointer Aliasing Rules section for more + information.

    The getelementptr instruction is often confusing. For some more insight into how it works, see the getelementptr FAQ.

    @@ -5544,6 +6047,87 @@ freestanding environments and non-C-based languages.

    + +

    + 'landingpad' Instruction +

    + +
    + +
    Syntax:
    +
    +  <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
    +  <resultval> = landingpad <somety> personality <type> <pers_fn> cleanup <clause>*
    +
    +  <clause> := catch <type> <value>
    +  <clause> := filter <array constant type> <array constant>
    +
    + +
    Overview:
    +

    The 'landingpad' instruction is used by + LLVM's exception handling + system to specify that a basic block is a landing pad — one where + the exception lands, and corresponds to the code found in the + catch portion of a try/catch sequence. It + defines values supplied by the personality function (pers_fn) upon + re-entry to the function. The resultval has the + type somety.

    + +
    Arguments:
    +

    This instruction takes a pers_fn value. This is the personality + function associated with the unwinding mechanism. The optional + cleanup flag indicates that the landing pad block is a cleanup.

    + +

    A clause begins with the clause type — catch + or filter — and contains the global variable representing the + "type" that may be caught or filtered respectively. Unlike the + catch clause, the filter clause takes an array constant as + its argument. Use "[0 x i8**] undef" for a filter which cannot + throw. The 'landingpad' instruction must contain at least + one clause or the cleanup flag.

    + +
    Semantics:
    +

    The 'landingpad' instruction defines the values which are set by the + personality function (pers_fn) upon re-entry to the function, and + therefore the "result type" of the landingpad instruction. As with + calling conventions, how the personality function results are represented in + LLVM IR is target specific.

    + +

    The clauses are applied in order from top to bottom. If two + landingpad instructions are merged together through inlining, the + clauses from the calling function are appended to the list of clauses.

    + +

    The landingpad instruction has several restrictions:

    + +
      +
    • A landing pad block is a basic block which is the unwind destination of an + 'invoke' instruction.
    • +
    • A landing pad block must have a 'landingpad' instruction as its + first non-PHI instruction.
    • +
    • There can be only one 'landingpad' instruction within the landing + pad block.
    • +
    • A basic block that is not a landing pad block may not include a + 'landingpad' instruction.
    • +
    • All 'landingpad' instructions in a function must have the same + personality function.
    • +
    + +
    Example:
    +
    +  ;; A landing pad which can catch an integer.
    +  %res = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
    +           catch i8** @_ZTIi
    +  ;; A landing pad that is a cleanup.
    +  %res = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
    +           cleanup
    +  ;; A landing pad which can catch an integer and can only throw a double.
    +  %res = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0
    +           catch i8** @_ZTIi
    +           filter [1 x i8**] [@_ZTId]
    +
    + +
    + @@ -5737,6 +6321,8 @@ declare void @llvm.va_end(i8*) + +

    Accurate Garbage Collection Intrinsics @@ -7115,12 +7701,12 @@ LLVM.

    - Trampoline Intrinsic + Trampoline Intrinsics

    -

    This intrinsic makes it possible to excise one parameter, marked with +

    These intrinsics make it possible to excise one parameter, marked with the nest attribute, from a function. The result is a callable function pointer lacking the nest parameter - the caller does not need to @@ -7137,7 +7723,8 @@ LLVM.

       %tramp = alloca [10 x i8], align 4 ; size and alignment only correct for X86
       %tramp1 = getelementptr [10 x i8]* %tramp, i32 0, i32 0
    -  %p = call i8* @llvm.init.trampoline(i8* %tramp1, i8* bitcast (i32 (i8* nest , i32, i32)* @f to i8*), i8* %nval)
    +  call i8* @llvm.init.trampoline(i8* %tramp1, i8* bitcast (i32 (i8*, i32, i32)* @f to i8*), i8* %nval)
    +  %p = call i8* @llvm.adjust.trampoline(i8* %tramp1)
       %fp = bitcast i8* %p to i32 (i32, i32)*
     
    @@ -7155,12 +7742,12 @@ LLVM.

    Syntax:
    -  declare i8* @llvm.init.trampoline(i8* <tramp>, i8* <func>, i8* <nval>)
    +  declare void @llvm.init.trampoline(i8* <tramp>, i8* <func>, i8* <nval>)
     
    Overview:
    -

    This fills the memory pointed to by tramp with code and returns a - function pointer suitable for executing it.

    +

    This fills the memory pointed to by tramp with executable code, + turning it into a trampoline.

    Arguments:

    The llvm.init.trampoline intrinsic takes three arguments, all @@ -7174,17 +7761,50 @@ LLVM.

    Semantics:

    The block of memory pointed to by tramp is filled with target - dependent code, turning it into a function. A pointer to this function is - returned, but needs to be bitcast to an appropriate - function pointer type before being called. The new function's signature - is the same as that of func with any arguments marked with - the nest attribute removed. At most one such nest argument - is allowed, and it must be of pointer type. Calling the new function is - equivalent to calling func with the same argument list, but - with nval used for the missing nest argument. If, after - calling llvm.init.trampoline, the memory pointed to - by tramp is modified, then the effect of any later call to the - returned function pointer is undefined.

    + dependent code, turning it into a function. Then tramp needs to be + passed to llvm.adjust.trampoline to get a pointer + which can be bitcast (to a new function) and + called. The new function's signature is the same as that of + func with any arguments marked with the nest attribute + removed. At most one such nest argument is allowed, and it must be of + pointer type. Calling the new function is equivalent to calling func + with the same argument list, but with nval used for the missing + nest argument. If, after calling llvm.init.trampoline, the + memory pointed to by tramp is modified, then the effect of any later call + to the returned function pointer is undefined.

    +
    + + +

    + + 'llvm.adjust.trampoline' Intrinsic + +

    + +
    + +
    Syntax:
    +
    +  declare i8* @llvm.adjust.trampoline(i8* <tramp>)
    +
    + +
    Overview:
    +

    This performs any required machine-specific adjustment to the address of a + trampoline (passed as tramp).

    + +
    Arguments:
    +

    tramp must point to a block of memory which already has trampoline code + filled in by a previous call to llvm.init.trampoline + .

    + +
    Semantics:
    +

    On some architectures the address of the code to be executed needs to be + different to the address where the trampoline is actually stored. This + intrinsic returns the executable address corresponding to tramp + after performing the required machine specific adjustments. + The pointer returned can then be bitcast and + executed. +

    @@ -7846,7 +8466,7 @@ LLVM.

    Semantics:

    This intrinsic allows annotation of local variables with arbitrary strings. This can be useful for special purpose optimizations that want to look for - these annotations. These have no other defined use, they are ignored by code + these annotations. These have no other defined use; they are ignored by code generation and optimization.

    @@ -7882,7 +8502,7 @@ LLVM.

    Semantics:

    This intrinsic allows annotations to be put on arbitrary expressions with arbitrary strings. This can be useful for special purpose optimizations that - want to look for these annotations. These have no other defined use, they + want to look for these annotations. These have no other defined use; they are ignored by code generation and optimization.

    @@ -7995,7 +8615,7 @@ LLVM.

    Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-07-09 19:41:24 +0200 (Sat, 09 Jul 2011) $ + Last modified: $Date: 2011-10-14 01:04:49 +0200 (Fri, 14 Oct 2011) $ diff --git a/docs/Lexicon.html b/docs/Lexicon.html index 449e26eb922e..e12041d0a89e 100644 --- a/docs/Lexicon.html +++ b/docs/Lexicon.html @@ -35,6 +35,10 @@ DSA DSE + - F - + + FCA + - G - GC @@ -137,6 +141,14 @@ href="http://www.program-transformation.org/Transform/BURG">BURG tool. +

    - F -

    +
    +
    +
    FCA
    +
    First Class Aggregate
    +
    +
    +

    - G -

    @@ -272,7 +284,7 @@ href="http://www.program-transformation.org/Transform/BURG">BURG tool. src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01">The LLVM Team
    The LLVM Compiler Infrastructure
    -Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ +Last modified: $Date: 2011-09-27 20:44:01 +0200 (Tue, 27 Sep 2011) $ diff --git a/docs/LinkTimeOptimization.html b/docs/LinkTimeOptimization.html index 289da236270a..a1e8bba74d05 100644 --- a/docs/LinkTimeOptimization.html +++ b/docs/LinkTimeOptimization.html @@ -79,7 +79,7 @@ conservative escape analysis.

    The following example illustrates the advantages of LTO's integrated approach and clean interface. This example requires a system linker which supports LTO through the interface described in this document. Here, - llvm-gcc transparently invokes system linker.

    + clang transparently invokes system linker.

    • Input source file a.c is compiled into LLVM bitcode form.
    • Input source file main.c is compiled into native object code. @@ -89,27 +89,29 @@ conservative escape analysis. extern int foo1(void); extern void foo2(void); extern void foo4(void); + --- a.c --- #include "a.h" static signed int i = 0; void foo2(void) { - i = -1; + i = -1; } static int foo3() { -foo4(); -return 10; + foo4(); + return 10; } int foo1(void) { -int data = 0; + int data = 0; -if (i < 0) { data = foo3(); } + if (i < 0) + data = foo3(); -data = data + 42; -return data; + data = data + 42; + return data; } --- main.c --- @@ -117,30 +119,35 @@ return data; #include "a.h" void foo4(void) { - printf ("Hi\n"); + printf("Hi\n"); } int main() { - return foo1(); + return foo1(); } --- command lines --- -$ llvm-gcc --emit-llvm -c a.c -o a.o # <-- a.o is LLVM bitcode file -$ llvm-gcc -c main.c -o main.o # <-- main.o is native object file -$ llvm-gcc a.o main.o -o main # <-- standard link command without any modifications +$ clang -emit-llvm -c a.c -o a.o # <-- a.o is LLVM bitcode file +$ clang -c main.c -o main.o # <-- main.o is native object file +$ clang a.o main.o -o main # <-- standard link command without any modifications -

      In this example, the linker recognizes that foo2() is an - externally visible symbol defined in LLVM bitcode file. The linker completes - its usual symbol resolution - pass and finds that foo2() is not used anywhere. This information - is used by the LLVM optimizer and it removes foo2(). As soon as - foo2() is removed, the optimizer recognizes that condition - i < 0 is always false, which means foo3() is never - used. Hence, the optimizer removes foo3(), also. And this in turn, - enables linker to remove foo4(). This example illustrates the - advantage of tight integration with the linker. Here, the optimizer can not - remove foo3() without the linker's input. -

      + +
        +
      • In this example, the linker recognizes that foo2() is an + externally visible symbol defined in LLVM bitcode file. The linker + completes its usual symbol resolution pass and finds that foo2() + is not used anywhere. This information is used by the LLVM optimizer and + it removes foo2().
      • +
      • As soon as foo2() is removed, the optimizer recognizes that condition + i < 0 is always false, which means foo3() is never + used. Hence, the optimizer also removes foo3().
      • +
      • And this in turn, enables linker to remove foo4().
      • +
      + +

      This example illustrates the advantage of tight integration with the + linker. Here, the optimizer can not remove foo3() without the + linker's input.

      +
    @@ -385,7 +392,7 @@ of the native object files.

    Devang Patel and Nick Kledzik
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-09-18 14:51:05 +0200 (Sun, 18 Sep 2011) $ diff --git a/docs/Passes.html b/docs/Passes.html index ca9602c6e076..eb4a11549e15 100644 --- a/docs/Passes.html +++ b/docs/Passes.html @@ -161,7 +161,6 @@ perl -e '$/ = undef; for (split(/\n/, <>)) { s:^ *///? ?::; print "

    \n" if ! -loop-unswitchUnswitch loops -loweratomicLower atomic intrinsics to non-atomic form -lowerinvokeLower invoke and unwind, for unwindless code generators --lowersetjmpLower Set Jump -lowerswitchLower SwitchInst's to branches -mem2regPromote Memory to Register -memcpyoptMemCpy Optimization @@ -1476,35 +1475,6 @@ if (X < 3) {

    - -

    - -lowersetjmp: Lower Set Jump -

    -
    -

    - Lowers setjmp and longjmp to use the LLVM invoke and unwind - instructions as necessary. -

    - -

    - Lowering of longjmp is fairly trivial. We replace the call with a - call to the LLVM library function __llvm_sjljeh_throw_longjmp(). - This unwinds the stack for us calling all of the destructors for - objects allocated on the stack. -

    - -

    - At a setjmp call, the basic block is split and the setjmp - removed. The calls in a function that have a setjmp are converted to - invoke where the except part checks to see if it's a longjmp - exception and, if so, if it's handled in the function. If it is, then it gets - the value returned by the longjmp and goes to where the basic block - was split. invoke instructions are handled in a similar fashion with - the original except block being executed if it isn't a longjmp - except that is handled by that function. -

    -
    -

    -lowerswitch: Lower SwitchInst's to branches @@ -2071,7 +2041,7 @@ if (X < 3) { Reid Spencer
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-08-04 00:18:20 +0200 (Thu, 04 Aug 2011) $ diff --git a/docs/ProgrammersManual.html b/docs/ProgrammersManual.html index ed43f1f8eaf1..3697dd7501ba 100644 --- a/docs/ProgrammersManual.html +++ b/docs/ProgrammersManual.html @@ -59,6 +59,7 @@ option
  • llvm/ADT/ArrayRef.h
  • Fixed Size Arrays
  • Heap Allocated Arrays
  • +
  • "llvm/ADT/TinyPtrVector.h"
  • "llvm/ADT/SmallVector.h"
  • <vector>
  • <deque>
  • @@ -67,6 +68,13 @@ option
  • llvm/ADT/PackedVector.h
  • Other Sequential Container Options
  • +
  • String-like containers +
  • Set-Like Containers (std::set, SmallSet, SetVector, etc)
  • -
  • String-like containers -
  • BitVector-like containers
    • A dense bitvector
    • @@ -875,6 +879,9 @@ elements (but could contain many), for example, it's much better to use . Doing so avoids (relatively) expensive malloc/free calls, which dwarf the cost of adding the elements to the container.

      + + +

      Sequential Containers (std::vector, std::list, etc) @@ -883,7 +890,7 @@ cost of adding the elements to the container.

      There are a variety of sequential containers available for you, based on your needs. Pick the first in this section that will do what you want. - +

      llvm/ADT/ArrayRef.h @@ -926,6 +933,22 @@ destructors will be run for every element in the array (re-sizable vectors only construct those elements actually used).

      + +

      + "llvm/ADT/TinyPtrVector.h" +

      + + +
      +

      TinyPtrVector<Type> is a highly specialized collection class +that is optimized to avoid allocation in the case when a vector has zero or one +elements. It has two major restrictions: 1) it can only hold values of pointer +type, and 2) it cannot hold a null pointer.

      + +

      Since this container is highly specialized, it is rarely used.

      + +
      +

      "llvm/ADT/SmallVector.h" @@ -1190,9 +1213,187 @@ std::priority_queue, std::stack, etc. These provide simplified access to an underlying container but don't affect the cost of the container itself.

      - + +

      + String-like containers +

      + +
      + +

      +There are a variety of ways to pass around and use strings in C and C++, and +LLVM adds a few new options to choose from. Pick the first option on this list +that will do what you need, they are ordered according to their relative cost. +

      +

      +Note that is is generally preferred to not pass strings around as +"const char*"'s. These have a number of problems, including the fact +that they cannot represent embedded nul ("\0") characters, and do not have a +length available efficiently. The general replacement for 'const +char*' is StringRef. +

      + +

      For more information on choosing string containers for APIs, please see +Passing strings.

      + + + +

      + llvm/ADT/StringRef.h +

      + +
      +

      +The StringRef class is a simple value class that contains a pointer to a +character and a length, and is quite related to the ArrayRef class (but specialized for arrays of +characters). Because StringRef carries a length with it, it safely handles +strings with embedded nul characters in it, getting the length does not require +a strlen call, and it even has very convenient APIs for slicing and dicing the +character range that it represents. +

      + +

      +StringRef is ideal for passing simple strings around that are known to be live, +either because they are C string literals, std::string, a C array, or a +SmallVector. Each of these cases has an efficient implicit conversion to +StringRef, which doesn't result in a dynamic strlen being executed. +

      + +

      StringRef has a few major limitations which make more powerful string +containers useful:

      + +
        +
      1. You cannot directly convert a StringRef to a 'const char*' because there is +no way to add a trailing nul (unlike the .c_str() method on various stronger +classes).
      2. + + +
      3. StringRef doesn't own or keep alive the underlying string bytes. +As such it can easily lead to dangling pointers, and is not suitable for +embedding in datastructures in most cases (instead, use an std::string or +something like that).
      4. + +
      5. For the same reason, StringRef cannot be used as the return value of a +method if the method "computes" the result string. Instead, use +std::string.
      6. + +
      7. StringRef's do not allow you to mutate the pointed-to string bytes and it +doesn't allow you to insert or remove bytes from the range. For editing +operations like this, it interoperates with the Twine class.
      8. +
      + +

      Because of its strengths and limitations, it is very common for a function to +take a StringRef and for a method on an object to return a StringRef that +points into some string that it owns.

      + +
      + + +

      + llvm/ADT/Twine.h +

      + +
      +

      + The Twine class is used as an intermediary datatype for APIs that want to take + a string that can be constructed inline with a series of concatenations. + Twine works by forming recursive instances of the Twine datatype (a simple + value object) on the stack as temporary objects, linking them together into a + tree which is then linearized when the Twine is consumed. Twine is only safe + to use as the argument to a function, and should always be a const reference, + e.g.: +

      + +
      +    void foo(const Twine &T);
      +    ...
      +    StringRef X = ...
      +    unsigned i = ...
      +    foo(X + "." + Twine(i));
      +  
      + +

      This example forms a string like "blarg.42" by concatenating the values + together, and does not form intermediate strings containing "blarg" or + "blarg.". +

      + +

      Because Twine is constructed with temporary objects on the stack, and + because these instances are destroyed at the end of the current statement, + it is an inherently dangerous API. For example, this simple variant contains + undefined behavior and will probably crash:

      + +
      +    void foo(const Twine &T);
      +    ...
      +    StringRef X = ...
      +    unsigned i = ...
      +    const Twine &Tmp = X + "." + Twine(i);
      +    foo(Tmp);
      +  
      + +

      ... because the temporaries are destroyed before the call. That said, + Twine's are much more efficient than intermediate std::string temporaries, and + they work really well with StringRef. Just be aware of their limitations.

      + +
      + + + +

      + llvm/ADT/SmallString.h +

      + +
      + +

      SmallString is a subclass of SmallVector that +adds some convenience APIs like += that takes StringRef's. SmallString avoids +allocating memory in the case when the preallocated space is enough to hold its +data, and it calls back to general heap allocation when required. Since it owns +its data, it is very safe to use and supports full mutation of the string.

      + +

      Like SmallVector's, the big downside to SmallString is their sizeof. While +they are optimized for small strings, they themselves are not particularly +small. This means that they work great for temporary scratch buffers on the +stack, but should not generally be put into the heap: it is very rare to +see a SmallString as the member of a frequently-allocated heap data structure +or returned by-value. +

      + +
      + + +

      + std::string +

      + +
      + +

      The standard C++ std::string class is a very general class that (like + SmallString) owns its underlying data. sizeof(std::string) is very reasonable + so it can be embedded into heap data structures and returned by-value. + On the other hand, std::string is highly inefficient for inline editing (e.g. + concatenating a bunch of stuff together) and because it is provided by the + standard library, its performance characteristics depend a lot of the host + standard library (e.g. libc++ and MSVC provide a highly optimized string + class, GCC contains a really slow implementation). +

      + +

      The major disadvantage of std::string is that almost every operation that + makes them larger can allocate memory, which is slow. As such, it is better + to use SmallVector or Twine as a scratch buffer, but then use std::string to + persist the result.

      + + +
      + + +
      + +

      Set-Like Containers (std::set, SmallSet, SetVector, etc) @@ -1381,12 +1582,13 @@ elements out of (linear time), unless you use it's "pop_back" method, which is faster.

      -

      SetVector is an adapter class that defaults to using std::vector and std::set -for the underlying containers, so it is quite expensive. However, -"llvm/ADT/SetVector.h" also provides a SmallSetVector class, which -defaults to using a SmallVector and SmallSet of a specified size. If you use -this, and if your sets are dynamically smaller than N, you will save a lot of -heap traffic.

      +

      SetVector is an adapter class that defaults to + using std::vector and a size 16 SmallSet for the underlying + containers, so it is quite expensive. However, + "llvm/ADT/SetVector.h" also provides a SmallSetVector + class, which defaults to using a SmallVector and SmallSet + of a specified size. If you use this, and if your sets are dynamically + smaller than N, you will save a lot of heap traffic.

      @@ -1634,20 +1836,6 @@ always better.

      - -

      - String-like containers -

      - -
      - -

      -TODO: const char* vs stringref vs smallstring vs std::string. Describe twine, -xref to #string_apis. -

      - -
      -

      Bit storage containers (BitVector, SparseBitVector) @@ -3867,7 +4055,7 @@ arguments. An argument has a pointer to the parent Function.

      Dinakar Dhurjati and Chris Lattner
      The LLVM Compiler Infrastructure
      - Last modified: $Date: 2011-07-12 13:37:02 +0200 (Tue, 12 Jul 2011) $ + Last modified: $Date: 2011-10-11 08:33:56 +0200 (Tue, 11 Oct 2011) $ diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html index d54698d6884a..b0d4f67e9836 100644 --- a/docs/ReleaseNotes.html +++ b/docs/ReleaseNotes.html @@ -44,21 +44,21 @@ Release Notes.

      This document contains the release notes for the LLVM Compiler -Infrastructure, release 3.0. 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 LLVM releases web site.

      + Infrastructure, release 3.0. 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 LLVM releases web site.

      For more information about LLVM, including information about the latest -release, please check out the main LLVM -web site. If you have questions or comments, the LLVM Developer's -Mailing List is a good place to send them.

      + release, please check out the main LLVM web + site. If you have questions or comments, + the LLVM + Developer's Mailing List is a good place to send them.

      -

      Note that if you are reading this file from a Subversion checkout or the -main LLVM web page, this document applies to the next release, not the -current one. To see the release notes for a specific release, please see the -releases page.

      +

      Note that if you are reading this file from a Subversion checkout or the main + LLVM web page, this document applies to the next release, not the + current one. To see the release notes for a specific release, please see the + releases page.

      @@ -78,13 +78,12 @@ current one. To see the release notes for a specific release, please see the
      -

      -The LLVM 3.0 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 -development. Here we include updates on these subprojects. -

      + +

      The LLVM 3.0 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 development. Here we include updates on these subprojects.

      @@ -94,20 +93,47 @@ development. Here we include updates on these subprojects.

      Clang is an LLVM front end for the C, -C++, and Objective-C languages. Clang aims to provide a better user experience -through expressive diagnostics, a high level of conformance to language -standards, fast compilation, and low memory use. Like LLVM, Clang provides a -modular, library-based architecture that makes it suitable for creating or -integrating with other development tools. Clang is considered a -production-quality compiler for C, Objective-C, C++ and Objective-C++ on x86 -(32- and 64-bit), and for darwin/arm targets.

      + C++, and Objective-C languages. Clang aims to provide a better user + experience through expressive diagnostics, a high level of conformance to + language standards, fast compilation, and low memory use. Like LLVM, Clang + provides a modular, library-based architecture that makes it suitable for + creating or integrating with other development tools. Clang is considered a + production-quality compiler for C, Objective-C, C++ and Objective-C++ on x86 + (32- and 64-bit), and for darwin/arm targets.

      In the LLVM 3.0 time-frame, the Clang team has made many improvements:

      + +
        +
      • Greatly improved support for building C++ applications, with greater + stability and better diagnostics.
      • + +
      • Improved support for + the C++ + 2011 standard, including implementations of non-static data member + initializers, alias templates, delegating constructors, the range-based + for loop, and implicitly-generated move constructors and move assignment + operators, among others.
      • + +
      • Implemented support for some features of the upcoming C1x standard, + including static assertions and generic selections.
      • + +
      • Better detection of include and linking paths for system headers and + libraries, especially for Linux distributions.
      • + +
      • Implemented support + for Automatic + Reference Counting for Objective-C.
      • + +
      • Implemented a number of optimizations in libclang, the Clang C + interface, to improve the performance of code completion and the mapping + from source locations to abstract syntax tree nodes.
      • +
      +

      If Clang rejects your code but another compiler accepts it, please take a -look at the language -compatibility guide to make sure this is not intentional or a known issue. -

      + look at the language + compatibility guide to make sure this is not intentional or a known + issue.

      @@ -117,20 +143,17 @@ compatibility guide to make sure this is not intentional or a known issue.

      -

      -DragonEgg is a -gcc plugin that replaces GCC's -optimizers and code generators with LLVM's. -Currently it requires a patched version of gcc-4.5. -The plugin can target the x86-32 and x86-64 processor families and has been -used successfully on the Darwin, FreeBSD and Linux platforms. -The Ada, C, C++ and Fortran languages work well. -The plugin is capable of compiling plenty of Obj-C, Obj-C++ and Java but it is -not known whether the compiled code actually works or not! -

      +

      DragonEgg is a + gcc plugin that replaces GCC's + optimizers and code generators with LLVM's. Currently it requires a patched + version of gcc-4.5. The plugin can target the x86-32 and x86-64 processor + families and has been used successfully on the Darwin, FreeBSD and Linux + platforms. The Ada, C, C++ and Fortran languages work well. The plugin is + capable of compiling plenty of Obj-C, Obj-C++ and Java but it is not known + whether the compiled code actually works or not!

      + +

      The 3.0 release has the following notable changes:

      -

      -The 3.0 release has the following notable changes:

        @@ -226,13 +246,14 @@ Like compiler_rt, libc++ is now dual
  • +

    The VMKit project is an implementation - of a Java Virtual Machine (Java VM or JVM) that uses LLVM for static and - just-in-time compilation. As of LLVM 3.0, VMKit now supports generational - garbage collectors. The garbage collectors are provided by the MMTk framework, - and VMKit can be configured to use one of the numerous implemented collectors - of MMTk. -

    + of a Java Virtual Machine (Java VM or JVM) that uses LLVM for static and + just-in-time compilation. As of LLVM 3.0, VMKit now supports generational + garbage collectors. The garbage collectors are provided by the MMTk + framework, and VMKit can be configured to use one of the numerous implemented + collectors of MMTk.

    +
    @@ -272,125 +293,133 @@ be used to verify some algorithms.

    Crack Programming Language

    -

    -Crack aims to provide the -ease of development of a scripting language with the performance of a compiled -language. The language derives concepts from C++, Java and Python, incorporating -object-oriented programming, operator overloading and strong typing.

    + +

    Crack aims to provide + the ease of development of a scripting language with the performance of a + compiled language. The language derives concepts from C++, Java and Python, + incorporating object-oriented programming, operator overloading and strong + typing.

    +
    -

    TTA-based Codesign Environment (TCE)

    +

    TCE is a toolset for designing application-specific processors (ASP) based on -the Transport triggered architecture (TTA). The toolset provides a complete -co-design flow from C/C++ programs down to synthesizable VHDL and parallel -program binaries. Processor customization points include the register files, -function units, supported operations, and the interconnection network.

    + the Transport triggered architecture (TTA). The toolset provides a complete + co-design flow from C/C++ programs down to synthesizable VHDL and parallel + program binaries. Processor customization points include the register files, + function units, supported operations, and the interconnection network.

    TCE uses Clang and LLVM for C/C++ language support, target independent -optimizations and also for parts of code generation. It generates new LLVM-based -code generators "on the fly" for the designed TTA processors and loads them in -to the compiler backend as runtime libraries to avoid per-target recompilation -of larger parts of the compiler chain.

    + optimizations and also for parts of code generation. It generates new + LLVM-based code generators "on the fly" for the designed TTA processors and + loads them in to the compiler backend as runtime libraries to avoid + per-target recompilation of larger parts of the compiler chain.

    +
    - -

    PinaVM

    +

    PinaVM is an open -source, SystemC front-end. Unlike many -other front-ends, PinaVM actually executes the elaboration of the -program analyzed using LLVM's JIT infrastructure. It later enriches the -bitcode with SystemC-specific information.

    + source, SystemC front-end. Unlike many + other front-ends, PinaVM actually executes the elaboration of the program + analyzed using LLVM's JIT infrastructure. It later enriches the bitcode with + SystemC-specific information.

    +

    Pure

    +

    Pure is an - algebraic/functional - programming language based on term rewriting. Programs are collections - of equations which are used to evaluate expressions in a symbolic - fashion. The interpreter uses LLVM as a backend to JIT-compile Pure - programs to fast native code. Pure offers dynamic typing, eager and lazy - evaluation, lexical closures, a hygienic macro system (also based on - term rewriting), built-in list and matrix support (including list and - matrix comprehensions) and an easy-to-use interface to C and other - programming languages (including the ability to load LLVM bitcode - modules, and inline C, C++, Fortran and Faust code in Pure programs if - the corresponding LLVM-enabled compilers are installed).

    + algebraic/functional programming language based on term rewriting. Programs + are collections of equations which are used to evaluate expressions in a + symbolic fashion. The interpreter uses LLVM as a backend to JIT-compile Pure + programs to fast native code. Pure offers dynamic typing, eager and lazy + evaluation, lexical closures, a hygienic macro system (also based on term + rewriting), built-in list and matrix support (including list and matrix + comprehensions) and an easy-to-use interface to C and other programming + languages (including the ability to load LLVM bitcode modules, and inline C, + C++, Fortran and Faust code in Pure programs if the corresponding + LLVM-enabled compilers are installed).

    -

    Pure version 0.47 has been tested and is known to work with LLVM 3.0 - (and continues to work with older LLVM releases >= 2.5).

    +

    Pure version 0.47 has been tested and is known to work with LLVM 3.0 (and + continues to work with older LLVM releases >= 2.5).

    +

    IcedTea Java Virtual Machine Implementation

    -

    -IcedTea provides a -harness to build OpenJDK using only free software build tools and to provide -replacements for the not-yet free parts of OpenJDK. One of the extensions that -IcedTea provides is a new JIT compiler named Shark which uses LLVM -to provide native code generation without introducing processor-dependent -code. -

    -

    OpenJDK 7 b112, IcedTea6 1.9 and IcedTea7 1.13 and later have been tested -and are known to work with LLVM 3.0 (and continue to work with older LLVM -releases >= 2.6 as well).

    +

    IcedTea provides a + harness to build OpenJDK using only free software build tools and to provide + replacements for the not-yet free parts of OpenJDK. One of the extensions + that IcedTea provides is a new JIT compiler + named Shark + which uses LLVM to provide native code generation without introducing + processor-dependent code.

    + +

    OpenJDK 7 b112, IcedTea6 1.9 and IcedTea7 1.13 and later have been tested and + are known to work with LLVM 3.0 (and continue to work with older LLVM + releases >= 2.6 as well).

    +

    Glasgow Haskell Compiler (GHC)

    -

    GHC is an open source, state-of-the-art programming suite for Haskell, -a standard lazy functional programming language. It includes an -optimizing static compiler generating good code for a variety of -platforms, together with an interactive system for convenient, quick -development.

    + +

    GHC is an open source, state-of-the-art programming suite for Haskell, a + standard lazy functional programming language. It includes an optimizing + static compiler generating good code for a variety of platforms, together + with an interactive system for convenient, quick development.

    In addition to the existing C and native code generators, GHC 7.0 now -supports an LLVM code generator. GHC supports LLVM 2.7 and later.

    + supports an LLVM code generator. GHC supports LLVM 2.7 and later.

    +

    Polly - Polyhedral optimizations for LLVM

    +

    Polly is a project that aims to provide advanced memory access optimizations -to better take advantage of SIMD units, cache hierarchies, multiple cores or -even vector accelerators for LLVM. Built around an abstract mathematical -description based on Z-polyhedra, it provides the infrastructure to develop -advanced optimizations in LLVM and to connect complex external optimizers. In -its first year of existence Polly already provides an exact value-based -dependency analysis as well as basic SIMD and OpenMP code generation support. -Furthermore, Polly can use PoCC(Pluto) an advanced optimizer for data-locality -and parallelism.

    + to better take advantage of SIMD units, cache hierarchies, multiple cores or + even vector accelerators for LLVM. Built around an abstract mathematical + description based on Z-polyhedra, it provides the infrastructure to develop + advanced optimizations in LLVM and to connect complex external optimizers. In + its first year of existence Polly already provides an exact value-based + dependency analysis as well as basic SIMD and OpenMP code generation support. + Furthermore, Polly can use PoCC(Pluto) an advanced optimizer for + data-locality and parallelism.

    +

    Rubinius

    -

    Rubinius is an environment - for running Ruby code which strives to write as much of the implementation in - Ruby as possible. Combined with a bytecode interpreting VM, it uses LLVM to - optimize and compile ruby code down to machine code. Techniques such as type - feedback, method inlining, and deoptimization are all used to remove dynamism - from ruby execution and increase performance.

    -
    +

    Rubinius is an environment + for running Ruby code which strives to write as much of the implementation in + Ruby as possible. Combined with a bytecode interpreting VM, it uses LLVM to + optimize and compile ruby code down to machine code. Techniques such as type + feedback, method inlining, and deoptimization are all used to remove dynamism + from ruby execution and increase performance.

    + +

    @@ -398,12 +427,13 @@ and parallelism.

    -

    -FAUST is a compiled language for real-time -audio signal processing. The name FAUST stands for Functional AUdio STream. Its -programming model combines two approaches: functional programming and block -diagram composition. In addition with the C, C++, JAVA output formats, the -Faust compiler can now generate LLVM bitcode, and works with LLVM 2.7-3.0.

    + +

    FAUST is a compiled language for + real-time audio signal processing. The name FAUST stands for Functional AUdio + STream. Its programming model combines two approaches: functional programming + and block diagram composition. In addition with the C, C++, JAVA output + formats, the Faust compiler can now generate LLVM bitcode, and works with + LLVM 2.7-3.0.

    @@ -418,9 +448,8 @@ Faust compiler can now generate LLVM bitcode, and works with LLVM 2.7-3.0.

    This release includes a huge number of bug fixes, performance tweaks and -minor improvements. Some of the major improvements and new features are listed -in this section. -

    + minor improvements. Some of the major improvements and new features are + listed in this section.

    @@ -447,15 +476,121 @@ in this section.

    +

    LLVM IR has several new features for better support of new targets and that -expose new optimization opportunities:

    + expose new optimization opportunities:

    + +

    One of the biggest changes is that 3.0 has a new exception handling + system. The old system used LLVM intrinsics to convey the exception handling + information to the code generator. It worked in most cases, but not + all. Inlining was especially difficult to get right. Also, the intrinsics + could be moved away from the invoke instruction, making it hard + to recover that information.

    + +

    The new EH system makes exception handling a first-class member of the IR. It + adds two new instructions:

      - +
    • landingpad — + this instruction defines a landing pad basic block. It contains all of the + information that's needed by the code generator. It's also required to be + the first non-PHI instruction in the landing pad. In addition, a landing + pad may be jumped to only by the unwind edge of an invoke + instruction.
    • + +
    • resume — this + instruction causes the current exception to resume traveling up the + stack. It replaces the @llvm.eh.resume intrinsic.
    +

    Converting from the old EH API to the new EH API is rather simple, because a + lot of complexity has been removed. The two intrinsics, + @llvm.eh.exception and @llvm.eh.selector have been + superceded by the landingpad instruction. Instead of generating + a call to @llvm.eh.exception and @llvm.eh.selector: + +

    +
    +Function *ExcIntr = Intrinsic::getDeclaration(TheModule,
    +                                              Intrinsic::eh_exception);
    +Function *SlctrIntr = Intrinsic::getDeclaration(TheModule,
    +                                                Intrinsic::eh_selector);
    +
    +// The exception pointer.
    +Value *ExnPtr = Builder.CreateCall(ExcIntr, "exc_ptr");
    +
    +std::vector<Value*> Args;
    +Args.push_back(ExnPtr);
    +Args.push_back(Builder.CreateBitCast(Personality,
    +                                     Type::getInt8PtrTy(Context)));
    +
    +// Add selector clauses to Args.
    +
    +// The selector call.
    +Builder.CreateCall(SlctrIntr, Args, "exc_sel");
    +
    +
    + +

    You should instead generate a landingpad instruction, that + returns an exception object and selector value:

    + +
    +
    +LandingPadInst *LPadInst =
    +  Builder.CreateLandingPad(StructType::get(Int8PtrTy, Int32Ty, NULL),
    +                           Personality, 0);
    +
    +Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
    +Builder.CreateStore(LPadExn, getExceptionSlot());
    +
    +Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
    +Builder.CreateStore(LPadSel, getEHSelectorSlot());
    +
    +
    + +

    It's now trivial to add the individual clauses to the landingpad + instruction.

    + +
    +
    +// Adding a catch clause
    +Constant *TypeInfo = getTypeInfo();
    +LPadInst->addClause(TypeInfo);
    +
    +// Adding a C++ catch-all
    +LPadInst->addClause(Constant::getNullValue(Builder.getInt8PtrTy()));
    +
    +// Adding a cleanup
    +LPadInst->setCleanup(true);
    +
    +// Adding a filter clause
    +std::vector<Constant*> TypeInfos;
    +Constant *TypeInfo = getFilterTypeInfo();
    +TypeInfos.push_back(Builder.CreateBitCast(TypeInfo, Builder.getInt8PtrTy()));
    +
    +ArrayType *FilterTy = ArrayType::get(Int8PtrTy, TypeInfos.size());
    +LPadInst->addClause(ConstantArray::get(FilterTy, TypeInfos));
    +
    +
    + +

    Converting from using the @llvm.eh.resume intrinsic to + the resume instruction is trivial. It takes the exception + pointer and exception selector values returned by + the landingpad instruction:

    + +
    +
    +Type *UnwindDataTy = StructType::get(Builder.getInt8PtrTy(),
    +                                     Builder.getInt32Ty(), NULL);
    +Value *UnwindData = UndefValue::get(UnwindDataTy);
    +Value *ExcPtr = Builder.CreateLoad(getExceptionObjSlot());
    +Value *ExcSel = Builder.CreateLoad(getExceptionSelSlot());
    +UnwindData = Builder.CreateInsertValue(UnwindData, ExcPtr, 0, "exc_ptr");
    +UnwindData = Builder.CreateInsertValue(UnwindData, ExcSel, 1, "exc_sel");
    +Builder.CreateResume(UnwindData);
    +
    +
    +
    @@ -466,7 +601,8 @@ expose new optimization opportunities:

    In addition to a large array of minor performance tweaks and bug fixes, this -release includes a few major enhancements and additions to the optimizers:

    + release includes a few major enhancements and additions to the + optimizers:

    -

    For more information, please see the Intro to the -LLVM MC Project Blog Post. -

    +

    For more information, please see + the Intro + to the LLVM MC Project Blog Post.

    @@ -511,8 +646,8 @@ LLVM MC Project Blog Post.

    We have put a significant amount of work into the code generator -infrastructure, which allows us to implement more aggressive algorithms and make -it run faster:

    + infrastructure, which allows us to implement more aggressive algorithms and + make it run faster:

    +
    @@ -576,16 +715,33 @@ it run faster:

    -

    If you're already an LLVM user or developer with out-of-tree changes based -on LLVM 2.9, this section lists some "gotchas" that you may run into upgrading -from the previous release.

    +

    If you're already an LLVM user or developer with out-of-tree changes based on + LLVM 2.9, this section lists some "gotchas" that you may run into upgrading + from the previous release.

      - +
    • The LLVMC front end code was removed while separating + out language independence.
    • +
    • The LowerSetJmp pass wasn't used effectively by any + target and has been removed.
    • +
    • The old TailDup pass was not used in the standard pipeline + and was unable to update ssa form, so it has been removed. +
    • The syntax of volatile loads and stores in IR has been changed to + "load volatile"/"store volatile". The old + syntax ("volatile load"/"volatile store") + is still accepted, but is now considered deprecated.
    +

    Windows (32-bit)

    +
    + +
      +
    • On Win32(MinGW32 and MSVC), Windows 2000 will not be supported. + Windows XP or higher is required.
    • +
    + +
    +
    @@ -596,33 +752,41 @@ from the previous release.

    In addition, many APIs have changed in this release. Some of the major - LLVM API changes are:

    + LLVM API changes are:

      +
    • The biggest and most pervasive change is that llvm::Type's are no longer + returned or accepted as 'const' values. Instead, just pass around + non-const Type's.
    • + +
    • PHINode::reserveOperandSpace has been removed. Instead, you + must specify how many operands to reserve space for when you create the + PHINode, by passing an extra argument + into PHINode::Create.
    • -
    • PHINode::reserveOperandSpace has been removed. Instead, you - must specify how many operands to reserve space for when you create the - PHINode, by passing an extra argument into PHINode::Create.
    • +
    • PHINodes no longer store their incoming BasicBlocks as operands. Instead, + the list of incoming BasicBlocks is stored separately, and can be accessed + with new functions PHINode::block_begin + and PHINode::block_end.
    • -
    • PHINodes no longer store their incoming BasicBlocks as operands. Instead, - the list of incoming BasicBlocks is stored separately, and can be accessed - with new functions PHINode::block_begin - and PHINode::block_end.
    • - -
    • Various functions now take an ArrayRef instead of either a pair - of pointers (or iterators) to the beginning and end of a range, or a pointer - and a length. Others now return an ArrayRef instead of a - reference to a SmallVector or std::vector. These - include: +
    • Various functions now take an ArrayRef instead of either a + pair of pointers (or iterators) to the beginning and end of a range, or a + pointer and a length. Others now return an ArrayRef instead + of a reference to a SmallVector + or std::vector. These include:
      • CallInst::Create
      • ComputeLinearIndex (in llvm/CodeGen/Analysis.h)
      • ConstantArray::get
      • ConstantExpr::getExtractElement
      • +
      • ConstantExpr::getGetElementPtr
      • +
      • ConstantExpr::getInBoundsGetElementPtr
      • ConstantExpr::getIndices
      • ConstantExpr::getInsertElement
      • ConstantExpr::getWithOperands
      • +
      • ConstantFoldCall (in llvm/Analysis/ConstantFolding.h)
      • +
      • ConstantFoldInstOperands (in llvm/Analysis/ConstantFolding.h)
      • ConstantVector::get
      • DIBuilder::createComplexVariable
      • DIBuilder::getOrCreateArray
      • @@ -630,23 +794,67 @@ from the previous release.

      • ExtractValueInst::getIndexedType
      • ExtractValueInst::getIndices
      • FindInsertedValue (in llvm/Analysis/ValueTracking.h)
      • -
      • IRBuilder::CreateCall
      • -
      • IRBuilder::CreateExtractValue
      • -
      • IRBuilder::CreateInsertValue
      • -
      • IRBuilder::CreateInvoke
      • +
      • gep_type_begin (in llvm/Support/GetElementPtrTypeIterator.h)
      • +
      • gep_type_end (in llvm/Support/GetElementPtrTypeIterator.h)
      • +
      • GetElementPtrInst::Create
      • +
      • GetElementPtrInst::CreateInBounds
      • +
      • GetElementPtrInst::getIndexedType
      • InsertValueInst::Create
      • InsertValueInst::getIndices
      • InvokeInst::Create
      • +
      • IRBuilder::CreateCall
      • +
      • IRBuilder::CreateExtractValue
      • +
      • IRBuilder::CreateGEP
      • +
      • IRBuilder::CreateInBoundsGEP
      • +
      • IRBuilder::CreateInsertValue
      • +
      • IRBuilder::CreateInvoke
      • MDNode::get
      • MDNode::getIfExists
      • MDNode::getTemporary
      • MDNode::getWhenValsUnresolved
      • +
      • SimplifyGEPInst (in llvm/Analysis/InstructionSimplify.h)
      • +
      • TargetData::getIndexedOffset
    • -
    • All forms of StringMap::getOrCreateValue have been remove - except for the one which takes a StringRef.
    • +
    • All forms of StringMap::getOrCreateValue have been remove + except for the one which takes a StringRef.
    • +
    • The LLVMBuildUnwind function from the C API was removed. The + LLVM unwind instruction has been deprecated for a long time + and isn't used by the current front-ends. So this was removed during the + exception handling rewrite.
    • + +
    • The LLVMAddLowerSetJmpPass function from the C API was + removed because the LowerSetJmp pass was removed.
    • + +
    • The DIBuilder interface used by front ends to encode + debugging information in the LLVM IR now expects clients to + use DIBuilder::finalize() at the end of translation unit to + complete debugging information encoding.
    • + +
    • The way the type system works has been + rewritten: PATypeHolder and OpaqueType are gone, + and all APIs deal with Type* instead of const + Type*. If you need to create recursive structures, then create a + named structure, and use setBody() when all its elements are + built. Type merging and refining is gone too: named structures are not + merged with other structures, even if their layout is identical. (of + course anonymous structures are still uniqued by layout).
    • + +
    • TargetSelect.h moved to Support/ from Target/
    • + +
    • UpgradeIntrinsicCall no longer upgrades pre-2.9 intrinsic calls (for + example llvm.memset.i32).
    • + +
    • It is mandatory to initialize all out-of-tree passes too and their dependencies now with + INITIALIZE_PASS{BEGIN,END,} + and INITIALIZE_{PASS,AG}_DEPENDENCY.
    • + +
    • The interface for MemDepResult in MemoryDependenceAnalysis has been + enhanced with new return types Unknown and NonFuncLocal, in addition to + the existing types Clobber, Def, and NonLocal.
    +
    @@ -659,10 +867,10 @@ from the previous release.

    -

    This section contains significant known problems with the LLVM system, -listed by component. If you run into a problem, please check the LLVM bug database and submit a bug if -there isn't already one.

    +

    This section contains significant known problems with the LLVM system, listed + by component. If you run into a problem, please check + the LLVM bug database and submit a bug if + there isn't already one.

    @@ -672,18 +880,19 @@ there isn't already one.

    The following components of this LLVM release are either untested, known to -be broken or unreliable, or are in early development. These components should -not be relied on, and bugs should not be filed against them, but they may be -useful to some people. In particular, if you would like to work on one of these -components, please contact us on the LLVMdev list.

    + be broken or unreliable, or are in early development. These components + should not be relied on, and bugs should not be filed against them, but they + may be useful to some people. In particular, if you would like to work on + one of these components, please contact us on + the LLVMdev + list.

      -
    • The Alpha, Blackfin, CellSPU, MicroBlaze, MSP430, MIPS, PTX, SystemZ - and XCore backends are experimental.
    • -
    • llc "-filetype=obj" is experimental on all targets - other than darwin and ELF X86 systems.
    • - +
    • The Alpha, Blackfin, CellSPU, MicroBlaze, MSP430, MIPS, PTX, SystemZ and + XCore backends are experimental.
    • + +
    • llc "-filetype=obj" is experimental on all targets other + than darwin and ELF X86 systems.
    @@ -697,23 +906,28 @@ href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev list.

    • The X86 backend does not yet support - all inline assembly that uses the X86 - floating point stack. It supports the 'f' and 't' constraints, but not - 'u'.
    • + all inline assembly that uses the X86 + floating point stack. It supports the 'f' and 't' constraints, but + not 'u'. +
    • The X86-64 backend does not yet support the LLVM IR instruction - va_arg. Currently, front-ends support variadic - argument constructs on X86-64 by lowering them manually.
    • + va_arg. Currently, front-ends support variadic argument + constructs on X86-64 by lowering them manually. +
    • Windows x64 (aka Win64) code generator has a few issues.
        -
      • llvm-gcc cannot build the mingw-w64 runtime currently - due to lack of support for the 'u' inline assembly - constraint and for X87 floating point inline assembly.
      • -
      • On mingw-w64, you will see unresolved symbol __chkstk - due to Bug 8919. - It is fixed in r128206.
      • +
      • llvm-gcc cannot build the mingw-w64 runtime currently due to lack of + support for the 'u' inline assembly constraint and for X87 floating + point inline assembly.
      • + +
      • On mingw-w64, you will see unresolved symbol __chkstk due + to Bug 8919. + It is fixed + in r128206.
      • +
      • Miss-aligned MOVDQA might crash your program. It is due to - Bug 9483, - lack of handling aligned internal globals.
      • + Bug 9483, lack + of handling aligned internal globals.
    • @@ -729,8 +943,8 @@ href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev list.

        -
      • The Linux PPC32/ABI support needs testing for the interpreter and static -compilation, and lacks support for debug information.
      • +
      • The Linux PPC32/ABI support needs testing for the interpreter and static + compilation, and lacks support for debug information.
      @@ -743,11 +957,12 @@ compilation, and lacks support for debug information.
        -
      • Thumb mode works only on ARMv6 or higher processors. On sub-ARMv6 -processors, thumb programs can crash or produce wrong -results (PR1388).
      • -
      • Compilation for ARM Linux OABI (old ABI) is supported but not fully tested. -
      • +
      • Thumb mode works only on ARMv6 or higher processors. On sub-ARMv6 + processors, thumb programs can crash or produce wrong results + (PR1388).
      • + +
      • Compilation for ARM Linux OABI (old ABI) is supported but not fully + tested.
      @@ -760,8 +975,8 @@ results (PR1388).
        -
      • The SPARC backend only supports the 32-bit SPARC ABI (-m32); it does not - support the 64-bit SPARC ABI (-m64).
      • +
      • The SPARC backend only supports the 32-bit SPARC ABI (-m32); it does not + support the 64-bit SPARC ABI (-m64).
      @@ -774,7 +989,7 @@ results (PR1388).
        -
      • 64-bit MIPS targets are not supported yet.
      • +
      • 64-bit MIPS targets are not supported yet.
      @@ -787,11 +1002,10 @@ results (PR1388).
        - -
      • On 21164s, some rare FP arithmetic sequences which may trap do not have the -appropriate nops inserted to ensure restartability.
      • - +
      • On 21164s, some rare FP arithmetic sequences which may trap do not have + the appropriate nops inserted to ensure restartability.
      +
      @@ -802,16 +1016,19 @@ appropriate nops inserted to ensure restartability.

      The C backend has numerous problems and is not being actively maintained. -Depending on it for anything serious is not advised.

      + Depending on it for anything serious is not advised.

      @@ -824,7 +1041,7 @@ Depending on it for anything serious is not advised.

      -

      LLVM 3.0 will be the last release of llvm-gcc.

      +

      LLVM 2.9 was the last release of llvm-gcc.

      llvm-gcc is generally very stable for the C family of languages. The only major language feature of GCC not supported by llvm-gcc is the @@ -841,8 +1058,9 @@ Depending on it for anything serious is not advised.

      dragonegg instead.

      The llvm-gcc 4.2 Ada compiler has basic functionality, but is no longer being -actively maintained. If you are interested in Ada, we recommend that you -consider using dragonegg instead.

      + actively maintained. If you are interested in Ada, we recommend that you + consider using dragonegg instead.

      +

    @@ -855,17 +1073,16 @@ consider using dragonegg instead.

    -

    A wide variety of additional information is available on the LLVM web page, in particular in the documentation section. The web page also -contains versions of the API documentation which is up-to-date with the -Subversion version of the source code. -You can access versions of these documents specific to this release by going -into the "llvm/doc/" directory in the LLVM tree.

    +

    A wide variety of additional information is available on + the LLVM web page, in particular in + the documentation section. The web page + also contains versions of the API documentation which is up-to-date with the + Subversion version of the source code. You can access versions of these + documents specific to this release by going into the "llvm/doc/" + directory in the LLVM tree.

    If you have any questions or comments about LLVM, please feel free to contact -us via the mailing -lists.

    + us via the mailing lists.

    @@ -879,7 +1096,7 @@ lists.

    src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"> LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-07-15 10:37:34 +0200 (Fri, 15 Jul 2011) $ + Last modified: $Date: 2011-10-17 08:31:58 +0200 (Mon, 17 Oct 2011) $ diff --git a/docs/SegmentedStacks.html b/docs/SegmentedStacks.html new file mode 100644 index 000000000000..a91b109308a2 --- /dev/null +++ b/docs/SegmentedStacks.html @@ -0,0 +1,99 @@ + + + + Segmented Stacks in LLVM + + + + + +

    Segmented Stacks in LLVM

    +
    +

    Written by Sanjoy Das

    +
    + +
      +
    1. Introduction
    2. +
    3. Implementation Details +
        +
      1. Allocating Stacklets
      2. +
      3. Variable Sized Allocas
      4. +
      +
    4. +
    5. Results +
        +
      1. Go on LLVM
      2. +
      3. Runtime ABI
      4. +
      +
    6. +
    + +

    Introduction

    +
    +

    + Segmented stack allows stack space to be allocated incrementally than as a monolithic chunk (of some worst case size) at thread initialization. This is done by allocating stack blocks (henceforth called stacklets) and linking them into a doubly linked list. The function prologue is responsible for checking if the current stacklet has enough space for the function to execute; and if not, call into the libgcc runtime to allocate more stack space. Support for segmented stacks on x86 / Linux is currently being worked on. +

    +

    + The runtime functionality is already there in libgcc. +

    +
    + +

    Implementation Details

    +
    +

    Allocating Stacklets

    +
    +

    + As mentioned above, the function prologue checks if the current stacklet has enough space. The current approach is to use a slot in the TCB to store the current stack limit (minus the amount of space needed to allocate a new block) - this slot's offset is again dictated by libgcc. The generated assembly looks like this on x86-64: +

    +
    +	          leaq	-8(%rsp), %r10
    +	          cmpq	%fs:112,  %r10
    +	          jg	.LBB0_2
    +
    +            # More stack space needs to be allocated
    +	          movabsq	$8, %r10 # The amount of space needed
    +	          movabsq	$0, %r11 # The total size of arguments passed on stack
    +	          callq	__morestack
    +	          ret # The reason for this extra return is explained below
    +            .LBB0_2:
    +            # Usual prologue continues here
    +            
    +

    + The size of function arguments on the stack needs to be passed to __morestack (this function is implemented in libgcc) since that number of bytes has to be copied from the previous stacklet to the current one. This is so that SP (and FP) relative addressing of function arguments work as expected. +

    +

    + The unusual ret is needed to have the function which made a call to __morestack return correctly. __morestack, instead of returning, calls into .LBB0_2. This is possible since both, the size of the ret instruction and the PC of call to __morestack are known. When the function body returns, control is transferred back to __morestack. __morestack then de-allocates the new stacklet, restores the correct SP value, and does a second return, which returns control to the correct caller. +

    +
    + +

    Variable Sized Allocas

    +
    +

    + The section on allocating stacklets automatically assumes that every stack frame will be of fixed size. However, LLVM allows the use of the llvm.alloca intrinsic to allocate dynamically sized blocks of memory on the stack. When faced with such a variable-sized alloca, code is generated to +

    +
      +
    • Check if the current stacklet has enough space. If yes, just bump the SP, like in the normal case.
    • +
    • If not, generate a call to libgcc, which allocates the memory from the heap.
    • +
    +

    + The memory allocated from the heap is linked into a list in the current stacklet, and freed along with the same. This prevents a memory leak. +

    +
    + +
    + +
    +
    + + Valid CSS + + + Valid HTML 4.01 + + Sanjoy Das
    + LLVM Compiler Infrastructure
    + Last modified: $Date$ +
    + + + diff --git a/docs/SourceLevelDebugging.html b/docs/SourceLevelDebugging.html index bab42a8a6efc..75fae6e89c1f 100644 --- a/docs/SourceLevelDebugging.html +++ b/docs/SourceLevelDebugging.html @@ -298,8 +298,8 @@ height="369"> of tags are loosely bound to the tag values of DWARF information entries. However, that does not restrict the use of the information supplied to DWARF targets. To facilitate versioning of debug information, the tag is augmented - with the current debug version (LLVMDebugVersion = 8 << 16 or 0x80000 or - 524288.)

    + with the current debug version (LLVMDebugVersion = 8 << 16 or + 0x80000 or 524288.)

    The details of the various descriptors follow.

    @@ -324,6 +324,10 @@ height="369"> i1, ;; True if this is optimized. metadata, ;; Flags i32 ;; Runtime version + metadata ;; List of enums types + metadata ;; List of retained types + metadata ;; List of subprograms + metadata ;; List of global variables } @@ -337,7 +341,8 @@ height="369">

    Compile unit descriptors provide the root context for objects declared in a specific compilation unit. File descriptors are defined using this context. These descriptors are collected by a named metadata - !llvm.dbg.cu. + !llvm.dbg.cu. Compile unit descriptor keeps track of subprograms, + global variables and type information. @@ -355,7 +360,7 @@ height="369"> ;; (DW_TAG_file_type) metadata, ;; Source file name metadata, ;; Source file directory (includes trailing slash) - metadata ;; Reference to compile unit where defined + metadata ;; Unused } @@ -365,8 +370,7 @@ height="369"> provide context for source line correspondence.

    Each input file is encoded as a separate file descriptor in LLVM debugging - information output. Each file descriptor would be defined using a - compile unit.

    + information output.

    @@ -434,6 +438,7 @@ global variables are collected by named metadata !llvm.dbg.gv.

    Function *,;; Pointer to LLVM function metadata, ;; Lists function template parameters metadata ;; Function declaration descriptor + metadata ;; List of function variables } @@ -467,10 +472,23 @@ global variables are collected by named metadata !llvm.dbg.gv.

    -

    These descriptors provide debug information about nested blocks within a +

    This descriptor provides debug information about nested blocks within a subprogram. The line number and column numbers are used to dinstinguish two lexical blocks at same depth.

    +
    +
    +!3 = metadata !{
    +  i32,     ;; Tag = 11 + LLVMDebugVersion (DW_TAG_lexical_block)
    +  metadata ;; Reference to the scope we're annotating with a file change
    +  metadata,;; Reference to the file the scope is enclosed in.
    +}
    +
    +
    + +

    This descriptor provides a wrapper around a lexical scope to handle file + changes in the middle of a lexical block.

    + @@ -485,7 +503,7 @@ global variables are collected by named metadata !llvm.dbg.gv.

    !4 = metadata !{ i32, ;; Tag = 36 + LLVMDebugVersion ;; (DW_TAG_base_type) - metadata, ;; Reference to context (typically a compile unit) + metadata, ;; Reference to context metadata, ;; Name (may be "" for anonymous types) metadata, ;; Reference to file where defined (may be NULL) i32, ;; Line number where defined (may be 0) @@ -500,7 +518,7 @@ global variables are collected by named metadata !llvm.dbg.gv.

    These descriptors define primitive types used in the code. Example int, bool and float. The context provides the scope of the type, which is usually the - top level. Since basic types are not usually user defined the compile unit + top level. Since basic types are not usually user defined the context and line number can be left as NULL and 0. The size, alignment and offset are expressed in bits and can be 64 bit values. The alignment is used to round the offset when embedded in a @@ -585,7 +603,7 @@ DW_TAG_restrict_type = 55 the derived type.

    Derived type location can be determined - from the compile unit and line number. The size, alignment and offset are + from the context and line number. The size, alignment and offset are expressed in bits and can be 64 bit values. The alignment is used to round the offset when embedded in a composite type (example to keep float doubles on 64 bit boundaries.) The offset is @@ -675,7 +693,7 @@ DW_TAG_inheritance = 28 the formal arguments to the subroutine.

    Composite type location can be - determined from the compile unit and line number. The size, alignment and + determined from the context and line number. The size, alignment and offset are expressed in bits and can be 64 bit values. The alignment is used to round the offset when embedded in a composite type (as an example, to keep @@ -750,7 +768,9 @@ DW_TAG_inheritance = 28 metadata, ;; Reference to file where defined i32, ;; 24 bit - Line number where defined ;; 8 bit - Argument number. 1 indicates 1st argument. - metadata ;; Type descriptor + metadata, ;; Type descriptor + i32, ;; flags + metadata ;; (optional) Reference to inline location } @@ -772,7 +792,7 @@ DW_TAG_return_variable = 258 has no source correspondent.

    The context is either the subprogram or block where the variable is defined. - Name the source variable name. Compile unit and line indicate where the + Name the source variable name. Context and line indicate where the variable was defined. Type descriptor defines the declared type of the variable.

    @@ -1794,7 +1814,7 @@ enum Trees { Chris Lattner
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-05-31 20:06:14 +0200 (Tue, 31 May 2011) $ + Last modified: $Date: 2011-10-12 00:59:11 +0200 (Wed, 12 Oct 2011) $ diff --git a/docs/TableGenFundamentals.html b/docs/TableGenFundamentals.html index 37ca04621a34..f607ef8ebeab 100644 --- a/docs/TableGenFundamentals.html +++ b/docs/TableGenFundamentals.html @@ -911,7 +911,7 @@ This should highlight the APIs in TableGen/Record.h.

    Chris Lattner
    LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-10-07 20:25:05 +0200 (Fri, 07 Oct 2011) $ diff --git a/docs/WritingAnLLVMPass.html b/docs/WritingAnLLVMPass.html index 75426e051d35..adbd691b870b 100644 --- a/docs/WritingAnLLVMPass.html +++ b/docs/WritingAnLLVMPass.html @@ -227,11 +227,13 @@ the pass itself.

    Now that we have a way to compile our new pass, we just have to write it. Start out with:

    -
    +
    +
     #include "llvm/Pass.h"
     #include "llvm/Function.h"
     #include "llvm/Support/raw_ostream.h"
    -
    +
    +

    Which are needed because we are writing a Pass, @@ -240,53 +242,66 @@ href="http://llvm.org/doxygen/classllvm_1_1Function.html">Function's, and we will be doing some printing.

    Next we have:

    -
    +
    +
    +
     using namespace llvm;
    -
    +
    +
    +

    ... which is required because the functions from the include files -live in the llvm namespace. -

    +live in the llvm namespace.

    Next we have:

    -
    +
    +
     namespace {
    -
    +
    +

    ... which starts out an anonymous namespace. Anonymous namespaces are to C++ what the "static" keyword is to C (at global scope). It makes the -things declared inside of the anonymous namespace only visible to the current +things declared inside of the anonymous namespace visible only to the current file. If you're not familiar with them, consult a decent C++ book for more information.

    Next, we declare our pass itself:

    -
    +
    +
       struct Hello : public FunctionPass {
    -

    +

    +

    This declares a "Hello" class that is a subclass of FunctionPass. The different builtin pass subclasses are described in detail later, but for now, know that FunctionPass's operate a function at a +href="#FunctionPass">FunctionPass's operate on a function at a time.

    -
    -     static char ID;
    -     Hello() : FunctionPass(ID) {}
    -

    +

    +
    +    static char ID;
    +    Hello() : FunctionPass(ID) {}
    +
    +
    -

    This declares pass identifier used by LLVM to identify pass. This allows LLVM to -avoid using expensive C++ runtime information.

    +

    This declares pass identifier used by LLVM to identify pass. This allows LLVM +to avoid using expensive C++ runtime information.

    -
    +
    +
         virtual bool runOnFunction(Function &F) {
    -      errs() << "Hello: " << F.getName() << "\n";
    +      errs() << "Hello: ";
    +      errs().write_escaped(F.getName()) << "\n";
           return false;
         }
       };  // end of struct Hello
    -
    +} // end of anonymous namespace +
    +

    We declare a "runOnFunction" method, which overloads an abstract virtual method inherited from FunctionPass. This is where we are supposed to do our thing, so we just print out our message with the name of each function.

    -
    -  char Hello::ID = 0;
    -
    +
    +
    +char Hello::ID = 0;
    +
    +
    -

    We initialize pass ID here. LLVM uses ID's address to identify pass so +

    We initialize pass ID here. LLVM uses ID's address to identify a pass, so initialization value is not important.

    -
    -  static RegisterPass<Hello> X("hello", "Hello World Pass",
    -                        false /* Only looks at CFG */,
    -                        false /* Analysis Pass */);
    -}  // end of anonymous namespace
    -
    +
    +
    +static RegisterPass<Hello> X("hello", "Hello World Pass",
    +                             false /* Only looks at CFG */,
    +                             false /* Analysis Pass */);
    +
    +
    -

    Lastly, we register our class Hello, -giving it a command line -argument "hello", and a name "Hello World Pass". -Last two arguments describe its behavior. -If a pass walks CFG without modifying it then third argument is set to true. -If a pass is an analysis pass, for example dominator tree pass, then true -is supplied as fourth argument.

    +

    Lastly, we register our class Hello, +giving it a command line argument "hello", and a name "Hello World +Pass". The last two arguments describe its behavior: if a pass walks CFG +without modifying it then the third argument is set to true; if a pass +is an analysis pass, for example dominator tree pass, then true is +supplied as the fourth argument.

    As a whole, the .cpp file looks like:

    -
    +
    +
     #include "llvm/Pass.h"
     #include "llvm/Function.h"
     #include "llvm/Support/raw_ostream.h"
    @@ -332,24 +350,26 @@ is supplied as fourth argument. 

    Hello() : FunctionPass(ID) {} virtual bool runOnFunction(Function &F) { - errs() << "Hello: " << F.getName() << "\n"; + errs() << "Hello: "; + errs().write_escaped(F.getName()) << '\n'; return false; } - }; - - char Hello::ID = 0; - static RegisterPass<Hello> X("hello", "Hello World Pass", false, false); -} -
    + }; +} + +char Hello::ID = 0; +static RegisterPass<Hello> X("hello", "Hello World Pass", false, false); +
    +

    Now that it's all together, compile the file with a simple "gmake" command in the local directory and you should get a new file "Debug+Asserts/lib/Hello.so" under the top level directory of the LLVM source tree (not in the local directory). Note that everything in this file is -contained in an anonymous namespace: this reflects the fact that passes are self -contained units that do not need external interfaces (although they can have -them) to be useful.

    +contained in an anonymous namespace — this reflects the fact that passes +are self contained units that do not need external interfaces (although they can +have them) to be useful.

    @@ -1929,7 +1949,7 @@ Despite that, we have kept the LLVM passes SMP ready, and you should too.

    Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-10-11 09:03:52 +0200 (Tue, 11 Oct 2011) $ diff --git a/docs/doxygen.cfg.in b/docs/doxygen.cfg.in index 45b8f42e5d56..bc4ab9ff7513 100644 --- a/docs/doxygen.cfg.in +++ b/docs/doxygen.cfg.in @@ -1,4 +1,4 @@ -# Doxyfile 1.5.6 +# Doxyfile 1.7.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project @@ -11,214 +11,219 @@ # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- -# Project related configuration options +# Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = LLVM -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = @abs_top_builddir@/docs/doxygen -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. -CREATE_SUBDIRS = NO +CREATE_SUBDIRS = YES -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, -# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, -# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, -# and Ukrainian. +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" -ABBREVIATE_BRIEF = +ABBREVIATE_BRIEF = -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = ../.. -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 2 -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = +ALIASES = -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO @@ -228,414 +233,459 @@ BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file +# If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the +# Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES -# The ENABLED_SECTIONS tag can be used to enable conditional +# The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. -ENABLED_SECTIONS = +ENABLED_SECTIONS = -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the +# This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. -FILE_VERSION_FILTER = +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated +# The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = NO -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = NO -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) -WARN_FORMAT = +WARN_FORMAT = -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written # to stderr. -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @abs_top_srcdir@/include \ @abs_top_srcdir@/lib \ @abs_top_srcdir@/docs/doxygen.intro -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 -FILE_PATTERNS = +FILE_PATTERNS = -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = +EXCLUDE = -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = @abs_top_srcdir@/examples -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left # blank all files are included. -EXAMPLE_PATTERNS = +EXAMPLE_PATTERNS = -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = YES -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = @abs_top_srcdir@/docs/img -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be # ignored. -INPUT_FILTER = +INPUT_FILTER = -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. -FILTER_PATTERNS = +FILTER_PATTERNS = -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO @@ -644,32 +694,32 @@ FILTER_SOURCE_FILES = NO # configuration options related to source browsing #--------------------------------------------------------------------------- -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES -# Setting the INLINE_SOURCES tag to YES will include the body +# Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = NO -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES @@ -677,20 +727,21 @@ REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. +# link to the source code. +# Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES @@ -699,21 +750,21 @@ VERBATIM_HEADERS = YES # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 4 -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = llvm:: @@ -722,106 +773,149 @@ IGNORE_PREFIX = llvm:: # configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = @abs_top_srcdir@/docs/doxygen.header -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = @abs_top_srcdir@/docs/doxygen.footer -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = @abs_top_srcdir@/docs/doxygen.css -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be # written to the html output directory. -CHM_FILE = +CHM_FILE = -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. -HHC_LOCATION = +HHC_LOCATION = -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO @@ -830,203 +924,314 @@ GENERATE_CHI = NO # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. -CHM_INDEX_ENCODING = +CHM_INDEX_ENCODING = -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO -# The TOC_EXPAND flag can be set to YES to add extra items for group members +# The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO -# This tag can be used to set the number of enum values (range [1..20]) +# This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. -# If the tag value is set to FRAME, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. Other possible values -# for this tag are: HIERARCHIES, which will generate the Groups, Directories, -# and Class Hiererachy pages using a tree view instead of an ordered list; -# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which -# disables this behavior completely. For backwards compatibility with previous -# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE -# respectively. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = NO + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. -LATEX_OUTPUT = +LATEX_OUTPUT = -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. LATEX_CMD_NAME = latex -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = letter -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. -EXTRA_PACKAGES = +EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! -LATEX_HEADER = +LATEX_HEADER = -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. -RTF_OUTPUT = +RTF_OUTPUT = -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. -RTF_STYLESHEET_FILE = +RTF_STYLESHEET_FILE = -# Set optional variables used in the generation of an rtf document. +# Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. -RTF_EXTENSIONS_FILE = +RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. -MAN_OUTPUT = +MAN_OUTPUT = -# The MAN_EXTENSION tag determines the extension that is added to +# The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) -MAN_EXTENSION = +MAN_EXTENSION = -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO @@ -1035,33 +1240,33 @@ MAN_LINKS = NO # configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_SCHEMA = +XML_SCHEMA = -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_DTD = +XML_DTD = -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES @@ -1070,10 +1275,10 @@ XML_PROGRAMLISTING = YES # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO @@ -1082,338 +1287,346 @@ GENERATE_AUTOGEN_DEF = NO # configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- -# Configuration options related to the preprocessor +# Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = ../include -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- -# Configuration::additions related to external references +# Configuration::additions related to external references #--------------------------------------------------------------------------- -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen +# If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. -TAGFILES = +TAGFILES = -# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. -GENERATE_TAGFILE = +GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = YES -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES -# The PERL_PATH should be the absolute path and name of the perl script +# The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). -PERL_PATH = +PERL_PATH = #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. -MSCGEN_PATH = +MSCGEN_PATH = -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = NO -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. -DOT_FONTPATH = +DOT_FONTPATH = -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO -# If set to YES, the inheritance and collaboration graphs will show the +# If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = YES -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png -# The tag DOT_PATH can be used to specify the path where the dot tool can be +# The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = @DOT@ -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the # \dotfile command). -DOTFILE_DIRS = +DOTFILE_DIRS = -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is enabled by default, which results in a transparent -# background. Warning: Depending on the platform used, enabling this option -# may lead to badly anti-aliased labels on the edges of a graph (i.e. they -# become hard to read). +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/docs/index.html b/docs/index.html index fc43569c55e0..e22d991055f1 100644 --- a/docs/index.html +++ b/docs/index.html @@ -63,6 +63,11 @@ Discusses how to get up and running quickly with the LLVM infrastructure. Everything from unpacking and compilation of the distribution to execution of some tools. +
  • LLVM CMake guide - An addendum to the main Getting +Started guide for those using the CMake build +system. +
  • +
  • Getting Started with the LLVM System using Microsoft Visual Studio - An addendum to the main Getting Started guide for those using Visual Studio on Windows.
  • @@ -87,7 +92,6 @@ Current tools: opt, llc, lli, - llvmc llvm-gcc, llvm-g++, bugpoint, @@ -216,14 +220,6 @@ in LLVM.
  • Bugpoint - automatic bug finder and test-case reducer description and usage information.
  • -
  • Compiler Driver (llvmc) Tutorial -- This document is a tutorial introduction to the usage and -configuration of the LLVM compiler driver tool, llvmc.
  • - -
  • Compiler Driver (llvmc) -Reference - This document describes the design and configuration -of llvmc in more detail.
  • -
  • LLVM Bitcode File Format - This describes the file format and encoding used for LLVM "bc" files.
  • @@ -289,7 +285,7 @@ times each day, making it a high volume list. src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"> LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-07-06 20:31:02 +0200 (Wed, 06 Jul 2011) $ + Last modified: $Date: 2011-10-11 18:35:07 +0200 (Tue, 11 Oct 2011) $ diff --git a/docs/llvm.css b/docs/llvm.css index 1222cf12bcb1..e3e6351adb38 100644 --- a/docs/llvm.css +++ b/docs/llvm.css @@ -70,6 +70,14 @@ h4, .doc_subsubsection { margin: 2.0em 0.5em 0.5em 0.5em; display: table; } +blockquote pre { + padding: 1em 2em 1em 1em; + border: solid 1px gray; + background: #eeeeee; + margin: 0 1em 0 1em; + display: table; +} + h2+div, h2+p {text-align: left; padding-left: 20pt; padding-right: 10pt;} h3+div, h3+p {text-align: left; padding-left: 20pt; padding-right: 10pt;} h4+div, h4+p {text-align: left; padding-left: 20pt; padding-right: 10pt;} diff --git a/docs/tutorial/LangImpl2.html b/docs/tutorial/LangImpl2.html index c6a9bb1ec1c3..2696d86d0a8d 100644 --- a/docs/tutorial/LangImpl2.html +++ b/docs/tutorial/LangImpl2.html @@ -801,10 +801,10 @@ course.) To build this, just compile with:

    -   # Compile
    -   g++ -g -O3 toy.cpp 
    -   # Run
    -   ./a.out 
    +# Compile
    +clang++ -g -O3 toy.cpp
    +# Run
    +./a.out 
     
    @@ -1225,7 +1225,7 @@ int main() { Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-10-16 10:07:38 +0200 (Sun, 16 Oct 2011) $ diff --git a/docs/tutorial/LangImpl3.html b/docs/tutorial/LangImpl3.html index 47406ca36e41..c9517a0b7cbd 100644 --- a/docs/tutorial/LangImpl3.html +++ b/docs/tutorial/LangImpl3.html @@ -266,7 +266,7 @@ Value *CallExprAST::Codegen() { if (ArgsV.back() == 0) return 0; } - return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); + return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } @@ -308,11 +308,11 @@ bodies and external function declarations. The code starts with:

     Function *PrototypeAST::Codegen() {
       // Make the function type:  double(double,double) etc.
    -  std::vector<const Type*> Doubles(Args.size(),
    -                                   Type::getDoubleTy(getGlobalContext()));
    +  std::vector<Type*> Doubles(Args.size(),
    +                             Type::getDoubleTy(getGlobalContext()));
       FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()),
                                            Doubles, false);
    -  
    +
       Function *F = Function::Create(FT, Function::ExternalLinkage, Name, TheModule);
     
    @@ -532,9 +532,9 @@ functions. For example:
     ready> 4+5;
     Read top-level expression:
    -define double @""() {
    +define double @0() {
     entry:
    -        ret double 9.000000e+00
    +  ret double 9.000000e+00
     }
     
    @@ -553,13 +553,13 @@ ready> def foo(a b) a*a + 2*a*b + b*b; Read function definition: define double @foo(double %a, double %b) { entry: - %multmp = fmul double %a, %a - %multmp1 = fmul double 2.000000e+00, %a - %multmp2 = fmul double %multmp1, %b - %addtmp = fadd double %multmp, %multmp2 - %multmp3 = fmul double %b, %b - %addtmp4 = fadd double %addtmp, %multmp3 - ret double %addtmp4 + %multmp = fmul double %a, %a + %multmp1 = fmul double 2.000000e+00, %a + %multmp2 = fmul double %multmp1, %b + %addtmp = fadd double %multmp, %multmp2 + %multmp3 = fmul double %b, %b + %addtmp4 = fadd double %addtmp, %multmp3 + ret double %addtmp4 } @@ -573,10 +573,10 @@ ready> def bar(a) foo(a, 4.0) + bar(31337); Read function definition: define double @bar(double %a) { entry: - %calltmp = call double @foo(double %a, double 4.000000e+00) - %calltmp1 = call double @bar(double 3.133700e+04) - %addtmp = fadd double %calltmp, %calltmp1 - ret double %addtmp + %calltmp = call double @foo(double %a, double 4.000000e+00) + %calltmp1 = call double @bar(double 3.133700e+04) + %addtmp = fadd double %calltmp, %calltmp1 + ret double %addtmp } @@ -593,10 +593,10 @@ declare double @cos(double) ready> cos(1.234); Read top-level expression: -define double @""() { +define double @1() { entry: - %calltmp = call double @cos(double 1.234000e+00) - ret double %calltmp + %calltmp = call double @cos(double 1.234000e+00) + ret double %calltmp } @@ -609,37 +609,37 @@ entry: ready> ^D ; ModuleID = 'my cool jit' -define double @""() { +define double @0() { entry: - %addtmp = fadd double 4.000000e+00, 5.000000e+00 - ret double %addtmp + %addtmp = fadd double 4.000000e+00, 5.000000e+00 + ret double %addtmp } define double @foo(double %a, double %b) { entry: - %multmp = fmul double %a, %a - %multmp1 = fmul double 2.000000e+00, %a - %multmp2 = fmul double %multmp1, %b - %addtmp = fadd double %multmp, %multmp2 - %multmp3 = fmul double %b, %b - %addtmp4 = fadd double %addtmp, %multmp3 - ret double %addtmp4 + %multmp = fmul double %a, %a + %multmp1 = fmul double 2.000000e+00, %a + %multmp2 = fmul double %multmp1, %b + %addtmp = fadd double %multmp, %multmp2 + %multmp3 = fmul double %b, %b + %addtmp4 = fadd double %addtmp, %multmp3 + ret double %addtmp4 } define double @bar(double %a) { entry: - %calltmp = call double @foo(double %a, double 4.000000e+00) - %calltmp1 = call double @bar(double 3.133700e+04) - %addtmp = fadd double %calltmp, %calltmp1 - ret double %addtmp + %calltmp = call double @foo(double %a, double 4.000000e+00) + %calltmp1 = call double @bar(double 3.133700e+04) + %addtmp = fadd double %calltmp, %calltmp1 + ret double %addtmp } declare double @cos(double) -define double @""() { +define double @1() { entry: - %calltmp = call double @cos(double 1.234000e+00) - ret double %calltmp + %calltmp = call double @cos(double 1.234000e+00) + ret double %calltmp } @@ -670,10 +670,10 @@ our makefile/command line about which options to use:

    -   # Compile
    -   g++ -g -O3 toy.cpp `llvm-config --cppflags --ldflags --libs core` -o toy
    -   # Run
    -   ./toy
    +# Compile
    +clang++ -g -O3 toy.cpp `llvm-config --cppflags --ldflags --libs core` -o toy
    +# Run
    +./toy
     
    @@ -1081,13 +1081,13 @@ Value *CallExprAST::Codegen() { if (ArgsV.back() == 0) return 0; } - return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); + return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } Function *PrototypeAST::Codegen() { // Make the function type: double(double,double) etc. - std::vector<const Type*> Doubles(Args.size(), - Type::getDoubleTy(getGlobalContext())); + std::vector<Type*> Doubles(Args.size(), + Type::getDoubleTy(getGlobalContext())); FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); @@ -1262,7 +1262,7 @@ int main() { Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-10-16 10:07:38 +0200 (Sun, 16 Oct 2011) $ diff --git a/docs/tutorial/LangImpl4.html b/docs/tutorial/LangImpl4.html index 5b8990e441e4..e910cc1fbdda 100644 --- a/docs/tutorial/LangImpl4.html +++ b/docs/tutorial/LangImpl4.html @@ -343,9 +343,10 @@ code that is statically linked into your application.

     ready> 4+5;
    -define double @""() {
    +Read top-level expression:
    +define double @0() {
     entry:
    -        ret double 9.000000e+00
    +  ret double 9.000000e+00
     }
     
     Evaluated to 9.000000
    @@ -363,16 +364,17 @@ ready> def testfunc(x y) x + y*2; 
     Read function definition:
     define double @testfunc(double %x, double %y) {
     entry:
    -        %multmp = fmul double %y, 2.000000e+00
    -        %addtmp = fadd double %multmp, %x
    -        ret double %addtmp
    +  %multmp = fmul double %y, 2.000000e+00
    +  %addtmp = fadd double %multmp, %x
    +  ret double %addtmp
     }
     
     ready> testfunc(4, 10);
    -define double @""() {
    +Read top-level expression:
    +define double @1() {
     entry:
    -        %calltmp = call double @testfunc(double 4.000000e+00, double 1.000000e+01)
    -        ret double %calltmp
    +  %calltmp = call double @testfunc(double 4.000000e+00, double 1.000000e+01)
    +  ret double %calltmp
     }
     
     Evaluated to 24.000000
    @@ -404,21 +406,34 @@ Read extern:
     declare double @cos(double)
     
     ready> sin(1.0);
    +Read top-level expression:
    +define double @2() {
    +entry:
    +  ret double 0x3FEAED548F090CEE
    +}
    +
     Evaluated to 0.841471
     
     ready> def foo(x) sin(x)*sin(x) + cos(x)*cos(x);
     Read function definition:
     define double @foo(double %x) {
     entry:
    -        %calltmp = call double @sin(double %x)
    -        %multmp = fmul double %calltmp, %calltmp
    -        %calltmp2 = call double @cos(double %x)
    -        %multmp4 = fmul double %calltmp2, %calltmp2
    -        %addtmp = fadd double %multmp, %multmp4
    -        ret double %addtmp
    +  %calltmp = call double @sin(double %x)
    +  %multmp = fmul double %calltmp, %calltmp
    +  %calltmp2 = call double @cos(double %x)
    +  %multmp4 = fmul double %calltmp2, %calltmp2
    +  %addtmp = fadd double %multmp, %multmp4
    +  ret double %addtmp
     }
     
     ready> foo(4.0);
    +Read top-level expression:
    +define double @3() {
    +entry:
    +  %calltmp = call double @foo(double 4.000000e+00)
    +  ret double %calltmp
    +}
    +
     Evaluated to 1.000000
     
    @@ -484,10 +499,10 @@ LLVM JIT and optimizer. To build this example, use:
    -   # Compile
    -   g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
    -   # Run
    -   ./toy
    +# Compile
    +clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
    +# Run
    +./toy
     
    @@ -509,9 +524,9 @@ at runtime.

    #include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Passes.h" #include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetSelect.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/IRBuilder.h" +#include "llvm/Support/TargetSelect.h" #include <cstdio> #include <string> #include <map> @@ -905,13 +920,13 @@ Value *CallExprAST::Codegen() { if (ArgsV.back() == 0) return 0; } - return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); + return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } Function *PrototypeAST::Codegen() { // Make the function type: double(double,double) etc. - std::vector<const Type*> Doubles(Args.size(), - Type::getDoubleTy(getGlobalContext())); + std::vector<Type*> Doubles(Args.size(), + Type::getDoubleTy(getGlobalContext())); FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); @@ -1013,6 +1028,9 @@ static void HandleTopLevelExpression() { // Evaluate a top-level expression into an anonymous function. if (FunctionAST *F = ParseTopLevelExpr()) { if (Function *LF = F->Codegen()) { + fprintf(stderr, "Read top-level expression:"); + LF->dump(); + // JIT the function, returning a function pointer. void *FPtr = TheExecutionEngine->getPointerToFunction(LF); @@ -1076,7 +1094,7 @@ int main() { // Create the JIT. This takes ownership of the module. std::string ErrStr; -TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create(); + TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create(); if (!TheExecutionEngine) { fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); exit(1); @@ -1129,7 +1147,7 @@ TheExecutionEngine = EngineBuilder(TheModule).setErrorStr(&ErrStr).create(); Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-10-16 10:07:38 +0200 (Sun, 16 Oct 2011) $ diff --git a/docs/tutorial/LangImpl5.html b/docs/tutorial/LangImpl5.html index 4fc23a149429..95144dcc4167 100644 --- a/docs/tutorial/LangImpl5.html +++ b/docs/tutorial/LangImpl5.html @@ -259,20 +259,20 @@ declare double @bar() define double @baz(double %x) { entry: - %ifcond = fcmp one double %x, 0.000000e+00 - br i1 %ifcond, label %then, label %else + %ifcond = fcmp one double %x, 0.000000e+00 + br i1 %ifcond, label %then, label %else then: ; preds = %entry - %calltmp = call double @foo() - br label %ifcont + %calltmp = call double @foo() + br label %ifcont else: ; preds = %entry - %calltmp1 = call double @bar() - br label %ifcont + %calltmp1 = call double @bar() + br label %ifcont ifcont: ; preds = %else, %then - %iftmp = phi double [ %calltmp, %then ], [ %calltmp1, %else ] - ret double %iftmp + %iftmp = phi double [ %calltmp, %then ], [ %calltmp1, %else ] + ret double %iftmp } @@ -660,25 +660,25 @@ declare double @putchard(double) define double @printstar(double %n) { entry: - ; initial value = 1.0 (inlined into phi) - br label %loop + ; initial value = 1.0 (inlined into phi) + br label %loop loop: ; preds = %loop, %entry - %i = phi double [ 1.000000e+00, %entry ], [ %nextvar, %loop ] - ; body - %calltmp = call double @putchard(double 4.200000e+01) - ; increment - %nextvar = fadd double %i, 1.000000e+00 + %i = phi double [ 1.000000e+00, %entry ], [ %nextvar, %loop ] + ; body + %calltmp = call double @putchard(double 4.200000e+01) + ; increment + %nextvar = fadd double %i, 1.000000e+00 - ; termination test - %cmptmp = fcmp ult double %i, %n - %booltmp = uitofp i1 %cmptmp to double - %loopcond = fcmp one double %booltmp, 0.000000e+00 - br i1 %loopcond, label %loop, label %afterloop + ; termination test + %cmptmp = fcmp ult double %i, %n + %booltmp = uitofp i1 %cmptmp to double + %loopcond = fcmp one double %booltmp, 0.000000e+00 + br i1 %loopcond, label %loop, label %afterloop afterloop: ; preds = %loop - ; loop always returns 0.0 - ret double 0.000000e+00 + ; loop always returns 0.0 + ret double 0.000000e+00 } @@ -829,10 +829,11 @@ statement.

    With the code for the body of the loop complete, we just need to finish up -the control flow for it. This code remembers the end block (for the phi node), then creates the block for the loop exit ("afterloop"). Based on the value of the -exit condition, it creates a conditional branch that chooses between executing -the loop again and exiting the loop. Any future code is emitted in the -"afterloop" block, so it sets the insertion position to it.

    +the control flow for it. This code remembers the end block (for the phi node), +then creates the block for the loop exit ("afterloop"). Based on the value of +the exit condition, it creates a conditional branch that chooses between +executing the loop again and exiting the loop. Any future code is emitted in +the "afterloop" block, so it sets the insertion position to it.

    @@ -880,10 +881,10 @@ if/then/else and for expressions..  To build this example, use:
     
     
    -   # Compile
    -   g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
    -   # Run
    -   ./toy
    +# Compile
    +clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
    +# Run
    +./toy
     
    @@ -900,9 +901,9 @@ if/then/else and for expressions.. To build this example, use: #include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Passes.h" #include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetSelect.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/IRBuilder.h" +#include "llvm/Support/TargetSelect.h" #include <cstdio> #include <string> #include <map> @@ -1397,7 +1398,7 @@ Value *CallExprAST::Codegen() { if (ArgsV.back() == 0) return 0; } - return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); + return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } Value *IfExprAST::Codegen() { @@ -1546,8 +1547,8 @@ Value *ForExprAST::Codegen() { Function *PrototypeAST::Codegen() { // Make the function type: double(double,double) etc. - std::vector<const Type*> Doubles(Args.size(), - Type::getDoubleTy(getGlobalContext())); + std::vector<Type*> Doubles(Args.size(), + Type::getDoubleTy(getGlobalContext())); FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); @@ -1765,7 +1766,7 @@ int main() { Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-10-16 10:07:38 +0200 (Sun, 16 Oct 2011) $ diff --git a/docs/tutorial/LangImpl6.html b/docs/tutorial/LangImpl6.html index 31d7ff4cd215..8876e8317983 100644 --- a/docs/tutorial/LangImpl6.html +++ b/docs/tutorial/LangImpl6.html @@ -293,8 +293,8 @@ Value *BinaryExprAST::Codegen() { Function *F = TheModule->getFunction(std::string("binary")+Op); assert(F && "binary operator not found!"); - Value *Ops[] = { L, R }; - return Builder.CreateCall(F, Ops, Ops+2, "binop"); + Value *Ops[2] = { L, R }; + return Builder.CreateCall(F, Ops, "binop"); }
    @@ -505,7 +505,9 @@ defined to print out the specified value and a newline):

     ready> extern printd(x);
    -Read extern: declare double @printd(double)
    +Read extern:
    +declare double @printd(double)
    +
     ready> def binary : 1 (x y) 0;  # Low-precedence operator that ignores operands.
     ..
     ready> printd(123) : printd(456) : printd(789);
    @@ -555,6 +557,9 @@ def binary& 6 (LHS RHS)
     def binary = 9 (LHS RHS)
       !(LHS < RHS | LHS > RHS);
     
    +# Define ':' for sequencing: as a low-precedence operator that ignores operands
    +# and just returns the RHS.
    +def binary : 1 (x y) y;
     
    @@ -579,9 +584,10 @@ def printdensity(d) else putchard(42); # '*' ... -ready> printdensity(1): printdensity(2): printdensity(3) : - printdensity(4): printdensity(5): printdensity(9): putchard(10); -*++.. +ready> printdensity(1): printdensity(2): printdensity(3): + printdensity(4): printdensity(5): printdensity(9): + putchard(10); +**++. Evaluated to 0.000000
    @@ -593,7 +599,7 @@ converge:

    -# determine whether the specific location diverges.
    +# Determine whether the specific location diverges.
     # Solve for z = z^2 + c in the complex plane.
     def mandleconverger(real imag iters creal cimag)
       if iters > 255 | (real*real + imag*imag > 4) then
    @@ -603,25 +609,25 @@ def mandleconverger(real imag iters creal cimag)
                         2*real*imag + cimag,
                         iters+1, creal, cimag);
     
    -# return the number of iterations required for the iteration to escape
    +# Return the number of iterations required for the iteration to escape
     def mandleconverge(real imag)
       mandleconverger(real, imag, 0, real, imag);
     
    -

    This "z = z2 + c" function is a beautiful little creature that is the basis -for computation of the Mandelbrot Set. Our -mandelconverge function returns the number of iterations that it takes -for a complex orbit to escape, saturating to 255. This is not a very useful -function by itself, but if you plot its value over a two-dimensional plane, -you can see the Mandelbrot set. Given that we are limited to using putchard -here, our amazing graphical output is limited, but we can whip together +

    This "z = z2 + c" function is a beautiful little +creature that is the basis for computation of +the Mandelbrot Set. +Our mandelconverge function returns the number of iterations that it +takes for a complex orbit to escape, saturating to 255. This is not a very +useful function by itself, but if you plot its value over a two-dimensional +plane, you can see the Mandelbrot set. Given that we are limited to using +putchard here, our amazing graphical output is limited, but we can whip together something using the density plotter above:

    -# compute and plot the mandlebrot set with the specified 2 dimensional range
    +# Compute and plot the mandlebrot set with the specified 2 dimensional range
     # info.
     def mandelhelp(xmin xmax xstep   ymin ymax ystep)
       for y = ymin, y < ymax, ystep in (
    @@ -808,13 +814,19 @@ if/then/else and for expressions..  To build this example, use:
     
     
    -   # Compile
    -   g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
    -   # Run
    -   ./toy
    +# Compile
    +clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
    +# Run
    +./toy
     
    +

    On some platforms, you will need to specify -rdynamic or -Wl,--export-dynamic +when linking. This ensures that symbols defined in the main executable are +exported to the dynamic linker and so are available for symbol resolution at +run time. This is not needed if you compile your support code into a shared +library, although doing that will cause problems on Windows.

    +

    Here is the code:

    @@ -828,9 +840,9 @@ if/then/else and for expressions.. To build this example, use: #include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Passes.h" #include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetSelect.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/IRBuilder.h" +#include "llvm/Support/TargetSelect.h" #include <cstdio> #include <string> #include <map> @@ -1409,8 +1421,8 @@ Value *BinaryExprAST::Codegen() { Function *F = TheModule->getFunction(std::string("binary")+Op); assert(F && "binary operator not found!"); - Value *Ops[] = { L, R }; - return Builder.CreateCall(F, Ops, Ops+2, "binop"); + Value *Ops[2] = { L, R }; + return Builder.CreateCall(F, Ops, "binop"); } Value *CallExprAST::Codegen() { @@ -1429,7 +1441,7 @@ Value *CallExprAST::Codegen() { if (ArgsV.back() == 0) return 0; } - return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); + return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } Value *IfExprAST::Codegen() { @@ -1578,8 +1590,8 @@ Value *ForExprAST::Codegen() { Function *PrototypeAST::Codegen() { // Make the function type: double(double,double) etc. - std::vector<const Type*> Doubles(Args.size(), - Type::getDoubleTy(getGlobalContext())); + std::vector<Type*> Doubles(Args.size(), + Type::getDoubleTy(getGlobalContext())); FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); @@ -1811,7 +1823,7 @@ int main() { Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-10-16 10:07:38 +0200 (Sun, 16 Oct 2011) $ diff --git a/docs/tutorial/LangImpl7.html b/docs/tutorial/LangImpl7.html index a4a21f1aed22..939987b2df60 100644 --- a/docs/tutorial/LangImpl7.html +++ b/docs/tutorial/LangImpl7.html @@ -102,19 +102,19 @@ The LLVM IR that we want for this example looks like this:

    define i32 @test(i1 %Condition) { entry: - br i1 %Condition, label %cond_true, label %cond_false + br i1 %Condition, label %cond_true, label %cond_false cond_true: - %X.0 = load i32* @G - br label %cond_next + %X.0 = load i32* @G + br label %cond_next cond_false: - %X.1 = load i32* @H - br label %cond_next + %X.1 = load i32* @H + br label %cond_next cond_next: - %X.2 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ] - ret i32 %X.2 + %X.2 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ] + ret i32 %X.2 }
    @@ -174,12 +174,12 @@ being declared with global variable definitions, they are declared with the
     define i32 @example() {
     entry:
    -	%X = alloca i32           ; type of %X is i32*.
    -	...
    -	%tmp = load i32* %X       ; load the stack value %X from the stack.
    -	%tmp2 = add i32 %tmp, 1   ; increment it
    -	store i32 %tmp2, i32* %X  ; store it back
    -	...
    +  %X = alloca i32           ; type of %X is i32*.
    +  ...
    +  %tmp = load i32* %X       ; load the stack value %X from the stack.
    +  %tmp2 = add i32 %tmp, 1   ; increment it
    +  store i32 %tmp2, i32* %X  ; store it back
    +  ...
     
    @@ -196,22 +196,22 @@ example to use the alloca technique to avoid using a PHI node:

    define i32 @test(i1 %Condition) { entry: - %X = alloca i32 ; type of %X is i32*. - br i1 %Condition, label %cond_true, label %cond_false + %X = alloca i32 ; type of %X is i32*. + br i1 %Condition, label %cond_true, label %cond_false cond_true: - %X.0 = load i32* @G - store i32 %X.0, i32* %X ; Update X - br label %cond_next + %X.0 = load i32* @G + store i32 %X.0, i32* %X ; Update X + br label %cond_next cond_false: - %X.1 = load i32* @H - store i32 %X.1, i32* %X ; Update X - br label %cond_next + %X.1 = load i32* @H + store i32 %X.1, i32* %X ; Update X + br label %cond_next cond_next: - %X.2 = load i32* %X ; Read X - ret i32 %X.2 + %X.2 = load i32* %X ; Read X + ret i32 %X.2 } @@ -242,19 +242,19 @@ $ llvm-as < example.ll | opt -mem2reg | llvm-dis define i32 @test(i1 %Condition) { entry: - br i1 %Condition, label %cond_true, label %cond_false + br i1 %Condition, label %cond_true, label %cond_false cond_true: - %X.0 = load i32* @G - br label %cond_next + %X.0 = load i32* @G + br label %cond_next cond_false: - %X.1 = load i32* @H - br label %cond_next + %X.1 = load i32* @H + br label %cond_next cond_next: - %X.01 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ] - ret i32 %X.01 + %X.01 = phi i32 [ %X.1, %cond_false ], [ %X.0, %cond_true ] + ret i32 %X.01 } @@ -542,30 +542,30 @@ recursive fib function. Before the optimization:

     define double @fib(double %x) {
     entry:
    -	%x1 = alloca double
    -	store double %x, double* %x1
    -	%x2 = load double* %x1
    -	%cmptmp = fcmp ult double %x2, 3.000000e+00
    -	%booltmp = uitofp i1 %cmptmp to double
    -	%ifcond = fcmp one double %booltmp, 0.000000e+00
    -	br i1 %ifcond, label %then, label %else
    +  %x1 = alloca double
    +  store double %x, double* %x1
    +  %x2 = load double* %x1
    +  %cmptmp = fcmp ult double %x2, 3.000000e+00
    +  %booltmp = uitofp i1 %cmptmp to double
    +  %ifcond = fcmp one double %booltmp, 0.000000e+00
    +  br i1 %ifcond, label %then, label %else
     
     then:		; preds = %entry
    -	br label %ifcont
    +  br label %ifcont
     
     else:		; preds = %entry
    -	%x3 = load double* %x1
    -	%subtmp = fsub double %x3, 1.000000e+00
    -	%calltmp = call double @fib(double %subtmp)
    -	%x4 = load double* %x1
    -	%subtmp5 = fsub double %x4, 2.000000e+00
    -	%calltmp6 = call double @fib(double %subtmp5)
    -	%addtmp = fadd double %calltmp, %calltmp6
    -	br label %ifcont
    +  %x3 = load double* %x1
    +  %subtmp = fsub double %x3, 1.000000e+00
    +  %calltmp = call double @fib(double %subtmp)
    +  %x4 = load double* %x1
    +  %subtmp5 = fsub double %x4, 2.000000e+00
    +  %calltmp6 = call double @fib(double %subtmp5)
    +  %addtmp = fadd double %calltmp, %calltmp6
    +  br label %ifcont
     
     ifcont:		; preds = %else, %then
    -	%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
    -	ret double %iftmp
    +  %iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
    +  ret double %iftmp
     }
     
    @@ -584,25 +584,25 @@ PHI node for it, so we still just make the PHI.

     define double @fib(double %x) {
     entry:
    -	%cmptmp = fcmp ult double %x, 3.000000e+00
    -	%booltmp = uitofp i1 %cmptmp to double
    -	%ifcond = fcmp one double %booltmp, 0.000000e+00
    -	br i1 %ifcond, label %then, label %else
    +  %cmptmp = fcmp ult double %x, 3.000000e+00
    +  %booltmp = uitofp i1 %cmptmp to double
    +  %ifcond = fcmp one double %booltmp, 0.000000e+00
    +  br i1 %ifcond, label %then, label %else
     
     then:
    -	br label %ifcont
    +  br label %ifcont
     
     else:
    -	%subtmp = fsub double %x, 1.000000e+00
    -	%calltmp = call double @fib(double %subtmp)
    -	%subtmp5 = fsub double %x, 2.000000e+00
    -	%calltmp6 = call double @fib(double %subtmp5)
    -	%addtmp = fadd double %calltmp, %calltmp6
    -	br label %ifcont
    +  %subtmp = fsub double %x, 1.000000e+00
    +  %calltmp = call double @fib(double %subtmp)
    +  %subtmp5 = fsub double %x, 2.000000e+00
    +  %calltmp6 = call double @fib(double %subtmp5)
    +  %addtmp = fadd double %calltmp, %calltmp6
    +  br label %ifcont
     
     ifcont:		; preds = %else, %then
    -	%iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
    -	ret double %iftmp
    +  %iftmp = phi double [ 1.000000e+00, %then ], [ %addtmp, %else ]
    +  ret double %iftmp
     }
     
    @@ -617,21 +617,21 @@ such blatent inefficiencies :).

     define double @fib(double %x) {
     entry:
    -	%cmptmp = fcmp ult double %x, 3.000000e+00
    -	%booltmp = uitofp i1 %cmptmp to double
    -	%ifcond = fcmp ueq double %booltmp, 0.000000e+00
    -	br i1 %ifcond, label %else, label %ifcont
    +  %cmptmp = fcmp ult double %x, 3.000000e+00
    +  %booltmp = uitofp i1 %cmptmp to double
    +  %ifcond = fcmp ueq double %booltmp, 0.000000e+00
    +  br i1 %ifcond, label %else, label %ifcont
     
     else:
    -	%subtmp = fsub double %x, 1.000000e+00
    -	%calltmp = call double @fib(double %subtmp)
    -	%subtmp5 = fsub double %x, 2.000000e+00
    -	%calltmp6 = call double @fib(double %subtmp5)
    -	%addtmp = fadd double %calltmp, %calltmp6
    -	ret double %addtmp
    +  %subtmp = fsub double %x, 1.000000e+00
    +  %calltmp = call double @fib(double %subtmp)
    +  %subtmp5 = fsub double %x, 2.000000e+00
    +  %calltmp6 = call double @fib(double %subtmp5)
    +  %addtmp = fadd double %calltmp, %calltmp6
    +  ret double %addtmp
     
     ifcont:
    -	ret double 1.000000e+00
    +  ret double 1.000000e+00
     }
     
    @@ -988,10 +988,10 @@ variables and var/in support. To build this example, use:
    -   # Compile
    -   g++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
    -   # Run
    -   ./toy
    +# Compile
    +clang++ -g toy.cpp `llvm-config --cppflags --ldflags --libs core jit native` -O3 -o toy
    +# Run
    +./toy
     
    @@ -1008,9 +1008,9 @@ variables and var/in support. To build this example, use: #include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Passes.h" #include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetSelect.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/IRBuilder.h" +#include "llvm/Support/TargetSelect.h" #include <cstdio> #include <string> #include <map> @@ -1686,8 +1686,8 @@ Value *BinaryExprAST::Codegen() { Function *F = TheModule->getFunction(std::string("binary")+Op); assert(F && "binary operator not found!"); - Value *Ops[] = { L, R }; - return Builder.CreateCall(F, Ops, Ops+2, "binop"); + Value *Ops[2] = { L, R }; + return Builder.CreateCall(F, Ops, "binop"); } Value *CallExprAST::Codegen() { @@ -1706,7 +1706,7 @@ Value *CallExprAST::Codegen() { if (ArgsV.back() == 0) return 0; } - return Builder.CreateCall(CalleeF, ArgsV.begin(), ArgsV.end(), "calltmp"); + return Builder.CreateCall(CalleeF, ArgsV, "calltmp"); } Value *IfExprAST::Codegen() { @@ -1907,8 +1907,8 @@ Value *VarExprAST::Codegen() { Function *PrototypeAST::Codegen() { // Make the function type: double(double,double) etc. - std::vector<const Type*> Doubles(Args.size(), - Type::getDoubleTy(getGlobalContext())); + std::vector<Type*> Doubles(Args.size(), + Type::getDoubleTy(getGlobalContext())); FunctionType *FT = FunctionType::get(Type::getDoubleTy(getGlobalContext()), Doubles, false); @@ -2158,7 +2158,7 @@ int main() { Chris Lattner
    The LLVM Compiler Infrastructure
    - Last modified: $Date: 2011-04-23 02:30:22 +0200 (Sat, 23 Apr 2011) $ + Last modified: $Date: 2011-10-16 10:07:38 +0200 (Sun, 16 Oct 2011) $ diff --git a/docs/tutorial/Makefile b/docs/tutorial/Makefile index 9082ad4d8575..fdf1bb68a726 100644 --- a/docs/tutorial/Makefile +++ b/docs/tutorial/Makefile @@ -11,6 +11,7 @@ LEVEL := ../.. include $(LEVEL)/Makefile.common HTML := $(wildcard $(PROJ_SRC_DIR)/*.html) +PNG := $(wildcard $(PROJ_SRC_DIR)/*.png) EXTRA_DIST := $(HTML) index.html HTML_DIR := $(DESTDIR)$(PROJ_docsdir)/html/tutorial @@ -18,6 +19,7 @@ install-local:: $(HTML) $(Echo) Installing HTML Tutorial Documentation $(Verb) $(MKDIR) $(HTML_DIR) $(Verb) $(DataInstall) $(HTML) $(HTML_DIR) + $(Verb) $(DataInstall) $(PNG) $(HTML_DIR) $(Verb) $(DataInstall) $(PROJ_SRC_DIR)/index.html $(HTML_DIR) uninstall-local:: diff --git a/examples/BrainF/BrainF.cpp b/examples/BrainF/BrainF.cpp index 67af099d1d3a..df6687f2805e 100644 --- a/examples/BrainF/BrainF.cpp +++ b/examples/BrainF/BrainF.cpp @@ -80,8 +80,8 @@ void BrainF::header(LLVMContext& C) { //%arr = malloc i8, i32 %d ConstantInt *val_mem = ConstantInt::get(C, APInt(32, memtotal)); BasicBlock* BB = builder->GetInsertBlock(); - const Type* IntPtrTy = IntegerType::getInt32Ty(C); - const Type* Int8Ty = IntegerType::getInt8Ty(C); + Type* IntPtrTy = IntegerType::getInt32Ty(C); + Type* Int8Ty = IntegerType::getInt8Ty(C); Constant* allocsize = ConstantExpr::getSizeOf(Int8Ty); allocsize = ConstantExpr::getTruncOrBitCast(allocsize, IntPtrTy); ptr_arr = CallInst::CreateMalloc(BB, IntPtrTy, Int8Ty, allocsize, val_mem, @@ -162,8 +162,7 @@ void BrainF::header(LLVMContext& C) { }; Constant *msgptr = ConstantExpr:: - getGetElementPtr(aberrormsg, gep_params, - array_lengthof(gep_params)); + getGetElementPtr(aberrormsg, gep_params); Value *puts_params[] = { msgptr diff --git a/examples/BrainF/BrainFDriver.cpp b/examples/BrainF/BrainFDriver.cpp index c11a58067e8d..cdbf02a61bca 100644 --- a/examples/BrainF/BrainFDriver.cpp +++ b/examples/BrainF/BrainFDriver.cpp @@ -31,9 +31,9 @@ #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/ExecutionEngine/JIT.h" -#include "llvm/Target/TargetSelect.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include #include diff --git a/examples/ExceptionDemo/ExceptionDemo.cpp b/examples/ExceptionDemo/ExceptionDemo.cpp index e5d94514464c..20516a783b9d 100644 --- a/examples/ExceptionDemo/ExceptionDemo.cpp +++ b/examples/ExceptionDemo/ExceptionDemo.cpp @@ -40,7 +40,8 @@ // // 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. +// type info type of 7 is explained by: example in rules 1.6.4 in +// http://sourcery.mentor.com/public/cxx-abi/abi-eh.html (v1.22) // // This code uses code from the llvm compiler-rt project and the llvm // Kaleidoscope project. @@ -56,11 +57,16 @@ #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 "llvm/Support/TargetSelect.h" + +#ifdef OLD_EXC_SYSTEM +// See use of UpgradeExceptionHandling(...) below +#include "llvm/AutoUpgrade.h" +#endif // FIXME: Although all systems tested with (Linux, OS X), do not need this // header file included. A user on ubuntu reported, undefined symbols @@ -81,7 +87,7 @@ #endif // System C++ ABI unwind types from: -// http://refspecs.freestandards.org/abi-eh-1.21.html +// http://sourcery.mentor.com/public/cxx-abi/abi-eh.html (v1.22) extern "C" { @@ -182,6 +188,9 @@ static std::vector ourTypeInfoNames; static std::map ourTypeInfoNamesIndex; static llvm::StructType *ourTypeInfoType; +#ifndef OLD_EXC_SYSTEM +static llvm::StructType *ourCaughtResultType; +#endif static llvm::StructType *ourExceptionType; static llvm::StructType *ourUnwindExceptionType; @@ -209,7 +218,7 @@ typedef std::vector ArgTypes; /// @param isVarArg function uses vararg arguments /// @returns function instance llvm::Function *createFunction(llvm::Module &module, - const llvm::Type *retType, + llvm::Type *retType, const ArgTypes &theArgTypes, const ArgNames &theArgNames, const std::string &functName, @@ -246,7 +255,7 @@ llvm::Function *createFunction(llvm::Module &module, /// @returns AllocaInst instance static llvm::AllocaInst *createEntryBlockAlloca(llvm::Function &function, const std::string &varName, - const llvm::Type *type, + llvm::Type *type, llvm::Constant *initWith = 0) { llvm::BasicBlock &block = function.getEntryBlock(); llvm::IRBuilder<> tmp(&block, block.begin()); @@ -893,9 +902,8 @@ void generateStringPrint(llvm::LLVMContext &context, builder.CreateStore(stringConstant, stringVar); } - llvm::Value *cast = - builder.CreatePointerCast(stringVar, - builder.getInt8PtrTy()); + llvm::Value *cast = builder.CreatePointerCast(stringVar, + builder.getInt8PtrTy()); builder.CreateCall(printFunct, cast); } @@ -937,9 +945,8 @@ void generateIntegerPrint(llvm::LLVMContext &context, builder.CreateStore(stringConstant, stringVar); } - llvm::Value *cast = - builder.CreateBitCast(stringVar, - builder.getInt8PtrTy()); + llvm::Value *cast = builder.CreateBitCast(stringVar, + builder.getInt8PtrTy()); builder.CreateCall2(&printFunct, &toPrint, cast); } @@ -962,6 +969,9 @@ void generateIntegerPrint(llvm::LLVMContext &context, /// @param unwindResumeBlock unwind resume block /// @param exceptionCaughtFlag reference exception caught/thrown status storage /// @param exceptionStorage reference to exception pointer storage +#ifndef OLD_EXC_SYSTEM +/// @param caughtResultStorage reference to landingpad result storage +#endif /// @returns newly created block static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context, llvm::Module &module, @@ -972,28 +982,42 @@ static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context, llvm::BasicBlock &terminatorBlock, llvm::BasicBlock &unwindResumeBlock, llvm::Value **exceptionCaughtFlag, - llvm::Value **exceptionStorage) { + llvm::Value **exceptionStorage +#ifndef OLD_EXC_SYSTEM + ,llvm::Value **caughtResultStorage +#endif + ) { assert(exceptionCaughtFlag && "ExceptionDemo::createFinallyBlock(...):exceptionCaughtFlag " "is NULL"); assert(exceptionStorage && "ExceptionDemo::createFinallyBlock(...):exceptionStorage " "is NULL"); + +#ifndef OLD_EXC_SYSTEM + assert(caughtResultStorage && + "ExceptionDemo::createFinallyBlock(...):caughtResultStorage " + "is NULL"); +#endif - *exceptionCaughtFlag = - createEntryBlockAlloca(toAddTo, - "exceptionCaught", - ourExceptionNotThrownState->getType(), - ourExceptionNotThrownState); + *exceptionCaughtFlag = createEntryBlockAlloca(toAddTo, + "exceptionCaught", + ourExceptionNotThrownState->getType(), + ourExceptionNotThrownState); - const llvm::PointerType *exceptionStorageType = - builder.getInt8PtrTy(); - *exceptionStorage = - createEntryBlockAlloca(toAddTo, - "exceptionStorage", - exceptionStorageType, - llvm::ConstantPointerNull::get( - exceptionStorageType)); + llvm::PointerType *exceptionStorageType = builder.getInt8PtrTy(); + *exceptionStorage = createEntryBlockAlloca(toAddTo, + "exceptionStorage", + exceptionStorageType, + llvm::ConstantPointerNull::get( + exceptionStorageType)); +#ifndef OLD_EXC_SYSTEM + *caughtResultStorage = createEntryBlockAlloca(toAddTo, + "caughtResultStorage", + ourCaughtResultType, + llvm::ConstantAggregateZero::get( + ourCaughtResultType)); +#endif llvm::BasicBlock *ret = llvm::BasicBlock::Create(context, blockName, @@ -1010,10 +1034,10 @@ static llvm::BasicBlock *createFinallyBlock(llvm::LLVMContext &context, bufferToPrint.str(), USE_GLOBAL_STR_CONSTS); - llvm::SwitchInst *theSwitch = - builder.CreateSwitch(builder.CreateLoad(*exceptionCaughtFlag), - &terminatorBlock, - 2); + llvm::SwitchInst *theSwitch = builder.CreateSwitch(builder.CreateLoad( + *exceptionCaughtFlag), + &terminatorBlock, + 2); theSwitch->addCase(ourExceptionCaughtState, &terminatorBlock); theSwitch->addCase(ourExceptionThrownState, &unwindResumeBlock); @@ -1121,29 +1145,35 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, "normal", ret); // Unwind block for invoke - llvm::BasicBlock *exceptionBlock = - llvm::BasicBlock::Create(context, "exception", ret); + 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); + llvm::BasicBlock *exceptionRouteBlock = llvm::BasicBlock::Create(context, + "exceptionRoute", + ret); // Foreign exception handler - llvm::BasicBlock *externalExceptionBlock = - llvm::BasicBlock::Create(context, "externalException", ret); + llvm::BasicBlock *externalExceptionBlock = llvm::BasicBlock::Create(context, + "externalException", + ret); // Block which calls _Unwind_Resume - llvm::BasicBlock *unwindResumeBlock = - llvm::BasicBlock::Create(context, "unwindResume", ret); + 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); + llvm::BasicBlock *endBlock = llvm::BasicBlock::Create(context, "end", ret); std::string nextName; std::vector catchBlocks(numExceptionsToCatch); llvm::Value *exceptionCaughtFlag = NULL; llvm::Value *exceptionStorage = NULL; +#ifndef OLD_EXC_SYSTEM + llvm::Value *caughtResultStorage = NULL; +#endif // Finally block which will branch to unwindResumeBlock if // exception is not caught. Initializes/allocates stack locations. @@ -1156,7 +1186,11 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, *endBlock, *unwindResumeBlock, &exceptionCaughtFlag, - &exceptionStorage); + &exceptionStorage +#ifndef OLD_EXC_SYSTEM + ,&caughtResultStorage +#endif + ); for (unsigned i = 0; i < numExceptionsToCatch; ++i) { nextName = ourTypeInfoNames[exceptionTypesToCatch[i]]; @@ -1181,8 +1215,7 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, builder.CreateInvoke(&toInvoke, normalBlock, exceptionBlock, - args.begin(), - args.end()); + args); // End Block @@ -1193,8 +1226,7 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, builder, "Gen: In end block: exiting in " + ourId + ".\n", USE_GLOBAL_STR_CONSTS); - llvm::Function *deleteOurException = - module.getFunction("deleteOurException"); + llvm::Function *deleteOurException = module.getFunction("deleteOurException"); // Note: function handles NULL exceptions builder.CreateCall(deleteOurException, @@ -1218,28 +1250,57 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, builder.SetInsertPoint(unwindResumeBlock); - llvm::Function *resumeOurException = - module.getFunction("_Unwind_Resume"); + +#ifndef OLD_EXC_SYSTEM + builder.CreateResume(builder.CreateLoad(caughtResultStorage)); +#else + llvm::Function *resumeOurException = module.getFunction("_Unwind_Resume"); builder.CreateCall(resumeOurException, builder.CreateLoad(exceptionStorage)); builder.CreateUnreachable(); +#endif // Exception Block builder.SetInsertPoint(exceptionBlock); - llvm::Function *ehException = module.getFunction("llvm.eh.exception"); + llvm::Function *personality = module.getFunction("ourPersonality"); +#ifndef OLD_EXC_SYSTEM + llvm::LandingPadInst *caughtResult = + builder.CreateLandingPad(ourCaughtResultType, + personality, + numExceptionsToCatch, + "landingPad"); + + caughtResult->setCleanup(true); + + for (unsigned i = 0; i < numExceptionsToCatch; ++i) { + // Set up type infos to be caught + caughtResult->addClause(module.getGlobalVariable( + ourTypeInfoNames[exceptionTypesToCatch[i]])); + } + + llvm::Value *unwindException = builder.CreateExtractValue(caughtResult, 0); + llvm::Value *retTypeInfoIndex = builder.CreateExtractValue(caughtResult, 1); + + // FIXME: Redundant storage which, beyond utilizing value of + // caughtResultStore for unwindException storage, may be alleviated + // alltogether with a block rearrangement + builder.CreateStore(caughtResult, caughtResultStorage); + builder.CreateStore(unwindException, exceptionStorage); + builder.CreateStore(ourExceptionThrownState, exceptionCaughtFlag); +#else + 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.getInt8PtrTy()); + llvm::Value *functPtr = builder.CreatePointerCast(personality, + builder.getInt8PtrTy()); args.clear(); args.push_back(unwindException); @@ -1263,9 +1324,8 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, // 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()); + llvm::Value *retTypeInfoIndex = builder.CreateCall(ehSelector, args); +#endif // Retrieve exception_class member from thrown exception // (_Unwind_Exception instance). This member tells us whether or not @@ -1305,10 +1365,10 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, // (OurException instance). // // Note: ourBaseFromUnwindOffset is usually negative - llvm::Value *typeInfoThrown = - builder.CreatePointerCast(builder.CreateConstGEP1_64(unwindException, + llvm::Value *typeInfoThrown = builder.CreatePointerCast( + builder.CreateConstGEP1_64(unwindException, ourBaseFromUnwindOffset), - ourExceptionType->getPointerTo()); + ourExceptionType->getPointerTo()); // Retrieve thrown exception type info type // @@ -1331,10 +1391,9 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, USE_GLOBAL_STR_CONSTS); // Route to matched type info catch block or run cleanup finally block - llvm::SwitchInst *switchToCatchBlock = - builder.CreateSwitch(retTypeInfoIndex, - finallyBlock, - numExceptionsToCatch); + llvm::SwitchInst *switchToCatchBlock = builder.CreateSwitch(retTypeInfoIndex, + finallyBlock, + numExceptionsToCatch); unsigned nextTypeToCatch; @@ -1344,6 +1403,12 @@ llvm::Function *createCatchWrappedInvokeFunction(llvm::Module &module, llvm::Type::getInt32Ty(context), i), catchBlocks[nextTypeToCatch]); } + +#ifdef OLD_EXC_SYSTEM + // Must be run before verifier + UpgradeExceptionHandling(&module); +#endif + llvm::verifyFunction(*ret); fpm.run(*ret); @@ -1395,15 +1460,13 @@ llvm::Function *createThrowExceptionFunction(llvm::Module &module, "entry", ret); // Throws a foreign exception - llvm::BasicBlock *nativeThrowBlock = - llvm::BasicBlock::Create(context, - "nativeThrow", - ret); + llvm::BasicBlock *nativeThrowBlock = llvm::BasicBlock::Create(context, + "nativeThrow", + ret); // Throws one of our Exceptions - llvm::BasicBlock *generatedThrowBlock = - llvm::BasicBlock::Create(context, - "generatedThrow", - ret); + llvm::BasicBlock *generatedThrowBlock = llvm::BasicBlock::Create(context, + "generatedThrow", + ret); // Retrieved runtime type info type to throw llvm::Value *exceptionType = namedValues["exceptTypeToThrow"]; @@ -1445,15 +1508,13 @@ llvm::Function *createThrowExceptionFunction(llvm::Module &module, builder.SetInsertPoint(generatedThrowBlock); - llvm::Function *createOurException = - module.getFunction("createOurException"); - llvm::Function *raiseOurException = - module.getFunction("_Unwind_RaiseException"); + 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"]); + llvm::Value *exception = builder.CreateCall(createOurException, + namedValues["exceptTypeToThrow"]); // Throw generated Exception builder.CreateCall(raiseOurException, exception); @@ -1501,32 +1562,29 @@ llvm::Function *createUnwindExceptionTest(llvm::Module &module, createStandardUtilityFunctions(numTypeInfos, module, builder); - llvm::Function *nativeThrowFunct = - module.getFunction(nativeThrowFunctName); + 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); + 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); + sizeof(unsigned); // Generate inner function. - llvm::Function *innerCatchFunct = - createCatchWrappedInvokeFunction(module, - builder, - fpm, - *throwFunct, - "innerCatchFunct", - numExceptionTypesToCatch, - innerExceptionTypesToCatch); + llvm::Function *innerCatchFunct = createCatchWrappedInvokeFunction(module, + builder, + fpm, + *throwFunct, + "innerCatchFunct", + numExceptionTypesToCatch, + innerExceptionTypesToCatch); // Outer function will catch odd type infos unsigned outerExceptionTypesToCatch[] = {3, 1, 5}; @@ -1534,14 +1592,13 @@ llvm::Function *createUnwindExceptionTest(llvm::Module &module, sizeof(unsigned); // Generate outer function - llvm::Function *outerCatchFunct = - createCatchWrappedInvokeFunction(module, - builder, - fpm, - *innerCatchFunct, - "outerCatchFunct", - numExceptionTypesToCatch, - outerExceptionTypesToCatch); + llvm::Function *outerCatchFunct = createCatchWrappedInvokeFunction(module, + builder, + fpm, + *innerCatchFunct, + "outerCatchFunct", + numExceptionTypesToCatch, + outerExceptionTypesToCatch); // Return outer function to run return(outerCatchFunct); @@ -1607,12 +1664,12 @@ void runExceptionThrow(llvm::ExecutionEngine *engine, 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. - + // Catch all exceptions including our generated ones. This latter + // functionality works according to the example in rules 1.6.4 of + // http://sourcery.mentor.com/public/cxx-abi/abi-eh.html (v1.22), + // given that these will be exceptions foreign to C++ + // (the _Unwind_Exception::exception_class should be different from + // the one used by C++). fprintf(stderr, "\nrunExceptionThrow(...):In C++ catch all.\n"); } @@ -1640,17 +1697,31 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, // Setup exception catch state ourExceptionNotThrownState = - llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 0), + llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 0), ourExceptionThrownState = - llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 1), + llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 1), ourExceptionCaughtState = - llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 2), + llvm::ConstantInt::get(llvm::Type::getInt8Ty(context), 2), // Create our type info type ourTypeInfoType = llvm::StructType::get(context, - TypeArray(builder.getInt32Ty())); + TypeArray(builder.getInt32Ty())); + +#ifndef OLD_EXC_SYSTEM + + llvm::Type *caughtResultFieldTypes[] = { + builder.getInt8PtrTy(), + builder.getInt32Ty() + }; + + // Create our landingpad result type + ourCaughtResultType = llvm::StructType::get(context, + TypeArray(caughtResultFieldTypes)); + +#endif + // Create OurException type ourExceptionType = llvm::StructType::get(context, TypeArray(ourTypeInfoType)); @@ -1667,7 +1738,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, // Calculate offset of OurException::unwindException member. ourBaseFromUnwindOffset = ((uintptr_t) &dummyException) - - ((uintptr_t) &(dummyException.unwindException)); + ((uintptr_t) &(dummyException.unwindException)); #ifdef DEBUG fprintf(stderr, @@ -1724,7 +1795,7 @@ static void createStandardUtilityFunctions(unsigned numTypeInfos, // print32Int - const llvm::Type *retType = builder.getVoidTy(); + llvm::Type *retType = builder.getVoidTy(); argTypes.clear(); argTypes.push_back(builder.getInt32Ty()); diff --git a/examples/Fibonacci/fibonacci.cpp b/examples/Fibonacci/fibonacci.cpp index a7bbf8c72684..a7d1ca8ff6a2 100644 --- a/examples/Fibonacci/fibonacci.cpp +++ b/examples/Fibonacci/fibonacci.cpp @@ -33,7 +33,7 @@ #include "llvm/ExecutionEngine/Interpreter.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetSelect.h" +#include "llvm/Support/TargetSelect.h" using namespace llvm; static Function *CreateFibFunction(Module *M, LLVMContext &Context) { diff --git a/examples/HowToUseJIT/HowToUseJIT.cpp b/examples/HowToUseJIT/HowToUseJIT.cpp index 2fb2b5e872d1..92b2860eec3f 100644 --- a/examples/HowToUseJIT/HowToUseJIT.cpp +++ b/examples/HowToUseJIT/HowToUseJIT.cpp @@ -42,7 +42,7 @@ #include "llvm/ExecutionEngine/JIT.h" #include "llvm/ExecutionEngine/Interpreter.h" #include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/Target/TargetSelect.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/IRBuilder.h" diff --git a/examples/Kaleidoscope/Chapter4/toy.cpp b/examples/Kaleidoscope/Chapter4/toy.cpp index 1bed182ab54e..9a283229b93a 100644 --- a/examples/Kaleidoscope/Chapter4/toy.cpp +++ b/examples/Kaleidoscope/Chapter4/toy.cpp @@ -7,9 +7,9 @@ #include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Passes.h" #include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetSelect.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/IRBuilder.h" +#include "llvm/Support/TargetSelect.h" #include #include #include diff --git a/examples/Kaleidoscope/Chapter5/toy.cpp b/examples/Kaleidoscope/Chapter5/toy.cpp index 58ab6f3990ef..adfbad507417 100644 --- a/examples/Kaleidoscope/Chapter5/toy.cpp +++ b/examples/Kaleidoscope/Chapter5/toy.cpp @@ -7,9 +7,9 @@ #include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Passes.h" #include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetSelect.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/IRBuilder.h" +#include "llvm/Support/TargetSelect.h" #include #include #include diff --git a/examples/Kaleidoscope/Chapter6/toy.cpp b/examples/Kaleidoscope/Chapter6/toy.cpp index b25e946cc2d6..c16d6bdb5b56 100644 --- a/examples/Kaleidoscope/Chapter6/toy.cpp +++ b/examples/Kaleidoscope/Chapter6/toy.cpp @@ -7,9 +7,9 @@ #include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Passes.h" #include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetSelect.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/IRBuilder.h" +#include "llvm/Support/TargetSelect.h" #include #include #include diff --git a/examples/Kaleidoscope/Chapter7/toy.cpp b/examples/Kaleidoscope/Chapter7/toy.cpp index 63a7bca29df4..87b28c305601 100644 --- a/examples/Kaleidoscope/Chapter7/toy.cpp +++ b/examples/Kaleidoscope/Chapter7/toy.cpp @@ -7,9 +7,9 @@ #include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Passes.h" #include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetSelect.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/IRBuilder.h" +#include "llvm/Support/TargetSelect.h" #include #include #include diff --git a/examples/ParallelJIT/ParallelJIT.cpp b/examples/ParallelJIT/ParallelJIT.cpp index 9231abf6e31e..3e483275edbb 100644 --- a/examples/ParallelJIT/ParallelJIT.cpp +++ b/examples/ParallelJIT/ParallelJIT.cpp @@ -26,7 +26,7 @@ #include "llvm/ExecutionEngine/JIT.h" #include "llvm/ExecutionEngine/Interpreter.h" #include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/Target/TargetSelect.h" +#include "llvm/Support/TargetSelect.h" #include using namespace llvm; diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index a4456dd13e4b..d23b91c4e0de 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -115,7 +115,10 @@ typedef enum { LLVMNoImplicitFloatAttribute = 1<<23, LLVMNakedAttribute = 1<<24, LLVMInlineHintAttribute = 1<<25, - LLVMStackAlignment = 7<<26 + LLVMStackAlignment = 7<<26, + LLVMReturnsTwice = 1 << 29, + LLVMUWTable = 1 << 30, + LLVMNonLazyBind = 1 << 31 } LLVMAttribute; typedef enum { @@ -125,7 +128,7 @@ typedef enum { LLVMSwitch = 3, LLVMIndirectBr = 4, LLVMInvoke = 5, - LLVMUnwind = 6, + /* removed 6 due to API changes */ LLVMUnreachable = 7, /* Standard Binary Operators */ @@ -176,14 +179,26 @@ typedef enum { LLVMPHI = 44, LLVMCall = 45, LLVMSelect = 46, - /* UserOp1 */ - /* UserOp2 */ + LLVMUserOp1 = 47, + LLVMUserOp2 = 48, LLVMVAArg = 49, LLVMExtractElement = 50, LLVMInsertElement = 51, LLVMShuffleVector = 52, LLVMExtractValue = 53, - LLVMInsertValue = 54 + LLVMInsertValue = 54, + + /* Atomic operators */ + LLVMFence = 55, + LLVMAtomicCmpXchg = 56, + LLVMAtomicRMW = 57, + + /* Exception Handling Operators */ + LLVMResume = 58, + LLVMLandingPad = 59, + LLVMUnwind = 60 + + } LLVMOpcode; typedef enum { @@ -274,6 +289,11 @@ typedef enum { LLVMRealPredicateTrue /**< Always true (always folded) */ } LLVMRealPredicate; +typedef enum { + LLVMLandingPadCatch, /**< A catch clause */ + LLVMLandingPadFilter /**< A filter clause */ +} LLVMLandingPadClauseTy; + void LLVMInitializeCore(LLVMPassRegistryRef R); @@ -340,6 +360,7 @@ LLVMContextRef LLVMGetModuleContext(LLVMModuleRef M); /** See llvm::LLVMTypeKind::getTypeID. */ LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty); +LLVMBool LLVMTypeIsSized(LLVMTypeRef Ty); /** See llvm::LLVMType::getContext. */ LLVMContextRef LLVMGetTypeContext(LLVMTypeRef Ty); @@ -388,6 +409,7 @@ LLVMTypeRef LLVMStructTypeInContext(LLVMContextRef C, LLVMTypeRef *ElementTypes, LLVMTypeRef LLVMStructType(LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMBool Packed); LLVMTypeRef LLVMStructCreateNamed(LLVMContextRef C, const char *Name); +const char *LLVMGetStructName(LLVMTypeRef Ty); void LLVMStructSetBody(LLVMTypeRef StructTy, LLVMTypeRef *ElementTypes, unsigned ElementCount, LLVMBool Packed); @@ -427,8 +449,11 @@ LLVMTypeRef LLVMX86MMXType(void); macro(Argument) \ macro(BasicBlock) \ macro(InlineAsm) \ + macro(MDNode) \ + macro(MDString) \ macro(User) \ macro(Constant) \ + macro(BlockAddress) \ macro(ConstantAggregateZero) \ macro(ConstantArray) \ macro(ConstantExpr) \ @@ -448,29 +473,32 @@ LLVMTypeRef LLVMX86MMXType(void); macro(IntrinsicInst) \ macro(DbgInfoIntrinsic) \ macro(DbgDeclareInst) \ + macro(EHExceptionInst) \ macro(EHSelectorInst) \ macro(MemIntrinsic) \ macro(MemCpyInst) \ macro(MemMoveInst) \ macro(MemSetInst) \ macro(CmpInst) \ - macro(FCmpInst) \ - macro(ICmpInst) \ + macro(FCmpInst) \ + macro(ICmpInst) \ macro(ExtractElementInst) \ macro(GetElementPtrInst) \ macro(InsertElementInst) \ macro(InsertValueInst) \ + macro(LandingPadInst) \ macro(PHINode) \ macro(SelectInst) \ macro(ShuffleVectorInst) \ macro(StoreInst) \ macro(TerminatorInst) \ macro(BranchInst) \ + macro(IndirectBrInst) \ macro(InvokeInst) \ macro(ReturnInst) \ macro(SwitchInst) \ macro(UnreachableInst) \ - macro(UnwindInst) \ + macro(ResumeInst) \ macro(UnaryInstruction) \ macro(AllocaInst) \ macro(CastInst) \ @@ -533,6 +561,11 @@ LLVMValueRef LLVMMDString(const char *Str, unsigned SLen); LLVMValueRef LLVMMDNodeInContext(LLVMContextRef C, LLVMValueRef *Vals, unsigned Count); LLVMValueRef LLVMMDNode(LLVMValueRef *Vals, unsigned Count); +const char *LLVMGetMDString(LLVMValueRef V, unsigned* Len); +int LLVMGetMDNodeNumOperands(LLVMValueRef V); +LLVMValueRef *LLVMGetMDNodeOperand(LLVMValueRef V, unsigned i); +unsigned LLVMGetNamedMetadataNumOperands(LLVMModuleRef M, const char* name); +void LLVMGetNamedMetadataOperands(LLVMModuleRef M, const char* name, LLVMValueRef *Dest); /* Operations on scalar constants */ LLVMValueRef LLVMConstInt(LLVMTypeRef IntTy, unsigned long long N, @@ -728,6 +761,7 @@ LLVMValueRef LLVMBasicBlockAsValue(LLVMBasicBlockRef BB); LLVMBool LLVMValueIsBasicBlock(LLVMValueRef Val); LLVMBasicBlockRef LLVMValueAsBasicBlock(LLVMValueRef Val); LLVMValueRef LLVMGetBasicBlockParent(LLVMBasicBlockRef BB); +LLVMValueRef LLVMGetBasicBlockTerminator(LLVMBasicBlockRef BB); unsigned LLVMCountBasicBlocks(LLVMValueRef Fn); void LLVMGetBasicBlocks(LLVMValueRef Fn, LLVMBasicBlockRef *BasicBlocks); LLVMBasicBlockRef LLVMGetFirstBasicBlock(LLVMValueRef Fn); @@ -747,16 +781,21 @@ LLVMBasicBlockRef LLVMAppendBasicBlock(LLVMValueRef Fn, const char *Name); LLVMBasicBlockRef LLVMInsertBasicBlock(LLVMBasicBlockRef InsertBeforeBB, const char *Name); void LLVMDeleteBasicBlock(LLVMBasicBlockRef BB); +void LLVMRemoveBasicBlockFromParent(LLVMBasicBlockRef BB); void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos); void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef BB, LLVMBasicBlockRef MovePos); -/* Operations on instructions */ -LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst); LLVMValueRef LLVMGetFirstInstruction(LLVMBasicBlockRef BB); LLVMValueRef LLVMGetLastInstruction(LLVMBasicBlockRef BB); + +/* Operations on instructions */ +LLVMBasicBlockRef LLVMGetInstructionParent(LLVMValueRef Inst); LLVMValueRef LLVMGetNextInstruction(LLVMValueRef Inst); LLVMValueRef LLVMGetPreviousInstruction(LLVMValueRef Inst); +void LLVMInstructionEraseFromParent(LLVMValueRef Inst); +LLVMOpcode LLVMGetInstructionOpcode(LLVMValueRef Inst); +LLVMIntPredicate LLVMGetICmpPredicate(LLVMValueRef Inst); /* Operations on call sites */ void LLVMSetInstructionCallConv(LLVMValueRef Instr, unsigned CC); @@ -771,6 +810,9 @@ void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index, LLVMBool LLVMIsTailCall(LLVMValueRef CallInst); void LLVMSetTailCall(LLVMValueRef CallInst, LLVMBool IsTailCall); +/* Operations on switch instructions (only) */ +LLVMBasicBlockRef LLVMGetSwitchDefaultDest(LLVMValueRef SwitchInstr); + /* Operations on phi nodes */ void LLVMAddIncoming(LLVMValueRef PhiNode, LLVMValueRef *IncomingValues, LLVMBasicBlockRef *IncomingBlocks, unsigned Count); @@ -818,7 +860,10 @@ LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, const char *Name); -LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef); +LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty, + LLVMValueRef PersFn, unsigned NumClauses, + const char *Name); +LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn); LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef); /* Add a case to the switch instruction */ @@ -828,6 +873,12 @@ void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal, /* Add a destination to the indirectbr instruction */ void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest); +/* Add a catch or filter clause to the landingpad instruction */ +void LLVMAddClause(LLVMValueRef LandingPad, LLVMValueRef ClauseVal); + +/* Set the 'cleanup' flag in the landingpad instruction */ +void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val); + /* Arithmetic */ LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); @@ -1136,7 +1187,7 @@ namespace llvm { return reinterpret_cast(Tys); } - inline LLVMTypeRef *wrap(const Type **Tys) { + inline LLVMTypeRef *wrap(Type **Tys) { return reinterpret_cast(const_cast(Tys)); } diff --git a/include/llvm-c/Disassembler.h b/include/llvm-c/Disassembler.h index 3a3eb235e983..bf2f2767cd34 100644 --- a/include/llvm-c/Disassembler.h +++ b/include/llvm-c/Disassembler.h @@ -66,7 +66,7 @@ typedef int (*LLVMOpInfoCallback)(void *DisInfo, uint64_t PC, */ struct LLVMOpInfoSymbol1 { uint64_t Present; /* 1 if this symbol is present */ - char *Name; /* symbol name if not NULL */ + const char *Name; /* symbol name if not NULL */ uint64_t Value; /* symbol value if name is NULL */ }; @@ -93,11 +93,35 @@ struct LLVMOpInfo1 { * disassembler for things like adding a comment for a PC plus a constant * offset load instruction to use a symbol name instead of a load address value. * It is passed the block information is saved when the disassembler context is - * created and a value of a symbol to look up. If no symbol is found NULL is - * returned. + * created and the ReferenceValue to look up as a symbol. If no symbol is found + * for the ReferenceValue NULL is returned. The ReferenceType of the + * instruction is passed indirectly as is the PC of the instruction in + * ReferencePC. If the output reference can be determined its type is returned + * indirectly in ReferenceType along with ReferenceName if any, or that is set + * to NULL. */ typedef const char *(*LLVMSymbolLookupCallback)(void *DisInfo, - uint64_t SymbolValue); + uint64_t ReferenceValue, + uint64_t *ReferenceType, + uint64_t ReferencePC, + const char **ReferenceName); +/** + * The reference types on input and output. + */ +/* No input reference type or no output reference type. */ +#define LLVMDisassembler_ReferenceType_InOut_None 0 + +/* The input reference is from a branch instruction. */ +#define LLVMDisassembler_ReferenceType_In_Branch 1 +/* The input reference is from a PC relative load instruction. */ +#define LLVMDisassembler_ReferenceType_In_PCrel_Load 2 + +/* The output reference is to as symbol stub. */ +#define LLVMDisassembler_ReferenceType_Out_SymbolStub 1 +/* The output reference is to a symbol address in a literal pool. */ +#define LLVMDisassembler_ReferenceType_Out_LitPool_SymAddr 2 +/* The output reference is to a cstring address in a literal pool. */ +#define LLVMDisassembler_ReferenceType_Out_LitPool_CstrAddr 3 #ifdef __cplusplus extern "C" { diff --git a/include/llvm-c/Object.h b/include/llvm-c/Object.h index 6e72b5946644..7b1cf717f777 100644 --- a/include/llvm-c/Object.h +++ b/include/llvm-c/Object.h @@ -59,14 +59,14 @@ namespace llvm { return reinterpret_cast(const_cast(OF)); } - inline ObjectFile::section_iterator *unwrap(LLVMSectionIteratorRef SI) { - return reinterpret_cast(SI); + inline section_iterator *unwrap(LLVMSectionIteratorRef SI) { + return reinterpret_cast(SI); } inline LLVMSectionIteratorRef - wrap(const ObjectFile::section_iterator *SI) { + wrap(const section_iterator *SI) { return reinterpret_cast - (const_cast(SI)); + (const_cast(SI)); } } } diff --git a/include/llvm-c/Target.h b/include/llvm-c/Target.h index d21644011ad4..7afaef15c419 100644 --- a/include/llvm-c/Target.h +++ b/include/llvm-c/Target.h @@ -29,6 +29,7 @@ extern "C" { enum LLVMByteOrdering { LLVMBigEndian, LLVMLittleEndian }; typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef; +typedef struct LLVMOpaqueTargetLibraryInfotData *LLVMTargetLibraryInfoRef; typedef struct LLVMStructLayout *LLVMStructLayoutRef; /* Declare all of the target-initialization functions that are available. */ @@ -42,7 +43,7 @@ typedef struct LLVMStructLayout *LLVMStructLayoutRef; #undef LLVM_TARGET /* Explicit undef to make SWIG happier */ #define LLVM_TARGET(TargetName) \ - void LLVMInitialize##TargetName##MCAsmInfo(void); + void LLVMInitialize##TargetName##TargetMC(void); #include "llvm/Config/Targets.def" #undef LLVM_TARGET /* Explicit undef to make SWIG happier */ @@ -72,7 +73,7 @@ static inline LLVMBool LLVMInitializeNativeTarget(void) { #ifdef LLVM_NATIVE_TARGET LLVM_NATIVE_TARGETINFO(); LLVM_NATIVE_TARGET(); - LLVM_NATIVE_MCASMINFO(); + LLVM_NATIVE_TARGETMC(); return 0; #else return 1; @@ -90,6 +91,11 @@ LLVMTargetDataRef LLVMCreateTargetData(const char *StringRep); See the method llvm::PassManagerBase::add. */ void LLVMAddTargetData(LLVMTargetDataRef, LLVMPassManagerRef); +/** Adds target library information to a pass manager. This does not take + ownership of the target library info. + See the method llvm::PassManagerBase::add. */ +void LLVMAddTargetLibraryInfo(LLVMTargetLibraryInfoRef, LLVMPassManagerRef); + /** Converts target data to a target layout string. The string must be disposed with LLVMDisposeMessage. See the constructor llvm::TargetData::TargetData. */ @@ -157,6 +163,7 @@ void LLVMDisposeTargetData(LLVMTargetDataRef); namespace llvm { class TargetData; + class TargetLibraryInfo; inline TargetData *unwrap(LLVMTargetDataRef P) { return reinterpret_cast(P); @@ -165,6 +172,15 @@ namespace llvm { inline LLVMTargetDataRef wrap(const TargetData *P) { return reinterpret_cast(const_cast(P)); } + + inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) { + return reinterpret_cast(P); + } + + inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) { + TargetLibraryInfo *X = const_cast(P); + return reinterpret_cast(X); + } } #endif /* defined(__cplusplus) */ diff --git a/include/llvm-c/Transforms/IPO.h b/include/llvm-c/Transforms/IPO.h index 89b129869c7b..710bebe598be 100644 --- a/include/llvm-c/Transforms/IPO.h +++ b/include/llvm-c/Transforms/IPO.h @@ -36,6 +36,9 @@ void LLVMAddFunctionAttrsPass(LLVMPassManagerRef PM); /** See llvm::createFunctionInliningPass function. */ void LLVMAddFunctionInliningPass(LLVMPassManagerRef PM); +/** See llvm::createAlwaysInlinerPass function. */ +void LLVMAddAlwaysInlinerPass(LLVMPassManagerRef PM); + /** See llvm::createGlobalDCEPass function. */ void LLVMAddGlobalDCEPass(LLVMPassManagerRef PM); @@ -45,9 +48,6 @@ void LLVMAddGlobalOptimizerPass(LLVMPassManagerRef PM); /** See llvm::createIPConstantPropagationPass function. */ void LLVMAddIPConstantPropagationPass(LLVMPassManagerRef PM); -/** See llvm::createLowerSetJmpPass function. */ -void LLVMAddLowerSetJmpPass(LLVMPassManagerRef PM); - /** See llvm::createPruneEHPass function. */ void LLVMAddPruneEHPass(LLVMPassManagerRef PM); @@ -57,9 +57,6 @@ void LLVMAddIPSCCPPass(LLVMPassManagerRef PM); /** See llvm::createInternalizePass function. */ void LLVMAddInternalizePass(LLVMPassManagerRef, unsigned AllButMain); -// FIXME: Remove in LLVM 3.0. -void LLVMAddRaiseAllocationsPass(LLVMPassManagerRef PM); - /** See llvm::createStripDeadPrototypesPass function. */ void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef PM); diff --git a/include/llvm-c/Transforms/PassManagerBuilder.h b/include/llvm-c/Transforms/PassManagerBuilder.h new file mode 100644 index 000000000000..fa722c95874d --- /dev/null +++ b/include/llvm-c/Transforms/PassManagerBuilder.h @@ -0,0 +1,90 @@ +/*===-- llvm-c/Transform/PassManagerBuilder.h - PMB 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 the PassManagerBuilder class. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#ifndef LLVM_C_PASSMANAGERBUILDER +#define LLVM_C_PASSMANAGERBUILDER + +#include "llvm-c/Core.h" + +typedef struct LLVMOpaquePassManagerBuilder *LLVMPassManagerBuilderRef; + +#ifdef __cplusplus +#include "llvm/Transforms/IPO/PassManagerBuilder.h" +extern "C" { +#endif + +/** See llvm::PassManagerBuilder. */ +LLVMPassManagerBuilderRef LLVMPassManagerBuilderCreate(void); +void LLVMPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB); + +/** See llvm::PassManagerBuilder::OptLevel. */ +void +LLVMPassManagerBuilderSetOptLevel(LLVMPassManagerBuilderRef PMB, + unsigned OptLevel); + +/** See llvm::PassManagerBuilder::SizeLevel. */ +void +LLVMPassManagerBuilderSetSizeLevel(LLVMPassManagerBuilderRef PMB, + unsigned SizeLevel); + +/** See llvm::PassManagerBuilder::DisableUnitAtATime. */ +void +LLVMPassManagerBuilderSetDisableUnitAtATime(LLVMPassManagerBuilderRef PMB, + LLVMBool Value); + +/** See llvm::PassManagerBuilder::DisableUnrollLoops. */ +void +LLVMPassManagerBuilderSetDisableUnrollLoops(LLVMPassManagerBuilderRef PMB, + LLVMBool Value); + +/** See llvm::PassManagerBuilder::DisableSimplifyLibCalls */ +void +LLVMPassManagerBuilderSetDisableSimplifyLibCalls(LLVMPassManagerBuilderRef PMB, + LLVMBool Value); + +/** See llvm::PassManagerBuilder::Inliner. */ +void +LLVMPassManagerBuilderUseInlinerWithThreshold(LLVMPassManagerBuilderRef PMB, + unsigned Threshold); + +/** See llvm::PassManagerBuilder::populateFunctionPassManager. */ +void +LLVMPassManagerBuilderPopulateFunctionPassManager(LLVMPassManagerBuilderRef PMB, + LLVMPassManagerRef PM); + +/** See llvm::PassManagerBuilder::populateModulePassManager. */ +void +LLVMPassManagerBuilderPopulateModulePassManager(LLVMPassManagerBuilderRef PMB, + LLVMPassManagerRef PM); + +/** See llvm::PassManagerBuilder::populateLTOPassManager. */ +void LLVMPassManagerBuilderPopulateLTOPassManager(LLVMPassManagerBuilderRef PMB, + LLVMPassManagerRef PM, + bool Internalize, + bool RunInliner); + +#ifdef __cplusplus +} + +namespace llvm { + inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) { + return reinterpret_cast(P); + } + + inline LLVMPassManagerBuilderRef wrap(PassManagerBuilder *P) { + return reinterpret_cast(P); + } +} +#endif + +#endif diff --git a/include/llvm-c/Transforms/Scalar.h b/include/llvm-c/Transforms/Scalar.h index cf8d71f5d007..6015ef90eed2 100644 --- a/include/llvm-c/Transforms/Scalar.h +++ b/include/llvm-c/Transforms/Scalar.h @@ -107,6 +107,9 @@ void LLVMAddCorrelatedValuePropagationPass(LLVMPassManagerRef PM); /** See llvm::createEarlyCSEPass function */ void LLVMAddEarlyCSEPass(LLVMPassManagerRef PM); +/** See llvm::createLowerExpectIntrinsicPass function */ +void LLVMAddLowerExpectIntrinsicPass(LLVMPassManagerRef PM); + /** See llvm::createTypeBasedAliasAnalysisPass function */ void LLVMAddTypeBasedAliasAnalysisPass(LLVMPassManagerRef PM); diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index e68e579cdfc6..707e0dbb6b91 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -15,6 +15,7 @@ #ifndef LLVM_APINT_H #define LLVM_APINT_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/MathExtras.h" #include #include @@ -160,7 +161,7 @@ class APInt { /// not assume that the string is well-formed and (2) grows the /// result to hold the input. /// - /// @param radix 2, 8, 10, or 16 + /// @param radix 2, 8, 10, 16, or 36 /// @brief Convert a char array into an APInt void fromString(unsigned numBits, StringRef str, uint8_t radix); @@ -176,6 +177,9 @@ class APInt { /// out-of-line slow case for inline constructor void initSlowCase(unsigned numBits, uint64_t val, bool isSigned); + /// shared code between two array constructors + void initFromArray(ArrayRef array); + /// out-of-line slow case for inline copy constructor void initSlowCase(const APInt& that); @@ -230,19 +234,26 @@ class APInt { clearUnusedBits(); } - /// Note that numWords can be smaller or larger than the corresponding bit - /// width but any extraneous bits will be dropped. + /// Note that bigVal.size() can be smaller or larger than the corresponding + /// bit width but any extraneous bits will be dropped. /// @param numBits the bit width of the constructed APInt - /// @param numWords the number of words in bigVal /// @param bigVal a sequence of words to form the initial value of the APInt /// @brief Construct an APInt of numBits width, initialized as bigVal[]. + APInt(unsigned numBits, ArrayRef bigVal); + /// Equivalent to APInt(numBits, ArrayRef(bigVal, numWords)), but + /// deprecated because this constructor is prone to ambiguity with the + /// APInt(unsigned, uint64_t, bool) constructor. + /// + /// If this overload is ever deleted, care should be taken to prevent calls + /// from being incorrectly captured by the APInt(unsigned, uint64_t, bool) + /// constructor. APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]); /// This constructor interprets the string \arg str in the given radix. The /// interpretation stops when the first character that is not suitable for the /// radix is encountered, or the end of the string. Acceptable radix values - /// are 2, 8, 10 and 16. It is an error for the value implied by the string to - /// require more bits than numBits. + /// are 2, 8, 10, 16, and 36. It is an error for the value implied by the + /// string to require more bits than numBits. /// /// @param numBits the bit width of the constructed APInt /// @param str the string to be interpreted @@ -342,7 +353,8 @@ class APInt { if (isSingleWord()) return isUIntN(N, VAL); - return APInt(N, getNumWords(), pVal).zext(getBitWidth()) == (*this); + return APInt(N, makeArrayRef(pVal, getNumWords())).zext(getBitWidth()) + == (*this); } /// @brief Check if this APInt has an N-bits signed integer value. @@ -1245,13 +1257,13 @@ class APInt { bool formatAsCLiteral = false) const; /// Considers the APInt to be unsigned and converts it into a string in the - /// radix given. The radix can be 2, 8, 10 or 16. + /// radix given. The radix can be 2, 8, 10 16, or 36. void toStringUnsigned(SmallVectorImpl &Str, unsigned Radix = 10) const { toString(Str, Radix, false, false); } /// Considers the APInt to be signed and converts it into a string in the - /// radix given. The radix can be 2, 8, 10 or 16. + /// radix given. The radix can be 2, 8, 10, 16, or 36. void toStringSigned(SmallVectorImpl &Str, unsigned Radix = 10) const { toString(Str, Radix, true, false); } diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index 6db866e8c70d..33a8c651b23a 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -147,7 +147,53 @@ namespace llvm { /// @} }; - + + /// @name ArrayRef Convenience constructors + /// @{ + + /// Construct an ArrayRef from a single element. + template + ArrayRef makeArrayRef(const T &OneElt) { + return OneElt; + } + + /// Construct an ArrayRef from a pointer and length. + template + ArrayRef makeArrayRef(const T *data, size_t length) { + return ArrayRef(data, length); + } + + /// Construct an ArrayRef from a range. + template + ArrayRef makeArrayRef(const T *begin, const T *end) { + return ArrayRef(begin, end); + } + + /// Construct an ArrayRef from a SmallVector. + template + ArrayRef makeArrayRef(const SmallVectorImpl &Vec) { + return Vec; + } + + /// Construct an ArrayRef from a SmallVector. + template + ArrayRef makeArrayRef(const SmallVector &Vec) { + return Vec; + } + + /// Construct an ArrayRef from a std::vector. + template + ArrayRef makeArrayRef(const std::vector &Vec) { + return Vec; + } + + /// Construct an ArrayRef from a C array. + template + ArrayRef makeArrayRef(const T (&Arr)[N]) { + return ArrayRef(Arr); + } + + /// @} /// @name ArrayRef Comparison Operators /// @{ diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index 0f1cfebc3672..e70cacf3ca5b 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -540,6 +540,12 @@ class DenseMapIterator { ++Ptr; } }; + +template +static inline size_t +capacity_in_bytes(const DenseMap &X) { + return X.getMemorySize(); +} } // end namespace llvm diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h index 744b6f4aef30..df4084e6f411 100644 --- a/include/llvm/ADT/DenseMapInfo.h +++ b/include/llvm/ADT/DenseMapInfo.h @@ -51,7 +51,7 @@ struct DenseMapInfo { template<> struct DenseMapInfo { static inline char getEmptyKey() { return ~0; } static inline char getTombstoneKey() { return ~0 - 1; } - static unsigned getHashValue(const char& Val) { return Val * 37; } + static unsigned getHashValue(const char& Val) { return Val * 37U; } static bool isEqual(const char &LHS, const char &RHS) { return LHS == RHS; } @@ -61,7 +61,7 @@ template<> struct DenseMapInfo { template<> struct DenseMapInfo { static inline unsigned getEmptyKey() { return ~0; } static inline unsigned getTombstoneKey() { return ~0U - 1; } - static unsigned getHashValue(const unsigned& Val) { return Val * 37; } + static unsigned getHashValue(const unsigned& Val) { return Val * 37U; } static bool isEqual(const unsigned& LHS, const unsigned& RHS) { return LHS == RHS; } @@ -96,7 +96,7 @@ template<> struct DenseMapInfo { template<> struct DenseMapInfo { static inline int getEmptyKey() { return 0x7fffffff; } static inline int getTombstoneKey() { return -0x7fffffff - 1; } - static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37); } + static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); } static bool isEqual(const int& LHS, const int& RHS) { return LHS == RHS; } @@ -109,7 +109,7 @@ template<> struct DenseMapInfo { } static inline long getTombstoneKey() { return getEmptyKey() - 1L; } static unsigned getHashValue(const long& Val) { - return (unsigned)(Val * 37L); + return (unsigned)(Val * 37UL); } static bool isEqual(const long& LHS, const long& RHS) { return LHS == RHS; @@ -121,7 +121,7 @@ template<> struct DenseMapInfo { static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; } static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; } static unsigned getHashValue(const long long& Val) { - return (unsigned)(Val * 37LL); + return (unsigned)(Val * 37ULL); } static bool isEqual(const long long& LHS, const long long& RHS) { @@ -142,7 +142,7 @@ struct DenseMapInfo > { } static inline Pair getTombstoneKey() { return std::make_pair(FirstInfo::getTombstoneKey(), - SecondInfo::getEmptyKey()); + SecondInfo::getTombstoneKey()); } static unsigned getHashValue(const Pair& PairVal) { uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32 @@ -158,7 +158,7 @@ struct DenseMapInfo > { return (unsigned)key; } static bool isEqual(const Pair &LHS, const Pair &RHS) { - return FirstInfo::isEqual(LHS.first, RHS.first) && + return FirstInfo::isEqual(LHS.first, RHS.first) && SecondInfo::isEqual(LHS.second, RHS.second); } }; diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h index 67321f539848..8ab9a33200c3 100644 --- a/include/llvm/ADT/DenseSet.h +++ b/include/llvm/ADT/DenseSet.h @@ -28,7 +28,7 @@ class DenseSet { MapTy TheMap; public: DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {} - explicit DenseSet(unsigned NumInitBuckets = 64) : TheMap(NumInitBuckets) {} + explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) {} bool empty() const { return TheMap.empty(); } unsigned size() const { return TheMap.size(); } diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h index d6cce7ccfa05..8346ffabff76 100644 --- a/include/llvm/ADT/ImmutableMap.h +++ b/include/llvm/ADT/ImmutableMap.h @@ -117,6 +117,10 @@ class ImmutableMap { return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T); } + typename TreeTy::Factory *getTreeFactory() const { + return const_cast(&F); + } + private: Factory(const Factory& RHS); // DO NOT IMPLEMENT void operator=(const Factory& RHS); // DO NOT IMPLEMENT @@ -256,6 +260,159 @@ class ImmutableMap { } }; +// NOTE: This will possibly become the new implementation of ImmutableMap some day. +template > +class ImmutableMapRef { +public: + typedef typename ValInfo::value_type value_type; + typedef typename ValInfo::value_type_ref value_type_ref; + typedef typename ValInfo::key_type key_type; + typedef typename ValInfo::key_type_ref key_type_ref; + typedef typename ValInfo::data_type data_type; + typedef typename ValInfo::data_type_ref data_type_ref; + typedef ImutAVLTree TreeTy; + typedef typename TreeTy::Factory FactoryTy; + +protected: + TreeTy *Root; + FactoryTy *Factory; + +public: + /// Constructs a map from a pointer to a tree root. In general one + /// should use a Factory object to create maps instead of directly + /// invoking the constructor, but there are cases where make this + /// constructor public is useful. + explicit ImmutableMapRef(const TreeTy* R, FactoryTy *F) + : Root(const_cast(R)), + Factory(F) { + if (Root) { Root->retain(); } + } + + ImmutableMapRef(const ImmutableMapRef &X) + : Root(X.Root), + Factory(X.Factory) { + if (Root) { Root->retain(); } + } + + ImmutableMapRef &operator=(const ImmutableMapRef &X) { + if (Root != X.Root) { + if (X.Root) + X.Root->retain(); + + if (Root) + Root->release(); + + Root = X.Root; + Factory = X.Factory; + } + return *this; + } + + ~ImmutableMapRef() { + if (Root) + Root->release(); + } + + static inline ImmutableMapRef getEmptyMap(FactoryTy *F) { + return ImmutableMapRef(0, F); + } + + ImmutableMapRef add(key_type_ref K, data_type_ref D) { + TreeTy *NewT = Factory->add(Root, std::pair(K, D)); + return ImmutableMapRef(NewT, Factory); + } + + ImmutableMapRef remove(key_type_ref K) { + TreeTy *NewT = Factory->remove(Root, K); + return ImmutableMapRef(NewT, Factory); + } + + bool contains(key_type_ref K) const { + return Root ? Root->contains(K) : false; + } + + ImmutableMap asImmutableMap() const { + return ImmutableMap(Factory->getCanonicalTree(Root)); + } + + bool operator==(const ImmutableMapRef &RHS) const { + return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root; + } + + bool operator!=(const ImmutableMapRef &RHS) const { + return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root; + } + + bool isEmpty() const { return !Root; } + + //===--------------------------------------------------===// + // For testing. + //===--------------------------------------------------===// + + void verify() const { if (Root) Root->verify(); } + + //===--------------------------------------------------===// + // Iterators. + //===--------------------------------------------------===// + + class iterator { + typename TreeTy::iterator itr; + + iterator() {} + iterator(TreeTy* t) : itr(t) {} + friend class ImmutableMapRef; + + public: + value_type_ref operator*() const { return itr->getValue(); } + value_type* operator->() const { return &itr->getValue(); } + + key_type_ref getKey() const { return itr->getValue().first; } + data_type_ref getData() const { return itr->getValue().second; } + + + iterator& operator++() { ++itr; return *this; } + iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; } + iterator& operator--() { --itr; return *this; } + iterator operator--(int) { iterator tmp(*this); --itr; return tmp; } + bool operator==(const iterator& RHS) const { return RHS.itr == itr; } + bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } + }; + + iterator begin() const { return iterator(Root); } + iterator end() const { return iterator(); } + + data_type* lookup(key_type_ref K) const { + if (Root) { + TreeTy* T = Root->find(K); + if (T) return &T->getValue().second; + } + + return 0; + } + + /// getMaxElement - Returns the pair in the ImmutableMap for + /// which key is the highest in the ordering of keys in the map. This + /// method returns NULL if the map is empty. + value_type* getMaxElement() const { + return Root ? &(Root->getMaxElement()->getValue()) : 0; + } + + //===--------------------------------------------------===// + // Utility methods. + //===--------------------------------------------------===// + + unsigned getHeight() const { return Root ? Root->getHeight() : 0; } + + static inline void Profile(FoldingSetNodeID& ID, const ImmutableMapRef &M) { + ID.AddPointer(M.Root); + } + + inline void Profile(FoldingSetNodeID& ID) const { + return Profile(ID, *this); + } +}; + } // end namespace llvm #endif diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index 3ca910ce944f..d597a7c9be72 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -997,6 +997,10 @@ class ImmutableSet { BumpPtrAllocator& getAllocator() { return F.getAllocator(); } + typename TreeTy::Factory *getTreeFactory() const { + return const_cast(&F); + } + private: Factory(const Factory& RHS); // DO NOT IMPLEMENT void operator=(const Factory& RHS); // DO NOT IMPLEMENT @@ -1021,6 +1025,10 @@ class ImmutableSet { if (Root) { Root->retain(); } return Root; } + + TreeTy *getRootWithoutRetain() const { + return Root; + } /// isEmpty - Return true if the set contains no elements. bool isEmpty() const { return !Root; } @@ -1078,6 +1086,132 @@ class ImmutableSet { void validateTree() const { if (Root) Root->validateTree(); } }; + +// NOTE: This may some day replace the current ImmutableSet. +template > +class ImmutableSetRef { +public: + typedef typename ValInfo::value_type value_type; + typedef typename ValInfo::value_type_ref value_type_ref; + typedef ImutAVLTree TreeTy; + typedef typename TreeTy::Factory FactoryTy; + +private: + TreeTy *Root; + FactoryTy *Factory; + +public: + /// Constructs a set from a pointer to a tree root. In general one + /// should use a Factory object to create sets instead of directly + /// invoking the constructor, but there are cases where make this + /// constructor public is useful. + explicit ImmutableSetRef(TreeTy* R, FactoryTy *F) + : Root(R), + Factory(F) { + if (Root) { Root->retain(); } + } + ImmutableSetRef(const ImmutableSetRef &X) + : Root(X.Root), + Factory(X.Factory) { + if (Root) { Root->retain(); } + } + ImmutableSetRef &operator=(const ImmutableSetRef &X) { + if (Root != X.Root) { + if (X.Root) { X.Root->retain(); } + if (Root) { Root->release(); } + Root = X.Root; + Factory = X.Factory; + } + return *this; + } + ~ImmutableSetRef() { + if (Root) { Root->release(); } + } + + static inline ImmutableSetRef getEmptySet(FactoryTy *F) { + return ImmutableSetRef(0, F); + } + + ImmutableSetRef add(value_type_ref V) { + return ImmutableSetRef(Factory->add(Root, V), Factory); + } + + ImmutableSetRef remove(value_type_ref V) { + return ImmutableSetRef(Factory->remove(Root, V), Factory); + } + + /// Returns true if the set contains the specified value. + bool contains(value_type_ref V) const { + return Root ? Root->contains(V) : false; + } + + ImmutableSet asImmutableSet(bool canonicalize = true) const { + return ImmutableSet(canonicalize ? + Factory->getCanonicalTree(Root) : Root); + } + + TreeTy *getRootWithoutRetain() const { + return Root; + } + + bool operator==(const ImmutableSetRef &RHS) const { + return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root; + } + + bool operator!=(const ImmutableSetRef &RHS) const { + return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root; + } + + /// isEmpty - Return true if the set contains no elements. + bool isEmpty() const { return !Root; } + + /// isSingleton - Return true if the set contains exactly one element. + /// This method runs in constant time. + bool isSingleton() const { return getHeight() == 1; } + + //===--------------------------------------------------===// + // Iterators. + //===--------------------------------------------------===// + + class iterator { + typename TreeTy::iterator itr; + iterator(TreeTy* t) : itr(t) {} + friend class ImmutableSetRef; + public: + iterator() {} + inline value_type_ref operator*() const { return itr->getValue(); } + inline iterator& operator++() { ++itr; return *this; } + inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; } + inline iterator& operator--() { --itr; return *this; } + inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; } + inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; } + inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; } + inline value_type *operator->() const { return &(operator*()); } + }; + + iterator begin() const { return iterator(Root); } + iterator end() const { return iterator(); } + + //===--------------------------------------------------===// + // Utility methods. + //===--------------------------------------------------===// + + unsigned getHeight() const { return Root ? Root->getHeight() : 0; } + + static inline void Profile(FoldingSetNodeID& ID, const ImmutableSetRef& S) { + ID.AddPointer(S.Root); + } + + inline void Profile(FoldingSetNodeID& ID) const { + return Profile(ID,*this); + } + + //===--------------------------------------------------===// + // For testing. + //===--------------------------------------------------===// + + void validateTree() const { if (Root) Root->validateTree(); } +}; } // end namespace llvm diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h index f28ebf3b9a5f..1230e8f5fb43 100644 --- a/include/llvm/ADT/IntervalMap.h +++ b/include/llvm/ADT/IntervalMap.h @@ -1335,6 +1335,9 @@ class IntervalMap::const_iterator : /// valid - Return true if the current position is valid, false for end(). bool valid() const { return path.valid(); } + /// atBegin - Return true if the current position is the first map entry. + bool atBegin() const { return path.atBegin(); } + /// start - Return the beginning of the current interval. const KeyT &start() const { return unsafeStart(); } diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index 13b98cef07ab..487096a17105 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -108,7 +108,11 @@ namespace llvm { /// isNull - Return true if the pointer held in the union is null, /// regardless of which type it is. - bool isNull() const { return Val.getPointer() == 0; } + bool isNull() const { + // Convert from the void* to one of the pointer types, to make sure that + // we recursively strip off low bits if we have a nested PointerUnion. + return !PointerLikeTypeTraits::getFromVoidPointer(Val.getPointer()); + } operator bool() const { return !isNull(); } /// is() return true if the Union currently holds the type matching T. diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h index e3b499488d0c..63a2b5219f73 100644 --- a/include/llvm/ADT/PostOrderIterator.h +++ b/include/llvm/ADT/PostOrderIterator.h @@ -29,6 +29,14 @@ class po_iterator_storage { SetType Visited; }; +/// DFSetTraits - Allow the SetType used to record depth-first search results to +/// optionally record node postorder. +template +struct DFSetTraits { + static void finishPostorder( + typename SetType::iterator::value_type, SetType &) {} +}; + template class po_iterator_storage { public: @@ -109,6 +117,8 @@ class po_iterator : public std::iterator() const { return operator*(); } inline _Self& operator++() { // Preincrement + DFSetTraits::finishPostorder(VisitStack.back().first, + this->Visited); VisitStack.pop_back(); if (!VisitStack.empty()) traverseChild(); diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h index 3e93cfe914fa..48436c667474 100644 --- a/include/llvm/ADT/SCCIterator.h +++ b/include/llvm/ADT/SCCIterator.h @@ -1,4 +1,4 @@ -//===-- Support/SCCIterator.h - Strongly Connected Comp. Iter. --*- C++ -*-===// +//===---- ADT/SCCIterator.h - Strongly Connected Comp. Iter. ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -87,7 +87,7 @@ class scc_iterator DFSVisitOne(childN); continue; } - + unsigned childNum = nodeVisitNumbers[childN]; if (MinVisitNumStack.back() > childNum) MinVisitNumStack.back() = childNum; @@ -114,7 +114,7 @@ class scc_iterator if (minVisitNum != nodeVisitNumbers[visitingN]) continue; - + // A full SCC is on the SCCNodeStack! It includes all nodes below // visitingN on the stack. Copy those nodes to CurrentSCC, // reset their minVisit values, and return (this suspends @@ -139,7 +139,7 @@ class scc_iterator // Provide static "constructors"... static inline _Self begin(const GraphT &G){return _Self(GT::getEntryNode(G));} - static inline _Self end (const GraphT &G) { return _Self(); } + static inline _Self end (const GraphT &) { return _Self(); } // Direct loop termination test: I.isAtEnd() is more efficient than I == end() inline bool isAtEnd() const { @@ -183,7 +183,7 @@ class scc_iterator return true; return false; } - + /// ReplaceNode - This informs the scc_iterator that the specified Old node /// has been deleted, and New is to be used in its place. void ReplaceNode(NodeType *Old, NodeType *New) { diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index 0b0346be2cc5..5da906dc8cf0 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -186,25 +186,21 @@ inline ItTy prior(ItTy it) // // do stuff // else // // do other stuff +template +struct tier { + typedef T1 &first_type; + typedef T2 &second_type; -namespace -{ - template - struct tier { - typedef T1 &first_type; - typedef T2 &second_type; + first_type first; + second_type second; - first_type first; - second_type second; - - tier(first_type f, second_type s) : first(f), second(s) { } - tier& operator=(const std::pair& p) { - first = p.first; - second = p.second; - return *this; - } - }; -} + tier(first_type f, second_type s) : first(f), second(s) { } + tier& operator=(const std::pair& p) { + first = p.first; + second = p.second; + return *this; + } +}; template inline tier tie(T1& f, T2& s) { diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 5f0a55bec46e..1c42f29771b3 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -78,21 +78,21 @@ class SmallVectorBase { return BeginX == static_cast(&FirstEl); } - /// size_in_bytes - This returns size()*sizeof(T). - size_t size_in_bytes() const { - return size_t((char*)EndX - (char*)BeginX); - } - - /// capacity_in_bytes - This returns capacity()*sizeof(T). - size_t capacity_in_bytes() const { - return size_t((char*)CapacityX - (char*)BeginX); - } - /// grow_pod - This is an implementation of the grow() method which only works /// on POD-like data types and is out of line to reduce code duplication. void grow_pod(size_t MinSizeInBytes, size_t TSize); public: + /// size_in_bytes - This returns size()*sizeof(T). + size_t size_in_bytes() const { + return size_t((char*)EndX - (char*)BeginX); + } + + /// capacity_in_bytes - This returns capacity()*sizeof(T). + size_t capacity_in_bytes() const { + return size_t((char*)CapacityX - (char*)BeginX); + } + bool empty() const { return BeginX == EndX; } }; @@ -738,6 +738,11 @@ class SmallVector : public SmallVectorImpl { }; +template +static inline size_t capacity_in_bytes(const SmallVector &X) { + return X.capacity_in_bytes(); +} + } // End llvm namespace namespace std { diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h index fda99c6edbc3..b8a1a2f5c4e8 100644 --- a/include/llvm/ADT/Statistic.h +++ b/include/llvm/ADT/Statistic.h @@ -54,7 +54,7 @@ class Statistic { Value = Val; return init(); } - + const Statistic &operator++() { // FIXME: This function and all those that follow carefully use an // atomic operation to update the value safely in the presence of @@ -63,41 +63,43 @@ class Statistic { sys::AtomicIncrement(&Value); return init(); } - + unsigned operator++(int) { init(); unsigned OldValue = Value; sys::AtomicIncrement(&Value); return OldValue; } - + const Statistic &operator--() { sys::AtomicDecrement(&Value); return init(); } - + unsigned operator--(int) { init(); unsigned OldValue = Value; sys::AtomicDecrement(&Value); return OldValue; } - + const Statistic &operator+=(const unsigned &V) { + if (!V) return *this; sys::AtomicAdd(&Value, V); return init(); } - + const Statistic &operator-=(const unsigned &V) { + if (!V) return *this; sys::AtomicAdd(&Value, -V); return init(); } - + const Statistic &operator*=(const unsigned &V) { sys::AtomicMul(&Value, V); return init(); } - + const Statistic &operator/=(const unsigned &V) { sys::AtomicDiv(&Value, V); return init(); diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 5f5c04187ada..d01d3e1d6b10 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -16,6 +16,7 @@ #include "llvm/Support/DataTypes.h" #include "llvm/ADT/APFloat.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/StringRef.h" #include #include diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h new file mode 100644 index 000000000000..ee86d8bdf70f --- /dev/null +++ b/include/llvm/ADT/TinyPtrVector.h @@ -0,0 +1,133 @@ +//===- llvm/ADT/TinyPtrVector.h - 'Normally tiny' vectors -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_TINYPTRVECTOR_H +#define LLVM_ADT_TINYPTRVECTOR_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/PointerUnion.h" + +namespace llvm { + +/// TinyPtrVector - This class is specialized for cases where there are +/// normally 0 or 1 element in a vector, but is general enough to go beyond that +/// when required. +/// +/// NOTE: This container doesn't allow you to store a null pointer into it. +/// +template +class TinyPtrVector { +public: + typedef llvm::SmallVector VecTy; + llvm::PointerUnion Val; + + TinyPtrVector() {} + TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) { + if (VecTy *V = Val.template dyn_cast()) + Val = new VecTy(*V); + } + ~TinyPtrVector() { + if (VecTy *V = Val.template dyn_cast()) + delete V; + } + + bool empty() const { + // This vector can be empty if it contains no element, or if it + // contains a pointer to an empty vector. + if (Val.isNull()) return true; + if (VecTy *Vec = Val.template dyn_cast()) + return Vec->empty(); + return false; + } + + unsigned size() const { + if (empty()) + return 0; + if (Val.template is()) + return 1; + return Val.template get()->size(); + } + + typedef const EltTy *iterator; + iterator begin() const { + if (empty()) + return 0; + + if (Val.template is()) + return Val.template getAddrOf(); + + return Val.template get()->begin(); + + } + iterator end() const { + if (empty()) + return 0; + + if (Val.template is()) + return begin() + 1; + + return Val.template get()->end(); + } + + + EltTy operator[](unsigned i) const { + assert(!Val.isNull() && "can't index into an empty vector"); + if (EltTy V = Val.template dyn_cast()) { + assert(i == 0 && "tinyvector index out of range"); + return V; + } + + assert(i < Val.template get()->size() && + "tinyvector index out of range"); + return (*Val.template get())[i]; + } + + EltTy front() const { + assert(!empty() && "vector empty"); + if (EltTy V = Val.template dyn_cast()) + return V; + return Val.template get()->front(); + } + + void push_back(EltTy NewVal) { + assert(NewVal != 0 && "Can't add a null value"); + + // If we have nothing, add something. + if (Val.isNull()) { + Val = NewVal; + return; + } + + // If we have a single value, convert to a vector. + if (EltTy V = Val.template dyn_cast()) { + Val = new VecTy(); + Val.template get()->push_back(V); + } + + // Add the new value, we know we have a vector. + Val.template get()->push_back(NewVal); + } + + void clear() { + // If we have a single value, convert to empty. + if (Val.template is()) { + Val = (EltTy)0; + } else if (VecTy *Vec = Val.template dyn_cast()) { + // If we have a vector form, just clear it. + Vec->clear(); + } + // Otherwise, we're already empty. + } + +private: + void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET. +}; +} // end namespace llvm + +#endif diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index fd23608a7591..3503c0f22145 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -10,8 +10,7 @@ #ifndef LLVM_ADT_TRIPLE_H #define LLVM_ADT_TRIPLE_H -#include "llvm/ADT/StringRef.h" -#include +#include "llvm/ADT/Twine.h" // Some system headers or GCC predefined macros conflict with identifiers in // this file. Undefine them here. @@ -19,8 +18,6 @@ #undef sparc namespace llvm { -class StringRef; -class Twine; /// Triple - Helper class for working with target triples. /// @@ -52,6 +49,8 @@ class Triple { cellspu, // CellSPU: spu, cellspu mips, // MIPS: mips, mipsallegrex mipsel, // MIPSEL: mipsel, mipsallegrexel, psp + mips64, // MIPS64: mips64 + mips64el,// MIPS64EL: mips64el msp430, // MSP430: msp430 ppc, // PPC: powerpc ppc64, // PPC64: powerpc64, ppu @@ -66,6 +65,8 @@ class Triple { mblaze, // MBlaze: mblaze ptx32, // PTX: ptx (32-bit) ptx64, // PTX: ptx (64-bit) + le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten) + amdil, // amdil: amd IL InvalidArch }; @@ -85,6 +86,7 @@ class Triple { DragonFly, FreeBSD, IOS, + KFreeBSD, Linux, Lv2, // PS3 MacOSX, @@ -96,7 +98,8 @@ class Triple { Win32, Haiku, Minix, - RTEMS + RTEMS, + NativeClient }; enum EnvironmentType { UnknownEnvironment, @@ -134,24 +137,16 @@ class Triple { /// @{ Triple() : Data(), Arch(InvalidArch) {} - explicit Triple(StringRef Str) : Data(Str), Arch(InvalidArch) {} - explicit Triple(StringRef ArchStr, StringRef VendorStr, StringRef OSStr) - : Data(ArchStr), Arch(InvalidArch) { - Data += '-'; - Data += VendorStr; - Data += '-'; - Data += OSStr; + explicit Triple(const Twine &Str) : Data(Str.str()), Arch(InvalidArch) {} + Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr) + : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr).str()), + Arch(InvalidArch) { } - explicit Triple(StringRef ArchStr, StringRef VendorStr, StringRef OSStr, - StringRef EnvironmentStr) - : Data(ArchStr), Arch(InvalidArch) { - Data += '-'; - Data += VendorStr; - Data += '-'; - Data += OSStr; - Data += '-'; - Data += EnvironmentStr; + Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr, + const Twine &EnvironmentStr) + : Data((ArchStr + Twine('-') + VendorStr + Twine('-') + OSStr + Twine('-') + + EnvironmentStr).str()), Arch(InvalidArch) { } /// @} diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h index ab8d3653e33f..3a60cab77935 100644 --- a/include/llvm/ADT/Twine.h +++ b/include/llvm/ADT/Twine.h @@ -99,6 +99,9 @@ namespace llvm { /// A pointer to a StringRef instance. StringRefKind, + /// A char value reinterpreted as a pointer, to render as a character. + CharKind, + /// An unsigned int value reinterpreted as a pointer, to render as an /// unsigned decimal integer. DecUIKind, @@ -126,13 +129,31 @@ namespace llvm { UHexKind }; + union Child + { + const Twine *twine; + const char *cString; + const std::string *stdString; + const StringRef *stringRef; + char character; + unsigned int decUI; + int decI; + const unsigned long *decUL; + const long *decL; + const unsigned long long *decULL; + const long long *decLL; + const uint64_t *uHex; + }; + private: /// LHS - The prefix in the concatenation, which may be uninitialized for /// Null or Empty kinds. - const void *LHS; + Child LHS; /// RHS - The suffix in the concatenation, which may be uninitialized for /// Null or Empty kinds. - const void *RHS; + Child RHS; + // enums stored as unsigned chars to save on space while some compilers + // don't support specifying the backing type for an enum /// LHSKind - The NodeKind of the left hand side, \see getLHSKind(). unsigned char LHSKind; /// RHSKind - The NodeKind of the left hand side, \see getLHSKind(). @@ -147,13 +168,15 @@ namespace llvm { /// Construct a binary twine. explicit Twine(const Twine &_LHS, const Twine &_RHS) - : LHS(&_LHS), RHS(&_RHS), LHSKind(TwineKind), RHSKind(TwineKind) { + : LHSKind(TwineKind), RHSKind(TwineKind) { + LHS.twine = &_LHS; + RHS.twine = &_RHS; assert(isValid() && "Invalid twine!"); } /// Construct a twine from explicit values. - explicit Twine(const void *_LHS, NodeKind _LHSKind, - const void *_RHS, NodeKind _RHSKind) + explicit Twine(Child _LHS, NodeKind _LHSKind, + Child _RHS, NodeKind _RHSKind) : LHS(_LHS), RHS(_RHS), LHSKind(_LHSKind), RHSKind(_RHSKind) { assert(isValid() && "Invalid twine!"); } @@ -200,10 +223,10 @@ namespace llvm { // A twine child should always be binary. if (getLHSKind() == TwineKind && - !static_cast(LHS)->isBinary()) + !LHS.twine->isBinary()) return false; if (getRHSKind() == TwineKind && - !static_cast(RHS)->isBinary()) + !RHS.twine->isBinary()) return false; return true; @@ -216,10 +239,10 @@ namespace llvm { NodeKind getRHSKind() const { return (NodeKind) RHSKind; } /// printOneChild - Print one child from a twine. - void printOneChild(raw_ostream &OS, const void *Ptr, NodeKind Kind) const; + void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const; /// printOneChildRepr - Print the representation of one child from a twine. - void printOneChildRepr(raw_ostream &OS, const void *Ptr, + void printOneChildRepr(raw_ostream &OS, Child Ptr, NodeKind Kind) const; public: @@ -239,7 +262,7 @@ namespace llvm { /*implicit*/ Twine(const char *Str) : RHSKind(EmptyKind) { if (Str[0] != '\0') { - LHS = Str; + LHS.cString = Str; LHSKind = CStringKind; } else LHSKind = EmptyKind; @@ -249,44 +272,70 @@ namespace llvm { /// Construct from an std::string. /*implicit*/ Twine(const std::string &Str) - : LHS(&Str), LHSKind(StdStringKind), RHSKind(EmptyKind) { + : LHSKind(StdStringKind), RHSKind(EmptyKind) { + LHS.stdString = &Str; assert(isValid() && "Invalid twine!"); } /// Construct from a StringRef. /*implicit*/ Twine(const StringRef &Str) - : LHS(&Str), LHSKind(StringRefKind), RHSKind(EmptyKind) { + : LHSKind(StringRefKind), RHSKind(EmptyKind) { + LHS.stringRef = &Str; assert(isValid() && "Invalid twine!"); } + /// Construct from a char. + explicit Twine(char Val) + : LHSKind(CharKind), RHSKind(EmptyKind) { + LHS.character = Val; + } + + /// Construct from a signed char. + explicit Twine(signed char Val) + : LHSKind(CharKind), RHSKind(EmptyKind) { + LHS.character = static_cast(Val); + } + + /// Construct from an unsigned char. + explicit Twine(unsigned char Val) + : LHSKind(CharKind), RHSKind(EmptyKind) { + LHS.character = static_cast(Val); + } + /// Construct a twine to print \arg Val as an unsigned decimal integer. explicit Twine(unsigned Val) - : LHS((void*)(intptr_t)Val), LHSKind(DecUIKind), RHSKind(EmptyKind) { + : LHSKind(DecUIKind), RHSKind(EmptyKind) { + LHS.decUI = Val; } /// Construct a twine to print \arg Val as a signed decimal integer. explicit Twine(int Val) - : LHS((void*)(intptr_t)Val), LHSKind(DecIKind), RHSKind(EmptyKind) { + : LHSKind(DecIKind), RHSKind(EmptyKind) { + LHS.decI = Val; } /// Construct a twine to print \arg Val as an unsigned decimal integer. explicit Twine(const unsigned long &Val) - : LHS(&Val), LHSKind(DecULKind), RHSKind(EmptyKind) { + : LHSKind(DecULKind), RHSKind(EmptyKind) { + LHS.decUL = &Val; } /// Construct a twine to print \arg Val as a signed decimal integer. explicit Twine(const long &Val) - : LHS(&Val), LHSKind(DecLKind), RHSKind(EmptyKind) { + : LHSKind(DecLKind), RHSKind(EmptyKind) { + LHS.decL = &Val; } /// Construct a twine to print \arg Val as an unsigned decimal integer. explicit Twine(const unsigned long long &Val) - : LHS(&Val), LHSKind(DecULLKind), RHSKind(EmptyKind) { + : LHSKind(DecULLKind), RHSKind(EmptyKind) { + LHS.decULL = &Val; } /// Construct a twine to print \arg Val as a signed decimal integer. explicit Twine(const long long &Val) - : LHS(&Val), LHSKind(DecLLKind), RHSKind(EmptyKind) { + : LHSKind(DecLLKind), RHSKind(EmptyKind) { + LHS.decLL = &Val; } // FIXME: Unfortunately, to make sure this is as efficient as possible we @@ -296,13 +345,17 @@ namespace llvm { /// Construct as the concatenation of a C string and a StringRef. /*implicit*/ Twine(const char *_LHS, const StringRef &_RHS) - : LHS(_LHS), RHS(&_RHS), LHSKind(CStringKind), RHSKind(StringRefKind) { + : LHSKind(CStringKind), RHSKind(StringRefKind) { + LHS.cString = _LHS; + RHS.stringRef = &_RHS; assert(isValid() && "Invalid twine!"); } /// Construct as the concatenation of a StringRef and a C string. /*implicit*/ Twine(const StringRef &_LHS, const char *_RHS) - : LHS(&_LHS), RHS(_RHS), LHSKind(StringRefKind), RHSKind(CStringKind) { + : LHSKind(StringRefKind), RHSKind(CStringKind) { + LHS.stringRef = &_LHS; + RHS.cString = _RHS; assert(isValid() && "Invalid twine!"); } @@ -318,7 +371,10 @@ namespace llvm { // Construct a twine to print \arg Val as an unsigned hexadecimal integer. static Twine utohexstr(const uint64_t &Val) { - return Twine(&Val, UHexKind, 0, EmptyKind); + Child LHS, RHS; + LHS.uHex = &Val; + RHS.twine = 0; + return Twine(LHS, UHexKind, RHS, EmptyKind); } /// @} @@ -371,9 +427,9 @@ namespace llvm { switch (getLHSKind()) { default: assert(0 && "Out of sync with isSingleStringRef"); case EmptyKind: return StringRef(); - case CStringKind: return StringRef((const char*)LHS); - case StdStringKind: return StringRef(*(const std::string*)LHS); - case StringRefKind: return *(const StringRef*)LHS; + case CStringKind: return StringRef(LHS.cString); + case StdStringKind: return StringRef(*LHS.stdString); + case StringRefKind: return *LHS.stringRef; } } @@ -422,7 +478,9 @@ namespace llvm { // Otherwise we need to create a new node, taking care to fold in unary // twines. - const void *NewLHS = this, *NewRHS = &Suffix; + Child NewLHS, NewRHS; + NewLHS.twine = this; + NewRHS.twine = &Suffix; NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind; if (isUnary()) { NewLHS = LHS; diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h index 5d8edd1bf4cd..d71ba208a129 100644 --- a/include/llvm/Analysis/AliasAnalysis.h +++ b/include/llvm/Analysis/AliasAnalysis.h @@ -88,7 +88,7 @@ class AliasAnalysis { /// getTypeStoreSize - Return the TargetData store size for the given type, /// if known, or a conservative value otherwise. /// - uint64_t getTypeStoreSize(const Type *Ty); + uint64_t getTypeStoreSize(Type *Ty); //===--------------------------------------------------------------------===// /// Alias Queries... @@ -136,6 +136,8 @@ class AliasAnalysis { Location getLocation(const LoadInst *LI); Location getLocation(const StoreInst *SI); Location getLocation(const VAArgInst *VI); + Location getLocation(const AtomicCmpXchgInst *CXI); + Location getLocation(const AtomicRMWInst *RMWI); static Location getLocationForSource(const MemTransferInst *MTI); static Location getLocationForDest(const MemIntrinsic *MI); @@ -341,6 +343,11 @@ class AliasAnalysis { case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc); case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc); case Instruction::Store: return getModRefInfo((const StoreInst*)I, Loc); + case Instruction::Fence: return getModRefInfo((const FenceInst*)I, Loc); + case Instruction::AtomicCmpXchg: + return getModRefInfo((const AtomicCmpXchgInst*)I, Loc); + case Instruction::AtomicRMW: + return getModRefInfo((const AtomicRMWInst*)I, Loc); case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc); case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc); default: return NoModRef; @@ -406,6 +413,39 @@ class AliasAnalysis { return getModRefInfo(S, Location(P, Size)); } + /// getModRefInfo (for fences) - Return whether information about whether + /// a particular store modifies or reads the specified memory location. + ModRefResult getModRefInfo(const FenceInst *S, const Location &Loc) { + // Conservatively correct. (We could possibly be a bit smarter if + // Loc is a alloca that doesn't escape.) + return ModRef; + } + + /// getModRefInfo (for fences) - A convenience wrapper. + ModRefResult getModRefInfo(const FenceInst *S, const Value *P, uint64_t Size){ + return getModRefInfo(S, Location(P, Size)); + } + + /// getModRefInfo (for cmpxchges) - Return whether information about whether + /// a particular cmpxchg modifies or reads the specified memory location. + ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc); + + /// getModRefInfo (for cmpxchges) - A convenience wrapper. + ModRefResult getModRefInfo(const AtomicCmpXchgInst *CX, + const Value *P, unsigned Size) { + return getModRefInfo(CX, Location(P, Size)); + } + + /// getModRefInfo (for atomicrmws) - Return whether information about whether + /// a particular atomicrmw modifies or reads the specified memory location. + ModRefResult getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc); + + /// getModRefInfo (for atomicrmws) - A convenience wrapper. + ModRefResult getModRefInfo(const AtomicRMWInst *RMW, + const Value *P, unsigned Size) { + return getModRefInfo(RMW, Location(P, Size)); + } + /// getModRefInfo (for va_args) - Return whether information about whether /// a particular va_arg modifies or reads the specified memory location. ModRefResult getModRefInfo(const VAArgInst* I, const Location &Loc); diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h index 03149c662e83..c4ebe4015bf8 100644 --- a/include/llvm/Analysis/AliasSetTracker.h +++ b/include/llvm/Analysis/AliasSetTracker.h @@ -111,8 +111,8 @@ class AliasSet : public ilist_node { AliasSet *Forward; // Forwarding pointer. AliasSet *Next, *Prev; // Doubly linked list of AliasSets. - // All calls & invokes in this alias set. - std::vector > CallSites; + // All instructions without a specific address in this alias set. + std::vector > UnknownInsts; // RefCount - Number of nodes pointing to this AliasSet plus the number of // AliasSets forwarding to it. @@ -147,9 +147,9 @@ class AliasSet : public ilist_node { removeFromTracker(AST); } - CallSite getCallSite(unsigned i) const { - assert(i < CallSites.size()); - return CallSite(CallSites[i]); + Instruction *getUnknownInst(unsigned i) const { + assert(i < UnknownInsts.size()); + return UnknownInsts[i]; } public: @@ -253,12 +253,12 @@ class AliasSet : public ilist_node { void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t Size, const MDNode *TBAAInfo, bool KnownMustAlias = false); - void addCallSite(CallSite CS, AliasAnalysis &AA); - void removeCallSite(CallSite CS) { - for (size_t i = 0, e = CallSites.size(); i != e; ++i) - if (CallSites[i] == CS.getInstruction()) { - CallSites[i] = CallSites.back(); - CallSites.pop_back(); + void addUnknownInst(Instruction *I, AliasAnalysis &AA); + void removeUnknownInst(Instruction *I) { + for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i) + if (UnknownInsts[i] == I) { + UnknownInsts[i] = UnknownInsts.back(); + UnknownInsts.pop_back(); --i; --e; // Revisit the moved entry. } } @@ -269,7 +269,7 @@ class AliasSet : public ilist_node { /// bool aliasesPointer(const Value *Ptr, uint64_t Size, const MDNode *TBAAInfo, AliasAnalysis &AA) const; - bool aliasesCallSite(CallSite CS, AliasAnalysis &AA) const; + bool aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const; }; inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) { @@ -326,12 +326,10 @@ class AliasSetTracker { bool add(LoadInst *LI); bool add(StoreInst *SI); bool add(VAArgInst *VAAI); - bool add(CallSite CS); // Call/Invoke instructions - bool add(CallInst *CI) { return add(CallSite(CI)); } - bool add(InvokeInst *II) { return add(CallSite(II)); } bool add(Instruction *I); // Dispatch to one of the other add methods... void add(BasicBlock &BB); // Add all instructions in basic block void add(const AliasSetTracker &AST); // Add alias relations from another AST + bool addUnknown(Instruction *I); /// remove methods - These methods are used to remove all entries that might /// be aliased by the specified instruction. These methods return true if any @@ -341,11 +339,9 @@ class AliasSetTracker { bool remove(LoadInst *LI); bool remove(StoreInst *SI); bool remove(VAArgInst *VAAI); - bool remove(CallSite CS); - bool remove(CallInst *CI) { return remove(CallSite(CI)); } - bool remove(InvokeInst *II) { return remove(CallSite(II)); } bool remove(Instruction *I); void remove(AliasSet &AS); + bool removeUnknown(Instruction *I); void clear(); @@ -429,7 +425,7 @@ class AliasSetTracker { AliasSet *findAliasSetForPointer(const Value *Ptr, uint64_t Size, const MDNode *TBAAInfo); - AliasSet *findAliasSetForCallSite(CallSite CS); + AliasSet *findAliasSetForUnknownInst(Instruction *Inst); }; inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) { diff --git a/include/llvm/Analysis/BlockFrequencyImpl.h b/include/llvm/Analysis/BlockFrequencyImpl.h index 6580fd1e4a9c..0fb2bd7db50e 100644 --- a/include/llvm/Analysis/BlockFrequencyImpl.h +++ b/include/llvm/Analysis/BlockFrequencyImpl.h @@ -19,6 +19,7 @@ #include "llvm/ADT/PostOrderIterator.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/Support/BlockFrequency.h" #include "llvm/Support/BranchProbability.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -29,8 +30,8 @@ namespace llvm { -class BlockFrequency; -class MachineBlockFrequency; +class BlockFrequencyInfo; +class MachineBlockFrequencyInfo; /// BlockFrequencyImpl implements block frequency algorithm for IR and /// Machine Instructions. Algorithm starts with value 1024 (START_FREQ) @@ -40,7 +41,7 @@ class MachineBlockFrequency; template class BlockFrequencyImpl { - DenseMap Freqs; + DenseMap Freqs; BlockProbInfoT *BPI; @@ -48,7 +49,7 @@ class BlockFrequencyImpl { typedef GraphTraits< Inverse > GT; - static const uint32_t START_FREQ = 1024; + const uint32_t EntryFreq; std::string getBlockName(BasicBlock *BB) const { return BB->getNameStr(); @@ -64,26 +65,21 @@ class BlockFrequencyImpl { return ss.str(); } - void setBlockFreq(BlockT *BB, uint32_t Freq) { + void setBlockFreq(BlockT *BB, BlockFrequency Freq) { Freqs[BB] = Freq; DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") = " << Freq << "\n"); } /// getEdgeFreq - Return edge frequency based on SRC frequency and Src -> Dst /// edge probability. - uint32_t getEdgeFreq(BlockT *Src, BlockT *Dst) const { + BlockFrequency getEdgeFreq(BlockT *Src, BlockT *Dst) const { BranchProbability Prob = BPI->getEdgeProbability(Src, Dst); - uint64_t N = Prob.getNumerator(); - uint64_t D = Prob.getDenominator(); - uint64_t Res = (N * getBlockFreq(Src)) / D; - - assert(Res <= UINT32_MAX); - return (uint32_t) Res; + return getBlockFreq(Src) * Prob; } /// incBlockFreq - Increase BB block frequency by FREQ. /// - void incBlockFreq(BlockT *BB, uint32_t Freq) { + void incBlockFreq(BlockT *BB, BlockFrequency Freq) { Freqs[BB] += Freq; DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") += " << Freq << " --> " << Freqs[BB] << "\n"); @@ -95,13 +91,13 @@ class BlockFrequencyImpl { uint64_t N = Prob.getNumerator(); assert(N && "Illegal division by zero!"); uint64_t D = Prob.getDenominator(); - uint64_t Freq = (Freqs[BB] * D) / N; + uint64_t Freq = (Freqs[BB].getFrequency() * D) / N; // Should we assert it? if (Freq > UINT32_MAX) Freq = UINT32_MAX; - Freqs[BB] = (uint32_t) Freq; + Freqs[BB] = BlockFrequency(Freq); DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") /= (" << Prob << ") --> " << Freqs[BB] << "\n"); } @@ -136,15 +132,6 @@ class BlockFrequencyImpl { } - /// Return a probability of getting to the DST block through SRC->DST edge. - /// - BranchProbability getBackEdgeProbability(BlockT *Src, BlockT *Dst) const { - uint32_t N = getEdgeFreq(Src, Dst); - uint32_t D = getBlockFreq(Dst); - - return BranchProbability(N, D); - } - /// isReachable - Returns if BB block is reachable from the entry. /// bool isReachable(BlockT *BB) { @@ -160,7 +147,7 @@ class BlockFrequencyImpl { unsigned a = RPO[Src]; unsigned b = RPO[Dst]; - return a > b; + return a >= b; } /// getSingleBlockPred - return single BB block predecessor or NULL if @@ -189,7 +176,7 @@ class BlockFrequencyImpl { setBlockFreq(BB, 0); if (BB == LoopHead) { - setBlockFreq(BB, START_FREQ); + setBlockFreq(BB, EntryFreq); return; } @@ -224,10 +211,10 @@ class BlockFrequencyImpl { if (!isLoopHead) return; - assert(START_FREQ >= CycleProb[BB]); + assert(EntryFreq >= CycleProb[BB]); uint32_t CProb = CycleProb[BB]; - uint32_t Numerator = START_FREQ - CProb ? START_FREQ - CProb : 1; - divBlockFreq(BB, BranchProbability(Numerator, START_FREQ)); + uint32_t Numerator = EntryFreq - CProb ? EntryFreq - CProb : 1; + divBlockFreq(BB, BranchProbability(Numerator, EntryFreq)); } /// doLoop - Propagate block frequency down throught the loop. @@ -237,11 +224,13 @@ class BlockFrequencyImpl { SmallPtrSet BlocksInLoop; - for (rpot_iterator I = rpot_at(Head), E = rpot_end(); I != E; ++I) { + for (rpot_iterator I = rpot_at(Head), E = rpot_at(Tail); ; ++I) { BlockT *BB = *I; doBlock(BB, Head, BlocksInLoop); BlocksInLoop.insert(BB); + if (I == E) + break; } // Compute loop's cyclic probability using backedges probabilities. @@ -252,19 +241,23 @@ class BlockFrequencyImpl { BlockT *Pred = *PI; assert(Pred); if (isReachable(Pred) && isBackedge(Pred, Head)) { - BranchProbability Prob = getBackEdgeProbability(Pred, Head); - uint64_t N = Prob.getNumerator(); - uint64_t D = Prob.getDenominator(); - uint64_t Res = (N * START_FREQ) / D; + uint64_t N = getEdgeFreq(Pred, Head).getFrequency(); + uint64_t D = getBlockFreq(Head).getFrequency(); + assert(N <= EntryFreq && "Backedge frequency must be <= EntryFreq!"); + uint64_t Res = (N * EntryFreq) / D; assert(Res <= UINT32_MAX); CycleProb[Head] += (uint32_t) Res; + DEBUG(dbgs() << " CycleProb[" << getBlockName(Head) << "] += " << Res + << " --> " << CycleProb[Head] << "\n"); } } } - friend class BlockFrequency; - friend class MachineBlockFrequency; + friend class BlockFrequencyInfo; + friend class MachineBlockFrequencyInfo; + + BlockFrequencyImpl() : EntryFreq(BlockFrequency::getEntryFrequency()) { } void doFunction(FunctionT *fn, BlockProbInfoT *bpi) { Fn = fn; @@ -314,13 +307,12 @@ class BlockFrequencyImpl { } public: - /// getBlockFreq - Return block frequency. Never return 0, value must be - /// positive. - uint32_t getBlockFreq(BlockT *BB) const { - typename DenseMap::const_iterator I = Freqs.find(BB); + /// getBlockFreq - Return block frequency. Return 0 if we don't have it. + BlockFrequency getBlockFreq(BlockT *BB) const { + typename DenseMap::const_iterator I = Freqs.find(BB); if (I != Freqs.end()) - return I->second ? I->second : 1; - return 1; + return I->second; + return 0; } void print(raw_ostream &OS) const { diff --git a/include/llvm/Analysis/BlockFrequency.h b/include/llvm/Analysis/BlockFrequencyInfo.h similarity index 58% rename from include/llvm/Analysis/BlockFrequency.h rename to include/llvm/Analysis/BlockFrequencyInfo.h index c4b1e087a0b1..9e698a9f4bb1 100644 --- a/include/llvm/Analysis/BlockFrequency.h +++ b/include/llvm/Analysis/BlockFrequencyInfo.h @@ -1,4 +1,4 @@ -//========-------- BlockFrequency.h - Block Frequency Analysis -------========// +//========-------- BlockFrequencyInfo.h - Block Frequency Analysis -------========// // // The LLVM Compiler Infrastructure // @@ -11,10 +11,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_ANALYSIS_BLOCKFREQUENCY_H -#define LLVM_ANALYSIS_BLOCKFREQUENCY_H +#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H +#define LLVM_ANALYSIS_BLOCKFREQUENCYINFO_H #include "llvm/Pass.h" +#include "llvm/Support/BlockFrequency.h" #include namespace llvm { @@ -23,29 +24,30 @@ class BranchProbabilityInfo; template class BlockFrequencyImpl; -/// BlockFrequency pass uses BlockFrequencyImpl implementation to estimate +/// BlockFrequencyInfo pass uses BlockFrequencyImpl implementation to estimate /// IR basic block frequencies. -class BlockFrequency : public FunctionPass { +class BlockFrequencyInfo : public FunctionPass { BlockFrequencyImpl *BFI; public: static char ID; - BlockFrequency(); + BlockFrequencyInfo(); - ~BlockFrequency(); + ~BlockFrequencyInfo(); void getAnalysisUsage(AnalysisUsage &AU) const; bool runOnFunction(Function &F); + void print(raw_ostream &O, const Module *M) const; - /// getblockFreq - Return block frequency. Never return 0, value must be - /// positive. Please note that initial frequency is equal to 1024. It means + /// getblockFreq - Return block frequency. Return 0 if we don't have the + /// information. Please note that initial frequency is equal to 1024. It means /// that we should not rely on the value itself, but only on the comparison to - /// the other block frequencies. We do this to avoid using of the floating - /// points. - uint32_t getBlockFreq(BasicBlock *BB); + /// the other block frequencies. We do this to avoid using of floating points. + /// + BlockFrequency getBlockFreq(BasicBlock *BB) const; }; } diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h index 02ead98321ff..a2c12ab9e824 100644 --- a/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/include/llvm/Analysis/BranchProbabilityInfo.h @@ -33,12 +33,12 @@ class BranchProbabilityInfo : public FunctionPass { // weight to just "inherit" the non-zero weight of an adjacent successor. static const uint32_t DEFAULT_WEIGHT = 16; - typedef std::pair Edge; + typedef std::pair Edge; DenseMap Weights; // Get sum of the block successors' weights. - uint32_t getSumForBlock(BasicBlock *BB) const; + uint32_t getSumForBlock(const BasicBlock *BB) const; public: static char ID; @@ -53,13 +53,14 @@ class BranchProbabilityInfo : public FunctionPass { // Returned value is between 1 and UINT32_MAX. Look at // BranchProbabilityInfo.cpp for details. - uint32_t getEdgeWeight(BasicBlock *Src, BasicBlock *Dst) const; + uint32_t getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const; // Look at BranchProbabilityInfo.cpp for details. Use it with caution! - void setEdgeWeight(BasicBlock *Src, BasicBlock *Dst, uint32_t Weight); + void setEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst, + uint32_t Weight); // A 'Hot' edge is an edge which probability is >= 80%. - bool isEdgeHot(BasicBlock *Src, BasicBlock *Dst) const; + bool isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const; // Return a hot successor for the block BB or null if there isn't one. BasicBlock *getHotSucc(BasicBlock *BB) const; @@ -67,7 +68,8 @@ class BranchProbabilityInfo : public FunctionPass { // Return a probability as a fraction between 0 (0% probability) and // 1 (100% probability), however the value is never equal to 0, and can be 1 // only iff SRC block has only one successor. - BranchProbability getEdgeProbability(BasicBlock *Src, BasicBlock *Dst) const; + BranchProbability getEdgeProbability(const BasicBlock *Src, + const BasicBlock *Dst) const; // Print value between 0 (0% probability) and 1 (100% probability), // however the value is never equal to 0, and can be 1 only iff SRC block diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h index 75edfbbed2e3..d96dd82b3591 100644 --- a/include/llvm/Analysis/CodeMetrics.h +++ b/include/llvm/Analysis/CodeMetrics.h @@ -18,6 +18,9 @@ #include "llvm/ADT/DenseMap.h" namespace llvm { + + class TargetData; + // CodeMetrics - Calculate size and a few similar metrics for a set of // basic blocks. struct CodeMetrics { @@ -46,7 +49,7 @@ namespace llvm { /// NumCalls - Keep track of the number of calls to 'big' functions. unsigned NumCalls; - + /// NumInlineCandidates - Keep track of the number of calls to internal /// functions with only a single caller. These are likely targets for /// future inlining, likely exposed by interleaved devirtualization. @@ -61,24 +64,24 @@ namespace llvm { unsigned NumRets; CodeMetrics() : callsSetJmp(false), isRecursive(false), - containsIndirectBr(false), usesDynamicAlloca(false), + containsIndirectBr(false), usesDynamicAlloca(false), NumInsts(0), NumBlocks(0), NumCalls(0), - NumInlineCandidates(0), NumVectorInsts(0), + NumInlineCandidates(0), NumVectorInsts(0), NumRets(0) {} /// analyzeBasicBlock - Add information about the specified basic block /// to the current structure. - void analyzeBasicBlock(const BasicBlock *BB); + void analyzeBasicBlock(const BasicBlock *BB, const TargetData *TD = 0); /// analyzeFunction - Add information about the specified function /// to the current structure. - void analyzeFunction(Function *F); - + void analyzeFunction(Function *F, const TargetData *TD = 0); + /// CountCodeReductionForConstant - Figure out an approximation for how /// many instructions will be constant folded if the specified value is /// constant. unsigned CountCodeReductionForConstant(Value *V); - + /// CountBonusForConstant - Figure out an approximation for how much /// per-call performance boost we can expect if the specified value is /// constant. diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h index f6b1f5ab9915..05018fa1617a 100644 --- a/include/llvm/Analysis/ConstantFolding.h +++ b/include/llvm/Analysis/ConstantFolding.h @@ -27,6 +27,8 @@ namespace llvm { class TargetData; class Function; class Type; + template + class ArrayRef; /// ConstantFoldInstruction - Try to constant fold the specified instruction. /// If successful, the constant result is returned, if not, null is returned. @@ -47,8 +49,8 @@ Constant *ConstantFoldConstantExpression(const ConstantExpr *CE, /// fold instructions like loads and stores, which have no constant expression /// form. /// -Constant *ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, - Constant *const *Ops, unsigned NumOps, +Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy, + ArrayRef Ops, const TargetData *TD = 0); /// ConstantFoldCompareInstOperands - Attempt to constant fold a compare @@ -59,6 +61,12 @@ Constant *ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const TargetData *TD = 0); +/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue +/// instruction with the specified operands and indices. The constant result is +/// returned if successful; if not, null is returned. +Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val, + ArrayRef Idxs); + /// ConstantFoldLoadFromConstPtr - Return the value that a load from C would /// produce if it is constant and determinable. If this is not determinable, /// return null. @@ -76,7 +84,7 @@ bool canConstantFoldCallTo(const Function *F); /// ConstantFoldCall - Attempt to constant fold a call to the specified function /// with the specified arguments, returning null if unsuccessful. Constant * -ConstantFoldCall(Function *F, Constant *const *Operands, unsigned NumOperands); +ConstantFoldCall(Function *F, ArrayRef Operands); } #endif diff --git a/include/llvm/Analysis/DIBuilder.h b/include/llvm/Analysis/DIBuilder.h index a706cc8f35db..ee24226c748f 100644 --- a/include/llvm/Analysis/DIBuilder.h +++ b/include/llvm/Analysis/DIBuilder.h @@ -37,6 +37,7 @@ namespace llvm { class DINameSpace; class DIVariable; class DISubrange; + class DILexicalBlockFile; class DILexicalBlock; class DISubprogram; class DITemplateTypeParameter; @@ -48,9 +49,19 @@ namespace llvm { LLVMContext & VMContext; MDNode *TheCU; + MDNode *TempEnumTypes; + MDNode *TempRetainTypes; + MDNode *TempSubprograms; + MDNode *TempGVs; + Function *DeclareFn; // llvm.dbg.declare Function *ValueFn; // llvm.dbg.value + SmallVector AllEnumTypes; + SmallVector AllRetainTypes; + SmallVector AllSubprograms; + SmallVector AllGVs; + DIBuilder(const DIBuilder &); // DO NOT IMPLEMENT void operator=(const DIBuilder &); // DO NOT IMPLEMENT @@ -59,6 +70,9 @@ namespace llvm { const MDNode *getCU() { return TheCU; } enum ComplexAddrKind { OpPlus=1, OpDeref }; + /// finalize - Construct any deferred debug info descriptors. + void finalize(); + /// createCompileUnit - A CompileUnit provides an anchor for all debugging /// information generated during this instance of compilation. /// @param Lang Source programming language, eg. dwarf::DW_LANG_C99 @@ -84,6 +98,9 @@ namespace llvm { /// createEnumerator - Create a single enumerator value. DIEnumerator createEnumerator(StringRef Name, uint64_t Val); + /// createNullPtrType - Create C++0x nullptr type. + DIType createNullPtrType(StringRef Name); + /// createBasicType - Create debugging information entry for a basic /// type. /// @param Name Type name. @@ -447,6 +464,14 @@ namespace llvm { DIFile File, unsigned LineNo); + /// createLexicalBlockFile - This creates a descriptor for a lexical + /// block with a new file attached. This merely extends the existing + /// lexical block as it crosses a file. + /// @param Scope Lexical block. + /// @param File Source file. + DILexicalBlockFile createLexicalBlockFile(DIDescriptor Scope, + DIFile File); + /// createLexicalBlock - This creates a descriptor for a lexical block /// with the specified parent context. /// @param Scope Parent lexical scope. diff --git a/include/llvm/Analysis/DebugInfo.h b/include/llvm/Analysis/DebugInfo.h index fbee5a6311e3..9a53c4dadba0 100644 --- a/include/llvm/Analysis/DebugInfo.h +++ b/include/llvm/Analysis/DebugInfo.h @@ -40,6 +40,7 @@ namespace llvm { class DIFile; class DISubprogram; class DILexicalBlock; + class DILexicalBlockFile; class DIVariable; class DIType; @@ -84,6 +85,7 @@ namespace llvm { explicit DIDescriptor(const MDNode *N) : DbgNode(N) {} explicit DIDescriptor(const DIFile F); explicit DIDescriptor(const DISubprogram F); + explicit DIDescriptor(const DILexicalBlockFile F); explicit DIDescriptor(const DILexicalBlock F); explicit DIDescriptor(const DIVariable F); explicit DIDescriptor(const DIType F); @@ -117,6 +119,7 @@ namespace llvm { bool isFile() const; bool isCompileUnit() const; bool isNameSpace() const; + bool isLexicalBlockFile() const; bool isLexicalBlock() const; bool isSubrange() const; bool isEnumerator() const; @@ -182,6 +185,11 @@ namespace llvm { StringRef getFlags() const { return getStringField(8); } unsigned getRunTimeVersion() const { return getUnsignedField(9); } + DIArray getEnumTypes() const; + DIArray getRetainedTypes() const; + DIArray getSubprograms() const; + DIArray getGlobalVariables() const; + /// Verify - Verify that a compile unit is well formed. bool Verify() const; @@ -201,7 +209,10 @@ namespace llvm { } StringRef getFilename() const { return getStringField(1); } StringRef getDirectory() const { return getStringField(2); } - DICompileUnit getCompileUnit() const{ return getFieldAs(3); } + DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid CompileUnit!"); + return getFieldAs(3); + } }; /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}'). @@ -237,6 +248,7 @@ namespace llvm { DIScope getContext() const { return getFieldAs(1); } StringRef getName() const { return getStringField(2); } DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); if (getVersion() == llvm::LLVMDebugVersion7) return getFieldAs(3); @@ -291,6 +303,9 @@ namespace llvm { return getFieldAs(3).getFilename(); } + /// isUnsignedDIType - Return true if type encoding is unsigned. + bool isUnsignedDIType(); + /// replaceAllUsesWith - Replace all uses of debug info referenced by /// this descriptor. void replaceAllUsesWith(DIDescriptor &D); @@ -447,6 +462,7 @@ namespace llvm { StringRef getDisplayName() const { return getStringField(4); } StringRef getLinkageName() const { return getStringField(5); } DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); if (getVersion() == llvm::LLVMDebugVersion7) return getFieldAs(6); @@ -545,6 +561,8 @@ namespace llvm { DISubprogram getFunctionDeclaration() const { return getFieldAs(18); } + MDNode *getVariablesNodes() const; + DIArray getVariables() const; }; /// DIGlobalVariable - This is a wrapper for a global variable. @@ -557,12 +575,24 @@ namespace llvm { StringRef getDisplayName() const { return getStringField(4); } StringRef getLinkageName() const { return getStringField(5); } DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); if (getVersion() == llvm::LLVMDebugVersion7) return getFieldAs(6); DIFile F = getFieldAs(6); return F.getCompileUnit(); } + StringRef getFilename() const { + if (getVersion() <= llvm::LLVMDebugVersion10) + return getContext().getFilename(); + return getFieldAs(6).getFilename(); + } + StringRef getDirectory() const { + if (getVersion() <= llvm::LLVMDebugVersion10) + return getContext().getDirectory(); + return getFieldAs(6).getDirectory(); + + } unsigned getLineNumber() const { return getUnsignedField(7); } DIType getType() const { return getFieldAs(8); } @@ -592,6 +622,7 @@ namespace llvm { DIScope getContext() const { return getFieldAs(1); } StringRef getName() const { return getStringField(2); } DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); if (getVersion() == llvm::LLVMDebugVersion7) return getFieldAs(3); @@ -614,6 +645,8 @@ namespace llvm { return (getUnsignedField(6) & FlagArtificial) != 0; } + /// getInlinedAt - If this variable is inlined then return inline location. + MDNode *getInlinedAt() const; /// Verify - Verify that a variable descriptor is well formed. bool Verify() const; @@ -628,7 +661,9 @@ namespace llvm { uint64_t getAddrElement(unsigned Idx) const { if (getVersion() <= llvm::LLVMDebugVersion8) return getUInt64Field(Idx+6); - return getUInt64Field(Idx+7); + if (getVersion() == llvm::LLVMDebugVersion9) + return getUInt64Field(Idx+7); + return getUInt64Field(Idx+8); } /// isBlockByrefVariable - Return true if the variable was declared as @@ -644,6 +679,8 @@ namespace llvm { /// print - print variable. void print(raw_ostream &OS) const; + void printExtendedName(raw_ostream &OS) const; + /// dump - print variable to dbgs() with a newline. void dump() const; }; @@ -665,6 +702,26 @@ namespace llvm { } }; + /// DILexicalBlockFile - This is a wrapper for a lexical block with + /// a filename change. + class DILexicalBlockFile : public DIScope { + public: + explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {} + DIScope getContext() const { return getScope().getContext(); } + unsigned getLineNumber() const { return getScope().getLineNumber(); } + unsigned getColumnNumber() const { return getScope().getColumnNumber(); } + StringRef getDirectory() const { + StringRef dir = getFieldAs(2).getDirectory(); + return !dir.empty() ? dir : getContext().getDirectory(); + } + StringRef getFilename() const { + StringRef filename = getFieldAs(2).getFilename(); + assert(!filename.empty() && "Why'd you create this then?"); + return filename; + } + DILexicalBlock getScope() const { return getFieldAs(1); } + }; + /// DINameSpace - A wrapper for a C++ style name space. class DINameSpace : public DIScope { public: @@ -678,6 +735,7 @@ namespace llvm { return getFieldAs(3).getFilename(); } DICompileUnit getCompileUnit() const{ + assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!"); if (getVersion() == llvm::LLVMDebugVersion7) return getFieldAs(3); @@ -708,13 +766,27 @@ namespace llvm { /// getDICompositeType - Find underlying composite type. DICompositeType getDICompositeType(DIType T); + /// isSubprogramContext - Return true if Context is either a subprogram + /// or another context nested inside a subprogram. + bool isSubprogramContext(const MDNode *Context); + /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable /// to hold function specific information. - NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, StringRef Name); + NamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP); /// getFnSpecificMDNode - Return a NameMDNode, if available, that is /// suitable to hold function specific information. - NamedMDNode *getFnSpecificMDNode(const Module &M, StringRef Name); + NamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP); + + /// createInlinedVariable - Create a new inlined variable based on current + /// variable. + /// @param DV Current Variable. + /// @param InlinedScope Location at current variable is inlined. + DIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope, + LLVMContext &VMContext); + + /// cleanseInlinedVariable - Remove inlined scope from the variable. + DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext); class DebugInfoFinder { public: diff --git a/include/llvm/Analysis/FindUsedTypes.h b/include/llvm/Analysis/FindUsedTypes.h index 3e5da572b284..b22cb8813513 100644 --- a/include/llvm/Analysis/FindUsedTypes.h +++ b/include/llvm/Analysis/FindUsedTypes.h @@ -23,7 +23,7 @@ class Type; class Value; class FindUsedTypes : public ModulePass { - SetVector UsedTypes; + SetVector UsedTypes; public: static char ID; // Pass identification, replacement for typeid FindUsedTypes() : ModulePass(ID) { @@ -33,7 +33,7 @@ class FindUsedTypes : public ModulePass { /// getTypes - After the pass has been run, return the set containing all of /// the types used in the module. /// - const SetVector &getTypes() const { return UsedTypes; } + const SetVector &getTypes() const { return UsedTypes; } /// Print the types found in the module. If the optional Module parameter is /// passed in, then the types are printed symbolically if possible, using the @@ -45,7 +45,7 @@ class FindUsedTypes : public ModulePass { /// IncorporateType - Incorporate one type and all of its subtypes into the /// collection of used types. /// - void IncorporateType(const Type *Ty); + void IncorporateType(Type *Ty); /// IncorporateValue - Incorporate all of the types used by this value. /// diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index e56d24d583df..2fb607cc5c37 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -140,6 +140,8 @@ class IVUsers : public LoopPass { static char ID; // Pass ID, replacement for typeid IVUsers(); + Loop *getLoop() const { return L; } + /// AddUsersIfInteresting - Inspect the specified Instruction. If it is a /// reducible SCEV, recursively add its users to the IVUsesByStride set and /// return true. Otherwise, return false. diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h index a0cce515e9e2..36a16e68df07 100644 --- a/include/llvm/Analysis/InlineCost.h +++ b/include/llvm/Analysis/InlineCost.h @@ -29,6 +29,7 @@ namespace llvm { class CallSite; template class SmallPtrSet; + class TargetData; namespace InlineConstants { // Various magic constants used to adjust heuristics. @@ -113,7 +114,7 @@ namespace llvm { /// analyzeFunction - Add information about the specified function /// to the current structure. - void analyzeFunction(Function *F); + void analyzeFunction(Function *F, const TargetData *TD); /// NeverInline - Returns true if the function should never be /// inlined into any caller. @@ -124,11 +125,17 @@ namespace llvm { // the ValueMap will update itself when this happens. ValueMap CachedFunctionInfo; + // TargetData if available, or null. + const TargetData *TD; + int CountBonusForConstant(Value *V, Constant *C = NULL); int ConstantFunctionBonus(CallSite CS, Constant *C); int getInlineSize(CallSite CS, Function *Callee); int getInlineBonuses(CallSite CS, Function *Callee); public: + InlineCostAnalyzer(): TD(0) {} + + void setTargetData(const TargetData *TData) { TD = TData; } /// getInlineCost - The heuristic used to determine if we should inline the /// function call or not. diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h index bc6e55f5490a..c1d87d3f7712 100644 --- a/include/llvm/Analysis/InstructionSimplify.h +++ b/include/llvm/Analysis/InstructionSimplify.h @@ -24,6 +24,8 @@ namespace llvm { class Instruction; class Value; class TargetData; + template + class ArrayRef; /// SimplifyAddInst - Given operands for an Add, see if we can /// fold the result. If not, this returns null. @@ -121,9 +123,16 @@ namespace llvm { /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can /// fold the result. If not, this returns null. - Value *SimplifyGEPInst(Value * const *Ops, unsigned NumOps, + Value *SimplifyGEPInst(ArrayRef Ops, const TargetData *TD = 0, const DominatorTree *DT = 0); + /// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we + /// can fold the result. If not, this returns null. + Value *SimplifyInsertValueInst(Value *Agg, Value *Val, + ArrayRef Idxs, + const TargetData *TD = 0, + const DominatorTree *DT = 0); + //=== Helper functions for higher up the class hierarchy. diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h index 392bdad5ab02..12cb6c5cc480 100644 --- a/include/llvm/Analysis/LoopInfo.h +++ b/include/llvm/Analysis/LoopInfo.h @@ -33,6 +33,7 @@ #include "llvm/Pass.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/SmallVector.h" @@ -105,7 +106,7 @@ class LoopBase { if (L == 0) return false; return contains(L->getParentLoop()); } - + /// contains - Return true if the specified basic block is in this loop. /// bool contains(const BlockT *BB) const { @@ -134,6 +135,11 @@ class LoopBase { block_iterator block_begin() const { return Blocks.begin(); } block_iterator block_end() const { return Blocks.end(); } + /// getNumBlocks - Get the number of blocks in this loop in constant time. + unsigned getNumBlocks() const { + return Blocks.size(); + } + /// isLoopExiting - True if terminator in the block can branch to another /// block that is outside of the current loop. /// @@ -479,12 +485,13 @@ class LoopBase { } /// verifyLoop - Verify loop structure of this loop and all nested loops. - void verifyLoopNest() const { + void verifyLoopNest(DenseSet *Loops) const { + Loops->insert(static_cast(this)); // Verify this loop. verifyLoop(); // Verify the subloops. for (iterator I = begin(), E = end(); I != E; ++I) - (*I)->verifyLoopNest(); + (*I)->verifyLoopNest(Loops); } void print(raw_ostream &OS, unsigned Depth = 0) const { @@ -527,7 +534,7 @@ class Loop : public LoopBase { bool isLoopInvariant(Value *V) const; /// hasLoopInvariantOperands - Return true if all the operands of the - /// specified instruction are loop invariant. + /// specified instruction are loop invariant. bool hasLoopInvariantOperands(Instruction *I) const; /// makeLoopInvariant - If the given value is an instruction inside of the @@ -607,7 +614,7 @@ class Loop : public LoopBase { /// has a predecessor that is outside the loop. bool hasDedicatedExits() const; - /// getUniqueExitBlocks - Return all unique successor blocks of this loop. + /// getUniqueExitBlocks - Return all unique successor blocks of this loop. /// These are the blocks _outside of the current loop_ which are branched to. /// This assumes that loop exits are in canonical form. /// @@ -618,7 +625,7 @@ class Loop : public LoopBase { BasicBlock *getUniqueExitBlock() const; void dump() const; - + private: friend class LoopInfoBase; explicit Loop(BasicBlock *BB) : LoopBase(BB) {} @@ -635,13 +642,14 @@ class LoopInfoBase { DenseMap BBMap; std::vector TopLevelLoops; friend class LoopBase; + friend class LoopInfo; void operator=(const LoopInfoBase &); // do not implement LoopInfoBase(const LoopInfo &); // do not implement public: LoopInfoBase() { } ~LoopInfoBase() { releaseMemory(); } - + void releaseMemory() { for (typename std::vector::iterator I = TopLevelLoops.begin(), E = TopLevelLoops.end(); I != E; ++I) @@ -650,7 +658,7 @@ class LoopInfoBase { BBMap.clear(); // Reset internal state of analysis TopLevelLoops.clear(); } - + /// iterator/begin/end - The interface to the top-level loops in the current /// function. /// @@ -658,7 +666,7 @@ class LoopInfoBase { iterator begin() const { return TopLevelLoops.begin(); } iterator end() const { return TopLevelLoops.end(); } bool empty() const { return TopLevelLoops.empty(); } - + /// getLoopFor - Return the inner most loop that BB lives in. If a basic /// block is in no loop (for example the entry node), null is returned. /// @@ -667,13 +675,13 @@ class LoopInfoBase { BBMap.find(const_cast(BB)); return I != BBMap.end() ? I->second : 0; } - + /// operator[] - same as getLoopFor... /// const LoopT *operator[](const BlockT *BB) const { return getLoopFor(BB); } - + /// getLoopDepth - Return the loop nesting level of the specified block. A /// depth of 0 means the block is not inside any loop. /// @@ -687,7 +695,7 @@ class LoopInfoBase { const LoopT *L = getLoopFor(BB); return L && L->getHeader() == BB; } - + /// removeLoop - This removes the specified top-level loop from this loop info /// object. The loop is not deleted, as it will presumably be inserted into /// another loop. @@ -698,16 +706,20 @@ class LoopInfoBase { TopLevelLoops.erase(TopLevelLoops.begin() + (I-begin())); return L; } - + /// changeLoopFor - Change the top-level loop that contains BB to the /// specified loop. This should be used by transformations that restructure /// the loop hierarchy tree. void changeLoopFor(BlockT *BB, LoopT *L) { - LoopT *&OldLoop = BBMap[BB]; - assert(OldLoop && "Block not in a loop yet!"); - OldLoop = L; + if (!L) { + typename DenseMap::iterator I = BBMap.find(BB); + if (I != BBMap.end()) + BBMap.erase(I); + return; + } + BBMap[BB] = L; } - + /// changeTopLevelLoop - Replace the specified loop in the top-level loops /// list with the indicated loop. void changeTopLevelLoop(LoopT *OldLoop, @@ -719,14 +731,14 @@ class LoopInfoBase { assert(NewLoop->ParentLoop == 0 && OldLoop->ParentLoop == 0 && "Loops already embedded into a subloop!"); } - + /// addTopLevelLoop - This adds the specified loop to the collection of /// top-level loops. void addTopLevelLoop(LoopT *New) { assert(New->getParentLoop() == 0 && "Loop already in subloop!"); TopLevelLoops.push_back(New); } - + /// removeBlock - This method completely removes BB from all data structures, /// including all of the Loop objects it is nested in and our mapping from /// BasicBlocks to loops. @@ -739,16 +751,16 @@ class LoopInfoBase { BBMap.erase(I); } } - + // Internals - + static bool isNotAlreadyContainedIn(const LoopT *SubLoop, const LoopT *ParentLoop) { if (SubLoop == 0) return true; if (SubLoop == ParentLoop) return false; return isNotAlreadyContainedIn(SubLoop->getParentLoop(), ParentLoop); } - + void Calculate(DominatorTreeBase &DT) { BlockT *RootNode = DT.getRootNode()->getBlock(); @@ -757,7 +769,7 @@ class LoopInfoBase { if (LoopT *L = ConsiderForLoop(*NI, DT)) TopLevelLoops.push_back(L); } - + LoopT *ConsiderForLoop(BlockT *BB, DominatorTreeBase &DT) { if (BBMap.find(BB) != BBMap.end()) return 0;// Haven't processed this node? @@ -812,9 +824,9 @@ class LoopInfoBase { // Normal case, add the block to our loop... L->Blocks.push_back(X); - + typedef GraphTraits > InvBlockTraits; - + // Add all of the predecessors of X to the end of the work stack... TodoStack.insert(TodoStack.end(), InvBlockTraits::child_begin(X), InvBlockTraits::child_end(X)); @@ -878,7 +890,7 @@ class LoopInfoBase { return L; } - + /// MoveSiblingLoopInto - This method moves the NewChild loop to live inside /// of the NewParent Loop, instead of being a sibling of it. void MoveSiblingLoopInto(LoopT *NewChild, @@ -897,7 +909,7 @@ class LoopInfoBase { InsertLoopInto(NewChild, NewParent); } - + /// InsertLoopInto - This inserts loop L into the specified parent loop. If /// the parent loop contains a loop which should contain L, the loop gets /// inserted into L instead. @@ -918,9 +930,9 @@ class LoopInfoBase { Parent->SubLoops.push_back(L); L->ParentLoop = Parent; } - + // Debugging - + void print(raw_ostream &OS) const { for (unsigned i = 0; i < TopLevelLoops.size(); ++i) TopLevelLoops[i]->print(OS); @@ -990,7 +1002,7 @@ class LoopInfo : public FunctionPass { virtual void releaseMemory() { LI.releaseMemory(); } virtual void print(raw_ostream &O, const Module* M = 0) const; - + virtual void getAnalysisUsage(AnalysisUsage &AU) const; /// removeLoop - This removes the specified top-level loop from this loop info @@ -1024,6 +1036,12 @@ class LoopInfo : public FunctionPass { LI.removeBlock(BB); } + /// updateUnloop - Update LoopInfo after removing the last backedge from a + /// loop--now the "unloop". This updates the loop forest and parent loops for + /// each block so that Unloop is no longer referenced, but the caller must + /// actually delete the Unloop object. + void updateUnloop(Loop *Unloop); + /// replacementPreservesLCSSAForm - Returns true if replacing From with To /// everywhere is guaranteed to preserve LCSSA form. bool replacementPreservesLCSSAForm(Instruction *From, Value *To) { diff --git a/include/llvm/Analysis/LoopIterator.h b/include/llvm/Analysis/LoopIterator.h new file mode 100644 index 000000000000..269ac8074054 --- /dev/null +++ b/include/llvm/Analysis/LoopIterator.h @@ -0,0 +1,186 @@ +//===--------- LoopIterator.h - Iterate over loop blocks --------*- 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 iterators to visit the basic blocks within a loop. +// +// These iterators currently visit blocks within subloops as well. +// Unfortunately we have no efficient way of summarizing loop exits which would +// allow skipping subloops during traversal. +// +// If you want to visit all blocks in a loop and don't need an ordered traveral, +// use Loop::block_begin() instead. +// +// This is intentionally designed to work with ill-formed loops in which the +// backedge has been deleted. The only prerequisite is that all blocks +// contained within the loop according to the most recent LoopInfo analysis are +// reachable from the loop header. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_LOOP_ITERATOR_H +#define LLVM_ANALYSIS_LOOP_ITERATOR_H + +#include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/PostOrderIterator.h" +#include "llvm/Analysis/LoopInfo.h" + +namespace llvm { + +class LoopBlocksTraversal; + +/// Store the result of a depth first search within basic blocks contained by a +/// single loop. +/// +/// TODO: This could be generalized for any CFG region, or the entire CFG. +class LoopBlocksDFS { +public: + /// Postorder list iterators. + typedef std::vector::const_iterator POIterator; + typedef std::vector::const_reverse_iterator RPOIterator; + + friend class LoopBlocksTraversal; + +private: + Loop *L; + + /// Map each block to its postorder number. A block is only mapped after it is + /// preorder visited by DFS. It's postorder number is initially zero and set + /// to nonzero after it is finished by postorder traversal. + DenseMap PostNumbers; + std::vector PostBlocks; + +public: + LoopBlocksDFS(Loop *Container) : + L(Container), PostNumbers(NextPowerOf2(Container->getNumBlocks())) { + PostBlocks.reserve(Container->getNumBlocks()); + } + + Loop *getLoop() const { return L; } + + /// Traverse the loop blocks and store the DFS result. + void perform(LoopInfo *LI); + + /// Return true if postorder numbers are assigned to all loop blocks. + bool isComplete() const { return PostBlocks.size() == L->getNumBlocks(); } + + /// Iterate over the cached postorder blocks. + POIterator beginPostorder() const { + assert(isComplete() && "bad loop DFS"); + return PostBlocks.begin(); + } + POIterator endPostorder() const { return PostBlocks.end(); } + + /// Reverse iterate over the cached postorder blocks. + RPOIterator beginRPO() const { + assert(isComplete() && "bad loop DFS"); + return PostBlocks.rbegin(); + } + RPOIterator endRPO() const { return PostBlocks.rend(); } + + /// Return true if this block has been preorder visited. + bool hasPreorder(BasicBlock *BB) const { return PostNumbers.count(BB); } + + /// Return true if this block has a postorder number. + bool hasPostorder(BasicBlock *BB) const { + DenseMap::const_iterator I = PostNumbers.find(BB); + return I != PostNumbers.end() && I->second; + } + + /// Get a block's postorder number. + unsigned getPostorder(BasicBlock *BB) const { + DenseMap::const_iterator I = PostNumbers.find(BB); + assert(I != PostNumbers.end() && "block not visited by DFS"); + assert(I->second && "block not finished by DFS"); + return I->second; + } + + /// Get a block's reverse postorder number. + unsigned getRPO(BasicBlock *BB) const { + return 1 + PostBlocks.size() - getPostorder(BB); + } + + void clear() { + PostNumbers.clear(); + PostBlocks.clear(); + } +}; + +/// Traverse the blocks in a loop using a depth-first search. +class LoopBlocksTraversal { +public: + /// Graph traversal iterator. + typedef po_iterator POTIterator; + +private: + LoopBlocksDFS &DFS; + LoopInfo *LI; + +public: + LoopBlocksTraversal(LoopBlocksDFS &Storage, LoopInfo *LInfo) : + DFS(Storage), LI(LInfo) {} + + /// Postorder traversal over the graph. This only needs to be done once. + /// po_iterator "automatically" calls back to visitPreorder and + /// finishPostorder to record the DFS result. + POTIterator begin() { + assert(DFS.PostBlocks.empty() && "Need clear DFS result before traversing"); + assert(DFS.L->getNumBlocks() && "po_iterator cannot handle an empty graph"); + return po_ext_begin(DFS.L->getHeader(), *this); + } + POTIterator end() { + // po_ext_end interface requires a basic block, but ignores its value. + return po_ext_end(DFS.L->getHeader(), *this); + } + + /// Called by po_iterator upon reaching a block via a CFG edge. If this block + /// is contained in the loop and has not been visited, then mark it preorder + /// visited and return true. + /// + /// TODO: If anyone is interested, we could record preorder numbers here. + bool visitPreorder(BasicBlock *BB) { + if (!DFS.L->contains(LI->getLoopFor(BB))) + return false; + + return DFS.PostNumbers.insert(std::make_pair(BB, 0)).second; + } + + /// Called by po_iterator each time it advances, indicating a block's + /// postorder. + void finishPostorder(BasicBlock *BB) { + assert(DFS.PostNumbers.count(BB) && "Loop DFS skipped preorder"); + DFS.PostBlocks.push_back(BB); + DFS.PostNumbers[BB] = DFS.PostBlocks.size(); + } + + //===---------------------------------------------------------------------- + // Implement part of the std::set interface for the purpose of driving the + // generic po_iterator. + + /// Return true if the block is outside the loop or has already been visited. + /// Sorry if this is counterintuitive. + bool count(BasicBlock *BB) const { + return !DFS.L->contains(LI->getLoopFor(BB)) || DFS.PostNumbers.count(BB); + } + + /// If this block is contained in the loop and has not been visited, return + /// true and assign a preorder number. This is a proxy for visitPreorder + /// called by POIterator. + bool insert(BasicBlock *BB) { + return visitPreorder(BB); + } +}; + +/// Specialize DFSetTraits to record postorder numbers. +template<> struct DFSetTraits { + static void finishPostorder(BasicBlock *BB, LoopBlocksTraversal& LBT) { + LBT.finishPostorder(BB); + } +}; + +} // End namespace llvm + +#endif diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h index 1603d2ea7a4f..e6ed9bccee31 100644 --- a/include/llvm/Analysis/LoopPass.h +++ b/include/llvm/Analysis/LoopPass.h @@ -84,7 +84,7 @@ class LoopPass : public Pass { class LPPassManager : public FunctionPass, public PMDataManager { public: static char ID; - explicit LPPassManager(int Depth); + explicit LPPassManager(); /// run - Execute all of the passes scheduled for execution. Keep track of /// whether any of the passes modifies the module, and if so, return true. diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index 22493f6f8b9e..865d236f6f3a 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -51,14 +51,14 @@ const CallInst *isArrayMalloc(const Value *I, const TargetData *TD); /// 0: PointerType is the malloc calls' return type. /// 1: PointerType is the bitcast's result type. /// >1: Unique PointerType cannot be determined, return NULL. -const PointerType *getMallocType(const CallInst *CI); +PointerType *getMallocType(const CallInst *CI); /// getMallocAllocatedType - Returns the Type allocated by malloc call. /// The Type depends on the number of bitcast uses of the malloc call: /// 0: PointerType is the malloc calls' return type. /// 1: PointerType is the bitcast's result type. /// >1: Unique PointerType cannot be determined, return NULL. -const Type *getMallocAllocatedType(const CallInst *CI); +Type *getMallocAllocatedType(const CallInst *CI); /// getMallocArraySize - Returns the array size of a malloc call. If the /// argument passed to malloc is a multiple of the size of the malloced type, diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h index 34860e712fbb..e18d937f6916 100644 --- a/include/llvm/Analysis/MemoryDependenceAnalysis.h +++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h @@ -52,9 +52,6 @@ namespace llvm { /// 1. Loads are clobbered by may-alias stores. /// 2. Loads are considered clobbered by partially-aliased loads. The /// client may choose to analyze deeper into these cases. - /// - /// A dependence query on the first instruction of the entry block will - /// return a clobber(self) result. Clobber, /// Def - This is a dependence on the specified instruction which @@ -76,11 +73,27 @@ namespace llvm { /// operands to the calls are the same. Def, + /// Other - This marker indicates that the query has no known dependency + /// in the specified block. More detailed state info is encoded in the + /// upper part of the pair (i.e. the Instruction*) + Other + }; + /// If DepType is "Other", the upper part of the pair + /// (i.e. the Instruction* part) is instead used to encode more detailed + /// type information as follows + enum OtherType { /// NonLocal - This marker indicates that the query has no dependency in /// the specified block. To find out more, the client should query other /// predecessor blocks. - NonLocal + NonLocal = 0x4, + /// NonFuncLocal - This marker indicates that the query has no + /// dependency in the specified function. + NonFuncLocal = 0x8, + /// Unknown - This marker indicates that the query dependency + /// is unknown. + Unknown = 0xc }; + typedef PointerIntPair PairTy; PairTy Value; explicit MemDepResult(PairTy V) : Value(V) {} @@ -98,19 +111,21 @@ namespace llvm { return MemDepResult(PairTy(Inst, Clobber)); } static MemDepResult getNonLocal() { - return MemDepResult(PairTy(0, NonLocal)); + return MemDepResult( + PairTy(reinterpret_cast(NonLocal), Other)); + } + static MemDepResult getNonFuncLocal() { + return MemDepResult( + PairTy(reinterpret_cast(NonFuncLocal), Other)); } static MemDepResult getUnknown() { - return MemDepResult(PairTy(0, Clobber)); + return MemDepResult( + PairTy(reinterpret_cast(Unknown), Other)); } /// isClobber - Return true if this MemDepResult represents a query that is /// a instruction clobber dependency. - bool isClobber() const { return Value.getInt() == Clobber && getInst(); } - - /// isUnknown - Return true if this MemDepResult represents a query which - /// cannot and/or will not be computed. - bool isUnknown() const { return Value.getInt() == Clobber && !getInst(); } + bool isClobber() const { return Value.getInt() == Clobber; } /// isDef - Return true if this MemDepResult represents a query that is /// a instruction definition dependency. @@ -119,11 +134,31 @@ namespace llvm { /// isNonLocal - Return true if this MemDepResult represents a query that /// is transparent to the start of the block, but where a non-local hasn't /// been done. - bool isNonLocal() const { return Value.getInt() == NonLocal; } + bool isNonLocal() const { + return Value.getInt() == Other + && Value.getPointer() == reinterpret_cast(NonLocal); + } + + /// isNonFuncLocal - Return true if this MemDepResult represents a query + /// that is transparent to the start of the function. + bool isNonFuncLocal() const { + return Value.getInt() == Other + && Value.getPointer() == reinterpret_cast(NonFuncLocal); + } + /// isUnknown - Return true if this MemDepResult represents a query which + /// cannot and/or will not be computed. + bool isUnknown() const { + return Value.getInt() == Other + && Value.getPointer() == reinterpret_cast(Unknown); + } + /// getInst() - If this is a normal dependency, return the instruction that /// is depended on. Otherwise, return null. - Instruction *getInst() const { return Value.getPointer(); } + Instruction *getInst() const { + if (Value.getInt() == Other) return NULL; + return Value.getPointer(); + } bool operator==(const MemDepResult &M) const { return Value == M.Value; } bool operator!=(const MemDepResult &M) const { return Value != M.Value; } diff --git a/include/llvm/Analysis/RegionPass.h b/include/llvm/Analysis/RegionPass.h index 1a93859bab9c..68f12012bcd1 100644 --- a/include/llvm/Analysis/RegionPass.h +++ b/include/llvm/Analysis/RegionPass.h @@ -88,7 +88,7 @@ class RGPassManager : public FunctionPass, public PMDataManager { public: static char ID; - explicit RGPassManager(int Depth); + explicit RGPassManager(); /// @brief Execute all of the passes scheduled for execution. /// diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index 554524a127a8..10d933e68f5b 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -103,7 +103,7 @@ namespace llvm { /// getType - Return the LLVM type of this SCEV expression. /// - const Type *getType() const; + Type *getType() const; /// isZero - Return true if the expression is a constant zero. /// @@ -241,31 +241,94 @@ namespace llvm { /// ValueExprMapType ValueExprMap; + /// ExitLimit - Information about the number of loop iterations for + /// which a loop exit's branch condition evaluates to the not-taken path. + /// This is a temporary pair of exact and max expressions that are + /// eventually summarized in ExitNotTakenInfo and BackedgeTakenInfo. + struct ExitLimit { + const SCEV *Exact; + const SCEV *Max; + + /*implicit*/ ExitLimit(const SCEV *E) : Exact(E), Max(E) {} + + ExitLimit(const SCEV *E, const SCEV *M) : Exact(E), Max(M) {} + + /// hasAnyInfo - Test whether this ExitLimit contains any computed + /// information, or whether it's all SCEVCouldNotCompute values. + bool hasAnyInfo() const { + return !isa(Exact) || + !isa(Max); + } + }; + + /// ExitNotTakenInfo - Information about the number of times a particular + /// loop exit may be reached before exiting the loop. + struct ExitNotTakenInfo { + AssertingVH ExitingBlock; + const SCEV *ExactNotTaken; + PointerIntPair NextExit; + + ExitNotTakenInfo() : ExitingBlock(0), ExactNotTaken(0) {} + + /// isCompleteList - Return true if all loop exits are computable. + bool isCompleteList() const { + return NextExit.getInt() == 0; + } + + void setIncomplete() { NextExit.setInt(1); } + + /// getNextExit - Return a pointer to the next exit's not-taken info. + ExitNotTakenInfo *getNextExit() const { + return NextExit.getPointer(); + } + + void setNextExit(ExitNotTakenInfo *ENT) { NextExit.setPointer(ENT); } + }; + /// BackedgeTakenInfo - Information about the backedge-taken count /// of a loop. This currently includes an exact count and a maximum count. /// - struct BackedgeTakenInfo { - /// Exact - An expression indicating the exact backedge-taken count of - /// the loop if it is known, or a SCEVCouldNotCompute otherwise. - const SCEV *Exact; + class BackedgeTakenInfo { + /// ExitNotTaken - A list of computable exits and their not-taken counts. + /// Loops almost never have more than one computable exit. + ExitNotTakenInfo ExitNotTaken; /// Max - An expression indicating the least maximum backedge-taken /// count of the loop that is known, or a SCEVCouldNotCompute. const SCEV *Max; - /*implicit*/ BackedgeTakenInfo(const SCEV *exact) : - Exact(exact), Max(exact) {} + public: + BackedgeTakenInfo() : Max(0) {} - BackedgeTakenInfo(const SCEV *exact, const SCEV *max) : - Exact(exact), Max(max) {} + /// Initialize BackedgeTakenInfo from a list of exact exit counts. + BackedgeTakenInfo( + SmallVectorImpl< std::pair > &ExitCounts, + bool Complete, const SCEV *MaxCount); /// hasAnyInfo - Test whether this BackedgeTakenInfo contains any /// computed information, or whether it's all SCEVCouldNotCompute /// values. bool hasAnyInfo() const { - return !isa(Exact) || - !isa(Max); + return ExitNotTaken.ExitingBlock || !isa(Max); } + + /// getExact - Return an expression indicating the exact backedge-taken + /// count of the loop if it is known, or SCEVCouldNotCompute + /// otherwise. This is the number of times the loop header can be + /// guaranteed to execute, minus one. + const SCEV *getExact(ScalarEvolution *SE) const; + + /// getExact - Return the number of times this loop exit may fall through + /// to the back edge, or SCEVCouldNotCompute. The loop is guaranteed not + /// to exit via this block before this number of iterations, but may exit + /// via another block. + const SCEV *getExact(BasicBlock *ExitingBlock, ScalarEvolution *SE) const; + + /// getMax - Get the max backedge taken count for the loop. + const SCEV *getMax(ScalarEvolution *SE) const; + + /// clear - Invalidate this result and free associated memory. + void clear(); }; /// BackedgeTakenCounts - Cache the backedge-taken count of the loops for @@ -365,64 +428,59 @@ namespace llvm { /// loop will iterate. BackedgeTakenInfo ComputeBackedgeTakenCount(const Loop *L); - /// ComputeBackedgeTakenCountFromExit - Compute the number of times the - /// backedge of the specified loop will execute if it exits via the - /// specified block. - BackedgeTakenInfo ComputeBackedgeTakenCountFromExit(const Loop *L, - BasicBlock *ExitingBlock); + /// ComputeExitLimit - Compute the number of times the backedge of the + /// specified loop will execute if it exits via the specified block. + ExitLimit ComputeExitLimit(const Loop *L, BasicBlock *ExitingBlock); - /// ComputeBackedgeTakenCountFromExitCond - Compute the number of times the - /// backedge of the specified loop will execute if its exit condition - /// were a conditional branch of ExitCond, TBB, and FBB. - BackedgeTakenInfo - ComputeBackedgeTakenCountFromExitCond(const Loop *L, - Value *ExitCond, - BasicBlock *TBB, - BasicBlock *FBB); + /// ComputeExitLimitFromCond - Compute the number of times the backedge of + /// the specified loop will execute if its exit condition were a conditional + /// branch of ExitCond, TBB, and FBB. + ExitLimit ComputeExitLimitFromCond(const Loop *L, + Value *ExitCond, + BasicBlock *TBB, + BasicBlock *FBB); - /// ComputeBackedgeTakenCountFromExitCondICmp - Compute the number of - /// times the backedge of the specified loop will execute if its exit - /// condition were a conditional branch of the ICmpInst ExitCond, TBB, - /// and FBB. - BackedgeTakenInfo - ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L, - ICmpInst *ExitCond, - BasicBlock *TBB, - BasicBlock *FBB); + /// ComputeExitLimitFromICmp - Compute the number of times the backedge of + /// the specified loop will execute if its exit condition were a conditional + /// branch of the ICmpInst ExitCond, TBB, and FBB. + ExitLimit ComputeExitLimitFromICmp(const Loop *L, + ICmpInst *ExitCond, + BasicBlock *TBB, + BasicBlock *FBB); - /// ComputeLoadConstantCompareBackedgeTakenCount - Given an exit condition + /// ComputeLoadConstantCompareExitLimit - Given an exit condition /// of 'icmp op load X, cst', try to see if we can compute the /// backedge-taken count. - BackedgeTakenInfo - ComputeLoadConstantCompareBackedgeTakenCount(LoadInst *LI, - Constant *RHS, - const Loop *L, - ICmpInst::Predicate p); + ExitLimit ComputeLoadConstantCompareExitLimit(LoadInst *LI, + Constant *RHS, + const Loop *L, + ICmpInst::Predicate p); - /// ComputeBackedgeTakenCountExhaustively - If the loop is known to execute - /// a constant number of times (the condition evolves only from constants), + /// ComputeExitCountExhaustively - If the loop is known to execute a + /// constant number of times (the condition evolves only from constants), /// try to evaluate a few iterations of the loop until we get the exit /// condition gets a value of ExitWhen (true or false). If we cannot - /// evaluate the backedge-taken count of the loop, return CouldNotCompute. - const SCEV *ComputeBackedgeTakenCountExhaustively(const Loop *L, - Value *Cond, - bool ExitWhen); + /// evaluate the exit count of the loop, return CouldNotCompute. + const SCEV *ComputeExitCountExhaustively(const Loop *L, + Value *Cond, + bool ExitWhen); - /// HowFarToZero - Return the number of times a backedge comparing the - /// specified value to zero will execute. If not computable, return + /// HowFarToZero - Return the number of times an exit condition comparing + /// the specified value to zero will execute. If not computable, return /// CouldNotCompute. - BackedgeTakenInfo HowFarToZero(const SCEV *V, const Loop *L); + ExitLimit HowFarToZero(const SCEV *V, const Loop *L); - /// HowFarToNonZero - Return the number of times a backedge checking the - /// specified value for nonzero will execute. If not computable, return + /// HowFarToNonZero - Return the number of times an exit condition checking + /// the specified value for nonzero will execute. If not computable, return /// CouldNotCompute. - BackedgeTakenInfo HowFarToNonZero(const SCEV *V, const Loop *L); + ExitLimit HowFarToNonZero(const SCEV *V, const Loop *L); - /// HowManyLessThans - Return the number of times a backedge containing the - /// specified less-than comparison will execute. If not computable, return - /// CouldNotCompute. isSigned specifies whether the less-than is signed. - BackedgeTakenInfo HowManyLessThans(const SCEV *LHS, const SCEV *RHS, - const Loop *L, bool isSigned); + /// HowManyLessThans - Return the number of times an exit condition + /// containing the specified less-than comparison will execute. If not + /// computable, return CouldNotCompute. isSigned specifies whether the + /// less-than is signed. + ExitLimit HowManyLessThans(const SCEV *LHS, const SCEV *RHS, + const Loop *L, bool isSigned); /// getPredecessorWithUniqueSuccessorForBB - Return a predecessor of BB /// (which may not be an immediate predecessor) which has exactly one @@ -450,7 +508,8 @@ namespace llvm { /// FoundLHS, and FoundRHS is true. bool isImpliedCondOperandsHelper(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS, - const SCEV *FoundLHS, const SCEV *FoundRHS); + const SCEV *FoundLHS, + const SCEV *FoundRHS); /// getConstantEvolutionLoopExitValue - If we know that the specified Phi is /// in the header of its containing loop, we know the loop executes a @@ -479,17 +538,17 @@ namespace llvm { /// the SCEV framework. This primarily includes integer types, and it /// can optionally include pointer types if the ScalarEvolution class /// has access to target-specific information. - bool isSCEVable(const Type *Ty) const; + bool isSCEVable(Type *Ty) const; /// getTypeSizeInBits - Return the size in bits of the specified type, /// for which isSCEVable must return true. - uint64_t getTypeSizeInBits(const Type *Ty) const; + uint64_t getTypeSizeInBits(Type *Ty) const; /// getEffectiveSCEVType - Return a type with the same bitwidth as /// the given type and which represents how SCEV will treat the given /// type, for which isSCEVable must return true. For pointer types, /// this is the pointer-sized integer type. - const Type *getEffectiveSCEVType(const Type *Ty) const; + Type *getEffectiveSCEVType(Type *Ty) const; /// getSCEV - Return a SCEV expression for the full generality of the /// specified expression. @@ -497,11 +556,11 @@ namespace llvm { const SCEV *getConstant(ConstantInt *V); const SCEV *getConstant(const APInt& Val); - const SCEV *getConstant(const Type *Ty, uint64_t V, bool isSigned = false); - const SCEV *getTruncateExpr(const SCEV *Op, const Type *Ty); - const SCEV *getZeroExtendExpr(const SCEV *Op, const Type *Ty); - const SCEV *getSignExtendExpr(const SCEV *Op, const Type *Ty); - const SCEV *getAnyExtendExpr(const SCEV *Op, const Type *Ty); + const SCEV *getConstant(Type *Ty, uint64_t V, bool isSigned = false); + const SCEV *getTruncateExpr(const SCEV *Op, Type *Ty); + const SCEV *getZeroExtendExpr(const SCEV *Op, Type *Ty); + const SCEV *getSignExtendExpr(const SCEV *Op, Type *Ty); + const SCEV *getAnyExtendExpr(const SCEV *Op, Type *Ty); const SCEV *getAddExpr(SmallVectorImpl &Ops, SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap); const SCEV *getAddExpr(const SCEV *LHS, const SCEV *RHS, @@ -529,6 +588,14 @@ namespace llvm { Ops.push_back(RHS); return getMulExpr(Ops, Flags); } + const SCEV *getMulExpr(const SCEV *Op0, const SCEV *Op1, const SCEV *Op2, + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap) { + SmallVector Ops; + Ops.push_back(Op0); + Ops.push_back(Op1); + Ops.push_back(Op2); + return getMulExpr(Ops, Flags); + } const SCEV *getUDivExpr(const SCEV *LHS, const SCEV *RHS); const SCEV *getAddRecExpr(const SCEV *Start, const SCEV *Step, const Loop *L, SCEV::NoWrapFlags Flags); @@ -550,19 +617,19 @@ namespace llvm { /// getSizeOfExpr - Return an expression for sizeof on the given type. /// - const SCEV *getSizeOfExpr(const Type *AllocTy); + const SCEV *getSizeOfExpr(Type *AllocTy); /// getAlignOfExpr - Return an expression for alignof on the given type. /// - const SCEV *getAlignOfExpr(const Type *AllocTy); + const SCEV *getAlignOfExpr(Type *AllocTy); /// getOffsetOfExpr - Return an expression for offsetof on the given field. /// - const SCEV *getOffsetOfExpr(const StructType *STy, unsigned FieldNo); + const SCEV *getOffsetOfExpr(StructType *STy, unsigned FieldNo); /// getOffsetOfExpr - Return an expression for offsetof on the given field. /// - const SCEV *getOffsetOfExpr(const Type *CTy, Constant *FieldNo); + const SCEV *getOffsetOfExpr(Type *CTy, Constant *FieldNo); /// getNegativeSCEV - Return the SCEV object corresponding to -V. /// @@ -579,33 +646,33 @@ namespace llvm { /// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion /// of the input value to the specified type. If the type must be /// extended, it is zero extended. - const SCEV *getTruncateOrZeroExtend(const SCEV *V, const Type *Ty); + const SCEV *getTruncateOrZeroExtend(const SCEV *V, Type *Ty); /// getTruncateOrSignExtend - Return a SCEV corresponding to a conversion /// of the input value to the specified type. If the type must be /// extended, it is sign extended. - const SCEV *getTruncateOrSignExtend(const SCEV *V, const Type *Ty); + const SCEV *getTruncateOrSignExtend(const SCEV *V, Type *Ty); /// getNoopOrZeroExtend - Return a SCEV corresponding to a conversion of /// the input value to the specified type. If the type must be extended, /// it is zero extended. The conversion must not be narrowing. - const SCEV *getNoopOrZeroExtend(const SCEV *V, const Type *Ty); + const SCEV *getNoopOrZeroExtend(const SCEV *V, Type *Ty); /// getNoopOrSignExtend - Return a SCEV corresponding to a conversion of /// the input value to the specified type. If the type must be extended, /// it is sign extended. The conversion must not be narrowing. - const SCEV *getNoopOrSignExtend(const SCEV *V, const Type *Ty); + const SCEV *getNoopOrSignExtend(const SCEV *V, Type *Ty); /// getNoopOrAnyExtend - Return a SCEV corresponding to a conversion of /// the input value to the specified type. If the type must be extended, /// it is extended with unspecified bits. The conversion must not be /// narrowing. - const SCEV *getNoopOrAnyExtend(const SCEV *V, const Type *Ty); + const SCEV *getNoopOrAnyExtend(const SCEV *V, Type *Ty); /// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the /// input value to the specified type. The conversion must not be /// widening. - const SCEV *getTruncateOrNoop(const SCEV *V, const Type *Ty); + const SCEV *getTruncateOrNoop(const SCEV *V, Type *Ty); /// getUMaxFromMismatchedTypes - Promote the operands to the wider of /// the types using zero-extension, and then perform a umax operation @@ -653,6 +720,23 @@ namespace llvm { bool isLoopBackedgeGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS); + /// getSmallConstantTripCount - Returns the maximum trip count of this loop + /// as a normal unsigned value, if possible. Returns 0 if the trip count is + /// unknown or not constant. + unsigned getSmallConstantTripCount(Loop *L, BasicBlock *ExitBlock); + + /// getSmallConstantTripMultiple - Returns the largest constant divisor of + /// the trip count of this loop as a normal unsigned value, if + /// possible. This means that the actual trip count is always a multiple of + /// the returned value (don't forget the trip count could very well be zero + /// as well!). + unsigned getSmallConstantTripMultiple(Loop *L, BasicBlock *ExitBlock); + + // getExitCount - Get the expression for the number of loop iterations for + // which this loop is guaranteed not to exit via ExitingBlock. Otherwise + // return SCEVCouldNotCompute. + const SCEV *getExitCount(Loop *L, BasicBlock *ExitingBlock); + /// getBackedgeTakenCount - If the specified loop has a predictable /// backedge-taken count, return it, otherwise return a SCEVCouldNotCompute /// object. The backedge-taken count is the number of times the loop header diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index a8c03b2219e1..a4ad1451d412 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -64,16 +64,34 @@ namespace llvm { /// in a more literal form. bool CanonicalMode; + /// When invoked from LSR, the expander is in "strength reduction" mode. The + /// only difference is that phi's are only reused if they are already in + /// "expanded" form. + bool LSRMode; + typedef IRBuilder BuilderType; BuilderType Builder; +#ifndef NDEBUG + const char *DebugType; +#endif + friend struct SCEVVisitor; public: /// SCEVExpander - Construct a SCEVExpander in "canonical" mode. explicit SCEVExpander(ScalarEvolution &se, const char *name) : SE(se), IVName(name), IVIncInsertLoop(0), IVIncInsertPos(0), - CanonicalMode(true), Builder(se.getContext(), TargetFolder(se.TD)) {} + CanonicalMode(true), LSRMode(false), + Builder(se.getContext(), TargetFolder(se.TD)) { +#ifndef NDEBUG + DebugType = ""; +#endif + } + +#ifndef NDEBUG + void setDebugType(const char* s) { DebugType = s; } +#endif /// clear - Erase the contents of the InsertedExpressions map so that users /// trying to expand the same expression into multiple BasicBlocks or @@ -88,13 +106,21 @@ namespace llvm { /// canonical induction variable of the specified type for the specified /// loop (inserting one if there is none). A canonical induction variable /// starts at zero and steps by one on each iteration. - PHINode *getOrInsertCanonicalInductionVariable(const Loop *L, - const Type *Ty); + PHINode *getOrInsertCanonicalInductionVariable(const Loop *L, Type *Ty); + + /// hoistStep - Utility for hoisting an IV increment. + static bool hoistStep(Instruction *IncV, Instruction *InsertPos, + const DominatorTree *DT); + + /// replaceCongruentIVs - replace congruent phis with their most canonical + /// representative. Return the number of phis eliminated. + unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT, + SmallVectorImpl &DeadInsts); /// expandCodeFor - Insert code to directly compute the specified SCEV /// expression into the program. The inserted code is inserted into the /// specified block. - Value *expandCodeFor(const SCEV *SH, const Type *Ty, Instruction *I); + Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I); /// setIVIncInsertPos - Set the current IV increment loop and position. void setIVIncInsertPos(const Loop *L, Instruction *Pos) { @@ -127,13 +153,14 @@ namespace llvm { /// is useful for late optimization passes. void disableCanonicalMode() { CanonicalMode = false; } + void enableLSRMode() { LSRMode = true; } + /// clearInsertPoint - Clear the current insertion point. This is useful /// if the instruction that had been serving as the insertion point may /// have been deleted. void clearInsertPoint() { Builder.ClearInsertionPoint(); } - private: LLVMContext &getContext() const { return SE.getContext(); } @@ -145,20 +172,20 @@ namespace llvm { /// reusing an existing cast if a suitable one exists, moving an existing /// cast if a suitable one exists but isn't in the right place, or /// or creating a new one. - Value *ReuseOrCreateCast(Value *V, const Type *Ty, + Value *ReuseOrCreateCast(Value *V, Type *Ty, Instruction::CastOps Op, BasicBlock::iterator IP); /// InsertNoopCastOfTo - Insert a cast of V to the specified type, /// which must be possible with a noop cast, doing what we can to /// share the casts. - Value *InsertNoopCastOfTo(Value *V, const Type *Ty); + Value *InsertNoopCastOfTo(Value *V, Type *Ty); /// expandAddToGEP - Expand a SCEVAddExpr with a pointer type into a GEP /// instead of using ptrtoint+arithmetic+inttoptr. Value *expandAddToGEP(const SCEV *const *op_begin, const SCEV *const *op_end, - const PointerType *PTy, const Type *Ty, Value *V); + PointerType *PTy, Type *Ty, Value *V); Value *expand(const SCEV *S); @@ -166,7 +193,7 @@ namespace llvm { /// expression into the program. The inserted code is inserted into the /// SCEVExpander's current insertion point. If a type is specified, the /// result will be expanded to have that type, with a cast if necessary. - Value *expandCodeFor(const SCEV *SH, const Type *Ty = 0); + Value *expandCodeFor(const SCEV *SH, Type *Ty = 0); /// isInsertedInstruction - Return true if the specified instruction was /// inserted by the code rewriter. If so, the client should not modify the @@ -208,11 +235,15 @@ namespace llvm { void restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I); + bool isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L); + + bool isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L); + Value *expandAddRecExprLiterally(const SCEVAddRecExpr *); PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, const Loop *L, - const Type *ExpandTy, - const Type *IntTy); + Type *ExpandTy, + Type *IntTy); }; } diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h index 856d92c97c08..b6f0ae54cfa0 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -42,7 +42,7 @@ namespace llvm { public: ConstantInt *getValue() const { return V; } - const Type *getType() const { return V->getType(); } + Type *getType() const { return V->getType(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SCEVConstant *S) { return true; } @@ -57,14 +57,14 @@ namespace llvm { class SCEVCastExpr : public SCEV { protected: const SCEV *Op; - const Type *Ty; + Type *Ty; SCEVCastExpr(const FoldingSetNodeIDRef ID, - unsigned SCEVTy, const SCEV *op, const Type *ty); + unsigned SCEVTy, const SCEV *op, Type *ty); public: const SCEV *getOperand() const { return Op; } - const Type *getType() const { return Ty; } + Type *getType() const { return Ty; } /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SCEVCastExpr *S) { return true; } @@ -83,7 +83,7 @@ namespace llvm { friend class ScalarEvolution; SCEVTruncateExpr(const FoldingSetNodeIDRef ID, - const SCEV *op, const Type *ty); + const SCEV *op, Type *ty); public: /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -101,7 +101,7 @@ namespace llvm { friend class ScalarEvolution; SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID, - const SCEV *op, const Type *ty); + const SCEV *op, Type *ty); public: /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -119,7 +119,7 @@ namespace llvm { friend class ScalarEvolution; SCEVSignExtendExpr(const FoldingSetNodeIDRef ID, - const SCEV *op, const Type *ty); + const SCEV *op, Type *ty); public: /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -158,7 +158,7 @@ namespace llvm { op_iterator op_begin() const { return Operands; } op_iterator op_end() const { return Operands + NumOperands; } - const Type *getType() const { return getOperand(0)->getType(); } + Type *getType() const { return getOperand(0)->getType(); } NoWrapFlags getNoWrapFlags(NoWrapFlags Mask = NoWrapMask) const { return (NoWrapFlags)(SubclassData & Mask); @@ -214,7 +214,7 @@ namespace llvm { } public: - const Type *getType() const { + Type *getType() const { // Use the type of the last operand, which is likely to be a pointer // type, if there is one. This doesn't usually matter, but it can help // reduce casts when the expressions are expanded. @@ -263,7 +263,7 @@ namespace llvm { const SCEV *getLHS() const { return LHS; } const SCEV *getRHS() const { return RHS; } - const Type *getType() const { + Type *getType() const { // In most cases the types of LHS and RHS will be the same, but in some // crazy cases one or the other may be a pointer. ScalarEvolution doesn't // depend on the type for correctness, but handling types carefully can @@ -441,11 +441,11 @@ namespace llvm { /// 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; + bool isSizeOf(Type *&AllocTy) const; + bool isAlignOf(Type *&AllocTy) const; + bool isOffsetOf(Type *&STy, Constant *&FieldNo) const; - const Type *getType() const { return getValPtr()->getType(); } + Type *getType() const { return getValPtr()->getType(); } /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SCEVUnknown *S) { return true; } diff --git a/include/llvm/Argument.h b/include/llvm/Argument.h index ff8637881eb7..cd7488266231 100644 --- a/include/llvm/Argument.h +++ b/include/llvm/Argument.h @@ -39,7 +39,7 @@ class Argument : public Value, public ilist_node { /// Argument ctor - If Function argument is specified, this argument is /// inserted at the end of the argument list for the function. /// - explicit Argument(const Type *Ty, const Twine &Name = "", Function *F = 0); + explicit Argument(Type *Ty, const Twine &Name = "", Function *F = 0); inline const Function *getParent() const { return Parent; } inline Function *getParent() { return Parent; } diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 233eab8bf179..2d7b33b29bcf 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -65,8 +65,7 @@ const Attributes StackAlignment = 7<<26; ///< Alignment of stack for ///of alignment with +1 bias ///0 means unaligned (different from ///alignstack(1)) -const Attributes Hotpatch = 1<<29; ///< Function should have special - ///'hotpatch' sequence in prologue +const Attributes ReturnsTwice = 1<<29; ///< Function can return twice const Attributes UWTable = 1<<30; ///< Function must be in a unwind ///table const Attributes NonLazyBind = 1U<<31; ///< Function is called early and/or @@ -93,7 +92,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment | - Hotpatch | UWTable | NonLazyBind; + UWTable | NonLazyBind | ReturnsTwice; /// @brief Parameter attributes that do not apply to vararg call arguments. const Attributes VarArgsIncompatible = StructRet; @@ -107,7 +106,7 @@ const Attributes MutuallyIncompatible[4] = { }; /// @brief Which attributes cannot be applied to a type. -Attributes typeIncompatible(const Type *Ty); +Attributes typeIncompatible(Type *Ty); /// This turns an int alignment (a power of 2, normally) into the /// form used internally in Attributes. diff --git a/include/llvm/AutoUpgrade.h b/include/llvm/AutoUpgrade.h index 5ce20b69e2fb..8ca3548f533e 100644 --- a/include/llvm/AutoUpgrade.h +++ b/include/llvm/AutoUpgrade.h @@ -43,6 +43,10 @@ namespace llvm { /// This function checks debug info intrinsics. If an intrinsic is invalid /// then this function simply removes the intrinsic. void CheckDebugInfoIntrinsics(Module *M); + + /// This function upgrades the old pre-3.0 exception handling system to the + /// new one. N.B. This will be removed in 3.1. + void UpgradeExceptionHandling(Module *M); } // End llvm namespace #endif diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h index 3b953c06a81b..1cd8dc55ab58 100644 --- a/include/llvm/BasicBlock.h +++ b/include/llvm/BasicBlock.h @@ -22,6 +22,7 @@ namespace llvm { +class LandingPadInst; class TerminatorInst; class LLVMContext; class BlockAddress; @@ -144,6 +145,14 @@ class BasicBlock : public Value, // Basic blocks are data objects also return const_cast(this)->getFirstNonPHIOrDbgOrLifetime(); } + /// getFirstInsertionPt - Returns an iterator to the first instruction in this + /// block that is suitable for inserting a non-PHI instruction. In particular, + /// it skips all PHIs and LandingPad instructions. + iterator getFirstInsertionPt(); + const_iterator getFirstInsertionPt() const { + return const_cast(this)->getFirstInsertionPt(); + } + /// removeFromParent - This method unlinks 'this' from the containing /// function, but does not delete it. /// @@ -258,6 +267,14 @@ class BasicBlock : public Value, // Basic blocks are data objects also /// to refer to basic block New instead of to us. void replaceSuccessorsPhiUsesWith(BasicBlock *New); + /// isLandingPad - Return true if this basic block is a landing pad. I.e., + /// it's the destination of the 'unwind' edge of an invoke instruction. + bool isLandingPad() const; + + /// getLandingPadInst() - Return the landingpad instruction associated with + /// the landing pad. + LandingPadInst *getLandingPadInst(); + private: /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress /// objects using it. This is almost always 0, sometimes one, possibly but diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index df68bd5ddd39..4b0dcc36232f 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -205,6 +205,23 @@ namespace bitc { BINOP_XOR = 12 }; + /// These are values used in the bitcode files to encode AtomicRMW operations. + /// The values of these enums have no fixed relation to the LLVM IR enum + /// values. Changing these will break compatibility with old files. + enum RMWOperations { + RMW_XCHG = 0, + RMW_ADD = 1, + RMW_SUB = 2, + RMW_AND = 3, + RMW_NAND = 4, + RMW_OR = 5, + RMW_XOR = 6, + RMW_MAX = 7, + RMW_MIN = 8, + RMW_UMAX = 9, + RMW_UMIN = 10 + }; + /// OverflowingBinaryOperatorOptionalFlags - Flags for serializing /// OverflowingBinaryOperator's SubclassOptionalData contents. enum OverflowingBinaryOperatorOptionalFlags { @@ -218,6 +235,23 @@ namespace bitc { PEO_EXACT = 0 }; + /// Encoded AtomicOrdering values. + enum AtomicOrderingCodes { + ORDERING_NOTATOMIC = 0, + ORDERING_UNORDERED = 1, + ORDERING_MONOTONIC = 2, + ORDERING_ACQUIRE = 3, + ORDERING_RELEASE = 4, + ORDERING_ACQREL = 5, + ORDERING_SEQCST = 6 + }; + + /// Encoded SynchronizationScope values. + enum AtomicSynchScopeCodes { + SYNCHSCOPE_SINGLETHREAD = 0, + SYNCHSCOPE_CROSSTHREAD = 1 + }; + // The function body block (FUNCTION_BLOCK_ID) describes function bodies. It // can contain a constant block (CONSTANTS_BLOCK_ID). enum FunctionCodes { @@ -266,7 +300,19 @@ namespace bitc { FUNC_CODE_INST_CALL = 34, // CALL: [attr, fnty, fnid, args...] - FUNC_CODE_DEBUG_LOC = 35 // DEBUG_LOC: [Line,Col,ScopeVal, IAVal] + FUNC_CODE_DEBUG_LOC = 35, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal] + FUNC_CODE_INST_FENCE = 36, // FENCE: [ordering, synchscope] + FUNC_CODE_INST_CMPXCHG = 37, // CMPXCHG: [ptrty,ptr,cmp,new, align, vol, + // ordering, synchscope] + FUNC_CODE_INST_ATOMICRMW = 38, // ATOMICRMW: [ptrty,ptr,val, operation, + // align, vol, + // ordering, synchscope] + FUNC_CODE_INST_RESUME = 39, // RESUME: [opval] + FUNC_CODE_INST_LANDINGPAD = 40, // LANDINGPAD: [ty,val,val,num,id0,val0...] + FUNC_CODE_INST_LOADATOMIC = 41, // LOAD: [opty, op, align, vol, + // ordering, synchscope] + FUNC_CODE_INST_STOREATOMIC = 42 // STORE: [ptrty,ptr,val, align, vol + // ordering, synchscope] }; } // End bitc namespace } // End llvm namespace diff --git a/include/llvm/CMakeLists.txt b/include/llvm/CMakeLists.txt index 0c3ca1cd0c5c..7956f8cafcfa 100644 --- a/include/llvm/CMakeLists.txt +++ b/include/llvm/CMakeLists.txt @@ -1,6 +1,6 @@ set(LLVM_TARGET_DEFINITIONS Intrinsics.td) -tablegen(Intrinsics.gen -gen-intrinsic) +llvm_tablegen(Intrinsics.gen -gen-intrinsic) add_custom_target(intrinsics_gen ALL DEPENDS ${llvm_builded_incs_dir}/Intrinsics.gen) diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h index f8a70293c155..d8e64071a1d9 100644 --- a/include/llvm/CodeGen/Analysis.h +++ b/include/llvm/CodeGen/Analysis.h @@ -33,12 +33,12 @@ class SelectionDAG; /// of insertvalue or extractvalue indices that identify a member, return /// the linearized index of the start of the member. /// -unsigned ComputeLinearIndex(const Type *Ty, +unsigned ComputeLinearIndex(Type *Ty, const unsigned *Indices, const unsigned *IndicesEnd, unsigned CurIndex = 0); -inline unsigned ComputeLinearIndex(const Type *Ty, +inline unsigned ComputeLinearIndex(Type *Ty, ArrayRef Indices, unsigned CurIndex = 0) { return ComputeLinearIndex(Ty, Indices.begin(), Indices.end(), CurIndex); @@ -51,7 +51,7 @@ inline unsigned ComputeLinearIndex(const Type *Ty, /// If Offsets is non-null, it points to a vector to be filled in /// with the in-memory offsets of each of the individual values. /// -void ComputeValueVTs(const TargetLowering &TLI, const Type *Ty, +void ComputeValueVTs(const TargetLowering &TLI, Type *Ty, SmallVectorImpl &ValueVTs, SmallVectorImpl *Offsets = 0, uint64_t StartingOffset = 0); diff --git a/include/llvm/CodeGen/CalcSpillWeights.h b/include/llvm/CodeGen/CalcSpillWeights.h index 60edcc584559..2f76a6cc5583 100644 --- a/include/llvm/CodeGen/CalcSpillWeights.h +++ b/include/llvm/CodeGen/CalcSpillWeights.h @@ -49,11 +49,6 @@ namespace llvm { const MachineLoopInfo &loops) : MF(mf), LIS(lis), Loops(loops) {} - /// CalculateRegClass - recompute the register class for reg from its uses. - /// Since the register class can affect the allocation hint, this function - /// should be called before CalculateWeightAndHint if both are called. - void CalculateRegClass(unsigned reg); - /// CalculateWeightAndHint - (re)compute li's spill weight and allocation /// hint. void CalculateWeightAndHint(LiveInterval &li); diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 962a4e263538..18202d93b460 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -54,8 +54,18 @@ class FastISel { const TargetInstrInfo &TII; const TargetLowering &TLI; const TargetRegisterInfo &TRI; + + /// The position of the last instruction for materializing constants + /// for use in the current block. It resets to EmitStartPt when it + /// makes sense (for example, it's usually profitable to avoid function + /// calls between the definition and the use) MachineInstr *LastLocalValue; + /// The top most instruction in the current block that is allowed for + /// emitting local variables. LastLocalValue resets to EmitStartPt when + /// it makes sense (for example, on function calls) + MachineInstr *EmitStartPt; + public: /// getLastLocalValue - Return the position of the last instruction /// emitted for materializing constants for use in the current block. @@ -63,7 +73,10 @@ class FastISel { /// setLastLocalValue - Update the position of the last instruction /// emitted for materializing constants for use in the current block. - void setLastLocalValue(MachineInstr *I) { LastLocalValue = I; } + void setLastLocalValue(MachineInstr *I) { + EmitStartPt = I; + LastLocalValue = I; + } /// startNewBlock - Set the current block to which generated machine /// instructions will be appended, and clear the local CSE map. @@ -358,6 +371,11 @@ class FastISel { /// be materialized with new instructions. unsigned materializeRegForValue(const Value *V, MVT VT); + /// flushLocalValueMap - clears LocalValueMap and moves the area for the + /// new local variables to the beginning of the block. It helps to avoid + /// spilling cached variables across heavy instructions like calls. + void flushLocalValueMap(); + /// hasTrivialKill - Test whether the given value has exactly one use. bool hasTrivialKill(const Value *V) const; }; diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h index 84bbf480473a..09dac8547a62 100644 --- a/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -19,6 +19,7 @@ #include "llvm/Instructions.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallVector.h" #ifndef NDEBUG @@ -139,7 +140,7 @@ class FunctionLoweringInfo { unsigned CreateReg(EVT VT); - unsigned CreateRegs(const Type *Ty); + unsigned CreateRegs(Type *Ty); unsigned InitializeRegForValue(const Value *V) { unsigned &R = ValueMap[V]; @@ -198,12 +199,12 @@ class FunctionLoweringInfo { LiveOutRegInfo[Reg].IsValid = false; } - /// setByValArgumentFrameIndex - Record frame index for the byval + /// setArgumentFrameIndex - Record frame index for the byval /// argument. - void setByValArgumentFrameIndex(const Argument *A, int FI); + void setArgumentFrameIndex(const Argument *A, int FI); - /// getByValArgumentFrameIndex - Get frame index for the byval argument. - int getByValArgumentFrameIndex(const Argument *A); + /// getArgumentFrameIndex - Get frame index for the byval argument. + int getArgumentFrameIndex(const Argument *A); private: /// LiveOutRegInfo - Information about live out vregs. @@ -220,6 +221,11 @@ void AddCatchInfo(const CallInst &I, void CopyCatchInfo(const BasicBlock *SuccBB, const BasicBlock *LPad, MachineModuleInfo *MMI, FunctionLoweringInfo &FLI); +/// AddLandingPadInfo - Extract the exception handling information from the +/// landingpad instruction and add them to the specified machine module info. +void AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI, + MachineBasicBlock *MBB); + } // end namespace llvm #endif diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h index 459cecda21e0..184e96dc4766 100644 --- a/include/llvm/CodeGen/ISDOpcodes.h +++ b/include/llvm/CodeGen/ISDOpcodes.h @@ -95,7 +95,7 @@ namespace ISD { // execution to HANDLER. Many platform-related details also :) EH_RETURN, - // OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) + // RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) // This corresponds to the eh.sjlj.setjmp intrinsic. // It takes an input chain and a pointer to the jump buffer as inputs // and returns an outchain. @@ -323,6 +323,12 @@ namespace ISD { // i1 then the high bits must conform to getBooleanContents. SELECT, + // Select with a vector condition (op #0) and two vector operands (ops #1 + // and #2), returning a vector result. All vectors have the same length. + // Much like the scalar select and setcc, each bit in the condition selects + // whether the corresponding result element is taken from op #1 or op #2. + VSELECT, + // Select with condition operator - This selects between a true value and // a false value (ops #2 and #3) based on the boolean result of comparing // the lhs and rhs (ops #0 and #1) of a conditional expression with the @@ -333,16 +339,10 @@ namespace ISD { // true. If the result value type is not i1 then the high bits conform // to getBooleanContents. The operands to this are the left and right // operands to compare (ops #0, and #1) and the condition code to compare - // them with (op #2) as a CondCodeSDNode. + // them with (op #2) as a CondCodeSDNode. If the operands are vector types + // then the result type must also be a vector type. SETCC, - // RESULT = VSETCC(LHS, RHS, COND) operator - This evaluates to a vector of - // integer elements with all bits of the result elements set to true if the - // comparison is true or all cleared if the comparison is false. The - // operands to this are the left and right operands to compare (LHS/RHS) and - // the condition code to compare them with (COND) as a CondCodeSDNode. - VSETCC, - // SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded // integer shift operations, just like ADD/SUB_PARTS. The operation // ordering is: @@ -566,14 +566,19 @@ namespace ISD { // HANDLENODE node - Used as a handle for various purposes. HANDLENODE, - // TRAMPOLINE - This corresponds to the init_trampoline intrinsic. - // It takes as input a token chain, the pointer to the trampoline, - // the pointer to the nested function, the pointer to pass for the - // 'nest' parameter, a SRCVALUE for the trampoline and another for - // the nested function (allowing targets to access the original - // Function*). It produces the result of the intrinsic and a token - // chain as output. - TRAMPOLINE, + // INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic. It + // takes as input a token chain, the pointer to the trampoline, the pointer + // to the nested function, the pointer to pass for the 'nest' parameter, a + // SRCVALUE for the trampoline and another for the nested function (allowing + // targets to access the original Function*). It produces a token chain as + // output. + INIT_TRAMPOLINE, + + // ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic. + // It takes a pointer to the trampoline and produces a (possibly) new + // pointer to the same trampoline with platform-specific adjustments + // applied. The pointer it returns points to an executable block of code. + ADJUST_TRAMPOLINE, // TRAP - Trapping instruction TRAP, @@ -592,22 +597,27 @@ namespace ISD { // and produces an output chain. MEMBARRIER, + // OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) + // This corresponds to the fence instruction. It takes an input chain, and + // two integer constants: an AtomicOrdering and a SynchronizationScope. + ATOMIC_FENCE, + + // Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) + // This corresponds to "load atomic" instruction. + ATOMIC_LOAD, + + // OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr, val) + // This corresponds to "store atomic" instruction. + ATOMIC_STORE, + // Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) - // this corresponds to the atomic.lcs intrinsic. - // cmp is compared to *ptr, and if equal, swap is stored in *ptr. - // the return is always the original value in *ptr + // This corresponds to the cmpxchg instruction. ATOMIC_CMP_SWAP, // Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) - // this corresponds to the atomic.swap intrinsic. - // amt is stored to *ptr atomically. - // the return is always the original value in *ptr - ATOMIC_SWAP, - // Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt) - // this corresponds to the atomic.load.[OpName] intrinsic. - // op(*ptr, amt) is stored to *ptr atomically. - // the return is always the original value in *ptr + // These correspond to the atomicrmw instruction. + ATOMIC_SWAP, ATOMIC_LOAD_ADD, ATOMIC_LOAD_SUB, ATOMIC_LOAD_AND, diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h new file mode 100644 index 000000000000..0271c5d85222 --- /dev/null +++ b/include/llvm/CodeGen/LexicalScopes.h @@ -0,0 +1,248 @@ +//===- LexicalScopes.cpp - Collecting lexical scope 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 LexicalScopes analysis. +// +// This pass collects lexical scope information and maps machine instructions +// to respective lexical scopes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_LEXICALSCOPES_H +#define LLVM_CODEGEN_LEXICALSCOPES_H + +#include "llvm/Metadata.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DebugLoc.h" +#include "llvm/Support/ValueHandle.h" +#include +namespace llvm { + +class MachineInstr; +class MachineBasicBlock; +class MachineFunction; +class LexicalScope; + +//===----------------------------------------------------------------------===// +/// InsnRange - This is used to track range of instructions with identical +/// lexical scope. +/// +typedef std::pair InsnRange; + +//===----------------------------------------------------------------------===// +/// LexicalScopes - This class provides interface to collect and use lexical +/// scoping information from machine instruction. +/// +class LexicalScopes { +public: + LexicalScopes() : MF(NULL), CurrentFnLexicalScope(NULL) { } + virtual ~LexicalScopes(); + + /// initialize - Scan machine function and constuct lexical scope nest. + virtual void initialize(const MachineFunction &); + + /// releaseMemory - release memory. + virtual void releaseMemory(); + + /// empty - Return true if there is any lexical scope information available. + bool empty() { return CurrentFnLexicalScope == NULL; } + + /// isCurrentFunctionScope - Return true if given lexical scope represents + /// current function. + bool isCurrentFunctionScope(const LexicalScope *LS) { + return LS == CurrentFnLexicalScope; + } + + /// getCurrentFunctionScope - Return lexical scope for the current function. + LexicalScope *getCurrentFunctionScope() const { return CurrentFnLexicalScope;} + + /// getMachineBasicBlocks - Populate given set using machine basic blocks + /// which have machine instructions that belong to lexical scope identified by + /// DebugLoc. + void getMachineBasicBlocks(DebugLoc DL, + SmallPtrSet &MBBs); + + /// dominates - Return true if DebugLoc's lexical scope dominates at least one + /// machine instruction's lexical scope in a given machine basic block. + bool dominates(DebugLoc DL, MachineBasicBlock *MBB); + + /// findLexicalScope - Find lexical scope, either regular or inlined, for the + /// given DebugLoc. Return NULL if not found. + LexicalScope *findLexicalScope(DebugLoc DL); + + /// getAbstractScopesList - Return a reference to list of abstract scopes. + ArrayRef getAbstractScopesList() const { + return AbstractScopesList; + } + + /// findAbstractScope - Find an abstract scope or return NULL. + LexicalScope *findAbstractScope(const MDNode *N) { + return AbstractScopeMap.lookup(N); + } + + /// findInlinedScope - Find an inlined scope for the given DebugLoc or return + /// NULL. + LexicalScope *findInlinedScope(DebugLoc DL) { + return InlinedLexicalScopeMap.lookup(DL); + } + + /// findLexicalScope - Find regular lexical scope or return NULL. + LexicalScope *findLexicalScope(const MDNode *N) { + return LexicalScopeMap.lookup(N); + } + + /// dump - Print data structures to dbgs(). + void dump(); + +private: + + /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If + /// not available then create new lexical scope. + LexicalScope *getOrCreateLexicalScope(DebugLoc DL); + + /// getOrCreateRegularScope - Find or create a regular lexical scope. + LexicalScope *getOrCreateRegularScope(MDNode *Scope); + + /// getOrCreateInlinedScope - Find or create an inlined lexical scope. + LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt); + + /// getOrCreateAbstractScope - Find or create an abstract lexical scope. + LexicalScope *getOrCreateAbstractScope(const MDNode *N); + + /// extractLexicalScopes - Extract instruction ranges for each lexical scopes + /// for the given machine function. + void extractLexicalScopes(SmallVectorImpl &MIRanges, + DenseMap &M); + void constructScopeNest(LexicalScope *Scope); + void assignInstructionRanges(SmallVectorImpl &MIRanges, + DenseMap &M); + +private: + const MachineFunction *MF; + + /// LexicalScopeMap - Tracks the scopes in the current function. Owns the + /// contained LexicalScope*s. + DenseMap LexicalScopeMap; + + /// InlinedLexicalScopeMap - Tracks inlined function scopes in current function. + DenseMap InlinedLexicalScopeMap; + + /// AbstractScopeMap - These scopes are not included LexicalScopeMap. + /// AbstractScopes owns its LexicalScope*s. + DenseMap AbstractScopeMap; + + /// AbstractScopesList - Tracks abstract scopes constructed while processing + /// a function. + SmallVectorAbstractScopesList; + + /// CurrentFnLexicalScope - Top level scope for the current function. + /// + LexicalScope *CurrentFnLexicalScope; +}; + +//===----------------------------------------------------------------------===// +/// LexicalScope - This class is used to track scope information. +/// +class LexicalScope { + +public: + LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A) + : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A), + LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0), IndentLevel(0) { + if (Parent) + Parent->addChild(this); + } + + virtual ~LexicalScope() {} + + // Accessors. + LexicalScope *getParent() const { return Parent; } + const MDNode *getDesc() const { return Desc; } + const MDNode *getInlinedAt() const { return InlinedAtLocation; } + const MDNode *getScopeNode() const { return Desc; } + bool isAbstractScope() const { return AbstractScope; } + SmallVector &getChildren() { return Children; } + SmallVector &getRanges() { return Ranges; } + + /// addChild - Add a child scope. + void addChild(LexicalScope *S) { Children.push_back(S); } + + /// openInsnRange - This scope covers instruction range starting from MI. + void openInsnRange(const MachineInstr *MI) { + if (!FirstInsn) + FirstInsn = MI; + + if (Parent) + Parent->openInsnRange(MI); + } + + /// extendInsnRange - Extend the current instruction range covered by + /// this scope. + void extendInsnRange(const MachineInstr *MI) { + assert (FirstInsn && "MI Range is not open!"); + LastInsn = MI; + if (Parent) + Parent->extendInsnRange(MI); + } + + /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected + /// until now. This is used when a new scope is encountered while walking + /// machine instructions. + void closeInsnRange(LexicalScope *NewScope = NULL) { + assert (LastInsn && "Last insn missing!"); + Ranges.push_back(InsnRange(FirstInsn, LastInsn)); + FirstInsn = NULL; + LastInsn = NULL; + // If Parent dominates NewScope then do not close Parent's instruction + // range. + if (Parent && (!NewScope || !Parent->dominates(NewScope))) + Parent->closeInsnRange(NewScope); + } + + /// dominates - Return true if current scope dominsates given lexical scope. + bool dominates(const LexicalScope *S) const { + if (S == this) + return true; + if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut()) + return true; + return false; + } + + // Depth First Search support to walk and manipulate LexicalScope hierarchy. + unsigned getDFSOut() const { return DFSOut; } + void setDFSOut(unsigned O) { DFSOut = O; } + unsigned getDFSIn() const { return DFSIn; } + void setDFSIn(unsigned I) { DFSIn = I; } + + /// dump - print lexical scope. + void dump() const; + +private: + LexicalScope *Parent; // Parent to this scope. + AssertingVH Desc; // Debug info descriptor. + AssertingVH InlinedAtLocation; // Location at which this + // scope is inlined. + bool AbstractScope; // Abstract Scope + SmallVector Children; // Scopes defined in scope. + // Contents not owned. + SmallVector Ranges; + + const MachineInstr *LastInsn; // Last instruction of this scope. + const MachineInstr *FirstInsn; // First instruction of this scope. + unsigned DFSIn, DFSOut; // In & Out Depth use to determine + // scope nesting. + mutable unsigned IndentLevel; // Private state for dump() +}; + +} // end llvm namespace + +#endif diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 5fd4d3df2666..2288c1a98b2d 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -100,6 +100,7 @@ namespace llvm { bool isDefByCopy() const { return copy != 0; } /// Returns true if one or more kills are PHI nodes. + /// Obsolete, do not use! bool hasPHIKill() const { return flags & HAS_PHI_KILL; } /// Set the PHI kill flag on this value. void setHasPHIKill(bool hasKill) { @@ -313,7 +314,6 @@ namespace llvm { /// RenumberValues - Renumber all values in order of appearance and remove /// unused values. - /// Recalculate phi-kill flags in case any phi-def values were removed. void RenumberValues(LiveIntervals &lis); /// isOnlyLROfValNo - Return true if the specified live range is the only @@ -411,6 +411,14 @@ namespace llvm { return I == end() ? 0 : I->valno; } + /// getVNInfoBefore - Return the VNInfo that is live up to but not + /// necessarilly including Idx, or NULL. Use this to find the reaching def + /// used by an instruction at this SlotIndex position. + VNInfo *getVNInfoBefore(SlotIndex Idx) const { + const_iterator I = FindLiveRangeContaining(Idx.getPrevSlot()); + return I == end() ? 0 : I->valno; + } + /// FindLiveRangeContaining - Return an iterator to the live range that /// contains the specified index, or end() if there is none. iterator FindLiveRangeContaining(SlotIndex Idx) { @@ -452,10 +460,10 @@ namespace llvm { addRangeFrom(LR, ranges.begin()); } - /// extendInBlock - If this interval is live before UseIdx in the basic - /// block that starts at StartIdx, extend it to be live at UseIdx and return - /// the value. If there is no live range before UseIdx, return NULL. - VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex UseIdx); + /// extendInBlock - If this interval is live before Kill in the basic block + /// that starts at StartIdx, extend it to be live up to Kill, and return + /// the value. If there is no live range before Kill, return NULL. + VNInfo *extendInBlock(SlotIndex StartIdx, SlotIndex Kill); /// join - Join two live intervals (this, and other) together. This applies /// mappings to the value numbers in the LHS/RHS intervals as specified. If diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h index 8a8dcaf5728f..86c4d7c11067 100644 --- a/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/include/llvm/CodeGen/LiveStackAnalysis.h @@ -25,6 +25,8 @@ namespace llvm { class LiveStacks : public MachineFunctionPass { + const TargetRegisterInfo *TRI; + /// Special pool allocator for VNInfo's (LiveInterval val#). /// VNInfo::Allocator VNInfoAllocator; diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h index f9b81b1ea7d6..7ba901fc28a4 100644 --- a/include/llvm/CodeGen/LiveVariables.h +++ b/include/llvm/CodeGen/LiveVariables.h @@ -231,6 +231,7 @@ class LiveVariables : public MachineFunctionPass { } assert(Removed && "Register is not used by this instruction!"); + (void)Removed; return true; } @@ -265,6 +266,7 @@ class LiveVariables : public MachineFunctionPass { } } assert(Removed && "Register is not defined by this instruction!"); + (void)Removed; return true; } diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h index 397e59ef18b9..5a20e952b9cc 100644 --- a/include/llvm/CodeGen/MachineBasicBlock.h +++ b/include/llvm/CodeGen/MachineBasicBlock.h @@ -232,7 +232,7 @@ class MachineBasicBlock : public ilist_node { /// setIsLandingPad - Indicates the block is a landing pad. That is /// this basic block is entered via an exception handler. - void setIsLandingPad() { IsLandingPad = true; } + void setIsLandingPad(bool V = true) { IsLandingPad = V; } /// getLandingPadSuccessor - If this block has a successor that is a landing /// pad, return it. Otherwise return NULL. diff --git a/include/llvm/CodeGen/MachineBlockFrequency.h b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h similarity index 60% rename from include/llvm/CodeGen/MachineBlockFrequency.h rename to include/llvm/CodeGen/MachineBlockFrequencyInfo.h index 25bf1f08dc64..416d40bf3098 100644 --- a/include/llvm/CodeGen/MachineBlockFrequency.h +++ b/include/llvm/CodeGen/MachineBlockFrequencyInfo.h @@ -1,4 +1,4 @@ -//====----- MachineBlockFrequency.h - MachineBlock Frequency Analysis ----====// +//====----- MachineBlockFrequencyInfo.h - MachineBlock Frequency Analysis ----====// // // The LLVM Compiler Infrastructure // @@ -11,10 +11,11 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_MACHINEBLOCKFREQUENCY_H -#define LLVM_CODEGEN_MACHINEBLOCKFREQUENCY_H +#ifndef LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H +#define LLVM_CODEGEN_MACHINEBLOCKFREQUENCYINFO_H #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/Support/BlockFrequency.h" #include namespace llvm { @@ -23,29 +24,29 @@ class MachineBranchProbabilityInfo; template class BlockFrequencyImpl; -/// MachineBlockFrequency pass uses BlockFrequencyImpl implementation to estimate +/// MachineBlockFrequencyInfo pass uses BlockFrequencyImpl implementation to estimate /// machine basic block frequencies. -class MachineBlockFrequency : public MachineFunctionPass { +class MachineBlockFrequencyInfo : public MachineFunctionPass { BlockFrequencyImpl *MBFI; public: static char ID; - MachineBlockFrequency(); + MachineBlockFrequencyInfo(); - ~MachineBlockFrequency(); + ~MachineBlockFrequencyInfo(); void getAnalysisUsage(AnalysisUsage &AU) const; bool runOnMachineFunction(MachineFunction &F); - /// getblockFreq - Return block frequency. Never return 0, value must be - /// positive. Please note that initial frequency is equal to 1024. It means + /// getblockFreq - Return block frequency. Return 0 if we don't have the + /// information. Please note that initial frequency is equal to 1024. It means /// that we should not rely on the value itself, but only on the comparison to - /// the other block frequencies. We do this to avoid using of the floating - /// points. - uint32_t getBlockFreq(MachineBasicBlock *MBB); + /// the other block frequencies. We do this to avoid using of floating points. + /// + BlockFrequency getBlockFreq(MachineBasicBlock *MBB) const; }; } diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h index beb16a2824d7..29f4f443bf7b 100644 --- a/include/llvm/CodeGen/MachineConstantPool.h +++ b/include/llvm/CodeGen/MachineConstantPool.h @@ -34,15 +34,15 @@ class raw_ostream; /// Abstract base class for all machine specific constantpool value subclasses. /// class MachineConstantPoolValue { - const Type *Ty; + Type *Ty; public: - explicit MachineConstantPoolValue(const Type *ty) : Ty(ty) {} + explicit MachineConstantPoolValue(Type *ty) : Ty(ty) {} virtual ~MachineConstantPoolValue() {} /// getType - get type of this MachineConstantPoolValue. /// - const Type *getType() const { return Ty; } + Type *getType() const { return Ty; } /// getRelocationInfo - This method classifies the entry according to @@ -54,7 +54,7 @@ class MachineConstantPoolValue { virtual int getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment) = 0; - virtual void AddSelectionDAGCSEId(FoldingSetNodeID &ID) = 0; + virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID) = 0; /// print - Implement operator<< virtual void print(raw_ostream &O) const = 0; @@ -104,7 +104,7 @@ class MachineConstantPoolEntry { return Alignment & ~(1 << (sizeof(unsigned)*CHAR_BIT-1)); } - const Type *getType() const; + Type *getType() const; /// getRelocationInfo - This method classifies the entry according to /// whether or not it may generate a relocation entry. This must be diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index 4ea6aa3396a9..b347ca8e680a 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -174,6 +174,10 @@ class MachineFrameInfo { /// StackProtectorIdx - The frame index for the stack protector. int StackProtectorIdx; + /// FunctionContextIdx - The frame index for the function context. Used for + /// SjLj exceptions. + int FunctionContextIdx; + /// MaxCallFrameSize - This contains the size of the largest call frame if the /// target uses frame setup/destroy pseudo instructions (as defined in the /// TargetFrameInfo class). This information is important for frame pointer @@ -220,6 +224,7 @@ class MachineFrameInfo { AdjustsStack = false; HasCalls = false; StackProtectorIdx = -1; + FunctionContextIdx = -1; MaxCallFrameSize = 0; CSIValid = false; LocalFrameSize = 0; @@ -244,6 +249,11 @@ class MachineFrameInfo { int getStackProtectorIndex() const { return StackProtectorIdx; } void setStackProtectorIndex(int I) { StackProtectorIdx = I; } + /// getFunctionContextIndex/setFunctionContextIndex - Return the index for the + /// function context object. This object is used for SjLj exceptions. + int getFunctionContextIndex() const { return FunctionContextIdx; } + void setFunctionContextIndex(int I) { FunctionContextIdx = I; } + /// isFrameAddressTaken - This method may be called any time after instruction /// selection is complete to determine if there is a call to /// \@llvm.frameaddress in this function. diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h index 5b3d3ea62a45..cae38f34709d 100644 --- a/include/llvm/CodeGen/MachineInstr.h +++ b/include/llvm/CodeGen/MachineInstr.h @@ -32,6 +32,7 @@ namespace llvm { template class SmallVectorImpl; class AliasAnalysis; class TargetInstrInfo; +class TargetRegisterClass; class TargetRegisterInfo; class MachineFunction; class MachineMemOperand; @@ -58,8 +59,6 @@ class MachineInstr : public ilist_node { }; private: const MCInstrDesc *MCID; // Instruction descriptor. - uint16_t NumImplicitOps; // Number of implicit operands (which - // are determined at construction time). uint8_t Flags; // Various bits of additional // information about machine @@ -78,9 +77,6 @@ class MachineInstr : public ilist_node { MachineBasicBlock *Parent; // Pointer to the owning basic block. DebugLoc debugLoc; // Source line information. - // OperandComplete - Return true if it's illegal to add a new operand - bool OperandsComplete() const; - MachineInstr(const MachineInstr&); // DO NOT IMPLEMENT void operator=(const MachineInstr&); // DO NOT IMPLEMENT @@ -393,6 +389,30 @@ class MachineInstr : public ilist_node { /// none is found. int findFirstPredOperandIdx() const; + /// findInlineAsmFlagIdx() - Find the index of the flag word operand that + /// corresponds to operand OpIdx on an inline asm instruction. Returns -1 if + /// getOperand(OpIdx) does not belong to an inline asm operand group. + /// + /// If GroupNo is not NULL, it will receive the number of the operand group + /// containing OpIdx. + /// + /// The flag operand is an immediate that can be decoded with methods like + /// InlineAsm::hasRegClassConstraint(). + /// + int findInlineAsmFlagIdx(unsigned OpIdx, unsigned *GroupNo = 0) const; + + /// getRegClassConstraint - Compute the static register class constraint for + /// operand OpIdx. For normal instructions, this is derived from the + /// MCInstrDesc. For inline assembly it is derived from the flag words. + /// + /// Returns NULL if the static register classs constraint cannot be + /// determined. + /// + const TargetRegisterClass* + getRegClassConstraint(unsigned OpIdx, + const TargetInstrInfo *TII, + const TargetRegisterInfo *TRI) const; + /// isRegTiedToUseOperand - Given the index of a register def operand, /// check if the register def is tied to a source operand, due to either /// two-address elimination or inline assembly constraints. Returns the diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h index fa185c46d5e3..2bf7f1788f8a 100644 --- a/include/llvm/CodeGen/MachineModuleInfo.h +++ b/include/llvm/CodeGen/MachineModuleInfo.h @@ -34,7 +34,7 @@ #include "llvm/Pass.h" #include "llvm/GlobalValue.h" #include "llvm/Metadata.h" -#include "llvm/CodeGen/MachineLocation.h" +#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCContext.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/DebugLoc.h" @@ -107,36 +107,42 @@ class MachineModuleInfo : public ImmutablePass { /// want. MachineModuleInfoImpl *ObjFileMMI; - // FrameMoves - List of moves done by a function's prolog. Used to construct - // frame maps by debug and exception handling consumers. + /// FrameMoves - List of moves done by a function's prolog. Used to construct + /// frame maps by debug and exception handling consumers. std::vector FrameMoves; - // LandingPads - List of LandingPadInfo describing the landing pad information - // in the current function. + /// CompactUnwindEncoding - If the target supports it, this is the compact + /// unwind encoding. It replaces a function's CIE and FDE. + uint32_t CompactUnwindEncoding; + + /// LandingPads - List of LandingPadInfo describing the landing pad + /// information in the current function. std::vector LandingPads; - // Map of invoke call site index values to associated begin EH_LABEL for - // the current function. + /// LPadToCallSiteMap - Map a landing pad's EH symbol to the call site + /// indexes. + DenseMap > LPadToCallSiteMap; + + /// CallSiteMap - Map of invoke call site index values to associated begin + /// EH_LABEL for the current function. DenseMap CallSiteMap; - // The current call site index being processed, if any. 0 if none. + /// CurCallSite - The current call site index being processed, if any. 0 if + /// none. unsigned CurCallSite; - // TypeInfos - List of C++ TypeInfo used in the current function. - // + /// TypeInfos - List of C++ TypeInfo used in the current function. std::vector TypeInfos; - // FilterIds - List of typeids encoding filters used in the current function. - // + /// FilterIds - List of typeids encoding filters used in the current function. std::vector FilterIds; - // FilterEnds - List of the indices in FilterIds corresponding to filter - // terminators. - // + /// FilterEnds - List of the indices in FilterIds corresponding to filter + /// terminators. std::vector FilterEnds; - // Personalities - Vector of all personality functions ever seen. Used to emit - // common EH frames. + /// Personalities - Vector of all personality functions ever seen. Used to + /// emit common EH frames. std::vector Personalities; /// UsedFunctions - The functions in the @llvm.used list in a more easily @@ -144,7 +150,6 @@ class MachineModuleInfo : public ImmutablePass { /// llvm.compiler.used. SmallPtrSet UsedFunctions; - /// AddrLabelSymbols - This map keeps track of which symbol is being used for /// the specified basic block's address of label. MMIAddrLabelMap *AddrLabelSymbols; @@ -156,8 +161,9 @@ class MachineModuleInfo : public ImmutablePass { /// in this module. bool DbgInfoAvailable; - /// True if this module calls VarArg function with floating point arguments. - /// This is used to emit an undefined reference to fltused on Windows targets. + /// CallsExternalVAFunctionWithFloatingPointArguments - True if this module + /// calls VarArg function with floating point arguments. This is used to emit + /// an undefined reference to fltused on Windows targets. bool CallsExternalVAFunctionWithFloatingPointArguments; public: @@ -170,7 +176,8 @@ class MachineModuleInfo : public ImmutablePass { MachineModuleInfo(); // DUMMY CONSTRUCTOR, DO NOT CALL. // Real constructor. - MachineModuleInfo(const MCAsmInfo &MAI, const TargetAsmInfo *TAI); + MachineModuleInfo(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, + const MCObjectFileInfo *MOFI); ~MachineModuleInfo(); bool doInitialization(); @@ -229,6 +236,15 @@ class MachineModuleInfo : public ImmutablePass { /// handling comsumers. std::vector &getFrameMoves() { return FrameMoves; } + /// getCompactUnwindEncoding - Returns the compact unwind encoding for a + /// function if the target supports the encoding. This encoding replaces a + /// function's CIE and FDE. + uint32_t getCompactUnwindEncoding() const { return CompactUnwindEncoding; } + + /// setCompactUnwindEncoding - Set the compact unwind encoding for a function + /// if the target supports the encoding. + void setCompactUnwindEncoding(uint32_t Enc) { CompactUnwindEncoding = Enc; } + /// getAddrLabelSymbol - Return the symbol to be used for the specified basic /// block when its address is taken. This cannot be its normal LBB label /// because the block may be accessed outside its containing function. @@ -286,12 +302,12 @@ class MachineModuleInfo : public ImmutablePass { /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad. /// void addCatchTypeInfo(MachineBasicBlock *LandingPad, - std::vector &TyInfo); + ArrayRef TyInfo); /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad. /// void addFilterTypeInfo(MachineBasicBlock *LandingPad, - std::vector &TyInfo); + ArrayRef TyInfo); /// addCleanup - Add a cleanup action for a landing pad. /// @@ -315,18 +331,42 @@ class MachineModuleInfo : public ImmutablePass { return LandingPads; } - /// setCallSiteBeginLabel - Map the begin label for a call site + /// setCallSiteLandingPad - Map the landing pad's EH symbol to the call + /// site indexes. + void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef Sites); + + /// getCallSiteLandingPad - Get the call site indexes for a landing pad EH + /// symbol. + SmallVectorImpl &getCallSiteLandingPad(MCSymbol *Sym) { + assert(hasCallSiteLandingPad(Sym) && + "missing call site number for landing pad!"); + return LPadToCallSiteMap[Sym]; + } + + /// hasCallSiteLandingPad - Return true if the landing pad Eh symbol has an + /// associated call site. + bool hasCallSiteLandingPad(MCSymbol *Sym) { + return !LPadToCallSiteMap[Sym].empty(); + } + + /// setCallSiteBeginLabel - Map the begin label for a call site. void setCallSiteBeginLabel(MCSymbol *BeginLabel, unsigned Site) { CallSiteMap[BeginLabel] = Site; } - /// getCallSiteBeginLabel - Get the call site number for a begin label + /// getCallSiteBeginLabel - Get the call site number for a begin label. unsigned getCallSiteBeginLabel(MCSymbol *BeginLabel) { - assert(CallSiteMap.count(BeginLabel) && + assert(hasCallSiteBeginLabel(BeginLabel) && "Missing call site number for EH_LABEL!"); return CallSiteMap[BeginLabel]; } + /// hasCallSiteBeginLabel - Return true if the begin label has a call site + /// number associated with it. + bool hasCallSiteBeginLabel(MCSymbol *BeginLabel) { + return CallSiteMap[BeginLabel] != 0; + } + /// setCurrentCallSite - Set the call site currently being processed. void setCurrentCallSite(unsigned Site) { CurCallSite = Site; } diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h index fdef574be932..5440a636a4a5 100644 --- a/include/llvm/CodeGen/MachineOperand.h +++ b/include/llvm/CodeGen/MachineOperand.h @@ -83,8 +83,23 @@ class MachineOperand { /// This is only valid on definitions of registers. bool IsDead : 1; - /// IsUndef - True if this is a register def / use of "undef", i.e. register - /// defined by an IMPLICIT_DEF. This is only valid on registers. + /// IsUndef - True if this register operand reads an "undef" value, i.e. the + /// read value doesn't matter. This flag can be set on both use and def + /// operands. On a sub-register def operand, it refers to the part of the + /// register that isn't written. On a full-register def operand, it is a + /// noop. See readsReg(). + /// + /// This is only valid on registers. + /// + /// Note that an instruction may have multiple operands referring to + /// the same register. In that case, the instruction may depend on those + /// operands reading the same dont-care value. For example: + /// + /// %vreg1 = XOR %vreg2, %vreg2 + /// + /// Any register can be used for %vreg2, and its value doesn't matter, but + /// the two operands must be the same register. + /// bool IsUndef : 1; /// IsEarlyClobber - True if this MO_Register 'def' operand is written to @@ -253,6 +268,15 @@ class MachineOperand { return IsDebug; } + /// readsReg - Returns true if this operand reads the previous value of its + /// register. A use operand with the flag set doesn't read its + /// register. A sub-register def implicitly reads the other parts of the + /// register being redefined unless the flag is set. + bool readsReg() const { + assert(isReg() && "Wrong MachineOperand accessor"); + return !isUndef() && (isUse() || getSubReg()); + } + /// getNextOperandForReg - Return the next MachineOperand in the function that /// uses or defines this register. MachineOperand *getNextOperandForReg() const { diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h index 10797263650d..3866b2650d0b 100644 --- a/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/include/llvm/CodeGen/MachineRegisterInfo.h @@ -25,6 +25,12 @@ namespace llvm { /// registers, including vreg register classes, use/def chains for registers, /// etc. class MachineRegisterInfo { + const TargetRegisterInfo *const TRI; + + /// IsSSA - True when the machine function is in SSA form and virtual + /// registers have a single def. + bool IsSSA; + /// VRegInfo - Information we keep for each virtual register. /// /// Each element in this list contains the register class of the vreg and the @@ -65,7 +71,23 @@ class MachineRegisterInfo { public: explicit MachineRegisterInfo(const TargetRegisterInfo &TRI); ~MachineRegisterInfo(); - + + //===--------------------------------------------------------------------===// + // Function State + //===--------------------------------------------------------------------===// + + // isSSA - Returns true when the machine function is in SSA form. Early + // passes require the machine function to be in SSA form where every virtual + // register has a single defining instruction. + // + // The TwoAddressInstructionPass and PHIElimination passes take the machine + // function out of SSA form when they introduce multiple defs per virtual + // register. + bool isSSA() const { return IsSSA; } + + // leaveSSA - Indicates that the machine function is no longer in SSA form. + void leaveSSA() { IsSSA = false; } + //===--------------------------------------------------------------------===// // Register Info //===--------------------------------------------------------------------===// @@ -195,12 +217,25 @@ class MachineRegisterInfo { void setRegClass(unsigned Reg, const TargetRegisterClass *RC); /// constrainRegClass - Constrain the register class of the specified virtual - /// register to be a common subclass of RC and the current register class. - /// Return the new register class, or NULL if no such class exists. + /// register to be a common subclass of RC and the current register class, + /// but only if the new class has at least MinNumRegs registers. Return the + /// new register class, or NULL if no such class exists. /// This should only be used when the constraint is known to be trivial, like /// GR32 -> GR32_NOSP. Beware of increasing register pressure. + /// const TargetRegisterClass *constrainRegClass(unsigned Reg, - const TargetRegisterClass *RC); + const TargetRegisterClass *RC, + unsigned MinNumRegs = 0); + + /// recomputeRegClass - Try to find a legal super-class of Reg's register + /// class that still satisfies the constraints from the instructions using + /// Reg. Returns true if Reg was upgraded. + /// + /// This method can be used after constraints have been removed from a + /// virtual register, for example after removing instructions or splitting + /// the live range. + /// + bool recomputeRegClass(unsigned Reg, const TargetMachine&); /// createVirtualRegister - Create and return a new virtual register in the /// function with the specified register class. diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index e7928cb65bd3..7a03ce905d89 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -24,7 +24,7 @@ namespace llvm { class MachineFunctionPass; class PassInfo; class TargetLowering; - class RegisterCoalescer; + class TargetRegisterClass; class raw_ostream; /// createUnreachableBlockEliminationPass - The LLVM code generator does not @@ -81,6 +81,9 @@ namespace llvm { /// register allocators. extern char &TwoAddressInstructionPassID; + /// RegisteCoalescer pass - This pass merges live ranges to eliminate copies. + extern char &RegisterCoalescerPassID; + /// SpillPlacement analysis. Suggest optimal placement of spill code between /// basic blocks. /// @@ -125,21 +128,15 @@ namespace llvm { /// FunctionPass *createDefaultPBQPRegisterAllocator(); - /// RegisterCoalescer Pass - Coalesce all copies possible. Can run - /// independently of the register allocator. - /// - RegisterCoalescer *createRegisterCoalescer(); - /// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code, /// and eliminates abstract frame references. /// FunctionPass *createPrologEpilogCodeInserter(); - /// LowerSubregs Pass - This pass lowers subregs to register-register copies - /// which yields suboptimal, but correct code if the register allocator - /// cannot coalesce all subreg operations during allocation. + /// ExpandPostRAPseudos Pass - This pass expands pseudo instructions after + /// register allocation. /// - FunctionPass *createLowerSubregsPass(); + FunctionPass *createExpandPostRAPseudosPass(); /// createPostRAScheduler - This pass performs post register allocation /// scheduling. @@ -229,6 +226,14 @@ namespace llvm { /// FunctionPass *createExpandISelPseudosPass(); + /// createExecutionDependencyFixPass - This pass fixes execution time + /// problems with dependent instructions, such as switching execution + /// domains to match. + /// + /// The pass will examine instructions using and defining registers in RC. + /// + FunctionPass *createExecutionDependencyFixPass(const TargetRegisterClass *RC); + } // End llvm namespace #endif diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 3ec5adabe6f2..132983c504e7 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -450,6 +450,10 @@ class SelectionDAG { SDValue getVectorShuffle(EVT VT, DebugLoc dl, SDValue N1, SDValue N2, const int *MaskElts); + /// getAnyExtOrTrunc - Convert Op, which must be of integer type, to the + /// integer type VT, by either any-extending or truncating it. + SDValue getAnyExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT); + /// getSExtOrTrunc - Convert Op, which must be of integer type, to the /// integer type VT, by either sign-extending or truncating it. SDValue getSExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT); @@ -560,17 +564,13 @@ class SelectionDAG { /// SDValue getSetCC(DebugLoc DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond) { + assert(LHS.getValueType().isVector() == RHS.getValueType().isVector() && + "Cannot compare scalars to vectors"); + assert(LHS.getValueType().isVector() == VT.isVector() && + "Cannot compare scalars to vectors"); return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond)); } - /// getVSetCC - Helper function to make it easier to build VSetCC's nodes - /// if you just have an ISD::CondCode instead of an SDValue. - /// - SDValue getVSetCC(DebugLoc DL, EVT VT, SDValue LHS, SDValue RHS, - ISD::CondCode Cond) { - return getNode(ISD::VSETCC, DL, VT, LHS, RHS, getCondCode(Cond)); - } - /// getSelectCC - Helper function to make it easier to build SelectCC's if you /// just have an ISD::CondCode instead of an SDValue. /// @@ -589,19 +589,37 @@ class SelectionDAG { /// takes 3 operands SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp, - MachinePointerInfo PtrInfo, unsigned Alignment=0); + MachinePointerInfo PtrInfo, unsigned Alignment, + AtomicOrdering Ordering, + SynchronizationScope SynchScope); SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp, - MachineMemOperand *MMO); + MachineMemOperand *MMO, + AtomicOrdering Ordering, + SynchronizationScope SynchScope); - /// getAtomic - Gets a node for an atomic op, produces result and chain and - /// takes 2 operands. + /// getAtomic - Gets a node for an atomic op, produces result (if relevant) + /// and chain and takes 2 operands. SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, const Value* PtrVal, - unsigned Alignment = 0); + unsigned Alignment, AtomicOrdering Ordering, + SynchronizationScope SynchScope); SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, - SDValue Ptr, SDValue Val, - MachineMemOperand *MMO); + SDValue Ptr, SDValue Val, MachineMemOperand *MMO, + AtomicOrdering Ordering, + SynchronizationScope SynchScope); + + /// getAtomic - Gets a node for an atomic op, produces result and chain and + /// takes 1 operand. + SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, EVT VT, + SDValue Chain, SDValue Ptr, const Value* PtrVal, + unsigned Alignment, + AtomicOrdering Ordering, + SynchronizationScope SynchScope); + SDValue getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, EVT VT, + SDValue Chain, SDValue Ptr, MachineMemOperand *MMO, + AtomicOrdering Ordering, + SynchronizationScope SynchScope); /// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a /// result and takes a list of operands. Opcode may be INTRINSIC_VOID, diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index a5c4201ef69a..6c7be69b4d2f 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -20,6 +20,7 @@ #define LLVM_CODEGEN_SELECTIONDAGNODES_H #include "llvm/Constants.h" +#include "llvm/Instructions.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/ilist_node.h" @@ -917,6 +918,13 @@ class MemSDNode : public SDNode { bool isVolatile() const { return (SubclassData >> 5) & 1; } bool isNonTemporal() const { return (SubclassData >> 6) & 1; } + AtomicOrdering getOrdering() const { + return AtomicOrdering((SubclassData >> 7) & 15); + } + SynchronizationScope getSynchScope() const { + return SynchronizationScope((SubclassData >> 11) & 1); + } + /// Returns the SrcValue and offset that describes the location of the access const Value *getSrcValue() const { return MMO->getValue(); } int64_t getSrcValueOffset() const { return MMO->getOffset(); } @@ -968,6 +976,8 @@ class MemSDNode : public SDNode { N->getOpcode() == ISD::ATOMIC_LOAD_MAX || N->getOpcode() == ISD::ATOMIC_LOAD_UMIN || N->getOpcode() == ISD::ATOMIC_LOAD_UMAX || + N->getOpcode() == ISD::ATOMIC_LOAD || + N->getOpcode() == ISD::ATOMIC_STORE || N->isTargetMemoryOpcode(); } }; @@ -977,6 +987,23 @@ class MemSDNode : public SDNode { class AtomicSDNode : public MemSDNode { SDUse Ops[4]; + void InitAtomic(AtomicOrdering Ordering, SynchronizationScope SynchScope) { + // This must match encodeMemSDNodeFlags() in SelectionDAG.cpp. + assert((Ordering & 15) == Ordering && + "Ordering may not require more than 4 bits!"); + assert((SynchScope & 1) == SynchScope && + "SynchScope may not require more than 1 bit!"); + SubclassData |= Ordering << 7; + SubclassData |= SynchScope << 11; + assert(getOrdering() == Ordering && "Ordering encoding error!"); + assert(getSynchScope() == SynchScope && "Synch-scope encoding error!"); + + assert((readMem() || getOrdering() <= Monotonic) && + "Acquire/Release MachineMemOperand must be a load!"); + assert((writeMem() || getOrdering() <= Monotonic) && + "Acquire/Release MachineMemOperand must be a store!"); + } + public: // Opc: opcode for atomic // VTL: value type list @@ -988,20 +1015,28 @@ class AtomicSDNode : public MemSDNode { // Align: alignment of memory AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT, SDValue Chain, SDValue Ptr, - SDValue Cmp, SDValue Swp, MachineMemOperand *MMO) + SDValue Cmp, SDValue Swp, MachineMemOperand *MMO, + AtomicOrdering Ordering, SynchronizationScope SynchScope) : MemSDNode(Opc, dl, VTL, MemVT, MMO) { - assert(readMem() && "Atomic MachineMemOperand is not a load!"); - assert(writeMem() && "Atomic MachineMemOperand is not a store!"); + InitAtomic(Ordering, SynchScope); InitOperands(Ops, Chain, Ptr, Cmp, Swp); } AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT, SDValue Chain, SDValue Ptr, - SDValue Val, MachineMemOperand *MMO) + SDValue Val, MachineMemOperand *MMO, + AtomicOrdering Ordering, SynchronizationScope SynchScope) : MemSDNode(Opc, dl, VTL, MemVT, MMO) { - assert(readMem() && "Atomic MachineMemOperand is not a load!"); - assert(writeMem() && "Atomic MachineMemOperand is not a store!"); + InitAtomic(Ordering, SynchScope); InitOperands(Ops, Chain, Ptr, Val); } + AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, EVT MemVT, + SDValue Chain, SDValue Ptr, + MachineMemOperand *MMO, + AtomicOrdering Ordering, SynchronizationScope SynchScope) + : MemSDNode(Opc, dl, VTL, MemVT, MMO) { + InitAtomic(Ordering, SynchScope); + InitOperands(Ops, Chain, Ptr); + } const SDValue &getBasePtr() const { return getOperand(1); } const SDValue &getVal() const { return getOperand(2); } @@ -1025,7 +1060,9 @@ class AtomicSDNode : public MemSDNode { N->getOpcode() == ISD::ATOMIC_LOAD_MIN || N->getOpcode() == ISD::ATOMIC_LOAD_MAX || N->getOpcode() == ISD::ATOMIC_LOAD_UMIN || - N->getOpcode() == ISD::ATOMIC_LOAD_UMAX; + N->getOpcode() == ISD::ATOMIC_LOAD_UMAX || + N->getOpcode() == ISD::ATOMIC_LOAD || + N->getOpcode() == ISD::ATOMIC_STORE; } }; @@ -1291,7 +1328,7 @@ class ConstantPoolSDNode : public SDNode { unsigned getAlignment() const { return Alignment; } unsigned char getTargetFlags() const { return TargetFlags; } - const Type *getType() const; + Type *getType() const; static bool classof(const ConstantPoolSDNode *) { return true; } static bool classof(const SDNode *N) { diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h index 6eb31802120e..2d98864dc9ed 100644 --- a/include/llvm/CodeGen/SlotIndexes.h +++ b/include/llvm/CodeGen/SlotIndexes.h @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements SlotIndex and related classes. The purpuse of SlotIndex +// This file implements SlotIndex and related classes. The purpose of SlotIndex // is to describe a position at which a register can become live, or cease to // be live. // diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 711280e98c91..ca40ccf85378 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -33,42 +33,13 @@ namespace llvm { class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { -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; public: - TargetLoweringObjectFileELF(); - ~TargetLoweringObjectFileELF() {} - - virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); - - virtual const MCSection *getEHFrameSection() const; - virtual const MCSection *getWin64EHFuncTableSection(StringRef) const { - return NULL; - } - virtual const MCSection *getWin64EHTableSection(StringRef) const{return NULL;} + virtual ~TargetLoweringObjectFileELF() {} virtual void emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, const MCSymbol *Sym) const; - 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; @@ -99,48 +70,8 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile { class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { - /// TLSDataSection - Section for thread local data. - /// - const MCSection *TLSDataSection; // Defaults to ".tdata". - - /// TLSBSSSection - Section for thread local uninitialized data. - /// - const MCSection *TLSBSSSection; // Defaults to ".tbss". - - /// TLSTLVSection - Section for thread local structure information. - /// Contains the source code name of the variable, visibility and a pointer - /// to the initial value (.tdata or .tbss). - const MCSection *TLSTLVSection; // Defaults to ".tlv". - - /// TLSThreadInitSection - Section for thread local data initialization - /// functions. - const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func". - - const MCSection *CStringSection; - const MCSection *UStringSection; - const MCSection *TextCoalSection; - const MCSection *ConstTextCoalSection; - 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(); - ~TargetLoweringObjectFileMachO() {} - - virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); - - virtual const MCSection *getEHFrameSection() const; - virtual const MCSection *getWin64EHFuncTableSection(StringRef) const { - return NULL; - } - virtual const MCSection *getWin64EHTableSection(StringRef) const{return NULL;} + virtual ~TargetLoweringObjectFileMachO() {} virtual const MCSection * SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, @@ -158,30 +89,6 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV, Mangler *) 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; - } - /// getExprForDwarfGlobalReference - The mach-o version of this method /// defaults to returning a stub reference. virtual const MCExpr * @@ -193,30 +100,13 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile { virtual MCSymbol * getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, MachineModuleInfo *MMI) const; - - virtual unsigned getPersonalityEncoding() const; - virtual unsigned getLSDAEncoding() const; - virtual unsigned getFDEEncoding(bool CFI) const; - virtual unsigned getTTypeEncoding() const; }; class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { - const MCSection *DrectveSection; - const MCSection *PDataSection; - const MCSection *XDataSection; public: - TargetLoweringObjectFileCOFF(); - ~TargetLoweringObjectFileCOFF() {} - - virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); - - virtual const MCSection *getEHFrameSection() const; - virtual const MCSection *getWin64EHFuncTableSection(StringRef) const; - virtual const MCSection *getWin64EHTableSection(StringRef) const; - - virtual const MCSection *getDrectveSection() const { return DrectveSection; } + virtual ~TargetLoweringObjectFileCOFF() {} virtual const MCSection * getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h index 424721bf6490..cae0bcb165c1 100644 --- a/include/llvm/CodeGen/ValueTypes.h +++ b/include/llvm/CodeGen/ValueTypes.h @@ -144,14 +144,14 @@ namespace llvm { /// isFloatingPoint - Return true if this is a FP, or a vector FP type. bool isFloatingPoint() const { return ((SimpleTy >= MVT::f32 && SimpleTy <= MVT::ppcf128) || - (SimpleTy >= MVT::v2f32 && SimpleTy <= MVT::v4f64)); + (SimpleTy >= MVT::v2f32 && SimpleTy <= MVT::v4f64)); } /// isInteger - Return true if this is an integer, or a vector integer type. bool isInteger() const { return ((SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE && SimpleTy <= MVT::LAST_INTEGER_VALUETYPE) || - (SimpleTy >= MVT::v2i8 && SimpleTy <= MVT::v8i64)); + (SimpleTy >= MVT::v2i8 && SimpleTy <= MVT::v8i64)); } /// isVector - Return true if this is a vector value type. @@ -380,7 +380,7 @@ namespace llvm { struct EVT { private: MVT V; - const Type *LLVMTy; + Type *LLVMTy; public: EVT() : V((MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE)), @@ -438,6 +438,21 @@ namespace llvm { return MVT::INVALID_SIMPLE_VALUE_TYPE; } + /// changeVectorElementTypeToInteger - Return a vector with the same number + /// of elements as this vector, but with the element type converted to an + /// integer type with the same bitwidth. + EVT changeVectorElementTypeToInteger() const { + if (!isSimple()) + return changeExtendedVectorElementTypeToInteger(); + MVT EltTy = getSimpleVT().getVectorElementType(); + unsigned BitWidth = EltTy.getSizeInBits(); + MVT IntTy = MVT::getIntegerVT(BitWidth); + MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements()); + assert(VecTy != MVT::INVALID_SIMPLE_VALUE_TYPE && + "Simple vector VT not representable by simple integer vector VT!"); + return VecTy; + } + /// isSimple - Test if the given EVT is simple (as opposed to being /// extended). bool isSimple() const { @@ -645,12 +660,12 @@ namespace llvm { /// getTypeForEVT - This method returns an LLVM type corresponding to the /// specified EVT. For integer types, this returns an unsigned type. Note /// that this will abort for types that cannot be represented. - const Type *getTypeForEVT(LLVMContext &Context) const; + Type *getTypeForEVT(LLVMContext &Context) const; /// getEVT - Return the value type corresponding to the specified type. /// This returns all pointers as iPTR. If HandleUnknown is true, unknown /// types are returned as Other, otherwise they are invalid. - static EVT getEVT(const Type *Ty, bool HandleUnknown = false); + static EVT getEVT(Type *Ty, bool HandleUnknown = false); intptr_t getRawBits() { if (isSimple()) @@ -674,6 +689,7 @@ namespace llvm { // Methods for handling the Extended-type case in functions above. // These are all out-of-line to prevent users of this header file // from having a dependency on Type.h. + EVT changeExtendedVectorElementTypeToInteger() const; static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth); static EVT getExtendedVectorVT(LLVMContext &C, EVT VT, unsigned NumElements); diff --git a/include/llvm/CompilerDriver/Action.h b/include/llvm/CompilerDriver/Action.h deleted file mode 100644 index f2b79655f60f..000000000000 --- a/include/llvm/CompilerDriver/Action.h +++ /dev/null @@ -1,54 +0,0 @@ -//===--- Action.h - The LLVM Compiler Driver --------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Action - encapsulates a single shell command. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_INCLUDE_COMPILER_DRIVER_ACTION_H -#define LLVM_INCLUDE_COMPILER_DRIVER_ACTION_H - -#include -#include - -namespace llvmc { - - typedef std::vector StrVector; - - /// Action - A class that encapsulates a single shell command. - class Action { - /// Command_ - The actual command (for example, 'ls'). - std::string Command_; - /// Args_ - Command arguments. Stdout redirection ("> file") is allowed. - std::vector Args_; - /// StopCompilation_ - Should we stop compilation after executing - /// this action? - bool StopCompilation_; - /// OutFile_ - The output file name. - std::string OutFile_; - - public: - void Construct (const std::string& C, const StrVector& A, - bool S, const std::string& O) { - Command_ = C; - Args_ = A; - StopCompilation_ = S; - OutFile_ = O; - } - bool IsConstructed () { return (Command_.size() != 0);} - - /// Execute - Executes the command. Returns -1 on error. - int Execute () const; - bool StopCompilation () const { return StopCompilation_; } - const std::string& OutFile() { return OutFile_; } - }; - -} - -#endif // LLVM_INCLUDE_COMPILER_DRIVER_ACTION_H diff --git a/include/llvm/CompilerDriver/AutoGenerated.h b/include/llvm/CompilerDriver/AutoGenerated.h deleted file mode 100644 index 7b926c622c90..000000000000 --- a/include/llvm/CompilerDriver/AutoGenerated.h +++ /dev/null @@ -1,40 +0,0 @@ -//===--- AutoGenerated.h - The LLVM Compiler Driver -------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Interface to the autogenerated driver code. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_INCLUDE_COMPILER_DRIVER_AUTOGENERATED_H -#define LLVM_INCLUDE_COMPILER_DRIVER_AUTOGENERATED_H - -namespace llvmc { - class LanguageMap; - class CompilationGraph; - - namespace autogenerated { - - int PreprocessOptions(); - int PopulateLanguageMap(LanguageMap& langMap); - int PopulateCompilationGraph(CompilationGraph& graph); - - inline int RunInitialization (LanguageMap& M, CompilationGraph& G) { - if (int ret = PreprocessOptions()) - return ret; - if (int ret = PopulateLanguageMap(M)) - return ret; - if (int ret = PopulateCompilationGraph(G)) - return ret; - - return 0; - } - } -} - -#endif // LLVM_INCLUDE_COMPILER_DRIVER_AUTOGENERATED_H diff --git a/include/llvm/CompilerDriver/BuiltinOptions.h b/include/llvm/CompilerDriver/BuiltinOptions.h deleted file mode 100644 index 7b9c15c52f7f..000000000000 --- a/include/llvm/CompilerDriver/BuiltinOptions.h +++ /dev/null @@ -1,39 +0,0 @@ -//===--- BuiltinOptions.h - The LLVM Compiler Driver ------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Declarations of all global command-line option variables. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H -#define LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H - -#include "llvm/Support/CommandLine.h" - -#include - -namespace llvmc { - -namespace SaveTempsEnum { enum Values { Cwd, Obj, Unset }; } - -extern llvm::cl::list InputFilenames; -extern llvm::cl::opt OutputFilename; -extern llvm::cl::opt TempDirname; -extern llvm::cl::list Languages; -extern llvm::cl::opt DryRun; -extern llvm::cl::opt Time; -extern llvm::cl::opt VerboseMode; -extern llvm::cl::opt CheckGraph; -extern llvm::cl::opt ViewGraph; -extern llvm::cl::opt WriteGraph; -extern llvm::cl::opt SaveTemps; - -} // End namespace llvmc. - -#endif // LLVM_INCLUDE_COMPILER_DRIVER_BUILTIN_OPTIONS_H diff --git a/include/llvm/CompilerDriver/Common.td b/include/llvm/CompilerDriver/Common.td deleted file mode 100644 index 6ba30aaa6406..000000000000 --- a/include/llvm/CompilerDriver/Common.td +++ /dev/null @@ -1,127 +0,0 @@ -//===- Common.td - Common definitions for LLVMC2 ----------*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains common definitions used in llvmc tool description files. -// -//===----------------------------------------------------------------------===// - -class Tool l> { - list properties = l; -} - -// Possible Tool properties. - -def in_language; -def out_language; -def output_suffix; -def command; -def out_file_option; -def in_file_option; -def join; -def sink; -def works_on_empty; -def actions; - -// Possible option types. - -def alias_option; -def switch_option; -def switch_list_option; -def parameter_option; -def parameter_list_option; -def prefix_option; -def prefix_list_option; - -// Possible option properties. - -def help; -def hidden; -def init; -def multi_val; -def one_or_more; -def zero_or_more; -def optional; -def really_hidden; -def required; -def comma_separated; -def forward_not_split; - -// The 'case' construct. -def case; - -// Boolean constants. -class Bool { - bit Value = val; -} -def true : Bool<1>; -def false : Bool<0>; - -// Boolean operators. -def and; -def or; -def not; - -// Primitive tests. -def switch_on; -def parameter_equals; -def element_in_list; -def input_languages_contain; -def empty; -def not_empty; -def default; -def single_input_file; -def multiple_input_files; -def any_switch_on; -def any_not_empty; -def any_empty; - -// Possible actions. - -def append_cmd; -def forward; -def forward_as; -def forward_value; -def forward_transformed_value; -def stop_compilation; -def no_out_file; -def unpack_values; -def warning; -def error; -def set_option; -def unset_option; - -// Increase the edge weight. -def inc_weight; - -// Option list - a single place to specify options. -class OptionList l> { - list options = l; -} - -// Option preprocessor - actions taken during plugin loading. -class OptionPreprocessor { - dag preprocessor = d; -} - -// Map from suffixes to language names - -def lang_to_suffixes; - -class LanguageMap l> { - list map = l; -} - -// Compilation graph - -def edge; -def optional_edge; - -class CompilationGraph l> { - list edges = l; -} diff --git a/include/llvm/CompilerDriver/CompilationGraph.h b/include/llvm/CompilerDriver/CompilationGraph.h deleted file mode 100644 index 951aff6f938d..000000000000 --- a/include/llvm/CompilerDriver/CompilationGraph.h +++ /dev/null @@ -1,330 +0,0 @@ -//===--- CompilationGraph.h - The LLVM Compiler Driver ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Compilation graph - definition. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_INCLUDE_COMPILER_DRIVER_COMPILATION_GRAPH_H -#define LLVM_INCLUDE_COMPILER_DRIVER_COMPILATION_GRAPH_H - -#include "llvm/CompilerDriver/Tool.h" - -#include "llvm/ADT/GraphTraits.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/Support/Path.h" - -#include -#include - -namespace llvmc { - - class CompilationGraph; - typedef llvm::StringSet<> InputLanguagesSet; - - /// LanguageMap - Maps from extensions to language names. - class LanguageMap : public llvm::StringMap { - public: - - /// GetLanguage - Find the language name corresponding to a given file. - const std::string* GetLanguage(const llvm::sys::Path&) const; - }; - - /// Edge - Represents an edge of the compilation graph. - class Edge : public llvm::RefCountedBaseVPTR { - public: - Edge(const std::string& T) : ToolName_(T) {} - virtual ~Edge() {} - - const std::string& ToolName() const { return ToolName_; } - virtual int Weight(const InputLanguagesSet& InLangs) const = 0; - private: - std::string ToolName_; - }; - - /// SimpleEdge - An edge that has no properties. - class SimpleEdge : public Edge { - public: - SimpleEdge(const std::string& T) : Edge(T) {} - int Weight(const InputLanguagesSet&) const { return 1; } - }; - - /// Node - A node (vertex) of the compilation graph. - struct Node { - // A Node holds a list of the outward edges. - typedef llvm::SmallVector, 3> container_type; - typedef container_type::iterator iterator; - typedef container_type::const_iterator const_iterator; - - Node() : OwningGraph(0), InEdges(0) {} - Node(CompilationGraph* G) : OwningGraph(G), InEdges(0) {} - Node(CompilationGraph* G, Tool* T) : - OwningGraph(G), ToolPtr(T), InEdges(0) {} - - bool HasChildren() const { return !OutEdges.empty(); } - const std::string Name() const - { return ToolPtr ? ToolPtr->Name() : "root"; } - - // Iteration. - iterator EdgesBegin() { return OutEdges.begin(); } - const_iterator EdgesBegin() const { return OutEdges.begin(); } - iterator EdgesEnd() { return OutEdges.end(); } - const_iterator EdgesEnd() const { return OutEdges.end(); } - - /// AddEdge - Add an outward edge. Takes ownership of the provided - /// Edge object. - void AddEdge(Edge* E); - - // Inward edge counter. Used to implement topological sort. - void IncrInEdges() { ++InEdges; } - void DecrInEdges() { --InEdges; } - bool HasNoInEdges() const { return InEdges == 0; } - - // Needed to implement NodeChildIterator/GraphTraits - CompilationGraph* OwningGraph; - // The corresponding Tool. - // WARNING: ToolPtr can be NULL (for the root node). - llvm::IntrusiveRefCntPtr ToolPtr; - // Links to children. - container_type OutEdges; - // Inward edge counter. Updated in - // CompilationGraph::insertEdge(). Used for topological sorting. - unsigned InEdges; - }; - - class NodesIterator; - - /// CompilationGraph - The compilation graph itself. - class CompilationGraph { - /// nodes_map_type - The main data structure. - typedef llvm::StringMap nodes_map_type; - /// tools_vector_type, tools_map_type - Data structures used to - /// map from language names to tools. (We can have several tools - /// associated with each language name, hence the need for a - /// vector.) - typedef - llvm::SmallVector, 3> tools_vector_type; - typedef llvm::StringMap tools_map_type; - - /// ToolsMap - Map from language names to lists of tool names. - tools_map_type ToolsMap; - /// NodesMap - Map from tool names to Tool objects. - nodes_map_type NodesMap; - - public: - - typedef nodes_map_type::iterator nodes_iterator; - typedef nodes_map_type::const_iterator const_nodes_iterator; - - CompilationGraph(); - - /// insertNode - Insert a new node into the graph. Takes - /// ownership of the object. - void insertNode(Tool* T); - - /// insertEdge - Insert a new edge into the graph. Takes ownership - /// of the Edge object. Returns non-zero value on error. - int insertEdge(const std::string& A, Edge* E); - - /// Build - Build target(s) from the input file set. Command-line options - /// are passed implicitly as global variables. Returns non-zero value on - /// error (usually the failed program's exit code). - int Build(llvm::sys::Path const& TempDir, const LanguageMap& LangMap); - - /// Check - Check the compilation graph for common errors like cycles, - /// input/output language mismatch and multiple default edges. Prints error - /// messages and in case it finds any errors. - int Check(); - - /// getNode - Return a reference to the node corresponding to the given tool - /// name. Returns 0 on error. - Node* getNode(const std::string& ToolName); - const Node* getNode(const std::string& ToolName) const; - - /// viewGraph - This function is meant for use from the debugger. You can - /// just say 'call G->viewGraph()' and a ghostview window should pop up from - /// the program, displaying the compilation graph. This depends on there - /// being a 'dot' and 'gv' program in your path. - void viewGraph(); - - /// writeGraph - Write Graphviz .dot source file to the current direcotry. - int writeGraph(const std::string& OutputFilename); - - // GraphTraits support. - friend NodesIterator GraphBegin(CompilationGraph*); - friend NodesIterator GraphEnd(CompilationGraph*); - - private: - // Helper functions. - - /// getToolsVector - Return a reference to the list of tool names - /// corresponding to the given language name. Returns 0 on error. - const tools_vector_type* getToolsVector(const std::string& LangName) const; - - /// PassThroughGraph - Pass the input file through the toolchain starting at - /// StartNode. - int PassThroughGraph (const llvm::sys::Path& In, const Node* StartNode, - const InputLanguagesSet& InLangs, - const llvm::sys::Path& TempDir, - const LanguageMap& LangMap) const; - - /// FindToolChain - Find head of the toolchain corresponding to - /// the given file. - const Node* FindToolChain(const llvm::sys::Path& In, - const std::string* ForceLanguage, - InputLanguagesSet& InLangs, - const LanguageMap& LangMap) const; - - /// BuildInitial - Traverse the initial parts of the toolchains. Returns - /// non-zero value on error. - int BuildInitial(InputLanguagesSet& InLangs, - const llvm::sys::Path& TempDir, - const LanguageMap& LangMap); - - /// TopologicalSort - Sort the nodes in topological order. Returns non-zero - /// value on error. - int TopologicalSort(std::vector& Out); - /// TopologicalSortFilterJoinNodes - Call TopologicalSort and filter the - /// resulting list to include only Join nodes. Returns non-zero value on - /// error. - int TopologicalSortFilterJoinNodes(std::vector& Out); - - // Functions used to implement Check(). - - /// CheckLanguageNames - Check that output/input language names match for - /// all nodes. Returns non-zero value on error (number of errors - /// encountered). - int CheckLanguageNames() const; - /// CheckMultipleDefaultEdges - check that there are no multiple default - /// default edges. Returns non-zero value on error (number of errors - /// encountered). - int CheckMultipleDefaultEdges() const; - /// CheckCycles - Check that there are no cycles in the graph. Returns - /// non-zero value on error (number of errors encountered). - int CheckCycles(); - - }; - - // GraphTraits support code. - - /// NodesIterator - Auxiliary class needed to implement GraphTraits - /// support. Can be generalised to something like value_iterator - /// for map-like containers. - class NodesIterator : public CompilationGraph::nodes_iterator { - typedef CompilationGraph::nodes_iterator super; - typedef NodesIterator ThisType; - typedef Node* pointer; - typedef Node& reference; - - public: - NodesIterator(super I) : super(I) {} - - inline reference operator*() const { - return super::operator->()->second; - } - inline pointer operator->() const { - return &super::operator->()->second; - } - }; - - inline NodesIterator GraphBegin(CompilationGraph* G) { - return NodesIterator(G->NodesMap.begin()); - } - - inline NodesIterator GraphEnd(CompilationGraph* G) { - return NodesIterator(G->NodesMap.end()); - } - - - /// NodeChildIterator - Another auxiliary class needed by GraphTraits. - class NodeChildIterator : public - std::iterator { - typedef NodeChildIterator ThisType; - typedef Node::container_type::iterator iterator; - - CompilationGraph* OwningGraph; - iterator EdgeIter; - public: - typedef Node* pointer; - typedef Node& reference; - - NodeChildIterator(Node* N, iterator I) : - OwningGraph(N->OwningGraph), EdgeIter(I) {} - - const ThisType& operator=(const ThisType& I) { - assert(OwningGraph == I.OwningGraph); - EdgeIter = I.EdgeIter; - return *this; - } - - inline bool operator==(const ThisType& I) const { - assert(OwningGraph == I.OwningGraph); - return EdgeIter == I.EdgeIter; - } - inline bool operator!=(const ThisType& I) const { - return !this->operator==(I); - } - - inline pointer operator*() const { - return OwningGraph->getNode((*EdgeIter)->ToolName()); - } - inline pointer operator->() const { - return this->operator*(); - } - - ThisType& operator++() { ++EdgeIter; return *this; } // Preincrement - ThisType operator++(int) { // Postincrement - ThisType tmp = *this; - ++*this; - return tmp; - } - - inline ThisType& operator--() { --EdgeIter; return *this; } // Predecrement - inline ThisType operator--(int) { // Postdecrement - ThisType tmp = *this; - --*this; - return tmp; - } - - }; -} - -namespace llvm { - template <> - struct GraphTraits { - typedef llvmc::CompilationGraph GraphType; - typedef llvmc::Node NodeType; - typedef llvmc::NodeChildIterator ChildIteratorType; - - static NodeType* getEntryNode(GraphType* G) { - return G->getNode("root"); - } - - static ChildIteratorType child_begin(NodeType* N) { - return ChildIteratorType(N, N->OutEdges.begin()); - } - static ChildIteratorType child_end(NodeType* N) { - return ChildIteratorType(N, N->OutEdges.end()); - } - - typedef llvmc::NodesIterator nodes_iterator; - static nodes_iterator nodes_begin(GraphType *G) { - return GraphBegin(G); - } - static nodes_iterator nodes_end(GraphType *G) { - return GraphEnd(G); - } - }; - -} - -#endif // LLVM_INCLUDE_COMPILER_DRIVER_COMPILATION_GRAPH_H diff --git a/include/llvm/CompilerDriver/Error.h b/include/llvm/CompilerDriver/Error.h deleted file mode 100644 index 013094e5dd79..000000000000 --- a/include/llvm/CompilerDriver/Error.h +++ /dev/null @@ -1,29 +0,0 @@ -//===--- Error.h - The LLVM Compiler Driver ---------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Error handling. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_INCLUDE_COMPILER_DRIVER_ERROR_H -#define LLVM_INCLUDE_COMPILER_DRIVER_ERROR_H - -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/raw_ostream.h" - -namespace llvmc { - - inline void PrintError(llvm::StringRef Err) { - extern const char* ProgramName; - llvm::errs() << ProgramName << ": " << Err << '\n'; - } - -} - -#endif // LLVM_INCLUDE_COMPILER_DRIVER_ERROR_H diff --git a/include/llvm/CompilerDriver/Main.h b/include/llvm/CompilerDriver/Main.h deleted file mode 100644 index d136a5d2fa19..000000000000 --- a/include/llvm/CompilerDriver/Main.h +++ /dev/null @@ -1,21 +0,0 @@ -//===--- Main.h - The LLVM Compiler Driver ----------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Entry point for the driver executable. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_INCLUDE_COMPILER_DRIVER_MAIN_H -#define LLVM_INCLUDE_COMPILER_DRIVER_MAIN_H - -namespace llvmc { - int Main(int argc, char** argv); -} - -#endif // LLVM_INCLUDE_COMPILER_DRIVER_MAIN_H diff --git a/include/llvm/CompilerDriver/Main.inc b/include/llvm/CompilerDriver/Main.inc deleted file mode 100644 index 41640437de89..000000000000 --- a/include/llvm/CompilerDriver/Main.inc +++ /dev/null @@ -1,23 +0,0 @@ -//===--- Main.inc - The LLVM Compiler Driver --------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Default main() for the driver executable. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_INCLUDE_COMPILER_DRIVER_MAIN_INC -#define LLVM_INCLUDE_COMPILER_DRIVER_MAIN_INC - -#include "llvm/CompilerDriver/Main.h" - -int main(int argc, char** argv) { - return llvmc::Main(argc, argv); -} - -#endif // LLVM_INCLUDE_COMPILER_DRIVER_MAIN_INC diff --git a/include/llvm/CompilerDriver/Tool.h b/include/llvm/CompilerDriver/Tool.h deleted file mode 100644 index 18a2b767923e..000000000000 --- a/include/llvm/CompilerDriver/Tool.h +++ /dev/null @@ -1,100 +0,0 @@ -//===--- Tool.h - The LLVM Compiler Driver ----------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Tool abstract base class - an interface to tool descriptions. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_INCLUDE_COMPILER_DRIVER_TOOL_H -#define LLVM_INCLUDE_COMPILER_DRIVER_TOOL_H - -#include "llvm/CompilerDriver/Action.h" - -#include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/Support/Path.h" - -#include -#include -#include - -namespace llvmc { - - class LanguageMap; - typedef std::vector > ArgsVector; - typedef std::vector PathVector; - typedef std::vector StrVector; - typedef llvm::StringSet<> InputLanguagesSet; - - /// Tool - Represents a single tool. - class Tool : public llvm::RefCountedBaseVPTR { - public: - - virtual ~Tool() {} - - /// GenerateAction - Generate an Action given particular command-line - /// options. Returns non-zero value on error. - virtual int GenerateAction (Action& Out, - const PathVector& inFiles, - const bool HasChildren, - const llvm::sys::Path& TempDir, - const InputLanguagesSet& InLangs, - const LanguageMap& LangMap) const = 0; - - /// GenerateAction - Generate an Action given particular command-line - /// options. Returns non-zero value on error. - virtual int GenerateAction (Action& Out, - const llvm::sys::Path& inFile, - const bool HasChildren, - const llvm::sys::Path& TempDir, - const InputLanguagesSet& InLangs, - const LanguageMap& LangMap) const = 0; - - virtual const char* Name() const = 0; - virtual const char** InputLanguages() const = 0; - virtual const char** OutputLanguages() const = 0; - - virtual bool IsJoin() const = 0; - virtual bool WorksOnEmpty() const = 0; - - protected: - /// OutFileName - Generate the output file name. - llvm::sys::Path OutFilename(const llvm::sys::Path& In, - const llvm::sys::Path& TempDir, - bool StopCompilation, - const char* OutputSuffix) const; - - StrVector SortArgs(ArgsVector& Args) const; - }; - - /// JoinTool - A Tool that has an associated input file list. - class JoinTool : public Tool { - public: - void AddToJoinList(const llvm::sys::Path& P) { JoinList_.push_back(P); } - void ClearJoinList() { JoinList_.clear(); } - bool JoinListEmpty() const { return JoinList_.empty(); } - - int GenerateAction(Action& Out, - const bool HasChildren, - const llvm::sys::Path& TempDir, - const InputLanguagesSet& InLangs, - const LanguageMap& LangMap) const { - return GenerateAction(Out, JoinList_, HasChildren, TempDir, InLangs, - LangMap); - } - // We shouldn't shadow base class's version of GenerateAction. - using Tool::GenerateAction; - - private: - PathVector JoinList_; - }; - -} - -#endif // LLVM_INCLUDE_COMPILER_DRIVER_TOOL_H diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake index 0b8a0add7e27..e44d429dfcf1 100644 --- a/include/llvm/Config/config.h.cmake +++ b/include/llvm/Config/config.h.cmake @@ -5,6 +5,27 @@ #ifndef CONFIG_H #define CONFIG_H +/* Bug report URL. */ +#define BUG_REPORT_URL "${BUG_REPORT_URL}" + +/* Relative directory for resource files */ +#define CLANG_RESOURCE_DIR "${CLANG_RESOURCE_DIR}" + +/* 32 bit multilib directory. */ +#define CXX_INCLUDE_32BIT_DIR "${CXX_INCLUDE_32BIT_DIR}" + +/* 64 bit multilib directory. */ +#define CXX_INCLUDE_64BIT_DIR "${CXX_INCLUDE_64BIT_DIR}" + +/* Arch the libstdc++ headers. */ +#define CXX_INCLUDE_ARCH "${CXX_INCLUDE_ARCH}" + +/* Directory with the libstdc++ headers. */ +#define CXX_INCLUDE_ROOT "${CXX_INCLUDE_ROOT}" + +/* Directories clang will search for headers */ +#define C_INCLUDE_DIRS "${C_INCLUDE_DIRS}" + /* Define if CBE is enabled for printf %a output */ #cmakedefine ENABLE_CBE_PRINTF_A ${ENABLE_CBE_PRINTF_A} @@ -196,9 +217,6 @@ /* Define to 1 if you have the `udis86' library (-ludis86). */ #undef HAVE_LIBUDIS86 -/* Type of 1st arg on ELM Callback */ -#cmakedefine WIN32_ELMCB_PCSTR ${WIN32_ELMCB_PCSTR} - /* Define to 1 if you have the header file. */ #cmakedefine HAVE_LIMITS_H ${HAVE_LIMITS_H} @@ -437,6 +455,12 @@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H} +/* Define if the neat program is available */ +#cmakedefine HAVE_TWOPI ${HAVE_TWOPI} + +/* Define to 1 if the system has the type `uint64_t'. */ +#cmakedefine HAVE_UINT64_T ${HAVE_UINT64_T} + /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H ${HAVE_UNISTD_H} @@ -513,41 +537,44 @@ #undef HOST_LINK_VERSION /* Installation directory for binary executables */ -#undef LLVM_BINDIR +#cmakedefine LLVM_BINDIR "${LLVM_BINDIR}" /* Time at which LLVM was configured */ -#undef LLVM_CONFIGTIME +#cmakedefine LLVM_CONFIGTIME "${LLVM_CONFIGTIME}" + +/* Installation directory for data files */ +#cmakedefine LLVM_DATADIR "${LLVM_DATADIR}" /* Installation directory for documentation */ -#undef LLVM_DATADIR - -/* Installation directory for documentation */ -#undef LLVM_DOCSDIR +#cmakedefine LLVM_DOCSDIR "${LLVM_DOCSDIR}" /* Installation directory for config files */ -#undef LLVM_ETCDIR +#cmakedefine LLVM_ETCDIR "${LLVM_ETCDIR}" + +/* Has gcc/MSVC atomic intrinsics */ +#cmakedefine01 LLVM_HAS_ATOMICS /* Host triple we were built on */ #cmakedefine LLVM_HOSTTRIPLE "${LLVM_HOSTTRIPLE}" /* Installation directory for include files */ -#undef LLVM_INCLUDEDIR +#cmakedefine LLVM_INCLUDEDIR "${LLVM_INCLUDEDIR}" /* Installation directory for .info files */ -#undef LLVM_INFODIR +#cmakedefine LLVM_INFODIR "${LLVM_INFODIR}" /* Installation directory for libraries */ -#undef LLVM_LIBDIR +#cmakedefine LLVM_LIBDIR "${LLVM_LIBDIR}" /* Installation directory for man pages */ -#undef LLVM_MANDIR - -/* Build multithreading support into LLVM */ -#cmakedefine LLVM_MULTITHREADED ${LLVM_MULTITHREADED} +#cmakedefine LLVM_MANDIR "${LLVM_MANDIR}" /* LLVM architecture name for the native architecture, if available */ #cmakedefine LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH} +/* LLVM name for the native AsmParser init function, if available */ +#cmakedefine LLVM_NATIVE_ASMPARSER LLVMInitialize${LLVM_NATIVE_ARCH}AsmParser + /* LLVM name for the native AsmPrinter init function, if available */ #cmakedefine LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter @@ -557,8 +584,8 @@ /* LLVM name for the native TargetInfo init function, if available */ #cmakedefine LLVM_NATIVE_TARGETINFO LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo -/* LLVM name for the native MCAsmInfo init function, if available */ -#cmakedefine LLVM_NATIVE_MCASMINFO LLVMInitialize${LLVM_NATIVE_ARCH}MCAsmInfo +/* LLVM name for the native target MC init function, if available */ +#cmakedefine LLVM_NATIVE_TARGETMC LLVMInitialize${LLVM_NATIVE_ARCH}TargetMC /* Define if this is Unixish platform */ #cmakedefine LLVM_ON_UNIX ${LLVM_ON_UNIX} @@ -579,7 +606,7 @@ #cmakedefine LLVM_PATH_FDP "${LLVM_PATH_FDP}" /* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */ -#undef LLVM_PATH_GRAPHVIZ +#cmakedefine LLVM_PATH_GRAPHVIZ "${LLVM_PATH_GRAPHVIZ}" /* Define to path to gv program if found or 'echo gv' otherwise */ #cmakedefine LLVM_PATH_GV "${LLVM_PATH_GV}" @@ -641,20 +668,6 @@ /* Define to 1 if the `S_IS*' macros in do not work properly. */ #undef STAT_MACROS_BROKEN -/* 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 do not work properly. */ -#undef STAT_MACROS_BROKEN - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME @@ -667,6 +680,9 @@ /* Define if use udis86 library */ #undef USE_UDIS86 +/* Type of 1st arg on ELM Callback */ +#cmakedefine WIN32_ELMCB_PCSTR ${WIN32_ELMCB_PCSTR} + /* Define to empty if `const' does not conform to ANSI C. */ #undef const @@ -679,16 +695,6 @@ /* Define to `unsigned int' if does not define. */ #undef size_t -/* Define if the neat program is available */ -#cmakedefine HAVE_TWOPI ${HAVE_TWOPI} - -/* Define to 1 if the system has the type `uint64_t'. */ -#cmakedefine HAVE_UINT64_T ${HAVE_UINT64_T} - -/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a - `char[]'. */ -#undef YYTEXT_POINTER - /* Define to a function replacing strtoll */ #cmakedefine strtoll ${strtoll} @@ -704,36 +710,6 @@ /* Define to 1 if you have the `_chsize_s' function. */ #cmakedefine HAVE__CHSIZE_S ${HAVE__CHSIZE_S} -/* define if the compiler implements namespaces */ -#undef HAVE_NAMESPACES - -/* Does not have std namespace iterator */ -#undef HAVE_STD_ITERATOR - -/* Does not have forward iterator */ -#undef HAVE_FWD_ITERATOR - -/* Does not have bi-directional iterator */ -#undef HAVE_BI_ITERATOR - -/* Does not have */ -#undef HAVE_GLOBAL_HASH_MAP - -/* Does not have hash_set in global namespace */ -#undef HAVE_GLOBAL_HASH_SET - -/* Does not have ext/hash_map */ -#undef HAVE_GNU_EXT_HASH_MAP - -/* Does not have hash_set in gnu namespace */ -#undef HAVE_GNU_EXT_HASH_SET - -/* Does not have ext/hash_map> */ -#undef HAVE_STD_EXT_HASH_MAP - -/* Does not have hash_set in std namespace */ -#undef HAVE_STD_EXT_HASH_SET - /* Added by Kevin -- Maximum path length */ #cmakedefine MAXPATHLEN ${MAXPATHLEN} diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in index 0a716ea79746..3670de557f4f 100644 --- a/include/llvm/Config/config.h.in +++ b/include/llvm/Config/config.h.in @@ -3,6 +3,9 @@ #ifndef CONFIG_H #define CONFIG_H +/* Bug report URL. */ +#undef BUG_REPORT_URL + /* Relative directory for resource files */ #undef CLANG_RESOURCE_DIR @@ -546,6 +549,9 @@ /* Installation directory for config files */ #undef LLVM_ETCDIR +/* Has gcc/MSVC atomic intrinsics */ +#undef LLVM_HAS_ATOMICS + /* Host triple we were built on */ #undef LLVM_HOSTTRIPLE @@ -561,9 +567,6 @@ /* Installation directory for man pages */ #undef LLVM_MANDIR -/* Build multithreading support into LLVM */ -#undef LLVM_MULTITHREADED - /* LLVM architecture name for the native architecture, if available */ #undef LLVM_NATIVE_ARCH @@ -573,15 +576,15 @@ /* LLVM name for the native AsmPrinter init function, if available */ #undef LLVM_NATIVE_ASMPRINTER -/* LLVM name for the native MCAsmInfo init function, if available */ -#undef LLVM_NATIVE_MCASMINFO - /* LLVM name for the native Target init function, if available */ #undef LLVM_NATIVE_TARGET /* LLVM name for the native TargetInfo init function, if available */ #undef LLVM_NATIVE_TARGETINFO +/* LLVM name for the native target MC init function, if available */ +#undef LLVM_NATIVE_TARGETMC + /* Define if this is Unixish platform */ #undef LLVM_ON_UNIX diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake index 5f948a2ab15a..4147fd1ff66d 100644 --- a/include/llvm/Config/llvm-config.h.cmake +++ b/include/llvm/Config/llvm-config.h.cmake @@ -31,6 +31,9 @@ /* Installation directory for config files */ #cmakedefine LLVM_ETCDIR "${LLVM_ETCDIR}" +/* Has gcc/MSVC atomic intrinsics */ +#cmakedefine01 LLVM_HAS_ATOMICS + /* Host triple we were built on */ #cmakedefine LLVM_HOSTTRIPLE "${LLVM_HOSTTRIPLE}" @@ -46,26 +49,23 @@ /* Installation directory for man pages */ #cmakedefine LLVM_MANDIR "${LLVM_MANDIR}" -/* Build multithreading support into LLVM */ -#cmakedefine LLVM_MULTITHREADED ${LLVM_MULTITHREADED} - /* LLVM architecture name for the native architecture, if available */ #cmakedefine LLVM_NATIVE_ARCH ${LLVM_NATIVE_ARCH} +/* LLVM name for the native AsmParser init function, if available */ +#cmakedefine LLVM_NATIVE_ASMPARSER LLVMInitialize${LLVM_NATIVE_ARCH}AsmParser + +/* LLVM name for the native AsmPrinter init function, if available */ +#cmakedefine LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter + /* LLVM name for the native Target init function, if available */ #cmakedefine LLVM_NATIVE_TARGET LLVMInitialize${LLVM_NATIVE_ARCH}Target /* LLVM name for the native TargetInfo init function, if available */ #cmakedefine LLVM_NATIVE_TARGETINFO LLVMInitialize${LLVM_NATIVE_ARCH}TargetInfo -/* LLVM name for the native MCAsmInfo init function, if available */ -#cmakedefine LLVM_NATIVE_MCASMINFO LLVMInitialize${LLVM_NATIVE_ARCH}MCAsmInfo - -/* LLVM name for the native AsmPrinter init function, if available */ -#cmakedefine LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter - -/* LLVM name for the native AsmPrinter init function, if available */ -#cmakedefine LLVM_NATIVE_ASMPARSER LLVMInitialize${LLVM_NATIVE_ARCH}AsmParser +/* LLVM name for the native target MC init function, if available */ +#cmakedefine LLVM_NATIVE_TARGETMC LLVMInitialize${LLVM_NATIVE_ARCH}TargetMC /* Define if this is Unixish platform */ #cmakedefine LLVM_ON_UNIX ${LLVM_ON_UNIX} diff --git a/include/llvm/Config/llvm-config.h.in b/include/llvm/Config/llvm-config.h.in index bc8ddce56fb6..b2257f37bbc7 100644 --- a/include/llvm/Config/llvm-config.h.in +++ b/include/llvm/Config/llvm-config.h.in @@ -31,6 +31,9 @@ /* Installation directory for config files */ #undef LLVM_ETCDIR +/* Has gcc/MSVC atomic intrinsics */ +#undef LLVM_HAS_ATOMICS + /* Host triple we were built on */ #undef LLVM_HOSTTRIPLE @@ -46,26 +49,23 @@ /* Installation directory for man pages */ #undef LLVM_MANDIR -/* Build multithreading support into LLVM */ -#undef LLVM_MULTITHREADED - /* LLVM architecture name for the native architecture, if available */ #undef LLVM_NATIVE_ARCH +/* LLVM name for the native AsmParser init function, if available */ +#undef LLVM_NATIVE_ASMPARSER + +/* LLVM name for the native AsmPrinter init function, if available */ +#undef LLVM_NATIVE_ASMPRINTER + /* LLVM name for the native Target init function, if available */ #undef LLVM_NATIVE_TARGET /* LLVM name for the native TargetInfo init function, if available */ #undef LLVM_NATIVE_TARGETINFO -/* LLVM name for the native MCAsmInfo init function, if available */ -#undef LLVM_NATIVE_MCASMINFO - -/* LLVM name for the native AsmPrinter init function, if available */ -#undef LLVM_NATIVE_ASMPRINTER - -/* LLVM name for the native AsmPrinter init function, if available */ -#undef LLVM_NATIVE_ASMPARSER +/* LLVM name for the native target MC init function, if available */ +#undef LLVM_NATIVE_TARGETMC /* Define if this is Unixish platform */ #undef LLVM_ON_UNIX @@ -97,6 +97,9 @@ /* Define to path to twopi program if found or 'echo twopi' otherwise */ #undef LLVM_PATH_TWOPI +/* Define to path to xdot.py program if found or 'echo xdot.py' otherwise */ +#undef LLVM_PATH_XDOT_PY + /* Installation prefix directory */ #undef LLVM_PREFIX diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h index 5e351c4ec504..ecc1fe70cc5d 100644 --- a/include/llvm/Constant.h +++ b/include/llvm/Constant.h @@ -43,7 +43,7 @@ class Constant : public User { Constant(const Constant &); // Do not implement protected: - Constant(const Type *ty, ValueTy vty, Use *Ops, unsigned NumOps) + Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps) : User(ty, vty, Ops, NumOps) {} void destroyConstantImpl(); @@ -52,6 +52,10 @@ class Constant : public User { /// getNullValue. bool isNullValue() const; + /// isAllOnesValue - Return true if this is the value that would be returned by + /// getAllOnesValue. + bool isAllOnesValue() const; + /// isNegativeZeroValue - Return true if the value is what would be returned /// by getZeroValueForNegation. bool isNegativeZeroValue() const; @@ -128,16 +132,16 @@ class Constant : public User { assert(0 && "Constants that do not have operands cannot be using 'From'!"); } - static Constant *getNullValue(const Type* Ty); + static Constant *getNullValue(Type* Ty); /// @returns the value for an integer constant of the given type that has all /// its bits set to true. /// @brief Get the all ones value - static Constant *getAllOnesValue(const Type* Ty); + static Constant *getAllOnesValue(Type* Ty); /// getIntegerValue - Return the value for an integer or pointer constant, /// or a vector thereof, with the given scalar value. - static Constant *getIntegerValue(const Type* Ty, const APInt &V); + static Constant *getIntegerValue(Type* Ty, const APInt &V); /// removeDeadConstantUsers - If there are any dead constant users dangling /// off of this constant, remove them. This method is useful for clients diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 01fca291843a..6545a3fedb92 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -47,7 +47,7 @@ struct ConvertConstantType; class ConstantInt : public Constant { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT ConstantInt(const ConstantInt &); // DO NOT IMPLEMENT - ConstantInt(const IntegerType *Ty, const APInt& V); + ConstantInt(IntegerType *Ty, const APInt& V); APInt Val; protected: // allocate space for exactly zero operands @@ -57,12 +57,12 @@ class ConstantInt : public Constant { public: static ConstantInt *getTrue(LLVMContext &Context); static ConstantInt *getFalse(LLVMContext &Context); - static Constant *getTrue(const Type *Ty); - static Constant *getFalse(const Type *Ty); + static Constant *getTrue(Type *Ty); + static Constant *getFalse(Type *Ty); /// If Ty is a vector type, return a Constant with a splat of the given /// value. Otherwise return a ConstantInt for the given value. - static Constant *get(const Type *Ty, uint64_t V, bool isSigned = false); + static Constant *get(Type *Ty, uint64_t V, bool isSigned = false); /// Return a ConstantInt with the specified integer value for the specified /// type. If the type is wider than 64 bits, the value will be zero-extended @@ -70,7 +70,7 @@ class ConstantInt : public Constant { /// be interpreted as a 64-bit signed integer and sign-extended to fit /// the type. /// @brief Get a ConstantInt for a specific value. - static ConstantInt *get(const IntegerType *Ty, uint64_t V, + static ConstantInt *get(IntegerType *Ty, uint64_t V, bool isSigned = false); /// Return a ConstantInt with the specified value for the specified type. The @@ -78,8 +78,8 @@ class ConstantInt : public Constant { /// either getSExtValue() or getZExtValue() will yield a correctly sized and /// signed value for the type Ty. /// @brief Get a ConstantInt for a specific signed value. - static ConstantInt *getSigned(const IntegerType *Ty, int64_t V); - static Constant *getSigned(const Type *Ty, int64_t V); + static ConstantInt *getSigned(IntegerType *Ty, int64_t V); + static Constant *getSigned(Type *Ty, int64_t V); /// Return a ConstantInt with the specified value and an implied Type. The /// type is the integer type that corresponds to the bit width of the value. @@ -87,12 +87,12 @@ class ConstantInt : public Constant { /// Return a ConstantInt constructed from the string strStart with the given /// radix. - static ConstantInt *get(const IntegerType *Ty, StringRef Str, + static ConstantInt *get(IntegerType *Ty, StringRef Str, uint8_t radix); /// If Ty is a vector type, return a Constant with a splat of the given /// value. Otherwise return a ConstantInt for the given value. - static Constant *get(const Type* Ty, const APInt& V); + static Constant *get(Type* Ty, const APInt& V); /// Return the constant as an APInt value reference. This allows clients to /// obtain a copy of the value, with all its precision in tact. @@ -133,8 +133,8 @@ class ConstantInt : public Constant { /// getType - Specialize the getType() method to always return an IntegerType, /// which reduces the amount of casting needed in parts of the compiler. /// - inline const IntegerType *getType() const { - return reinterpret_cast(Value::getType()); + inline IntegerType *getType() const { + return reinterpret_cast(Value::getType()); } /// This static method returns true if the type Ty is big enough to @@ -146,8 +146,8 @@ class ConstantInt : public Constant { /// to the appropriate unsigned type before calling the method. /// @returns true if V is a valid value for type Ty /// @brief Determine if the value is in range for the given type. - static bool isValueValidForType(const Type *Ty, uint64_t V); - static bool isValueValidForType(const Type *Ty, int64_t V); + static bool isValueValidForType(Type *Ty, uint64_t V); + static bool isValueValidForType(Type *Ty, int64_t V); bool isNegative() const { return Val.isNegative(); } @@ -170,7 +170,7 @@ class ConstantInt : public Constant { /// to true. /// @returns true iff this constant's bits are all set to true. /// @brief Determine if the value is all ones. - bool isAllOnesValue() const { + bool isMinusOne() const { return Val.isAllOnesValue(); } @@ -203,7 +203,7 @@ class ConstantInt : public Constant { /// value. /// @returns true iff this constant is greater or equal to the given number. /// @brief Determine if the value is greater or equal to the given number. - bool uge(uint64_t Num) { + bool uge(uint64_t Num) const { return Val.getActiveBits() > 64 || Val.getZExtValue() >= Num; } @@ -233,7 +233,7 @@ class ConstantFP : public Constant { ConstantFP(const ConstantFP &); // DO NOT IMPLEMENT friend class LLVMContextImpl; protected: - ConstantFP(const Type *Ty, const APFloat& V); + ConstantFP(Type *Ty, const APFloat& V); protected: // allocate space for exactly zero operands void *operator new(size_t s) { @@ -243,20 +243,20 @@ class ConstantFP : public Constant { /// Floating point negation must be implemented with f(x) = -0.0 - x. This /// method returns the negative zero constant for floating point or vector /// floating point types; for all other types, it returns the null value. - static Constant *getZeroValueForNegation(const Type *Ty); + static Constant *getZeroValueForNegation(Type *Ty); /// get() - This returns a ConstantFP, or a vector containing a splat of a /// ConstantFP, for the specified value in the specified type. This should /// only be used for simple constant values like 2.0/1.0 etc, that are /// known-valid both as host double and as the target format. - static Constant *get(const Type* Ty, double V); - static Constant *get(const Type* Ty, StringRef Str); + static Constant *get(Type* Ty, double V); + static Constant *get(Type* Ty, StringRef Str); static ConstantFP *get(LLVMContext &Context, const APFloat &V); - static ConstantFP *getNegativeZero(const Type* Ty); - static ConstantFP *getInfinity(const Type *Ty, bool Negative = false); + static ConstantFP *getNegativeZero(Type* Ty); + static ConstantFP *getInfinity(Type *Ty, bool Negative = false); /// isValueValidForType - return true if Ty is big enough to represent V. - static bool isValueValidForType(const Type *Ty, const APFloat &V); + static bool isValueValidForType(Type *Ty, const APFloat &V); inline const APFloat &getValueAPF() const { return Val; } /// isZero - Return true if the value is positive or negative zero. @@ -300,7 +300,7 @@ class ConstantAggregateZero : public Constant { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT ConstantAggregateZero(const ConstantAggregateZero &); // DO NOT IMPLEMENT protected: - explicit ConstantAggregateZero(const Type *ty) + explicit ConstantAggregateZero(Type *ty) : Constant(ty, ConstantAggregateZeroVal, 0, 0) {} protected: // allocate space for exactly zero operands @@ -308,7 +308,7 @@ class ConstantAggregateZero : public Constant { return User::operator new(s, 0); } public: - static ConstantAggregateZero* get(const Type *Ty); + static ConstantAggregateZero* get(Type *Ty); virtual void destroyConstant(); @@ -329,10 +329,10 @@ class ConstantArray : public Constant { std::vector >; ConstantArray(const ConstantArray &); // DO NOT IMPLEMENT protected: - ConstantArray(const ArrayType *T, const std::vector &Val); + ConstantArray(ArrayType *T, ArrayRef Val); public: // ConstantArray accessors - static Constant *get(const ArrayType *T, ArrayRef V); + static Constant *get(ArrayType *T, ArrayRef V); /// This method constructs a ConstantArray and initializes it with a text /// string. The default behavior (AddNull==true) causes a null terminator to @@ -349,8 +349,8 @@ class ConstantArray : public Constant { /// getType - Specialize the getType() method to always return an ArrayType, /// which reduces the amount of casting needed in parts of the compiler. /// - inline const ArrayType *getType() const { - return reinterpret_cast(Value::getType()); + inline ArrayType *getType() const { + return reinterpret_cast(Value::getType()); } /// isString - This method returns true if the array is an array of i8 and @@ -390,7 +390,7 @@ struct OperandTraits : public VariadicOperandTraits { }; -DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantArray, Constant) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantArray, Constant) //===----------------------------------------------------------------------===// // ConstantStruct - Constant Struct Declarations @@ -400,11 +400,11 @@ class ConstantStruct : public Constant { std::vector >; ConstantStruct(const ConstantStruct &); // DO NOT IMPLEMENT protected: - ConstantStruct(const StructType *T, const std::vector &Val); + ConstantStruct(StructType *T, ArrayRef Val); public: // ConstantStruct accessors - static Constant *get(const StructType *T, ArrayRef V); - static Constant *get(const StructType *T, ...) END_WITH_NULL; + static Constant *get(StructType *T, ArrayRef V); + static Constant *get(StructType *T, ...) END_WITH_NULL; /// getAnon - Return an anonymous struct that has the specified /// elements. If the struct is possibly empty, then you must specify a @@ -431,8 +431,8 @@ class ConstantStruct : public Constant { /// getType() specialization - Reduce amount of casting... /// - inline const StructType *getType() const { - return reinterpret_cast(Value::getType()); + inline StructType *getType() const { + return reinterpret_cast(Value::getType()); } virtual void destroyConstant(); @@ -450,7 +450,7 @@ struct OperandTraits : public VariadicOperandTraits { }; -DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantStruct, Constant) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantStruct, Constant) //===----------------------------------------------------------------------===// @@ -461,7 +461,7 @@ class ConstantVector : public Constant { std::vector >; ConstantVector(const ConstantVector &); // DO NOT IMPLEMENT protected: - ConstantVector(const VectorType *T, const std::vector &Val); + ConstantVector(VectorType *T, ArrayRef Val); public: // ConstantVector accessors static Constant *get(ArrayRef V); @@ -472,8 +472,8 @@ class ConstantVector : public Constant { /// getType - Specialize the getType() method to always return a VectorType, /// which reduces the amount of casting needed in parts of the compiler. /// - inline const VectorType *getType() const { - return reinterpret_cast(Value::getType()); + inline VectorType *getType() const { + return reinterpret_cast(Value::getType()); } /// This function will return true iff every element in this vector constant @@ -501,7 +501,7 @@ struct OperandTraits : public VariadicOperandTraits { }; -DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantVector, Constant) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantVector, Constant) //===----------------------------------------------------------------------===// /// ConstantPointerNull - a constant pointer value that points to null @@ -511,8 +511,8 @@ class ConstantPointerNull : public Constant { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT ConstantPointerNull(const ConstantPointerNull &); // DO NOT IMPLEMENT protected: - explicit ConstantPointerNull(const PointerType *T) - : Constant(reinterpret_cast(T), + explicit ConstantPointerNull(PointerType *T) + : Constant(reinterpret_cast(T), Value::ConstantPointerNullVal, 0, 0) {} protected: @@ -522,15 +522,15 @@ class ConstantPointerNull : public Constant { } public: /// get() - Static factory methods - Return objects of the specified value - static ConstantPointerNull *get(const PointerType *T); + static ConstantPointerNull *get(PointerType *T); virtual void destroyConstant(); /// getType - Specialize the getType() method to always return an PointerType, /// which reduces the amount of casting needed in parts of the compiler. /// - inline const PointerType *getType() const { - return reinterpret_cast(Value::getType()); + inline PointerType *getType() const { + return reinterpret_cast(Value::getType()); } /// Methods for support type inquiry through isa, cast, and dyn_cast: @@ -575,7 +575,7 @@ struct OperandTraits : public FixedNumOperandTraits { }; -DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(BlockAddress, Value) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BlockAddress, Value) //===----------------------------------------------------------------------===// @@ -591,7 +591,7 @@ class ConstantExpr : public Constant { friend struct ConvertConstantType; protected: - ConstantExpr(const Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps) + ConstantExpr(Type *ty, unsigned Opcode, Use *Ops, unsigned NumOps) : Constant(ty, ConstantExprVal, Ops, NumOps) { // Operation type (an Instruction opcode) is stored as the SubclassData. setValueSubclassData(Opcode); @@ -605,23 +605,23 @@ class ConstantExpr : public Constant { /// getAlignOf constant expr - computes the alignment of a type in a target /// independent way (Note: the return type is an i64). - static Constant *getAlignOf(const Type *Ty); + static Constant *getAlignOf(Type *Ty); /// getSizeOf constant expr - computes the (alloc) size of a type (in /// address-units, not bits) in a target independent way (Note: the return /// type is an i64). /// - static Constant *getSizeOf(const Type *Ty); + static Constant *getSizeOf(Type *Ty); /// 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); + static Constant *getOffsetOf(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 Type *Ty, Constant *FieldNo); + static Constant *getOffsetOf(Type *Ty, Constant *FieldNo); static Constant *getNeg(Constant *C, bool HasNUW = false, bool HasNSW =false); static Constant *getFNeg(Constant *C); @@ -648,18 +648,18 @@ class ConstantExpr : public Constant { bool HasNUW = false, bool HasNSW = false); static Constant *getLShr(Constant *C1, Constant *C2, bool isExact = false); static Constant *getAShr(Constant *C1, Constant *C2, bool isExact = false); - static Constant *getTrunc (Constant *C, const Type *Ty); - static Constant *getSExt (Constant *C, const Type *Ty); - static Constant *getZExt (Constant *C, const Type *Ty); - static Constant *getFPTrunc (Constant *C, const Type *Ty); - static Constant *getFPExtend(Constant *C, const Type *Ty); - static Constant *getUIToFP (Constant *C, const Type *Ty); - static Constant *getSIToFP (Constant *C, const Type *Ty); - static Constant *getFPToUI (Constant *C, const Type *Ty); - static Constant *getFPToSI (Constant *C, const Type *Ty); - static Constant *getPtrToInt(Constant *C, const Type *Ty); - static Constant *getIntToPtr(Constant *C, const Type *Ty); - static Constant *getBitCast (Constant *C, const Type *Ty); + static Constant *getTrunc (Constant *C, Type *Ty); + static Constant *getSExt (Constant *C, Type *Ty); + static Constant *getZExt (Constant *C, Type *Ty); + static Constant *getFPTrunc (Constant *C, Type *Ty); + static Constant *getFPExtend(Constant *C, Type *Ty); + static Constant *getUIToFP (Constant *C, Type *Ty); + static Constant *getSIToFP (Constant *C, Type *Ty); + static Constant *getFPToUI (Constant *C, Type *Ty); + static Constant *getFPToSI (Constant *C, Type *Ty); + static Constant *getPtrToInt(Constant *C, Type *Ty); + static Constant *getIntToPtr(Constant *C, Type *Ty); + static Constant *getBitCast (Constant *C, Type *Ty); static Constant *getNSWNeg(Constant *C) { return getNeg(C, false, true); } static Constant *getNUWNeg(Constant *C) { return getNeg(C, true, false); } @@ -708,44 +708,44 @@ class ConstantExpr : public Constant { static Constant *getCast( unsigned ops, ///< The opcode for the conversion Constant *C, ///< The constant to be converted - const Type *Ty ///< The type to which the constant is converted + Type *Ty ///< The type to which the constant is converted ); // @brief Create a ZExt or BitCast cast constant expression static Constant *getZExtOrBitCast( Constant *C, ///< The constant to zext or bitcast - const Type *Ty ///< The type to zext or bitcast C to + Type *Ty ///< The type to zext or bitcast C to ); // @brief Create a SExt or BitCast cast constant expression static Constant *getSExtOrBitCast( Constant *C, ///< The constant to sext or bitcast - const Type *Ty ///< The type to sext or bitcast C to + Type *Ty ///< The type to sext or bitcast C to ); // @brief Create a Trunc or BitCast cast constant expression static Constant *getTruncOrBitCast( Constant *C, ///< The constant to trunc or bitcast - const Type *Ty ///< The type to trunc or bitcast C to + Type *Ty ///< The type to trunc or bitcast C to ); /// @brief Create a BitCast or a PtrToInt cast constant expression static Constant *getPointerCast( Constant *C, ///< The pointer value to be casted (operand 0) - const Type *Ty ///< The type to which cast should be made + Type *Ty ///< The type to which cast should be made ); /// @brief Create a ZExt, Bitcast or Trunc for integer -> integer casts static Constant *getIntegerCast( Constant *C, ///< The integer constant to be casted - const Type *Ty, ///< The integer type to cast to + Type *Ty, ///< The integer type to cast to bool isSigned ///< Whether C should be treated as signed or not ); /// @brief Create a FPExt, Bitcast or FPTrunc for fp -> fp casts static Constant *getFPCast( Constant *C, ///< The integer constant to be casted - const Type *Ty ///< The integer type to cast to + Type *Ty ///< The integer type to cast to ); /// @brief Return true if this is a convert constant expression @@ -788,25 +788,40 @@ class ConstantExpr : public Constant { /// all elements must be Constant's. /// static Constant *getGetElementPtr(Constant *C, - Constant *const *IdxList, unsigned NumIdx, + ArrayRef IdxList, bool InBounds = false) { - return getGetElementPtr(C, (Value**)IdxList, NumIdx, InBounds); + return getGetElementPtr(C, makeArrayRef((Value * const *)IdxList.data(), + IdxList.size()), + InBounds); } static Constant *getGetElementPtr(Constant *C, - Value *const *IdxList, unsigned NumIdx, + Constant *Idx, + bool InBounds = false) { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef or + // ArrayRef. + return getGetElementPtr(C, cast(Idx), InBounds); + } + static Constant *getGetElementPtr(Constant *C, + ArrayRef IdxList, bool InBounds = false); /// Create an "inbounds" getelementptr. See the documentation for the /// "inbounds" flag in LangRef.html for details. static Constant *getInBoundsGetElementPtr(Constant *C, - Constant *const *IdxList, - unsigned NumIdx) { - return getGetElementPtr(C, IdxList, NumIdx, true); + ArrayRef IdxList) { + return getGetElementPtr(C, IdxList, true); } static Constant *getInBoundsGetElementPtr(Constant *C, - Value* const *IdxList, - unsigned NumIdx) { - return getGetElementPtr(C, IdxList, NumIdx, true); + Constant *Idx) { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef or + // ArrayRef. + return getGetElementPtr(C, Idx, true); + } + static Constant *getInBoundsGetElementPtr(Constant *C, + ArrayRef IdxList) { + return getGetElementPtr(C, IdxList, true); } static Constant *getExtractElement(Constant *Vec, Constant *Idx); @@ -845,7 +860,7 @@ class ConstantExpr : public Constant { /// operands replaced with the specified values and with the specified result /// type. The specified array must have the same number of operands as our /// current one. - Constant *getWithOperands(ArrayRef Ops, const Type *Ty) const; + Constant *getWithOperands(ArrayRef Ops, Type *Ty) const; virtual void destroyConstant(); virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); @@ -869,7 +884,7 @@ struct OperandTraits : public VariadicOperandTraits { }; -DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(ConstantExpr, Constant) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantExpr, Constant) //===----------------------------------------------------------------------===// /// UndefValue - 'undef' values are things that do not have specified contents. @@ -886,7 +901,7 @@ class UndefValue : public Constant { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT UndefValue(const UndefValue &); // DO NOT IMPLEMENT protected: - explicit UndefValue(const Type *T) : Constant(T, UndefValueVal, 0, 0) {} + explicit UndefValue(Type *T) : Constant(T, UndefValueVal, 0, 0) {} protected: // allocate space for exactly zero operands void *operator new(size_t s) { @@ -896,7 +911,7 @@ class UndefValue : public Constant { /// get() - Static factory methods - Return an 'undef' object of the specified /// type. /// - static UndefValue *get(const Type *T); + static UndefValue *get(Type *T); virtual void destroyConstant(); diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h new file mode 100644 index 000000000000..64f80c506504 --- /dev/null +++ b/include/llvm/DebugInfo/DIContext.h @@ -0,0 +1,68 @@ +//===-- DIContext.h ---------------------------------------------*- 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 DIContext, an abstract data structure that holds +// debug information data. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DICONTEXT_H +#define LLVM_DEBUGINFO_DICONTEXT_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" +#include + +namespace llvm { + +class raw_ostream; + +/// DILineInfo - a format-neutral container for source line information. +class DILineInfo { + const char *FileName; + uint32_t Line; + uint32_t Column; +public: + DILineInfo() : FileName(""), Line(0), Column(0) {} + DILineInfo(const char *fileName, uint32_t line, uint32_t column) + : FileName(fileName), Line(line), Column(column) {} + + const char *getFileName() const { return FileName; } + uint32_t getLine() const { return Line; } + uint32_t getColumn() const { return Column; } + + bool operator==(const DILineInfo &RHS) const { + return Line == RHS.Line && Column == RHS.Column && + std::strcmp(FileName, RHS.FileName) == 0; + } + bool operator!=(const DILineInfo &RHS) const { + return !(*this == RHS); + } +}; + +class DIContext { +public: + virtual ~DIContext(); + + /// getDWARFContext - get a context for binary DWARF data. + static DIContext *getDWARFContext(bool isLittleEndian, + StringRef infoSection, + StringRef abbrevSection, + StringRef aRangeSection = StringRef(), + StringRef lineSection = StringRef(), + StringRef stringSection = StringRef()); + + virtual void dump(raw_ostream &OS) = 0; + + virtual DILineInfo getLineInfoForAddress(uint64_t address) = 0; +}; + +} + +#endif diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index acb28deada10..445c3deb7ce2 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -96,26 +96,26 @@ class IntegerType : public Type { class FunctionType : public Type { FunctionType(const FunctionType &); // Do not implement const FunctionType &operator=(const FunctionType &); // Do not implement - FunctionType(const Type *Result, ArrayRef Params, bool IsVarArgs); + FunctionType(Type *Result, ArrayRef Params, bool IsVarArgs); public: /// FunctionType::get - This static method is the primary way of constructing /// a FunctionType. /// - static FunctionType *get(const Type *Result, + static FunctionType *get(Type *Result, ArrayRef Params, bool isVarArg); /// FunctionType::get - Create a FunctionType taking no parameters. /// - static FunctionType *get(const Type *Result, bool isVarArg); + static FunctionType *get(Type *Result, bool isVarArg); /// isValidReturnType - Return true if the specified type is valid as a return /// type. - static bool isValidReturnType(const Type *RetTy); + static bool isValidReturnType(Type *RetTy); /// isValidArgumentType - Return true if the specified type is valid as an /// argument type. - static bool isValidArgumentType(const Type *ArgTy); + static bool isValidArgumentType(Type *ArgTy); bool isVarArg() const { return getSubclassData(); } Type *getReturnType() const { return ContainedTys[0]; } @@ -150,8 +150,8 @@ class CompositeType : public Type { /// getTypeAtIndex - Given an index value into the type, return the type of /// the element. /// - Type *getTypeAtIndex(const Value *V) const; - Type *getTypeAtIndex(unsigned Idx) const; + Type *getTypeAtIndex(const Value *V); + Type *getTypeAtIndex(unsigned Idx); bool indexValid(const Value *V) const; bool indexValid(unsigned Idx) const; @@ -166,10 +166,25 @@ class CompositeType : public Type { }; -/// StructType - Class to represent struct types, both normal and packed. -/// Besides being optionally packed, structs can be either "anonymous" or may -/// have an identity. Anonymous structs are uniqued by structural equivalence, -/// but types are each unique when created, and optionally have a name. +/// StructType - Class to represent struct types. There are two different kinds +/// of struct types: Literal structs and Identified structs. +/// +/// Literal struct types (e.g. { i32, i32 }) are uniqued structurally, and must +/// always have a body when created. You can get one of these by using one of +/// the StructType::get() forms. +/// +/// Identified structs (e.g. %foo or %42) may optionally have a name and are not +/// uniqued. The names for identified structs are managed at the LLVMContext +/// level, so there can only be a single identified struct with a given name in +/// a particular LLVMContext. Identified structs may also optionally be opaque +/// (have no body specified). You get one of these by using one of the +/// StructType::create() forms. +/// +/// Independent of what kind of struct you have, the body of a struct type are +/// laid out in memory consequtively with the elements directly one after the +/// other (if the struct is packed) or (if not packed) with padding between the +/// elements as defined by TargetData (which is required to match what the code +/// generator for a target expects). /// class StructType : public CompositeType { StructType(const StructType &); // Do not implement @@ -180,13 +195,13 @@ class StructType : public CompositeType { // This is the contents of the SubClassData field. SCDB_HasBody = 1, SCDB_Packed = 2, - SCDB_IsAnonymous = 4 + SCDB_IsLiteral = 4 }; /// SymbolTableEntry - For a named struct that actually has a name, this is a /// pointer to the symbol table entry (maintained by LLVMContext) for the - /// struct. This is null if the type is an anonymous struct or if it is - /// a named type that has an empty name. + /// struct. This is null if the type is an literal struct or if it is + /// a identified type that has an empty name. /// void *SymbolTableEntry; public: @@ -194,20 +209,23 @@ class StructType : public CompositeType { delete [] ContainedTys; // Delete the body. } - /// StructType::createNamed - This creates a named struct with no body - /// specified. If the name is empty, it creates an unnamed struct, which has - /// a unique identity but no actual name. - static StructType *createNamed(LLVMContext &Context, StringRef Name); + /// StructType::create - This creates an identified struct. + static StructType *create(LLVMContext &Context, StringRef Name); + static StructType *create(LLVMContext &Context); - static StructType *createNamed(StringRef Name, ArrayRef Elements, - bool isPacked = false); - static StructType *createNamed(LLVMContext &Context, StringRef Name, - ArrayRef Elements, - bool isPacked = false); - static StructType *createNamed(StringRef Name, Type *elt1, ...) END_WITH_NULL; + static StructType *create(ArrayRef Elements, + StringRef Name, + bool isPacked = false); + static StructType *create(ArrayRef Elements); + static StructType *create(LLVMContext &Context, + ArrayRef Elements, + StringRef Name, + bool isPacked = false); + static StructType *create(LLVMContext &Context, ArrayRef Elements); + static StructType *create(StringRef Name, Type *elt1, ...) END_WITH_NULL; /// StructType::get - This static method is the primary way to create a - /// StructType. + /// literal StructType. static StructType *get(LLVMContext &Context, ArrayRef Elements, bool isPacked = false); @@ -223,9 +241,9 @@ class StructType : public CompositeType { bool isPacked() const { return (getSubclassData() & SCDB_Packed) != 0; } - /// isAnonymous - Return true if this type is uniqued by structural - /// equivalence, false if it has an identity. - bool isAnonymous() const {return (getSubclassData() & SCDB_IsAnonymous) != 0;} + /// isLiteral - Return true if this type is uniqued by structural + /// equivalence, false if it is a struct definition. + bool isLiteral() const { return (getSubclassData() & SCDB_IsLiteral) != 0; } /// isOpaque - Return true if this is a type with an identity that has no body /// specified yet. These prints as 'opaque' in .ll files. @@ -236,21 +254,21 @@ class StructType : public CompositeType { /// getName - Return the name for this struct type if it has an identity. /// This may return an empty string for an unnamed struct type. Do not call - /// this on an anonymous type. + /// this on an literal type. StringRef getName() const; /// setName - Change the name of this type to the specified name, or to a name - /// with a suffix if there is a collision. Do not call this on an anonymous + /// with a suffix if there is a collision. Do not call this on an literal /// type. void setName(StringRef Name); - /// setBody - Specify a body for an opaque type. + /// setBody - Specify a body for an opaque identified type. void setBody(ArrayRef Elements, bool isPacked = false); void setBody(Type *elt1, ...) END_WITH_NULL; /// isValidElementType - Return true if the specified type is valid as a /// element type. - static bool isValidElementType(const Type *ElemTy); + static bool isValidElementType(Type *ElemTy); // Iterator access to the elements. @@ -260,7 +278,7 @@ class StructType : public CompositeType { /// isLayoutIdentical - Return true if this is layout identical to the /// specified struct. - bool isLayoutIdentical(const StructType *Other) const; + bool isLayoutIdentical(StructType *Other) const; // Random access to the elements unsigned getNumElements() const { return NumContainedTys; } @@ -321,11 +339,11 @@ class ArrayType : public SequentialType { /// ArrayType::get - This static method is the primary way to construct an /// ArrayType /// - static ArrayType *get(const Type *ElementType, uint64_t NumElements); + static ArrayType *get(Type *ElementType, uint64_t NumElements); /// isValidElementType - Return true if the specified type is valid as a /// element type. - static bool isValidElementType(const Type *ElemTy); + static bool isValidElementType(Type *ElemTy); uint64_t getNumElements() const { return NumElements; } @@ -348,13 +366,13 @@ class VectorType : public SequentialType { /// VectorType::get - This static method is the primary way to construct an /// VectorType. /// - static VectorType *get(const Type *ElementType, unsigned NumElements); + static VectorType *get(Type *ElementType, unsigned NumElements); /// VectorType::getInteger - This static method gets a VectorType with the /// same number of elements as the input type, and the element type is an /// integer type of the same width as the input element type. /// - static VectorType *getInteger(const VectorType *VTy) { + static VectorType *getInteger(VectorType *VTy) { unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); Type *EltTy = IntegerType::get(VTy->getContext(), EltBits); return VectorType::get(EltTy, VTy->getNumElements()); @@ -364,7 +382,7 @@ class VectorType : public SequentialType { /// getInteger except that the element types are twice as wide as the /// elements in the input type. /// - static VectorType *getExtendedElementVectorType(const VectorType *VTy) { + static VectorType *getExtendedElementVectorType(VectorType *VTy) { unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); Type *EltTy = IntegerType::get(VTy->getContext(), EltBits * 2); return VectorType::get(EltTy, VTy->getNumElements()); @@ -374,7 +392,7 @@ class VectorType : public SequentialType { /// getInteger except that the element types are half as wide as the /// elements in the input type. /// - static VectorType *getTruncatedElementVectorType(const VectorType *VTy) { + static VectorType *getTruncatedElementVectorType(VectorType *VTy) { unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); assert((EltBits & 1) == 0 && "Cannot truncate vector element with odd bit-width"); @@ -384,7 +402,7 @@ class VectorType : public SequentialType { /// isValidElementType - Return true if the specified type is valid as a /// element type. - static bool isValidElementType(const Type *ElemTy); + static bool isValidElementType(Type *ElemTy); /// @brief Return the number of elements in the Vector type. unsigned getNumElements() const { return NumElements; } @@ -411,17 +429,17 @@ class PointerType : public SequentialType { public: /// PointerType::get - This constructs a pointer to an object of the specified /// type in a numbered address space. - static PointerType *get(const Type *ElementType, unsigned AddressSpace); + static PointerType *get(Type *ElementType, unsigned AddressSpace); /// PointerType::getUnqual - This constructs a pointer to an object of the /// specified type in the generic address space (address space zero). - static PointerType *getUnqual(const Type *ElementType) { + static PointerType *getUnqual(Type *ElementType) { return PointerType::get(ElementType, 0); } /// isValidElementType - Return true if the specified type is valid as a /// element type. - static bool isValidElementType(const Type *ElemTy); + static bool isValidElementType(Type *ElemTy); /// @brief Return the address space of the Pointer type. inline unsigned getAddressSpace() const { return getSubclassData(); } diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 88b21cd4d253..cf85671eb414 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -18,6 +18,7 @@ #include #include #include +#include "llvm/MC/MCCodeGenInfo.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/ValueMap.h" @@ -119,9 +120,7 @@ class ExecutionEngine { /// optimize for the case where there is only one module. SmallVector Modules; - void setTargetData(const TargetData *td) { - TD = td; - } + void setTargetData(const TargetData *td) { TD = td; } /// getMemoryforGV - Allocate memory for a global variable. virtual char *getMemoryForGV(const GlobalVariable *GV); @@ -143,8 +142,7 @@ class ExecutionEngine { CodeGenOpt::Level OptLevel, bool GVsWithCode, TargetMachine *TM); - static ExecutionEngine *(*InterpCtor)(Module *M, - std::string *ErrorStr); + static ExecutionEngine *(*InterpCtor)(Module *M, std::string *ErrorStr); /// LazyFunctionCreator - If an unknown function is needed, this function /// pointer is invoked to create it. If this returns null, the JIT will @@ -186,7 +184,7 @@ class ExecutionEngine { bool ForceInterpreter = false, std::string *ErrorStr = 0, CodeGenOpt::Level OptLevel = - CodeGenOpt::Default, + CodeGenOpt::Default, bool GVsWithCode = true); /// createJIT - This is the factory method for creating a JIT for the current @@ -199,10 +197,11 @@ class ExecutionEngine { std::string *ErrorStr = 0, JITMemoryManager *JMM = 0, CodeGenOpt::Level OptLevel = - CodeGenOpt::Default, + CodeGenOpt::Default, bool GVsWithCode = true, + Reloc::Model RM = Reloc::Default, CodeModel::Model CMM = - CodeModel::Default); + CodeModel::JITDefault); /// 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 @@ -314,7 +313,7 @@ class ExecutionEngine { /// GenericValue *. It is not a pointer to a GenericValue containing the /// address at which to store Val. void StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr, - const Type *Ty); + Type *Ty); void InitializeMemory(const Constant *Init, void *Addr); @@ -440,7 +439,7 @@ class ExecutionEngine { GenericValue getConstantValue(const Constant *C); void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, - const Type *Ty); + Type *Ty); }; namespace EngineKind { @@ -463,6 +462,7 @@ class EngineBuilder { CodeGenOpt::Level OptLevel; JITMemoryManager *JMM; bool AllocateGVsWithCode; + Reloc::Model RelocModel; CodeModel::Model CMModel; std::string MArch; std::string MCPU; @@ -476,7 +476,8 @@ class EngineBuilder { OptLevel = CodeGenOpt::Default; JMM = NULL; AllocateGVsWithCode = false; - CMModel = CodeModel::Default; + RelocModel = Reloc::Default; + CMModel = CodeModel::JITDefault; UseMCJIT = false; } @@ -517,8 +518,16 @@ class EngineBuilder { return *this; } + /// setRelocationModel - Set the relocation model that the ExecutionEngine + /// target is using. Defaults to target specific default "Reloc::Default". + EngineBuilder &setRelocationModel(Reloc::Model RM) { + RelocModel = RM; + return *this; + } + /// setCodeModel - Set the CodeModel that the ExecutionEngine target - /// data is using. Defaults to target specific default "CodeModel::Default". + /// data is using. Defaults to target specific default + /// "CodeModel::JITDefault". EngineBuilder &setCodeModel(CodeModel::Model M) { CMModel = M; return *this; @@ -569,6 +578,8 @@ class EngineBuilder { StringRef MArch, StringRef MCPU, const SmallVectorImpl& MAttrs, + Reloc::Model RM, + CodeModel::Model CM, std::string *Err); ExecutionEngine *create(); diff --git a/include/llvm/Function.h b/include/llvm/Function.h index 0aa5b2a9fa4c..678651bbf1f8 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -117,11 +117,11 @@ class Function : public GlobalValue, /// function is automatically inserted into the end of the function list for /// the module. /// - Function(const FunctionType *Ty, LinkageTypes Linkage, + Function(FunctionType *Ty, LinkageTypes Linkage, const Twine &N = "", Module *M = 0); public: - static Function *Create(const FunctionType *Ty, LinkageTypes Linkage, + static Function *Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N = "", Module *M = 0) { return new(0) Function(Ty, Linkage, N, M); } diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h index c3d3c38bd344..164d976588d6 100644 --- a/include/llvm/GlobalAlias.h +++ b/include/llvm/GlobalAlias.h @@ -23,7 +23,6 @@ namespace llvm { class Module; -class Constant; template class SymbolTableListTraits; @@ -41,11 +40,11 @@ class GlobalAlias : public GlobalValue, public ilist_node { } /// GlobalAlias ctor - If a parent module is specified, the alias is /// automatically inserted into the end of the specified module's alias list. - GlobalAlias(const Type *Ty, LinkageTypes Linkage, const Twine &Name = "", + GlobalAlias(Type *Ty, LinkageTypes Linkage, const Twine &Name = "", Constant* Aliasee = 0, Module *Parent = 0); /// Provide fast operand accessors - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); /// removeFromParent - This method unlinks 'this' from the containing module, /// but does not delete it. @@ -60,10 +59,10 @@ class GlobalAlias : public GlobalValue, public ilist_node { /// set/getAliasee - These methods retrive and set alias target. void setAliasee(Constant *GV); const Constant *getAliasee() const { - return cast_or_null(getOperand(0)); + return getOperand(0); } Constant *getAliasee() { - return cast_or_null(getOperand(0)); + return getOperand(0); } /// getAliasedGlobal() - Aliasee can be either global or bitcast of /// global. This method retrives the global for both aliasee flavours. @@ -88,7 +87,7 @@ struct OperandTraits : public FixedNumOperandTraits { }; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalAlias, Value) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalAlias, Constant) } // End llvm namespace diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index d0f0888a227a..63dc4ab6bae0 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -57,7 +57,7 @@ class GlobalValue : public Constant { }; protected: - GlobalValue(const Type *ty, ValueTy vty, Use *Ops, unsigned NumOps, + GlobalValue(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps, LinkageTypes linkage, const Twine &Name) : Constant(ty, vty, Ops, NumOps), Parent(0), Linkage(linkage), Visibility(DefaultVisibility), Alignment(0), diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h index bbc09c177e20..034ade1fb031 100644 --- a/include/llvm/GlobalVariable.h +++ b/include/llvm/GlobalVariable.h @@ -50,12 +50,12 @@ class GlobalVariable : public GlobalValue, public ilist_node { } /// GlobalVariable ctor - If a parent module is specified, the global is /// automatically inserted into the end of the specified modules global list. - GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage, + GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage, Constant *Initializer = 0, const Twine &Name = "", bool ThreadLocal = false, unsigned AddressSpace = 0); /// GlobalVariable ctor - This creates a global and inserts it before the /// specified other global. - GlobalVariable(Module &M, const Type *Ty, bool isConstant, + GlobalVariable(Module &M, Type *Ty, bool isConstant, LinkageTypes Linkage, Constant *Initializer, const Twine &Name, GlobalVariable *InsertBefore = 0, bool ThreadLocal = false, diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 4caf8f1b46a7..c91fbf8de812 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -65,7 +65,7 @@ void initializeArgPromotionPass(PassRegistry&); void initializeBasicAliasAnalysisPass(PassRegistry&); void initializeBasicCallGraphPass(PassRegistry&); void initializeBlockExtractorPassPass(PassRegistry&); -void initializeBlockFrequencyPass(PassRegistry&); +void initializeBlockFrequencyInfoPass(PassRegistry&); void initializeBlockPlacementPass(PassRegistry&); void initializeBranchProbabilityInfoPass(PassRegistry&); void initializeBreakCriticalEdgesPass(PassRegistry&); @@ -143,9 +143,8 @@ void initializeLowerAtomicPass(PassRegistry&); void initializeLowerExpectIntrinsicPass(PassRegistry&); void initializeLowerIntrinsicsPass(PassRegistry&); void initializeLowerInvokePass(PassRegistry&); -void initializeLowerSetJmpPass(PassRegistry&); void initializeLowerSwitchPass(PassRegistry&); -void initializeMachineBlockFrequencyPass(PassRegistry&); +void initializeMachineBlockFrequencyInfoPass(PassRegistry&); void initializeMachineBranchProbabilityInfoPass(PassRegistry&); void initializeMachineCSEPass(PassRegistry&); void initializeMachineDominatorTreePass(PassRegistry&); @@ -220,7 +219,6 @@ void initializeStripNonDebugSymbolsPass(PassRegistry&); void initializeStripSymbolsPass(PassRegistry&); void initializeStrongPHIEliminationPass(PassRegistry&); void initializeTailCallElimPass(PassRegistry&); -void initializeTailDupPass(PassRegistry&); void initializeTargetDataPass(PassRegistry&); void initializeTargetLibraryInfoPass(PassRegistry&); void initializeTwoAddressInstructionPassPass(PassRegistry&); diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h index a98aff178cc4..de5ce4ecafc7 100644 --- a/include/llvm/InlineAsm.h +++ b/include/llvm/InlineAsm.h @@ -43,7 +43,7 @@ class InlineAsm : public Value { bool HasSideEffects; bool IsAlignStack; - InlineAsm(const PointerType *Ty, const std::string &AsmString, + InlineAsm(PointerType *Ty, const std::string &AsmString, const std::string &Constraints, bool hasSideEffects, bool isAlignStack); virtual ~InlineAsm(); @@ -55,7 +55,7 @@ class InlineAsm : public Value { /// InlineAsm::get - Return the specified uniqued inline asm string. /// - static InlineAsm *get(const FunctionType *Ty, StringRef AsmString, + static InlineAsm *get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack = false); @@ -79,7 +79,7 @@ class InlineAsm : public Value { /// the specified constraint string is legal for the type. This returns true /// if legal, false if not. /// - static bool Verify(const FunctionType *Ty, StringRef Constraints); + static bool Verify(FunctionType *Ty, StringRef Constraints); // Constraint String Parsing enum ConstraintPrefix { @@ -219,6 +219,7 @@ class InlineAsm : public Value { static unsigned getFlagWord(unsigned Kind, unsigned NumOps) { assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!"); + assert(Kind >= Kind_RegUse && Kind <= Kind_Mem && "Invalid Kind"); return Kind | (NumOps << 3); } @@ -227,9 +228,24 @@ class InlineAsm : public Value { /// to a previous output operand. static unsigned getFlagWordForMatchingOp(unsigned InputFlag, unsigned MatchedOperandNo) { + assert(MatchedOperandNo <= 0x7fff && "Too big matched operand"); + assert((InputFlag & ~0xffff) == 0 && "High bits already contain data"); return InputFlag | Flag_MatchingOperand | (MatchedOperandNo << 16); } + /// getFlagWordForRegClass - Augment an existing flag word returned by + /// getFlagWord with the required register class for the following register + /// operands. + /// A tied use operand cannot have a register class, use the register class + /// from the def operand instead. + static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC) { + // Store RC + 1, reserve the value 0 to mean 'no register class'. + ++RC; + assert(RC <= 0x7fff && "Too large register class ID"); + assert((InputFlag & ~0xffff) == 0 && "High bits already contain data"); + return InputFlag | (RC << 16); + } + static unsigned getKind(unsigned Flags) { return Flags & 7; } @@ -259,6 +275,19 @@ class InlineAsm : public Value { return true; } + /// hasRegClassConstraint - Returns true if the flag contains a register + /// class constraint. Sets RC to the register class ID. + static bool hasRegClassConstraint(unsigned Flag, unsigned &RC) { + if (Flag & Flag_MatchingOperand) + return false; + unsigned High = Flag >> 16; + // getFlagWordForRegClass() uses 0 to mean no register class, and otherwise + // stores RC + 1. + if (!High) + return false; + RC = High - 1; + return true; + } }; diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h index cc9ec3ac76e1..a1492f3c141a 100644 --- a/include/llvm/InstrTypes.h +++ b/include/llvm/InstrTypes.h @@ -34,12 +34,12 @@ class LLVMContext; /// class TerminatorInst : public Instruction { protected: - TerminatorInst(const Type *Ty, Instruction::TermOps iType, + TerminatorInst(Type *Ty, Instruction::TermOps iType, Use *Ops, unsigned NumOps, Instruction *InsertBefore = 0) : Instruction(Ty, iType, Ops, NumOps, InsertBefore) {} - TerminatorInst(const Type *Ty, Instruction::TermOps iType, + TerminatorInst(Type *Ty, Instruction::TermOps iType, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd) : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {} @@ -91,12 +91,12 @@ class UnaryInstruction : public Instruction { void *operator new(size_t, unsigned); // Do not implement protected: - UnaryInstruction(const Type *Ty, unsigned iType, Value *V, + UnaryInstruction(Type *Ty, unsigned iType, Value *V, Instruction *IB = 0) : Instruction(Ty, iType, &Op<0>(), 1, IB) { Op<0>() = V; } - UnaryInstruction(const Type *Ty, unsigned iType, Value *V, BasicBlock *IAE) + UnaryInstruction(Type *Ty, unsigned iType, Value *V, BasicBlock *IAE) : Instruction(Ty, iType, &Op<0>(), 1, IAE) { Op<0>() = V; } @@ -141,9 +141,9 @@ class BinaryOperator : public Instruction { void *operator new(size_t, unsigned); // Do not implement protected: void init(BinaryOps iType); - BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, + BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, const Twine &Name, Instruction *InsertBefore); - BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty, + BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd); virtual BinaryOperator *clone_impl() const; public: @@ -390,13 +390,13 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value) class CastInst : public UnaryInstruction { protected: /// @brief Constructor with insert-before-instruction semantics for subclasses - CastInst(const Type *Ty, unsigned iType, Value *S, + CastInst(Type *Ty, unsigned iType, Value *S, const Twine &NameStr = "", Instruction *InsertBefore = 0) : UnaryInstruction(Ty, iType, S, InsertBefore) { setName(NameStr); } /// @brief Constructor with insert-at-end-of-block semantics for subclasses - CastInst(const Type *Ty, unsigned iType, Value *S, + CastInst(Type *Ty, unsigned iType, Value *S, const Twine &NameStr, BasicBlock *InsertAtEnd) : UnaryInstruction(Ty, iType, S, InsertAtEnd) { setName(NameStr); @@ -411,7 +411,7 @@ class CastInst : public UnaryInstruction { static CastInst *Create( Instruction::CastOps, ///< The opcode of the cast instruction Value *S, ///< The value to be casted (operand 0) - const Type *Ty, ///< The type to which cast should be made + Type *Ty, ///< The type to which cast should be made const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); @@ -424,7 +424,7 @@ class CastInst : public UnaryInstruction { static CastInst *Create( Instruction::CastOps, ///< The opcode for the cast instruction Value *S, ///< The value to be casted (operand 0) - const Type *Ty, ///< The type to which operand is casted + Type *Ty, ///< The type to which operand is casted const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -432,7 +432,7 @@ class CastInst : public UnaryInstruction { /// @brief Create a ZExt or BitCast cast instruction static CastInst *CreateZExtOrBitCast( Value *S, ///< The value to be casted (operand 0) - const Type *Ty, ///< The type to which cast should be made + Type *Ty, ///< The type to which cast should be made const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); @@ -440,7 +440,7 @@ class CastInst : public UnaryInstruction { /// @brief Create a ZExt or BitCast cast instruction static CastInst *CreateZExtOrBitCast( Value *S, ///< The value to be casted (operand 0) - const Type *Ty, ///< The type to which operand is casted + Type *Ty, ///< The type to which operand is casted const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -448,7 +448,7 @@ class CastInst : public UnaryInstruction { /// @brief Create a SExt or BitCast cast instruction static CastInst *CreateSExtOrBitCast( Value *S, ///< The value to be casted (operand 0) - const Type *Ty, ///< The type to which cast should be made + Type *Ty, ///< The type to which cast should be made const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); @@ -456,7 +456,7 @@ class CastInst : public UnaryInstruction { /// @brief Create a SExt or BitCast cast instruction static CastInst *CreateSExtOrBitCast( Value *S, ///< The value to be casted (operand 0) - const Type *Ty, ///< The type to which operand is casted + Type *Ty, ///< The type to which operand is casted const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -464,7 +464,7 @@ class CastInst : public UnaryInstruction { /// @brief Create a BitCast or a PtrToInt cast instruction static CastInst *CreatePointerCast( Value *S, ///< The pointer value to be casted (operand 0) - const Type *Ty, ///< The type to which operand is casted + Type *Ty, ///< The type to which operand is casted const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -472,7 +472,7 @@ class CastInst : public UnaryInstruction { /// @brief Create a BitCast or a PtrToInt cast instruction static CastInst *CreatePointerCast( Value *S, ///< The pointer value to be casted (operand 0) - const Type *Ty, ///< The type to which cast should be made + Type *Ty, ///< The type to which cast should be made const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); @@ -480,7 +480,7 @@ class CastInst : public UnaryInstruction { /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts. static CastInst *CreateIntegerCast( Value *S, ///< The pointer value to be casted (operand 0) - const Type *Ty, ///< The type to which cast should be made + Type *Ty, ///< The type to which cast should be made bool isSigned, ///< Whether to regard S as signed or not const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction @@ -489,7 +489,7 @@ class CastInst : public UnaryInstruction { /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts. static CastInst *CreateIntegerCast( Value *S, ///< The integer value to be casted (operand 0) - const Type *Ty, ///< The integer type to which operand is casted + Type *Ty, ///< The integer type to which operand is casted bool isSigned, ///< Whether to regard S as signed or not const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into @@ -498,7 +498,7 @@ class CastInst : public UnaryInstruction { /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts static CastInst *CreateFPCast( Value *S, ///< The floating point value to be casted - const Type *Ty, ///< The floating point type to cast to + Type *Ty, ///< The floating point type to cast to const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); @@ -506,7 +506,7 @@ class CastInst : public UnaryInstruction { /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts static CastInst *CreateFPCast( Value *S, ///< The floating point value to be casted - const Type *Ty, ///< The floating point type to cast to + Type *Ty, ///< The floating point type to cast to const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -514,7 +514,7 @@ class CastInst : public UnaryInstruction { /// @brief Create a Trunc or BitCast cast instruction static CastInst *CreateTruncOrBitCast( Value *S, ///< The value to be casted (operand 0) - const Type *Ty, ///< The type to which cast should be made + Type *Ty, ///< The type to which cast should be made const Twine &Name = "", ///< Name for the instruction Instruction *InsertBefore = 0 ///< Place to insert the instruction ); @@ -522,15 +522,15 @@ class CastInst : public UnaryInstruction { /// @brief Create a Trunc or BitCast cast instruction static CastInst *CreateTruncOrBitCast( Value *S, ///< The value to be casted (operand 0) - const Type *Ty, ///< The type to which operand is casted + Type *Ty, ///< The type to which operand is casted const Twine &Name, ///< The name for the instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); /// @brief Check whether it is valid to call getCastOpcode for these types. static bool isCastable( - const Type *SrcTy, ///< The Type from which the value should be cast. - const Type *DestTy ///< The Type to which the value should be cast. + Type *SrcTy, ///< The Type from which the value should be cast. + Type *DestTy ///< The Type to which the value should be cast. ); /// Returns the opcode necessary to cast Val into Ty using usual casting @@ -539,7 +539,7 @@ class CastInst : public UnaryInstruction { static Instruction::CastOps getCastOpcode( const Value *Val, ///< The value to cast bool SrcIsSigned, ///< Whether to treat the source as signed - const Type *Ty, ///< The Type to which the value should be casted + Type *Ty, ///< The Type to which the value should be casted bool DstIsSigned ///< Whether to treate the dest. as signed ); @@ -568,14 +568,14 @@ class CastInst : public UnaryInstruction { /// @brief Determine if the described cast is a no-op cast. static bool isNoopCast( Instruction::CastOps Opcode, ///< Opcode of cast - const Type *SrcTy, ///< SrcTy of cast - const Type *DstTy, ///< DstTy of cast - const Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null + Type *SrcTy, ///< SrcTy of cast + Type *DstTy, ///< DstTy of cast + Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null ); /// @brief Determine if this cast is a no-op cast. bool isNoopCast( - const Type *IntPtrTy ///< Integer type corresponding to pointer + Type *IntPtrTy ///< Integer type corresponding to pointer ) const; /// Determine how a pair of casts can be eliminated, if they can be at all. @@ -587,10 +587,10 @@ class CastInst : public UnaryInstruction { static unsigned isEliminableCastPair( Instruction::CastOps firstOpcode, ///< Opcode of first cast Instruction::CastOps secondOpcode, ///< Opcode of second cast - const Type *SrcTy, ///< SrcTy of 1st cast - const Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast - const Type *DstTy, ///< DstTy of 2nd cast - const Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null + Type *SrcTy, ///< SrcTy of 1st cast + Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast + Type *DstTy, ///< DstTy of 2nd cast + Type *IntPtrTy ///< Integer type corresponding to Ptr types, or null ); /// @brief Return the opcode of this CastInst @@ -599,15 +599,15 @@ class CastInst : public UnaryInstruction { } /// @brief Return the source type, as a convenience - const Type* getSrcTy() const { return getOperand(0)->getType(); } + Type* getSrcTy() const { return getOperand(0)->getType(); } /// @brief Return the destination type, as a convenience - const Type* getDestTy() const { return getType(); } + Type* getDestTy() const { return getType(); } /// This method can be used to determine if a cast from S to DstTy using /// Opcode op is valid or not. /// @returns true iff the proposed cast is valid. /// @brief Determine if a cast is valid without creating one. - static bool castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy); + static bool castIsValid(Instruction::CastOps op, Value *S, Type *DstTy); /// @brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const CastInst *) { return true; } @@ -629,11 +629,11 @@ class CmpInst : public Instruction { void *operator new(size_t, unsigned); // DO NOT IMPLEMENT CmpInst(); // do not implement protected: - CmpInst(const Type *ty, Instruction::OtherOps op, unsigned short pred, + CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS, const Twine &Name = "", Instruction *InsertBefore = 0); - CmpInst(const Type *ty, Instruction::OtherOps op, unsigned short pred, + CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS, const Twine &Name, BasicBlock *InsertAtEnd); @@ -825,8 +825,8 @@ class CmpInst : public Instruction { } /// @brief Create a result type for fcmp/icmp - static const Type* makeCmpResultType(const Type* opnd_type) { - if (const VectorType* vt = dyn_cast(opnd_type)) { + static Type* makeCmpResultType(Type* opnd_type) { + if (VectorType* vt = dyn_cast(opnd_type)) { return VectorType::get(Type::getInt1Ty(opnd_type->getContext()), vt->getNumElements()); } diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def index 205f30313e76..d36e4be1d912 100644 --- a/include/llvm/Instruction.def +++ b/include/llvm/Instruction.def @@ -100,76 +100,80 @@ HANDLE_TERM_INST ( 3, Switch , SwitchInst) HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst) HANDLE_TERM_INST ( 5, Invoke , InvokeInst) HANDLE_TERM_INST ( 6, Unwind , UnwindInst) -HANDLE_TERM_INST ( 7, Unreachable, UnreachableInst) - LAST_TERM_INST ( 7) +HANDLE_TERM_INST ( 7, Resume , ResumeInst) +HANDLE_TERM_INST ( 8, Unreachable, UnreachableInst) + LAST_TERM_INST ( 8) // Standard binary operators... - FIRST_BINARY_INST( 8) -HANDLE_BINARY_INST( 8, Add , BinaryOperator) -HANDLE_BINARY_INST( 9, FAdd , BinaryOperator) -HANDLE_BINARY_INST(10, Sub , BinaryOperator) -HANDLE_BINARY_INST(11, FSub , BinaryOperator) -HANDLE_BINARY_INST(12, Mul , BinaryOperator) -HANDLE_BINARY_INST(13, FMul , BinaryOperator) -HANDLE_BINARY_INST(14, UDiv , BinaryOperator) -HANDLE_BINARY_INST(15, SDiv , BinaryOperator) -HANDLE_BINARY_INST(16, FDiv , BinaryOperator) -HANDLE_BINARY_INST(17, URem , BinaryOperator) -HANDLE_BINARY_INST(18, SRem , BinaryOperator) -HANDLE_BINARY_INST(19, FRem , BinaryOperator) + FIRST_BINARY_INST( 9) +HANDLE_BINARY_INST( 9, Add , BinaryOperator) +HANDLE_BINARY_INST(10, FAdd , BinaryOperator) +HANDLE_BINARY_INST(11, Sub , BinaryOperator) +HANDLE_BINARY_INST(12, FSub , BinaryOperator) +HANDLE_BINARY_INST(13, Mul , BinaryOperator) +HANDLE_BINARY_INST(14, FMul , BinaryOperator) +HANDLE_BINARY_INST(15, UDiv , BinaryOperator) +HANDLE_BINARY_INST(16, SDiv , BinaryOperator) +HANDLE_BINARY_INST(17, FDiv , BinaryOperator) +HANDLE_BINARY_INST(18, URem , BinaryOperator) +HANDLE_BINARY_INST(19, SRem , BinaryOperator) +HANDLE_BINARY_INST(20, FRem , BinaryOperator) // Logical operators (integer operands) -HANDLE_BINARY_INST(20, Shl , BinaryOperator) // Shift left (logical) -HANDLE_BINARY_INST(21, LShr , BinaryOperator) // Shift right (logical) -HANDLE_BINARY_INST(22, AShr , BinaryOperator) // Shift right (arithmetic) -HANDLE_BINARY_INST(23, And , BinaryOperator) -HANDLE_BINARY_INST(24, Or , BinaryOperator) -HANDLE_BINARY_INST(25, Xor , BinaryOperator) - LAST_BINARY_INST(25) +HANDLE_BINARY_INST(21, Shl , BinaryOperator) // Shift left (logical) +HANDLE_BINARY_INST(22, LShr , BinaryOperator) // Shift right (logical) +HANDLE_BINARY_INST(23, AShr , BinaryOperator) // Shift right (arithmetic) +HANDLE_BINARY_INST(24, And , BinaryOperator) +HANDLE_BINARY_INST(25, Or , BinaryOperator) +HANDLE_BINARY_INST(26, Xor , BinaryOperator) + LAST_BINARY_INST(26) // Memory operators... - FIRST_MEMORY_INST(26) -HANDLE_MEMORY_INST(26, Alloca, AllocaInst) // Stack management -HANDLE_MEMORY_INST(27, Load , LoadInst ) // Memory manipulation instrs -HANDLE_MEMORY_INST(28, Store , StoreInst ) -HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst) - LAST_MEMORY_INST(29) + FIRST_MEMORY_INST(27) +HANDLE_MEMORY_INST(27, Alloca, AllocaInst) // Stack management +HANDLE_MEMORY_INST(28, Load , LoadInst ) // Memory manipulation instrs +HANDLE_MEMORY_INST(29, Store , StoreInst ) +HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst) +HANDLE_MEMORY_INST(31, Fence , FenceInst ) +HANDLE_MEMORY_INST(32, AtomicCmpXchg , AtomicCmpXchgInst ) +HANDLE_MEMORY_INST(33, AtomicRMW , AtomicRMWInst ) + LAST_MEMORY_INST(33) // Cast operators ... // NOTE: The order matters here because CastInst::isEliminableCastPair // NOTE: (see Instructions.cpp) encodes a table based on this ordering. - FIRST_CAST_INST(30) -HANDLE_CAST_INST(30, Trunc , TruncInst ) // Truncate integers -HANDLE_CAST_INST(31, ZExt , ZExtInst ) // Zero extend integers -HANDLE_CAST_INST(32, SExt , SExtInst ) // Sign extend integers -HANDLE_CAST_INST(33, FPToUI , FPToUIInst ) // floating point -> UInt -HANDLE_CAST_INST(34, FPToSI , FPToSIInst ) // floating point -> SInt -HANDLE_CAST_INST(35, UIToFP , UIToFPInst ) // UInt -> floating point -HANDLE_CAST_INST(36, SIToFP , SIToFPInst ) // SInt -> floating point -HANDLE_CAST_INST(37, FPTrunc , FPTruncInst ) // Truncate floating point -HANDLE_CAST_INST(38, FPExt , FPExtInst ) // Extend floating point -HANDLE_CAST_INST(39, PtrToInt, PtrToIntInst) // Pointer -> Integer -HANDLE_CAST_INST(40, IntToPtr, IntToPtrInst) // Integer -> Pointer -HANDLE_CAST_INST(41, BitCast , BitCastInst ) // Type cast - LAST_CAST_INST(41) + FIRST_CAST_INST(34) +HANDLE_CAST_INST(34, Trunc , TruncInst ) // Truncate integers +HANDLE_CAST_INST(35, ZExt , ZExtInst ) // Zero extend integers +HANDLE_CAST_INST(36, SExt , SExtInst ) // Sign extend integers +HANDLE_CAST_INST(37, FPToUI , FPToUIInst ) // floating point -> UInt +HANDLE_CAST_INST(38, FPToSI , FPToSIInst ) // floating point -> SInt +HANDLE_CAST_INST(39, UIToFP , UIToFPInst ) // UInt -> floating point +HANDLE_CAST_INST(40, SIToFP , SIToFPInst ) // SInt -> floating point +HANDLE_CAST_INST(41, FPTrunc , FPTruncInst ) // Truncate floating point +HANDLE_CAST_INST(42, FPExt , FPExtInst ) // Extend floating point +HANDLE_CAST_INST(43, PtrToInt, PtrToIntInst) // Pointer -> Integer +HANDLE_CAST_INST(44, IntToPtr, IntToPtrInst) // Integer -> Pointer +HANDLE_CAST_INST(45, BitCast , BitCastInst ) // Type cast + LAST_CAST_INST(45) // Other operators... - FIRST_OTHER_INST(42) -HANDLE_OTHER_INST(42, ICmp , ICmpInst ) // Integer comparison instruction -HANDLE_OTHER_INST(43, FCmp , FCmpInst ) // Floating point comparison instr. -HANDLE_OTHER_INST(44, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(45, Call , CallInst ) // Call a function -HANDLE_OTHER_INST(46, Select , SelectInst ) // select instruction -HANDLE_OTHER_INST(47, UserOp1, Instruction) // May be used internally in a pass -HANDLE_OTHER_INST(48, UserOp2, Instruction) // Internal to passes only -HANDLE_OTHER_INST(49, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(50, ExtractElement, ExtractElementInst)// extract from vector -HANDLE_OTHER_INST(51, InsertElement, InsertElementInst) // insert into vector -HANDLE_OTHER_INST(52, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. -HANDLE_OTHER_INST(53, ExtractValue, ExtractValueInst)// extract from aggregate -HANDLE_OTHER_INST(54, InsertValue, InsertValueInst) // insert into aggregate - - LAST_OTHER_INST(54) + FIRST_OTHER_INST(46) +HANDLE_OTHER_INST(46, ICmp , ICmpInst ) // Integer comparison instruction +HANDLE_OTHER_INST(47, FCmp , FCmpInst ) // Floating point comparison instr. +HANDLE_OTHER_INST(48, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(49, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(50, Select , SelectInst ) // select instruction +HANDLE_OTHER_INST(51, UserOp1, Instruction) // May be used internally in a pass +HANDLE_OTHER_INST(52, UserOp2, Instruction) // Internal to passes only +HANDLE_OTHER_INST(53, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(54, ExtractElement, ExtractElementInst)// extract from vector +HANDLE_OTHER_INST(55, InsertElement, InsertElementInst) // insert into vector +HANDLE_OTHER_INST(56, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. +HANDLE_OTHER_INST(57, ExtractValue, ExtractValueInst)// extract from aggregate +HANDLE_OTHER_INST(58, InsertValue, InsertValueInst) // insert into aggregate +HANDLE_OTHER_INST(59, LandingPad, LandingPadInst) // Landing pad instruction. + LAST_OTHER_INST(59) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h index 89bb9fdf423d..934e890151f0 100644 --- a/include/llvm/Instruction.h +++ b/include/llvm/Instruction.h @@ -223,6 +223,13 @@ class Instruction : public User, public ilist_node { /// bool mayReadFromMemory() const; + /// mayReadOrWriteMemory - Return true if this instruction may read or + /// write memory. + /// + bool mayReadOrWriteMemory() const { + return mayReadFromMemory() || mayWriteToMemory(); + } + /// mayThrow - Return true if this instruction may throw an exception. /// bool mayThrow() const; @@ -365,9 +372,9 @@ class Instruction : public User, public ilist_node { return getSubclassDataFromValue() & ~HasMetadataBit; } - Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, + Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, Instruction *InsertBefore = 0); - Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, + Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd); virtual Instruction *clone_impl() const = 0; diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 0bc9a3b6436e..3faab35bf687 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -22,6 +22,7 @@ #include "llvm/CallingConv.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/ErrorHandling.h" #include namespace llvm { @@ -31,6 +32,22 @@ class ConstantRange; class APInt; class LLVMContext; +enum AtomicOrdering { + NotAtomic = 0, + Unordered = 1, + Monotonic = 2, + // Consume = 3, // Not specified yet. + Acquire = 4, + Release = 5, + AcquireRelease = 6, + SequentiallyConsistent = 7 +}; + +enum SynchronizationScope { + SingleThread = 0, + CrossThread = 1 +}; + //===----------------------------------------------------------------------===// // AllocaInst Class //===----------------------------------------------------------------------===// @@ -41,17 +58,17 @@ class AllocaInst : public UnaryInstruction { protected: virtual AllocaInst *clone_impl() const; public: - explicit AllocaInst(const Type *Ty, Value *ArraySize = 0, + explicit AllocaInst(Type *Ty, Value *ArraySize = 0, const Twine &Name = "", Instruction *InsertBefore = 0); - AllocaInst(const Type *Ty, Value *ArraySize, + AllocaInst(Type *Ty, Value *ArraySize, const Twine &Name, BasicBlock *InsertAtEnd); - AllocaInst(const Type *Ty, const Twine &Name, Instruction *InsertBefore = 0); - AllocaInst(const Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd); + AllocaInst(Type *Ty, const Twine &Name, Instruction *InsertBefore = 0); + AllocaInst(Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd); - AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align, + AllocaInst(Type *Ty, Value *ArraySize, unsigned Align, const Twine &Name = "", Instruction *InsertBefore = 0); - AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align, + AllocaInst(Type *Ty, Value *ArraySize, unsigned Align, const Twine &Name, BasicBlock *InsertAtEnd); // Out of line virtual method, so the vtable, etc. has a home. @@ -70,8 +87,8 @@ class AllocaInst : public UnaryInstruction { /// getType - Overload to return most specific pointer type /// - const PointerType *getType() const { - return reinterpret_cast(Instruction::getType()); + PointerType *getType() const { + return reinterpret_cast(Instruction::getType()); } /// getAllocatedType - Return the type that is being allocated by the @@ -125,12 +142,20 @@ class LoadInst : public UnaryInstruction { LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd); LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile = false, Instruction *InsertBefore = 0); - LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, - unsigned Align, Instruction *InsertBefore = 0); LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, BasicBlock *InsertAtEnd); + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, + unsigned Align, Instruction *InsertBefore = 0); LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, unsigned Align, BasicBlock *InsertAtEnd); + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, + unsigned Align, AtomicOrdering Order, + SynchronizationScope SynchScope = CrossThread, + Instruction *InsertBefore = 0); + LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, + unsigned Align, AtomicOrdering Order, + SynchronizationScope SynchScope, + BasicBlock *InsertAtEnd); LoadInst(Value *Ptr, const char *NameStr, Instruction *InsertBefore); LoadInst(Value *Ptr, const char *NameStr, BasicBlock *InsertAtEnd); @@ -154,11 +179,47 @@ class LoadInst : public UnaryInstruction { /// getAlignment - Return the alignment of the access that is being performed /// unsigned getAlignment() const { - return (1 << (getSubclassDataFromInstruction() >> 1)) >> 1; + return (1 << ((getSubclassDataFromInstruction() >> 1) & 31)) >> 1; } void setAlignment(unsigned Align); + /// Returns the ordering effect of this fence. + AtomicOrdering getOrdering() const { + return AtomicOrdering((getSubclassDataFromInstruction() >> 7) & 7); + } + + /// Set the ordering constraint on this load. May not be Release or + /// AcquireRelease. + void setOrdering(AtomicOrdering Ordering) { + setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 7)) | + (Ordering << 7)); + } + + SynchronizationScope getSynchScope() const { + return SynchronizationScope((getSubclassDataFromInstruction() >> 6) & 1); + } + + /// Specify whether this load is ordered with respect to all + /// concurrently executing threads, or only with respect to signal handlers + /// executing in the same thread. + void setSynchScope(SynchronizationScope xthread) { + setInstructionSubclassData((getSubclassDataFromInstruction() & ~(1 << 6)) | + (xthread << 6)); + } + + bool isAtomic() const { return getOrdering() != NotAtomic; } + void setAtomic(AtomicOrdering Ordering, + SynchronizationScope SynchScope = CrossThread) { + setOrdering(Ordering); + setSynchScope(SynchScope); + } + + bool isSimple() const { return !isAtomic() && !isVolatile(); } + bool isUnordered() const { + return getOrdering() <= Unordered && !isVolatile(); + } + Value *getPointerOperand() { return getOperand(0); } const Value *getPointerOperand() const { return getOperand(0); } static unsigned getPointerOperandIndex() { return 0U; } @@ -205,19 +266,27 @@ class StoreInst : public Instruction { StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd); StoreInst(Value *Val, Value *Ptr, bool isVolatile = false, Instruction *InsertBefore = 0); - StoreInst(Value *Val, Value *Ptr, bool isVolatile, - unsigned Align, Instruction *InsertBefore = 0); StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd); + StoreInst(Value *Val, Value *Ptr, bool isVolatile, + unsigned Align, Instruction *InsertBefore = 0); StoreInst(Value *Val, Value *Ptr, bool isVolatile, unsigned Align, BasicBlock *InsertAtEnd); + StoreInst(Value *Val, Value *Ptr, bool isVolatile, + unsigned Align, AtomicOrdering Order, + SynchronizationScope SynchScope = CrossThread, + Instruction *InsertBefore = 0); + StoreInst(Value *Val, Value *Ptr, bool isVolatile, + unsigned Align, AtomicOrdering Order, + SynchronizationScope SynchScope, + BasicBlock *InsertAtEnd); + - - /// isVolatile - Return true if this is a load from a volatile memory + /// isVolatile - Return true if this is a store to a volatile memory /// location. /// bool isVolatile() const { return getSubclassDataFromInstruction() & 1; } - /// setVolatile - Specify whether this is a volatile load or not. + /// setVolatile - Specify whether this is a volatile store or not. /// void setVolatile(bool V) { setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | @@ -230,11 +299,47 @@ class StoreInst : public Instruction { /// getAlignment - Return the alignment of the access that is being performed /// unsigned getAlignment() const { - return (1 << (getSubclassDataFromInstruction() >> 1)) >> 1; + return (1 << ((getSubclassDataFromInstruction() >> 1) & 31)) >> 1; } void setAlignment(unsigned Align); + /// Returns the ordering effect of this store. + AtomicOrdering getOrdering() const { + return AtomicOrdering((getSubclassDataFromInstruction() >> 7) & 7); + } + + /// Set the ordering constraint on this store. May not be Acquire or + /// AcquireRelease. + void setOrdering(AtomicOrdering Ordering) { + setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 7)) | + (Ordering << 7)); + } + + SynchronizationScope getSynchScope() const { + return SynchronizationScope((getSubclassDataFromInstruction() >> 6) & 1); + } + + /// Specify whether this store instruction is ordered with respect to all + /// concurrently executing threads, or only with respect to signal handlers + /// executing in the same thread. + void setSynchScope(SynchronizationScope xthread) { + setInstructionSubclassData((getSubclassDataFromInstruction() & ~(1 << 6)) | + (xthread << 6)); + } + + bool isAtomic() const { return getOrdering() != NotAtomic; } + void setAtomic(AtomicOrdering Ordering, + SynchronizationScope SynchScope = CrossThread) { + setOrdering(Ordering); + setSynchScope(SynchScope); + } + + bool isSimple() const { return !isAtomic() && !isVolatile(); } + bool isUnordered() const { + return getOrdering() <= Unordered && !isVolatile(); + } + Value *getValueOperand() { return getOperand(0); } const Value *getValueOperand() const { return getOperand(0); } @@ -268,6 +373,325 @@ struct OperandTraits : public FixedNumOperandTraits { DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value) +//===----------------------------------------------------------------------===// +// FenceInst Class +//===----------------------------------------------------------------------===// + +/// FenceInst - an instruction for ordering other memory operations +/// +class FenceInst : public Instruction { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void Init(AtomicOrdering Ordering, SynchronizationScope SynchScope); +protected: + virtual FenceInst *clone_impl() const; +public: + // allocate space for exactly zero operands + void *operator new(size_t s) { + return User::operator new(s, 0); + } + + // Ordering may only be Acquire, Release, AcquireRelease, or + // SequentiallyConsistent. + FenceInst(LLVMContext &C, AtomicOrdering Ordering, + SynchronizationScope SynchScope = CrossThread, + Instruction *InsertBefore = 0); + FenceInst(LLVMContext &C, AtomicOrdering Ordering, + SynchronizationScope SynchScope, + BasicBlock *InsertAtEnd); + + /// Returns the ordering effect of this fence. + AtomicOrdering getOrdering() const { + return AtomicOrdering(getSubclassDataFromInstruction() >> 1); + } + + /// Set the ordering constraint on this fence. May only be Acquire, Release, + /// AcquireRelease, or SequentiallyConsistent. + void setOrdering(AtomicOrdering Ordering) { + setInstructionSubclassData((getSubclassDataFromInstruction() & 1) | + (Ordering << 1)); + } + + SynchronizationScope getSynchScope() const { + return SynchronizationScope(getSubclassDataFromInstruction() & 1); + } + + /// Specify whether this fence orders other operations with respect to all + /// concurrently executing threads, or only with respect to signal handlers + /// executing in the same thread. + void setSynchScope(SynchronizationScope xthread) { + setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | + xthread); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const FenceInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::Fence; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +private: + // Shadow Instruction::setInstructionSubclassData with a private forwarding + // method so that subclasses cannot accidentally use it. + void setInstructionSubclassData(unsigned short D) { + Instruction::setInstructionSubclassData(D); + } +}; + +//===----------------------------------------------------------------------===// +// AtomicCmpXchgInst Class +//===----------------------------------------------------------------------===// + +/// AtomicCmpXchgInst - an instruction that atomically checks whether a +/// specified value is in a memory location, and, if it is, stores a new value +/// there. Returns the value that was loaded. +/// +class AtomicCmpXchgInst : public Instruction { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + void Init(Value *Ptr, Value *Cmp, Value *NewVal, + AtomicOrdering Ordering, SynchronizationScope SynchScope); +protected: + virtual AtomicCmpXchgInst *clone_impl() const; +public: + // allocate space for exactly three operands + void *operator new(size_t s) { + return User::operator new(s, 3); + } + AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal, + AtomicOrdering Ordering, SynchronizationScope SynchScope, + Instruction *InsertBefore = 0); + AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal, + AtomicOrdering Ordering, SynchronizationScope SynchScope, + BasicBlock *InsertAtEnd); + + /// isVolatile - Return true if this is a cmpxchg from a volatile memory + /// location. + /// + bool isVolatile() const { + return getSubclassDataFromInstruction() & 1; + } + + /// setVolatile - Specify whether this is a volatile cmpxchg. + /// + void setVolatile(bool V) { + setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | + (unsigned)V); + } + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + /// Set the ordering constraint on this cmpxchg. + void setOrdering(AtomicOrdering Ordering) { + assert(Ordering != NotAtomic && + "CmpXchg instructions can only be atomic."); + setInstructionSubclassData((getSubclassDataFromInstruction() & 3) | + (Ordering << 2)); + } + + /// Specify whether this cmpxchg is atomic and orders other operations with + /// respect to all concurrently executing threads, or only with respect to + /// signal handlers executing in the same thread. + void setSynchScope(SynchronizationScope SynchScope) { + setInstructionSubclassData((getSubclassDataFromInstruction() & ~2) | + (SynchScope << 1)); + } + + /// Returns the ordering constraint on this cmpxchg. + AtomicOrdering getOrdering() const { + return AtomicOrdering(getSubclassDataFromInstruction() >> 2); + } + + /// Returns whether this cmpxchg is atomic between threads or only within a + /// single thread. + SynchronizationScope getSynchScope() const { + return SynchronizationScope((getSubclassDataFromInstruction() & 2) >> 1); + } + + Value *getPointerOperand() { return getOperand(0); } + const Value *getPointerOperand() const { return getOperand(0); } + static unsigned getPointerOperandIndex() { return 0U; } + + Value *getCompareOperand() { return getOperand(1); } + const Value *getCompareOperand() const { return getOperand(1); } + + Value *getNewValOperand() { return getOperand(2); } + const Value *getNewValOperand() const { return getOperand(2); } + + unsigned getPointerAddressSpace() const { + return cast(getPointerOperand()->getType())->getAddressSpace(); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const AtomicCmpXchgInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::AtomicCmpXchg; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +private: + // Shadow Instruction::setInstructionSubclassData with a private forwarding + // method so that subclasses cannot accidentally use it. + void setInstructionSubclassData(unsigned short D) { + Instruction::setInstructionSubclassData(D); + } +}; + +template <> +struct OperandTraits : + public FixedNumOperandTraits { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicCmpXchgInst, Value) + +//===----------------------------------------------------------------------===// +// AtomicRMWInst Class +//===----------------------------------------------------------------------===// + +/// AtomicRMWInst - an instruction that atomically reads a memory location, +/// combines it with another value, and then stores the result back. Returns +/// the old value. +/// +class AtomicRMWInst : public Instruction { + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT +protected: + virtual AtomicRMWInst *clone_impl() const; +public: + /// This enumeration lists the possible modifications atomicrmw can make. In + /// the descriptions, 'p' is the pointer to the instruction's memory location, + /// 'old' is the initial value of *p, and 'v' is the other value passed to the + /// instruction. These instructions always return 'old'. + enum BinOp { + /// *p = v + Xchg, + /// *p = old + v + Add, + /// *p = old - v + Sub, + /// *p = old & v + And, + /// *p = ~old & v + Nand, + /// *p = old | v + Or, + /// *p = old ^ v + Xor, + /// *p = old >signed v ? old : v + Max, + /// *p = old unsigned v ? old : v + UMax, + /// *p = old (getSubclassDataFromInstruction() >> 5); + } + + void setOperation(BinOp Operation) { + unsigned short SubclassData = getSubclassDataFromInstruction(); + setInstructionSubclassData((SubclassData & 31) | + (Operation << 5)); + } + + /// isVolatile - Return true if this is a RMW on a volatile memory location. + /// + bool isVolatile() const { + return getSubclassDataFromInstruction() & 1; + } + + /// setVolatile - Specify whether this is a volatile RMW or not. + /// + void setVolatile(bool V) { + setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | + (unsigned)V); + } + + /// Transparently provide more efficient getOperand methods. + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + /// Set the ordering constraint on this RMW. + void setOrdering(AtomicOrdering Ordering) { + assert(Ordering != NotAtomic && + "atomicrmw instructions can only be atomic."); + setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 2)) | + (Ordering << 2)); + } + + /// Specify whether this RMW orders other operations with respect to all + /// concurrently executing threads, or only with respect to signal handlers + /// executing in the same thread. + void setSynchScope(SynchronizationScope SynchScope) { + setInstructionSubclassData((getSubclassDataFromInstruction() & ~2) | + (SynchScope << 1)); + } + + /// Returns the ordering constraint on this RMW. + AtomicOrdering getOrdering() const { + return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7); + } + + /// Returns whether this RMW is atomic between threads or only within a + /// single thread. + SynchronizationScope getSynchScope() const { + return SynchronizationScope((getSubclassDataFromInstruction() & 2) >> 1); + } + + Value *getPointerOperand() { return getOperand(0); } + const Value *getPointerOperand() const { return getOperand(0); } + static unsigned getPointerOperandIndex() { return 0U; } + + Value *getValOperand() { return getOperand(1); } + const Value *getValOperand() const { return getOperand(1); } + + unsigned getPointerAddressSpace() const { + return cast(getPointerOperand()->getType())->getAddressSpace(); + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const AtomicRMWInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::AtomicRMW; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +private: + void Init(BinOp Operation, Value *Ptr, Value *Val, + AtomicOrdering Ordering, SynchronizationScope SynchScope); + // Shadow Instruction::setInstructionSubclassData with a private forwarding + // method so that subclasses cannot accidentally use it. + void setInstructionSubclassData(unsigned short D) { + Instruction::setInstructionSubclassData(D); + } +}; + +template <> +struct OperandTraits + : public FixedNumOperandTraits { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicRMWInst, Value) + //===----------------------------------------------------------------------===// // GetElementPtrInst Class //===----------------------------------------------------------------------===// @@ -275,7 +699,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value) // checkGEPType - Simple wrapper function to give a better assertion failure // message on bad indexes for a gep instruction. // -static inline const Type *checkGEPType(const Type *Ty) { +static inline Type *checkGEPType(Type *Ty) { assert(Ty && "Invalid GetElementPtrInst indices for type!"); return Ty; } @@ -285,149 +709,51 @@ static inline const Type *checkGEPType(const Type *Ty) { /// class GetElementPtrInst : public Instruction { GetElementPtrInst(const GetElementPtrInst &GEPI); - void init(Value *Ptr, Value* const *Idx, unsigned NumIdx, - const Twine &NameStr); - void init(Value *Ptr, Value *Idx, const Twine &NameStr); - - template - void init(Value *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, - const Twine &NameStr, - // This argument ensures that we have an iterator we can - // do arithmetic on in constant time - std::random_access_iterator_tag) { - unsigned NumIdx = static_cast(std::distance(IdxBegin, IdxEnd)); - - if (NumIdx > 0) { - // This requires that the iterator points to contiguous memory. - init(Ptr, &*IdxBegin, NumIdx, NameStr); // FIXME: for the general case - // we have to build an array here - } - else { - init(Ptr, 0, NumIdx, NameStr); - } - } - - /// getIndexedType - Returns the type of the element that would be loaded with - /// a load instruction with the specified parameters. - /// - /// Null is returned if the indices are invalid for the specified - /// pointer type. - /// - template - static Type *getIndexedType(const Type *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, - // This argument ensures that we - // have an iterator we can do - // arithmetic on in constant time - std::random_access_iterator_tag) { - unsigned NumIdx = static_cast(std::distance(IdxBegin, IdxEnd)); - - if (NumIdx > 0) - // This requires that the iterator points to contiguous memory. - return getIndexedType(Ptr, &*IdxBegin, NumIdx); - else - return getIndexedType(Ptr, (Value *const*)0, NumIdx); - } + void init(Value *Ptr, ArrayRef IdxList, const Twine &NameStr); /// Constructors - Create a getelementptr instruction with a base pointer an /// list of indices. The first ctor can optionally insert before an existing /// instruction, the second appends the new instruction to the specified /// BasicBlock. - template - inline GetElementPtrInst(Value *Ptr, RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, - unsigned Values, - const Twine &NameStr, + inline GetElementPtrInst(Value *Ptr, ArrayRef IdxList, + unsigned Values, const Twine &NameStr, Instruction *InsertBefore); - template - inline GetElementPtrInst(Value *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, - unsigned Values, - const Twine &NameStr, BasicBlock *InsertAtEnd); - - /// Constructors - These two constructors are convenience methods because one - /// and two index getelementptr instructions are so common. - GetElementPtrInst(Value *Ptr, Value *Idx, const Twine &NameStr = "", - Instruction *InsertBefore = 0); - GetElementPtrInst(Value *Ptr, Value *Idx, - const Twine &NameStr, BasicBlock *InsertAtEnd); + inline GetElementPtrInst(Value *Ptr, ArrayRef IdxList, + unsigned Values, const Twine &NameStr, + BasicBlock *InsertAtEnd); protected: virtual GetElementPtrInst *clone_impl() const; public: - template - static GetElementPtrInst *Create(Value *Ptr, RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + static GetElementPtrInst *Create(Value *Ptr, ArrayRef IdxList, const Twine &NameStr = "", Instruction *InsertBefore = 0) { - typename std::iterator_traits::difference_type - Values = 1 + std::distance(IdxBegin, IdxEnd); + unsigned Values = 1 + unsigned(IdxList.size()); return new(Values) - GetElementPtrInst(Ptr, IdxBegin, IdxEnd, Values, NameStr, InsertBefore); + GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertBefore); } - template - static GetElementPtrInst *Create(Value *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + static GetElementPtrInst *Create(Value *Ptr, ArrayRef IdxList, const Twine &NameStr, BasicBlock *InsertAtEnd) { - typename std::iterator_traits::difference_type - Values = 1 + std::distance(IdxBegin, IdxEnd); + unsigned Values = 1 + unsigned(IdxList.size()); return new(Values) - GetElementPtrInst(Ptr, IdxBegin, IdxEnd, Values, NameStr, InsertAtEnd); - } - - /// Constructors - These two creators are convenience methods because one - /// index getelementptr instructions are so common. - static GetElementPtrInst *Create(Value *Ptr, Value *Idx, - const Twine &NameStr = "", - Instruction *InsertBefore = 0) { - return new(2) GetElementPtrInst(Ptr, Idx, NameStr, InsertBefore); - } - static GetElementPtrInst *Create(Value *Ptr, Value *Idx, - const Twine &NameStr, - BasicBlock *InsertAtEnd) { - return new(2) GetElementPtrInst(Ptr, Idx, NameStr, InsertAtEnd); + GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertAtEnd); } /// Create an "inbounds" getelementptr. See the documentation for the /// "inbounds" flag in LangRef.html for details. - template static GetElementPtrInst *CreateInBounds(Value *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef IdxList, const Twine &NameStr = "", Instruction *InsertBefore = 0) { - GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd, - NameStr, InsertBefore); + GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertBefore); GEP->setIsInBounds(true); return GEP; } - template static GetElementPtrInst *CreateInBounds(Value *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef IdxList, const Twine &NameStr, BasicBlock *InsertAtEnd) { - GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd, - NameStr, InsertAtEnd); - GEP->setIsInBounds(true); - return GEP; - } - static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx, - const Twine &NameStr = "", - Instruction *InsertBefore = 0) { - GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertBefore); - GEP->setIsInBounds(true); - return GEP; - } - static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx, - const Twine &NameStr, - BasicBlock *InsertAtEnd) { - GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertAtEnd); + GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertAtEnd); GEP->setIsInBounds(true); return GEP; } @@ -436,8 +762,8 @@ class GetElementPtrInst : public Instruction { DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); // getType - Overload to return most specific pointer type... - const PointerType *getType() const { - return reinterpret_cast(Instruction::getType()); + PointerType *getType() const { + return reinterpret_cast(Instruction::getType()); } /// getIndexedType - Returns the type of the element that would be loaded with @@ -446,23 +772,9 @@ class GetElementPtrInst : public Instruction { /// Null is returned if the indices are invalid for the specified /// pointer type. /// - template - static Type *getIndexedType(const Type *Ptr, RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd) { - return getIndexedType(Ptr, IdxBegin, IdxEnd, - typename std::iterator_traits:: - iterator_category()); - } - - // FIXME: Use ArrayRef - static Type *getIndexedType(const Type *Ptr, - Value* const *Idx, unsigned NumIdx); - static Type *getIndexedType(const Type *Ptr, - Constant* const *Idx, unsigned NumIdx); - - static Type *getIndexedType(const Type *Ptr, - uint64_t const *Idx, unsigned NumIdx); - static Type *getIndexedType(const Type *Ptr, Value *Idx); + static Type *getIndexedType(Type *Ptr, ArrayRef IdxList); + static Type *getIndexedType(Type *Ptr, ArrayRef IdxList); + static Type *getIndexedType(Type *Ptr, ArrayRef IdxList); inline op_iterator idx_begin() { return op_begin()+1; } inline const_op_iterator idx_begin() const { return op_begin()+1; } @@ -485,8 +797,8 @@ class GetElementPtrInst : public Instruction { /// getPointerOperandType - Method to return the pointer operand as a /// PointerType. - const PointerType *getPointerOperandType() const { - return reinterpret_cast(getPointerOperand()->getType()); + PointerType *getPointerOperandType() const { + return reinterpret_cast(getPointerOperand()->getType()); } @@ -530,43 +842,33 @@ struct OperandTraits : public VariadicOperandTraits { }; -template GetElementPtrInst::GetElementPtrInst(Value *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef IdxList, unsigned Values, const Twine &NameStr, Instruction *InsertBefore) : Instruction(PointerType::get(checkGEPType( - getIndexedType(Ptr->getType(), - IdxBegin, IdxEnd)), + getIndexedType(Ptr->getType(), IdxList)), cast(Ptr->getType()) ->getAddressSpace()), GetElementPtr, OperandTraits::op_end(this) - Values, Values, InsertBefore) { - init(Ptr, IdxBegin, IdxEnd, NameStr, - typename std::iterator_traits - ::iterator_category()); + init(Ptr, IdxList, NameStr); } -template GetElementPtrInst::GetElementPtrInst(Value *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + ArrayRef IdxList, unsigned Values, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(PointerType::get(checkGEPType( - getIndexedType(Ptr->getType(), - IdxBegin, IdxEnd)), + getIndexedType(Ptr->getType(), IdxList)), cast(Ptr->getType()) ->getAddressSpace()), GetElementPtr, OperandTraits::op_end(this) - Values, Values, InsertAtEnd) { - init(Ptr, IdxBegin, IdxEnd, NameStr, - typename std::iterator_traits - ::iterator_category()); + init(Ptr, IdxList, NameStr); } @@ -893,12 +1195,12 @@ class CallInst : public Instruction { /// 2. Call malloc with that argument. /// 3. Bitcast the result of the malloc call to the specified type. static Instruction *CreateMalloc(Instruction *InsertBefore, - const Type *IntPtrTy, const Type *AllocTy, + Type *IntPtrTy, Type *AllocTy, Value *AllocSize, Value *ArraySize = 0, Function* MallocF = 0, const Twine &Name = ""); static Instruction *CreateMalloc(BasicBlock *InsertAtEnd, - const Type *IntPtrTy, const Type *AllocTy, + Type *IntPtrTy, Type *AllocTy, Value *AllocSize, Value *ArraySize = 0, Function* MallocF = 0, const Twine &Name = ""); @@ -965,6 +1267,15 @@ class CallInst : public Instruction { else removeAttribute(~0, Attribute::NoInline); } + /// @brief Return true if the call can return twice + bool canReturnTwice() const { + return paramHasAttr(~0, Attribute::ReturnsTwice); + } + void setCanReturnTwice(bool Value = true) { + if (Value) addAttribute(~0, Attribute::ReturnsTwice); + else removeAttribute(~0, Attribute::ReturnsTwice); + } + /// @brief Determine if the call does not access memory. bool doesNotAccessMemory() const { return paramHasAttr(~0, Attribute::ReadNone); @@ -1165,12 +1476,12 @@ class VAArgInst : public UnaryInstruction { virtual VAArgInst *clone_impl() const; public: - VAArgInst(Value *List, const Type *Ty, const Twine &NameStr = "", + VAArgInst(Value *List, Type *Ty, const Twine &NameStr = "", Instruction *InsertBefore = 0) : UnaryInstruction(Ty, VAArg, List, InsertBefore) { setName(NameStr); } - VAArgInst(Value *List, const Type *Ty, const Twine &NameStr, + VAArgInst(Value *List, Type *Ty, const Twine &NameStr, BasicBlock *InsertAtEnd) : UnaryInstruction(Ty, VAArg, List, InsertAtEnd) { setName(NameStr); @@ -1226,8 +1537,8 @@ class ExtractElementInst : public Instruction { const Value *getVectorOperand() const { return Op<0>(); } const Value *getIndexOperand() const { return Op<1>(); } - const VectorType *getVectorOperandType() const { - return reinterpret_cast(getVectorOperand()->getType()); + VectorType *getVectorOperandType() const { + return reinterpret_cast(getVectorOperand()->getType()); } @@ -1286,8 +1597,8 @@ class InsertElementInst : public Instruction { /// getType - Overload to return most specific vector type. /// - const VectorType *getType() const { - return reinterpret_cast(Instruction::getType()); + VectorType *getType() const { + return reinterpret_cast(Instruction::getType()); } /// Transparently provide more efficient getOperand methods. @@ -1339,8 +1650,8 @@ class ShuffleVectorInst : public Instruction { /// getType - Overload to return most specific vector type. /// - const VectorType *getType() const { - return reinterpret_cast(Instruction::getType()); + VectorType *getType() const { + return reinterpret_cast(Instruction::getType()); } /// Transparently provide more efficient getOperand methods. @@ -1419,7 +1730,7 @@ class ExtractValueInst : public UnaryInstruction { /// with an extractvalue instruction with the specified parameters. /// /// Null is returned if the indices are invalid for the specified type. - static Type *getIndexedType(const Type *Agg, ArrayRef Idxs); + static Type *getIndexedType(Type *Agg, ArrayRef Idxs); typedef const unsigned* idx_iterator; inline idx_iterator idx_begin() const { return Indices.begin(); } @@ -1625,7 +1936,7 @@ class PHINode : public Instruction { void *operator new(size_t s) { return User::operator new(s, 0); } - explicit PHINode(const Type *Ty, unsigned NumReservedValues, + explicit PHINode(Type *Ty, unsigned NumReservedValues, const Twine &NameStr = "", Instruction *InsertBefore = 0) : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore), ReservedSpace(NumReservedValues) { @@ -1633,7 +1944,7 @@ class PHINode : public Instruction { OperandList = allocHungoffUses(ReservedSpace); } - PHINode(const Type *Ty, unsigned NumReservedValues, const Twine &NameStr, + PHINode(Type *Ty, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd), ReservedSpace(NumReservedValues) { @@ -1650,12 +1961,12 @@ class PHINode : public Instruction { public: /// Constructors - NumReservedValues is a hint for the number of incoming /// edges that this phi node will have (use 0 if you really have no idea). - static PHINode *Create(const Type *Ty, unsigned NumReservedValues, + static PHINode *Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr = "", Instruction *InsertBefore = 0) { return new PHINode(Ty, NumReservedValues, NameStr, InsertBefore); } - static PHINode *Create(const Type *Ty, unsigned NumReservedValues, + static PHINode *Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr, BasicBlock *InsertAtEnd) { return new PHINode(Ty, NumReservedValues, NameStr, InsertAtEnd); } @@ -1804,6 +2115,111 @@ struct OperandTraits : public HungoffOperandTraits<2> { DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PHINode, Value) +//===----------------------------------------------------------------------===// +// LandingPadInst Class +//===----------------------------------------------------------------------===// + +//===--------------------------------------------------------------------------- +/// LandingPadInst - The landingpad instruction holds all of the information +/// necessary to generate correct exception handling. The landingpad instruction +/// cannot be moved from the top of a landing pad block, which itself is +/// accessible only from the 'unwind' edge of an invoke. This uses the +/// SubclassData field in Value to store whether or not the landingpad is a +/// cleanup. +/// +class LandingPadInst : public Instruction { + /// ReservedSpace - The number of operands actually allocated. NumOperands is + /// the number actually in use. + unsigned ReservedSpace; + LandingPadInst(const LandingPadInst &LP); +public: + enum ClauseType { Catch, Filter }; +private: + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + // Allocate space for exactly zero operands. + void *operator new(size_t s) { + return User::operator new(s, 0); + } + void growOperands(unsigned Size); + void init(Value *PersFn, unsigned NumReservedValues, const Twine &NameStr); + + explicit LandingPadInst(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedValues, const Twine &NameStr, + Instruction *InsertBefore); + explicit LandingPadInst(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedValues, const Twine &NameStr, + BasicBlock *InsertAtEnd); +protected: + virtual LandingPadInst *clone_impl() const; +public: + /// Constructors - NumReservedClauses is a hint for the number of incoming + /// clauses that this landingpad will have (use 0 if you really have no idea). + static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedClauses, + const Twine &NameStr = "", + Instruction *InsertBefore = 0); + static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedClauses, + const Twine &NameStr, BasicBlock *InsertAtEnd); + ~LandingPadInst(); + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + /// getPersonalityFn - Get the personality function associated with this + /// landing pad. + Value *getPersonalityFn() const { return getOperand(0); } + + /// isCleanup - Return 'true' if this landingpad instruction is a + /// cleanup. I.e., it should be run when unwinding even if its landing pad + /// doesn't catch the exception. + bool isCleanup() const { return getSubclassDataFromInstruction() & 1; } + + /// setCleanup - Indicate that this landingpad instruction is a cleanup. + void setCleanup(bool V) { + setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) | + (V ? 1 : 0)); + } + + /// addClause - Add a catch or filter clause to the landing pad. + void addClause(Value *ClauseVal); + + /// getClause - Get the value of the clause at index Idx. Use isCatch/isFilter + /// to determine what type of clause this is. + Value *getClause(unsigned Idx) const { return OperandList[Idx + 1]; } + + /// isCatch - Return 'true' if the clause and index Idx is a catch clause. + bool isCatch(unsigned Idx) const { + return !isa(OperandList[Idx + 1]->getType()); + } + + /// isFilter - Return 'true' if the clause and index Idx is a filter clause. + bool isFilter(unsigned Idx) const { + return isa(OperandList[Idx + 1]->getType()); + } + + /// getNumClauses - Get the number of clauses for this landing pad. + unsigned getNumClauses() const { return getNumOperands() - 1; } + + /// reserveClauses - Grow the size of the operand list to accomodate the new + /// number of clauses. + void reserveClauses(unsigned Size) { growOperands(Size); } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const LandingPadInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::LandingPad; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +}; + +template <> +struct OperandTraits : public HungoffOperandTraits<2> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(LandingPadInst, Value) //===----------------------------------------------------------------------===// // ReturnInst Class @@ -1951,6 +2367,13 @@ class BranchInst : public TerminatorInst { *(&Op<-1>() - idx) = (Value*)NewSucc; } + /// \brief Swap the successors of this branch instruction. + /// + /// Swaps the successors of the branch instruction. This also swaps any + /// branch weight metadata associated with the instruction so that it + /// continues to map correctly to each operand. + void swapSuccessors(); + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BranchInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2102,6 +2525,13 @@ class SwitchInst : public TerminatorInst { return reinterpret_cast(getOperand(idx*2)); } + // setSuccessorValue - Updates the value associated with the specified + // successor. + void setSuccessorValue(unsigned idx, ConstantInt* SuccessorValue) { + assert(idx < getNumSuccessors() && "Successor # out of range!"); + setOperand(idx*2, reinterpret_cast(SuccessorValue)); + } + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SwitchInst *) { return true; } static inline bool classof(const Instruction *I) { @@ -2393,6 +2823,10 @@ class InvokeInst : public TerminatorInst { Op<-1>() = reinterpret_cast(B); } + /// getLandingPadInst - Get the landingpad instruction from the landing pad + /// block (the unwind destination). + LandingPadInst *getLandingPadInst() const; + BasicBlock *getSuccessor(unsigned i) const { assert(i < 2 && "Successor # out of range for invoke!"); return i == 0 ? getNormalDest() : getUnwindDest(); @@ -2491,6 +2925,57 @@ class UnwindInst : public TerminatorInst { virtual void setSuccessorV(unsigned idx, BasicBlock *B); }; +//===----------------------------------------------------------------------===// +// ResumeInst Class +//===----------------------------------------------------------------------===// + +//===--------------------------------------------------------------------------- +/// ResumeInst - Resume the propagation of an exception. +/// +class ResumeInst : public TerminatorInst { + ResumeInst(const ResumeInst &RI); + + explicit ResumeInst(Value *Exn, Instruction *InsertBefore=0); + ResumeInst(Value *Exn, BasicBlock *InsertAtEnd); +protected: + virtual ResumeInst *clone_impl() const; +public: + static ResumeInst *Create(Value *Exn, Instruction *InsertBefore = 0) { + return new(1) ResumeInst(Exn, InsertBefore); + } + static ResumeInst *Create(Value *Exn, BasicBlock *InsertAtEnd) { + return new(1) ResumeInst(Exn, InsertAtEnd); + } + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + /// Convenience accessor. + Value *getValue() const { return Op<0>(); } + + unsigned getNumSuccessors() const { return 0; } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const ResumeInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::Resume; + } + static inline bool classof(const Value *V) { + return isa(V) && classof(cast(V)); + } +private: + virtual BasicBlock *getSuccessorV(unsigned idx) const; + virtual unsigned getNumSuccessorsV() const; + virtual void setSuccessorV(unsigned idx, BasicBlock *B); +}; + +template <> +struct OperandTraits : + public FixedNumOperandTraits { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value) + //===----------------------------------------------------------------------===// // UnreachableInst Class //===----------------------------------------------------------------------===// @@ -2543,7 +3028,7 @@ class TruncInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics TruncInst( Value *S, ///< The value to be truncated - const Type *Ty, ///< The (smaller) type to truncate to + Type *Ty, ///< The (smaller) type to truncate to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2551,7 +3036,7 @@ class TruncInst : public CastInst { /// @brief Constructor with insert-at-end-of-block semantics TruncInst( Value *S, ///< The value to be truncated - const Type *Ty, ///< The (smaller) type to truncate to + Type *Ty, ///< The (smaller) type to truncate to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -2580,7 +3065,7 @@ class ZExtInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics ZExtInst( Value *S, ///< The value to be zero extended - const Type *Ty, ///< The type to zero extend to + Type *Ty, ///< The type to zero extend to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2588,7 +3073,7 @@ class ZExtInst : public CastInst { /// @brief Constructor with insert-at-end semantics. ZExtInst( Value *S, ///< The value to be zero extended - const Type *Ty, ///< The type to zero extend to + Type *Ty, ///< The type to zero extend to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -2617,7 +3102,7 @@ class SExtInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics SExtInst( Value *S, ///< The value to be sign extended - const Type *Ty, ///< The type to sign extend to + Type *Ty, ///< The type to sign extend to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2625,7 +3110,7 @@ class SExtInst : public CastInst { /// @brief Constructor with insert-at-end-of-block semantics SExtInst( Value *S, ///< The value to be sign extended - const Type *Ty, ///< The type to sign extend to + Type *Ty, ///< The type to sign extend to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -2654,7 +3139,7 @@ class FPTruncInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics FPTruncInst( Value *S, ///< The value to be truncated - const Type *Ty, ///< The type to truncate to + Type *Ty, ///< The type to truncate to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2662,7 +3147,7 @@ class FPTruncInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics FPTruncInst( Value *S, ///< The value to be truncated - const Type *Ty, ///< The type to truncate to + Type *Ty, ///< The type to truncate to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -2691,7 +3176,7 @@ class FPExtInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics FPExtInst( Value *S, ///< The value to be extended - const Type *Ty, ///< The type to extend to + Type *Ty, ///< The type to extend to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2699,7 +3184,7 @@ class FPExtInst : public CastInst { /// @brief Constructor with insert-at-end-of-block semantics FPExtInst( Value *S, ///< The value to be extended - const Type *Ty, ///< The type to extend to + Type *Ty, ///< The type to extend to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -2728,7 +3213,7 @@ class UIToFPInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics UIToFPInst( Value *S, ///< The value to be converted - const Type *Ty, ///< The type to convert to + Type *Ty, ///< The type to convert to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2736,7 +3221,7 @@ class UIToFPInst : public CastInst { /// @brief Constructor with insert-at-end-of-block semantics UIToFPInst( Value *S, ///< The value to be converted - const Type *Ty, ///< The type to convert to + Type *Ty, ///< The type to convert to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -2765,7 +3250,7 @@ class SIToFPInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics SIToFPInst( Value *S, ///< The value to be converted - const Type *Ty, ///< The type to convert to + Type *Ty, ///< The type to convert to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2773,7 +3258,7 @@ class SIToFPInst : public CastInst { /// @brief Constructor with insert-at-end-of-block semantics SIToFPInst( Value *S, ///< The value to be converted - const Type *Ty, ///< The type to convert to + Type *Ty, ///< The type to convert to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -2802,7 +3287,7 @@ class FPToUIInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics FPToUIInst( Value *S, ///< The value to be converted - const Type *Ty, ///< The type to convert to + Type *Ty, ///< The type to convert to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2810,7 +3295,7 @@ class FPToUIInst : public CastInst { /// @brief Constructor with insert-at-end-of-block semantics FPToUIInst( Value *S, ///< The value to be converted - const Type *Ty, ///< The type to convert to + Type *Ty, ///< The type to convert to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< Where to insert the new instruction ); @@ -2839,7 +3324,7 @@ class FPToSIInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics FPToSIInst( Value *S, ///< The value to be converted - const Type *Ty, ///< The type to convert to + Type *Ty, ///< The type to convert to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2847,7 +3332,7 @@ class FPToSIInst : public CastInst { /// @brief Constructor with insert-at-end-of-block semantics FPToSIInst( Value *S, ///< The value to be converted - const Type *Ty, ///< The type to convert to + Type *Ty, ///< The type to convert to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -2872,7 +3357,7 @@ class IntToPtrInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics IntToPtrInst( Value *S, ///< The value to be converted - const Type *Ty, ///< The type to convert to + Type *Ty, ///< The type to convert to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2880,7 +3365,7 @@ class IntToPtrInst : public CastInst { /// @brief Constructor with insert-at-end-of-block semantics IntToPtrInst( Value *S, ///< The value to be converted - const Type *Ty, ///< The type to convert to + Type *Ty, ///< The type to convert to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -2912,7 +3397,7 @@ class PtrToIntInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics PtrToIntInst( Value *S, ///< The value to be converted - const Type *Ty, ///< The type to convert to + Type *Ty, ///< The type to convert to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2920,7 +3405,7 @@ class PtrToIntInst : public CastInst { /// @brief Constructor with insert-at-end-of-block semantics PtrToIntInst( Value *S, ///< The value to be converted - const Type *Ty, ///< The type to convert to + Type *Ty, ///< The type to convert to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); @@ -2949,7 +3434,7 @@ class BitCastInst : public CastInst { /// @brief Constructor with insert-before-instruction semantics BitCastInst( Value *S, ///< The value to be casted - const Type *Ty, ///< The type to casted to + Type *Ty, ///< The type to casted to const Twine &NameStr = "", ///< A name for the new instruction Instruction *InsertBefore = 0 ///< Where to insert the new instruction ); @@ -2957,7 +3442,7 @@ class BitCastInst : public CastInst { /// @brief Constructor with insert-at-end-of-block semantics BitCastInst( Value *S, ///< The value to be casted - const Type *Ty, ///< The type to casted to + Type *Ty, ///< The type to casted to const Twine &NameStr, ///< A name for the new instruction BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h index 24e5fe7845fe..42862011ac7a 100644 --- a/include/llvm/IntrinsicInst.h +++ b/include/llvm/IntrinsicInst.h @@ -170,7 +170,7 @@ namespace llvm { setArgOperand(4, V); } - const Type *getAlignmentType() const { + Type *getAlignmentType() const { return getArgOperand(3)->getType(); } diff --git a/include/llvm/Intrinsics.h b/include/llvm/Intrinsics.h index 46361ca0c2f8..370382560337 100644 --- a/include/llvm/Intrinsics.h +++ b/include/llvm/Intrinsics.h @@ -49,7 +49,7 @@ namespace Intrinsic { /// Intrinsic::getType(ID) - Return the function type for an intrinsic. /// - const FunctionType *getType(LLVMContext &Context, ID id, + FunctionType *getType(LLVMContext &Context, ID id, ArrayRef Tys = ArrayRef()); /// Intrinsic::isOverloaded(ID) - Returns true if the intrinsic can be diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index 947cf1be7d40..d70f9153fd8a 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -309,7 +309,9 @@ def int_eh_selector : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_ptr_ty, llvm_vararg_ty]>; def int_eh_resume : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], [Throws]>; -def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; +// The result of eh.typeid.for depends on the enclosing function, but inside a +// given function it is 'const' and may be CSE'd etc. +def int_eh_typeid_for : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [IntrNoMem]>; def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>; def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>; @@ -320,12 +322,13 @@ def int_eh_unwind_init: Intrinsic<[]>, def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>; let Properties = [IntrNoMem] in { - def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; - def int_eh_sjlj_callsite: Intrinsic<[], [llvm_i32_ty]>; + def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>; + def int_eh_sjlj_callsite : Intrinsic<[], [llvm_i32_ty]>; } -def int_eh_sjlj_dispatch_setup : Intrinsic<[], [llvm_i32_ty]>; -def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; -def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>; +def int_eh_sjlj_functioncontext : Intrinsic<[], [llvm_ptr_ty]>; +def int_eh_sjlj_dispatch_setup : Intrinsic<[], [llvm_i32_ty]>; +def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>; +def int_eh_sjlj_longjmp : Intrinsic<[], [llvm_ptr_ty]>; //===---------------- Generic Variable Attribute Intrinsics----------------===// // @@ -344,10 +347,14 @@ def int_annotation : Intrinsic<[llvm_anyint_ty], //===------------------------ Trampoline Intrinsics -----------------------===// // -def int_init_trampoline : Intrinsic<[llvm_ptr_ty], +def int_init_trampoline : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty], - [IntrReadWriteArgMem]>, - GCCBuiltin<"__builtin_init_trampoline">; + [IntrReadWriteArgMem, NoCapture<0>]>, + GCCBuiltin<"__builtin_init_trampoline">; + +def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], + [IntrReadArgMem]>, + GCCBuiltin<"__builtin_adjust_trampoline">; //===------------------------ Overflow Intrinsics -------------------------===// // @@ -374,74 +381,6 @@ def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>; -//===------------------------- Atomic Intrinsics --------------------------===// -// -def int_memory_barrier : Intrinsic<[], - [llvm_i1_ty, llvm_i1_ty, - llvm_i1_ty, llvm_i1_ty, llvm_i1_ty], []>, - GCCBuiltin<"__builtin_llvm_memory_barrier">; - -def int_atomic_cmp_swap : Intrinsic<[llvm_anyint_ty], - [LLVMAnyPointerType>, - LLVMMatchType<0>, LLVMMatchType<0>], - [IntrReadWriteArgMem, NoCapture<0>]>, - GCCBuiltin<"__sync_val_compare_and_swap">; -def int_atomic_load_add : Intrinsic<[llvm_anyint_ty], - [LLVMAnyPointerType>, - LLVMMatchType<0>], - [IntrReadWriteArgMem, NoCapture<0>]>, - GCCBuiltin<"__sync_fetch_and_add">; -def int_atomic_swap : Intrinsic<[llvm_anyint_ty], - [LLVMAnyPointerType>, - LLVMMatchType<0>], - [IntrReadWriteArgMem, NoCapture<0>]>, - GCCBuiltin<"__sync_lock_test_and_set">; -def int_atomic_load_sub : Intrinsic<[llvm_anyint_ty], - [LLVMAnyPointerType>, - LLVMMatchType<0>], - [IntrReadWriteArgMem, NoCapture<0>]>, - GCCBuiltin<"__sync_fetch_and_sub">; -def int_atomic_load_and : Intrinsic<[llvm_anyint_ty], - [LLVMAnyPointerType>, - LLVMMatchType<0>], - [IntrReadWriteArgMem, NoCapture<0>]>, - GCCBuiltin<"__sync_fetch_and_and">; -def int_atomic_load_or : Intrinsic<[llvm_anyint_ty], - [LLVMAnyPointerType>, - LLVMMatchType<0>], - [IntrReadWriteArgMem, NoCapture<0>]>, - GCCBuiltin<"__sync_fetch_and_or">; -def int_atomic_load_xor : Intrinsic<[llvm_anyint_ty], - [LLVMAnyPointerType>, - LLVMMatchType<0>], - [IntrReadWriteArgMem, NoCapture<0>]>, - GCCBuiltin<"__sync_fetch_and_xor">; -def int_atomic_load_nand : Intrinsic<[llvm_anyint_ty], - [LLVMAnyPointerType>, - LLVMMatchType<0>], - [IntrReadWriteArgMem, NoCapture<0>]>, - GCCBuiltin<"__sync_fetch_and_nand">; -def int_atomic_load_min : Intrinsic<[llvm_anyint_ty], - [LLVMAnyPointerType>, - LLVMMatchType<0>], - [IntrReadWriteArgMem, NoCapture<0>]>, - GCCBuiltin<"__sync_fetch_and_min">; -def int_atomic_load_max : Intrinsic<[llvm_anyint_ty], - [LLVMAnyPointerType>, - LLVMMatchType<0>], - [IntrReadWriteArgMem, NoCapture<0>]>, - GCCBuiltin<"__sync_fetch_and_max">; -def int_atomic_load_umin : Intrinsic<[llvm_anyint_ty], - [LLVMAnyPointerType>, - LLVMMatchType<0>], - [IntrReadWriteArgMem, NoCapture<0>]>, - GCCBuiltin<"__sync_fetch_and_umin">; -def int_atomic_load_umax : Intrinsic<[llvm_anyint_ty], - [LLVMAnyPointerType>, - LLVMMatchType<0>], - [IntrReadWriteArgMem, NoCapture<0>]>, - GCCBuiltin<"__sync_fetch_and_umax">; - //===------------------------- Memory Use Markers -------------------------===// // def int_lifetime_start : Intrinsic<[], diff --git a/include/llvm/IntrinsicsXCore.td b/include/llvm/IntrinsicsXCore.td index a062fc4fc7e8..a4813135da8d 100644 --- a/include/llvm/IntrinsicsXCore.td +++ b/include/llvm/IntrinsicsXCore.td @@ -1,6 +1,9 @@ //==- IntrinsicsXCore.td - XCore intrinsics -*- tablegen -*-==// -// -// Copyright (C) 2008 XMOS +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -17,9 +20,15 @@ let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.". def int_xcore_crc32 : Intrinsic<[llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty], [IntrNoMem]>; + def int_xcore_sext : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; + def int_xcore_zext : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], + [IntrNoMem]>; def int_xcore_getid : Intrinsic<[llvm_i32_ty],[],[IntrNoMem]>; def int_xcore_getps : Intrinsic<[llvm_i32_ty],[llvm_i32_ty]>; def int_xcore_setps : Intrinsic<[],[llvm_i32_ty, llvm_i32_ty]>; + def int_xcore_geted : Intrinsic<[llvm_i32_ty],[]>; + def int_xcore_getet : Intrinsic<[llvm_i32_ty],[]>; def int_xcore_setsr : Intrinsic<[],[llvm_i32_ty]>; def int_xcore_clrsr : Intrinsic<[],[llvm_i32_ty]>; @@ -40,6 +49,10 @@ let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.". [NoCapture<0>]>; def int_xcore_chkct : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty], [NoCapture<0>]>; + def int_xcore_testct : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty], + [NoCapture<0>]>; + def int_xcore_testwct : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty], + [NoCapture<0>]>; def int_xcore_setd : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty], [NoCapture<0>]>; def int_xcore_setc : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty], @@ -58,6 +71,8 @@ let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.". [NoCapture<0>]>; def int_xcore_setv : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty], [NoCapture<0>]>; + def int_xcore_setev : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty], + [NoCapture<0>]>; def int_xcore_eeu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<0>]>; def int_xcore_setclk : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty], [NoCapture<0>, NoCapture<1>]>; @@ -65,6 +80,10 @@ let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.". [NoCapture<0>, NoCapture<1>]>; def int_xcore_setpsc : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty], [NoCapture<0>]>; + def int_xcore_peek : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty], + [NoCapture<0>]>; + def int_xcore_endin : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty], + [NoCapture<0>]>; // Intrinsics for events. def int_xcore_waitevent : Intrinsic<[llvm_ptr_ty],[], [IntrReadMem]>; diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 8467d1149033..f690d045d172 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -93,7 +93,6 @@ namespace { (void) llvm::createLoopRotatePass(); (void) llvm::createLowerExpectIntrinsicPass(); (void) llvm::createLowerInvokePass(); - (void) llvm::createLowerSetJmpPass(); (void) llvm::createLowerSwitchPass(); (void) llvm::createNoAAPass(); (void) llvm::createNoProfileInfoPass(); @@ -128,7 +127,6 @@ namespace { (void) llvm::createStripDeadDebugInfoPass(); (void) llvm::createStripDeadPrototypesPass(); (void) llvm::createTailCallEliminationPass(); - (void) llvm::createTailDuplicationPass(); (void) llvm::createJumpThreadingPass(); (void) llvm::createUnifyFunctionExitNodesPass(); (void) llvm::createInstCountPass(); @@ -157,7 +155,7 @@ namespace { (void)new llvm::FindUsedTypes(); (void)new llvm::ScalarEvolution(); ((llvm::Function*)0)->viewCFGOnly(); - llvm::RGPassManager RGM(0); + llvm::RGPassManager RGM; ((llvm::RegionPass*)0)->runOnRegion((llvm::Region*)0, RGM); llvm::AliasSetTracker X(*(llvm::AliasAnalysis*)0); X.add((llvm::Value*)0, 0, 0); // for -print-alias-sets diff --git a/include/llvm/Linker.h b/include/llvm/Linker.h index b402a6090e2c..88908fbd72a7 100644 --- a/include/llvm/Linker.h +++ b/include/llvm/Linker.h @@ -57,7 +57,12 @@ class Linker { QuietWarnings = 2, ///< Don't print warnings to stderr. QuietErrors = 4 ///< Don't print errors to stderr. }; - + + enum LinkerMode { + DestroySource = 0, // Allow source module to be destroyed. + PreserveSource = 1 // Preserve the source module. + }; + /// @} /// @name Constructors /// @{ @@ -245,7 +250,7 @@ class Linker { Module* Src, ///< Module linked into \p Dest std::string* ErrorMsg = 0 /// Error/diagnostic string ) { - return LinkModules(Composite, Src, ErrorMsg ); + return LinkModules(Composite, Src, Linker::DestroySource, ErrorMsg ); } /// This is the heart of the linker. This method will take unconditional @@ -259,7 +264,8 @@ class Linker { /// error. /// @returns True if an error occurs, false otherwise. /// @brief Generically link two modules together. - static bool LinkModules(Module* Dest, Module* Src, std::string* ErrorMsg); + static bool LinkModules(Module* Dest, Module* Src, unsigned Mode, + std::string* ErrorMsg); /// This function looks through the Linker's LibPaths to find a library with /// the name \p Filename. If the library cannot be found, the returned path diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h index 83d9e780feb7..0b9d3f63f677 100644 --- a/include/llvm/MC/EDInstInfo.h +++ b/include/llvm/MC/EDInstInfo.h @@ -21,7 +21,7 @@ struct EDInstInfo { uint8_t numOperands; uint8_t operandTypes[EDIS_MAX_OPERANDS]; uint8_t operandFlags[EDIS_MAX_OPERANDS]; - const char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS]; + const signed char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS]; }; } // namespace llvm diff --git a/include/llvm/Target/TargetAsmBackend.h b/include/llvm/MC/MCAsmBackend.h similarity index 90% rename from include/llvm/Target/TargetAsmBackend.h rename to include/llvm/MC/MCAsmBackend.h index 2111f6b7a950..4a0cf37a6eb2 100644 --- a/include/llvm/Target/TargetAsmBackend.h +++ b/include/llvm/MC/MCAsmBackend.h @@ -1,4 +1,4 @@ -//===-- llvm/Target/TargetAsmBackend.h - Target Asm Backend -----*- C++ -*-===// +//===-- llvm/MC/MCAsmBack.h - MC Asm Backend --------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_TARGETASMBACKEND_H -#define LLVM_TARGET_TARGETASMBACKEND_H +#ifndef LLVM_MC_MCASMBACKEND_H +#define LLVM_MC_MCASMBACKEND_H #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCFixup.h" @@ -25,17 +25,17 @@ template class SmallVectorImpl; class raw_ostream; -/// TargetAsmBackend - Generic interface to target specific assembler backends. -class TargetAsmBackend { - TargetAsmBackend(const TargetAsmBackend &); // DO NOT IMPLEMENT - void operator=(const TargetAsmBackend &); // DO NOT IMPLEMENT +/// MCAsmBackend - Generic interface to target specific assembler backends. +class MCAsmBackend { + MCAsmBackend(const MCAsmBackend &); // DO NOT IMPLEMENT + void operator=(const MCAsmBackend &); // DO NOT IMPLEMENT protected: // Can only create subclasses. - TargetAsmBackend(); + MCAsmBackend(); unsigned HasReliableSymbolDifference : 1; public: - virtual ~TargetAsmBackend(); + virtual ~MCAsmBackend(); /// createObjectWriter - Create a new MCObjectWriter instance for use by the /// assembler backend to emit the final object file. diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h index 41c171761e78..c3c296e23dc1 100644 --- a/include/llvm/MC/MCAsmInfo.h +++ b/include/llvm/MC/MCAsmInfo.h @@ -16,8 +16,10 @@ #ifndef LLVM_TARGET_ASM_INFO_H #define LLVM_TARGET_ASM_INFO_H +#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCDirectives.h" #include +#include namespace llvm { class MCExpr; @@ -30,6 +32,14 @@ namespace llvm { enum ExceptionsType { None, DwarfCFI, SjLj, ARM, Win64 }; } + namespace LCOMM { + enum LCOMMType { None, NoAlignment, ByteAlignment }; + } + + namespace Structors { + enum OutputOrder { None, PriorityOrder, ReversePriorityOrder }; + } + /// MCAsmInfo - This class is intended to be used as a base class for asm /// properties and features specific to the target. class MCAsmInfo { @@ -62,6 +72,11 @@ namespace llvm { /// the macho-specific .tbss directive for emitting thread local BSS Symbols bool HasMachoTBSSDirective; // Default is false. + /// StructorOutputOrder - Whether the static ctor/dtor list should be output + /// in no particular order, in order of increasing priority or the reverse: + /// in order of decreasing priority (the default). + Structors::OutputOrder StructorOutputOrder; // Default is reverse order. + /// HasStaticCtorDtorReferenceInStaticMode - True if the compiler should /// emit a ".reference .constructors_used" or ".reference .destructors_used" /// directive after the a static ctor/dtor list. This directive is only @@ -115,6 +130,13 @@ namespace llvm { const char *InlineAsmStart; // Defaults to "#APP\n" const char *InlineAsmEnd; // Defaults to "#NO_APP\n" + /// Code16Directive, Code32Directive, Code64Directive - These are assembly + /// directives that tells the assembler to interpret the following + /// instructions differently. + const char *Code16Directive; // Defaults to ".code16" + const char *Code32Directive; // Defaults to ".code32" + const char *Code64Directive; // Defaults to ".code64" + /// AssemblerDialect - Which dialect of an assembler variant to use. unsigned AssemblerDialect; // Defaults to 0 @@ -155,6 +177,18 @@ namespace llvm { const char *Data32bitsDirective; // Defaults to "\t.long\t" const char *Data64bitsDirective; // Defaults to "\t.quad\t" + /// [Data|Code]Begin - These magic labels are used to marked a region as + /// data or code, and are used to provide additional information for + /// correct disassembly on targets that like to mix data and code within + /// a segment. These labels will be implicitly suffixed by the streamer + /// to give them unique names. + const char *DataBegin; // Defaults to "$d." + const char *CodeBegin; // Defaults to "$a." + const char *JT8Begin; // Defaults to "$a." + const char *JT16Begin; // Defaults to "$a." + const char *JT32Begin; // Defaults to "$a." + bool SupportsDataRegions; + /// 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. @@ -220,9 +254,9 @@ namespace llvm { /// .long a - b bool HasAggressiveSymbolFolding; // Defaults to true. - /// HasLCOMMDirective - This is true if the target supports the .lcomm - /// directive. - bool HasLCOMMDirective; // Defaults to false. + /// LCOMMDirectiveType - Describes if the target supports the .lcomm + /// directive and whether it has an alignment parameter. + LCOMM::LCOMMType LCOMMDirectiveType; // Defaults to LCOMM::None. /// COMMDirectiveAlignmentIsInBytes - True is COMMDirective's optional /// alignment is to be specified in bytes instead of log2(n). @@ -304,6 +338,10 @@ namespace llvm { const char *const *AsmTransCBE; // Defaults to empty + //===--- Prologue State ----------------------------------------------===// + + std::vector InitialFrameState; + public: explicit MCAsmInfo(); virtual ~MCAsmInfo(); @@ -345,6 +383,14 @@ namespace llvm { } const char *getGPRel32Directive() const { return GPRel32Directive; } + /// [Code|Data]Begin label name accessors. + const char *getCodeBeginLabelName() const { return CodeBegin; } + const char *getDataBeginLabelName() const { return DataBegin; } + const char *getJumpTable8BeginLabelName() const { return JT8Begin; } + const char *getJumpTable16BeginLabelName() const { return JT16Begin; } + const char *getJumpTable32BeginLabelName() const { return JT32Begin; } + bool getSupportsDataRegions() const { return SupportsDataRegions; } + /// getNonexecutableStackSection - Targets can implement this method to /// specify a section to switch to if the translation unit doesn't have any /// trampolines that require an executable stack. @@ -378,6 +424,9 @@ namespace llvm { // bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; } bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; } + Structors::OutputOrder getStructorOutputOrder() const { + return StructorOutputOrder; + } bool hasStaticCtorDtorReferenceInStaticMode() const { return HasStaticCtorDtorReferenceInStaticMode; } @@ -417,6 +466,15 @@ namespace llvm { const char *getInlineAsmEnd() const { return InlineAsmEnd; } + const char *getCode16Directive() const { + return Code16Directive; + } + const char *getCode32Directive() const { + return Code32Directive; + } + const char *getCode64Directive() const { + return Code64Directive; + } unsigned getAssemblerDialect() const { return AssemblerDialect; } @@ -457,7 +515,9 @@ namespace llvm { bool hasAggressiveSymbolFolding() const { return HasAggressiveSymbolFolding; } - bool hasLCOMMDirective() const { return HasLCOMMDirective; } + LCOMM::LCOMMType getLCOMMDirectiveType() const { + return LCOMMDirectiveType; + } bool hasDotTypeDotSizeDirective() const {return HasDotTypeDotSizeDirective;} bool getCOMMDirectiveAlignmentIsInBytes() const { return COMMDirectiveAlignmentIsInBytes; @@ -512,6 +572,14 @@ namespace llvm { const char *const *getAsmCBE() const { return AsmTransCBE; } + + void addInitialFrameState(MCSymbol *label, const MachineLocation &D, + const MachineLocation &S) { + InitialFrameState.push_back(MachineMove(label, D, S)); + } + const std::vector &getInitialFrameState() const { + return InitialFrameState; + } }; } diff --git a/include/llvm/MC/MCAsmInfoDarwin.h b/include/llvm/MC/MCAsmInfoDarwin.h index c85aa3da9572..1f6c49938c9c 100644 --- a/include/llvm/MC/MCAsmInfoDarwin.h +++ b/include/llvm/MC/MCAsmInfoDarwin.h @@ -18,11 +18,6 @@ #include "llvm/MC/MCAsmInfo.h" namespace llvm { - class GlobalValue; - class GlobalVariable; - class Type; - class Mangler; - struct MCAsmInfoDarwin : public MCAsmInfo { explicit MCAsmInfoDarwin(); }; diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index fc919669e82d..b8f8cc4cec90 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -10,14 +10,14 @@ #ifndef LLVM_MC_MCASSEMBLER_H #define LLVM_MC_MCASSEMBLER_H +#include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCInst.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" #include "llvm/Support/Casting.h" -#include "llvm/MC/MCFixup.h" -#include "llvm/MC/MCInst.h" #include "llvm/Support/DataTypes.h" #include // FIXME: Shouldn't be needed. @@ -36,7 +36,7 @@ class MCSectionData; class MCSymbol; class MCSymbolData; class MCValue; -class TargetAsmBackend; +class MCAsmBackend; class MCFragment : public ilist_node { friend class MCAsmLayout; @@ -660,7 +660,7 @@ class MCAssembler { MCContext &Context; - TargetAsmBackend &Backend; + MCAsmBackend &Backend; MCCodeEmitter &Emitter; @@ -780,14 +780,14 @@ class MCAssembler { // concrete and require clients to pass in a target like object. The other // option is to make this abstract, and have targets provide concrete // implementations as we do with AsmParser. - MCAssembler(MCContext &Context_, TargetAsmBackend &Backend_, + MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, raw_ostream &OS); ~MCAssembler(); MCContext &getContext() const { return Context; } - TargetAsmBackend &getBackend() const { return Backend; } + MCAsmBackend &getBackend() const { return Backend; } MCCodeEmitter &getEmitter() const { return Emitter; } diff --git a/include/llvm/MC/MCAtom.h b/include/llvm/MC/MCAtom.h new file mode 100644 index 000000000000..682cf7cd76c6 --- /dev/null +++ b/include/llvm/MC/MCAtom.h @@ -0,0 +1,68 @@ +//===-- llvm/MC/MCAtom.h - MCAtom class ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the MCAtom class, which is used to +// represent a contiguous region in a decoded object that is uniformly data or +// instructions; +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCATOM_H +#define LLVM_MC_MCATOM_H + +#include "llvm/MC/MCInst.h" +#include "llvm/Support/DataTypes.h" +#include + +namespace llvm { + +class MCModule; + +/// MCData - An entry in a data MCAtom. +// NOTE: This may change to a more complex type in the future. +typedef uint8_t MCData; + +/// MCAtom - Represents a contiguous range of either instructions (a TextAtom) +/// or data (a DataAtom). Address ranges are expressed as _closed_ intervals. +class MCAtom { + friend class MCModule; + typedef enum { TextAtom, DataAtom } AtomType; + + AtomType Type; + MCModule *Parent; + uint64_t Begin, End; + + std::vector > Text; + std::vector Data; + + // Private constructor - only callable by MCModule + MCAtom(AtomType T, MCModule *P, uint64_t B, uint64_t E) + : Type(T), Parent(P), Begin(B), End(E) { } + +public: + bool isTextAtom() { return Type == TextAtom; } + bool isDataAtom() { return Type == DataAtom; } + + void addInst(const MCInst &I, uint64_t Address, unsigned Size); + void addData(const MCData &D); + + /// split - Splits the atom in two at a given address, which must align with + /// and instruction boundary if this is a TextAtom. Returns the newly created + /// atom representing the high part of the split. + MCAtom *split(uint64_t SplitPt); + + /// truncate - Truncates an atom so that TruncPt is the last byte address + /// contained in the atom. + void truncate(uint64_t TruncPt); +}; + +} + +#endif + diff --git a/include/llvm/MC/MCCodeGenInfo.h b/include/llvm/MC/MCCodeGenInfo.h new file mode 100644 index 000000000000..1c54c47e2d95 --- /dev/null +++ b/include/llvm/MC/MCCodeGenInfo.h @@ -0,0 +1,41 @@ +//===-- llvm/MC/MCCodeGenInfo.h - Target CodeGen 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 tracks information about the target which can affect codegen, +// asm parsing, and asm printing. For example, relocation model. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCCODEGENINFO_H +#define LLVM_MC_MCCODEGENINFO_H + +#include "llvm/Support/CodeGen.h" + +namespace llvm { + + class MCCodeGenInfo { + /// RelocationModel - Relocation model: statcic, pic, etc. + /// + Reloc::Model RelocationModel; + + /// CMModel - Code model. + /// + CodeModel::Model CMModel; + + public: + void InitMCCodeGenInfo(Reloc::Model RM = Reloc::Default, + CodeModel::Model CM = CodeModel::Default); + + Reloc::Model getRelocationModel() const { return RelocationModel; } + + CodeModel::Model getCodeModel() const { return CMModel; } + }; +} // namespace llvm + +#endif diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 43a9ce6cfa4d..a49a35c8d5ba 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -26,10 +26,11 @@ namespace llvm { class MCLabel; class MCDwarfFile; class MCDwarfLoc; + class MCObjectFileInfo; + class MCRegisterInfo; class MCLineSection; class StringRef; class Twine; - class TargetAsmInfo; class MCSectionMachO; class MCSectionELF; @@ -46,7 +47,11 @@ namespace llvm { /// The MCAsmInfo for this target. const MCAsmInfo &MAI; - const TargetAsmInfo *TAI; + /// The MCRegisterInfo for this target. + const MCRegisterInfo &MRI; + + /// The MCObjectFileInfo for this target. + const MCObjectFileInfo *MOFI; /// Allocator - Allocator object used for creating machine code objects. /// @@ -110,12 +115,15 @@ namespace llvm { MCSymbol *CreateSymbol(StringRef Name); public: - explicit MCContext(const MCAsmInfo &MAI, const TargetAsmInfo *TAI); + explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI, + const MCObjectFileInfo *MOFI); ~MCContext(); const MCAsmInfo &getAsmInfo() const { return MAI; } - const TargetAsmInfo &getTargetAsmInfo() const { return *TAI; } + const MCRegisterInfo &getRegisterInfo() const { return MRI; } + + const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; } void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; } diff --git a/include/llvm/MC/MCDirectives.h b/include/llvm/MC/MCDirectives.h index 1df55dc252e3..9180d1b369fe 100644 --- a/include/llvm/MC/MCDirectives.h +++ b/include/llvm/MC/MCDirectives.h @@ -47,8 +47,9 @@ enum MCSymbolAttr { enum MCAssemblerFlag { MCAF_SyntaxUnified, ///< .syntax (ARM/ELF) MCAF_SubsectionsViaSymbols, ///< .subsections_via_symbols (MachO) - MCAF_Code16, ///< .code 16 - MCAF_Code32 ///< .code 32 + MCAF_Code16, ///< .code16 (X86) / .code 16 (ARM) + MCAF_Code32, ///< .code32 (X86) / .code 32 (ARM) + MCAF_Code64 ///< .code64 (X86) }; } // end namespace llvm diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index ce8759a882eb..454277d6852c 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -15,6 +15,7 @@ namespace llvm { class MCInst; +class MCSubtargetInfo; class MemoryObject; class raw_ostream; class MCContext; @@ -25,8 +26,38 @@ struct EDInstInfo; /// and provides an array of assembly instructions. class MCDisassembler { public: + /// Ternary decode status. Most backends will just use Fail and + /// Success, however some have a concept of an instruction with + /// understandable semantics but which is architecturally + /// incorrect. An example of this is ARM UNPREDICTABLE instructions + /// which are disassemblable but cause undefined behaviour. + /// + /// Because it makes sense to disassemble these instructions, there + /// is a "soft fail" failure mode that indicates the MCInst& is + /// valid but architecturally incorrect. + /// + /// The enum numbers are deliberately chosen such that reduction + /// from Success->SoftFail ->Fail can be done with a simple + /// bitwise-AND: + /// + /// LEFT & TOP = | Success Unpredictable Fail + /// --------------+----------------------------------- + /// Success | Success Unpredictable Fail + /// Unpredictable | Unpredictable Unpredictable Fail + /// Fail | Fail Fail Fail + /// + /// An easy way of encoding this is as 0b11, 0b01, 0b00 for + /// Success, SoftFail, Fail respectively. + enum DecodeStatus { + Fail = 0, + SoftFail = 1, + Success = 3 + }; + /// Constructor - Performs initial setup for the disassembler. - MCDisassembler() : GetOpInfo(0), DisInfo(0), Ctx(0) {} + MCDisassembler(const MCSubtargetInfo &STI) : GetOpInfo(0), SymbolLookUp(0), + DisInfo(0), Ctx(0), + STI(STI), CommentStream(0) {} virtual ~MCDisassembler(); @@ -41,12 +72,17 @@ class MCDisassembler { /// @param address - The address, in the memory space of region, of the first /// byte of the instruction. /// @param vStream - The stream to print warnings and diagnostic messages on. - /// @return - True if the instruction is valid; false otherwise. - virtual bool getInstruction(MCInst& instr, + /// @param cStream - The stream to print comments and annotations on. + /// @return - MCDisassembler::Success if the instruction is valid, + /// MCDisassembler::SoftFail if the instruction was + /// disassemblable but invalid, + /// MCDisassembler::Fail if the instruction was invalid. + virtual DecodeStatus getInstruction(MCInst& instr, uint64_t& size, const MemoryObject ®ion, uint64_t address, - raw_ostream &vStream) const = 0; + raw_ostream &vStream, + raw_ostream &cStream) const = 0; /// getEDInfo - Returns the enhanced instruction information corresponding to /// the disassembler. @@ -62,23 +98,37 @@ class MCDisassembler { // // The function to get the symbolic information for operands. LLVMOpInfoCallback GetOpInfo; + // The function to lookup a symbol name. + LLVMSymbolLookupCallback SymbolLookUp; // The pointer to the block of symbolic information for above call back. void *DisInfo; // The assembly context for creating symbols and MCExprs in place of // immediate operands when there is symbolic information. MCContext *Ctx; +protected: + // Subtarget information, for instruction decoding predicates if required. + const MCSubtargetInfo &STI; public: void setupForSymbolicDisassembly(LLVMOpInfoCallback getOpInfo, + LLVMSymbolLookupCallback symbolLookUp, void *disInfo, MCContext *ctx) { GetOpInfo = getOpInfo; + SymbolLookUp = symbolLookUp; DisInfo = disInfo; Ctx = ctx; } LLVMOpInfoCallback getLLVMOpInfoCallback() const { return GetOpInfo; } + LLVMSymbolLookupCallback getLLVMSymbolLookupCallback() const { + return SymbolLookUp; + } void *getDisInfoBlock() const { return DisInfo; } MCContext *getMCContext() const { return Ctx; } + + // Marked mutable because we cache it inside the disassembler, rather than + // having to pass it around as an argument through all the autogenerated code. + mutable raw_ostream *CommentStream; }; } // namespace llvm diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 90c372856749..431e3c4da86a 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -16,15 +16,13 @@ #define LLVM_MC_MCDWARF_H #include "llvm/ADT/StringRef.h" -#include "llvm/CodeGen/MachineLocation.h" // FIXME +#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Dwarf.h" #include namespace llvm { - class TargetAsmInfo; - class MachineMove; class MCContext; class MCExpr; class MCSection; @@ -265,7 +263,7 @@ namespace llvm { struct MCDwarfFrameInfo { MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0), Function(0), Instructions(), PersonalityEncoding(), - LsdaEncoding(0) {} + LsdaEncoding(0), CompactUnwindEncoding(0) {} MCSymbol *Begin; MCSymbol *End; const MCSymbol *Personality; @@ -274,6 +272,7 @@ namespace llvm { std::vector Instructions; unsigned PersonalityEncoding; unsigned LsdaEncoding; + uint32_t CompactUnwindEncoding; }; class MCDwarfFrameEmitter { diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index d6ef7b4c33c1..d38476477495 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -144,6 +144,16 @@ class MCInst { Operands.push_back(Op); } + void clear() { Operands.clear(); } + size_t size() { return Operands.size(); } + + typedef SmallVector::iterator iterator; + iterator begin() { return Operands.begin(); } + iterator end() { return Operands.end(); } + iterator insert(iterator I, const MCOperand &Op) { + return Operands.insert(I, Op); + } + void print(raw_ostream &OS, const MCAsmInfo *MAI) const; void dump() const; diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h index 39002dabca14..01ad2d3f8088 100644 --- a/include/llvm/MC/MCInstPrinter.h +++ b/include/llvm/MC/MCInstPrinter.h @@ -28,6 +28,9 @@ class MCInstPrinter { /// The current set of available features. unsigned AvailableFeatures; + + /// Utility function for printing annotations. + void printAnnotation(raw_ostream &OS, StringRef Annot); public: MCInstPrinter(const MCAsmInfo &mai) : CommentStream(0), MAI(mai), AvailableFeatures(0) {} @@ -39,7 +42,8 @@ class MCInstPrinter { /// printInst - Print the specified MCInst to the specified raw_ostream. /// - virtual void printInst(const MCInst *MI, raw_ostream &OS) = 0; + virtual void printInst(const MCInst *MI, raw_ostream &OS, + StringRef Annot) = 0; /// getOpcodeName - Return the name of the specified opcode enum (e.g. /// "MOV32ri") or empty if we can't resolve it. diff --git a/include/llvm/MC/MCInstrAnalysis.h b/include/llvm/MC/MCInstrAnalysis.h new file mode 100644 index 000000000000..8f3c499b1c73 --- /dev/null +++ b/include/llvm/MC/MCInstrAnalysis.h @@ -0,0 +1,61 @@ +//===-- llvm/MC/MCInstrAnalysis.h - InstrDesc target hooks ------*- 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 MCInstrAnalysis class which the MCTargetDescs can +// derive from to give additional information to MC. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCInstrInfo.h" + +namespace llvm { + +class MCInstrAnalysis { +protected: + friend class Target; + const MCInstrInfo *Info; + +public: + MCInstrAnalysis(const MCInstrInfo *Info) : Info(Info) {} + + virtual ~MCInstrAnalysis() {} + + virtual bool isBranch(const MCInst &Inst) const { + return Info->get(Inst.getOpcode()).isBranch(); + } + + virtual bool isConditionalBranch(const MCInst &Inst) const { + return Info->get(Inst.getOpcode()).isBranch(); + } + + virtual bool isUnconditionalBranch(const MCInst &Inst) const { + return Info->get(Inst.getOpcode()).isUnconditionalBranch(); + } + + virtual bool isIndirectBranch(const MCInst &Inst) const { + return Info->get(Inst.getOpcode()).isIndirectBranch(); + } + + virtual bool isCall(const MCInst &Inst) const { + return Info->get(Inst.getOpcode()).isCall(); + } + + virtual bool isReturn(const MCInst &Inst) const { + return Info->get(Inst.getOpcode()).isReturn(); + } + + /// evaluateBranch - Given a branch instruction try to get the address the + /// branch targets. Otherwise return -1. + virtual uint64_t + evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size) const; +}; + +} diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index 49969143cd74..aafa800c1ac8 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file defines the MCOperandInfo and MCInstrDesc classes, which -// are used to describe target instructions and their operands. +// are used to describe target instructions and their operands. // //===----------------------------------------------------------------------===// @@ -22,14 +22,14 @@ namespace llvm { //===----------------------------------------------------------------------===// // Machine Operand Flags and Description //===----------------------------------------------------------------------===// - + namespace MCOI { // Operand constraints enum OperandConstraint { TIED_TO = 0, // Must be allocated the same register as. EARLY_CLOBBER // Operand is an early clobber register operand }; - + /// OperandFlags - These are flags set on operands, but should be considered /// private, all access should go through the MCOperandInfo accessors. /// See the accessors for a description of what these are. @@ -54,15 +54,15 @@ namespace MCOI { /// class MCOperandInfo { public: - /// RegClass - This specifies the register class enumeration of the operand + /// RegClass - This specifies the register class enumeration of the operand /// if the operand is a register. If isLookupPtrRegClass is set, then this is /// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to /// get a dynamic register class. short RegClass; - + /// Flags - These are flags from the MCOI::OperandFlags enum. unsigned short Flags; - + /// Lower 16 bits are used to specify which constraints are set. The higher 16 /// bits are used to specify the value of constraints (4 bits each). unsigned Constraints; @@ -70,21 +70,21 @@ class MCOperandInfo { /// OperandType - Information about the type of the operand. MCOI::OperandType OperandType; /// Currently no other information. - + /// isLookupPtrRegClass - Set if this operand is a pointer value and it /// requires a callback to look up its register class. - bool isLookupPtrRegClass() const { return Flags&(1 < AtomAllocationTracker; + + /// OffsetMap - Efficiently maps offset ranges to MCAtom's. + IntervalMap OffsetMap; + + /// BranchTargetMap - Maps offsets that are determined to be branches and + /// can be statically resolved to their target offsets. + DenseMap BranchTargetMap; + + friend class MCAtom; + + /// remap - Update the interval mapping for an MCAtom. + void remap(MCAtom *Atom, uint64_t NewBegin, uint64_t NewEnd); + +public: + MCModule(IntervalMap::Allocator &A) : OffsetMap(A) { } + + /// createAtom - Creates a new MCAtom covering the specified offset range. + MCAtom *createAtom(MCAtom::AtomType Type, uint64_t Begin, uint64_t End); +}; + +} + +#endif + diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h new file mode 100644 index 000000000000..060d5085d0c3 --- /dev/null +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -0,0 +1,294 @@ +//===-- llvm/MC/MCObjectFileInfo.h - Object File 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 describes common object file formats. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCBJECTFILEINFO_H +#define LLVM_MC_MCBJECTFILEINFO_H + +#include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/MC/SectionKind.h" + +namespace llvm { +class MCContext; +class MCSection; +class Triple; + +class MCObjectFileInfo { +protected: + /// CommDirectiveSupportsAlignment - True if .comm supports alignment. This + /// is a hack for as long as we support 10.4 Tiger, whose assembler doesn't + /// support alignment on comm. + bool CommDirectiveSupportsAlignment; + + /// SupportsWeakEmptyEHFrame - True if target object file supports a + /// weak_definition of constant 0 for an omitted EH frame. + bool SupportsWeakOmittedEHFrame; + + /// IsFunctionEHFrameSymbolPrivate - This flag is set to true if the + /// "EH_frame" symbol for EH information should be an assembler temporary (aka + /// private linkage, aka an L or .L label) or false if it should be a normal + /// non-.globl label. This defaults to true. + bool IsFunctionEHFrameSymbolPrivate; + + /// PersonalityEncoding, LSDAEncoding, FDEEncoding, TTypeEncoding - Some + /// encoding values for EH. + unsigned PersonalityEncoding; + unsigned LSDAEncoding; + unsigned FDEEncoding; + unsigned FDECFIEncoding; + unsigned TTypeEncoding; + + /// TextSection - Section directive for standard text. + /// + const MCSection *TextSection; + + /// DataSection - Section directive for standard data. + /// + const MCSection *DataSection; + + /// BSSSection - Section that is default initialized to zero. + const MCSection *BSSSection; + + /// ReadOnlySection - Section that is readonly and can contain arbitrary + /// initialized data. Targets are not required to have a readonly section. + /// If they don't, various bits of code will fall back to using the data + /// section for constants. + const MCSection *ReadOnlySection; + + /// StaticCtorSection - This section contains the static constructor pointer + /// list. + const MCSection *StaticCtorSection; + + /// StaticDtorSection - This section contains the static destructor pointer + /// list. + const MCSection *StaticDtorSection; + + /// LSDASection - If exception handling is supported by the target, this is + /// the section the Language Specific Data Area information is emitted to. + const MCSection *LSDASection; + + /// CompactUnwindSection - If exception handling is supported by the target + /// and the target can support a compact representation of the CIE and FDE, + /// this is the section to emit them into. + const MCSection *CompactUnwindSection; + + // Dwarf sections for debug info. If a target supports debug info, these must + // be set. + const MCSection *DwarfAbbrevSection; + const MCSection *DwarfInfoSection; + const MCSection *DwarfLineSection; + const MCSection *DwarfFrameSection; + const MCSection *DwarfPubNamesSection; + const MCSection *DwarfPubTypesSection; + const MCSection *DwarfDebugInlineSection; + const MCSection *DwarfStrSection; + const MCSection *DwarfLocSection; + const MCSection *DwarfARangesSection; + const MCSection *DwarfRangesSection; + const MCSection *DwarfMacroInfoSection; + + // Extra TLS Variable Data section. If the target needs to put additional + // information for a TLS variable, it'll go here. + const MCSection *TLSExtraDataSection; + + /// TLSDataSection - Section directive for Thread Local data. + /// ELF and MachO only. + const MCSection *TLSDataSection; // Defaults to ".tdata". + + /// TLSBSSSection - Section directive for Thread Local uninitialized data. + /// Null if this target doesn't support a BSS section. + /// ELF and MachO only. + const MCSection *TLSBSSSection; // Defaults to ".tbss". + + + /// EHFrameSection - EH frame section. It is initialized on demand so it + /// can be overwritten (with uniquing). + const MCSection *EHFrameSection; + + /// ELF specific sections. + /// + const MCSection *DataRelSection; + const MCSection *DataRelLocalSection; + const MCSection *DataRelROSection; + const MCSection *DataRelROLocalSection; + const MCSection *MergeableConst4Section; + const MCSection *MergeableConst8Section; + const MCSection *MergeableConst16Section; + + /// MachO specific sections. + /// + + /// TLSTLVSection - Section for thread local structure information. + /// Contains the source code name of the variable, visibility and a pointer + /// to the initial value (.tdata or .tbss). + const MCSection *TLSTLVSection; // Defaults to ".tlv". + + /// TLSThreadInitSection - Section for thread local data initialization + /// functions. + const MCSection *TLSThreadInitSection; // Defaults to ".thread_init_func". + + const MCSection *CStringSection; + const MCSection *UStringSection; + const MCSection *TextCoalSection; + const MCSection *ConstTextCoalSection; + 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; + + /// COFF specific sections. + /// + const MCSection *DrectveSection; + const MCSection *PDataSection; + const MCSection *XDataSection; + +public: + void InitMCObjectFileInfo(StringRef TT, Reloc::Model RM, CodeModel::Model CM, + MCContext &ctx); + + bool isFunctionEHFrameSymbolPrivate() const { + return IsFunctionEHFrameSymbolPrivate; + } + bool getSupportsWeakOmittedEHFrame() const { + return SupportsWeakOmittedEHFrame; + } + bool getCommDirectiveSupportsAlignment() const { + return CommDirectiveSupportsAlignment; + } + + unsigned getPersonalityEncoding() const { return PersonalityEncoding; } + unsigned getLSDAEncoding() const { return LSDAEncoding; } + unsigned getFDEEncoding(bool CFI) const { + return CFI ? FDECFIEncoding : FDEEncoding; + } + unsigned getTTypeEncoding() const { return TTypeEncoding; } + + const MCSection *getTextSection() const { return TextSection; } + const MCSection *getDataSection() const { return DataSection; } + const MCSection *getBSSSection() const { return BSSSection; } + const MCSection *getStaticCtorSection() const { return StaticCtorSection; } + const MCSection *getStaticDtorSection() const { return StaticDtorSection; } + const MCSection *getLSDASection() const { return LSDASection; } + const MCSection *getCompactUnwindSection() const{ + return CompactUnwindSection; + } + const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; } + const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; } + const MCSection *getDwarfLineSection() const { return DwarfLineSection; } + const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; } + const MCSection *getDwarfPubNamesSection() const{return DwarfPubNamesSection;} + const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSection;} + const MCSection *getDwarfDebugInlineSection() const { + return DwarfDebugInlineSection; + } + const MCSection *getDwarfStrSection() const { return DwarfStrSection; } + const MCSection *getDwarfLocSection() const { return DwarfLocSection; } + const MCSection *getDwarfARangesSection() const { return DwarfARangesSection;} + const MCSection *getDwarfRangesSection() const { return DwarfRangesSection; } + const MCSection *getDwarfMacroInfoSection() const { + return DwarfMacroInfoSection; + } + const MCSection *getTLSExtraDataSection() const { + return TLSExtraDataSection; + } + const MCSection *getTLSDataSection() const { return TLSDataSection; } + const MCSection *getTLSBSSSection() const { return TLSBSSSection; } + + /// ELF specific sections. + /// + const MCSection *getDataRelSection() const { return DataRelSection; } + const MCSection *getDataRelLocalSection() const { + return DataRelLocalSection; + } + const MCSection *getDataRelROSection() const { return DataRelROSection; } + const MCSection *getDataRelROLocalSection() const { + return DataRelROLocalSection; + } + const MCSection *getMergeableConst4Section() const { + return MergeableConst4Section; + } + const MCSection *getMergeableConst8Section() const { + return MergeableConst8Section; + } + const MCSection *getMergeableConst16Section() const { + return MergeableConst16Section; + } + + /// MachO specific sections. + /// + const MCSection *getTLSTLVSection() const { return TLSTLVSection; } + const MCSection *getTLSThreadInitSection() const { + return TLSThreadInitSection; + } + const MCSection *getCStringSection() const { return CStringSection; } + const MCSection *getUStringSection() const { return UStringSection; } + const MCSection *getTextCoalSection() const { return TextCoalSection; } + const MCSection *getConstTextCoalSection() const { + return ConstTextCoalSection; + } + const MCSection *getConstDataSection() const { return ConstDataSection; } + const MCSection *getDataCoalSection() const { return DataCoalSection; } + const MCSection *getDataCommonSection() const { return DataCommonSection; } + const MCSection *getDataBSSSection() const { return DataBSSSection; } + const MCSection *getFourByteConstantSection() const { + return FourByteConstantSection; + } + const MCSection *getEightByteConstantSection() const { + return EightByteConstantSection; + } + const MCSection *getSixteenByteConstantSection() const { + return SixteenByteConstantSection; + } + const MCSection *getLazySymbolPointerSection() const { + return LazySymbolPointerSection; + } + const MCSection *getNonLazySymbolPointerSection() const { + return NonLazySymbolPointerSection; + } + + /// COFF specific sections. + /// + const MCSection *getDrectveSection() const { return DrectveSection; } + const MCSection *getPDataSection() const { return PDataSection; } + const MCSection *getXDataSection() const { return XDataSection; } + + const MCSection *getEHFrameSection() { + if (!EHFrameSection) + InitEHFrameSection(); + return EHFrameSection; + } + +private: + enum Environment { IsMachO, IsELF, IsCOFF }; + Environment Env; + Reloc::Model RelocM; + CodeModel::Model CMModel; + MCContext *Ctx; + + void InitMachOMCObjectFileInfo(Triple T); + void InitELFMCObjectFileInfo(Triple T); + void InitCOFFMCObjectFileInfo(Triple T); + + /// InitEHFrameSection - Initialize EHFrameSection on demand. + /// + void InitEHFrameSection(); +}; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index a89933b230ef..f897e64f4456 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -19,7 +19,7 @@ class MCSectionData; class MCExpr; class MCFragment; class MCDataFragment; -class TargetAsmBackend; +class MCAsmBackend; class raw_ostream; /// \brief Streaming object file generation interface. @@ -36,9 +36,9 @@ class MCObjectStreamer : public MCStreamer { virtual void EmitInstToData(const MCInst &Inst) = 0; protected: - MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, + MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter); - MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, + MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter, MCAssembler *_Assembler); ~MCObjectStreamer(); diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h index ab78799fdcd2..dcecfb6aa012 100644 --- a/include/llvm/MC/MCParser/AsmLexer.h +++ b/include/llvm/MC/MCParser/AsmLexer.h @@ -32,6 +32,7 @@ class AsmLexer : public MCAsmLexer { const char *CurPtr; const MemoryBuffer *CurBuf; + bool isAtStartOfLine; void operator=(const AsmLexer&); // DO NOT IMPLEMENT AsmLexer(const AsmLexer&); // DO NOT IMPLEMENT @@ -47,6 +48,7 @@ class AsmLexer : public MCAsmLexer { void setBuffer(const MemoryBuffer *buf, const char *ptr = NULL); virtual StringRef LexUntilEndOfStatement(); + StringRef LexUntilEndOfLine(); bool isAtStartOfComment(char Char); bool isAtStatementSeparator(const char *Ptr); diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 47c580f85b8c..9bbb75581c25 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -17,7 +17,6 @@ namespace llvm { class MCAsmLexer; class MCInst; -class Target; /// AsmToken - Target independent representation for an assembler token. class AsmToken { @@ -36,7 +35,7 @@ class AsmToken { // Real values. Real, - // Register values (stored in IntVal). Only used by TargetAsmLexer. + // Register values (stored in IntVal). Only used by MCTargetAsmLexer. Register, // No-value. diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h index 73766930dfe1..6ff175349e43 100644 --- a/include/llvm/MC/MCParser/MCAsmParser.h +++ b/include/llvm/MC/MCParser/MCAsmParser.h @@ -20,11 +20,10 @@ class MCAsmParserExtension; class MCContext; class MCExpr; class MCStreamer; +class MCTargetAsmParser; class SMLoc; class SourceMgr; class StringRef; -class Target; -class TargetAsmParser; class Twine; /// MCAsmParser - Generic assembler parser interface, for use by target specific @@ -37,7 +36,7 @@ class MCAsmParser { MCAsmParser(const MCAsmParser &); // DO NOT IMPLEMENT void operator=(const MCAsmParser &); // DO NOT IMPLEMENT - TargetAsmParser *TargetParser; + MCTargetAsmParser *TargetParser; unsigned ShowParsedOperands : 1; @@ -60,8 +59,8 @@ class MCAsmParser { /// getStreamer - Return the output streamer for the assembler. virtual MCStreamer &getStreamer() = 0; - TargetAsmParser &getTargetParser() const { return *TargetParser; } - void setTargetParser(TargetAsmParser &P); + MCTargetAsmParser &getTargetParser() const { return *TargetParser; } + void setTargetParser(MCTargetAsmParser &P); bool getShowParsedOperands() const { return ShowParsedOperands; } void setShowParsedOperands(bool Value) { ShowParsedOperands = Value; } @@ -131,7 +130,7 @@ class MCAsmParser { }; /// \brief Create an MCAsmParser instance. -MCAsmParser *createMCAsmParser(const Target &, SourceMgr &, MCContext &, +MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, const MCAsmInfo &); } // End llvm namespace diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index caf98bb89f6b..ada5ae80af0c 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -16,10 +16,94 @@ #ifndef LLVM_MC_MCREGISTERINFO_H #define LLVM_MC_MCREGISTERINFO_H +#include "llvm/ADT/DenseMap.h" #include namespace llvm { +/// MCRegisterClass - Base class of TargetRegisterClass. +class MCRegisterClass { +public: + typedef const unsigned* iterator; + typedef const unsigned* const_iterator; +private: + unsigned ID; + const char *Name; + const unsigned RegSize, Alignment; // Size & Alignment of register in bytes + const int CopyCost; + const bool Allocatable; + const iterator RegsBegin, RegsEnd; + const unsigned char *const RegSet; + const unsigned RegSetSize; +public: + MCRegisterClass(unsigned id, const char *name, + unsigned RS, unsigned Al, int CC, bool Allocable, + iterator RB, iterator RE, const unsigned char *Bits, + unsigned NumBytes) + : ID(id), Name(name), RegSize(RS), Alignment(Al), CopyCost(CC), + Allocatable(Allocable), RegsBegin(RB), RegsEnd(RE), RegSet(Bits), + RegSetSize(NumBytes) { + for (iterator i = RegsBegin; i != RegsEnd; ++i) + assert(contains(*i) && "Bit field corrupted."); + } + + /// getID() - Return the register class ID number. + /// + unsigned getID() const { return ID; } + + /// getName() - Return the register class name for debugging. + /// + const char *getName() const { return Name; } + + /// begin/end - Return all of the registers in this class. + /// + iterator begin() const { return RegsBegin; } + iterator end() const { return RegsEnd; } + + /// getNumRegs - Return the number of registers in this class. + /// + unsigned getNumRegs() const { return (unsigned)(RegsEnd-RegsBegin); } + + /// getRegister - Return the specified register in the class. + /// + unsigned getRegister(unsigned i) const { + assert(i < getNumRegs() && "Register number out of range!"); + return RegsBegin[i]; + } + + /// contains - Return true if the specified register is included in this + /// register class. This does not include virtual registers. + bool contains(unsigned Reg) const { + unsigned InByte = Reg % 8; + unsigned Byte = Reg / 8; + if (Byte >= RegSetSize) + return false; + return (RegSet[Byte] & (1 << InByte)) != 0; + } + + /// contains - Return true if both registers are in this class. + bool contains(unsigned Reg1, unsigned Reg2) const { + return contains(Reg1) && contains(Reg2); + } + + /// getSize - Return the size of the register in bytes, which is also the size + /// of a stack slot allocated to hold a spilled copy of this register. + unsigned getSize() const { return RegSize; } + + /// getAlignment - Return the minimum required alignment for a register of + /// this class. + unsigned getAlignment() const { return Alignment; } + + /// getCopyCost - Return the cost of copying a value between two registers in + /// this class. A negative number means the register class is very expensive + /// to copy e.g. status flag register classes. + int getCopyCost() const { return CopyCost; } + + /// isAllocatable - Return true if this register class may be used to create + /// virtual registers. + bool isAllocatable() const { return Allocatable; } +}; + /// MCRegisterDesc - This record contains all of the information known about /// a particular register. The Overlaps field contains a pointer to a zero /// terminated array of registers that this register aliases, starting with @@ -50,18 +134,67 @@ struct MCRegisterDesc { /// virtual methods. /// class MCRegisterInfo { +public: + typedef const MCRegisterClass *regclass_iterator; private: - const MCRegisterDesc *Desc; // Pointer to the descriptor array - unsigned NumRegs; // Number of entries in the array + const MCRegisterDesc *Desc; // Pointer to the descriptor array + unsigned NumRegs; // Number of entries in the array + unsigned RAReg; // Return address register + const MCRegisterClass *Classes; // Pointer to the regclass array + unsigned NumClasses; // Number of entries in the array + DenseMap L2DwarfRegs; // LLVM to Dwarf regs mapping + DenseMap EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH + DenseMap Dwarf2LRegs; // Dwarf to LLVM regs mapping + DenseMap EHDwarf2LRegs; // Dwarf to LLVM regs mapping EH + DenseMap L2SEHRegs; // LLVM to SEH regs mapping public: /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen /// auto-generated routines. *DO NOT USE*. - void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR) { + void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, + const MCRegisterClass *C, unsigned NC) { Desc = D; NumRegs = NR; + RAReg = RA; + Classes = C; + NumClasses = NC; + } + + /// mapLLVMRegToDwarfReg - Used to initialize LLVM register to Dwarf + /// register number mapping. Called by TableGen auto-generated routines. + /// *DO NOT USE*. + void mapLLVMRegToDwarfReg(unsigned LLVMReg, int DwarfReg, bool isEH) { + if (isEH) + EHL2DwarfRegs[LLVMReg] = DwarfReg; + else + L2DwarfRegs[LLVMReg] = DwarfReg; } + /// mapDwarfRegToLLVMReg - Used to initialize Dwarf register to LLVM + /// register number mapping. Called by TableGen auto-generated routines. + /// *DO NOT USE*. + void mapDwarfRegToLLVMReg(unsigned DwarfReg, unsigned LLVMReg, bool isEH) { + if (isEH) + EHDwarf2LRegs[DwarfReg] = LLVMReg; + else + Dwarf2LRegs[DwarfReg] = LLVMReg; + } + + /// mapLLVMRegToSEHReg - Used to initialize LLVM register to SEH register + /// number mapping. By default the SEH register number is just the same + /// as the LLVM register number. + /// FIXME: TableGen these numbers. Currently this requires target specific + /// initialization code. + void mapLLVMRegToSEHReg(unsigned LLVMReg, int SEHReg) { + L2SEHRegs[LLVMReg] = SEHReg; + } + + /// getRARegister - This method should return the register where the return + /// address can be found. + unsigned getRARegister() const { + return RAReg; + } + const MCRegisterDesc &operator[](unsigned RegNo) const { assert(RegNo < NumRegs && "Attempting to access record for invalid register number!"); @@ -122,6 +255,51 @@ class MCRegisterInfo { unsigned getNumRegs() const { return NumRegs; } + + /// getDwarfRegNum - Map a target register to an equivalent dwarf register + /// number. Returns -1 if there is no equivalent value. The second + /// parameter allows targets to use different numberings for EH info and + /// debugging info. + int getDwarfRegNum(unsigned RegNum, bool isEH) const { + const DenseMap &M = isEH ? EHL2DwarfRegs : L2DwarfRegs; + const DenseMap::const_iterator I = M.find(RegNum); + if (I == M.end()) return -1; + return I->second; + } + + /// getLLVMRegNum - Map a dwarf register back to a target register. + /// + int getLLVMRegNum(unsigned RegNum, bool isEH) const { + const DenseMap &M = isEH ? EHDwarf2LRegs : Dwarf2LRegs; + const DenseMap::const_iterator I = M.find(RegNum); + if (I == M.end()) { + assert(0 && "Invalid RegNum"); + return -1; + } + return I->second; + } + + /// getSEHRegNum - Map a target register to an equivalent SEH register + /// number. Returns LLVM register number if there is no equivalent value. + int getSEHRegNum(unsigned RegNum) const { + const DenseMap::const_iterator I = L2SEHRegs.find(RegNum); + if (I == L2SEHRegs.end()) return (int)RegNum; + return I->second; + } + + regclass_iterator regclass_begin() const { return Classes; } + regclass_iterator regclass_end() const { return Classes+NumClasses; } + + unsigned getNumRegClasses() const { + return (unsigned)(regclass_end()-regclass_begin()); + } + + /// getRegClass - Returns the register class associated with the enumeration + /// value. See class MCOperandInfo. + const MCRegisterClass getRegClass(unsigned i) const { + assert(i < getNumRegClasses() && "Register Class ID out of range"); + return Classes[i]; + } }; } // End llvm namespace diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 7bdba5fa50b5..451efbff6e3a 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -14,13 +14,15 @@ #ifndef LLVM_MC_MCSTREAMER_H #define LLVM_MC_MCSTREAMER_H -#include "llvm/ADT/SmallVector.h" #include "llvm/Support/DataTypes.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCWin64EH.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" namespace llvm { + class MCAsmBackend; class MCAsmInfo; class MCCodeEmitter; class MCContext; @@ -30,7 +32,6 @@ namespace llvm { class MCSection; class MCSymbol; class StringRef; - class TargetAsmBackend; class TargetLoweringObjectFile; class Twine; class raw_ostream; @@ -63,14 +64,29 @@ namespace llvm { void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame); void EnsureValidW64UnwindInfo(); - const MCSymbol* LastNonPrivate; + MCSymbol* LastSymbol; /// SectionStack - This is stack of current and previous section /// values saved by PushSection. SmallVector, 4> SectionStack; + unsigned UniqueCodeBeginSuffix; + unsigned UniqueDataBeginSuffix; + protected: + /// Indicator of whether the previous data-or-code indicator was for + /// code or not. Used to determine when we need to emit a new indicator. + enum DataType { + Data, + Code, + JumpTable8, + JumpTable16, + JumpTable32 + }; + DataType RegionIndicator; + + MCStreamer(MCContext &Ctx); const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A, @@ -96,6 +112,10 @@ namespace llvm { return FrameInfos[i]; } + ArrayRef getFrameInfos() { + return FrameInfos; + } + unsigned getNumW64UnwindInfos() { return W64UnwindInfos.size(); } @@ -219,6 +239,41 @@ namespace llvm { /// used in an assignment. virtual void EmitLabel(MCSymbol *Symbol); + /// EmitDataRegion - Emit a label that marks the beginning of a data + /// region. + /// On ELF targets, this corresponds to an assembler statement such as: + /// $d.1: + virtual void EmitDataRegion(); + + /// EmitJumpTable8Region - Emit a label that marks the beginning of a + /// jump table composed of 8-bit offsets. + /// On ELF targets, this corresponds to an assembler statement such as: + /// $d.1: + virtual void EmitJumpTable8Region(); + + /// EmitJumpTable16Region - Emit a label that marks the beginning of a + /// jump table composed of 16-bit offsets. + /// On ELF targets, this corresponds to an assembler statement such as: + /// $d.1: + virtual void EmitJumpTable16Region(); + + /// EmitJumpTable32Region - Emit a label that marks the beginning of a + /// jump table composed of 32-bit offsets. + /// On ELF targets, this corresponds to an assembler statement such as: + /// $d.1: + virtual void EmitJumpTable32Region(); + + /// EmitCodeRegion - Emit a label that marks the beginning of a code + /// region. + /// On ELF targets, this corresponds to an assembler statement such as: + /// $a.1: + virtual void EmitCodeRegion(); + + /// ForceCodeRegion - Forcibly sets the current region mode to code. Used + /// at function entry points. + void ForceCodeRegion() { RegionIndicator = Code; } + + virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol); @@ -299,7 +354,9 @@ namespace llvm { /// /// @param Symbol - The common symbol to emit. /// @param Size - The size of the common symbol. - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) = 0; + /// @param ByteAlignment - The alignment of the common symbol in bytes. + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) = 0; /// EmitZerofill - Emit the zerofill section and an optional symbol. /// @@ -470,6 +527,7 @@ namespace llvm { void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label, int PointerSize); + virtual void EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding); virtual void EmitCFISections(bool EH, bool Debug); virtual void EmitCFIStartProc(); virtual void EmitCFIEndProc(); @@ -557,14 +615,14 @@ namespace llvm { bool useCFI, MCInstPrinter *InstPrint = 0, MCCodeEmitter *CE = 0, - TargetAsmBackend *TAB = 0, + MCAsmBackend *TAB = 0, bool ShowInst = false); /// createMachOStreamer - Create a machine code streamer which will generate /// Mach-O format object files. /// /// Takes ownership of \arg TAB and \arg CE. - MCStreamer *createMachOStreamer(MCContext &Ctx, TargetAsmBackend &TAB, + MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll = false); @@ -573,13 +631,13 @@ namespace llvm { /// /// Takes ownership of \arg TAB and \arg CE. MCStreamer *createWinCOFFStreamer(MCContext &Ctx, - TargetAsmBackend &TAB, + MCAsmBackend &TAB, MCCodeEmitter &CE, raw_ostream &OS, bool RelaxAll = false); /// createELFStreamer - Create a machine code streamer which will generate /// ELF format object files. - MCStreamer *createELFStreamer(MCContext &Ctx, TargetAsmBackend &TAB, + MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll, bool NoExecStack); @@ -593,7 +651,7 @@ namespace llvm { /// "pure" MC object files, for use with MC-JIT and testing tools. /// /// Takes ownership of \arg TAB and \arg CE. - MCStreamer *createPureStreamer(MCContext &Ctx, TargetAsmBackend &TAB, + MCStreamer *createPureStreamer(MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *CE); } // end namespace llvm diff --git a/include/llvm/Target/TargetAsmLexer.h b/include/llvm/MC/MCTargetAsmLexer.h similarity index 81% rename from include/llvm/Target/TargetAsmLexer.h rename to include/llvm/MC/MCTargetAsmLexer.h index 9fcf449a86cd..acb3d4d6144c 100644 --- a/include/llvm/Target/TargetAsmLexer.h +++ b/include/llvm/MC/MCTargetAsmLexer.h @@ -1,4 +1,4 @@ -//===-- llvm/Target/TargetAsmLexer.h - Target Assembly Lexer ----*- C++ -*-===// +//===-- llvm/MC/MCTargetAsmLexer.h - Target Assembly Lexer ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,16 +7,16 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_TARGETASMLEXER_H -#define LLVM_TARGET_TARGETASMLEXER_H +#ifndef LLVM_MC_MCTARGETASMLEXER_H +#define LLVM_MC_MCTARGETASMLEXER_H #include "llvm/MC/MCParser/MCAsmLexer.h" namespace llvm { class Target; -/// TargetAsmLexer - Generic interface to target specific assembly lexers. -class TargetAsmLexer { +/// MCTargetAsmLexer - Generic interface to target specific assembly lexers. +class MCTargetAsmLexer { /// The current token AsmToken CurTok; @@ -24,10 +24,10 @@ class TargetAsmLexer { SMLoc ErrLoc; std::string Err; - TargetAsmLexer(const TargetAsmLexer &); // DO NOT IMPLEMENT - void operator=(const TargetAsmLexer &); // DO NOT IMPLEMENT + MCTargetAsmLexer(const MCTargetAsmLexer &); // DO NOT IMPLEMENT + void operator=(const MCTargetAsmLexer &); // DO NOT IMPLEMENT protected: // Can only create subclasses. - TargetAsmLexer(const Target &); + MCTargetAsmLexer(const Target &); virtual AsmToken LexToken() = 0; @@ -41,7 +41,7 @@ class TargetAsmLexer { MCAsmLexer *Lexer; public: - virtual ~TargetAsmLexer(); + virtual ~MCTargetAsmLexer(); const Target &getTarget() const { return TheTarget; } diff --git a/include/llvm/Target/TargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h similarity index 75% rename from include/llvm/Target/TargetAsmParser.h rename to include/llvm/MC/MCTargetAsmParser.h index df84231eea19..4e3fd0d3a9ec 100644 --- a/include/llvm/Target/TargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -1,4 +1,4 @@ -//===-- llvm/Target/TargetAsmParser.h - Target Assembly Parser --*- C++ -*-===// +//===-- llvm/MC/MCTargetAsmParser.h - Target Assembly Parser ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_TARGETPARSER_H -#define LLVM_TARGET_TARGETPARSER_H +#ifndef LLVM_MC_TARGETPARSER_H +#define LLVM_MC_TARGETPARSER_H #include "llvm/MC/MCParser/MCAsmParserExtension.h" @@ -18,20 +18,32 @@ class StringRef; class SMLoc; class AsmToken; class MCParsedAsmOperand; +class MCInst; template class SmallVectorImpl; -/// TargetAsmParser - Generic interface to target specific assembly parsers. -class TargetAsmParser : public MCAsmParserExtension { - TargetAsmParser(const TargetAsmParser &); // DO NOT IMPLEMENT - void operator=(const TargetAsmParser &); // DO NOT IMPLEMENT +/// MCTargetAsmParser - Generic interface to target specific assembly parsers. +class MCTargetAsmParser : public MCAsmParserExtension { +public: + enum MatchResultTy { + Match_ConversionFail, + Match_InvalidOperand, + Match_MissingFeature, + Match_MnemonicFail, + Match_Success, + FIRST_TARGET_MATCH_RESULT_TY + }; + +private: + MCTargetAsmParser(const MCTargetAsmParser &); // DO NOT IMPLEMENT + void operator=(const MCTargetAsmParser &); // DO NOT IMPLEMENT protected: // Can only create subclasses. - TargetAsmParser(); - + MCTargetAsmParser(); + /// AvailableFeatures - The current set of available features. unsigned AvailableFeatures; public: - virtual ~TargetAsmParser(); + virtual ~MCTargetAsmParser(); unsigned getAvailableFeatures() const { return AvailableFeatures; } void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; } @@ -66,18 +78,24 @@ class TargetAsmParser : public MCAsmParserExtension { /// /// \param DirectiveID - the identifier token of the directive. virtual bool ParseDirective(AsmToken DirectiveID) = 0; - + /// MatchAndEmitInstruction - Recognize a series of operands of a parsed /// instruction as an actual MCInst and emit it to the specified MCStreamer. /// This returns false on success and returns true on failure to match. /// /// On failure, the target parser is responsible for emitting a diagnostic /// explaining the match failure. - virtual bool + virtual bool MatchAndEmitInstruction(SMLoc IDLoc, SmallVectorImpl &Operands, MCStreamer &Out) = 0; - + + /// checkTargetMatchPredicate - Validate the instruction match against + /// any complex target predicates not expressible via match classes. + virtual unsigned checkTargetMatchPredicate(MCInst &Inst) { + return Match_Success; + } + }; } // End llvm namespace diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h index df8dbd930bf7..8352ed183f09 100644 --- a/include/llvm/MC/MCValue.h +++ b/include/llvm/MC/MCValue.h @@ -46,16 +46,6 @@ class MCValue { /// isAbsolute - Is this an absolute (as opposed to relocatable) value. bool isAbsolute() const { return !SymA && !SymB; } - /// getAssociatedSection - For relocatable values, return the section the - /// value is associated with. - /// - /// @result - The value's associated section, or null for external or constant - /// values. - // - // FIXME: Switch to a tagged section, so this can return the tagged section - // value. - const MCSection *getAssociatedSection() const; - /// print - Print the value to the stream \arg OS. void print(raw_ostream &OS, const MCAsmInfo *MAI) const; diff --git a/include/llvm/CodeGen/MachineLocation.h b/include/llvm/MC/MachineLocation.h similarity index 91% rename from include/llvm/CodeGen/MachineLocation.h rename to include/llvm/MC/MachineLocation.h index 21951b6680b6..8ddfdbcece49 100644 --- a/include/llvm/CodeGen/MachineLocation.h +++ b/include/llvm/MC/MachineLocation.h @@ -1,4 +1,4 @@ -//===-- llvm/CodeGen/MachineLocation.h --------------------------*- C++ -*-===// +//===-- llvm/MC/MachineLocation.h -------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,8 +18,8 @@ //===----------------------------------------------------------------------===// -#ifndef LLVM_CODEGEN_MACHINELOCATION_H -#define LLVM_CODEGEN_MACHINELOCATION_H +#ifndef LLVM_MC_MACHINELOCATION_H +#define LLVM_MC_MACHINELOCATION_H namespace llvm { class MCSymbol; @@ -36,11 +36,11 @@ class MachineLocation { VirtualFP = ~0U }; MachineLocation() - : IsRegister(false), Register(0), Offset(0) {} + : IsRegister(false), Register(0), Offset(0) {} explicit MachineLocation(unsigned R) - : IsRegister(true), Register(R), Offset(0) {} + : IsRegister(true), Register(R), Offset(0) {} MachineLocation(unsigned R, int O) - : IsRegister(false), Register(R), Offset(O) {} + : IsRegister(false), Register(R), Offset(O) {} bool operator==(const MachineLocation &Other) const { return IsRegister == Other.IsRegister && Register == Other.Register && diff --git a/include/llvm/Module.h b/include/llvm/Module.h index 47d23f36c13c..8ce5ec4f1d14 100644 --- a/include/llvm/Module.h +++ b/include/llvm/Module.h @@ -50,17 +50,35 @@ template<> struct ilist_traits private: mutable ilist_node Sentinel; }; + template<> struct ilist_traits : public SymbolTableListTraits { // createSentinel is used to create a node that marks the end of the list. - static GlobalVariable *createSentinel(); - static void destroySentinel(GlobalVariable *GV) { delete GV; } + GlobalVariable *createSentinel() const { + return static_cast(&Sentinel); + } + static void destroySentinel(GlobalVariable*) {} + + GlobalVariable *provideInitialHead() const { return createSentinel(); } + GlobalVariable *ensureHead(GlobalVariable*) const { return createSentinel(); } + static void noteHead(GlobalVariable*, GlobalVariable*) {} +private: + mutable ilist_node Sentinel; }; + template<> struct ilist_traits : public SymbolTableListTraits { // createSentinel is used to create a node that marks the end of the list. - static GlobalAlias *createSentinel(); - static void destroySentinel(GlobalAlias *GA) { delete GA; } + GlobalAlias *createSentinel() const { + return static_cast(&Sentinel); + } + static void destroySentinel(GlobalAlias*) {} + + GlobalAlias *provideInitialHead() const { return createSentinel(); } + GlobalAlias *ensureHead(GlobalAlias*) const { return createSentinel(); } + static void noteHead(GlobalAlias*, GlobalAlias*) {} +private: + mutable ilist_node Sentinel; }; template<> struct ilist_traits @@ -272,10 +290,10 @@ class Module { /// the existing function. /// 4. Finally, the function exists but has the wrong prototype: return the /// function with a constantexpr cast to the right prototype. - Constant *getOrInsertFunction(StringRef Name, const FunctionType *T, + Constant *getOrInsertFunction(StringRef Name, FunctionType *T, AttrListPtr AttributeList); - Constant *getOrInsertFunction(StringRef Name, const FunctionType *T); + Constant *getOrInsertFunction(StringRef Name, FunctionType *T); /// getOrInsertFunction - Look up the specified function in the module symbol /// table. If it does not exist, add a prototype for the function and return @@ -286,14 +304,14 @@ class Module { /// clients to use. Constant *getOrInsertFunction(StringRef Name, AttrListPtr AttributeList, - const Type *RetTy, ...) END_WITH_NULL; + Type *RetTy, ...) END_WITH_NULL; /// getOrInsertFunction - Same as above, but without the attributes. - Constant *getOrInsertFunction(StringRef Name, const Type *RetTy, ...) + Constant *getOrInsertFunction(StringRef Name, Type *RetTy, ...) END_WITH_NULL; Constant *getOrInsertTargetIntrinsic(StringRef Name, - const FunctionType *Ty, + FunctionType *Ty, AttrListPtr AttributeList); /// getFunction - Look up the specified function in the module symbol table. @@ -325,7 +343,7 @@ class Module { /// with a constantexpr cast to the right type. /// 3. Finally, if the existing global is the correct declaration, return /// the existing global. - Constant *getOrInsertGlobal(StringRef Name, const Type *Ty); + Constant *getOrInsertGlobal(StringRef Name, Type *Ty); /// @} /// @name Global Alias Accessors diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h new file mode 100644 index 000000000000..4f081206c5bc --- /dev/null +++ b/include/llvm/Object/Archive.h @@ -0,0 +1,90 @@ +//===- Archive.h - ar archive 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 declares the ar archive file format class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_ARCHIVE_H +#define LLVM_OBJECT_ARCHIVE_H + +#include "llvm/Object/Binary.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { +namespace object { + +class Archive : public Binary { +public: + class Child { + const Archive *Parent; + StringRef Data; + + public: + Child(const Archive *p, StringRef d) : Parent(p), Data(d) {} + + bool operator ==(const Child &other) const { + return (Parent == other.Parent) && (Data.begin() == other.Data.begin()); + } + + Child getNext() const; + error_code getName(StringRef &Result) const; + int getLastModified() const; + int getUID() const; + int getGID() const; + int getAccessMode() const; + ///! Return the size of the archive member without the header or padding. + uint64_t getSize() const; + + MemoryBuffer *getBuffer() const; + error_code getAsBinary(OwningPtr &Result) const; + }; + + class child_iterator { + Child child; + public: + child_iterator(const Child &c) : child(c) {} + const Child* operator->() const { + return &child; + } + + bool operator==(const child_iterator &other) const { + return child == other.child; + } + + bool operator!=(const child_iterator &other) const { + return !(*this == other); + } + + child_iterator& operator++() { // Preincrement + child = child.getNext(); + return *this; + } + }; + + Archive(MemoryBuffer *source, error_code &ec); + + child_iterator begin_children() const; + child_iterator end_children() const; + + // Cast methods. + static inline bool classof(Archive const *v) { return true; } + static inline bool classof(Binary const *v) { + return v->getType() == Binary::isArchive; + } + +private: + child_iterator StringTable; +}; + +} +} + +#endif diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 121f9e850451..067bcd471ae9 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -67,6 +67,12 @@ struct coff_section { support::ulittle32_t Characteristics; }; +struct coff_relocation { + support::ulittle32_t VirtualAddress; + support::ulittle32_t SymbolTableIndex; + support::ulittle16_t Type; +}; + class COFFObjectFile : public ObjectFile { private: const coff_file_header *Header; @@ -78,26 +84,52 @@ class COFFObjectFile : public ObjectFile { error_code getSection(int32_t index, const coff_section *&Res) const; error_code getString(uint32_t offset, StringRef &Res) const; + error_code getSymbol(uint32_t index, + const coff_symbol *&Res) const; const coff_symbol *toSymb(DataRefImpl Symb) const; const coff_section *toSec(DataRefImpl Sec) const; + const coff_relocation *toRel(DataRefImpl Rel) const; protected: virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; + virtual error_code getSymbolOffset(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const; + virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const; + virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::SymbolType &Res) const; virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; + virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const; virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const; + virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; + virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const; + + virtual error_code getRelocationNext(DataRefImpl Rel, + RelocationRef &Res) const; + virtual error_code getRelocationAddress(DataRefImpl Rel, + uint64_t &Res) const; + virtual error_code getRelocationSymbol(DataRefImpl Rel, + SymbolRef &Res) const; + virtual error_code getRelocationType(DataRefImpl Rel, + uint32_t &Res) const; + virtual error_code getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl &Result) const; + virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, + int64_t &Res) const; + virtual error_code getRelocationValueString(DataRefImpl Rel, + SmallVectorImpl &Result) const; public: COFFObjectFile(MemoryBuffer *Object, error_code &ec); diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h new file mode 100644 index 000000000000..f5e7461a488a --- /dev/null +++ b/include/llvm/Object/MachO.h @@ -0,0 +1,106 @@ +//===- MachO.h - MachO object file implementation ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the MachOObjectFile class, which binds the MachOObject +// class to the generic ObjectFile wrapper. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_MACHO_H +#define LLVM_OBJECT_MACHO_H + +#include "llvm/Object/ObjectFile.h" +#include "llvm/Object/MachOObject.h" +#include "llvm/Support/MachO.h" +#include "llvm/ADT/SmallVector.h" + +namespace llvm { +namespace object { + +typedef MachOObject::LoadCommandInfo LoadCommandInfo; + +class MachOObjectFile : public ObjectFile { +public: + MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, error_code &ec); + + virtual symbol_iterator begin_symbols() const; + virtual symbol_iterator end_symbols() const; + virtual section_iterator begin_sections() const; + virtual section_iterator end_sections() const; + + virtual uint8_t getBytesInAddress() const; + virtual StringRef getFileFormatName() const; + virtual unsigned getArch() const; + +protected: + virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; + virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; + virtual error_code getSymbolOffset(DataRefImpl Symb, uint64_t &Res) const; + virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; + virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; + virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; + virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const; + virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const; + virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::SymbolType &Res) const; + + virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; + virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; + virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; + virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; + virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; + virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const; + virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; + virtual error_code sectionContainsSymbol(DataRefImpl DRI, DataRefImpl S, + bool &Result) const; + virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; + virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const; + + virtual error_code getRelocationNext(DataRefImpl Rel, + RelocationRef &Res) const; + virtual error_code getRelocationAddress(DataRefImpl Rel, + uint64_t &Res) const; + virtual error_code getRelocationSymbol(DataRefImpl Rel, + SymbolRef &Res) const; + virtual error_code getRelocationType(DataRefImpl Rel, + uint32_t &Res) const; + virtual error_code getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl &Result) const; + virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, + int64_t &Res) const; + virtual error_code getRelocationValueString(DataRefImpl Rel, + SmallVectorImpl &Result) const; + +private: + MachOObject *MachOObj; + mutable uint32_t RegisteredStringTable; + typedef SmallVector SectionList; + SectionList Sections; + + + void moveToNextSection(DataRefImpl &DRI) const; + void getSymbolTableEntry(DataRefImpl DRI, + InMemoryStruct &Res) const; + void getSymbol64TableEntry(DataRefImpl DRI, + InMemoryStruct &Res) const; + void moveToNextSymbol(DataRefImpl &DRI) const; + void getSection(DataRefImpl DRI, InMemoryStruct &Res) const; + void getSection64(DataRefImpl DRI, + InMemoryStruct &Res) const; + void getRelocation(DataRefImpl Rel, + InMemoryStruct &Res) const; + std::size_t getSectionIndex(DataRefImpl Sec) const; +}; + +} +} + +#endif + diff --git a/include/llvm/Object/MachOFormat.h b/include/llvm/Object/MachOFormat.h index 31cd523ea219..089cde92a0a3 100644 --- a/include/llvm/Object/MachOFormat.h +++ b/include/llvm/Object/MachOFormat.h @@ -137,7 +137,10 @@ namespace macho { LCT_Symtab = 0x2, LCT_Dysymtab = 0xb, LCT_Segment64 = 0x19, - LCT_UUID = 0x1b + LCT_UUID = 0x1b, + LCT_CodeSignature = 0x1d, + LCT_SegmentSplitInfo = 0x1e, + LCT_FunctionStarts = 0x26 }; /// \brief Load command structure. @@ -218,6 +221,13 @@ namespace macho { uint32_t NumLocalRelocationTableEntries; }; + struct LinkeditDataLoadCommand { + uint32_t Type; + uint32_t Size; + uint32_t DataOffset; + uint32_t DataSize; + }; + /// @} /// @name Section Data /// @{ diff --git a/include/llvm/Object/MachOObject.h b/include/llvm/Object/MachOObject.h index 19a399e62fe3..51be847858a1 100644 --- a/include/llvm/Object/MachOObject.h +++ b/include/llvm/Object/MachOObject.h @@ -150,6 +150,9 @@ class MachOObject { void ReadDysymtabLoadCommand( const LoadCommandInfo &LCI, InMemoryStruct &Res) const; + void ReadLinkeditDataLoadCommand( + const LoadCommandInfo &LCI, + InMemoryStruct &Res) const; void ReadIndirectSymbolTableEntry( const macho::DysymtabLoadCommand &DLC, unsigned Index, @@ -171,6 +174,7 @@ class MachOObject { void ReadSymbol64TableEntry( uint64_t SymbolTableOffset, unsigned Index, InMemoryStruct &Res) const; + void ReadULEB128s(uint64_t Index, SmallVectorImpl &Out) const; /// @} diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 98ac0672796f..83854a0d6c28 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -27,34 +27,57 @@ namespace object { class ObjectFile; union DataRefImpl { + struct { + // ELF needs this for relocations. This entire union should probably be a + // char[max(8, sizeof(uintptr_t))] and require the impl to cast. + uint16_t a, b; + uint32_t c; + } w; struct { uint32_t a, b; } d; uintptr_t p; }; +template +class content_iterator { + content_type Current; +public: + content_iterator(content_type symb) + : Current(symb) {} + + const content_type* operator->() const { + return &Current; + } + + const content_type &operator*() const { + return Current; + } + + bool operator==(const content_iterator &other) const { + return Current == other.Current; + } + + bool operator!=(const content_iterator &other) const { + return !(*this == other); + } + + content_iterator& increment(error_code &err) { + content_type next; + if (error_code ec = Current.getNext(next)) + err = ec; + else + Current = next; + return *this; + } +}; + static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) { // Check bitwise identical. This is the only legal way to compare a union w/o // knowing which member is in use. return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0; } -class RelocationRef { - DataRefImpl RelocationPimpl; - const ObjectFile *OwningObject; - -public: - RelocationRef() : OwningObject(NULL) { - std::memset(&RelocationPimpl, 0, sizeof(RelocationPimpl)); - } - - RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner); - - bool operator==(const RelocationRef &Other) const; - - error_code getNext(RelocationRef &Result); -}; - /// SymbolRef - This is a value type class that represents a single symbol in /// the list of symbols in the object file. class SymbolRef { @@ -67,6 +90,13 @@ class SymbolRef { std::memset(&SymbolPimpl, 0, sizeof(SymbolPimpl)); } + enum SymbolType { + ST_Function, + ST_Data, + ST_External, // Defined in another object file + ST_Other + }; + SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner); bool operator==(const SymbolRef &Other) const; @@ -75,7 +105,9 @@ class SymbolRef { error_code getName(StringRef &Result) const; error_code getAddress(uint64_t &Result) const; + error_code getOffset(uint64_t &Result) const; error_code getSize(uint64_t &Result) const; + error_code getSymbolType(SymbolRef::SymbolType &Result) const; /// Returns the ascii char that should be displayed in a symbol table dump via /// nm for this symbol. @@ -84,7 +116,49 @@ class SymbolRef { /// Returns true for symbols that are internal to the object file format such /// as section symbols. error_code isInternal(bool &Result) const; + + /// Returns true for symbols that can be used in another objects, + /// such as library functions + error_code isGlobal(bool &Result) const; + + DataRefImpl getRawDataRefImpl() const; }; +typedef content_iterator symbol_iterator; + +/// RelocationRef - This is a value type class that represents a single +/// relocation in the list of relocations in the object file. +class RelocationRef { + DataRefImpl RelocationPimpl; + const ObjectFile *OwningObject; + +public: + RelocationRef() : OwningObject(NULL) { + std::memset(&RelocationPimpl, 0, sizeof(RelocationPimpl)); + } + + RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner); + + bool operator==(const RelocationRef &Other) const; + + error_code getNext(RelocationRef &Result) const; + + error_code getAddress(uint64_t &Result) const; + error_code getSymbol(SymbolRef &Result) const; + error_code getType(uint32_t &Result) const; + + /// @brief Get a string that represents the type of this relocation. + /// + /// This is for display purposes only. + error_code getTypeName(SmallVectorImpl &Result) const; + error_code getAdditionalInfo(int64_t &Result) const; + + /// @brief Get a string that represents the calculation of the value of this + /// relocation. + /// + /// This is for display purposes only. + error_code getValueString(SmallVectorImpl &Result) const; +}; +typedef content_iterator relocation_iterator; /// SectionRef - This is a value type class that represents a single section in /// the list of sections in the object file. @@ -109,11 +183,20 @@ class SectionRef { error_code getSize(uint64_t &Result) const; error_code getContents(StringRef &Result) const; + /// @brief Get the alignment of this section as the actual value (not log 2). + error_code getAlignment(uint64_t &Result) const; + // FIXME: Move to the normalization layer when it's created. error_code isText(bool &Result) const; + error_code isData(bool &Result) const; + error_code isBSS(bool &Result) const; error_code containsSymbol(SymbolRef S, bool &Result) const; + + relocation_iterator begin_relocations() const; + relocation_iterator end_relocations() const; }; +typedef content_iterator section_iterator; const uint64_t UnknownAddressOrSize = ~0ULL; @@ -144,9 +227,12 @@ class ObjectFile : public Binary { virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0; virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0; virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const =0; + virtual error_code getSymbolOffset(DataRefImpl Symb, uint64_t &Res) const =0; virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0; virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0; virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const = 0; + virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const = 0; + virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::SymbolType &Res) const = 0; // Same as above for SectionRef. friend class SectionRef; @@ -155,47 +241,34 @@ class ObjectFile : public Binary { virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0; virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0; virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)const=0; + virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res)const=0; virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0; + virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0; + virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const = 0; + virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const = 0; + virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const = 0; + // Same as above for RelocationRef. + friend class RelocationRef; + virtual error_code getRelocationNext(DataRefImpl Rel, + RelocationRef &Res) const = 0; + virtual error_code getRelocationAddress(DataRefImpl Rel, + uint64_t &Res) const =0; + virtual error_code getRelocationSymbol(DataRefImpl Rel, + SymbolRef &Res) const = 0; + virtual error_code getRelocationType(DataRefImpl Rel, + uint32_t &Res) const = 0; + virtual error_code getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl &Result) const = 0; + virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, + int64_t &Res) const = 0; + virtual error_code getRelocationValueString(DataRefImpl Rel, + SmallVectorImpl &Result) const = 0; + public: - template - class content_iterator { - content_type Current; - public: - content_iterator(content_type symb) - : Current(symb) {} - - const content_type* operator->() const { - return &Current; - } - - const content_type &operator*() const { - return Current; - } - - bool operator==(const content_iterator &other) const { - return Current == other.Current; - } - - bool operator!=(const content_iterator &other) const { - return !(*this == other); - } - - content_iterator& increment(error_code &err) { - content_type next; - if (error_code ec = Current.getNext(next)) - err = ec; - else - Current = next; - return *this; - } - }; - - typedef content_iterator symbol_iterator; - typedef content_iterator section_iterator; virtual symbol_iterator begin_symbols() const = 0; virtual symbol_iterator end_symbols() const = 0; @@ -250,6 +323,10 @@ inline error_code SymbolRef::getAddress(uint64_t &Result) const { return OwningObject->getSymbolAddress(SymbolPimpl, Result); } +inline error_code SymbolRef::getOffset(uint64_t &Result) const { + return OwningObject->getSymbolOffset(SymbolPimpl, Result); +} + inline error_code SymbolRef::getSize(uint64_t &Result) const { return OwningObject->getSymbolSize(SymbolPimpl, Result); } @@ -262,6 +339,18 @@ inline error_code SymbolRef::isInternal(bool &Result) const { return OwningObject->isSymbolInternal(SymbolPimpl, Result); } +inline error_code SymbolRef::isGlobal(bool &Result) const { + return OwningObject->isSymbolGlobal(SymbolPimpl, Result); +} + +inline error_code SymbolRef::getSymbolType(SymbolRef::SymbolType &Result) const { + return OwningObject->getSymbolType(SymbolPimpl, Result); +} + +inline DataRefImpl SymbolRef::getRawDataRefImpl() const { + return SymbolPimpl; +} + /// SectionRef inline SectionRef::SectionRef(DataRefImpl SectionP, @@ -293,15 +382,76 @@ inline error_code SectionRef::getContents(StringRef &Result) const { return OwningObject->getSectionContents(SectionPimpl, Result); } +inline error_code SectionRef::getAlignment(uint64_t &Result) const { + return OwningObject->getSectionAlignment(SectionPimpl, Result); +} + inline error_code SectionRef::isText(bool &Result) const { return OwningObject->isSectionText(SectionPimpl, Result); } +inline error_code SectionRef::isData(bool &Result) const { + return OwningObject->isSectionData(SectionPimpl, Result); +} + +inline error_code SectionRef::isBSS(bool &Result) const { + return OwningObject->isSectionBSS(SectionPimpl, Result); +} + inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const { return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl, Result); } +inline relocation_iterator SectionRef::begin_relocations() const { + return OwningObject->getSectionRelBegin(SectionPimpl); +} + +inline relocation_iterator SectionRef::end_relocations() const { + return OwningObject->getSectionRelEnd(SectionPimpl); +} + + +/// RelocationRef +inline RelocationRef::RelocationRef(DataRefImpl RelocationP, + const ObjectFile *Owner) + : RelocationPimpl(RelocationP) + , OwningObject(Owner) {} + +inline bool RelocationRef::operator==(const RelocationRef &Other) const { + return RelocationPimpl == Other.RelocationPimpl; +} + +inline error_code RelocationRef::getNext(RelocationRef &Result) const { + return OwningObject->getRelocationNext(RelocationPimpl, Result); +} + +inline error_code RelocationRef::getAddress(uint64_t &Result) const { + return OwningObject->getRelocationAddress(RelocationPimpl, Result); +} + +inline error_code RelocationRef::getSymbol(SymbolRef &Result) const { + return OwningObject->getRelocationSymbol(RelocationPimpl, Result); +} + +inline error_code RelocationRef::getType(uint32_t &Result) const { + return OwningObject->getRelocationType(RelocationPimpl, Result); +} + +inline error_code RelocationRef::getTypeName(SmallVectorImpl &Result) + const { + return OwningObject->getRelocationTypeName(RelocationPimpl, Result); +} + +inline error_code RelocationRef::getAdditionalInfo(int64_t &Result) const { + return OwningObject->getRelocationAdditionalInfo(RelocationPimpl, Result); +} + +inline error_code RelocationRef::getValueString(SmallVectorImpl &Result) + const { + return OwningObject->getRelocationValueString(RelocationPimpl, Result); +} + } // end namespace object } // end namespace llvm diff --git a/include/llvm/OperandTraits.h b/include/llvm/OperandTraits.h index f0df5fa9bde8..3d8dc329b39f 100644 --- a/include/llvm/OperandTraits.h +++ b/include/llvm/OperandTraits.h @@ -136,45 +136,8 @@ CLASS::const_op_iterator CLASS::op_end() const { \ VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \ assert(i_nocapture < OperandTraits::operands(this) \ && "getOperand() out of range!"); \ - return static_cast( \ - OperandTraits::op_begin(const_cast(this))[i_nocapture]); \ -} \ -void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \ - assert(i_nocapture < OperandTraits::operands(this) \ - && "setOperand() out of range!"); \ - OperandTraits::op_begin(this)[i_nocapture] = Val_nocapture; \ -} \ -unsigned CLASS::getNumOperands() const { \ - return OperandTraits::operands(this); \ -} \ -template Use &CLASS::Op() { \ - return this->OpFrom(this); \ -} \ -template const Use &CLASS::Op() const { \ - return this->OpFrom(this); \ -} - - -/// Macro for generating out-of-class operand accessor -/// definitions with casted result -#define DEFINE_TRANSPARENT_CASTED_OPERAND_ACCESSORS(CLASS, VALUECLASS) \ -CLASS::op_iterator CLASS::op_begin() { \ - return OperandTraits::op_begin(this); \ -} \ -CLASS::const_op_iterator CLASS::op_begin() const { \ - return OperandTraits::op_begin(const_cast(this)); \ -} \ -CLASS::op_iterator CLASS::op_end() { \ - return OperandTraits::op_end(this); \ -} \ -CLASS::const_op_iterator CLASS::op_end() const { \ - return OperandTraits::op_end(const_cast(this)); \ -} \ -VALUECLASS *CLASS::getOperand(unsigned i_nocapture) const { \ - assert(i_nocapture < OperandTraits::operands(this) \ - && "getOperand() out of range!"); \ - return cast( \ - OperandTraits::op_begin(const_cast(this))[i_nocapture]); \ + return cast_or_null( \ + OperandTraits::op_begin(const_cast(this))[i_nocapture].get()); \ } \ void CLASS::setOperand(unsigned i_nocapture, VALUECLASS *Val_nocapture) { \ assert(i_nocapture < OperandTraits::operands(this) \ diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h index e9aa4997f285..48a5796383b4 100644 --- a/include/llvm/Operator.h +++ b/include/llvm/Operator.h @@ -261,8 +261,8 @@ class GEPOperator /// getPointerOperandType - Method to return the pointer operand as a /// PointerType. - const PointerType *getPointerOperandType() const { - return reinterpret_cast(getPointerOperand()->getType()); + PointerType *getPointerOperandType() const { + return reinterpret_cast(getPointerOperand()->getType()); } unsigned getNumIndices() const { // Note: always non-negative diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h index c4f409ef525c..c05347da7934 100644 --- a/include/llvm/PassManagers.h +++ b/include/llvm/PassManagers.h @@ -263,7 +263,7 @@ class PMTopLevelManager { class PMDataManager { public: - explicit PMDataManager(int Depth) : TPM(NULL), Depth(Depth) { + explicit PMDataManager() : TPM(NULL), Depth(0) { initializeAnalysisInfo(); } @@ -333,6 +333,7 @@ class PMDataManager { void setTopLevelManager(PMTopLevelManager *T) { TPM = T; } unsigned getDepth() const { return Depth; } + void setDepth(unsigned newDepth) { Depth = newDepth; } // Print routines used by debug-pass void dumpLastUses(Pass *P, unsigned Offset) const; @@ -408,8 +409,8 @@ class PMDataManager { class FPPassManager : public ModulePass, public PMDataManager { public: static char ID; - explicit FPPassManager(int Depth) - : ModulePass(ID), PMDataManager(Depth) { } + explicit FPPassManager() + : ModulePass(ID), PMDataManager() { } /// run - Execute all of the passes scheduled for execution. Keep track of /// whether any of the passes modifies the module, and if so, return true. diff --git a/include/llvm/Support/BlockFrequency.h b/include/llvm/Support/BlockFrequency.h new file mode 100644 index 000000000000..554b7845696d --- /dev/null +++ b/include/llvm/Support/BlockFrequency.h @@ -0,0 +1,63 @@ +//===-------- BlockFrequency.h - Block Frequency Wrapper --------*- 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 Block Frequency class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_BLOCKFREQUENCY_H +#define LLVM_SUPPORT_BLOCKFREQUENCY_H + +namespace llvm { + +class raw_ostream; +class BranchProbability; + +// This class represents Block Frequency as a 64-bit value. +class BlockFrequency { + + uint64_t Frequency; + static const int64_t ENTRY_FREQ = 1024; + +public: + BlockFrequency(uint64_t Freq = 0) : Frequency(Freq) { } + + static uint64_t getEntryFrequency() { return ENTRY_FREQ; } + uint64_t getFrequency() const { return Frequency; } + + BlockFrequency &operator*=(const BranchProbability &Prob); + const BlockFrequency operator*(const BranchProbability &Prob) const; + + BlockFrequency &operator+=(const BlockFrequency &Freq); + const BlockFrequency operator+(const BlockFrequency &Freq) const; + + bool operator<(const BlockFrequency &RHS) const { + return Frequency < RHS.Frequency; + } + + bool operator<=(const BlockFrequency &RHS) const { + return Frequency <= RHS.Frequency; + } + + bool operator>(const BlockFrequency &RHS) const { + return Frequency > RHS.Frequency; + } + + bool operator>=(const BlockFrequency &RHS) const { + return Frequency >= RHS.Frequency; + } + + void print(raw_ostream &OS) const; +}; + +raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq); + +} + +#endif diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h index 2e81490ebf66..05c24d4fcfcb 100644 --- a/include/llvm/Support/BranchProbability.h +++ b/include/llvm/Support/BranchProbability.h @@ -1,4 +1,4 @@ -//===- BranchProbability.h - Branch Probability Analysis --------*- C++ -*-===// +//===- BranchProbability.h - Branch Probability Wrapper ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -34,13 +34,13 @@ class BranchProbability { uint32_t getNumerator() const { return N; } uint32_t getDenominator() const { return D; } - + // Return (1 - Probability). BranchProbability getCompl() { return BranchProbability(D - N, D); } - raw_ostream &print(raw_ostream &OS) const; + void print(raw_ostream &OS) const; void dump() const; }; diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h index 8a998a8cd0d1..04b8c4e69c52 100644 --- a/include/llvm/Support/CallSite.h +++ b/include/llvm/Support/CallSite.h @@ -147,7 +147,7 @@ class CallSiteBase { /// getType - Return the type of the instruction that generated this call site /// - const Type *getType() const { return (*this)->getType(); } + Type *getType() const { return (*this)->getType(); } /// getCaller - Return the caller function for this call site /// diff --git a/include/llvm/Support/Capacity.h b/include/llvm/Support/Capacity.h new file mode 100644 index 000000000000..d8cda43b3576 --- /dev/null +++ b/include/llvm/Support/Capacity.h @@ -0,0 +1,30 @@ +//===--- Capacity.h - Generic computation of ADT memory use -----*- 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 capacity function that computes the amount of +// memory used by an ADT. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_CAPACITY_H +#define LLVM_SUPPORT_CAPACITY_H + +namespace llvm { + +template +static inline size_t capacity_in_bytes(const T &x) { + // This default definition of capacity should work for things like std::vector + // and friends. More specialized versions will work for others. + return x.capacity() * sizeof(typename T::value_type); +} + +} // end namespace llvm + +#endif + diff --git a/include/llvm/Support/CodeGen.h b/include/llvm/Support/CodeGen.h new file mode 100644 index 000000000000..41351dc73f3b --- /dev/null +++ b/include/llvm/Support/CodeGen.h @@ -0,0 +1,32 @@ +//===-- llvm/Support/CodeGen.h - CodeGen Concepts ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file define some types which define code generation concepts. For +// example, relocation model. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_CODEGEN_H +#define LLVM_SUPPORT_CODEGEN_H + +namespace llvm { + + // Relocation model types. + namespace Reloc { + enum Model { Default, Static, PIC_, DynamicNoPIC }; + } + + // Code model types. + namespace CodeModel { + enum Model { Default, JITDefault, Small, Kernel, Medium, Large }; + } + +} // end llvm namespace + +#endif diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h index d6098711a07a..c6b62a8df9a4 100644 --- a/include/llvm/Support/CommandLine.h +++ b/include/llvm/Support/CommandLine.h @@ -59,6 +59,15 @@ void ParseEnvironmentOptions(const char *progName, const char *envvar, /// CommandLine utilities to print their own version string. void SetVersionPrinter(void (*func)()); +///===---------------------------------------------------------------------===// +/// AddExtraVersionPrinter - Add an extra printer to use in addition to the +/// default one. This can be called multiple times, +/// and each time it adds a new function to the list +/// which will be called after the basic LLVM version +/// printing is complete. Each can then add additional +/// information specific to the tool. +void AddExtraVersionPrinter(void (*func)()); + // PrintOptionValues - Print option values. // With -print-options print the difference between option values and defaults. @@ -796,6 +805,28 @@ class parser : public basic_parser { EXTERN_TEMPLATE_INSTANTIATION(class basic_parser); +//-------------------------------------------------- +// parser +// +template<> +class parser : public basic_parser { +public: + // parse - Return true on error. + bool parse(Option &O, StringRef ArgName, StringRef Arg, + unsigned long long &Val); + + // getValueName - Overload in subclass to provide a better default value. + virtual const char *getValueName() const { return "uint"; } + + void printOptionDiff(const Option &O, unsigned long long V, OptVal Default, + size_t GlobalWidth) const; + + // An out-of-line virtual method to provide a 'home' for this class. + virtual void anchor(); +}; + +EXTERN_TEMPLATE_INSTANTIATION(class basic_parser); + //-------------------------------------------------- // parser // diff --git a/include/llvm/Support/ConstantFolder.h b/include/llvm/Support/ConstantFolder.h index 733023566a6f..93aa3436d273 100644 --- a/include/llvm/Support/ConstantFolder.h +++ b/include/llvm/Support/ConstantFolder.h @@ -118,22 +118,34 @@ class ConstantFolder { // Memory Instructions //===--------------------------------------------------------------------===// - Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx); + Constant *CreateGetElementPtr(Constant *C, + ArrayRef IdxList) const { + return ConstantExpr::getGetElementPtr(C, IdxList); } - Constant *CreateGetElementPtr(Constant *C, Value* const *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx); + Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef or + // ArrayRef. + return ConstantExpr::getGetElementPtr(C, Idx); + } + Constant *CreateGetElementPtr(Constant *C, + ArrayRef IdxList) const { + return ConstantExpr::getGetElementPtr(C, IdxList); } - Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx); + Constant *CreateInBoundsGetElementPtr(Constant *C, + ArrayRef IdxList) const { + return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); } - Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx); + Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef or + // ArrayRef. + return ConstantExpr::getInBoundsGetElementPtr(C, Idx); + } + Constant *CreateInBoundsGetElementPtr(Constant *C, + ArrayRef IdxList) const { + return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); } //===--------------------------------------------------------------------===// @@ -141,37 +153,37 @@ class ConstantFolder { //===--------------------------------------------------------------------===// Constant *CreateCast(Instruction::CastOps Op, Constant *C, - const Type *DestTy) const { + Type *DestTy) const { return ConstantExpr::getCast(Op, C, DestTy); } - Constant *CreatePointerCast(Constant *C, const Type *DestTy) const { + Constant *CreatePointerCast(Constant *C, Type *DestTy) const { return ConstantExpr::getPointerCast(C, DestTy); } - Constant *CreateIntCast(Constant *C, const Type *DestTy, + Constant *CreateIntCast(Constant *C, Type *DestTy, bool isSigned) const { return ConstantExpr::getIntegerCast(C, DestTy, isSigned); } - Constant *CreateFPCast(Constant *C, const Type *DestTy) const { + Constant *CreateFPCast(Constant *C, Type *DestTy) const { return ConstantExpr::getFPCast(C, DestTy); } - Constant *CreateBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateBitCast(Constant *C, Type *DestTy) const { return CreateCast(Instruction::BitCast, C, DestTy); } - Constant *CreateIntToPtr(Constant *C, const Type *DestTy) const { + Constant *CreateIntToPtr(Constant *C, Type *DestTy) const { return CreateCast(Instruction::IntToPtr, C, DestTy); } - Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const { + Constant *CreatePtrToInt(Constant *C, Type *DestTy) const { return CreateCast(Instruction::PtrToInt, C, DestTy); } - Constant *CreateZExtOrBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { return ConstantExpr::getZExtOrBitCast(C, DestTy); } - Constant *CreateSExtOrBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { return ConstantExpr::getSExtOrBitCast(C, DestTy); } - Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { return ConstantExpr::getTruncOrBitCast(C, DestTy); } diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h new file mode 100644 index 000000000000..506ec96930d9 --- /dev/null +++ b/include/llvm/Support/DataExtractor.h @@ -0,0 +1,352 @@ +//===-- DataExtractor.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_DATAEXTRACTOR_H +#define LLVM_SUPPORT_DATAEXTRACTOR_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { +class DataExtractor { + StringRef Data; + uint8_t IsLittleEndian; + uint8_t PointerSize; +public: + /// Construct with a buffer that is owned by the caller. + /// + /// This constructor allows us to use data that is owned by the + /// caller. The data must stay around as long as this object is + /// valid. + DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t PointerSize) + : Data(Data), IsLittleEndian(IsLittleEndian), PointerSize(PointerSize) {} + + /// getData - Get the data pointed to by this extractor. + StringRef getData() const { return Data; } + /// isLittleEndian - Get the endianess for this extractor. + bool isLittleEndian() const { return IsLittleEndian; } + /// getAddressSize - Get the address size for this extractor. + uint8_t getAddressSize() const { return PointerSize; } + + /// Extract a C string from \a *offset_ptr. + /// + /// Returns a pointer to a C String from the data at the offset + /// pointed to by \a offset_ptr. A variable length NULL terminated C + /// string will be extracted and the \a offset_ptr will be + /// updated with the offset of the byte that follows the NULL + /// terminator byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// A pointer to the C string value in the data. If the offset + /// pointed to by \a offset_ptr is out of bounds, or if the + /// offset plus the length of the C string is out of bounds, + /// NULL will be returned. + const char *getCStr(uint32_t *offset_ptr) const; + + /// Extract an unsigned integer of size \a byte_size from \a + /// *offset_ptr. + /// + /// Extract a single unsigned integer value and update the offset + /// pointed to by \a offset_ptr. The size of the extracted integer + /// is specified by the \a byte_size argument. \a byte_size should + /// have a value greater than or equal to one and less than or equal + /// to eight since the return value is 64 bits wide. Any + /// \a byte_size values less than 1 or greater than 8 will result in + /// nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in byte of the integer to extract. + /// + /// @return + /// The unsigned integer value that was extracted, or zero on + /// failure. + uint64_t getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const; + + /// Extract an signed integer of size \a byte_size from \a *offset_ptr. + /// + /// Extract a single signed integer value (sign extending if required) + /// and update the offset pointed to by \a offset_ptr. The size of + /// the extracted integer is specified by the \a byte_size argument. + /// \a byte_size should have a value greater than or equal to one + /// and less than or equal to eight since the return value is 64 + /// bits wide. Any \a byte_size values less than 1 or greater than + /// 8 will result in nothing being extracted, and zero being returned. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[in] byte_size + /// The size in byte of the integer to extract. + /// + /// @return + /// The sign extended signed integer value that was extracted, + /// or zero on failure. + int64_t getSigned(uint32_t *offset_ptr, uint32_t size) const; + + //------------------------------------------------------------------ + /// Extract an pointer from \a *offset_ptr. + /// + /// Extract a single pointer from the data and update the offset + /// pointed to by \a offset_ptr. The size of the extracted pointer + /// comes from the \a m_addr_size member variable and should be + /// set correctly prior to extracting any pointer values. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted pointer value as a 64 integer. + uint64_t getAddress(uint32_t *offset_ptr) const { + return getUnsigned(offset_ptr, PointerSize); + } + + /// Extract a uint8_t value from \a *offset_ptr. + /// + /// Extract a single uint8_t from the binary data at the offset + /// pointed to by \a offset_ptr, and advance the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint8_t value. + uint8_t getU8(uint32_t *offset_ptr) const; + + /// Extract \a count uint8_t values from \a *offset_ptr. + /// + /// Extract \a count uint8_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint8_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint8_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// NULL otherise. + uint8_t *getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const; + + //------------------------------------------------------------------ + /// Extract a uint16_t value from \a *offset_ptr. + /// + /// Extract a single uint16_t from the binary data at the offset + /// pointed to by \a offset_ptr, and update the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint16_t value. + //------------------------------------------------------------------ + uint16_t getU16(uint32_t *offset_ptr) const; + + /// Extract \a count uint16_t values from \a *offset_ptr. + /// + /// Extract \a count uint16_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint16_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint16_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// NULL otherise. + uint16_t *getU16(uint32_t *offset_ptr, uint16_t *dst, uint32_t count) const; + + /// Extract a uint32_t value from \a *offset_ptr. + /// + /// Extract a single uint32_t from the binary data at the offset + /// pointed to by \a offset_ptr, and update the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint32_t value. + uint32_t getU32(uint32_t *offset_ptr) const; + + /// Extract \a count uint32_t values from \a *offset_ptr. + /// + /// Extract \a count uint32_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint32_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint32_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// NULL otherise. + uint32_t *getU32(uint32_t *offset_ptr, uint32_t *dst, uint32_t count) const; + + /// Extract a uint64_t value from \a *offset_ptr. + /// + /// Extract a single uint64_t from the binary data at the offset + /// pointed to by \a offset_ptr, and update the offset on success. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted uint64_t value. + uint64_t getU64(uint32_t *offset_ptr) const; + + /// Extract \a count uint64_t values from \a *offset_ptr. + /// + /// Extract \a count uint64_t values from the binary data at the + /// offset pointed to by \a offset_ptr, and advance the offset on + /// success. The extracted values are copied into \a dst. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @param[out] dst + /// A buffer to copy \a count uint64_t values into. \a dst must + /// be large enough to hold all requested data. + /// + /// @param[in] count + /// The number of uint64_t values to extract. + /// + /// @return + /// \a dst if all values were properly extracted and copied, + /// NULL otherise. + uint64_t *getU64(uint32_t *offset_ptr, uint64_t *dst, uint32_t count) const; + + /// Extract a signed LEB128 value from \a *offset_ptr. + /// + /// Extracts an signed LEB128 number from this object's data + /// starting at the offset pointed to by \a offset_ptr. The offset + /// pointed to by \a offset_ptr will be updated with the offset of + /// the byte following the last extracted byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted signed integer value. + int64_t getSLEB128(uint32_t *offset_ptr) const; + + /// Extract a unsigned LEB128 value from \a *offset_ptr. + /// + /// Extracts an unsigned LEB128 number from this object's data + /// starting at the offset pointed to by \a offset_ptr. The offset + /// pointed to by \a offset_ptr will be updated with the offset of + /// the byte following the last extracted byte. + /// + /// @param[in,out] offset_ptr + /// A pointer to an offset within the data that will be advanced + /// by the appropriate number of bytes if the value is extracted + /// correctly. If the offset is out of bounds or there are not + /// enough bytes to extract this value, the offset will be left + /// unmodified. + /// + /// @return + /// The extracted unsigned integer value. + uint64_t getULEB128(uint32_t *offset_ptr) const; + + /// Test the validity of \a offset. + /// + /// @return + /// \b true if \a offset is a valid offset into the data in this + /// object, \b false otherwise. + bool isValidOffset(uint32_t offset) const { return Data.size() > offset; } + + /// Test the availability of \a length bytes of data from \a offset. + /// + /// @return + /// \b true if \a offset is a valid offset and there are \a + /// length bytes available at that offset, \b false otherwise. + bool isValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const { + return offset + length >= offset && isValidOffset(offset + length - 1); + } +}; + +} // namespace llvm + +#endif diff --git a/include/llvm/Support/DataTypes.h.cmake b/include/llvm/Support/DataTypes.h.cmake index 72c451873c0f..8c0220a489b8 100644 --- a/include/llvm/Support/DataTypes.h.cmake +++ b/include/llvm/Support/DataTypes.h.cmake @@ -15,12 +15,14 @@ |* [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types*| |* [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values. *| |* *| -|* No library is required when using these functinons. *| +|* No library is required when using these functions. *| |* *| |*===----------------------------------------------------------------------===*/ /* Please leave this file C-compatible. */ +/* Please keep this file in sync with DataTypes.h.in */ + #ifndef SUPPORT_DATATYPES_H #define SUPPORT_DATATYPES_H @@ -131,7 +133,8 @@ typedef signed int ssize_t; # define INT32_MAX 2147483647 #endif #ifndef INT32_MIN -# define INT32_MIN -2147483648 +/* MSC treats -2147483648 as -(2147483648U). */ +# define INT32_MIN (-INT32_MAX - 1) #endif #ifndef UINT32_MAX # define UINT32_MAX 4294967295U @@ -163,6 +166,11 @@ typedef signed int ssize_t; #ifndef UINT64_C # define UINT64_C(C) C##ui64 #endif + +#ifndef PRIx64 +# define PRIx64 "I64x" +#endif + #endif /* _MSC_VER */ /* Set defaults for constants which we cannot find. */ diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in index 5965e8c0b2a9..425805a1669b 100644 --- a/include/llvm/Support/DataTypes.h.in +++ b/include/llvm/Support/DataTypes.h.in @@ -1,4 +1,4 @@ -/*===-- include/System/DataTypes.h - Define fixed size types -----*- C -*-===*\ +/*===-- include/Support/DataTypes.h - Define fixed size types -----*- C -*-===*\ |* *| |* The LLVM Compiler Infrastructure *| |* *| @@ -21,6 +21,8 @@ /* Please leave this file C-compatible. */ +/* Please keep this file in sync with DataTypes.h.cmake */ + #ifndef SUPPORT_DATATYPES_H #define SUPPORT_DATATYPES_H @@ -36,17 +38,19 @@ #include #endif +#ifndef _MSC_VER + /* Note that this header's correct operation depends on __STDC_LIMIT_MACROS being defined. We would define it here, but in order to prevent Bad Things happening when system headers or C++ STL headers include stdint.h before we define it here, we define it on the g++ command line (in Makefile.rules). */ #if !defined(__STDC_LIMIT_MACROS) -# error "Must #define __STDC_LIMIT_MACROS before #including System/DataTypes.h" +# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h" #endif #if !defined(__STDC_CONSTANT_MACROS) # error "Must #define __STDC_CONSTANT_MACROS before " \ - "#including System/DataTypes.h" + "#including Support/DataTypes.h" #endif /* Note that includes , if this is a C99 system. */ @@ -87,6 +91,88 @@ typedef u_int64_t uint64_t; #define UINT32_MAX 4294967295U #endif +#else /* _MSC_VER */ +/* Visual C++ doesn't provide standard integer headers, but it does provide + built-in data types. */ +#include +#include +#include +#ifdef __cplusplus +#include +#else +#include +#endif +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed int ssize_t; +#ifndef INT8_MAX +# define INT8_MAX 127 +#endif +#ifndef INT8_MIN +# define INT8_MIN -128 +#endif +#ifndef UINT8_MAX +# define UINT8_MAX 255 +#endif +#ifndef INT16_MAX +# define INT16_MAX 32767 +#endif +#ifndef INT16_MIN +# define INT16_MIN -32768 +#endif +#ifndef UINT16_MAX +# define UINT16_MAX 65535 +#endif +#ifndef INT32_MAX +# define INT32_MAX 2147483647 +#endif +#ifndef INT32_MIN +/* MSC treats -2147483648 as -(2147483648U). */ +# define INT32_MIN (-INT32_MAX - 1) +#endif +#ifndef UINT32_MAX +# define UINT32_MAX 4294967295U +#endif +/* Certain compatibility updates to VC++ introduce the `cstdint' + * header, which defines the INT*_C macros. On default installs they + * are absent. */ +#ifndef INT8_C +# define INT8_C(C) C##i8 +#endif +#ifndef UINT8_C +# define UINT8_C(C) C##ui8 +#endif +#ifndef INT16_C +# define INT16_C(C) C##i16 +#endif +#ifndef UINT16_C +# define UINT16_C(C) C##ui16 +#endif +#ifndef INT32_C +# define INT32_C(C) C##i32 +#endif +#ifndef UINT32_C +# define UINT32_C(C) C##ui32 +#endif +#ifndef INT64_C +# define INT64_C(C) C##i64 +#endif +#ifndef UINT64_C +# define UINT64_C(C) C##ui64 +#endif + +#ifndef PRIx64 +# define PRIx64 "I64x" +#endif + +#endif /* _MSC_VER */ + /* Set defaults for constants which we cannot find. */ #if !defined(INT64_MAX) # define INT64_MAX 9223372036854775807LL diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h index 70bac0c9fc86..30f91874db20 100644 --- a/include/llvm/Support/Dwarf.h +++ b/include/llvm/Support/Dwarf.h @@ -22,8 +22,10 @@ namespace llvm { // Debug info constants. enum { - LLVMDebugVersion = (9 << 16), // Current version of debug information. - LLVMDebugVersion8 = (8 << 16), // Cconstant for version 8. + LLVMDebugVersion = (11 << 16), // Current version of debug information. + LLVMDebugVersion10 = (10 << 16), // Constant for version 10. + LLVMDebugVersion9 = (9 << 16), // Constant for version 9. + LLVMDebugVersion8 = (8 << 16), // Constant for version 8. LLVMDebugVersion7 = (7 << 16), // Constant for version 7. LLVMDebugVersion6 = (6 << 16), // Constant for version 6. LLVMDebugVersion5 = (5 << 16), // Constant for version 5. @@ -117,7 +119,16 @@ enum dwarf_constants { DW_TAG_imported_unit = 0x3d, DW_TAG_condition = 0x3f, DW_TAG_shared_type = 0x40, - DW_TAG_rvalue_reference_type = 0x41, + DW_TAG_type_unit = 0x41, + DW_TAG_rvalue_reference_type = 0x42, + DW_TAG_template_alias = 0x43, + DW_TAG_MIPS_loop = 0x4081, + DW_TAG_format_label = 0x4101, + DW_TAG_function_template = 0x4102, + DW_TAG_class_template = 0x4103, + DW_TAG_GNU_template_template_param = 0x4106, + DW_TAG_GNU_template_parameter_pack = 0x4107, + DW_TAG_GNU_formal_parameter_pack = 0x4108, DW_TAG_lo_user = 0x4080, DW_TAG_hi_user = 0xffff, @@ -212,14 +223,36 @@ enum dwarf_constants { DW_AT_elemental = 0x66, DW_AT_pure = 0x67, DW_AT_recursive = 0x68, + DW_AT_signature = 0x69, + DW_AT_main_subprogram = 0x6a, + DW_AT_data_bit_offset = 0x6b, + DW_AT_const_expr = 0x6c, + DW_AT_enum_class = 0x6d, + DW_AT_linkage_name = 0x6e, + DW_AT_MIPS_loop_begin = 0x2002, + DW_AT_MIPS_tail_loop_begin = 0x2003, + DW_AT_MIPS_epilog_begin = 0x2004, + DW_AT_MIPS_loop_unroll_factor = 0x2005, + DW_AT_MIPS_software_pipeline_depth = 0x2006, DW_AT_MIPS_linkage_name = 0x2007, - DW_AT_sf_names = 0x2101, + DW_AT_MIPS_stride = 0x2008, + DW_AT_MIPS_abstract_name = 0x2009, + DW_AT_MIPS_clone_origin = 0x200a, + DW_AT_MIPS_has_inlines = 0x200b, + DW_AT_MIPS_stride_byte = 0x200c, + DW_AT_MIPS_stride_elem = 0x200d, + DW_AT_MIPS_ptr_dopetype = 0x200e, + DW_AT_MIPS_allocatable_dopetype = 0x200f, + DW_AT_MIPS_assumed_shape_dopetype = 0x2010, + DW_AT_sf_names = 0x2101, DW_AT_src_info = 0x2102, DW_AT_mac_info = 0x2103, DW_AT_src_coords = 0x2104, DW_AT_body_begin = 0x2105, DW_AT_body_end = 0x2106, DW_AT_GNU_vector = 0x2107, + DW_AT_GNU_template_name = 0x2110, + DW_AT_MIPS_assumed_size = 0x2011, DW_AT_lo_user = 0x2000, DW_AT_hi_user = 0x3fff, @@ -259,6 +292,10 @@ enum dwarf_constants { DW_FORM_ref8 = 0x14, DW_FORM_ref_udata = 0x15, DW_FORM_indirect = 0x16, + DW_FORM_sec_offset = 0x17, + DW_FORM_exprloc = 0x18, + DW_FORM_flag_present = 0x19, + DW_FORM_ref_sig8 = 0x20, // Operation encodings DW_OP_addr = 0x03, @@ -413,6 +450,8 @@ enum dwarf_constants { DW_OP_form_tls_address = 0x9b, DW_OP_call_frame_cfa = 0x9c, DW_OP_bit_piece = 0x9d, + DW_OP_implicit_value = 0x9e, + DW_OP_stack_value = 0x9f, DW_OP_lo_user = 0xe0, DW_OP_hi_user = 0xff, @@ -432,6 +471,7 @@ enum dwarf_constants { DW_ATE_signed_fixed = 0x0d, DW_ATE_unsigned_fixed = 0x0e, DW_ATE_decimal_float = 0x0f, + DW_ATE_UTF = 0x10, DW_ATE_lo_user = 0x80, DW_ATE_hi_user = 0xff, @@ -484,6 +524,7 @@ enum dwarf_constants { DW_LANG_ObjC_plus_plus = 0x0011, DW_LANG_UPC = 0x0012, DW_LANG_D = 0x0013, + DW_LANG_Python = 0x0014, DW_LANG_lo_user = 0x8000, DW_LANG_hi_user = 0xffff, @@ -533,6 +574,7 @@ enum dwarf_constants { DW_LNE_end_sequence = 0x01, DW_LNE_set_address = 0x02, DW_LNE_define_file = 0x03, + DW_LNE_set_discriminator = 0x04, DW_LNE_lo_user = 0x80, DW_LNE_hi_user = 0xff, @@ -571,6 +613,9 @@ enum dwarf_constants { DW_CFA_val_offset = 0x14, DW_CFA_val_offset_sf = 0x15, DW_CFA_val_expression = 0x16, + DW_CFA_MIPS_advance_loc8 = 0x1d, + DW_CFA_GNU_window_save = 0x2d, + DW_CFA_GNU_args_size = 0x2e, DW_CFA_lo_user = 0x1c, DW_CFA_hi_user = 0x3f, diff --git a/include/llvm/Support/DynamicLibrary.h b/include/llvm/Support/DynamicLibrary.h index e6d9ff57ae83..288936bc0b9b 100644 --- a/include/llvm/Support/DynamicLibrary.h +++ b/include/llvm/Support/DynamicLibrary.h @@ -28,36 +28,62 @@ namespace sys { /// 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 /// executable cannot be searched. + /// + /// Note: there is currently no interface for temporarily loading a library, + /// or for unloading libraries when the LLVM library is unloaded. class DynamicLibrary { - DynamicLibrary(); // DO NOT IMPLEMENT + // Placeholder whose address represents an invalid library. + // We use this instead of NULL or a pointer-int pair because the OS library + // might define 0 or 1 to be "special" handles, such as "search all". + static char Invalid; + + // Opaque data used to interface with OS-specific dynamic library handling. + void *Data; + + explicit DynamicLibrary(void *data = &Invalid) : Data(data) {} public: - /// This function allows a library to be loaded without instantiating a - /// DynamicLibrary object. Consequently, it is marked as being permanent - /// and will only be unloaded when the program terminates. This returns - /// false on success or returns true and fills in *ErrMsg on failure. + /// Returns true if the object refers to a valid library. + bool isValid() { return Data != &Invalid; } + + /// Searches through the library for the symbol \p symbolName. If it is + /// found, the address of that symbol is returned. If not, NULL is returned. + /// Note that NULL will also be returned if the library failed to load. + /// Use isValid() to distinguish these cases if it is important. + /// Note that this will \e not search symbols explicitly registered by + /// AddSymbol(). + void *getAddressOfSymbol(const char *symbolName); + + /// This function permanently loads the dynamic library at the given path. + /// The library will only be unloaded when the program terminates. + /// This returns a valid DynamicLibrary instance on success and an invalid + /// instance on failure (see isValid()). \p *errMsg will only be modified + /// if the library fails to load. + /// + /// It is safe to call this function multiple times for the same library. /// @brief Open a dynamic library permanently. + static DynamicLibrary getPermanentLibrary(const char *filename, + std::string *errMsg = 0); + + /// This function permanently loads the dynamic library at the given path. + /// Use this instead of getPermanentLibrary() when you won't need to get + /// symbols from the library itself. /// - /// NOTE: This function is not thread safe. - /// - static bool LoadLibraryPermanently(const char *filename, - std::string *ErrMsg = 0); + /// It is safe to call this function multiple times for the same library. + static bool LoadLibraryPermanently(const char *Filename, + std::string *ErrMsg = 0) { + return !getPermanentLibrary(Filename, ErrMsg).isValid(); + } /// This function will search through all previously loaded dynamic - /// libraries for the symbol \p symbolName. If it is found, the addressof + /// libraries for the symbol \p symbolName. If it is found, the address of /// that symbol is returned. If not, null is returned. Note that this will - /// search permanently loaded libraries (LoadLibraryPermanently) as well - /// as ephemerally loaded libraries (constructors). + /// search permanently loaded libraries (getPermanentLibrary()) as well + /// as explicitly registered symbols (AddSymbol()). /// @throws std::string on error. /// @brief Search through libraries for address of a symbol - /// - /// NOTE: This function is not thread safe. - /// static void *SearchForAddressOfSymbol(const char *symbolName); /// @brief Convenience function for C++ophiles. - /// - /// NOTE: This function is not thread safe. - /// static void *SearchForAddressOfSymbol(const std::string &symbolName) { return SearchForAddressOfSymbol(symbolName.c_str()); } @@ -66,18 +92,7 @@ namespace sys { /// value \p symbolValue. These symbols are searched before any /// libraries. /// @brief Add searchable symbol/value pair. - /// - /// NOTE: This function is not thread safe. - /// - static void AddSymbol(const char *symbolName, void *symbolValue); - - /// @brief Convenience function for C++ophiles. - /// - /// NOTE: This function is not thread safe. - /// - static void AddSymbol(const std::string &symbolName, void *symbolValue) { - AddSymbol(symbolName.c_str(), symbolValue); - } + static void AddSymbol(StringRef symbolName, void *symbolValue); }; } // End sys namespace diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index be48112a908b..c5b85e2e6a12 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -28,20 +28,18 @@ namespace llvm { namespace ELF { typedef uint32_t Elf32_Addr; // Program address -typedef uint16_t Elf32_Half; typedef uint32_t Elf32_Off; // File offset -typedef int32_t Elf32_Sword; +typedef uint16_t Elf32_Half; typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; typedef uint64_t Elf64_Addr; typedef uint64_t Elf64_Off; -typedef int32_t Elf64_Shalf; -typedef int32_t Elf64_Sword; +typedef uint16_t Elf64_Half; typedef uint32_t Elf64_Word; -typedef int64_t Elf64_Sxword; +typedef int32_t Elf64_Sword; typedef uint64_t Elf64_Xword; -typedef uint32_t Elf64_Half; -typedef uint16_t Elf64_Quarter; +typedef int64_t Elf64_Sxword; // Object file magic string. static const char ElfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' }; @@ -87,19 +85,19 @@ struct Elf32_Ehdr { // types (see above). struct Elf64_Ehdr { unsigned char e_ident[EI_NIDENT]; - Elf64_Quarter e_type; - Elf64_Quarter e_machine; - Elf64_Half e_version; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; Elf64_Addr e_entry; Elf64_Off e_phoff; Elf64_Off e_shoff; - Elf64_Half e_flags; - Elf64_Quarter e_ehsize; - Elf64_Quarter e_phentsize; - Elf64_Quarter e_phnum; - Elf64_Quarter e_shentsize; - Elf64_Quarter e_shnum; - Elf64_Quarter e_shstrndx; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; bool checkMagic() const { return (memcmp(e_ident, ElfMagic, strlen(ElfMagic))) == 0; } @@ -126,22 +124,170 @@ enum { // Machine architectures enum { - EM_NONE = 0, // No machine - EM_M32 = 1, // AT&T WE 32100 - EM_SPARC = 2, // SPARC - EM_386 = 3, // Intel 386 - EM_68K = 4, // Motorola 68000 - EM_88K = 5, // Motorola 88000 - EM_486 = 6, // Intel 486 (deprecated) - EM_860 = 7, // Intel 80860 - EM_MIPS = 8, // MIPS R3000 - EM_PPC = 20, // PowerPC - EM_PPC64 = 21, // PowerPC64 - EM_ARM = 40, // ARM - EM_ALPHA = 41, // DEC Alpha - EM_SPARCV9 = 43, // SPARC V9 - EM_X86_64 = 62, // AMD64 - EM_MBLAZE = 47787 // Xilinx MicroBlaze + EM_NONE = 0, // No machine + EM_M32 = 1, // AT&T WE 32100 + EM_SPARC = 2, // SPARC + EM_386 = 3, // Intel 386 + EM_68K = 4, // Motorola 68000 + EM_88K = 5, // Motorola 88000 + EM_486 = 6, // Intel 486 (deprecated) + EM_860 = 7, // Intel 80860 + EM_MIPS = 8, // MIPS R3000 + EM_S370 = 9, // IBM System/370 + EM_MIPS_RS3_LE = 10, // MIPS RS3000 Little-endian + EM_PARISC = 15, // Hewlett-Packard PA-RISC + EM_VPP500 = 17, // Fujitsu VPP500 + EM_SPARC32PLUS = 18, // Enhanced instruction set SPARC + EM_960 = 19, // Intel 80960 + EM_PPC = 20, // PowerPC + EM_PPC64 = 21, // PowerPC64 + EM_S390 = 22, // IBM System/390 + EM_SPU = 23, // IBM SPU/SPC + EM_V800 = 36, // NEC V800 + EM_FR20 = 37, // Fujitsu FR20 + EM_RH32 = 38, // TRW RH-32 + EM_RCE = 39, // Motorola RCE + EM_ARM = 40, // ARM + EM_ALPHA = 41, // DEC Alpha + EM_SH = 42, // Hitachi SH + EM_SPARCV9 = 43, // SPARC V9 + EM_TRICORE = 44, // Siemens TriCore + EM_ARC = 45, // Argonaut RISC Core + EM_H8_300 = 46, // Hitachi H8/300 + EM_H8_300H = 47, // Hitachi H8/300H + EM_H8S = 48, // Hitachi H8S + EM_H8_500 = 49, // Hitachi H8/500 + EM_IA_64 = 50, // Intel IA-64 processor architecture + EM_MIPS_X = 51, // Stanford MIPS-X + EM_COLDFIRE = 52, // Motorola ColdFire + EM_68HC12 = 53, // Motorola M68HC12 + EM_MMA = 54, // Fujitsu MMA Multimedia Accelerator + EM_PCP = 55, // Siemens PCP + EM_NCPU = 56, // Sony nCPU embedded RISC processor + EM_NDR1 = 57, // Denso NDR1 microprocessor + EM_STARCORE = 58, // Motorola Star*Core processor + EM_ME16 = 59, // Toyota ME16 processor + EM_ST100 = 60, // STMicroelectronics ST100 processor + EM_TINYJ = 61, // Advanced Logic Corp. TinyJ embedded processor family + EM_X86_64 = 62, // AMD x86-64 architecture + EM_PDSP = 63, // Sony DSP Processor + EM_PDP10 = 64, // Digital Equipment Corp. PDP-10 + EM_PDP11 = 65, // Digital Equipment Corp. PDP-11 + EM_FX66 = 66, // Siemens FX66 microcontroller + EM_ST9PLUS = 67, // STMicroelectronics ST9+ 8/16 bit microcontroller + EM_ST7 = 68, // STMicroelectronics ST7 8-bit microcontroller + EM_68HC16 = 69, // Motorola MC68HC16 Microcontroller + EM_68HC11 = 70, // Motorola MC68HC11 Microcontroller + EM_68HC08 = 71, // Motorola MC68HC08 Microcontroller + EM_68HC05 = 72, // Motorola MC68HC05 Microcontroller + EM_SVX = 73, // Silicon Graphics SVx + EM_ST19 = 74, // STMicroelectronics ST19 8-bit microcontroller + EM_VAX = 75, // Digital VAX + EM_CRIS = 76, // Axis Communications 32-bit embedded processor + EM_JAVELIN = 77, // Infineon Technologies 32-bit embedded processor + EM_FIREPATH = 78, // Element 14 64-bit DSP Processor + EM_ZSP = 79, // LSI Logic 16-bit DSP Processor + EM_MMIX = 80, // Donald Knuth's educational 64-bit processor + EM_HUANY = 81, // Harvard University machine-independent object files + EM_PRISM = 82, // SiTera Prism + EM_AVR = 83, // Atmel AVR 8-bit microcontroller + EM_FR30 = 84, // Fujitsu FR30 + EM_D10V = 85, // Mitsubishi D10V + EM_D30V = 86, // Mitsubishi D30V + EM_V850 = 87, // NEC v850 + EM_M32R = 88, // Mitsubishi M32R + EM_MN10300 = 89, // Matsushita MN10300 + EM_MN10200 = 90, // Matsushita MN10200 + EM_PJ = 91, // picoJava + EM_OPENRISC = 92, // OpenRISC 32-bit embedded processor + EM_ARC_COMPACT = 93, // ARC International ARCompact processor (old + // spelling/synonym: EM_ARC_A5) + EM_XTENSA = 94, // Tensilica Xtensa Architecture + EM_VIDEOCORE = 95, // Alphamosaic VideoCore processor + EM_TMM_GPP = 96, // Thompson Multimedia General Purpose Processor + EM_NS32K = 97, // National Semiconductor 32000 series + EM_TPC = 98, // Tenor Network TPC processor + EM_SNP1K = 99, // Trebia SNP 1000 processor + EM_ST200 = 100, // STMicroelectronics (www.st.com) ST200 + EM_IP2K = 101, // Ubicom IP2xxx microcontroller family + EM_MAX = 102, // MAX Processor + EM_CR = 103, // National Semiconductor CompactRISC microprocessor + EM_F2MC16 = 104, // Fujitsu F2MC16 + EM_MSP430 = 105, // Texas Instruments embedded microcontroller msp430 + EM_BLACKFIN = 106, // Analog Devices Blackfin (DSP) processor + EM_SE_C33 = 107, // S1C33 Family of Seiko Epson processors + EM_SEP = 108, // Sharp embedded microprocessor + EM_ARCA = 109, // Arca RISC Microprocessor + EM_UNICORE = 110, // Microprocessor series from PKU-Unity Ltd. and MPRC + // of Peking University + EM_EXCESS = 111, // eXcess: 16/32/64-bit configurable embedded CPU + EM_DXP = 112, // Icera Semiconductor Inc. Deep Execution Processor + EM_ALTERA_NIOS2 = 113, // Altera Nios II soft-core processor + EM_CRX = 114, // National Semiconductor CompactRISC CRX + EM_XGATE = 115, // Motorola XGATE embedded processor + EM_C166 = 116, // Infineon C16x/XC16x processor + EM_M16C = 117, // Renesas M16C series microprocessors + EM_DSPIC30F = 118, // Microchip Technology dsPIC30F Digital Signal + // Controller + EM_CE = 119, // Freescale Communication Engine RISC core + EM_M32C = 120, // Renesas M32C series microprocessors + EM_TSK3000 = 131, // Altium TSK3000 core + EM_RS08 = 132, // Freescale RS08 embedded processor + EM_SHARC = 133, // Analog Devices SHARC family of 32-bit DSP + // processors + EM_ECOG2 = 134, // Cyan Technology eCOG2 microprocessor + EM_SCORE7 = 135, // Sunplus S+core7 RISC processor + EM_DSP24 = 136, // New Japan Radio (NJR) 24-bit DSP Processor + EM_VIDEOCORE3 = 137, // Broadcom VideoCore III processor + EM_LATTICEMICO32 = 138, // RISC processor for Lattice FPGA architecture + EM_SE_C17 = 139, // Seiko Epson C17 family + EM_TI_C6000 = 140, // The Texas Instruments TMS320C6000 DSP family + EM_TI_C2000 = 141, // The Texas Instruments TMS320C2000 DSP family + EM_TI_C5500 = 142, // The Texas Instruments TMS320C55x DSP family + EM_MMDSP_PLUS = 160, // STMicroelectronics 64bit VLIW Data Signal Processor + EM_CYPRESS_M8C = 161, // Cypress M8C microprocessor + EM_R32C = 162, // Renesas R32C series microprocessors + EM_TRIMEDIA = 163, // NXP Semiconductors TriMedia architecture family + EM_QDSP6 = 164, // QUALCOMM DSP6 Processor + EM_8051 = 165, // Intel 8051 and variants + EM_STXP7X = 166, // STMicroelectronics STxP7x family of configurable + // and extensible RISC processors + EM_NDS32 = 167, // Andes Technology compact code size embedded RISC + // processor family + EM_ECOG1 = 168, // Cyan Technology eCOG1X family + EM_ECOG1X = 168, // Cyan Technology eCOG1X family + EM_MAXQ30 = 169, // Dallas Semiconductor MAXQ30 Core Micro-controllers + EM_XIMO16 = 170, // New Japan Radio (NJR) 16-bit DSP Processor + EM_MANIK = 171, // M2000 Reconfigurable RISC Microprocessor + EM_CRAYNV2 = 172, // Cray Inc. NV2 vector architecture + EM_RX = 173, // Renesas RX family + EM_METAG = 174, // Imagination Technologies META processor + // architecture + EM_MCST_ELBRUS = 175, // MCST Elbrus general purpose hardware architecture + EM_ECOG16 = 176, // Cyan Technology eCOG16 family + EM_CR16 = 177, // National Semiconductor CompactRISC CR16 16-bit + // microprocessor + EM_ETPU = 178, // Freescale Extended Time Processing Unit + EM_SLE9X = 179, // Infineon Technologies SLE9X core + EM_L10M = 180, // Intel L10M + EM_K10M = 181, // Intel K10M + EM_AVR32 = 185, // Atmel Corporation 32-bit microprocessor family + EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller + EM_TILE64 = 187, // Tilera TILE64 multicore architecture family + EM_TILEPRO = 188, // Tilera TILEPro multicore architecture family + EM_MICROBLAZE = 189, // Xilinx MicroBlaze 32-bit RISC soft processor core + EM_CUDA = 190, // NVIDIA CUDA architecture + EM_TILEGX = 191, // Tilera TILE-Gx multicore architecture family + EM_CLOUDSHIELD = 192, // CloudShield architecture family + EM_COREA_1ST = 193, // KIPO-KAIST Core-A 1st generation processor family + EM_COREA_2ND = 194, // KIPO-KAIST Core-A 2nd generation processor family + EM_ARC_COMPACT2 = 195, // Synopsys ARCompact V2 + EM_OPEN8 = 196, // Open8 8-bit RISC soft processor core + EM_RL78 = 197, // Renesas RL78 family + EM_VIDEOCORE5 = 198, // Broadcom VideoCore V processor + EM_78KOR = 199, // Renesas 78KOR family + EM_56800EX = 200, // Freescale 56800EX Digital Signal Controller (DSC) + EM_MBLAZE = 47787 // Xilinx MicroBlaze }; // Object file classes. @@ -211,6 +357,11 @@ enum { R_X86_64_PC64 = 24, R_X86_64_GOTOFF64 = 25, R_X86_64_GOTPC32 = 26, + R_X86_64_GOT64 = 27, + R_X86_64_GOTPCREL64 = 28, + R_X86_64_GOTPC64 = 29, + R_X86_64_GOTPLT64 = 30, + R_X86_64_PLTOFF64 = 31, R_X86_64_SIZE32 = 32, R_X86_64_SIZE64 = 33, R_X86_64_GOTPC32_TLSDESC = 34, @@ -290,6 +441,23 @@ enum { R_MICROBLAZE_COPY = 21 }; +enum { + R_PPC_NONE = 0, /* No relocation. */ + R_PPC_ADDR32 = 1, + R_PPC_ADDR24 = 2, + R_PPC_ADDR16 = 3, + R_PPC_ADDR16_LO = 4, + R_PPC_ADDR16_HI = 5, + R_PPC_ADDR16_HA = 6, + R_PPC_ADDR14 = 7, + R_PPC_ADDR14_BRTAKEN = 8, + R_PPC_ADDR14_BRNTAKEN = 9, + R_PPC_REL24 = 10, + R_PPC_REL14 = 11, + R_PPC_REL14_BRTAKEN = 12, + R_PPC_REL14_BRNTAKEN = 13, + R_PPC_REL32 = 26 +}; // ARM Specific e_flags enum { EF_ARM_EABIMASK = 0xFF000000U }; @@ -431,7 +599,61 @@ enum { R_ARM_THM_TLS_DESCSEQ32 = 0x82 }; - +// ELF Relocation types for Mips +enum { + R_MIPS_NONE = 0, + R_MIPS_16 = 1, + R_MIPS_32 = 2, + R_MIPS_REL32 = 3, + R_MIPS_26 = 4, + R_MIPS_HI16 = 5, + R_MIPS_LO16 = 6, + R_MIPS_GPREL16 = 7, + R_MIPS_LITERAL = 8, + R_MIPS_GOT16 = 9, + R_MIPS_PC16 = 10, + R_MIPS_CALL16 = 11, + R_MIPS_GPREL32 = 12, + R_MIPS_SHIFT5 = 16, + R_MIPS_SHIFT6 = 17, + R_MIPS_64 = 18, + R_MIPS_GOT_DISP = 19, + R_MIPS_GOT_PAGE = 20, + R_MIPS_GOT_OFST = 21, + R_MIPS_GOT_HI16 = 22, + R_MIPS_GOT_LO16 = 23, + R_MIPS_SUB = 24, + R_MIPS_INSERT_A = 25, + R_MIPS_INSERT_B = 26, + R_MIPS_DELETE = 27, + R_MIPS_HIGHER = 28, + R_MIPS_HIGHEST = 29, + R_MIPS_CALL_HI16 = 30, + R_MIPS_CALL_LO16 = 31, + R_MIPS_SCN_DISP = 32, + R_MIPS_REL16 = 33, + R_MIPS_ADD_IMMEDIATE = 34, + R_MIPS_PJUMP = 35, + R_MIPS_RELGOT = 36, + R_MIPS_JALR = 37, + R_MIPS_TLS_DTPMOD32 = 38, + R_MIPS_TLS_DTPREL32 = 39, + R_MIPS_TLS_DTPMOD64 = 40, + R_MIPS_TLS_DTPREL64 = 41, + R_MIPS_TLS_GD = 42, + R_MIPS_TLS_LDM = 43, + R_MIPS_TLS_DTPREL_HI16 = 44, + R_MIPS_TLS_DTPREL_LO16 = 45, + R_MIPS_TLS_GOTTPREL = 46, + R_MIPS_TLS_TPREL32 = 47, + R_MIPS_TLS_TPREL64 = 48, + R_MIPS_TLS_TPREL_HI16 = 49, + R_MIPS_TLS_TPREL_LO16 = 50, + R_MIPS_GLOB_DAT = 51, + R_MIPS_COPY = 126, + R_MIPS_JUMP_SLOT = 127, + R_MIPS_NUM = 218 +}; // Section header. struct Elf32_Shdr { @@ -449,14 +671,14 @@ struct Elf32_Shdr { // Section header for ELF64 - same fields as ELF32, different types. struct Elf64_Shdr { - Elf64_Half sh_name; - Elf64_Half sh_type; + Elf64_Word sh_name; + Elf64_Word sh_type; Elf64_Xword sh_flags; Elf64_Addr sh_addr; Elf64_Off sh_offset; Elf64_Xword sh_size; - Elf64_Half sh_link; - Elf64_Half sh_info; + Elf64_Word sh_link; + Elf64_Word sh_info; Elf64_Xword sh_addralign; Elf64_Xword sh_entsize; }; @@ -467,6 +689,8 @@ enum { SHN_LORESERVE = 0xff00, // Lowest reserved index SHN_LOPROC = 0xff00, // Lowest processor-specific index SHN_HIPROC = 0xff1f, // Highest processor-specific index + SHN_LOOS = 0xff20, // Lowest operating system-specific index + SHN_HIOS = 0xff3f, // Highest operating system-specific index SHN_ABS = 0xfff1, // Symbol has absolute value; does not need relocation SHN_COMMON = 0xfff2, // FORTRAN COMMON or C external global variables SHN_XINDEX = 0xffff, // Mark that the index is >= SHN_LORESERVE @@ -557,8 +781,19 @@ enum { /// set to the start of the section by the boot code. XCORE_SHF_DP_SECTION = 0x1000U, + SHF_MASKOS = 0x0ff00000, + // Bits indicating processor-specific flags. - SHF_MASKPROC = 0xf0000000 + SHF_MASKPROC = 0xf0000000, + + // If an object file section does not have this flag set, then it may not hold + // more than 2GB and can be freely referred to in objects using smaller code + // models. Otherwise, only objects using larger code models can refer to them. + // For example, a medium code model object can refer to data in a section that + // sets this flag besides being able to refer to data in a section that does + // not set it; likewise, a small code model object can refer only to code in a + // section that does not set this flag. + SHF_X86_64_LARGE = 0x10000000 }; // Section Group Flags @@ -619,6 +854,8 @@ enum { STB_LOCAL = 0, // Local symbol, not visible outside obj file containing def STB_GLOBAL = 1, // Global symbol, visible to all object files being combined STB_WEAK = 2, // Weak symbol, like global but lower-precedence + STB_LOOS = 10, // Lowest operating system-specific binding type + STB_HIOS = 12, // Highest operating system-specific binding type STB_LOPROC = 13, // Lowest processor-specific binding type STB_HIPROC = 15 // Highest processor-specific binding type }; @@ -632,6 +869,8 @@ enum { STT_FILE = 4, // Local, absolute symbol that refers to a file STT_COMMON = 5, // An uninitialized common block STT_TLS = 6, // Thread local data object + STT_LOOS = 7, // Lowest operating system-specific symbol type + STT_HIOS = 8, // Highest operating system-specific symbol type STT_LOPROC = 13, // Lowest processor-specific symbol type STT_HIPROC = 15 // Highest processor-specific symbol type }; @@ -746,6 +985,16 @@ enum { PT_NOTE = 4, // Auxiliary information. PT_SHLIB = 5, // Reserved. PT_PHDR = 6, // The program header table itself. + PT_TLS = 7, // The thread-local storage template. + PT_LOOS = 0x60000000, // Lowest operating system-specific pt entry type. + + // x86-64 program header types. + // These all contain stack unwind tables. + PT_GNU_EH_FRAME = 0x6474e550, + PT_SUNW_EH_FRAME = 0x6474e550, + PT_SUNW_UNWIND = 0x6464e550, + + PT_HIOS = 0x6fffffff, // Highest operating system-specific pt entry type. PT_LOPROC = 0x70000000, // Lowest processor-specific program hdr entry type. PT_HIPROC = 0x7fffffff // Highest processor-specific program hdr entry type. }; @@ -755,7 +1004,8 @@ enum { PF_X = 1, // Execute PF_W = 2, // Write PF_R = 4, // Read - PF_MASKPROC = 0xf0000000 // Unspecified + PF_MASKOS = 0x0ff00000,// Bits for operating system-specific semantics. + PF_MASKPROC = 0xf0000000 // Bits for processor-specific semantics. }; // Dynamic table entry for ELF32. @@ -811,12 +1061,29 @@ enum { DT_FINI_ARRAY = 26, // Pointer to array of termination functions. DT_INIT_ARRAYSZ = 27, // Size of DT_INIT_ARRAY. DT_FINI_ARRAYSZ = 28, // Size of DT_FINI_ARRAY. + DT_RUNPATH = 29, // String table offset of lib search path. + DT_FLAGS = 30, // Flags. + DT_ENCODING = 32, // Values from here to DT_LOOS follow the rules + // for the interpretation of the d_un union. + + DT_PREINIT_ARRAY = 32, // Pointer to array of preinit functions. + DT_PREINIT_ARRAYSZ = 33, // Size of the DT_PREINIT_ARRAY array. + DT_LOOS = 0x60000000, // Start of environment specific tags. DT_HIOS = 0x6FFFFFFF, // End of environment specific tags. DT_LOPROC = 0x70000000, // Start of processor specific tags. DT_HIPROC = 0x7FFFFFFF // End of processor specific tags. }; +// DT_FLAGS values. +enum { + DF_ORIGIN = 0x01, // The object may reference $ORIGIN. + DF_SYMBOLIC = 0x02, // Search the shared lib before searching the exe. + DF_TEXTREL = 0x04, // Relocations may modify a non-writable segment. + DF_BIND_NOW = 0x08, // Process all relocations on load. + DF_STATIC_TLS = 0x10 // Reject attempts to load dynamically. +}; + } // end namespace ELF } // end namespace llvm diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index 4f013f89e86c..a868e5f9f70b 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -201,30 +201,6 @@ error_code rename(const Twine &from, const Twine &to); /// platform specific error_code. error_code resize_file(const Twine &path, uint64_t size); -/// @brief Make file readable. -/// -/// @param path Input path. -/// @param value If true, make readable, else, make unreadable. -/// @results errc::success if readability has been successfully set, otherwise a -/// platform specific error_code. -error_code set_read(const Twine &path, bool value); - -/// @brief Make file writeable. -/// -/// @param path Input path. -/// @param value If true, make writeable, else, make unwriteable. -/// @results errc::success if writeability has been successfully set, otherwise -/// a platform specific error_code. -error_code set_write(const Twine &path, bool value); - -/// @brief Make file executable. -/// -/// @param path Input path. -/// @param value If true, make executable, else, make unexecutable. -/// @results errc::success if executability has been successfully set, otherwise -/// a platform specific error_code. -error_code set_execute(const Twine &path, bool value); - /// @} /// @name Physical Observers /// @{ @@ -245,6 +221,13 @@ bool exists(file_status status); /// platform specific error_code. error_code exists(const Twine &path, bool &result); +/// @brief Simpler version of exists for clients that don't need to +/// differentiate between an error and false. +inline bool exists(const Twine &path) { + bool result; + return !exists(path, result) && result; +} + /// @brief Do file_status's represent the same thing? /// /// @param A Input file_status. @@ -289,15 +272,6 @@ bool is_directory(file_status status); /// platform specific error_code. error_code is_directory(const Twine &path, bool &result); -/// @brief Is path an empty file? -/// -/// @param path Input path. -/// @param result Set to true if \a path is a an empty file, false if it is not. -/// Undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code is_empty(const Twine &path, bool &result); - /// @brief Does status represent a regular file? /// /// @param status A file_status previously returned from status. @@ -346,40 +320,6 @@ bool is_symlink(file_status status); /// platform specific error_code. error_code is_symlink(const Twine &path, bool &result); -/// @brief Get last write time without changing it. -/// -/// @param path Input path. -/// @param result Set to the last write time (UNIX time) of \a path if it -/// exists. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code last_write_time(const Twine &path, std::time_t &result); - -/// @brief Set last write time. -/// -/// @param path Input path. -/// @param value Time to set (UNIX time) \a path's last write time to. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code set_last_write_time(const Twine &path, std::time_t value); - -/// @brief Read a symlink's value. -/// -/// @param path Input path. -/// @param result Set to the value of the symbolic link \a path. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code read_symlink(const Twine &path, SmallVectorImpl &result); - -/// @brief Get disk space usage information. -/// -/// @param path Input path. -/// @param result Set to the capacity, free, and available space on the device -/// \a path is on. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code disk_space(const Twine &path, space_info &result); - /// @brief Get file status as if by POSIX stat(). /// /// @param path Input path. @@ -402,16 +342,6 @@ bool status_known(file_status s); /// platform specific error_code. error_code status_known(const Twine &path, bool &result); -/// @brief Get file status as if by POSIX lstat(). -/// -/// Does not resolve symlinks. -/// -/// @param path Input path. -/// @param result Set to the file status. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code symlink_status(const Twine &path, file_status &result); - /// @brief Generate a unique path and open it as a file. /// /// Generates a unique path suitable for a temporary file and then opens it as a @@ -427,10 +357,13 @@ error_code symlink_status(const Twine &path, file_status &result); /// @param model Name to base unique path off of. /// @param result_fs Set to the opened file's file descriptor. /// @param result_path Set to the opened file's absolute path. +/// @param makeAbsolute If true and @model is not an absolute path, a temp +/// directory will be prepended. /// @results errc::success if result_{fd,path} have been successfully set, /// otherwise a platform specific error_code. error_code unique_file(const Twine &model, int &result_fd, - SmallVectorImpl &result_path); + SmallVectorImpl &result_path, + bool makeAbsolute = true); /// @brief Canonicalize path. /// @@ -472,60 +405,6 @@ error_code get_magic(const Twine &path, uint32_t len, /// platform specific error_code. error_code identify_magic(const Twine &path, LLVMFileType &result); -/// @brief Is file bitcode? -/// -/// @param path Input path. -/// @param result Set to true if \a path is a bitcode file, false if it is not, -/// undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code is_bitcode(const Twine &path, bool &result); - -/// @brief Is file a dynamic library? -/// -/// @param path Input path. -/// @param result Set to true if \a path is a dynamic library, false if it is -/// not, undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code is_dynamic_library(const Twine &path, bool &result); - -/// @brief Is an object file? -/// -/// @param path Input path. -/// @param result Set to true if \a path is an object file, false if it is not, -/// undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code is_object_file(const Twine &path, bool &result); - -/// @brief Can file be read? -/// -/// @param path Input path. -/// @param result Set to true if \a path is readable, false it it is not, -/// undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code can_read(const Twine &path, bool &result); - -/// @brief Can file be written? -/// -/// @param path Input path. -/// @param result Set to true if \a path is writeable, false it it is not, -/// undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code can_write(const Twine &path, bool &result); - -/// @brief Can file be executed? -/// -/// @param path Input path. -/// @param result Set to true if \a path is executable, false it it is not, -/// undefined otherwise. -/// @results errc::success if result has been successfully set, otherwise a -/// platform specific error_code. -error_code can_execute(const Twine &path, bool &result); - /// @brief Get library paths the system linker uses. /// /// @param result Set to the list of system library paths. @@ -569,35 +448,28 @@ error_code GetMainExecutable(const char *argv0, void *MainAddr, /// @{ /// directory_entry - A single entry in a directory. Caches the status either -/// from the result of the iteration syscall, or the first time status or -/// symlink_status is called. +/// from the result of the iteration syscall, or the first time status is +/// called. class directory_entry { std::string Path; mutable file_status Status; - mutable file_status SymlinkStatus; public: - explicit directory_entry(const Twine &path, file_status st = file_status(), - file_status symlink_st = file_status()) + explicit directory_entry(const Twine &path, file_status st = file_status()) : Path(path.str()) - , Status(st) - , SymlinkStatus(symlink_st) {} + , Status(st) {} directory_entry() {} - void assign(const Twine &path, file_status st = file_status(), - file_status symlink_st = file_status()) { + void assign(const Twine &path, file_status st = file_status()) { Path = path.str(); Status = st; - SymlinkStatus = symlink_st; } - void replace_filename(const Twine &filename, file_status st = file_status(), - file_status symlink_st = file_status()); + void replace_filename(const Twine &filename, file_status st = file_status()); const std::string &path() const { return Path; } error_code status(file_status &result) const; - error_code symlink_status(file_status &result) const; bool operator==(const directory_entry& rhs) const { return Path == rhs.Path; } bool operator!=(const directory_entry& rhs) const { return !(*this == rhs); } diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h index f64e3db7d650..59812d98f589 100644 --- a/include/llvm/Support/Format.h +++ b/include/llvm/Support/Format.h @@ -126,6 +126,50 @@ class format_object3 : public format_object_base { } }; +/// format_object4 - This is a templated helper class used by the format +/// function that captures the object to be formated and the format string. When +/// actually printed, this synthesizes the string into a temporary buffer +/// provided and returns whether or not it is big enough. +template +class format_object4 : public format_object_base { + T1 Val1; + T2 Val2; + T3 Val3; + T4 Val4; +public: + format_object4(const char *fmt, const T1 &val1, const T2 &val2, + const T3 &val3, const T4 &val4) + : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4) { + } + + virtual int snprint(char *Buffer, unsigned BufferSize) const { + return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4); + } +}; + +/// format_object5 - This is a templated helper class used by the format +/// function that captures the object to be formated and the format string. When +/// actually printed, this synthesizes the string into a temporary buffer +/// provided and returns whether or not it is big enough. +template +class format_object5 : public format_object_base { + T1 Val1; + T2 Val2; + T3 Val3; + T4 Val4; + T5 Val5; +public: + format_object5(const char *fmt, const T1 &val1, const T2 &val2, + const T3 &val3, const T4 &val4, const T5 &val5) + : format_object_base(fmt), Val1(val1), Val2(val2), Val3(val3), Val4(val4), + Val5(val5) { + } + + virtual int snprint(char *Buffer, unsigned BufferSize) const { + return snprintf(Buffer, BufferSize, Fmt, Val1, Val2, Val3, Val4, Val5); + } +}; + /// format - This is a helper function that is used to produce formatted output. /// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; template @@ -149,6 +193,24 @@ template return format_object3(Fmt, Val1, Val2, Val3); } +/// format - This is a helper function that is used to produce formatted output. +/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +template +inline format_object4 format(const char *Fmt, const T1 &Val1, + const T2 &Val2, const T3 &Val3, + const T4 &Val4) { + return format_object4(Fmt, Val1, Val2, Val3, Val4); +} + +/// format - This is a helper function that is used to produce formatted output. +/// This is typically used like: OS << format("%0.4f", myfloat) << '\n'; +template +inline format_object5 format(const char *Fmt,const T1 &Val1, + const T2 &Val2, const T3 &Val3, + const T4 &Val4, const T5 &Val5) { + return format_object5(Fmt, Val1, Val2, Val3, Val4, Val5); +} + } // end namespace llvm #endif diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h new file mode 100644 index 000000000000..49cd87fc7b44 --- /dev/null +++ b/include/llvm/Support/GCOV.h @@ -0,0 +1,224 @@ +//===-- llvm/Support/GCOV.h - LLVM coverage tool ----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header provides the interface to read and write coverage files that +// use 'gcov' format. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_GCOV_H +#define LLVM_GCOV_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +class GCOVFunction; +class GCOVBlock; +class GCOVLines; +class FileInfo; + +enum GCOVFormat { + InvalidGCOV, + GCNO_402, + GCNO_404, + GCDA_402, + GCDA_404 +}; + +/// GCOVBuffer - A wrapper around MemoryBuffer to provide GCOV specific +/// read operations. +class GCOVBuffer { +public: + GCOVBuffer(MemoryBuffer *B) : Buffer(B), Cursor(0) {} + + /// readGCOVFormat - Read GCOV signature at the beginning of buffer. + enum GCOVFormat readGCOVFormat() { + StringRef Magic = Buffer->getBuffer().slice(0, 12); + Cursor = 12; + if (Magic == "oncg*404MVLL") + return GCNO_404; + else if (Magic == "oncg*204MVLL") + return GCNO_402; + else if (Magic == "adcg*404MVLL") + return GCDA_404; + else if (Magic == "adcg*204MVLL") + return GCDA_402; + + Cursor = 0; + return InvalidGCOV; + } + + /// readFunctionTag - If cursor points to a function tag then increment the + /// cursor and return true otherwise return false. + bool readFunctionTag() { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); + if (Tag.empty() || + Tag[0] != '\0' || Tag[1] != '\0' || + Tag[2] != '\0' || Tag[3] != '\1') { + return false; + } + Cursor += 4; + return true; + } + + /// readBlockTag - If cursor points to a block tag then increment the + /// cursor and return true otherwise return false. + bool readBlockTag() { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); + if (Tag.empty() || + Tag[0] != '\0' || Tag[1] != '\0' || + Tag[2] != '\x41' || Tag[3] != '\x01') { + return false; + } + Cursor += 4; + return true; + } + + /// readEdgeTag - If cursor points to an edge tag then increment the + /// cursor and return true otherwise return false. + bool readEdgeTag() { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); + if (Tag.empty() || + Tag[0] != '\0' || Tag[1] != '\0' || + Tag[2] != '\x43' || Tag[3] != '\x01') { + return false; + } + Cursor += 4; + return true; + } + + /// readLineTag - If cursor points to a line tag then increment the + /// cursor and return true otherwise return false. + bool readLineTag() { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); + if (Tag.empty() || + Tag[0] != '\0' || Tag[1] != '\0' || + Tag[2] != '\x45' || Tag[3] != '\x01') { + return false; + } + Cursor += 4; + return true; + } + + /// readArcTag - If cursor points to an gcda arc tag then increment the + /// cursor and return true otherwise return false. + bool readArcTag() { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); + if (Tag.empty() || + Tag[0] != '\0' || Tag[1] != '\0' || + Tag[2] != '\xa1' || Tag[3] != '\1') { + return false; + } + Cursor += 4; + return true; + } + + uint32_t readInt() { + uint32_t Result; + StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4); + assert (Str.empty() == false && "Unexpected memory buffer end!"); + Cursor += 4; + Result = *(uint32_t *)(Str.data()); + return Result; + } + + uint64_t readInt64() { + uint64_t Lo = readInt(); + uint64_t Hi = readInt(); + uint64_t Result = Lo | (Hi << 32); + return Result; + } + + StringRef readString() { + uint32_t Len = readInt() * 4; + StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+Len); + Cursor += Len; + return Str; + } + + uint64_t getCursor() const { return Cursor; } +private: + MemoryBuffer *Buffer; + uint64_t Cursor; +}; + +/// GCOVFile - Collects coverage information for one pair of coverage file +/// (.gcno and .gcda). +class GCOVFile { +public: + GCOVFile() {} + ~GCOVFile(); + bool read(GCOVBuffer &Buffer); + void dump(); + void collectLineCounts(FileInfo &FI); +private: + SmallVector Functions; +}; + +/// GCOVFunction - Collects function information. +class GCOVFunction { +public: + GCOVFunction() : Ident(0), LineNumber(0) {} + ~GCOVFunction(); + bool read(GCOVBuffer &Buffer, GCOVFormat Format); + void dump(); + void collectLineCounts(FileInfo &FI); +private: + uint32_t Ident; + uint32_t LineNumber; + StringRef Name; + StringRef Filename; + SmallVector Blocks; +}; + +/// GCOVBlock - Collects block information. +class GCOVBlock { +public: + GCOVBlock(uint32_t N) : Number(N), Counter(0) {} + ~GCOVBlock(); + void addEdge(uint32_t N) { Edges.push_back(N); } + void addLine(StringRef Filename, uint32_t LineNo); + void addCount(uint64_t N) { Counter = N; } + void dump(); + void collectLineCounts(FileInfo &FI); +private: + uint32_t Number; + uint64_t Counter; + SmallVector Edges; + StringMap Lines; +}; + +/// GCOVLines - A wrapper around a vector of int to keep track of line nos. +class GCOVLines { +public: + ~GCOVLines() { Lines.clear(); } + void add(uint32_t N) { Lines.push_back(N); } + void collectLineCounts(FileInfo &FI, StringRef Filename, uint32_t Count); + void dump(); + +private: + SmallVector Lines; +}; + +typedef SmallVector LineCounts; +class FileInfo { +public: + void addLineCount(StringRef Filename, uint32_t Line, uint32_t Count); + void print(); +private: + StringMap LineInfo; +}; + +} + +#endif diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h index e5e7fc74095d..ef92c95ee7e0 100644 --- a/include/llvm/Support/GetElementPtrTypeIterator.h +++ b/include/llvm/Support/GetElementPtrTypeIterator.h @@ -21,16 +21,16 @@ namespace llvm { template class generic_gep_type_iterator - : public std::iterator { + : public std::iterator { typedef std::iterator super; + Type *, ptrdiff_t> super; ItTy OpIt; - const Type *CurTy; + Type *CurTy; generic_gep_type_iterator() {} public: - static generic_gep_type_iterator begin(const Type *Ty, ItTy It) { + static generic_gep_type_iterator begin(Type *Ty, ItTy It) { generic_gep_type_iterator I; I.CurTy = Ty; I.OpIt = It; @@ -50,23 +50,23 @@ namespace llvm { return !operator==(x); } - const Type *operator*() const { + Type *operator*() const { return CurTy; } - const Type *getIndexedType() const { - const CompositeType *CT = cast(CurTy); + Type *getIndexedType() const { + CompositeType *CT = cast(CurTy); return CT->getTypeAtIndex(getOperand()); } // This is a non-standard operator->. It allows you to call methods on the // current type directly. - const Type *operator->() const { return operator*(); } + Type *operator->() const { return operator*(); } Value *getOperand() const { return *OpIt; } generic_gep_type_iterator& operator++() { // Preincrement - if (const CompositeType *CT = dyn_cast(CurTy)) { + if (CompositeType *CT = dyn_cast(CurTy)) { CurTy = CT->getTypeAtIndex(getOperand()); } else { CurTy = 0; @@ -97,16 +97,16 @@ namespace llvm { return gep_type_iterator::end(GEP.op_end()); } - template - inline generic_gep_type_iterator - gep_type_begin(const Type *Op0, ItTy I, ItTy E) { - return generic_gep_type_iterator::begin(Op0, I); + template + inline generic_gep_type_iterator + gep_type_begin(Type *Op0, ArrayRef A) { + return generic_gep_type_iterator::begin(Op0, A.begin()); } - template - inline generic_gep_type_iterator - gep_type_end(const Type *Op0, ItTy I, ItTy E) { - return generic_gep_type_iterator::end(E); + template + inline generic_gep_type_iterator + gep_type_end(Type *Op0, ArrayRef A) { + return generic_gep_type_iterator::end(A.end()); } } // end namespace llvm diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 91cd78e7f634..782800173f4b 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -475,8 +475,8 @@ class IRBuilder : public IRBuilderBase, public Inserter { Name); } - UnwindInst *CreateUnwind() { - return Insert(new UnwindInst(Context)); + ResumeInst *CreateResume(Value *Exn) { + return Insert(ResumeInst::Create(Exn)); } UnreachableInst *CreateUnreachable() { @@ -744,7 +744,7 @@ class IRBuilder : public IRBuilderBase, public Inserter { // Instruction creation methods: Memory Instructions //===--------------------------------------------------------------------===// - AllocaInst *CreateAlloca(const Type *Ty, Value *ArraySize = 0, + AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = 0, const Twine &Name = "") { return Insert(new AllocaInst(Ty, ArraySize), Name); } @@ -762,71 +762,74 @@ class IRBuilder : public IRBuilderBase, public Inserter { StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) { return Insert(new StoreInst(Val, Ptr, isVolatile)); } - template - Value *CreateGEP(Value *Ptr, - RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + FenceInst *CreateFence(AtomicOrdering Ordering, + SynchronizationScope SynchScope = CrossThread) { + return Insert(new FenceInst(Context, Ordering, SynchScope)); + } + AtomicCmpXchgInst *CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New, + AtomicOrdering Ordering, + SynchronizationScope SynchScope = CrossThread) { + return Insert(new AtomicCmpXchgInst(Ptr, Cmp, New, Ordering, SynchScope)); + } + AtomicRMWInst *CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val, + AtomicOrdering Ordering, + SynchronizationScope SynchScope = CrossThread) { + return Insert(new AtomicRMWInst(Op, Ptr, Val, Ordering, SynchScope)); + } + Value *CreateGEP(Value *Ptr, ArrayRef IdxList, const Twine &Name = "") { if (Constant *PC = dyn_cast(Ptr)) { // Every index must be constant. - RandomAccessIterator i; - for (i = IdxBegin; i < IdxEnd; ++i) - if (!isa(*i)) + size_t i, e; + for (i = 0, e = IdxList.size(); i != e; ++i) + if (!isa(IdxList[i])) break; - if (i == IdxEnd) - return Insert(Folder.CreateGetElementPtr(PC, &IdxBegin[0], - IdxEnd - IdxBegin), - Name); + if (i == e) + return Insert(Folder.CreateGetElementPtr(PC, IdxList), Name); } - return Insert(GetElementPtrInst::Create(Ptr, IdxBegin, IdxEnd), Name); + return Insert(GetElementPtrInst::Create(Ptr, IdxList), Name); } - template - Value *CreateInBoundsGEP(Value *Ptr, RandomAccessIterator IdxBegin, - RandomAccessIterator IdxEnd, + Value *CreateInBoundsGEP(Value *Ptr, ArrayRef IdxList, const Twine &Name = "") { if (Constant *PC = dyn_cast(Ptr)) { // Every index must be constant. - RandomAccessIterator i; - for (i = IdxBegin; i < IdxEnd; ++i) - if (!isa(*i)) + size_t i, e; + for (i = 0, e = IdxList.size(); i != e; ++i) + if (!isa(IdxList[i])) break; - if (i == IdxEnd) - return Insert(Folder.CreateInBoundsGetElementPtr(PC, - &IdxBegin[0], - IdxEnd - IdxBegin), - Name); + if (i == e) + return Insert(Folder.CreateInBoundsGetElementPtr(PC, IdxList), Name); } - return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxBegin, IdxEnd), - Name); + return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxList), Name); } Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") { if (Constant *PC = dyn_cast(Ptr)) if (Constant *IC = dyn_cast(Idx)) - return Insert(Folder.CreateGetElementPtr(PC, &IC, 1), Name); + return Insert(Folder.CreateGetElementPtr(PC, IC), Name); return Insert(GetElementPtrInst::Create(Ptr, Idx), Name); } Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const Twine &Name = "") { if (Constant *PC = dyn_cast(Ptr)) if (Constant *IC = dyn_cast(Idx)) - return Insert(Folder.CreateInBoundsGetElementPtr(PC, &IC, 1), Name); + return Insert(Folder.CreateInBoundsGetElementPtr(PC, IC), Name); return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name); } Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0); if (Constant *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateGetElementPtr(PC, &Idx, 1), Name); + return Insert(Folder.CreateGetElementPtr(PC, Idx), Name); - return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name); + return Insert(GetElementPtrInst::Create(Ptr, Idx), Name); } Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0); if (Constant *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1), Name); + return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name); + return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name); } Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1, const Twine &Name = "") { @@ -836,9 +839,9 @@ class IRBuilder : public IRBuilderBase, public Inserter { }; if (Constant *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateGetElementPtr(PC, Idxs, 2), Name); + return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name); - return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name); + return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name); } Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1, const Twine &Name = "") { @@ -848,26 +851,26 @@ class IRBuilder : public IRBuilderBase, public Inserter { }; if (Constant *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2), Name); + return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name); + return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name); } Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0); if (Constant *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateGetElementPtr(PC, &Idx, 1), Name); + return Insert(Folder.CreateGetElementPtr(PC, Idx), Name); - return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name); + return Insert(GetElementPtrInst::Create(Ptr, Idx), Name); } Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") { Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0); if (Constant *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1), Name); + return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name); + return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name); } Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name = "") { @@ -877,9 +880,9 @@ class IRBuilder : public IRBuilderBase, public Inserter { }; if (Constant *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateGetElementPtr(PC, Idxs, 2), Name); + return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name); - return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name); + return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name); } Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name = "") { @@ -889,9 +892,9 @@ class IRBuilder : public IRBuilderBase, public Inserter { }; if (Constant *PC = dyn_cast(Ptr)) - return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2), Name); + return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name); - return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name); + return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name); } Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") { return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name); @@ -903,54 +906,54 @@ class IRBuilder : public IRBuilderBase, public Inserter { Value *gv = CreateGlobalString(Str, Name); Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0); Value *Args[] = { zero, zero }; - return CreateInBoundsGEP(gv, Args, Args+2, Name); + return CreateInBoundsGEP(gv, Args, Name); } //===--------------------------------------------------------------------===// // Instruction creation methods: Cast/Conversion Operators //===--------------------------------------------------------------------===// - Value *CreateTrunc(Value *V, const Type *DestTy, const Twine &Name = "") { + Value *CreateTrunc(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::Trunc, V, DestTy, Name); } - Value *CreateZExt(Value *V, const Type *DestTy, const Twine &Name = "") { + Value *CreateZExt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::ZExt, V, DestTy, Name); } - Value *CreateSExt(Value *V, const Type *DestTy, const Twine &Name = "") { + Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::SExt, V, DestTy, Name); } - Value *CreateFPToUI(Value *V, const Type *DestTy, const Twine &Name = ""){ + Value *CreateFPToUI(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::FPToUI, V, DestTy, Name); } - Value *CreateFPToSI(Value *V, const Type *DestTy, const Twine &Name = ""){ + Value *CreateFPToSI(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::FPToSI, V, DestTy, Name); } - Value *CreateUIToFP(Value *V, const Type *DestTy, const Twine &Name = ""){ + Value *CreateUIToFP(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::UIToFP, V, DestTy, Name); } - Value *CreateSIToFP(Value *V, const Type *DestTy, const Twine &Name = ""){ + Value *CreateSIToFP(Value *V, Type *DestTy, const Twine &Name = ""){ return CreateCast(Instruction::SIToFP, V, DestTy, Name); } - Value *CreateFPTrunc(Value *V, const Type *DestTy, + Value *CreateFPTrunc(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::FPTrunc, V, DestTy, Name); } - Value *CreateFPExt(Value *V, const Type *DestTy, const Twine &Name = "") { + Value *CreateFPExt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::FPExt, V, DestTy, Name); } - Value *CreatePtrToInt(Value *V, const Type *DestTy, + Value *CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::PtrToInt, V, DestTy, Name); } - Value *CreateIntToPtr(Value *V, const Type *DestTy, + Value *CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::IntToPtr, V, DestTy, Name); } - Value *CreateBitCast(Value *V, const Type *DestTy, + Value *CreateBitCast(Value *V, Type *DestTy, const Twine &Name = "") { return CreateCast(Instruction::BitCast, V, DestTy, Name); } - Value *CreateZExtOrBitCast(Value *V, const Type *DestTy, + Value *CreateZExtOrBitCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -958,7 +961,7 @@ class IRBuilder : public IRBuilderBase, public Inserter { return Insert(Folder.CreateZExtOrBitCast(VC, DestTy), Name); return Insert(CastInst::CreateZExtOrBitCast(V, DestTy), Name); } - Value *CreateSExtOrBitCast(Value *V, const Type *DestTy, + Value *CreateSExtOrBitCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -966,7 +969,7 @@ class IRBuilder : public IRBuilderBase, public Inserter { return Insert(Folder.CreateSExtOrBitCast(VC, DestTy), Name); return Insert(CastInst::CreateSExtOrBitCast(V, DestTy), Name); } - Value *CreateTruncOrBitCast(Value *V, const Type *DestTy, + Value *CreateTruncOrBitCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -974,7 +977,7 @@ class IRBuilder : public IRBuilderBase, public Inserter { return Insert(Folder.CreateTruncOrBitCast(VC, DestTy), Name); return Insert(CastInst::CreateTruncOrBitCast(V, DestTy), Name); } - Value *CreateCast(Instruction::CastOps Op, Value *V, const Type *DestTy, + Value *CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -982,7 +985,7 @@ class IRBuilder : public IRBuilderBase, public Inserter { return Insert(Folder.CreateCast(Op, VC, DestTy), Name); return Insert(CastInst::Create(Op, V, DestTy), Name); } - Value *CreatePointerCast(Value *V, const Type *DestTy, + Value *CreatePointerCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -990,7 +993,7 @@ class IRBuilder : public IRBuilderBase, public Inserter { return Insert(Folder.CreatePointerCast(VC, DestTy), Name); return Insert(CastInst::CreatePointerCast(V, DestTy), Name); } - Value *CreateIntCast(Value *V, const Type *DestTy, bool isSigned, + Value *CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name = "") { if (V->getType() == DestTy) return V; @@ -1001,9 +1004,9 @@ class IRBuilder : public IRBuilderBase, public Inserter { private: // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a compile time // error, instead of converting the string to bool for the isSigned parameter. - Value *CreateIntCast(Value *, const Type *, const char *); // DO NOT IMPLEMENT + Value *CreateIntCast(Value *, Type *, const char *); // DO NOT IMPLEMENT public: - Value *CreateFPCast(Value *V, const Type *DestTy, const Twine &Name = "") { + Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") { if (V->getType() == DestTy) return V; if (Constant *VC = dyn_cast(V)) @@ -1108,7 +1111,7 @@ class IRBuilder : public IRBuilderBase, public Inserter { // Instruction creation methods: Other Instructions //===--------------------------------------------------------------------===// - PHINode *CreatePHI(const Type *Ty, unsigned NumReservedValues, + PHINode *CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name = "") { return Insert(PHINode::Create(Ty, NumReservedValues), Name); } @@ -1142,7 +1145,7 @@ class IRBuilder : public IRBuilderBase, public Inserter { CallInst *CreateCall(Value *Callee, ArrayRef Args, const Twine &Name = "") { - return Insert(CallInst::Create(Callee, Args, Name)); + return Insert(CallInst::Create(Callee, Args), Name); } Value *CreateSelect(Value *C, Value *True, Value *False, @@ -1154,7 +1157,7 @@ class IRBuilder : public IRBuilderBase, public Inserter { return Insert(SelectInst::Create(C, True, False), Name); } - VAArgInst *CreateVAArg(Value *List, const Type *Ty, const Twine &Name = "") { + VAArgInst *CreateVAArg(Value *List, Type *Ty, const Twine &Name = "") { return Insert(new VAArgInst(List, Ty), Name); } @@ -1201,6 +1204,11 @@ class IRBuilder : public IRBuilderBase, public Inserter { return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name); } + LandingPadInst *CreateLandingPad(Type *Ty, Value *PersFn, unsigned NumClauses, + const Twine &Name = "") { + return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses, Name)); + } + //===--------------------------------------------------------------------===// // Utility creation methods //===--------------------------------------------------------------------===// diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index b2e5d58b7c34..a661c4fac68d 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -163,12 +163,16 @@ class InstVisitor { RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);} RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);} + RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(Instruction); } RetTy visitLoadInst(LoadInst &I) { DELEGATE(Instruction); } RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); } + RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I){ DELEGATE(Instruction); } + RetTy visitAtomicRMWInst(AtomicRMWInst &I) { DELEGATE(Instruction); } + RetTy visitFenceInst(FenceInst &I) { DELEGATE(Instruction); } RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); } RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction); } RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst); } @@ -191,6 +195,7 @@ class InstVisitor { RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); } RetTy visitExtractValueInst(ExtractValueInst &I) { DELEGATE(Instruction);} RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } + RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); } // Next level propagators: If the user does not overload a specific // instruction type, they can overload one of these to get the whole class diff --git a/include/llvm/Support/MachO.h b/include/llvm/Support/MachO.h index 6841a0f1fc15..5b6858613ff6 100644 --- a/include/llvm/Support/MachO.h +++ b/include/llvm/Support/MachO.h @@ -110,6 +110,10 @@ namespace llvm { LoadCommandDynamicLinkerInfo = 0x00000022u, // LC_DYLD_INFO LoadCommandDynamicLinkerInfoOnly = 0x80000022u, // LC_DYLD_INFO_ONLY LoadCommandDylibLoadUpward = 0x80000023u, // LC_LOAD_UPWARD_DYLIB + LoadCommandVersionMinMacOSX = 0x00000024u, // LC_VERSION_MIN_MACOSX + LoadCommandVersionMinIPhoneOS = 0x00000025u, // LC_VERSION_MIN_IPHONEOS + LoadCommandFunctionStarts = 0x00000026u, // LC_FUNCTION_STARTS + LoadCommandDyldEnvironment = 0x00000027u, // LC_DYLD_ENVIRONMENT // Constant bits for the "flags" field in llvm::MachO::segment_command SegmentCommandFlagBitHighVM = 0x1u, // SG_HIGHVM @@ -569,6 +573,13 @@ namespace llvm { uint32_t cryptid; }; + struct version_min_command { + uint32_t cmd; + uint32_t cmdsize; + uint32_t version; + uint32_t reserved; + }; + struct dyld_info_command { uint32_t cmd; uint32_t cmdsize; diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h index 5e55bd981f0b..06816de9716a 100644 --- a/include/llvm/Support/MemoryBuffer.h +++ b/include/llvm/Support/MemoryBuffer.h @@ -75,9 +75,9 @@ class MemoryBuffer { /// return a MemoryBuffer. static error_code getOpenFile(int FD, const char *Filename, OwningPtr &result, - size_t FileSize = -1, - size_t MapSize = -1, - off_t Offset = 0, + uint64_t FileSize = -1, + uint64_t MapSize = -1, + int64_t Offset = 0, bool RequiresNullTerminator = true); /// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note diff --git a/include/llvm/Support/NoFolder.h b/include/llvm/Support/NoFolder.h index 94359a5328ef..75c1a79265e2 100644 --- a/include/llvm/Support/NoFolder.h +++ b/include/llvm/Support/NoFolder.h @@ -177,22 +177,22 @@ class NoFolder { // Memory Instructions //===--------------------------------------------------------------------===// - Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getGetElementPtr(C, IdxList, NumIdx); + Constant *CreateGetElementPtr(Constant *C, + ArrayRef IdxList) const { + return ConstantExpr::getGetElementPtr(C, IdxList); } - Instruction *CreateGetElementPtr(Constant *C, Value* const *IdxList, - unsigned NumIdx) const { - return GetElementPtrInst::Create(C, IdxList, IdxList+NumIdx); + Instruction *CreateGetElementPtr(Constant *C, + ArrayRef IdxList) const { + return GetElementPtrInst::Create(C, IdxList); } - Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList, - unsigned NumIdx) const { - return ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx); + Constant *CreateInBoundsGetElementPtr(Constant *C, + ArrayRef IdxList) const { + return ConstantExpr::getInBoundsGetElementPtr(C, IdxList); } - Instruction *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList, - unsigned NumIdx) const { - return GetElementPtrInst::CreateInBounds(C, IdxList, IdxList+NumIdx); + Instruction *CreateInBoundsGetElementPtr(Constant *C, + ArrayRef IdxList) const { + return GetElementPtrInst::CreateInBounds(C, IdxList); } //===--------------------------------------------------------------------===// @@ -200,37 +200,37 @@ class NoFolder { //===--------------------------------------------------------------------===// Instruction *CreateCast(Instruction::CastOps Op, Constant *C, - const Type *DestTy) const { + Type *DestTy) const { return CastInst::Create(Op, C, DestTy); } - Instruction *CreatePointerCast(Constant *C, const Type *DestTy) const { + Instruction *CreatePointerCast(Constant *C, Type *DestTy) const { return CastInst::CreatePointerCast(C, DestTy); } - Instruction *CreateIntCast(Constant *C, const Type *DestTy, + Instruction *CreateIntCast(Constant *C, Type *DestTy, bool isSigned) const { return CastInst::CreateIntegerCast(C, DestTy, isSigned); } - Instruction *CreateFPCast(Constant *C, const Type *DestTy) const { + Instruction *CreateFPCast(Constant *C, Type *DestTy) const { return CastInst::CreateFPCast(C, DestTy); } - Instruction *CreateBitCast(Constant *C, const Type *DestTy) const { + Instruction *CreateBitCast(Constant *C, Type *DestTy) const { return CreateCast(Instruction::BitCast, C, DestTy); } - Instruction *CreateIntToPtr(Constant *C, const Type *DestTy) const { + Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const { return CreateCast(Instruction::IntToPtr, C, DestTy); } - Instruction *CreatePtrToInt(Constant *C, const Type *DestTy) const { + Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const { return CreateCast(Instruction::PtrToInt, C, DestTy); } - Instruction *CreateZExtOrBitCast(Constant *C, const Type *DestTy) const { + Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { return CastInst::CreateZExtOrBitCast(C, DestTy); } - Instruction *CreateSExtOrBitCast(Constant *C, const Type *DestTy) const { + Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { return CastInst::CreateSExtOrBitCast(C, DestTy); } - Instruction *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const { + Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { return CastInst::CreateTruncOrBitCast(C, DestTy); } diff --git a/include/llvm/Support/PassManagerBuilder.h b/include/llvm/Support/PassManagerBuilder.h deleted file mode 100644 index b0cec6e81b10..000000000000 --- a/include/llvm/Support/PassManagerBuilder.h +++ /dev/null @@ -1,331 +0,0 @@ -//===-- llvm/Support/PassManagerBuilder.h - Build Standard Pass -*- 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 PassManagerBuilder class, which is used to set up a -// "standard" optimization sequence suitable for languages like C and C++. -// -// These are implemented as inline functions so that we do not have to worry -// about link issues. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_PASSMANAGERBUILDER_H -#define LLVM_SUPPORT_PASSMANAGERBUILDER_H - -#include "llvm/PassManager.h" -#include "llvm/DefaultPasses.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Target/TargetLibraryInfo.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/IPO.h" - -namespace llvm { - -/// PassManagerBuilder - This class is used to set up a standard optimization -/// sequence for languages like C and C++, allowing some APIs to customize the -/// pass sequence in various ways. A simple example of using it would be: -/// -/// PassManagerBuilder Builder; -/// Builder.OptLevel = 2; -/// Builder.populateFunctionPassManager(FPM); -/// Builder.populateModulePassManager(MPM); -/// -/// In addition to setting up the basic passes, PassManagerBuilder allows -/// frontends to vend a plugin API, where plugins are allowed to add extensions -/// to the default pass manager. They do this by specifying where in the pass -/// pipeline they want to be added, along with a callback function that adds -/// the pass(es). For example, a plugin that wanted to add a loop optimization -/// could do something like this: -/// -/// static void addMyLoopPass(const PMBuilder &Builder, PassManagerBase &PM) { -/// if (Builder.getOptLevel() > 2 && Builder.getOptSizeLevel() == 0) -/// PM.add(createMyAwesomePass()); -/// } -/// ... -/// Builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, -/// addMyLoopPass); -/// ... -class PassManagerBuilder { -public: - - /// Extensions are passed the builder itself (so they can see how it is - /// configured) as well as the pass manager to add stuff to. - typedef void (*ExtensionFn)(const PassManagerBuilder &Builder, - PassManagerBase &PM); - enum ExtensionPointTy { - /// EP_EarlyAsPossible - This extension point allows adding passes before - /// any other transformations, allowing them to see the code as it is coming - /// out of the frontend. - EP_EarlyAsPossible, - - /// EP_LoopOptimizerEnd - This extension point allows adding loop passes to - /// the end of the loop optimizer. - EP_LoopOptimizerEnd, - - /// EP_ScalarOptimizerLate - This extension point allows adding optimization - /// passes after most of the main optimizations, but before the last - /// cleanup-ish optimizations. - EP_ScalarOptimizerLate - }; - - /// The Optimization Level - Specify the basic optimization level. - /// 0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3 - unsigned OptLevel; - - /// SizeLevel - How much we're optimizing for size. - /// 0 = none, 1 = -Os, 2 = -Oz - unsigned SizeLevel; - - /// LibraryInfo - Specifies information about the runtime library for the - /// optimizer. If this is non-null, it is added to both the function and - /// per-module pass pipeline. - TargetLibraryInfo *LibraryInfo; - - /// Inliner - Specifies the inliner to use. If this is non-null, it is - /// added to the per-module passes. - Pass *Inliner; - - bool DisableSimplifyLibCalls; - bool DisableUnitAtATime; - bool DisableUnrollLoops; - -private: - /// ExtensionList - This is list of all of the extensions that are registered. - std::vector > Extensions; - -public: - PassManagerBuilder() { - OptLevel = 2; - SizeLevel = 0; - LibraryInfo = 0; - Inliner = 0; - DisableSimplifyLibCalls = false; - DisableUnitAtATime = false; - DisableUnrollLoops = false; - } - - ~PassManagerBuilder() { - delete LibraryInfo; - delete Inliner; - } - - void addExtension(ExtensionPointTy Ty, ExtensionFn Fn) { - Extensions.push_back(std::make_pair(Ty, Fn)); - } - -private: - void addExtensionsToPM(ExtensionPointTy ETy, PassManagerBase &PM) const { - for (unsigned i = 0, e = Extensions.size(); i != e; ++i) - if (Extensions[i].first == ETy) - Extensions[i].second(*this, PM); - } - - void addInitialAliasAnalysisPasses(PassManagerBase &PM) const { - // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that - // BasicAliasAnalysis wins if they disagree. This is intended to help - // support "obvious" type-punning idioms. - PM.add(createTypeBasedAliasAnalysisPass()); - PM.add(createBasicAliasAnalysisPass()); - } -public: - - /// populateFunctionPassManager - This fills in the function pass manager, - /// which is expected to be run on each function immediately as it is - /// generated. The idea is to reduce the size of the IR in memory. - void populateFunctionPassManager(FunctionPassManager &FPM) { - addExtensionsToPM(EP_EarlyAsPossible, FPM); - - // Add LibraryInfo if we have some. - if (LibraryInfo) FPM.add(new TargetLibraryInfo(*LibraryInfo)); - - if (OptLevel == 0) return; - - addInitialAliasAnalysisPasses(FPM); - - FPM.add(createCFGSimplificationPass()); - FPM.add(createScalarReplAggregatesPass()); - FPM.add(createEarlyCSEPass()); - FPM.add(createLowerExpectIntrinsicPass()); - } - - /// populateModulePassManager - This sets up the primary pass manager. - void populateModulePassManager(PassManagerBase &MPM) { - // If all optimizations are disabled, just run the always-inline pass. - if (OptLevel == 0) { - if (Inliner) { - MPM.add(Inliner); - Inliner = 0; - } - return; - } - - // Add LibraryInfo if we have some. - if (LibraryInfo) MPM.add(new TargetLibraryInfo(*LibraryInfo)); - - addInitialAliasAnalysisPasses(MPM); - - if (!DisableUnitAtATime) { - MPM.add(createGlobalOptimizerPass()); // Optimize out global vars - - MPM.add(createIPSCCPPass()); // IP SCCP - MPM.add(createDeadArgEliminationPass()); // Dead argument elimination - - MPM.add(createInstructionCombiningPass());// Clean up after IPCP & DAE - MPM.add(createCFGSimplificationPass()); // Clean up after IPCP & DAE - } - - // Start of CallGraph SCC passes. - if (!DisableUnitAtATime) - MPM.add(createPruneEHPass()); // Remove dead EH info - if (Inliner) { - MPM.add(Inliner); - Inliner = 0; - } - if (!DisableUnitAtATime) - MPM.add(createFunctionAttrsPass()); // Set readonly/readnone attrs - if (OptLevel > 2) - MPM.add(createArgumentPromotionPass()); // Scalarize uninlined fn args - - // Start of function pass. - // Break up aggregate allocas, using SSAUpdater. - MPM.add(createScalarReplAggregatesPass(-1, false)); - MPM.add(createEarlyCSEPass()); // Catch trivial redundancies - if (!DisableSimplifyLibCalls) - MPM.add(createSimplifyLibCallsPass()); // Library Call Optimizations - MPM.add(createJumpThreadingPass()); // Thread jumps. - MPM.add(createCorrelatedValuePropagationPass()); // Propagate conditionals - MPM.add(createCFGSimplificationPass()); // Merge & remove BBs - MPM.add(createInstructionCombiningPass()); // Combine silly seq's - - MPM.add(createTailCallEliminationPass()); // Eliminate tail calls - MPM.add(createCFGSimplificationPass()); // Merge & remove BBs - MPM.add(createReassociatePass()); // Reassociate expressions - MPM.add(createLoopRotatePass()); // Rotate Loop - MPM.add(createLICMPass()); // Hoist loop invariants - MPM.add(createLoopUnswitchPass(SizeLevel || OptLevel < 3)); - MPM.add(createInstructionCombiningPass()); - MPM.add(createIndVarSimplifyPass()); // Canonicalize indvars - MPM.add(createLoopIdiomPass()); // Recognize idioms like memset. - MPM.add(createLoopDeletionPass()); // Delete dead loops - if (!DisableUnrollLoops) - MPM.add(createLoopUnrollPass()); // Unroll small loops - addExtensionsToPM(EP_LoopOptimizerEnd, MPM); - - if (OptLevel > 1) - MPM.add(createGVNPass()); // Remove redundancies - MPM.add(createMemCpyOptPass()); // Remove memcpy / form memset - MPM.add(createSCCPPass()); // Constant prop with SCCP - - // Run instcombine after redundancy elimination to exploit opportunities - // opened up by them. - MPM.add(createInstructionCombiningPass()); - MPM.add(createJumpThreadingPass()); // Thread jumps - MPM.add(createCorrelatedValuePropagationPass()); - MPM.add(createDeadStoreEliminationPass()); // Delete dead stores - - addExtensionsToPM(EP_ScalarOptimizerLate, MPM); - - MPM.add(createAggressiveDCEPass()); // Delete dead instructions - MPM.add(createCFGSimplificationPass()); // Merge & remove BBs - MPM.add(createInstructionCombiningPass()); // Clean up after everything. - - if (!DisableUnitAtATime) { - // FIXME: We shouldn't bother with this anymore. - MPM.add(createStripDeadPrototypesPass()); // Get rid of dead prototypes - - // GlobalOpt already deletes dead functions and globals, at -O3 try a - // late pass of GlobalDCE. It is capable of deleting dead cycles. - if (OptLevel > 2) - MPM.add(createGlobalDCEPass()); // Remove dead fns and globals. - - if (OptLevel > 1) - MPM.add(createConstantMergePass()); // Merge dup global constants - } - } - - void populateLTOPassManager(PassManagerBase &PM, bool Internalize, - bool RunInliner) { - // Provide AliasAnalysis services for optimizations. - addInitialAliasAnalysisPasses(PM); - - // Now that composite has been compiled, scan through the module, looking - // for a main function. If main is defined, mark all other functions - // internal. - if (Internalize) - PM.add(createInternalizePass(true)); - - // Propagate constants at call sites into the functions they call. This - // opens opportunities for globalopt (and inlining) by substituting function - // pointers passed as arguments to direct uses of functions. - PM.add(createIPSCCPPass()); - - // Now that we internalized some globals, see if we can hack on them! - PM.add(createGlobalOptimizerPass()); - - // Linking modules together can lead to duplicated global constants, only - // keep one copy of each constant. - PM.add(createConstantMergePass()); - - // Remove unused arguments from functions. - PM.add(createDeadArgEliminationPass()); - - // Reduce the code after globalopt and ipsccp. Both can open up significant - // simplification opportunities, and both can propagate functions through - // function pointers. When this happens, we often have to resolve varargs - // calls, etc, so let instcombine do this. - PM.add(createInstructionCombiningPass()); - - // Inline small functions - if (RunInliner) - PM.add(createFunctionInliningPass()); - - PM.add(createPruneEHPass()); // Remove dead EH info. - - // Optimize globals again if we ran the inliner. - if (RunInliner) - PM.add(createGlobalOptimizerPass()); - PM.add(createGlobalDCEPass()); // Remove dead functions. - - // If we didn't decide to inline a function, check to see if we can - // transform it to pass arguments by value instead of by reference. - PM.add(createArgumentPromotionPass()); - - // The IPO passes may leave cruft around. Clean up after them. - PM.add(createInstructionCombiningPass()); - PM.add(createJumpThreadingPass()); - // Break up allocas - PM.add(createScalarReplAggregatesPass()); - - // Run a few AA driven optimizations here and now, to cleanup the code. - PM.add(createFunctionAttrsPass()); // Add nocapture. - PM.add(createGlobalsModRefPass()); // IP alias analysis. - - PM.add(createLICMPass()); // Hoist loop invariants. - PM.add(createGVNPass()); // Remove redundancies. - PM.add(createMemCpyOptPass()); // Remove dead memcpys. - // Nuke dead stores. - PM.add(createDeadStoreEliminationPass()); - - // Cleanup and simplify the code after the scalar optimizations. - PM.add(createInstructionCombiningPass()); - - PM.add(createJumpThreadingPass()); - - // Delete basic blocks, which optimization passes may have killed. - PM.add(createCFGSimplificationPass()); - - // Now that we have optimized the program, discard unreachable functions. - PM.add(createGlobalDCEPass()); - } -}; - - -} // end namespace llvm -#endif diff --git a/include/llvm/Support/PathV1.h b/include/llvm/Support/PathV1.h index 024bb39cedc2..45165ded619c 100644 --- a/include/llvm/Support/PathV1.h +++ b/include/llvm/Support/PathV1.h @@ -733,6 +733,7 @@ namespace sys { Mach_O_DynamicLinker_FileType, ///< The Mach-O dynamic linker Mach_O_Bundle_FileType, ///< Mach-O Bundle file Mach_O_DynamicallyLinkedSharedLibStub_FileType, ///< Mach-O Shared lib stub + Mach_O_DSYMCompanion_FileType, ///< Mach-O dSYM companion file COFF_FileType ///< COFF object file or lib }; diff --git a/include/llvm/Support/PathV2.h b/include/llvm/Support/PathV2.h index 251563398fb4..6d38c9571558 100644 --- a/include/llvm/Support/PathV2.h +++ b/include/llvm/Support/PathV2.h @@ -187,7 +187,7 @@ const StringRef root_name(StringRef path); /// @result The root directory of \a path if it has one, otherwise /// "". const StringRef root_directory(StringRef path); - + /// @brief Get root path. /// /// Equivalent to root_name + root_directory. @@ -264,6 +264,17 @@ const StringRef extension(StringRef path); /// @result true if \a value is a path separator character on the host OS bool is_separator(char value); +/// @brief Get the typical temporary directory for the system, e.g., +/// "/var/tmp" or "C:/TEMP" +/// +/// @param erasedOnReboot Whether to favor a path that is erased on reboot +/// rather than one that potentially persists longer. This parameter will be +/// ignored if the user or system has set the typical environment variable +/// (e.g., TEMP on Windows, TMPDIR on *nix) to specify a temporary directory. +/// +/// @param Result Holds the resulting path name. +void system_temp_directory(bool erasedOnReboot, SmallVectorImpl &result); + /// @brief Has root name? /// /// root_name != "" diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h index 33799229ff35..27ef2670093a 100644 --- a/include/llvm/Support/Process.h +++ b/include/llvm/Support/Process.h @@ -138,6 +138,9 @@ namespace sys { /// Resets the terminals colors, or returns an escape sequence to do so. static const char *ResetColor(); + + /// Change the program working directory to that given by \arg Path. + static void SetWorkingDirectory(std::string Path); /// @} }; } diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h index 967bf1432c64..02db32794b6d 100644 --- a/include/llvm/Support/SMLoc.h +++ b/include/llvm/Support/SMLoc.h @@ -18,19 +18,19 @@ namespace llvm { // SMLoc - Represents a location in source code. -class SMLoc { +class SMLoc { const char *Ptr; public: SMLoc() : Ptr(0) {} SMLoc(const SMLoc &RHS) : Ptr(RHS.Ptr) {} - + bool isValid() const { return Ptr != 0; } - + bool operator==(const SMLoc &RHS) const { return RHS.Ptr == Ptr; } bool operator!=(const SMLoc &RHS) const { return RHS.Ptr != Ptr; } - + const char *getPointer() const { return Ptr; } - + static SMLoc getFromPointer(const char *Ptr) { SMLoc L; L.Ptr = Ptr; diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h index 030db8f4e3fd..deb8cafa06d2 100644 --- a/include/llvm/Support/SourceMgr.h +++ b/include/llvm/Support/SourceMgr.h @@ -78,6 +78,9 @@ class SourceMgr { DiagContext = Ctx; } + DiagHandlerTy getDiagHandler() const { return DiagHandler; } + void *getDiagContext() const { return DiagContext; } + const SrcBuffer &getBufferInfo(unsigned i) const { assert(i < Buffers.size() && "Invalid Buffer ID!"); return Buffers[i]; @@ -138,8 +141,12 @@ class SourceMgr { const Twine &Msg, const char *Type, bool ShowLine = true) const; - -private: + /// PrintIncludeStack - Prints the names of included files and the line of the + /// file they were included from. A diagnostic handler can use this before + /// printing its custom formatted message. + /// + /// @param IncludeLoc - The line of the include. + /// @param OS the raw_ostream to print on. void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const; }; diff --git a/include/llvm/Support/TargetFolder.h b/include/llvm/Support/TargetFolder.h index 3233a98da9c1..c65faa66219e 100644 --- a/include/llvm/Support/TargetFolder.h +++ b/include/llvm/Support/TargetFolder.h @@ -130,22 +130,34 @@ class TargetFolder { // Memory Instructions //===--------------------------------------------------------------------===// - Constant *CreateGetElementPtr(Constant *C, Constant* const *IdxList, - unsigned NumIdx) const { - return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx)); + Constant *CreateGetElementPtr(Constant *C, + ArrayRef IdxList) const { + return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); } - Constant *CreateGetElementPtr(Constant *C, Value* const *IdxList, - unsigned NumIdx) const { - return Fold(ConstantExpr::getGetElementPtr(C, IdxList, NumIdx)); + Constant *CreateGetElementPtr(Constant *C, Constant *Idx) const { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef or + // ArrayRef. + return Fold(ConstantExpr::getGetElementPtr(C, Idx)); + } + Constant *CreateGetElementPtr(Constant *C, + ArrayRef IdxList) const { + return Fold(ConstantExpr::getGetElementPtr(C, IdxList)); } - Constant *CreateInBoundsGetElementPtr(Constant *C, Constant* const *IdxList, - unsigned NumIdx) const { - return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx)); + Constant *CreateInBoundsGetElementPtr(Constant *C, + ArrayRef IdxList) const { + return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); } - Constant *CreateInBoundsGetElementPtr(Constant *C, Value* const *IdxList, - unsigned NumIdx) const { - return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList, NumIdx)); + Constant *CreateInBoundsGetElementPtr(Constant *C, Constant *Idx) const { + // This form of the function only exists to avoid ambiguous overload + // warnings about whether to convert Idx to ArrayRef or + // ArrayRef. + return Fold(ConstantExpr::getInBoundsGetElementPtr(C, Idx)); + } + Constant *CreateInBoundsGetElementPtr(Constant *C, + ArrayRef IdxList) const { + return Fold(ConstantExpr::getInBoundsGetElementPtr(C, IdxList)); } //===--------------------------------------------------------------------===// @@ -153,40 +165,40 @@ class TargetFolder { //===--------------------------------------------------------------------===// Constant *CreateCast(Instruction::CastOps Op, Constant *C, - const Type *DestTy) const { + Type *DestTy) const { if (C->getType() == DestTy) return C; // avoid calling Fold return Fold(ConstantExpr::getCast(Op, C, DestTy)); } - Constant *CreateIntCast(Constant *C, const Type *DestTy, + Constant *CreateIntCast(Constant *C, Type *DestTy, bool isSigned) const { if (C->getType() == DestTy) return C; // avoid calling Fold return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned)); } - Constant *CreatePointerCast(Constant *C, const Type *DestTy) const { + Constant *CreatePointerCast(Constant *C, Type *DestTy) const { return ConstantExpr::getPointerCast(C, DestTy); } - Constant *CreateBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateBitCast(Constant *C, Type *DestTy) const { return CreateCast(Instruction::BitCast, C, DestTy); } - Constant *CreateIntToPtr(Constant *C, const Type *DestTy) const { + Constant *CreateIntToPtr(Constant *C, Type *DestTy) const { return CreateCast(Instruction::IntToPtr, C, DestTy); } - Constant *CreatePtrToInt(Constant *C, const Type *DestTy) const { + Constant *CreatePtrToInt(Constant *C, Type *DestTy) const { return CreateCast(Instruction::PtrToInt, C, DestTy); } - Constant *CreateZExtOrBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const { if (C->getType() == DestTy) return C; // avoid calling Fold return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy)); } - Constant *CreateSExtOrBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const { if (C->getType() == DestTy) return C; // avoid calling Fold return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy)); } - Constant *CreateTruncOrBitCast(Constant *C, const Type *DestTy) const { + Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const { if (C->getType() == DestTy) return C; // avoid calling Fold return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy)); diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h similarity index 66% rename from include/llvm/Target/TargetRegistry.h rename to include/llvm/Support/TargetRegistry.h index 7e0ce19f8f84..45f249d7ed0e 100644 --- a/include/llvm/Target/TargetRegistry.h +++ b/include/llvm/Support/TargetRegistry.h @@ -1,4 +1,4 @@ -//===-- Target/TargetRegistry.h - Target Registration -----------*- C++ -*-===// +//===-- Support/TargetRegistry.h - Target Registration ----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,9 +16,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_TARGETREGISTRY_H -#define LLVM_TARGET_TARGETREGISTRY_H +#ifndef LLVM_SUPPORT_TARGETREGISTRY_H +#define LLVM_SUPPORT_TARGETREGISTRY_H +#include "llvm/Support/CodeGen.h" #include "llvm/ADT/Triple.h" #include #include @@ -27,19 +28,21 @@ namespace llvm { class AsmPrinter; class Module; class MCAssembler; + class MCAsmBackend; class MCAsmInfo; class MCAsmParser; class MCCodeEmitter; + class MCCodeGenInfo; class MCContext; class MCDisassembler; + class MCInstrAnalysis; class MCInstPrinter; class MCInstrInfo; class MCRegisterInfo; class MCStreamer; class MCSubtargetInfo; - class TargetAsmBackend; - class TargetAsmLexer; - class TargetAsmParser; + class MCTargetAsmLexer; + class MCTargetAsmParser; class TargetMachine; class raw_ostream; class formatted_raw_ostream; @@ -49,7 +52,7 @@ namespace llvm { bool useLoc, bool useCFI, MCInstPrinter *InstPrint, MCCodeEmitter *CE, - TargetAsmBackend *TAB, + MCAsmBackend *TAB, bool ShowInst); /// Target - Wrapper for Target specific information. @@ -68,38 +71,46 @@ namespace llvm { typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const Target &T, StringRef TT); + typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, + Reloc::Model RM, + CodeModel::Model CM); typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void); - typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(void); + typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo*Info); + typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT); typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT, StringRef CPU, StringRef Features); typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T, - const std::string &TT, - const std::string &CPU, - const std::string &Features); + StringRef TT, + StringRef CPU, + StringRef Features, + Reloc::Model RM, + CodeModel::Model CM); typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM, MCStreamer &Streamer); - typedef TargetAsmBackend *(*AsmBackendCtorTy)(const Target &T, - const std::string &TT); - typedef TargetAsmLexer *(*AsmLexerCtorTy)(const Target &T, - const MCAsmInfo &MAI); - typedef TargetAsmParser *(*AsmParserCtorTy)(MCSubtargetInfo &STI, - MCAsmParser &P); - typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T); + typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T, StringRef TT); + typedef MCTargetAsmLexer *(*MCAsmLexerCtorTy)(const Target &T, + const MCRegisterInfo &MRI, + const MCAsmInfo &MAI); + typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI, + MCAsmParser &P); + typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T, + const MCSubtargetInfo &STI); typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T, unsigned SyntaxVariant, - const MCAsmInfo &MAI); - typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const MCInstrInfo &II, - const MCSubtargetInfo &STI, - MCContext &Ctx); - typedef MCStreamer *(*ObjectStreamerCtorTy)(const Target &T, - const std::string &TT, - MCContext &Ctx, - TargetAsmBackend &TAB, - raw_ostream &_OS, - MCCodeEmitter *_Emitter, - bool RelaxAll, - bool NoExecStack); + const MCAsmInfo &MAI, + const MCSubtargetInfo &STI); + typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II, + const MCSubtargetInfo &STI, + MCContext &Ctx); + typedef MCStreamer *(*MCObjectStreamerCtorTy)(const Target &T, + StringRef TT, + MCContext &Ctx, + MCAsmBackend &TAB, + raw_ostream &_OS, + MCCodeEmitter *_Emitter, + bool RelaxAll, + bool NoExecStack); typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx, formatted_raw_ostream &OS, bool isVerboseAsm, @@ -107,7 +118,7 @@ namespace llvm { bool useCFI, MCInstPrinter *InstPrint, MCCodeEmitter *CE, - TargetAsmBackend *TAB, + MCAsmBackend *TAB, bool ShowInst); private: @@ -132,10 +143,18 @@ namespace llvm { /// registered. MCAsmInfoCtorFnTy MCAsmInfoCtorFn; + /// MCCodeGenInfoCtorFn - Constructor function for this target's MCCodeGenInfo, + /// if registered. + MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn; + /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo, /// if registered. MCInstrInfoCtorFnTy MCInstrInfoCtorFn; + /// MCInstrAnalysisCtorFn - Constructor function for this target's + /// MCInstrAnalysis, if registered. + MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn; + /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo, /// if registered. MCRegInfoCtorFnTy MCRegInfoCtorFn; @@ -148,17 +167,17 @@ namespace llvm { /// TargetMachine, if registered. TargetMachineCtorTy TargetMachineCtorFn; - /// AsmBackendCtorFn - Construction function for this target's - /// TargetAsmBackend, if registered. - AsmBackendCtorTy AsmBackendCtorFn; + /// MCAsmBackendCtorFn - Construction function for this target's + /// MCAsmBackend, if registered. + MCAsmBackendCtorTy MCAsmBackendCtorFn; - /// AsmLexerCtorFn - Construction function for this target's TargetAsmLexer, - /// if registered. - AsmLexerCtorTy AsmLexerCtorFn; + /// MCAsmLexerCtorFn - Construction function for this target's + /// MCTargetAsmLexer, if registered. + MCAsmLexerCtorTy MCAsmLexerCtorFn; - /// AsmParserCtorFn - Construction function for this target's - /// TargetAsmParser, if registered. - AsmParserCtorTy AsmParserCtorFn; + /// MCAsmParserCtorFn - Construction function for this target's + /// MCTargetAsmParser, if registered. + MCAsmParserCtorTy MCAsmParserCtorFn; /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter, /// if registered. @@ -172,13 +191,13 @@ namespace llvm { /// MCInstPrinter, if registered. MCInstPrinterCtorTy MCInstPrinterCtorFn; - /// CodeEmitterCtorFn - Construction function for this target's CodeEmitter, - /// if registered. - CodeEmitterCtorTy CodeEmitterCtorFn; + /// MCCodeEmitterCtorFn - Construction function for this target's + /// CodeEmitter, if registered. + MCCodeEmitterCtorTy MCCodeEmitterCtorFn; - /// ObjectStreamerCtorFn - Construction function for this target's - /// ObjectStreamer, if registered. - ObjectStreamerCtorTy ObjectStreamerCtorFn; + /// MCObjectStreamerCtorFn - Construction function for this target's + /// MCObjectStreamer, if registered. + MCObjectStreamerCtorTy MCObjectStreamerCtorFn; /// AsmStreamerCtorFn - Construction function for this target's /// AsmStreamer, if registered (default = llvm::createAsmStreamer). @@ -209,14 +228,14 @@ namespace llvm { /// hasTargetMachine - Check if this target supports code generation. bool hasTargetMachine() const { return TargetMachineCtorFn != 0; } - /// hasAsmBackend - Check if this target supports .o generation. - bool hasAsmBackend() const { return AsmBackendCtorFn != 0; } + /// hasMCAsmBackend - Check if this target supports .o generation. + bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != 0; } - /// hasAsmLexer - Check if this target supports .s lexing. - bool hasAsmLexer() const { return AsmLexerCtorFn != 0; } + /// hasMCAsmLexer - Check if this target supports .s lexing. + bool hasMCAsmLexer() const { return MCAsmLexerCtorFn != 0; } /// hasAsmParser - Check if this target supports .s parsing. - bool hasAsmParser() const { return AsmParserCtorFn != 0; } + bool hasMCAsmParser() const { return MCAsmParserCtorFn != 0; } /// hasAsmPrinter - Check if this target supports .s printing. bool hasAsmPrinter() const { return AsmPrinterCtorFn != 0; } @@ -227,11 +246,11 @@ namespace llvm { /// hasMCInstPrinter - Check if this target has an instruction printer. bool hasMCInstPrinter() const { return MCInstPrinterCtorFn != 0; } - /// hasCodeEmitter - Check if this target supports instruction encoding. - bool hasCodeEmitter() const { return CodeEmitterCtorFn != 0; } + /// hasMCCodeEmitter - Check if this target supports instruction encoding. + bool hasMCCodeEmitter() const { return MCCodeEmitterCtorFn != 0; } - /// hasObjectStreamer - Check if this target supports streaming to files. - bool hasObjectStreamer() const { return ObjectStreamerCtorFn != 0; } + /// hasMCObjectStreamer - Check if this target supports streaming to files. + bool hasMCObjectStreamer() const { return MCObjectStreamerCtorFn != 0; } /// hasAsmStreamer - Check if this target supports streaming to files. bool hasAsmStreamer() const { return AsmStreamerCtorFn != 0; } @@ -253,6 +272,15 @@ namespace llvm { return MCAsmInfoCtorFn(*this, Triple); } + /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation. + /// + MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM, + CodeModel::Model CM) const { + if (!MCCodeGenInfoCtorFn) + return 0; + return MCCodeGenInfoCtorFn(Triple, RM, CM); + } + /// createMCInstrInfo - Create a MCInstrInfo implementation. /// MCInstrInfo *createMCInstrInfo() const { @@ -261,12 +289,20 @@ namespace llvm { return MCInstrInfoCtorFn(); } + /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation. + /// + MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const { + if (!MCInstrAnalysisCtorFn) + return 0; + return MCInstrAnalysisCtorFn(Info); + } + /// createMCRegInfo - Create a MCRegisterInfo implementation. /// - MCRegisterInfo *createMCRegInfo() const { + MCRegisterInfo *createMCRegInfo(StringRef Triple) const { if (!MCRegInfoCtorFn) return 0; - return MCRegInfoCtorFn(); + return MCRegInfoCtorFn(Triple); } /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation. @@ -292,41 +328,43 @@ namespace llvm { /// feature set; it should always be provided. Generally this should be /// either the target triple from the module, or the target triple of the /// host if that does not exist. - TargetMachine *createTargetMachine(const std::string &Triple, - const std::string &CPU, - const std::string &Features) const { + TargetMachine *createTargetMachine(StringRef Triple, StringRef CPU, + StringRef Features, + Reloc::Model RM = Reloc::Default, + CodeModel::Model CM = CodeModel::Default) const { if (!TargetMachineCtorFn) return 0; - return TargetMachineCtorFn(*this, Triple, CPU, Features); + return TargetMachineCtorFn(*this, Triple, CPU, Features, RM, CM); } - /// createAsmBackend - Create a target specific assembly parser. + /// createMCAsmBackend - Create a target specific assembly parser. /// /// \arg Triple - The target triple string. /// \arg Backend - The target independent assembler object. - TargetAsmBackend *createAsmBackend(const std::string &Triple) const { - if (!AsmBackendCtorFn) + MCAsmBackend *createMCAsmBackend(StringRef Triple) const { + if (!MCAsmBackendCtorFn) return 0; - return AsmBackendCtorFn(*this, Triple); + return MCAsmBackendCtorFn(*this, Triple); } - /// createAsmLexer - Create a target specific assembly lexer. + /// createMCAsmLexer - Create a target specific assembly lexer. /// - TargetAsmLexer *createAsmLexer(const MCAsmInfo &MAI) const { - if (!AsmLexerCtorFn) + MCTargetAsmLexer *createMCAsmLexer(const MCRegisterInfo &MRI, + const MCAsmInfo &MAI) const { + if (!MCAsmLexerCtorFn) return 0; - return AsmLexerCtorFn(*this, MAI); + return MCAsmLexerCtorFn(*this, MRI, MAI); } - /// createAsmParser - Create a target specific assembly parser. + /// createMCAsmParser - Create a target specific assembly parser. /// /// \arg Parser - The target independent parser implementation to use for /// parsing and lexing. - TargetAsmParser *createAsmParser(MCSubtargetInfo &STI, - MCAsmParser &Parser) const { - if (!AsmParserCtorFn) + MCTargetAsmParser *createMCAsmParser(MCSubtargetInfo &STI, + MCAsmParser &Parser) const { + if (!MCAsmParserCtorFn) return 0; - return AsmParserCtorFn(STI, Parser); + return MCAsmParserCtorFn(STI, Parser); } /// createAsmPrinter - Create a target specific assembly printer pass. This @@ -337,30 +375,31 @@ namespace llvm { return AsmPrinterCtorFn(TM, Streamer); } - MCDisassembler *createMCDisassembler() const { + MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI) const { if (!MCDisassemblerCtorFn) return 0; - return MCDisassemblerCtorFn(*this); + return MCDisassemblerCtorFn(*this, STI); } MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant, - const MCAsmInfo &MAI) const { + const MCAsmInfo &MAI, + const MCSubtargetInfo &STI) const { if (!MCInstPrinterCtorFn) return 0; - return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI); + return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, STI); } - /// createCodeEmitter - Create a target specific code emitter. - MCCodeEmitter *createCodeEmitter(const MCInstrInfo &II, - const MCSubtargetInfo &STI, - MCContext &Ctx) const { - if (!CodeEmitterCtorFn) + /// createMCCodeEmitter - Create a target specific code emitter. + MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II, + const MCSubtargetInfo &STI, + MCContext &Ctx) const { + if (!MCCodeEmitterCtorFn) return 0; - return CodeEmitterCtorFn(II, STI, Ctx); + return MCCodeEmitterCtorFn(II, STI, Ctx); } - /// createObjectStreamer - Create a target specific MCStreamer. + /// createMCObjectStreamer - Create a target specific MCStreamer. /// /// \arg TT - The target triple. /// \arg Ctx - The target context. @@ -369,16 +408,16 @@ namespace llvm { /// \arg _Emitter - The target independent assembler object.Takes ownership. /// \arg RelaxAll - Relax all fixups? /// \arg NoExecStack - Mark file as not needing a executable stack. - MCStreamer *createObjectStreamer(const std::string &TT, MCContext &Ctx, - TargetAsmBackend &TAB, - raw_ostream &_OS, - MCCodeEmitter *_Emitter, - bool RelaxAll, - bool NoExecStack) const { - if (!ObjectStreamerCtorFn) + MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx, + MCAsmBackend &TAB, + raw_ostream &_OS, + MCCodeEmitter *_Emitter, + bool RelaxAll, + bool NoExecStack) const { + if (!MCObjectStreamerCtorFn) return 0; - return ObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, RelaxAll, - NoExecStack); + return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, + RelaxAll, NoExecStack); } /// createAsmStreamer - Create a target specific MCStreamer. @@ -389,7 +428,7 @@ namespace llvm { bool useCFI, MCInstPrinter *InstPrint, MCCodeEmitter *CE, - TargetAsmBackend *TAB, + MCAsmBackend *TAB, bool ShowInst) const { // AsmStreamerCtorFn is default to llvm::createAsmStreamer return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useLoc, useCFI, @@ -438,6 +477,10 @@ namespace llvm { } }; + /// printRegisteredTargetsForVersion - Print the registered targets + /// appropriately for inclusion in a tool's version output. + static void printRegisteredTargetsForVersion(); + /// @name Registry Access /// @{ @@ -500,6 +543,22 @@ namespace llvm { T.MCAsmInfoCtorFn = Fn; } + /// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the + /// given target. + /// + /// Clients are responsible for ensuring that registration doesn't occur + /// while another thread is attempting to access the registry. Typically + /// this is done by initializing all targets at program startup. + /// + /// @param T - The target being registered. + /// @param Fn - A function to construct a MCCodeGenInfo for the target. + static void RegisterMCCodeGenInfo(Target &T, + Target::MCCodeGenInfoCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.MCCodeGenInfoCtorFn) + T.MCCodeGenInfoCtorFn = Fn; + } + /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the /// given target. /// @@ -515,6 +574,15 @@ namespace llvm { T.MCInstrInfoCtorFn = Fn; } + /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for + /// the given target. + static void RegisterMCInstrAnalysis(Target &T, + Target::MCInstrAnalysisCtorFnTy Fn) { + // Ignore duplicate registration. + if (!T.MCInstrAnalysisCtorFn) + T.MCInstrAnalysisCtorFn = Fn; + } + /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the /// given target. /// @@ -562,7 +630,7 @@ namespace llvm { T.TargetMachineCtorFn = Fn; } - /// RegisterAsmBackend - Register a TargetAsmBackend implementation for the + /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the /// given target. /// /// Clients are responsible for ensuring that registration doesn't occur @@ -571,12 +639,12 @@ namespace llvm { /// /// @param T - The target being registered. /// @param Fn - A function to construct an AsmBackend for the target. - static void RegisterAsmBackend(Target &T, Target::AsmBackendCtorTy Fn) { - if (!T.AsmBackendCtorFn) - T.AsmBackendCtorFn = Fn; + static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) { + if (!T.MCAsmBackendCtorFn) + T.MCAsmBackendCtorFn = Fn; } - /// RegisterAsmLexer - Register a TargetAsmLexer implementation for the + /// RegisterMCAsmLexer - Register a MCTargetAsmLexer implementation for the /// given target. /// /// Clients are responsible for ensuring that registration doesn't occur @@ -584,24 +652,24 @@ namespace llvm { /// this is done by initializing all targets at program startup. /// /// @param T - The target being registered. - /// @param Fn - A function to construct an AsmLexer for the target. - static void RegisterAsmLexer(Target &T, Target::AsmLexerCtorTy Fn) { - if (!T.AsmLexerCtorFn) - T.AsmLexerCtorFn = Fn; + /// @param Fn - A function to construct an MCAsmLexer for the target. + static void RegisterMCAsmLexer(Target &T, Target::MCAsmLexerCtorTy Fn) { + if (!T.MCAsmLexerCtorFn) + T.MCAsmLexerCtorFn = Fn; } - /// RegisterAsmParser - Register a TargetAsmParser implementation for the - /// given target. + /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for + /// the given target. /// /// Clients are responsible for ensuring that registration doesn't occur /// while another thread is attempting to access the registry. Typically /// this is done by initializing all targets at program startup. /// /// @param T - The target being registered. - /// @param Fn - A function to construct an AsmParser for the target. - static void RegisterAsmParser(Target &T, Target::AsmParserCtorTy Fn) { - if (!T.AsmParserCtorFn) - T.AsmParserCtorFn = Fn; + /// @param Fn - A function to construct an MCTargetAsmParser for the target. + static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) { + if (!T.MCAsmParserCtorFn) + T.MCAsmParserCtorFn = Fn; } /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given @@ -649,7 +717,7 @@ namespace llvm { T.MCInstPrinterCtorFn = Fn; } - /// RegisterCodeEmitter - Register a MCCodeEmitter implementation for the + /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the /// given target. /// /// Clients are responsible for ensuring that registration doesn't occur @@ -658,13 +726,14 @@ namespace llvm { /// /// @param T - The target being registered. /// @param Fn - A function to construct an MCCodeEmitter for the target. - static void RegisterCodeEmitter(Target &T, Target::CodeEmitterCtorTy Fn) { - if (!T.CodeEmitterCtorFn) - T.CodeEmitterCtorFn = Fn; + static void RegisterMCCodeEmitter(Target &T, + Target::MCCodeEmitterCtorTy Fn) { + if (!T.MCCodeEmitterCtorFn) + T.MCCodeEmitterCtorFn = Fn; } - /// RegisterObjectStreamer - Register a object code MCStreamer implementation - /// for the given target. + /// RegisterMCObjectStreamer - Register a object code MCStreamer + /// implementation for the given target. /// /// Clients are responsible for ensuring that registration doesn't occur /// while another thread is attempting to access the registry. Typically @@ -672,9 +741,10 @@ namespace llvm { /// /// @param T - The target being registered. /// @param Fn - A function to construct an MCStreamer for the target. - static void RegisterObjectStreamer(Target &T, Target::ObjectStreamerCtorTy Fn) { - if (!T.ObjectStreamerCtorFn) - T.ObjectStreamerCtorFn = Fn; + static void RegisterMCObjectStreamer(Target &T, + Target::MCObjectStreamerCtorTy Fn) { + if (!T.MCObjectStreamerCtorFn) + T.MCObjectStreamerCtorFn = Fn; } /// RegisterAsmStreamer - Register an assembly MCStreamer implementation @@ -756,6 +826,40 @@ namespace llvm { } }; + /// RegisterMCCodeGenInfo - Helper template for registering a target codegen info + /// implementation. This invokes the static "Create" method on the class + /// to actually do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCCodeGenInfo X(TheFooTarget); + /// } + template + struct RegisterMCCodeGenInfo { + RegisterMCCodeGenInfo(Target &T) { + TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator); + } + private: + static MCCodeGenInfo *Allocator(StringRef TT, + Reloc::Model RM, CodeModel::Model CM) { + return new MCCodeGenInfoImpl(); + } + }; + + /// RegisterMCCodeGenInfoFn - Helper template for registering a target codegen + /// info implementation. This invokes the specified function to do the + /// construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCCodeGenInfoFn X(TheFooTarget, TheFunction); + /// } + struct RegisterMCCodeGenInfoFn { + RegisterMCCodeGenInfoFn(Target &T, Target::MCCodeGenInfoCtorFnTy Fn) { + TargetRegistry::RegisterMCCodeGenInfo(T, Fn); + } + }; + /// RegisterMCInstrInfo - Helper template for registering a target instruction /// info implementation. This invokes the static "Create" method on the class /// to actually do the construction. Usage: @@ -789,6 +893,39 @@ namespace llvm { } }; + /// RegisterMCInstrAnalysis - Helper template for registering a target + /// instruction analyzer implementation. This invokes the static "Create" + /// method on the class to actually do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCInstrAnalysis X(TheFooTarget); + /// } + template + struct RegisterMCInstrAnalysis { + RegisterMCInstrAnalysis(Target &T) { + TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator); + } + private: + static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) { + return new MCInstrAnalysisImpl(Info); + } + }; + + /// RegisterMCInstrAnalysisFn - Helper template for registering a target + /// instruction analyzer implementation. This invokes the specified function + /// to do the construction. Usage: + /// + /// extern "C" void LLVMInitializeFooTarget() { + /// extern Target TheFooTarget; + /// RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction); + /// } + struct RegisterMCInstrAnalysisFn { + RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) { + TargetRegistry::RegisterMCInstrAnalysis(T, Fn); + } + }; + /// RegisterMCRegInfo - Helper template for registering a target register info /// implementation. This invokes the static "Create" method on the class to /// actually do the construction. Usage: @@ -803,7 +940,7 @@ namespace llvm { TargetRegistry::RegisterMCRegInfo(T, &Allocator); } private: - static MCRegisterInfo *Allocator() { + static MCRegisterInfo *Allocator(StringRef TT) { return new MCRegisterInfoImpl(); } }; @@ -871,70 +1008,72 @@ namespace llvm { } private: - static TargetMachine *Allocator(const Target &T, const std::string &TT, - const std::string &CPU, - const std::string &FS) { - return new TargetMachineImpl(T, TT, CPU, FS); + static TargetMachine *Allocator(const Target &T, StringRef TT, + StringRef CPU, StringRef FS, + Reloc::Model RM, + CodeModel::Model CM) { + return new TargetMachineImpl(T, TT, CPU, FS, RM, CM); } }; - /// RegisterAsmBackend - Helper template for registering a target specific + /// RegisterMCAsmBackend - Helper template for registering a target specific /// assembler backend. Usage: /// - /// extern "C" void LLVMInitializeFooAsmBackend() { + /// extern "C" void LLVMInitializeFooMCAsmBackend() { /// extern Target TheFooTarget; - /// RegisterAsmBackend X(TheFooTarget); + /// RegisterMCAsmBackend X(TheFooTarget); /// } - template - struct RegisterAsmBackend { - RegisterAsmBackend(Target &T) { - TargetRegistry::RegisterAsmBackend(T, &Allocator); + template + struct RegisterMCAsmBackend { + RegisterMCAsmBackend(Target &T) { + TargetRegistry::RegisterMCAsmBackend(T, &Allocator); } private: - static TargetAsmBackend *Allocator(const Target &T, - const std::string &Triple) { - return new AsmBackendImpl(T, Triple); + static MCAsmBackend *Allocator(const Target &T, StringRef Triple) { + return new MCAsmBackendImpl(T, Triple); } }; - /// RegisterAsmLexer - Helper template for registering a target specific + /// RegisterMCAsmLexer - Helper template for registering a target specific /// assembly lexer, for use in the target machine initialization /// function. Usage: /// - /// extern "C" void LLVMInitializeFooAsmLexer() { + /// extern "C" void LLVMInitializeFooMCAsmLexer() { /// extern Target TheFooTarget; - /// RegisterAsmLexer X(TheFooTarget); + /// RegisterMCAsmLexer X(TheFooTarget); /// } - template - struct RegisterAsmLexer { - RegisterAsmLexer(Target &T) { - TargetRegistry::RegisterAsmLexer(T, &Allocator); + template + struct RegisterMCAsmLexer { + RegisterMCAsmLexer(Target &T) { + TargetRegistry::RegisterMCAsmLexer(T, &Allocator); } private: - static TargetAsmLexer *Allocator(const Target &T, const MCAsmInfo &MAI) { - return new AsmLexerImpl(T, MAI); + static MCTargetAsmLexer *Allocator(const Target &T, + const MCRegisterInfo &MRI, + const MCAsmInfo &MAI) { + return new MCAsmLexerImpl(T, MRI, MAI); } }; - /// RegisterAsmParser - Helper template for registering a target specific + /// RegisterMCAsmParser - Helper template for registering a target specific /// assembly parser, for use in the target machine initialization /// function. Usage: /// - /// extern "C" void LLVMInitializeFooAsmParser() { + /// extern "C" void LLVMInitializeFooMCAsmParser() { /// extern Target TheFooTarget; - /// RegisterAsmParser X(TheFooTarget); + /// RegisterMCAsmParser X(TheFooTarget); /// } - template - struct RegisterAsmParser { - RegisterAsmParser(Target &T) { - TargetRegistry::RegisterAsmParser(T, &Allocator); + template + struct RegisterMCAsmParser { + RegisterMCAsmParser(Target &T) { + TargetRegistry::RegisterMCAsmParser(T, &Allocator); } private: - static TargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P) { - return new AsmParserImpl(STI, P); + static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P) { + return new MCAsmParserImpl(STI, P); } }; @@ -958,25 +1097,25 @@ namespace llvm { } }; - /// RegisterCodeEmitter - Helper template for registering a target specific + /// RegisterMCCodeEmitter - Helper template for registering a target specific /// machine code emitter, for use in the target initialization /// function. Usage: /// - /// extern "C" void LLVMInitializeFooCodeEmitter() { + /// extern "C" void LLVMInitializeFooMCCodeEmitter() { /// extern Target TheFooTarget; - /// RegisterCodeEmitter X(TheFooTarget); + /// RegisterMCCodeEmitter X(TheFooTarget); /// } - template - struct RegisterCodeEmitter { - RegisterCodeEmitter(Target &T) { - TargetRegistry::RegisterCodeEmitter(T, &Allocator); + template + struct RegisterMCCodeEmitter { + RegisterMCCodeEmitter(Target &T) { + TargetRegistry::RegisterMCCodeEmitter(T, &Allocator); } private: static MCCodeEmitter *Allocator(const MCInstrInfo &II, const MCSubtargetInfo &STI, MCContext &Ctx) { - return new CodeEmitterImpl(); + return new MCCodeEmitterImpl(); } }; diff --git a/include/llvm/Target/TargetSelect.h b/include/llvm/Support/TargetSelect.h similarity index 75% rename from include/llvm/Target/TargetSelect.h rename to include/llvm/Support/TargetSelect.h index 272ee09464f9..83ff68caaeac 100644 --- a/include/llvm/Target/TargetSelect.h +++ b/include/llvm/Support/TargetSelect.h @@ -13,8 +13,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_TARGET_TARGETSELECT_H -#define LLVM_TARGET_TARGETSELECT_H +#ifndef LLVM_SUPPORT_TARGETSELECT_H +#define LLVM_SUPPORT_TARGETSELECT_H #include "llvm/Config/llvm-config.h" @@ -26,18 +26,10 @@ extern "C" { #define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target(); #include "llvm/Config/Targets.def" -#define LLVM_TARGET(TargetName) \ - void LLVMInitialize##TargetName##MCAsmInfo(); + // Declare all of the target-MC-initialization functions that are available. +#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetMC(); #include "llvm/Config/Targets.def" - -#define LLVM_TARGET(TargetName) \ - void LLVMInitialize##TargetName##MCInstrInfo(); -#include "llvm/Config/Targets.def" - -#define LLVM_TARGET(TargetName) \ - void LLVMInitialize##TargetName##MCSubtargetInfo(); -#include "llvm/Config/Targets.def" - + // Declare all of the available assembly printer initialization functions. #define LLVM_ASM_PRINTER(TargetName) void LLVMInitialize##TargetName##AsmPrinter(); #include "llvm/Config/AsmPrinters.def" @@ -76,35 +68,13 @@ namespace llvm { #include "llvm/Config/Targets.def" } - /// InitializeAllMCAsmInfos - The main program should call this function - /// if it wants access to all available assembly infos for targets that - /// LLVM is configured to support, to make them available via the - /// TargetRegistry. + /// InitializeAllTargetMCs - The main program should call this function if it + /// wants access to all available target MC that LLVM is configured to + /// support, to make them available via the TargetRegistry. /// /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllMCAsmInfos() { -#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##MCAsmInfo(); -#include "llvm/Config/Targets.def" - } - - /// InitializeAllMCInstrInfos - The main program should call this function - /// if it wants access to all available instruction infos for targets that - /// LLVM is configured to support, to make them available via the - /// TargetRegistry. - /// - /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllMCInstrInfos() { -#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##MCInstrInfo(); -#include "llvm/Config/Targets.def" - } - - /// InitializeAllMCSubtargetInfos - The main program should call this function - /// if it wants access to all available subtarget infos for targets that LLVM - /// is configured to support, to make them available via the TargetRegistry. - /// - /// It is legal for a client to make multiple calls to this function. - inline void InitializeAllMCSubtargetInfos() { -#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##MCSubtargetInfo(); + inline void InitializeAllTargetMCs() { +#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetMC(); #include "llvm/Config/Targets.def" } @@ -148,7 +118,7 @@ namespace llvm { #ifdef LLVM_NATIVE_TARGET LLVM_NATIVE_TARGETINFO(); LLVM_NATIVE_TARGET(); - LLVM_NATIVE_MCASMINFO(); + LLVM_NATIVE_TARGETMC(); return false; #else return true; diff --git a/include/llvm/Support/TypeBuilder.h b/include/llvm/Support/TypeBuilder.h index 18007789736a..c75606917c1c 100644 --- a/include/llvm/Support/TypeBuilder.h +++ b/include/llvm/Support/TypeBuilder.h @@ -18,7 +18,6 @@ #include "llvm/DerivedTypes.h" #include "llvm/LLVMContext.h" #include -#include namespace llvm { @@ -254,9 +253,9 @@ template class TypeBuilder { template class TypeBuilder { public: static FunctionType *get(LLVMContext &Context) { - std::vector params; - params.reserve(1); - params.push_back(TypeBuilder::get(Context)); + Type *params[] = { + TypeBuilder::get(Context), + }; return FunctionType::get(TypeBuilder::get(Context), params, false); } @@ -265,10 +264,10 @@ template class TypeBuilder { public: static FunctionType *get(LLVMContext &Context) { - std::vector params; - params.reserve(2); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); + Type *params[] = { + TypeBuilder::get(Context), + TypeBuilder::get(Context), + }; return FunctionType::get(TypeBuilder::get(Context), params, false); } @@ -277,11 +276,11 @@ template class TypeBuilder { public: static FunctionType *get(LLVMContext &Context) { - std::vector params; - params.reserve(3); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); + Type *params[] = { + TypeBuilder::get(Context), + TypeBuilder::get(Context), + TypeBuilder::get(Context), + }; return FunctionType::get(TypeBuilder::get(Context), params, false); } @@ -292,12 +291,12 @@ template { public: static FunctionType *get(LLVMContext &Context) { - std::vector params; - params.reserve(4); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); + Type *params[] = { + TypeBuilder::get(Context), + TypeBuilder::get(Context), + TypeBuilder::get(Context), + TypeBuilder::get(Context), + }; return FunctionType::get(TypeBuilder::get(Context), params, false); } @@ -308,13 +307,13 @@ template { public: static FunctionType *get(LLVMContext &Context) { - std::vector params; - params.reserve(5); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); + Type *params[] = { + TypeBuilder::get(Context), + TypeBuilder::get(Context), + TypeBuilder::get(Context), + TypeBuilder::get(Context), + TypeBuilder::get(Context), + }; return FunctionType::get(TypeBuilder::get(Context), params, false); } @@ -330,9 +329,9 @@ template class TypeBuilder { public: static FunctionType *get(LLVMContext &Context) { - std::vector params; - params.reserve(1); - params.push_back(TypeBuilder::get(Context)); + Type *params[] = { + TypeBuilder::get(Context), + }; return FunctionType::get(TypeBuilder::get(Context), params, true); } }; @@ -340,10 +339,10 @@ template class TypeBuilder { public: static FunctionType *get(LLVMContext &Context) { - std::vector params; - params.reserve(2); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); + Type *params[] = { + TypeBuilder::get(Context), + TypeBuilder::get(Context), + }; return FunctionType::get(TypeBuilder::get(Context), params, true); } @@ -352,11 +351,11 @@ template class TypeBuilder { public: static FunctionType *get(LLVMContext &Context) { - std::vector params; - params.reserve(3); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); + Type *params[] = { + TypeBuilder::get(Context), + TypeBuilder::get(Context), + TypeBuilder::get(Context), + }; return FunctionType::get(TypeBuilder::get(Context), params, true); } @@ -367,12 +366,12 @@ template { public: static FunctionType *get(LLVMContext &Context) { - std::vector params; - params.reserve(4); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); + Type *params[] = { + TypeBuilder::get(Context), + TypeBuilder::get(Context), + TypeBuilder::get(Context), + TypeBuilder::get(Context), + }; return FunctionType::get(TypeBuilder::get(Context), params, true); } @@ -383,13 +382,13 @@ template { public: static FunctionType *get(LLVMContext &Context) { - std::vector params; - params.reserve(5); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); - params.push_back(TypeBuilder::get(Context)); + Type *params[] = { + TypeBuilder::get(Context), + TypeBuilder::get(Context), + TypeBuilder::get(Context), + TypeBuilder::get(Context), + TypeBuilder::get(Context), + }; return FunctionType::get(TypeBuilder::get(Context), params, true); } diff --git a/utils/TableGen/Error.h b/include/llvm/TableGen/Error.h similarity index 89% rename from utils/TableGen/Error.h rename to include/llvm/TableGen/Error.h index b3a01461940d..c01b32b1c2d2 100644 --- a/utils/TableGen/Error.h +++ b/include/llvm/TableGen/Error.h @@ -1,4 +1,4 @@ -//===- Error.h - tblgen error handling helper routines ----------*- C++ -*-===// +//===- llvm/TableGen/Error.h - tblgen error handling helpers ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef ERROR_H -#define ERROR_H +#ifndef LLVM_TABLEGEN_ERROR_H +#define LLVM_TABLEGEN_ERROR_H #include "llvm/Support/SourceMgr.h" diff --git a/include/llvm/TableGen/Main.h b/include/llvm/TableGen/Main.h new file mode 100644 index 000000000000..deaef4a9908a --- /dev/null +++ b/include/llvm/TableGen/Main.h @@ -0,0 +1,26 @@ +//===- llvm/TableGen/Main.h - tblgen entry point ----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the common entry point for tblgen tools. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TABLEGEN_MAIN_H +#define LLVM_TABLEGEN_MAIN_H + +namespace llvm { + +class TableGenAction; + +/// Run the table generator, performing the specified Action on parsed records. +int TableGenMain(char *argv0, TableGenAction &Action); + +} + +#endif diff --git a/utils/TableGen/Record.h b/include/llvm/TableGen/Record.h similarity index 80% rename from utils/TableGen/Record.h rename to include/llvm/TableGen/Record.h index 2f4080bbfd9c..afce76099867 100644 --- a/utils/TableGen/Record.h +++ b/include/llvm/TableGen/Record.h @@ -1,4 +1,4 @@ -//===- Record.h - Classes to represent Table Records ------------*- C++ -*-===// +//===- llvm/TableGen/Record.h - Classes for Table Records -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,9 +12,12 @@ // //===----------------------------------------------------------------------===// -#ifndef RECORD_H -#define RECORD_H +#ifndef LLVM_TABLEGEN_RECORD_H +#define LLVM_TABLEGEN_RECORD_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/raw_ostream.h" @@ -63,7 +66,10 @@ class RecordKeeper; // Type Classes //===----------------------------------------------------------------------===// -struct RecTy { +class RecTy { + ListRecTy *ListTy; +public: + RecTy() : ListTy(0) {} virtual ~RecTy() {} virtual std::string getAsString() const = 0; @@ -74,6 +80,9 @@ struct RecTy { /// converted to the specified type. virtual bool typeIsConvertibleTo(const RecTy *RHS) const = 0; + /// getListTy - Returns the type representing list. + ListRecTy *getListTy(); + public: // These methods should only be called from subclasses of Init virtual Init *convertValue( UnsetInit *UI) { return 0; } virtual Init *convertValue( BitInit *BI) { return 0; } @@ -124,7 +133,11 @@ inline raw_ostream &operator<<(raw_ostream &OS, const RecTy &Ty) { /// BitRecTy - 'bit' - Represent a single bit /// class BitRecTy : public RecTy { + static BitRecTy Shared; + BitRecTy() {} public: + static BitRecTy *get() { return &Shared; } + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } virtual Init *convertValue( BitInit *BI) { return (Init*)BI; } virtual Init *convertValue( BitsInit *BI); @@ -164,8 +177,9 @@ class BitRecTy : public RecTy { /// class BitsRecTy : public RecTy { unsigned Size; -public: explicit BitsRecTy(unsigned Sz) : Size(Sz) {} +public: + static BitsRecTy *get(unsigned Sz); unsigned getNumBits() const { return Size; } @@ -208,7 +222,11 @@ class BitsRecTy : public RecTy { /// IntRecTy - 'int' - Represent an integer value of no particular size /// class IntRecTy : public RecTy { + static IntRecTy Shared; + IntRecTy() {} public: + static IntRecTy *get() { return &Shared; } + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } virtual Init *convertValue( BitInit *BI); virtual Init *convertValue( BitsInit *BI); @@ -246,7 +264,11 @@ class IntRecTy : public RecTy { /// StringRecTy - 'string' - Represent an string value /// class StringRecTy : public RecTy { + static StringRecTy Shared; + StringRecTy() {} public: + static StringRecTy *get() { return &Shared; } + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } virtual Init *convertValue( BitInit *BI) { return 0; } virtual Init *convertValue( BitsInit *BI) { return 0; } @@ -288,9 +310,10 @@ class StringRecTy : public RecTy { /// class ListRecTy : public RecTy { RecTy *Ty; -public: explicit ListRecTy(RecTy *T) : Ty(T) {} - + friend ListRecTy *RecTy::getListTy(); +public: + static ListRecTy *get(RecTy *T) { return T->getListTy(); } RecTy *getElementType() const { return Ty; } virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } @@ -331,7 +354,11 @@ class ListRecTy : public RecTy { /// CodeRecTy - 'code' - Represent an code fragment, function or method. /// class CodeRecTy : public RecTy { + static CodeRecTy Shared; + CodeRecTy() {} public: + static CodeRecTy *get() { return &Shared; } + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } virtual Init *convertValue( BitInit *BI) { return 0; } virtual Init *convertValue( BitsInit *BI) { return 0; } @@ -367,7 +394,11 @@ class CodeRecTy : public RecTy { /// DagRecTy - 'dag' - Represent a dag fragment /// class DagRecTy : public RecTy { + static DagRecTy Shared; + DagRecTy() {} public: + static DagRecTy *get() { return &Shared; } + virtual Init *convertValue( UnsetInit *UI) { return (Init*)UI; } virtual Init *convertValue( BitInit *BI) { return 0; } virtual Init *convertValue( BitsInit *BI) { return 0; } @@ -407,8 +438,10 @@ class DagRecTy : public RecTy { /// class RecordRecTy : public RecTy { Record *Rec; -public: explicit RecordRecTy(Record *R) : Rec(R) {} + friend class Record; +public: + static RecordRecTy *get(Record *R); Record *getRecord() const { return Rec; } @@ -454,6 +487,12 @@ RecTy *resolveTypes(RecTy *T1, RecTy *T2); //===----------------------------------------------------------------------===// class Init { + Init(const Init &); // Do not define. + Init &operator=(const Init &); // Do not define. + +protected: + Init(void) {} + public: virtual ~Init() {} @@ -466,6 +505,11 @@ class Init { /// getAsString - Convert this value to a string form. virtual std::string getAsString() const = 0; + /// getAsUnquotedString - Convert this value to a string form, + /// without adding quote markers. This primaruly affects + /// StringInits where we will not surround the string value with + /// quotes. + virtual std::string getAsUnquotedString() const { return getAsString(); } /// dump - Debugging method that may be called through a debugger, just /// invokes print on stderr. @@ -475,14 +519,15 @@ class Init { /// function that should be overridden to call the appropriate /// RecTy::convertValue method. /// - virtual Init *convertInitializerTo(RecTy *Ty) = 0; + virtual Init *convertInitializerTo(RecTy *Ty) const = 0; /// convertInitializerBitRange - This method is used to implement the bitrange /// selection operator. Given an initializer, it selects the specified bits /// out, returning them as a new init of bits type. If it is not legal to use /// the bit subscript operator on this initializer, return null. /// - virtual Init *convertInitializerBitRange(const std::vector &Bits) { + virtual Init * + convertInitializerBitRange(const std::vector &Bits) const { return 0; } @@ -491,7 +536,8 @@ class Init { /// elements, returning them as a new init of list type. If it is not legal /// to take a slice of this, return null. /// - virtual Init *convertInitListSlice(const std::vector &Elements) { + virtual Init * + convertInitListSlice(const std::vector &Elements) const { return 0; } @@ -515,8 +561,8 @@ class Init { /// If a value is set for the variable later, this method will be called on /// users of the value to allow the value to propagate out. /// - virtual Init *resolveReferences(Record &R, const RecordVal *RV) { - return this; + virtual Init *resolveReferences(Record &R, const RecordVal *RV) const { + return const_cast(this); } }; @@ -529,13 +575,20 @@ inline raw_ostream &operator<<(raw_ostream &OS, const Init &I) { /// class TypedInit : public Init { RecTy *Ty; -public: + + TypedInit(const TypedInit &Other); // Do not define. + TypedInit &operator=(const TypedInit &Other); // Do not define. + +protected: explicit TypedInit(RecTy *T) : Ty(T) {} +public: RecTy *getType() const { return Ty; } - virtual Init *convertInitializerBitRange(const std::vector &Bits); - virtual Init *convertInitListSlice(const std::vector &Elements); + virtual Init * + convertInitializerBitRange(const std::vector &Bits) const; + virtual Init * + convertInitListSlice(const std::vector &Elements) const; /// getFieldType - This method is used to implement the FieldInit class. /// Implementors of this method should return the type of the named field if @@ -548,22 +601,28 @@ class TypedInit : public Init { /// simply return the resolved value, otherwise we return null. /// virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) = 0; + unsigned Bit) const = 0; /// resolveListElementReference - This method is used to implement /// VarListElementInit::resolveReferences. If the list element is resolvable /// now, we return the resolved value, otherwise we return null. virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, - unsigned Elt) = 0; + unsigned Elt) const = 0; }; /// UnsetInit - ? - Represents an uninitialized value /// class UnsetInit : public Init { + UnsetInit() : Init() {} + UnsetInit(const UnsetInit &); // Do not define. + UnsetInit &operator=(const UnsetInit &Other); // Do not define. + public: - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + static UnsetInit *get(); + + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } virtual bool isComplete() const { return false; } @@ -575,13 +634,18 @@ class UnsetInit : public Init { /// class BitInit : public Init { bool Value; -public: + explicit BitInit(bool V) : Value(V) {} + BitInit(const BitInit &Other); // Do not define. + BitInit &operator=(BitInit &Other); // Do not define. + +public: + static BitInit *get(bool V); bool getValue() const { return Value; } - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } virtual std::string getAsString() const { return Value ? "1" : "0"; } @@ -590,10 +654,18 @@ class BitInit : public Init { /// BitsInit - { a, b, c } - Represents an initializer for a BitsRecTy value. /// It contains a vector of bits, whose size is determined by the type. /// -class BitsInit : public Init { +class BitsInit : public Init, public FoldingSetNode { std::vector Bits; + + BitsInit(ArrayRef Range) : Bits(Range.begin(), Range.end()) {} + + BitsInit(const BitsInit &Other); // Do not define. + BitsInit &operator=(const BitsInit &Other); // Do not define. + public: - explicit BitsInit(unsigned Size) : Bits(Size) {} + static BitsInit *get(ArrayRef Range); + + void Profile(FoldingSetNodeID &ID) const; unsigned getNumBits() const { return Bits.size(); } @@ -601,16 +673,12 @@ class BitsInit : public Init { assert(Bit < Bits.size() && "Bit index out of range!"); return Bits[Bit]; } - void setBit(unsigned Bit, Init *V) { - assert(Bit < Bits.size() && "Bit index out of range!"); - assert(Bits[Bit] == 0 && "Bit already set!"); - Bits[Bit] = V; - } - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } - virtual Init *convertInitializerBitRange(const std::vector &Bits); + virtual Init * + convertInitializerBitRange(const std::vector &Bits) const; virtual bool isComplete() const { for (unsigned i = 0; i != getNumBits(); ++i) @@ -624,7 +692,7 @@ class BitsInit : public Init { } virtual std::string getAsString() const; - virtual Init *resolveReferences(Record &R, const RecordVal *RV); + virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; }; @@ -632,15 +700,22 @@ class BitsInit : public Init { /// class IntInit : public TypedInit { int64_t Value; + + explicit IntInit(int64_t V) : TypedInit(IntRecTy::get()), Value(V) {} + + IntInit(const IntInit &Other); // Do not define. + IntInit &operator=(const IntInit &Other); // Do note define. + public: - explicit IntInit(int64_t V) : TypedInit(new IntRecTy), Value(V) {} + static IntInit *get(int64_t V); int64_t getValue() const { return Value; } - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } - virtual Init *convertInitializerBitRange(const std::vector &Bits); + virtual Init * + convertInitializerBitRange(const std::vector &Bits) const; virtual std::string getAsString() const; @@ -649,7 +724,7 @@ class IntInit : public TypedInit { /// simply return the resolved value, otherwise we return null. /// virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) { + unsigned Bit) const { assert(0 && "Illegal bit reference off int"); return 0; } @@ -658,7 +733,7 @@ class IntInit : public TypedInit { /// VarListElementInit::resolveReferences. If the list element is resolvable /// now, we return the resolved value, otherwise we return null. virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, - unsigned Elt) { + unsigned Elt) const { assert(0 && "Illegal element reference off int"); return 0; } @@ -669,24 +744,31 @@ class IntInit : public TypedInit { /// class StringInit : public TypedInit { std::string Value; -public: + explicit StringInit(const std::string &V) - : TypedInit(new StringRecTy), Value(V) {} + : TypedInit(StringRecTy::get()), Value(V) {} + + StringInit(const StringInit &Other); // Do not define. + StringInit &operator=(const StringInit &Other); // Do not define. + +public: + static StringInit *get(const std::string &V); const std::string &getValue() const { return Value; } - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } virtual std::string getAsString() const { return "\"" + Value + "\""; } + virtual std::string getAsUnquotedString() const { return Value; } /// resolveBitReference - This method is used to implement /// VarBitInit::resolveReferences. If the bit is able to be resolved, we /// simply return the resolved value, otherwise we return null. /// virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) { + unsigned Bit) const { assert(0 && "Illegal bit reference off string"); return 0; } @@ -695,7 +777,7 @@ class StringInit : public TypedInit { /// VarListElementInit::resolveReferences. If the list element is resolvable /// now, we return the resolved value, otherwise we return null. virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, - unsigned Elt) { + unsigned Elt) const { assert(0 && "Illegal element reference off string"); return 0; } @@ -705,13 +787,19 @@ class StringInit : public TypedInit { /// class CodeInit : public Init { std::string Value; -public: + explicit CodeInit(const std::string &V) : Value(V) {} + CodeInit(const CodeInit &Other); // Do not define. + CodeInit &operator=(const CodeInit &Other); // Do not define. + +public: + static CodeInit *get(const std::string &V); + const std::string &getValue() const { return Value; } - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } virtual std::string getAsString() const { return "[{" + Value + "}]"; } @@ -719,18 +807,22 @@ class CodeInit : public Init { /// ListInit - [AL, AH, CL] - Represent a list of defs /// -class ListInit : public TypedInit { +class ListInit : public TypedInit, public FoldingSetNode { std::vector Values; public: - typedef std::vector::iterator iterator; typedef std::vector::const_iterator const_iterator; - explicit ListInit(std::vector &Vs, RecTy *EltTy) - : TypedInit(new ListRecTy(EltTy)) { - Values.swap(Vs); - } - explicit ListInit(iterator Start, iterator End, RecTy *EltTy) - : TypedInit(new ListRecTy(EltTy)), Values(Start, End) {} +private: + explicit ListInit(ArrayRef Range, RecTy *EltTy) + : TypedInit(ListRecTy::get(EltTy)), Values(Range.begin(), Range.end()) {} + + ListInit(const ListInit &Other); // Do not define. + ListInit &operator=(const ListInit &Other); // Do not define. + +public: + static ListInit *get(ArrayRef Range, RecTy *EltTy); + + void Profile(FoldingSetNodeID &ID) const; unsigned getSize() const { return Values.size(); } Init *getElement(unsigned i) const { @@ -740,10 +832,10 @@ class ListInit : public TypedInit { Record *getElementAsRecord(unsigned i) const; - Init *convertInitListSlice(const std::vector &Elements); + Init *convertInitListSlice(const std::vector &Elements) const; - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } /// resolveReferences - This method is used by classes that refer to other @@ -751,13 +843,13 @@ class ListInit : public TypedInit { /// If a value is set for the variable later, this method will be called on /// users of the value to allow the value to propagate out. /// - virtual Init *resolveReferences(Record &R, const RecordVal *RV); + virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; virtual std::string getAsString() const; - inline iterator begin() { return Values.begin(); } + ArrayRef getValues() const { return Values; } + inline const_iterator begin() const { return Values.begin(); } - inline iterator end () { return Values.end(); } inline const_iterator end () const { return Values.end(); } inline size_t size () const { return Values.size(); } @@ -768,7 +860,7 @@ class ListInit : public TypedInit { /// simply return the resolved value, otherwise we return null. /// virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) { + unsigned Bit) const { assert(0 && "Illegal bit reference off list"); return 0; } @@ -777,34 +869,38 @@ class ListInit : public TypedInit { /// VarListElementInit::resolveReferences. If the list element is resolvable /// now, we return the resolved value, otherwise we return null. virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, - unsigned Elt); + unsigned Elt) const; }; /// OpInit - Base class for operators /// class OpInit : public TypedInit { -public: - OpInit(RecTy *Type) : TypedInit(Type) {} + OpInit(const OpInit &Other); // Do not define. + OpInit &operator=(OpInit &Other); // Do not define. +protected: + explicit OpInit(RecTy *Type) : TypedInit(Type) {} + +public: // Clone - Clone this operator, replacing arguments with the new list - virtual OpInit *clone(std::vector &Operands) = 0; + virtual OpInit *clone(std::vector &Operands) const = 0; virtual int getNumOperands() const = 0; - virtual Init *getOperand(int i) = 0; + virtual Init *getOperand(int i) const = 0; // Fold - If possible, fold this to a simpler init. Return this if not // possible to fold. - virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) = 0; + virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const = 0; - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit); + unsigned Bit) const; virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, - unsigned Elt); + unsigned Elt) const; }; @@ -816,20 +912,25 @@ class UnOpInit : public OpInit { private: UnaryOp Opc; Init *LHS; + + UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type) + : OpInit(Type), Opc(opc), LHS(lhs) {} + + UnOpInit(const UnOpInit &Other); // Do not define. + UnOpInit &operator=(const UnOpInit &Other); // Do not define. + public: - UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type) : - OpInit(Type), Opc(opc), LHS(lhs) { - } + static UnOpInit *get(UnaryOp opc, Init *lhs, RecTy *Type); // Clone - Clone this operator, replacing arguments with the new list - virtual OpInit *clone(std::vector &Operands) { + virtual OpInit *clone(std::vector &Operands) const { assert(Operands.size() == 1 && "Wrong number of operands for unary operation"); - return new UnOpInit(getOpcode(), *Operands.begin(), getType()); + return UnOpInit::get(getOpcode(), *Operands.begin(), getType()); } int getNumOperands() const { return 1; } - Init *getOperand(int i) { + Init *getOperand(int i) const { assert(i == 0 && "Invalid operand id for unary operator"); return getOperand(); } @@ -839,9 +940,9 @@ class UnOpInit : public OpInit { // Fold - If possible, fold this to a simpler init. Return this if not // possible to fold. - Init *Fold(Record *CurRec, MultiClass *CurMultiClass); + Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; - virtual Init *resolveReferences(Record &R, const RecordVal *RV); + virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; virtual std::string getAsString() const; }; @@ -854,20 +955,26 @@ class BinOpInit : public OpInit { private: BinaryOp Opc; Init *LHS, *RHS; -public: + BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) : - OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) { - } + OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {} + + BinOpInit(const BinOpInit &Other); // Do not define. + BinOpInit &operator=(const BinOpInit &Other); // Do not define. + +public: + static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs, + RecTy *Type); // Clone - Clone this operator, replacing arguments with the new list - virtual OpInit *clone(std::vector &Operands) { + virtual OpInit *clone(std::vector &Operands) const { assert(Operands.size() == 2 && "Wrong number of operands for binary operation"); - return new BinOpInit(getOpcode(), Operands[0], Operands[1], getType()); + return BinOpInit::get(getOpcode(), Operands[0], Operands[1], getType()); } int getNumOperands() const { return 2; } - Init *getOperand(int i) { + Init *getOperand(int i) const { assert((i == 0 || i == 1) && "Invalid operand id for binary operator"); if (i == 0) { return getLHS(); @@ -882,9 +989,9 @@ class BinOpInit : public OpInit { // Fold - If possible, fold this to a simpler init. Return this if not // possible to fold. - Init *Fold(Record *CurRec, MultiClass *CurMultiClass); + Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; - virtual Init *resolveReferences(Record &R, const RecordVal *RV); + virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; virtual std::string getAsString() const; }; @@ -897,21 +1004,29 @@ class TernOpInit : public OpInit { private: TernaryOp Opc; Init *LHS, *MHS, *RHS; + + TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, + RecTy *Type) : + OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {} + + TernOpInit(const TernOpInit &Other); // Do not define. + TernOpInit &operator=(const TernOpInit &Other); // Do not define. + public: - TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type) : - OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) { - } + static TernOpInit *get(TernaryOp opc, Init *lhs, + Init *mhs, Init *rhs, + RecTy *Type); // Clone - Clone this operator, replacing arguments with the new list - virtual OpInit *clone(std::vector &Operands) { + virtual OpInit *clone(std::vector &Operands) const { assert(Operands.size() == 3 && "Wrong number of operands for ternary operation"); - return new TernOpInit(getOpcode(), Operands[0], Operands[1], Operands[2], - getType()); + return TernOpInit::get(getOpcode(), Operands[0], Operands[1], Operands[2], + getType()); } int getNumOperands() const { return 3; } - Init *getOperand(int i) { + Init *getOperand(int i) const { assert((i == 0 || i == 1 || i == 2) && "Invalid operand id for ternary operator"); if (i == 0) { @@ -930,11 +1045,11 @@ class TernOpInit : public OpInit { // Fold - If possible, fold this to a simpler init. Return this if not // possible to fold. - Init *Fold(Record *CurRec, MultiClass *CurMultiClass); + Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const; virtual bool isComplete() const { return false; } - virtual Init *resolveReferences(Record &R, const RecordVal *RV); + virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; virtual std::string getAsString() const; }; @@ -944,20 +1059,27 @@ class TernOpInit : public OpInit { /// class VarInit : public TypedInit { std::string VarName; -public: - explicit VarInit(const std::string &VN, RecTy *T) - : TypedInit(T), VarName(VN) {} - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + explicit VarInit(const std::string &VN, RecTy *T) + : TypedInit(T), VarName(VN) {} + + VarInit(const VarInit &Other); // Do not define. + VarInit &operator=(const VarInit &Other); // Do not define. + +public: + static VarInit *get(const std::string &VN, RecTy *T); + static VarInit *get(Init *VN, RecTy *T); + + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } const std::string &getName() const { return VarName; } virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit); + unsigned Bit) const; virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, - unsigned Elt); + unsigned Elt) const; virtual RecTy *getFieldType(const std::string &FieldName) const; virtual Init *getFieldInit(Record &R, const RecordVal *RV, @@ -968,7 +1090,7 @@ class VarInit : public TypedInit { /// If a value is set for the variable later, this method will be called on /// users of the value to allow the value to propagate out. /// - virtual Init *resolveReferences(Record &R, const RecordVal *RV); + virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; virtual std::string getAsString() const { return VarName; } }; @@ -979,22 +1101,28 @@ class VarInit : public TypedInit { class VarBitInit : public Init { TypedInit *TI; unsigned Bit; -public: + VarBitInit(TypedInit *T, unsigned B) : TI(T), Bit(B) { assert(T->getType() && dynamic_cast(T->getType()) && ((BitsRecTy*)T->getType())->getNumBits() > B && "Illegal VarBitInit expression!"); } - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + VarBitInit(const VarBitInit &Other); // Do not define. + VarBitInit &operator=(const VarBitInit &Other); // Do not define. + +public: + static VarBitInit *get(TypedInit *T, unsigned B); + + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } TypedInit *getVariable() const { return TI; } unsigned getBitNum() const { return Bit; } virtual std::string getAsString() const; - virtual Init *resolveReferences(Record &R, const RecordVal *RV); + virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; }; /// VarListElementInit - List[4] - Represent access to one element of a var or @@ -1002,43 +1130,59 @@ class VarBitInit : public Init { class VarListElementInit : public TypedInit { TypedInit *TI; unsigned Element; -public: + VarListElementInit(TypedInit *T, unsigned E) - : TypedInit(dynamic_cast(T->getType())->getElementType()), - TI(T), Element(E) { + : TypedInit(dynamic_cast(T->getType())->getElementType()), + TI(T), Element(E) { assert(T->getType() && dynamic_cast(T->getType()) && "Illegal VarBitInit expression!"); } - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + VarListElementInit(const VarListElementInit &Other); // Do not define. + VarListElementInit &operator=(const VarListElementInit &Other); // Do + // not + // define. + +public: + static VarListElementInit *get(TypedInit *T, unsigned E); + + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } TypedInit *getVariable() const { return TI; } unsigned getElementNum() const { return Element; } virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit); + unsigned Bit) const; /// resolveListElementReference - This method is used to implement /// VarListElementInit::resolveReferences. If the list element is resolvable /// now, we return the resolved value, otherwise we return null. - virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, - unsigned Elt); + virtual Init *resolveListElementReference(Record &R, + const RecordVal *RV, + unsigned Elt) const; virtual std::string getAsString() const; - virtual Init *resolveReferences(Record &R, const RecordVal *RV); + virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; }; /// DefInit - AL - Represent a reference to a 'def' in the description /// class DefInit : public TypedInit { Record *Def; -public: - explicit DefInit(Record *D) : TypedInit(new RecordRecTy(D)), Def(D) {} - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + DefInit(Record *D, RecordRecTy *T) : TypedInit(T), Def(D) {} + friend class Record; + + DefInit(const DefInit &Other); // Do not define. + DefInit &operator=(const DefInit &Other); // Do not define. + +public: + static DefInit *get(Record*); + + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } Record *getDef() const { return Def; } @@ -1056,7 +1200,7 @@ class DefInit : public TypedInit { /// simply return the resolved value, otherwise we return null. /// virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) { + unsigned Bit) const { assert(0 && "Illegal bit reference off def"); return 0; } @@ -1065,7 +1209,7 @@ class DefInit : public TypedInit { /// VarListElementInit::resolveReferences. If the list element is resolvable /// now, we return the resolved value, otherwise we return null. virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, - unsigned Elt) { + unsigned Elt) const { assert(0 && "Illegal element reference off def"); return 0; } @@ -1077,22 +1221,30 @@ class DefInit : public TypedInit { class FieldInit : public TypedInit { Init *Rec; // Record we are referring to std::string FieldName; // Field we are accessing -public: + FieldInit(Init *R, const std::string &FN) - : TypedInit(R->getFieldType(FN)), Rec(R), FieldName(FN) { + : TypedInit(R->getFieldType(FN)), Rec(R), FieldName(FN) { assert(getType() && "FieldInit with non-record type!"); } - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + FieldInit(const FieldInit &Other); // Do not define. + FieldInit &operator=(const FieldInit &Other); // Do not define. + +public: + static FieldInit *get(Init *R, const std::string &FN); + static FieldInit *get(Init *R, const Init *FN); + + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit); - virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, - unsigned Elt); + unsigned Bit) const; + virtual Init *resolveListElementReference(Record &R, + const RecordVal *RV, + unsigned Elt) const; - virtual Init *resolveReferences(Record &R, const RecordVal *RV); + virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; virtual std::string getAsString() const { return Rec->getAsString() + "." + FieldName; @@ -1103,29 +1255,34 @@ class FieldInit : public TypedInit { /// to have at least one value then a (possibly empty) list of arguments. Each /// argument can have a name associated with it. /// -class DagInit : public TypedInit { +class DagInit : public TypedInit, public FoldingSetNode { Init *Val; std::string ValName; std::vector Args; std::vector ArgNames; -public: - DagInit(Init *V, std::string VN, - const std::vector > &args) - : TypedInit(new DagRecTy), Val(V), ValName(VN) { - Args.reserve(args.size()); - ArgNames.reserve(args.size()); - for (unsigned i = 0, e = args.size(); i != e; ++i) { - Args.push_back(args[i].first); - ArgNames.push_back(args[i].second); - } - } - DagInit(Init *V, std::string VN, const std::vector &args, - const std::vector &argNames) - : TypedInit(new DagRecTy), Val(V), ValName(VN), Args(args), - ArgNames(argNames) { } - virtual Init *convertInitializerTo(RecTy *Ty) { - return Ty->convertValue(this); + DagInit(Init *V, const std::string &VN, + ArrayRef ArgRange, + ArrayRef NameRange) + : TypedInit(DagRecTy::get()), Val(V), ValName(VN), + Args(ArgRange.begin(), ArgRange.end()), + ArgNames(NameRange.begin(), NameRange.end()) {} + + DagInit(const DagInit &Other); // Do not define. + DagInit &operator=(const DagInit &Other); // Do not define. + +public: + static DagInit *get(Init *V, const std::string &VN, + ArrayRef ArgRange, + ArrayRef NameRange); + static DagInit *get(Init *V, const std::string &VN, + const std::vector< + std::pair > &args); + + void Profile(FoldingSetNodeID &ID) const; + + virtual Init *convertInitializerTo(RecTy *Ty) const { + return Ty->convertValue(const_cast(this)); } Init *getOperator() const { return Val; } @@ -1142,44 +1299,33 @@ class DagInit : public TypedInit { return ArgNames[Num]; } - void setArg(unsigned Num, Init *I) { - assert(Num < Args.size() && "Arg number out of range!"); - Args[Num] = I; - } - - virtual Init *resolveReferences(Record &R, const RecordVal *RV); + virtual Init *resolveReferences(Record &R, const RecordVal *RV) const; virtual std::string getAsString() const; - typedef std::vector::iterator arg_iterator; typedef std::vector::const_iterator const_arg_iterator; - typedef std::vector::iterator name_iterator; typedef std::vector::const_iterator const_name_iterator; - inline arg_iterator arg_begin() { return Args.begin(); } inline const_arg_iterator arg_begin() const { return Args.begin(); } - inline arg_iterator arg_end () { return Args.end(); } inline const_arg_iterator arg_end () const { return Args.end(); } inline size_t arg_size () const { return Args.size(); } inline bool arg_empty() const { return Args.empty(); } - inline name_iterator name_begin() { return ArgNames.begin(); } inline const_name_iterator name_begin() const { return ArgNames.begin(); } - inline name_iterator name_end () { return ArgNames.end(); } inline const_name_iterator name_end () const { return ArgNames.end(); } inline size_t name_size () const { return ArgNames.size(); } inline bool name_empty() const { return ArgNames.empty(); } virtual Init *resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) { + unsigned Bit) const { assert(0 && "Illegal bit reference off dag"); return 0; } virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, - unsigned Elt) { + unsigned Elt) const { assert(0 && "Illegal element reference off dag"); return 0; } @@ -1190,14 +1336,15 @@ class DagInit : public TypedInit { //===----------------------------------------------------------------------===// class RecordVal { - std::string Name; + Init *Name; RecTy *Ty; unsigned Prefix; Init *Value; public: + RecordVal(Init *N, RecTy *T, unsigned P); RecordVal(const std::string &N, RecTy *T, unsigned P); - const std::string &getName() const { return Name; } + const std::string &getName() const; unsigned getPrefix() const { return Prefix; } RecTy *getType() const { return Ty; } @@ -1226,7 +1373,7 @@ class Record { // Unique record ID. unsigned ID; - std::string Name; + Init *Name; SMLoc Loc; std::vector TemplateArgs; std::vector Values; @@ -1235,11 +1382,15 @@ class Record { // Tracks Record instances. Not owned by Record. RecordKeeper &TrackedRecords; + DefInit *TheInit; + + void checkName(); + public: // Constructs a record. explicit Record(const std::string &N, SMLoc loc, RecordKeeper &records) : - ID(LastID++), Name(N), Loc(loc), TrackedRecords(records) {} + ID(LastID++), Name(StringInit::get(N)), Loc(loc), TrackedRecords(records), TheInit(0) {} ~Record() {} @@ -1248,11 +1399,15 @@ class Record { unsigned getID() const { return ID; } - const std::string &getName() const { return Name; } + const std::string &getName() const; + void setName(Init *Name); // Also updates RecordKeeper. void setName(const std::string &Name); // Also updates RecordKeeper. SMLoc getLoc() const { return Loc; } + /// get the corresponding DefInit. + DefInit *getDefInit(); + const std::vector &getTemplateArgs() const { return TemplateArgs; } diff --git a/include/llvm/TableGen/TableGenAction.h b/include/llvm/TableGen/TableGenAction.h new file mode 100644 index 000000000000..9f1c23c5b457 --- /dev/null +++ b/include/llvm/TableGen/TableGenAction.h @@ -0,0 +1,34 @@ +//===- llvm/TableGen/TableGenAction.h - defines TableGenAction --*- 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 TableGenAction base class to be derived from by +// tblgen tools. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TABLEGEN_TABLEGENACTION_H +#define LLVM_TABLEGEN_TABLEGENACTION_H + +namespace llvm { + +class raw_ostream; +class RecordKeeper; + +class TableGenAction { +public: + virtual ~TableGenAction() {} + + /// Perform the action using Records, and write output to OS. + /// @returns true on error, false otherwise + virtual bool operator()(raw_ostream &OS, RecordKeeper &Records) = 0; +}; + +} + +#endif diff --git a/utils/TableGen/TableGenBackend.h b/include/llvm/TableGen/TableGenBackend.h similarity index 88% rename from utils/TableGen/TableGenBackend.h rename to include/llvm/TableGen/TableGenBackend.h index 9c2b948b0dfc..853f92e406fb 100644 --- a/utils/TableGen/TableGenBackend.h +++ b/include/llvm/TableGen/TableGenBackend.h @@ -1,4 +1,4 @@ -//===- TableGenBackend.h - Base class for TableGen Backends -----*- C++ -*-===// +//===- llvm/TableGen/TableGenBackend.h - Backend base class -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef TABLEGENBACKEND_H -#define TABLEGENBACKEND_H +#ifndef LLVM_TABLEGEN_TABLEGENBACKEND_H +#define LLVM_TABLEGEN_TABLEGENBACKEND_H #include "llvm/Support/raw_ostream.h" #include diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 018ccbd72846..aa9a4f5af18c 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -297,6 +297,10 @@ class Instruction { // from the opcode. int Size = 0; + // DecoderNamespace - The "namespace" in which this instruction exists, on + // targets like ARM which multiple ISA namespaces exist. + string DecoderNamespace = ""; + // Code size, for instruction selection. // FIXME: What does this actually mean? int CodeSize = 0; @@ -324,6 +328,7 @@ class Instruction { bit isPredicable = 0; // Is this instruction predicable? bit hasDelaySlot = 0; // Does this instruction have an delay slot? bit usesCustomInserter = 0; // Pseudo instr needing special help. + bit hasPostISelHook = 0; // To be *adjusted* after isel by target hook. bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains? bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction? bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction. @@ -581,7 +586,7 @@ class InstrInfo { // Standard Pseudo Instructions. // This list must match TargetOpcodes.h and CodeGenTarget.cpp. // Only these instructions are allowed in the TargetOpcode namespace. -let isCodeGenOnly = 1, Namespace = "TargetOpcode" in { +let isCodeGenOnly = 1, isPseudo = 1, Namespace = "TargetOpcode" in { def PHI : Instruction { let OutOperandList = (outs); let InOperandList = (ins variable_ops); diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h deleted file mode 100644 index 5a526dcebc9d..000000000000 --- a/include/llvm/Target/TargetAsmInfo.h +++ /dev/null @@ -1,103 +0,0 @@ -//===-- llvm/Target/TargetAsmInfo.h -----------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Interface to provide the information necessary for producing assembly files. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_TARGET_TARGETASMINFO_H -#define LLVM_TARGET_TARGETASMINFO_H - -#include "llvm/CodeGen/MachineLocation.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetRegisterInfo.h" - -namespace llvm { - template class ArrayRef; - class MCSection; - class MCContext; - class MachineFunction; - class TargetMachine; - class TargetLoweringObjectFile; - -class TargetAsmInfo { - std::vector InitialFrameState; - const TargetRegisterInfo *TRI; - const TargetFrameLowering *TFI; - const TargetLoweringObjectFile *TLOF; - -public: - explicit TargetAsmInfo(const TargetMachine &TM); - - const MCSection *getDwarfLineSection() const { - return TLOF->getDwarfLineSection(); - } - - const MCSection *getEHFrameSection() const { - return TLOF->getEHFrameSection(); - } - - const MCSection *getCompactUnwindSection() const { - return TLOF->getCompactUnwindSection(); - } - - const MCSection *getDwarfFrameSection() const { - return TLOF->getDwarfFrameSection(); - } - - const MCSection *getWin64EHFuncTableSection(StringRef Suffix) const { - return TLOF->getWin64EHFuncTableSection(Suffix); - } - - const MCSection *getWin64EHTableSection(StringRef Suffix) const { - return TLOF->getWin64EHTableSection(Suffix); - } - - unsigned getFDEEncoding(bool CFI) const { - return TLOF->getFDEEncoding(CFI); - } - - bool isFunctionEHFrameSymbolPrivate() const { - return TLOF->isFunctionEHFrameSymbolPrivate(); - } - - int getCompactUnwindEncoding(ArrayRef Instrs, - int DataAlignmentFactor, - bool IsEH) const { - return TFI->getCompactUnwindEncoding(Instrs, DataAlignmentFactor, IsEH); - } - - const unsigned *getCalleeSavedRegs(MachineFunction *MF = 0) const { - return TRI->getCalleeSavedRegs(MF); - } - - unsigned getDwarfRARegNum(bool isEH) const { - return TRI->getDwarfRegNum(TRI->getRARegister(), isEH); - } - - const std::vector &getInitialFrameState() const { - return InitialFrameState; - } - - int getDwarfRegNum(unsigned RegNum, bool isEH) const { - return TRI->getDwarfRegNum(RegNum, isEH); - } - - int getLLVMRegNum(unsigned DwarfRegNum, bool isEH) const { - return TRI->getLLVMRegNum(DwarfRegNum, isEH); - } - - int getSEHRegNum(unsigned RegNum) const { - return TRI->getSEHRegNum(RegNum); - } -}; - -} -#endif diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index c28081000d71..26fd1870ac39 100644 --- a/include/llvm/Target/TargetData.h +++ b/include/llvm/Target/TargetData.h @@ -33,6 +33,8 @@ class StructType; class StructLayout; class GlobalVariable; class LLVMContext; +template +class ArrayRef; /// Enum used to categorize the alignment types stored by TargetAlignElem enum AlignTypeEnum { @@ -42,6 +44,7 @@ enum AlignTypeEnum { AGGREGATE_ALIGN = 'a', ///< Aggregate alignment STACK_ALIGN = 's' ///< Stack objects alignment }; + /// Target alignment element. /// /// Stores the alignment data associated with a given alignment type (pointer, @@ -62,12 +65,19 @@ struct TargetAlignElem { bool operator==(const TargetAlignElem &rhs) const; }; +/// TargetData - This class holds a parsed version of the target data layout +/// string in a module and provides methods for querying it. The target data +/// layout string is specified *by the target* - a frontend generating LLVM IR +/// is required to generate the right target data for the target being codegen'd +/// to. If some measure of portability is desired, an empty string may be +/// specified in the module. class TargetData : public ImmutablePass { private: bool LittleEndian; ///< Defaults to false unsigned PointerMemSize; ///< Pointer size in bytes unsigned PointerABIAlign; ///< Pointer ABI alignment unsigned PointerPrefAlign; ///< Pointer preferred alignment + unsigned StackNaturalAlign; ///< Stack natural alignment SmallVector LegalIntWidths; ///< Legal Integers. @@ -90,9 +100,9 @@ class TargetData : public ImmutablePass { void setAlignment(AlignTypeEnum align_type, unsigned abi_align, unsigned pref_align, uint32_t bit_width); unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width, - bool ABIAlign, const Type *Ty) const; + bool ABIAlign, Type *Ty) const; //! Internal helper method that returns requested alignment for type. - unsigned getAlignment(const Type *Ty, bool abi_or_pref) const; + unsigned getAlignment(Type *Ty, bool abi_or_pref) const; /// Valid alignment predicate. /// @@ -161,6 +171,11 @@ class TargetData : public ImmutablePass { return !isLegalInteger(Width); } + /// Returns true if the given alignment exceeds the natural stack alignment. + bool exceedsNaturalStackAlignment(unsigned Align) const { + return (StackNaturalAlign != 0) && (Align > StackNaturalAlign); + } + /// fitsInLegalInteger - This function returns true if the specified type fits /// in a native integer type supported by the CPU. For example, if the CPU /// only supports i32 as a native integer type, then i27 fits in a legal @@ -200,19 +215,19 @@ class TargetData : public ImmutablePass { /// getTypeSizeInBits - Return the number of bits necessary to hold the /// specified type. For example, returns 36 for i36 and 80 for x86_fp80. - uint64_t getTypeSizeInBits(const Type* Ty) const; + uint64_t getTypeSizeInBits(Type* Ty) const; /// getTypeStoreSize - Return the maximum number of bytes that may be /// overwritten by storing the specified type. For example, returns 5 /// for i36 and 10 for x86_fp80. - uint64_t getTypeStoreSize(const Type *Ty) const { + uint64_t getTypeStoreSize(Type *Ty) const { return (getTypeSizeInBits(Ty)+7)/8; } /// getTypeStoreSizeInBits - Return the maximum number of bits that may be /// overwritten by storing the specified type; always a multiple of 8. For /// example, returns 40 for i36 and 80 for x86_fp80. - uint64_t getTypeStoreSizeInBits(const Type *Ty) const { + uint64_t getTypeStoreSizeInBits(Type *Ty) const { return 8*getTypeStoreSize(Ty); } @@ -220,7 +235,7 @@ class TargetData : public ImmutablePass { /// of the specified type, including alignment padding. This is the amount /// that alloca reserves for this type. For example, returns 12 or 16 for /// x86_fp80, depending on alignment. - uint64_t getTypeAllocSize(const Type* Ty) const { + uint64_t getTypeAllocSize(Type* Ty) const { // Round up to the next alignment boundary. return RoundUpAlignment(getTypeStoreSize(Ty), getABITypeAlignment(Ty)); } @@ -229,13 +244,13 @@ class TargetData : public ImmutablePass { /// objects of the specified type, including alignment padding; always a /// multiple of 8. This is the amount that alloca reserves for this type. /// For example, returns 96 or 128 for x86_fp80, depending on alignment. - uint64_t getTypeAllocSizeInBits(const Type* Ty) const { + uint64_t getTypeAllocSizeInBits(Type* Ty) const { return 8*getTypeAllocSize(Ty); } /// getABITypeAlignment - Return the minimum ABI-required alignment for the /// specified type. - unsigned getABITypeAlignment(const Type *Ty) const; + unsigned getABITypeAlignment(Type *Ty) const; /// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for /// an integer type of the specified bitwidth. @@ -244,17 +259,17 @@ class TargetData : public ImmutablePass { /// getCallFrameTypeAlignment - Return the minimum ABI-required alignment /// for the specified type when it is part of a call frame. - unsigned getCallFrameTypeAlignment(const Type *Ty) const; + unsigned getCallFrameTypeAlignment(Type *Ty) const; /// getPrefTypeAlignment - Return the preferred stack/global alignment for /// the specified type. This is always at least as good as the ABI alignment. - unsigned getPrefTypeAlignment(const Type *Ty) const; + unsigned getPrefTypeAlignment(Type *Ty) const; /// getPreferredTypeAlignmentShift - Return the preferred alignment for the /// specified type, returned as log2 of the value (a shift amount). /// - unsigned getPreferredTypeAlignmentShift(const Type *Ty) const; + unsigned getPreferredTypeAlignmentShift(Type *Ty) const; /// getIntPtrType - Return an unsigned integer type that is the same size or /// greater to the host pointer size. @@ -264,13 +279,12 @@ class TargetData : public ImmutablePass { /// getIndexedOffset - return the offset from the beginning of the type for /// the specified indices. This is used to implement getelementptr. /// - uint64_t getIndexedOffset(const Type *Ty, - Value* const* Indices, unsigned NumIndices) const; + uint64_t getIndexedOffset(Type *Ty, ArrayRef Indices) const; /// getStructLayout - Return a StructLayout object, indicating the alignment /// of the struct, its size, and the offsets of its fields. Note that this /// information is lazily cached. - const StructLayout *getStructLayout(const StructType *Ty) const; + const StructLayout *getStructLayout(StructType *Ty) const; /// getPreferredAlignment - Return the preferred alignment of the specified /// global. This includes an explicitly requested alignment (if the global @@ -333,7 +347,7 @@ class StructLayout { private: friend class TargetData; // Only TargetData can create this class - StructLayout(const StructType *ST, const TargetData &TD); + StructLayout(StructType *ST, const TargetData &TD); }; } // End llvm namespace diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h index e3d77cf7625d..4c759b2ccb9f 100644 --- a/include/llvm/Target/TargetFrameLowering.h +++ b/include/llvm/Target/TargetFrameLowering.h @@ -114,6 +114,10 @@ class TargetFrameLowering { virtual void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const = 0; + /// Adjust the prologue to have the function use segmented stacks. This works + /// by adding a check even before the "normal" function prologue. + virtual void adjustForSegmentedStacks(MachineFunction &MF) const { } + /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee /// saved registers and returns true if it isn't possible / profitable to do /// so by issuing a series of store instructions via @@ -161,11 +165,6 @@ class TargetFrameLowering { return hasReservedCallFrame(MF) || hasFP(MF); } - /// getInitialFrameState - Returns a list of machine moves that are assumed - /// on entry to all functions. Note that LabelID is ignored (assumed to be - /// the beginning of the function.) - virtual void getInitialFrameState(std::vector &Moves) const; - /// getFrameIndexOffset - Returns the displacement from the frame register to /// the stack frame of the specified index. virtual int getFrameIndexOffset(const MachineFunction &MF, int FI) const; @@ -191,14 +190,6 @@ class TargetFrameLowering { /// virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const { } - - /// getCompactUnwindEncoding - Get the compact unwind encoding for the - /// function. Return 0 if the compact unwind isn't available. - virtual uint32_t getCompactUnwindEncoding(ArrayRef Instrs, - int DataAlignmentFactor, - bool IsEH) const { - return 0; - } }; } // End llvm namespace diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index f6635667b5d9..07f614d61d93 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -49,7 +49,7 @@ class TargetInstrInfo : public MCInstrInfo { : CallFrameSetupOpcode(CFSetupOpcode), CallFrameDestroyOpcode(CFDestroyOpcode) { } - + virtual ~TargetInstrInfo(); /// getRegClass - Givem a machine instruction descriptor, returns the register @@ -386,6 +386,16 @@ class TargetInstrInfo : public MCInstrInfo { assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!"); } + /// expandPostRAPseudo - This function is called for all pseudo instructions + /// that remain after register allocation. Many pseudo instructions are + /// created to help register allocation. This is the place to convert them + /// into real instructions. The target can edit MI in place, or it can insert + /// new instructions and erase MI. The function should return true if + /// anything was changed. + virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const { + return false; + } + /// emitFrameIndexDebugValue - Emit a target-dependent form of /// DBG_VALUE encoding the address of a frame index. Addresses would /// normally be lowered the same way as other addresses on the target, @@ -671,6 +681,43 @@ class TargetInstrInfo : public MCInstrInfo { bool hasLowDefLatency(const InstrItineraryData *ItinData, const MachineInstr *DefMI, unsigned DefIdx) const; + /// verifyInstruction - Perform target specific instruction verification. + virtual + bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const { + return true; + } + + /// getExecutionDomain - Return the current execution domain and bit mask of + /// possible domains for instruction. + /// + /// Some micro-architectures have multiple execution domains, and multiple + /// opcodes that perform the same operation in different domains. For + /// example, the x86 architecture provides the por, orps, and orpd + /// instructions that all do the same thing. There is a latency penalty if a + /// register is written in one domain and read in another. + /// + /// This function returns a pair (domain, mask) containing the execution + /// domain of MI, and a bit mask of possible domains. The setExecutionDomain + /// function can be used to change the opcode to one of the domains in the + /// bit mask. Instructions whose execution domain can't be changed should + /// return a 0 mask. + /// + /// The execution domain numbers don't have any special meaning except domain + /// 0 is used for instructions that are not associated with any interesting + /// execution domain. + /// + virtual std::pair + getExecutionDomain(const MachineInstr *MI) const { + return std::make_pair(0, 0); + } + + /// setExecutionDomain - Change the opcode of MI to execute in Domain. + /// + /// The bit (1 << Domain) must be set in the mask returned from + /// getExecutionDomain(MI). + /// + virtual void setExecutionDomain(MachineInstr *MI, unsigned Domain) const {} + private: int CallFrameSetupOpcode, CallFrameDestroyOpcode; }; @@ -693,6 +740,12 @@ class TargetInstrInfoImpl : public TargetInstrInfo { unsigned &SrcOpIdx2) const; virtual bool canFoldMemoryOperand(const MachineInstr *MI, const SmallVectorImpl &Ops) const; + virtual bool hasLoadFromStackSlot(const MachineInstr *MI, + const MachineMemOperand *&MMO, + int &FrameIndex) const; + virtual bool hasStoreToStackSlot(const MachineInstr *MI, + const MachineMemOperand *&MMO, + int &FrameIndex) const; virtual bool PredicateInstruction(MachineInstr *MI, const SmallVectorImpl &Pred) const; virtual void reMaterialize(MachineBasicBlock &MBB, diff --git a/include/llvm/Target/TargetIntrinsicInfo.h b/include/llvm/Target/TargetIntrinsicInfo.h index ad8ac925e930..c44b9230c0d8 100644 --- a/include/llvm/Target/TargetIntrinsicInfo.h +++ b/include/llvm/Target/TargetIntrinsicInfo.h @@ -39,7 +39,7 @@ class TargetIntrinsicInfo { /// 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. - virtual std::string getName(unsigned IID, const Type **Tys = 0, + virtual std::string getName(unsigned IID, Type **Tys = 0, unsigned numTys = 0) const = 0; /// Look up target intrinsic by name. Return intrinsic ID or 0 for unknown @@ -55,7 +55,7 @@ class TargetIntrinsicInfo { /// Create or insert an LLVM Function declaration for an intrinsic, /// and return it. The Tys and numTys are for intrinsics with overloaded /// types. See above for more information. - virtual Function *getDeclaration(Module *M, unsigned ID, const Type **Tys = 0, + virtual Function *getDeclaration(Module *M, unsigned ID, Type **Tys = 0, unsigned numTys = 0) const = 0; }; diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 533c3ac8784f..013e70a05c03 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -113,6 +113,22 @@ class TargetLowering { ZeroOrNegativeOneBooleanContent // All bits equal to bit 0. }; + static ISD::NodeType getExtendForContent(BooleanContent Content) { + switch (Content) { + default: + assert(false && "Unknown BooleanContent!"); + case UndefinedBooleanContent: + // Extend by adding rubbish bits. + return ISD::ANY_EXTEND; + case ZeroOrOneBooleanContent: + // Extend by adding zero bits. + return ISD::ZERO_EXTEND; + case ZeroOrNegativeOneBooleanContent: + // Extend by copying the sign bit. + return ISD::SIGN_EXTEND; + } + } + /// NOTE: The constructor takes ownership of TLOF. explicit TargetLowering(const TargetMachine &TM, const TargetLoweringObjectFile *TLOF); @@ -148,8 +164,7 @@ class TargetLowering { /// the condition operand of SELECT and BRCOND nodes. In the case of /// BRCOND the argument passed is MVT::Other since there are no other /// operands to get a type hint from. - virtual - MVT::SimpleValueType getSetCCResultType(EVT VT) const; + virtual EVT getSetCCResultType(EVT VT) const; /// getCmpLibcallReturnType - Return the ValueType for comparison /// libcalls. Comparions libcalls include floating point comparion calls, @@ -162,7 +177,13 @@ class TargetLowering { /// "Boolean values" are special true/false values produced by nodes like /// SETCC and consumed (as the condition) by nodes like SELECT and BRCOND. /// Not to be confused with general values promoted from i1. - BooleanContent getBooleanContents() const { return BooleanContents;} + /// Some cpus distinguish between vectors of boolean and scalars; the isVec + /// parameter selects between the two kinds. For example on X86 a scalar + /// boolean should be zero extended from i1, while the elements of a vector + /// of booleans should be sign extended from i1. + BooleanContent getBooleanContents(bool isVec) const { + return isVec ? BooleanVectorContents : BooleanContents; + } /// getSchedulingPreference - Return target scheduling preference. Sched::Preference getSchedulingPreference() const { @@ -172,7 +193,7 @@ class TargetLowering { /// getSchedulingPreference - Some scheduler, e.g. hybrid, can switch to /// different scheduling heuristics for different nodes. This function returns /// the preference (or none) for the given node. - virtual Sched::Preference getSchedulingPreference(SDNode *N) const { + virtual Sched::Preference getSchedulingPreference(SDNode *) const { return Sched::None; } @@ -265,9 +286,9 @@ class TargetLowering { assert(!VT.isVector()); while (true) { switch (getTypeAction(Context, VT)) { - case Legal: + case TypeLegal: return VT; - case Expand: + case TypeExpandInteger: VT = getTypeToTransformTo(Context, VT); break; default: @@ -307,15 +328,15 @@ class TargetLowering { bool writeMem; // writes memory? }; - virtual bool getTgtMemIntrinsic(IntrinsicInfo &Info, - const CallInst &I, unsigned Intrinsic) const { + virtual bool getTgtMemIntrinsic(IntrinsicInfo &, const CallInst &, + unsigned /*Intrinsic*/) const { return false; } /// isFPImmLegal - Returns true if the target can instruction select the /// specified FP immediate natively. If false, the legalizer will materialize /// the FP immediate as a load from a constant pool. - virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const { + virtual bool isFPImmLegal(const APFloat &/*Imm*/, EVT /*VT*/) const { return false; } @@ -323,8 +344,8 @@ class TargetLowering { /// support *some* VECTOR_SHUFFLE operations, those with specific masks. /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values /// are assumed to be legal. - virtual bool isShuffleMaskLegal(const SmallVectorImpl &Mask, - EVT VT) const { + virtual bool isShuffleMaskLegal(const SmallVectorImpl &/*Mask*/, + EVT /*VT*/) const { return true; } @@ -337,8 +358,8 @@ class TargetLowering { /// 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 /// pool entry. - virtual bool isVectorClearMaskLegal(const SmallVectorImpl &Mask, - EVT VT) const { + virtual bool isVectorClearMaskLegal(const SmallVectorImpl &/*Mask*/, + EVT /*VT*/) const { return false; } @@ -383,9 +404,7 @@ class TargetLowering { /// isLoadExtLegal - Return true if the specified load with extension is legal /// on this target. bool isLoadExtLegal(unsigned ExtType, EVT VT) const { - return VT.isSimple() && - (getLoadExtAction(ExtType, VT) == Legal || - getLoadExtAction(ExtType, VT) == Custom); + return VT.isSimple() && getLoadExtAction(ExtType, VT) == Legal; } /// getTruncStoreAction - Return how this store with truncation should be @@ -404,8 +423,7 @@ class TargetLowering { /// legal on this target. bool isTruncStoreLegal(EVT ValVT, EVT MemVT) const { return isTypeLegal(ValVT) && MemVT.isSimple() && - (getTruncStoreAction(ValVT, MemVT) == Legal || - getTruncStoreAction(ValVT, MemVT) == Custom); + getTruncStoreAction(ValVT, MemVT) == Legal; } /// getIndexedLoadAction - Return how the indexed load should be treated: @@ -501,7 +519,7 @@ class TargetLowering { /// This is fixed by the LLVM operations except for the pointer size. If /// AllowUnknown is true, this will return MVT::Other for types with no EVT /// counterpart (e.g. structs), otherwise it will assert. - EVT getValueType(const Type *Ty, bool AllowUnknown = false) const { + EVT getValueType(Type *Ty, bool AllowUnknown = false) const { EVT VT = EVT::getEVT(Ty, AllowUnknown); return VT == MVT::iPTR ? PointerTy : VT; } @@ -509,7 +527,7 @@ class TargetLowering { /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate /// function arguments in the caller parameter area. This is the actual /// alignment, not its logarithm. - virtual unsigned getByValTypeAlignment(const Type *Ty) const; + virtual unsigned getByValTypeAlignment(Type *Ty) const; /// getRegisterType - Return the type of registers that this ValueType will /// eventually require. @@ -569,7 +587,7 @@ class TargetLowering { /// ShouldShrinkFPConstant - If true, then instruction selection should /// seek to shrink the FP constant of the specified type to a smaller type /// in order to save space and / or reduce runtime. - virtual bool ShouldShrinkFPConstant(EVT VT) const { return true; } + virtual bool ShouldShrinkFPConstant(EVT) const { return true; } /// hasTargetDAGCombine - If true, the target has custom DAG combine /// transformations that it can perform for the specified node. @@ -611,7 +629,7 @@ class TargetLowering { /// use helps to ensure that such replacements don't generate code that causes /// an alignment error (trap) on the target machine. /// @brief Determine if the target supports unaligned memory accesses. - virtual bool allowsUnalignedMemoryAccesses(EVT VT) const { + virtual bool allowsUnalignedMemoryAccesses(EVT) const { return false; } @@ -634,10 +652,11 @@ class TargetLowering { /// constant so it does not need to be loaded. /// It returns EVT::Other if the type should be determined using generic /// target-independent logic. - virtual EVT getOptimalMemOpType(uint64_t Size, - unsigned DstAlign, unsigned SrcAlign, - bool NonScalarIntSafe, bool MemcpyStrSrc, - MachineFunction &MF) const { + virtual EVT getOptimalMemOpType(uint64_t /*Size*/, + unsigned /*DstAlign*/, unsigned /*SrcAlign*/, + bool /*NonScalarIntSafe*/, + bool /*MemcpyStrSrc*/, + MachineFunction &/*MF*/) const { return MVT::Other; } @@ -717,23 +736,30 @@ class TargetLowering { return ShouldFoldAtomicFences; } + /// getInsertFencesFor - return whether the DAG builder should automatically + /// insert fences and reduce ordering for atomics. + /// + bool getInsertFencesForAtomic() const { + return InsertFencesForAtomic; + } + /// getPreIndexedAddressParts - returns true by value, base pointer and /// offset pointer and addressing mode by reference if the node's address /// can be legally represented as pre-indexed load / store address. - virtual bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, - SDValue &Offset, - ISD::MemIndexedMode &AM, - SelectionDAG &DAG) const { + virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/, + SDValue &/*Offset*/, + ISD::MemIndexedMode &/*AM*/, + SelectionDAG &/*DAG*/) const { return false; } /// getPostIndexedAddressParts - returns true by value, base pointer and /// offset pointer and addressing mode by reference if this node can be /// combined with a load / store to form a post-indexed load / store. - virtual bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, - SDValue &Base, SDValue &Offset, - ISD::MemIndexedMode &AM, - SelectionDAG &DAG) const { + virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/, + SDValue &/*Base*/, SDValue &/*Offset*/, + ISD::MemIndexedMode &/*AM*/, + SelectionDAG &/*DAG*/) const { return false; } @@ -743,9 +769,9 @@ class TargetLowering { virtual unsigned getJumpTableEncoding() const; virtual const MCExpr * - LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, - const MachineBasicBlock *MBB, unsigned uid, - MCContext &Ctx) const { + 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; } @@ -771,7 +797,8 @@ class TargetLowering { /// protector cookies at a fixed offset in some non-standard address /// space, and populates the address space and offset as /// appropriate. - virtual bool getStackCookieLocation(unsigned &AddressSpace, unsigned &Offset) const { + virtual bool getStackCookieLocation(unsigned &/*AddressSpace*/, + unsigned &/*Offset*/) const { return false; } @@ -906,7 +933,7 @@ class TargetLowering { /// the specified value type and it is 'desirable' to use the type for the /// given node type. e.g. On x86 i16 is legal, but undesirable since i16 /// instruction encodings are longer and some i16 instructions are slow. - virtual bool isTypeDesirableForOp(unsigned Opc, EVT VT) const { + virtual bool isTypeDesirableForOp(unsigned /*Opc*/, EVT VT) const { // By default, assume all legal types are desirable. return isTypeLegal(VT); } @@ -914,14 +941,15 @@ class TargetLowering { /// isDesirableToPromoteOp - Return true if it is profitable for dag combiner /// to transform a floating point op of specified opcode to a equivalent op of /// an integer type. e.g. f32 load -> i32 load can be profitable on ARM. - virtual bool isDesirableToTransformToIntegerOp(unsigned Opc, EVT VT) const { + virtual bool isDesirableToTransformToIntegerOp(unsigned /*Opc*/, + EVT /*VT*/) const { return false; } /// IsDesirableToPromoteOp - This method query the target whether it is /// beneficial for dag combiner to promote the specified node. If true, it /// should return the desired promotion type by reference. - virtual bool IsDesirableToPromoteOp(SDValue Op, EVT &PVT) const { + virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const { return false; } @@ -934,6 +962,12 @@ class TargetLowering { /// setBooleanContents - Specify how the target extends the result of a /// boolean value from i1 to a wider type. See getBooleanContents. void setBooleanContents(BooleanContent Ty) { BooleanContents = Ty; } + /// setBooleanVectorContents - Specify how the target extends the result + /// of a vector boolean value from a vector of i1 to a wider type. See + /// getBooleanContents. + void setBooleanVectorContents(BooleanContent Ty) { + BooleanVectorContents = Ty; + } /// setSchedulingPreference - Specify the target scheduling preference. void setSchedulingPreference(Sched::Preference Pref) { @@ -1137,6 +1171,13 @@ class TargetLowering { ShouldFoldAtomicFences = fold; } + /// setInsertFencesForAtomic - Set if the the DAG builder should + /// automatically insert fences and reduce the order of atomic memory + /// operations to Monotonic. + void setInsertFencesForAtomic(bool fence) { + InsertFencesForAtomic = fence; + } + public: //===--------------------------------------------------------------------===// // Lowering methods - These methods must be implemented by targets so that @@ -1150,11 +1191,11 @@ class TargetLowering { /// chain value. /// virtual SDValue - LowerFormalArguments(SDValue Chain, - CallingConv::ID CallConv, bool isVarArg, - const SmallVectorImpl &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl &InVals) const { + LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, + bool /*isVarArg*/, + const SmallVectorImpl &/*Ins*/, + DebugLoc /*dl*/, SelectionDAG &/*DAG*/, + SmallVectorImpl &/*InVals*/) const { assert(0 && "Not Implemented"); return SDValue(); // this is here to silence compiler errors } @@ -1166,7 +1207,7 @@ class TargetLowering { /// lowering. struct ArgListEntry { SDValue Node; - const Type* Ty; + Type* Ty; bool isSExt : 1; bool isZExt : 1; bool isInReg : 1; @@ -1180,7 +1221,7 @@ class TargetLowering { }; typedef std::vector ArgListTy; std::pair - LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt, + LowerCallTo(SDValue Chain, Type *RetTy, bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg, unsigned NumFixedArgs, CallingConv::ID CallConv, bool isTailCall, bool isReturnValueUsed, SDValue Callee, ArgListTy &Args, @@ -1193,13 +1234,14 @@ class TargetLowering { /// InVals array with legal-type return values from the call, and return /// the resulting token chain value. virtual SDValue - LowerCall(SDValue Chain, SDValue Callee, - CallingConv::ID CallConv, bool isVarArg, bool &isTailCall, - const SmallVectorImpl &Outs, - const SmallVectorImpl &OutVals, - const SmallVectorImpl &Ins, - DebugLoc dl, SelectionDAG &DAG, - SmallVectorImpl &InVals) const { + LowerCall(SDValue /*Chain*/, SDValue /*Callee*/, + CallingConv::ID /*CallConv*/, bool /*isVarArg*/, + bool &/*isTailCall*/, + const SmallVectorImpl &/*Outs*/, + const SmallVectorImpl &/*OutVals*/, + const SmallVectorImpl &/*Ins*/, + DebugLoc /*dl*/, SelectionDAG &/*DAG*/, + SmallVectorImpl &/*InVals*/) const { assert(0 && "Not Implemented"); return SDValue(); // this is here to silence compiler errors } @@ -1211,10 +1253,10 @@ class TargetLowering { /// return values described by the Outs array can fit into the return /// registers. If false is returned, an sret-demotion is performed. /// - virtual bool CanLowerReturn(CallingConv::ID CallConv, - MachineFunction &MF, bool isVarArg, - const SmallVectorImpl &Outs, - LLVMContext &Context) const + virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/, + MachineFunction &/*MF*/, bool /*isVarArg*/, + const SmallVectorImpl &/*Outs*/, + LLVMContext &/*Context*/) const { // Return true by default to get preexisting behavior. return true; @@ -1226,10 +1268,11 @@ class TargetLowering { /// value. /// virtual SDValue - LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, - const SmallVectorImpl &Outs, - const SmallVectorImpl &OutVals, - DebugLoc dl, SelectionDAG &DAG) const { + LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/, + bool /*isVarArg*/, + const SmallVectorImpl &/*Outs*/, + const SmallVectorImpl &/*OutVals*/, + DebugLoc /*dl*/, SelectionDAG &/*DAG*/) const { assert(0 && "Not Implemented"); return SDValue(); // this is here to silence compiler errors } @@ -1237,7 +1280,7 @@ class TargetLowering { /// isUsedByReturnOnly - Return true if result of the specified node is used /// by a return node only. This is used to determine whether it is possible /// to codegen a libcall as tail call at legalization time. - virtual bool isUsedByReturnOnly(SDNode *N) const { + virtual bool isUsedByReturnOnly(SDNode *) const { return false; } @@ -1245,7 +1288,7 @@ class TargetLowering { /// call instruction as a tail call. This is used by optimization passes to /// determine if it's profitable to duplicate return instructions to enable /// tailcall optimization. - virtual bool mayBeEmittedAsTailCall(CallInst *CI) const { + virtual bool mayBeEmittedAsTailCall(CallInst *) const { return false; } @@ -1256,7 +1299,7 @@ class TargetLowering { /// necessary for non-C calling conventions. The frontend should handle this /// and include all of the necessary information. virtual EVT getTypeForExtArgOrReturn(LLVMContext &Context, EVT VT, - ISD::NodeType ExtendKind) const { + ISD::NodeType /*ExtendKind*/) const { EVT MinVT = getRegisterType(Context, MVT::i32); return VT.bitsLT(MinVT) ? MinVT : VT; } @@ -1293,8 +1336,9 @@ class TargetLowering { /// /// If the target has no operations that require custom lowering, it need not /// implement this. The default implementation aborts. - virtual void ReplaceNodeResults(SDNode *N, SmallVectorImpl &Results, - SelectionDAG &DAG) const { + virtual void ReplaceNodeResults(SDNode * /*N*/, + SmallVectorImpl &/*Results*/, + SelectionDAG &/*DAG*/) const { assert(0 && "ReplaceNodeResults not implemented for this target!"); } @@ -1304,7 +1348,7 @@ class TargetLowering { /// createFastISel - This method returns a target specific FastISel object, /// or null if the target does not support "fast" ISel. - virtual FastISel *createFastISel(FunctionLoweringInfo &funcInfo) const { + virtual FastISel *createFastISel(FunctionLoweringInfo &) const { return 0; } @@ -1316,7 +1360,7 @@ class TargetLowering { /// call to be explicit llvm code if it wants to. This is useful for /// turning simple inline asms into LLVM intrinsics, which gives the /// compiler more information about the behavior of the code. - virtual bool ExpandInlineAsm(CallInst *CI) const { + virtual bool ExpandInlineAsm(CallInst *) const { return false; } @@ -1460,6 +1504,13 @@ class TargetLowering { virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; + /// AdjustInstrPostInstrSelection - This method should be implemented by + /// targets that mark instructions with the 'hasPostISelHook' flag. These + /// instructions must be adjusted after instruction selection by target hooks. + /// e.g. To fill in optional defs for ARM 's' setting instructions. + virtual void + AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const; + //===--------------------------------------------------------------------===// // Addressing mode description hooks (used by LSR etc). // @@ -1485,16 +1536,32 @@ class TargetLowering { /// The type may be VoidTy, in which case only return true if the addressing /// mode is legal for a load/store of any legal type. /// TODO: Handle pre/postinc as well. - virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty) const; + virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const; + + /// isLegalICmpImmediate - Return true if the specified immediate is legal + /// icmp immediate, that is the target has icmp instructions which can compare + /// a register against the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalICmpImmediate(int64_t) const { + return true; + } + + /// isLegalAddImmediate - Return true if the specified immediate is legal + /// add immediate, that is the target has add instructions which can add + /// a register with the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalAddImmediate(int64_t) const { + return true; + } /// isTruncateFree - Return true if it's free to truncate a value of /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in /// register EAX to i16 by referencing its sub-register AX. - virtual bool isTruncateFree(const Type *Ty1, const Type *Ty2) const { + virtual bool isTruncateFree(Type * /*Ty1*/, Type * /*Ty2*/) const { return false; } - virtual bool isTruncateFree(EVT VT1, EVT VT2) const { + virtual bool isTruncateFree(EVT /*VT1*/, EVT /*VT2*/) const { return false; } @@ -1506,37 +1573,21 @@ class TargetLowering { /// does not necessarily apply to truncate instructions. e.g. on x86-64, /// all instructions that define 32-bit values implicit zero-extend the /// result out to 64 bits. - virtual bool isZExtFree(const Type *Ty1, const Type *Ty2) const { + virtual bool isZExtFree(Type * /*Ty1*/, Type * /*Ty2*/) const { return false; } - virtual bool isZExtFree(EVT VT1, EVT VT2) const { + virtual bool isZExtFree(EVT /*VT1*/, EVT /*VT2*/) const { return false; } /// isNarrowingProfitable - Return true if it's profitable to narrow /// operations of type VT1 to VT2. e.g. on x86, it's profitable to narrow /// from i32 to i8 but not from i32 to i16. - virtual bool isNarrowingProfitable(EVT VT1, EVT VT2) const { + virtual bool isNarrowingProfitable(EVT /*VT1*/, EVT /*VT2*/) const { return false; } - /// isLegalICmpImmediate - Return true if the specified immediate is legal - /// icmp immediate, that is the target has icmp instructions which can compare - /// a register against the immediate without having to materialize the - /// immediate into a register. - virtual bool isLegalICmpImmediate(int64_t Imm) const { - return true; - } - - /// isLegalAddImmediate - Return true if the specified immediate is legal - /// add immediate, that is the target has add instructions which can add - /// a register with the immediate without having to materialize the - /// immediate into a register. - virtual bool isLegalAddImmediate(int64_t Imm) const { - return true; - } - //===--------------------------------------------------------------------===// // Div utility functions // @@ -1639,6 +1690,10 @@ class TargetLowering { /// BooleanContents - Information about the contents of the high-bits in /// boolean values held in a type wider than i1. See getBooleanContents. BooleanContent BooleanContents; + /// BooleanVectorContents - Information about the contents of the high-bits + /// in boolean vector values when the element type is wider than i1. See + /// getBooleanContents. + BooleanContent BooleanVectorContents; /// SchedPreferenceInfo - The target scheduling preference: shortest possible /// total cycles or lowest register usage. @@ -1676,6 +1731,11 @@ class TargetLowering { /// combiner. bool ShouldFoldAtomicFences; + /// InsertFencesForAtomic - Whether the DAG builder should automatically + /// insert fences and reduce ordering for atomics. (This will be set for + /// for most architectures with weak memory ordering.) + bool InsertFencesForAtomic; + /// StackPointerRegisterToSaveRestore - If set to a physical register, this /// specifies the register that llvm.savestack/llvm.restorestack should save /// and restore. @@ -1963,7 +2023,7 @@ class TargetLowering { /// GetReturnInfo - Given an LLVM IR type and return type attributes, /// compute the return value EVTs and flags, and optionally also /// the offsets, if the return value is being lowered to memory. -void GetReturnInfo(const Type* ReturnType, Attributes attr, +void GetReturnInfo(Type* ReturnType, Attributes attr, SmallVectorImpl &Outs, const TargetLowering &TLI, SmallVectorImpl *Offsets = 0); diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 2e1d6b97e733..7d06cec0a4e1 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -16,6 +16,7 @@ #define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/SectionKind.h" namespace llvm { @@ -31,137 +32,27 @@ namespace llvm { class GlobalValue; class TargetMachine; -class TargetLoweringObjectFile { +class TargetLoweringObjectFile : public MCObjectFileInfo { MCContext *Ctx; TargetLoweringObjectFile(const TargetLoweringObjectFile&); // DO NOT IMPLEMENT void operator=(const TargetLoweringObjectFile&); // DO NOT IMPLEMENT -protected: - TargetLoweringObjectFile(); - - /// TextSection - Section directive for standard text. - /// - const MCSection *TextSection; - - /// DataSection - Section directive for standard data. - /// - const MCSection *DataSection; - - /// BSSSection - Section that is default initialized to zero. - const MCSection *BSSSection; - - /// ReadOnlySection - Section that is readonly and can contain arbitrary - /// initialized data. Targets are not required to have a readonly section. - /// If they don't, various bits of code will fall back to using the data - /// section for constants. - const MCSection *ReadOnlySection; - - /// StaticCtorSection - This section contains the static constructor pointer - /// list. - const MCSection *StaticCtorSection; - - /// StaticDtorSection - This section contains the static destructor pointer - /// list. - const MCSection *StaticDtorSection; - - /// LSDASection - If exception handling is supported by the target, this is - /// the section the Language Specific Data Area information is emitted to. - const MCSection *LSDASection; - - /// CompactUnwindSection - If exception handling is supported by the target - /// and the target can support a compact representation of the CIE and FDE, - /// this is the section to emit them into. - const MCSection *CompactUnwindSection; - - // Dwarf sections for debug info. If a target supports debug info, these must - // be set. - const MCSection *DwarfAbbrevSection; - const MCSection *DwarfInfoSection; - const MCSection *DwarfLineSection; - const MCSection *DwarfFrameSection; - const MCSection *DwarfPubNamesSection; - const MCSection *DwarfPubTypesSection; - const MCSection *DwarfDebugInlineSection; - const MCSection *DwarfStrSection; - const MCSection *DwarfLocSection; - const MCSection *DwarfARangesSection; - const MCSection *DwarfRangesSection; - const MCSection *DwarfMacroInfoSection; - - // Extra TLS Variable Data section. If the target needs to put additional - // information for a TLS variable, it'll go here. - const MCSection *TLSExtraDataSection; - - /// CommDirectiveSupportsAlignment - True if .comm supports alignment. This - /// is a hack for as long as we support 10.4 Tiger, whose assembler doesn't - /// support alignment on comm. - bool CommDirectiveSupportsAlignment; - - /// SupportsWeakEmptyEHFrame - True if target object file supports a - /// weak_definition of constant 0 for an omitted EH frame. - bool SupportsWeakOmittedEHFrame; - - /// IsFunctionEHFrameSymbolPrivate - This flag is set to true if the - /// "EH_frame" symbol for EH information should be an assembler temporary (aka - /// private linkage, aka an L or .L label) or false if it should be a normal - /// non-.globl label. This defaults to true. - bool IsFunctionEHFrameSymbolPrivate; - public: MCContext &getContext() const { return *Ctx; } + + TargetLoweringObjectFile() : MCObjectFileInfo(), Ctx(0) {} virtual ~TargetLoweringObjectFile(); /// Initialize - this method must be called before any actual lowering is /// done. This specifies the current context for codegen, and gives the /// lowering implementations a chance to set up their default sections. - virtual void Initialize(MCContext &ctx, const TargetMachine &TM) { - Ctx = &ctx; - } + virtual void Initialize(MCContext &ctx, const TargetMachine &TM); - bool isFunctionEHFrameSymbolPrivate() const { - return IsFunctionEHFrameSymbolPrivate; - } - bool getSupportsWeakOmittedEHFrame() const { - return SupportsWeakOmittedEHFrame; - } - bool getCommDirectiveSupportsAlignment() const { - return CommDirectiveSupportsAlignment; - } - - const MCSection *getTextSection() const { return TextSection; } - const MCSection *getDataSection() const { return DataSection; } - const MCSection *getBSSSection() const { return BSSSection; } - const MCSection *getStaticCtorSection() const { return StaticCtorSection; } - const MCSection *getStaticDtorSection() const { return StaticDtorSection; } - const MCSection *getLSDASection() const { return LSDASection; } - const MCSection *getCompactUnwindSection() const{return CompactUnwindSection;} - virtual const MCSection *getEHFrameSection() const = 0; virtual void emitPersonalityValue(MCStreamer &Streamer, const TargetMachine &TM, const MCSymbol *Sym) const; - const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; } - const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; } - const MCSection *getDwarfLineSection() const { return DwarfLineSection; } - const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; } - const MCSection *getDwarfPubNamesSection() const{return DwarfPubNamesSection;} - const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSection;} - const MCSection *getDwarfDebugInlineSection() const { - return DwarfDebugInlineSection; - } - const MCSection *getDwarfStrSection() const { return DwarfStrSection; } - const MCSection *getDwarfLocSection() const { return DwarfLocSection; } - const MCSection *getDwarfARangesSection() const { return DwarfARangesSection;} - const MCSection *getDwarfRangesSection() const { return DwarfRangesSection; } - const MCSection *getDwarfMacroInfoSection() const { - return DwarfMacroInfoSection; - } - const MCSection *getTLSExtraDataSection() const { - return TLSExtraDataSection; - } - virtual const MCSection *getWin64EHFuncTableSection(StringRef suffix)const=0; - virtual const MCSection *getWin64EHTableSection(StringRef suffix) const = 0; /// shouldEmitUsedDirectiveFor - This hook allows targets to selectively /// decide not to emit the UsedDirective for some symbols in llvm.used. @@ -231,11 +122,6 @@ class TargetLoweringObjectFile { getExprForDwarfReference(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const; - virtual unsigned getPersonalityEncoding() const; - virtual unsigned getLSDAEncoding() const; - virtual unsigned getFDEEncoding(bool CFI) const; - virtual unsigned getTTypeEncoding() const; - protected: virtual const MCSection * SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index ac41a58ccda2..8a8d14229055 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -14,6 +14,7 @@ #ifndef LLVM_TARGET_TARGETMACHINE_H #define LLVM_TARGET_TARGETMACHINE_H +#include "llvm/MC/MCCodeGenInfo.h" #include "llvm/ADT/StringRef.h" #include #include @@ -23,6 +24,7 @@ namespace llvm { class InstrItineraryData; class JITCodeEmitter; class MCAsmInfo; +class MCCodeGenInfo; class MCContext; class Pass; class PassManager; @@ -41,27 +43,6 @@ class TargetSubtargetInfo; class formatted_raw_ostream; class raw_ostream; -// Relocation model types. -namespace Reloc { - enum Model { - Default, - Static, - PIC_, // Cannot be named PIC due to collision with -DPIC - DynamicNoPIC - }; -} - -// Code model types. -namespace CodeModel { - enum Model { - Default, - Small, - Kernel, - Medium, - Large - }; -} - // Code generation optimization level. namespace CodeGenOpt { enum Level { @@ -108,6 +89,9 @@ class TargetMachine { std::string TargetCPU; std::string TargetFS; + /// CodeGenInfo - Low level target information such as relocation model. + const MCCodeGenInfo *CodeGenInfo; + /// AsmInfo - Contains target specific asm information. /// const MCAsmInfo *AsmInfo; @@ -214,19 +198,11 @@ class TargetMachine { /// getRelocationModel - Returns the code generation relocation model. The /// choices are static, PIC, and dynamic-no-pic, and target default. - static Reloc::Model getRelocationModel(); - - /// setRelocationModel - Sets the code generation relocation model. - /// - static void setRelocationModel(Reloc::Model Model); + Reloc::Model getRelocationModel() const; /// getCodeModel - Returns the code model. The choices are small, kernel, /// medium, large, and target default. - static CodeModel::Model getCodeModel(); - - /// setCodeModel - Sets the code model. - /// - static void setCodeModel(CodeModel::Model Model); + CodeModel::Model getCodeModel() const; /// getAsmVerbosityDefault - Returns the default value of asm verbosity. /// @@ -309,7 +285,8 @@ class TargetMachine { class LLVMTargetMachine : public TargetMachine { protected: // Can only create subclasses. LLVMTargetMachine(const Target &T, StringRef TargetTriple, - StringRef CPU, StringRef FS); + StringRef CPU, StringRef FS, + Reloc::Model RM, CodeModel::Model CM); private: /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for @@ -318,9 +295,6 @@ class LLVMTargetMachine : public TargetMachine { bool addCommonCodeGenPasses(PassManagerBase &, CodeGenOpt::Level, bool DisableVerify, MCContext *&OutCtx); - virtual void setCodeModelForJIT(); - virtual void setCodeModelForStatic(); - public: /// addPassesToEmitFile - Add passes to the specified pass manager to get the /// specified file emitted. Typically this will involve several steps of code diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 55d50d977dc4..e07e8c1cea08 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -158,6 +158,8 @@ namespace llvm { /// instead of an ISD::TRAP node. extern StringRef getTrapFunctionName(); + extern bool EnableSegmentedStacks; + } // End llvm namespace #endif diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 8d827f117bad..682aa50736db 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -20,7 +20,6 @@ #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseSet.h" #include #include @@ -36,76 +35,75 @@ class TargetRegisterClass { public: typedef const unsigned* iterator; typedef const unsigned* const_iterator; - typedef const EVT* vt_iterator; typedef const TargetRegisterClass* const * sc_iterator; private: - unsigned ID; - const char *Name; + const MCRegisterClass *MC; const vt_iterator VTs; - const sc_iterator SubClasses; + const unsigned *SubClassMask; const sc_iterator SuperClasses; - const sc_iterator SubRegClasses; const sc_iterator SuperRegClasses; - const unsigned RegSize, Alignment; // Size & Alignment of register in bytes - const int CopyCost; - const bool Allocatable; - const iterator RegsBegin, RegsEnd; - DenseSet RegSet; public: - TargetRegisterClass(unsigned id, - const char *name, - const EVT *vts, - const TargetRegisterClass * const *subcs, + TargetRegisterClass(const MCRegisterClass *MC, const EVT *vts, + const unsigned *subcm, const TargetRegisterClass * const *supcs, - const TargetRegisterClass * const *subregcs, - const TargetRegisterClass * const *superregcs, - unsigned RS, unsigned Al, int CC, bool Allocable, - iterator RB, iterator RE) - : ID(id), Name(name), VTs(vts), SubClasses(subcs), SuperClasses(supcs), - SubRegClasses(subregcs), SuperRegClasses(superregcs), - RegSize(RS), Alignment(Al), CopyCost(CC), Allocatable(Allocable), - RegsBegin(RB), RegsEnd(RE) { - for (iterator I = RegsBegin, E = RegsEnd; I != E; ++I) - RegSet.insert(*I); - } + const TargetRegisterClass * const *superregcs) + : MC(MC), VTs(vts), SubClassMask(subcm), SuperClasses(supcs), + SuperRegClasses(superregcs) {} + virtual ~TargetRegisterClass() {} // Allow subclasses /// getID() - Return the register class ID number. /// - unsigned getID() const { return ID; } + unsigned getID() const { return MC->getID(); } /// getName() - Return the register class name for debugging. /// - const char *getName() const { return Name; } + const char *getName() const { return MC->getName(); } /// begin/end - Return all of the registers in this class. /// - iterator begin() const { return RegsBegin; } - iterator end() const { return RegsEnd; } + iterator begin() const { return MC->begin(); } + iterator end() const { return MC->end(); } /// getNumRegs - Return the number of registers in this class. /// - unsigned getNumRegs() const { return (unsigned)(RegsEnd-RegsBegin); } + unsigned getNumRegs() const { return MC->getNumRegs(); } /// getRegister - Return the specified register in the class. /// unsigned getRegister(unsigned i) const { - assert(i < getNumRegs() && "Register number out of range!"); - return RegsBegin[i]; + return MC->getRegister(i); } /// contains - Return true if the specified register is included in this /// register class. This does not include virtual registers. bool contains(unsigned Reg) const { - return RegSet.count(Reg); + return MC->contains(Reg); } /// contains - Return true if both registers are in this class. bool contains(unsigned Reg1, unsigned Reg2) const { - return contains(Reg1) && contains(Reg2); + return MC->contains(Reg1, Reg2); } + /// getSize - Return the size of the register in bytes, which is also the size + /// of a stack slot allocated to hold a spilled copy of this register. + unsigned getSize() const { return MC->getSize(); } + + /// getAlignment - Return the minimum required alignment for a register of + /// this class. + unsigned getAlignment() const { return MC->getAlignment(); } + + /// getCopyCost - Return the cost of copying a value between two registers in + /// this class. A negative number means the register class is very expensive + /// to copy e.g. status flag register classes. + int getCopyCost() const { return MC->getCopyCost(); } + + /// isAllocatable - Return true if this register class may be used to create + /// virtual registers. + bool isAllocatable() const { return MC->isAllocatable(); } + /// hasType - return true if this TargetRegisterClass has the ValueType vt. /// bool hasType(EVT vt) const { @@ -127,25 +125,6 @@ class TargetRegisterClass { return I; } - /// subregclasses_begin / subregclasses_end - Loop over all of - /// the subreg register classes of this register class. - sc_iterator subregclasses_begin() const { - return SubRegClasses; - } - - sc_iterator subregclasses_end() const { - sc_iterator I = SubRegClasses; - while (*I != NULL) ++I; - return I; - } - - /// getSubRegisterRegClass - Return the register class of subregisters with - /// index SubIdx, or NULL if no such class exists. - const TargetRegisterClass* getSubRegisterRegClass(unsigned SubIdx) const { - assert(SubIdx>0 && "Invalid subregister index"); - return SubRegClasses[SubIdx-1]; - } - /// superregclasses_begin / superregclasses_end - Loop over all of /// the superreg register classes of this register class. sc_iterator superregclasses_begin() const { @@ -159,59 +138,44 @@ class 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) - if (SubClasses[i] == cs) - return true; - return false; + /// is a proper sub-class of this TargetRegisterClass. + bool hasSubClass(const TargetRegisterClass *RC) const { + return RC != this && hasSubClassEq(RC); } - /// hasSubClassEq - Returns true if RC is a subclass of or equal to this + /// hasSubClassEq - Returns true if RC is a sub-class of or equal to this /// class. bool hasSubClassEq(const TargetRegisterClass *RC) const { - return RC == this || hasSubClass(RC); - } - - /// subclasses_begin / subclasses_end - Loop over all of the classes - /// that are proper subsets of this register class. - sc_iterator subclasses_begin() const { - return SubClasses; - } - - sc_iterator subclasses_end() const { - sc_iterator I = SubClasses; - while (*I != NULL) ++I; - return I; + unsigned ID = RC->getID(); + return (SubClassMask[ID / 32] >> (ID % 32)) & 1; } /// hasSuperClass - return true if the specified TargetRegisterClass is a - /// proper superset of this TargetRegisterClass. - bool hasSuperClass(const TargetRegisterClass *cs) const { - for (int i = 0; SuperClasses[i] != NULL; ++i) - if (SuperClasses[i] == cs) - return true; - return false; + /// proper super-class of this TargetRegisterClass. + bool hasSuperClass(const TargetRegisterClass *RC) const { + return RC->hasSubClass(this); } - /// hasSuperClassEq - Returns true if RC is a superclass of or equal to this + /// hasSuperClassEq - Returns true if RC is a super-class of or equal to this /// class. bool hasSuperClassEq(const TargetRegisterClass *RC) const { - return RC == this || hasSuperClass(RC); + return RC->hasSubClassEq(this); } - /// superclasses_begin / superclasses_end - Loop over all of the classes - /// that are proper supersets of this register class. - sc_iterator superclasses_begin() const { + /// getSubClassMask - Returns a bit vector of subclasses, including this one. + /// The vector is indexed by class IDs, see hasSubClassEq() above for how to + /// use it. + const unsigned *getSubClassMask() const { + return SubClassMask; + } + + /// getSuperClasses - Returns a NULL terminated list of super-classes. The + /// classes are ordered by ID which is also a topological ordering from large + /// to small classes. The list does NOT include the current class. + sc_iterator getSuperClasses() const { return SuperClasses; } - sc_iterator superclasses_end() const { - sc_iterator I = SuperClasses; - while (*I != NULL) ++I; - return I; - } - /// isASubClass - return true if this TargetRegisterClass is a subset /// class of at least one other TargetRegisterClass. bool isASubClass() const { @@ -234,25 +198,8 @@ class TargetRegisterClass { /// virtual ArrayRef getRawAllocationOrder(const MachineFunction &MF) const { - return ArrayRef(begin(), getNumRegs()); + return makeArrayRef(begin(), getNumRegs()); } - - /// getSize - Return the size of the register in bytes, which is also the size - /// of a stack slot allocated to hold a spilled copy of this register. - unsigned getSize() const { return RegSize; } - - /// getAlignment - Return the minimum required alignment for a register of - /// this class. - unsigned getAlignment() const { return Alignment; } - - /// getCopyCost - Return the cost of copying a value between two registers in - /// this class. A negative number means the register class is very expensive - /// to copy e.g. status flag register classes. - int getCopyCost() const { return CopyCost; } - - /// isAllocatable - Return true if this register class may be used to create - /// virtual registers. - bool isAllocatable() const { return Allocatable; } }; /// TargetRegisterInfoDesc - Extra information, not in MCRegisterDesc, about @@ -461,6 +408,20 @@ class TargetRegisterInfo : public MCRegisterInfo { return 0; } + /// getSubClassWithSubReg - Returns the largest legal sub-class of RC that + /// supports the sub-register index Idx. + /// If no such sub-class exists, return NULL. + /// If all registers in RC already have an Idx sub-register, return RC. + /// + /// TableGen generates a version of this function that is good enough in most + /// cases. Targets can override if they have constraints that TableGen + /// doesn't understand. For example, the x86 sub_8bit sub-register index is + /// supported by the full GR32 register class in 64-bit mode, but only by the + /// GR32_ABCD regiister class in 32-bit mode. + /// + virtual const TargetRegisterClass * + getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const =0; + /// composeSubRegIndices - Return the subregister index you get from composing /// two subregister indices. /// @@ -498,6 +459,12 @@ class TargetRegisterInfo : public MCRegisterInfo { return RegClassBegin[i]; } + /// getCommonSubClass - find the largest common subclass of A and B. Return + /// NULL if there is no common subclass. + const TargetRegisterClass * + getCommonSubClass(const TargetRegisterClass *A, + const TargetRegisterClass *B) const; + /// getPointerRegClass - Returns a TargetRegisterClass used for pointer /// values. If a target supports multiple different pointer register classes, /// kind specifies which one is indicated. @@ -699,28 +666,10 @@ class TargetRegisterInfo : public MCRegisterInfo { //===--------------------------------------------------------------------===// /// Debug information queries. - /// getDwarfRegNum - Map a target register to an equivalent dwarf register - /// number. Returns -1 if there is no equivalent value. The second - /// parameter allows targets to use different numberings for EH info and - /// debugging info. - virtual int getDwarfRegNum(unsigned RegNum, bool isEH) const = 0; - - virtual int getLLVMRegNum(unsigned RegNum, bool isEH) const = 0; - /// getFrameRegister - This method should return the register used as a base /// for values allocated in the current stack frame. virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0; - /// getRARegister - This method should return the register where the return - /// address can be found. - virtual unsigned getRARegister() const = 0; - - /// getSEHRegNum - Map a target register to an equivalent SEH register - /// number. Returns -1 if there is no equivalent value. - virtual int getSEHRegNum(unsigned i) const { - return i; - } - /// getCompactUnwindRegNum - This function maps the register to the number for /// compact unwind encoding. Return -1 if the register isn't valid. virtual int getCompactUnwindRegNum(unsigned, bool) const { @@ -736,11 +685,6 @@ struct VirtReg2IndexFunctor : public std::unary_function { } }; -/// getCommonSubClass - find the largest common subclass of A and B. Return NULL -/// if there is no common subclass. -const TargetRegisterClass *getCommonSubClass(const TargetRegisterClass *A, - const TargetRegisterClass *B); - /// PrintReg - Helper class for printing registers on a raw_ostream. /// Prints virtual and physical registers with or without a TRI instance. /// diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td index 9d1ef2c13729..612635ea746d 100644 --- a/include/llvm/Target/TargetSelectionDAG.td +++ b/include/llvm/Target/TargetSelectionDAG.td @@ -149,6 +149,10 @@ def SDTSelect : SDTypeProfile<1, 3, [ // select SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> ]>; +def SDTVSelect : SDTypeProfile<1, 3, [ // vselect + SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> +]>; + def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisSameAs<0, 3>, SDTCisVT<5, OtherVT> @@ -205,12 +209,21 @@ def SDTMemBarrier : SDTypeProfile<0, 5, [ // memory barier SDTCisSameAs<0,1>, SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisSameAs<0,4>, SDTCisInt<0> ]>; +def SDTAtomicFence : SDTypeProfile<0, 2, [ + SDTCisSameAs<0,1>, SDTCisPtrTy<0> +]>; def SDTAtomic3 : SDTypeProfile<1, 3, [ SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1> ]>; def SDTAtomic2 : SDTypeProfile<1, 2, [ SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1> ]>; +def SDTAtomicStore : SDTypeProfile<0, 2, [ + SDTCisPtrTy<0>, SDTCisInt<1> +]>; +def SDTAtomicLoad : SDTypeProfile<1, 1, [ + SDTCisInt<0>, SDTCisPtrTy<1> +]>; def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5> @@ -381,8 +394,8 @@ def f32_to_f16 : SDNode<"ISD::FP32_TO_FP16", SDTFPToIntOp>; def setcc : SDNode<"ISD::SETCC" , SDTSetCC>; def select : SDNode<"ISD::SELECT" , SDTSelect>; +def vselect : SDNode<"ISD::VSELECT" , SDTVSelect>; def selectcc : SDNode<"ISD::SELECT_CC" , SDTSelectCC>; -def vsetcc : SDNode<"ISD::VSETCC" , SDTSetCC>; def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>; def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>; @@ -397,6 +410,9 @@ def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch, def membarrier : SDNode<"ISD::MEMBARRIER" , SDTMemBarrier, [SDNPHasChain, SDNPSideEffect]>; +def atomic_fence : SDNode<"ISD::ATOMIC_FENCE" , SDTAtomicFence, + [SDNPHasChain, SDNPSideEffect]>; + def atomic_cmp_swap : SDNode<"ISD::ATOMIC_CMP_SWAP" , SDTAtomic3, [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; def atomic_load_add : SDNode<"ISD::ATOMIC_LOAD_ADD" , SDTAtomic2, @@ -421,6 +437,10 @@ def atomic_load_umin : SDNode<"ISD::ATOMIC_LOAD_UMIN", SDTAtomic2, [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; def atomic_load_umax : SDNode<"ISD::ATOMIC_LOAD_UMAX", SDTAtomic2, [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; +def atomic_store : SDNode<"ISD::ATOMIC_STORE", SDTAtomicStore, + [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; // Do not use ld, st directly. Use load, extload, sextload, zextload, store, // and truncst (see below). @@ -838,6 +858,28 @@ defm atomic_load_min : binary_atomic_op; defm atomic_load_max : binary_atomic_op; defm atomic_load_umin : binary_atomic_op; defm atomic_load_umax : binary_atomic_op; +defm atomic_store : binary_atomic_op; + +def atomic_load_8 : + PatFrag<(ops node:$ptr), + (atomic_load node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i8; +}]>; +def atomic_load_16 : + PatFrag<(ops node:$ptr), + (atomic_load node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i16; +}]>; +def atomic_load_32 : + PatFrag<(ops node:$ptr), + (atomic_load node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i32; +}]>; +def atomic_load_64 : + PatFrag<(ops node:$ptr), + (atomic_load node:$ptr), [{ + return cast(N)->getMemoryVT() == MVT::i64; +}]>; //===----------------------------------------------------------------------===// // Selection DAG CONVERT_RNDSAT patterns diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h index f025e180678b..f9d7f9e6b98a 100644 --- a/include/llvm/Transforms/IPO.h +++ b/include/llvm/Transforms/IPO.h @@ -49,13 +49,6 @@ ModulePass *createStripDebugDeclarePass(); // These pass removes unused symbols' debug info. ModulePass *createStripDeadDebugInfoPass(); -//===----------------------------------------------------------------------===// -/// createLowerSetJmpPass - This function lowers the setjmp/longjmp intrinsics -/// to invoke/unwind instructions. This should really be part of the C/C++ -/// front-end, but it's so much easier to write transformations in LLVM proper. -/// -ModulePass *createLowerSetJmpPass(); - //===----------------------------------------------------------------------===// /// createConstantMergePass - This function returns a new pass that merges /// duplicate global constants together into a single constant that is shared. @@ -81,7 +74,7 @@ ModulePass *createGlobalDCEPass(); //===----------------------------------------------------------------------===// -/// createGVExtractionPass - If deleteFn is true, this pass deletes as +/// createGVExtractionPass - If deleteFn is true, this pass deletes /// the specified global values. Otherwise, it deletes as much of the module as /// possible, except for the global values specified. /// diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h new file mode 100644 index 000000000000..cc74e7fefe16 --- /dev/null +++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -0,0 +1,133 @@ +// llvm/Transforms/IPO/PassManagerBuilder.h - Build Standard Pass -*- 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 PassManagerBuilder class, which is used to set up a +// "standard" optimization sequence suitable for languages like C and C++. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_PASSMANAGERBUILDER_H +#define LLVM_SUPPORT_PASSMANAGERBUILDER_H + +#include + +namespace llvm { + class TargetLibraryInfo; + class PassManagerBase; + class Pass; + class FunctionPassManager; + +/// PassManagerBuilder - This class is used to set up a standard optimization +/// sequence for languages like C and C++, allowing some APIs to customize the +/// pass sequence in various ways. A simple example of using it would be: +/// +/// PassManagerBuilder Builder; +/// Builder.OptLevel = 2; +/// Builder.populateFunctionPassManager(FPM); +/// Builder.populateModulePassManager(MPM); +/// +/// In addition to setting up the basic passes, PassManagerBuilder allows +/// frontends to vend a plugin API, where plugins are allowed to add extensions +/// to the default pass manager. They do this by specifying where in the pass +/// pipeline they want to be added, along with a callback function that adds +/// the pass(es). For example, a plugin that wanted to add a loop optimization +/// could do something like this: +/// +/// static void addMyLoopPass(const PMBuilder &Builder, PassManagerBase &PM) { +/// if (Builder.getOptLevel() > 2 && Builder.getOptSizeLevel() == 0) +/// PM.add(createMyAwesomePass()); +/// } +/// ... +/// Builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, +/// addMyLoopPass); +/// ... +class PassManagerBuilder { +public: + + /// Extensions are passed the builder itself (so they can see how it is + /// configured) as well as the pass manager to add stuff to. + typedef void (*ExtensionFn)(const PassManagerBuilder &Builder, + PassManagerBase &PM); + enum ExtensionPointTy { + /// EP_EarlyAsPossible - This extension point allows adding passes before + /// any other transformations, allowing them to see the code as it is coming + /// out of the frontend. + EP_EarlyAsPossible, + + /// EP_LoopOptimizerEnd - This extension point allows adding loop passes to + /// the end of the loop optimizer. + EP_LoopOptimizerEnd, + + /// EP_ScalarOptimizerLate - This extension point allows adding optimization + /// passes after most of the main optimizations, but before the last + /// cleanup-ish optimizations. + EP_ScalarOptimizerLate + }; + + /// The Optimization Level - Specify the basic optimization level. + /// 0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3 + unsigned OptLevel; + + /// SizeLevel - How much we're optimizing for size. + /// 0 = none, 1 = -Os, 2 = -Oz + unsigned SizeLevel; + + /// LibraryInfo - Specifies information about the runtime library for the + /// optimizer. If this is non-null, it is added to both the function and + /// per-module pass pipeline. + TargetLibraryInfo *LibraryInfo; + + /// Inliner - Specifies the inliner to use. If this is non-null, it is + /// added to the per-module passes. + Pass *Inliner; + + bool DisableSimplifyLibCalls; + bool DisableUnitAtATime; + bool DisableUnrollLoops; + +private: + /// ExtensionList - This is list of all of the extensions that are registered. + std::vector > Extensions; + +public: + PassManagerBuilder(); + ~PassManagerBuilder(); + /// Adds an extension that will be used by all PassManagerBuilder instances. + /// This is intended to be used by plugins, to register a set of + /// optimisations to run automatically. + static void addGlobalExtension(ExtensionPointTy Ty, ExtensionFn Fn); + void addExtension(ExtensionPointTy Ty, ExtensionFn Fn); + +private: + void addExtensionsToPM(ExtensionPointTy ETy, PassManagerBase &PM) const; + void addInitialAliasAnalysisPasses(PassManagerBase &PM) const; +public: + + /// populateFunctionPassManager - This fills in the function pass manager, + /// which is expected to be run on each function immediately as it is + /// generated. The idea is to reduce the size of the IR in memory. + void populateFunctionPassManager(FunctionPassManager &FPM); + + /// populateModulePassManager - This sets up the primary pass manager. + void populateModulePassManager(PassManagerBase &MPM); + void populateLTOPassManager(PassManagerBase &PM, bool Internalize, + bool RunInliner); +}; +/// Registers a function for adding a standard set of passes. This should be +/// used by optimizer plugins to allow all front ends to transparently use +/// them. Create a static instance of this class in your plugin, providing a +/// private function that the PassManagerBuilder can use to add your passes. +struct RegisterStandardPasses { + RegisterStandardPasses(PassManagerBuilder::ExtensionPointTy Ty, + PassManagerBuilder::ExtensionFn Fn) { + PassManagerBuilder::addGlobalExtension(Ty, Fn); + } +}; +} // end namespace llvm +#endif diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h index 2187d4eb7651..b1536f906d8c 100644 --- a/include/llvm/Transforms/Scalar.h +++ b/include/llvm/Transforms/Scalar.h @@ -174,13 +174,6 @@ extern char &DemoteRegisterToMemoryID; // FunctionPass *createReassociatePass(); -//===----------------------------------------------------------------------===// -// -// TailDuplication - Eliminate unconditional branches through controlled code -// duplication, creating simpler CFG structures. -// -FunctionPass *createTailDuplicationPass(); - //===----------------------------------------------------------------------===// // // JumpThreading - Thread control through mult-pred/multi-succ blocks where some diff --git a/include/llvm/Transforms/Utils/AddrModeMatcher.h b/include/llvm/Transforms/Utils/AddrModeMatcher.h index 0678eccb5d69..90485eb4c69c 100644 --- a/include/llvm/Transforms/Utils/AddrModeMatcher.h +++ b/include/llvm/Transforms/Utils/AddrModeMatcher.h @@ -58,7 +58,7 @@ class AddressingModeMatcher { /// AccessTy/MemoryInst - This is the type for the access (e.g. double) and /// the memory instruction that we're computing this address for. - const Type *AccessTy; + Type *AccessTy; Instruction *MemoryInst; /// AddrMode - This is the addressing mode that we're building up. This is @@ -71,7 +71,7 @@ class AddressingModeMatcher { bool IgnoreProfitability; AddressingModeMatcher(SmallVectorImpl &AMI, - const TargetLowering &T, const Type *AT, + const TargetLowering &T, Type *AT, Instruction *MI, ExtAddrMode &AM) : AddrModeInsts(AMI), TLI(T), AccessTy(AT), MemoryInst(MI), AddrMode(AM) { IgnoreProfitability = false; @@ -81,7 +81,7 @@ class AddressingModeMatcher { /// Match - Find the maximal addressing mode that a load/store of V can fold, /// give an access type of AccessTy. This returns a list of involved /// instructions in AddrModeInsts. - static ExtAddrMode Match(Value *V, const Type *AccessTy, + static ExtAddrMode Match(Value *V, Type *AccessTy, Instruction *MemoryInst, SmallVectorImpl &AddrModeInsts, const TargetLowering &TLI) { diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h index 90eabef12fa7..6fcd160e64e4 100644 --- a/include/llvm/Transforms/Utils/BasicBlockUtils.h +++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h @@ -31,8 +31,8 @@ class ReturnInst; /// DeleteDeadBlock - Delete the specified block, which must have no /// predecessors. void DeleteDeadBlock(BasicBlock *BB); - - + + /// FoldSingleEntryPHINodes - We know that BB has one predecessor. If there are /// any single-entry PHI nodes in it, fold them away. This handles the case /// when all entries to the PHI nodes in a block are guaranteed equal, such as @@ -75,7 +75,7 @@ void ReplaceInstWithInst(Instruction *From, Instruction *To); /// The output is added to Result, as pairs of edge info. void FindFunctionBackedges(const Function &F, SmallVectorImpl > &Result); - + /// GetSuccessorNumber - Search for the specified successor of basic block BB /// and return its position in the terminator instruction's list of @@ -97,10 +97,10 @@ bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum, /// was split, null otherwise. /// /// If MergeIdenticalEdges is true (not the default), *all* edges from TI to the -/// specified successor will be merged into the same critical edge block. -/// This is most commonly interesting with switch instructions, which may +/// specified successor will be merged into the same critical edge block. +/// This is most commonly interesting with switch instructions, which may /// have many edges to any one destination. This ensures that all edges to that -/// dest go to one block instead of each going to a different block, but isn't +/// dest go to one block instead of each going to a different block, but isn't /// the standard definition of a "critical edge". /// /// It is invalid to call this function on a critical edge that starts at an @@ -109,7 +109,8 @@ bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum, /// to. /// BasicBlock *SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, - Pass *P = 0, bool MergeIdenticalEdges = false); + Pass *P = 0, bool MergeIdenticalEdges = false, + bool DontDeleteUselessPHIs = false); inline BasicBlock *SplitCriticalEdge(BasicBlock *BB, succ_iterator SI, Pass *P = 0) { @@ -136,19 +137,21 @@ inline bool SplitCriticalEdge(BasicBlock *Succ, pred_iterator PI, Pass *P = 0) { /// described above. inline BasicBlock *SplitCriticalEdge(BasicBlock *Src, BasicBlock *Dst, Pass *P = 0, - bool MergeIdenticalEdges = false) { + bool MergeIdenticalEdges = false, + bool DontDeleteUselessPHIs = false) { TerminatorInst *TI = Src->getTerminator(); unsigned i = 0; while (1) { assert(i != TI->getNumSuccessors() && "Edge doesn't exist!"); if (TI->getSuccessor(i) == Dst) - return SplitCriticalEdge(TI, i, P, MergeIdenticalEdges); + return SplitCriticalEdge(TI, i, P, MergeIdenticalEdges, + DontDeleteUselessPHIs); ++i; } } -/// SplitEdge - Split the edge connecting specified block. Pass P must -/// not be NULL. +/// SplitEdge - Split the edge connecting specified block. Pass P must +/// not be NULL. BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To, Pass *P); /// SplitBlock - Split the specified block at the specified instruction - every @@ -157,7 +160,7 @@ BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To, Pass *P); /// the loop info is updated. /// BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P); - + /// SplitBlockPredecessors - This method transforms BB by introducing a new /// basic block into the function, and moving some of the predecessors of BB to /// be predecessors of the new block. The new predecessors are indicated by the @@ -174,6 +177,23 @@ BasicBlock *SplitBlockPredecessors(BasicBlock *BB, BasicBlock *const *Preds, unsigned NumPreds, const char *Suffix, Pass *P = 0); +/// SplitLandingPadPredecessors - This method transforms the landing pad, +/// OrigBB, by introducing two new basic blocks into the function. One of those +/// new basic blocks gets the predecessors listed in Preds. The other basic +/// block gets the remaining predecessors of OrigBB. The landingpad instruction +/// OrigBB is clone into both of the new basic blocks. The new blocks are given +/// the suffixes 'Suffix1' and 'Suffix2', and are returned in the NewBBs vector. +/// +/// This currently updates the LLVM IR, AliasAnalysis, DominatorTree, +/// DominanceFrontier, LoopInfo, and LCCSA but no other analyses. In particular, +/// it does not preserve LoopSimplify (because it's complicated to handle the +/// case where one of the edges being split is an exit of a loop with other +/// exits). +/// +void SplitLandingPadPredecessors(BasicBlock *OrigBB,ArrayRef Preds, + const char *Suffix, const char *Suffix2, + Pass *P, SmallVectorImpl &NewBBs); + /// FoldReturnIntoUncondBranch - This method duplicates the specified return /// instruction into a predecessor which ends in an unconditional branch. If /// the return instruction returns a value defined by a PHI, propagate the @@ -182,7 +202,7 @@ BasicBlock *SplitBlockPredecessors(BasicBlock *BB, BasicBlock *const *Preds, ReturnInst *FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB, BasicBlock *Pred); -/// GetFirstDebugLocInBasicBlock - Return first valid DebugLoc entry in a +/// GetFirstDebugLocInBasicBlock - Return first valid DebugLoc entry in a /// given basic block. DebugLoc GetFirstDebugLocInBasicBlock(const BasicBlock *BB); diff --git a/include/llvm/Transforms/Utils/FunctionUtils.h b/include/llvm/Transforms/Utils/FunctionUtils.h index 785b08f82917..8d71e43aa921 100644 --- a/include/llvm/Transforms/Utils/FunctionUtils.h +++ b/include/llvm/Transforms/Utils/FunctionUtils.h @@ -14,6 +14,7 @@ #ifndef LLVM_TRANSFORMS_UTILS_FUNCTION_H #define LLVM_TRANSFORMS_UTILS_FUNCTION_H +#include "llvm/ADT/ArrayRef.h" #include namespace llvm { @@ -22,20 +23,23 @@ namespace llvm { class Function; class Loop; - /// ExtractCodeRegion - rip out a sequence of basic blocks into a new function + /// ExtractCodeRegion - Rip out a sequence of basic blocks into a new + /// function. /// Function* ExtractCodeRegion(DominatorTree& DT, - const std::vector &code, + ArrayRef code, bool AggregateArgs = false); - /// ExtractLoop - rip out a natural loop into a new function + /// ExtractLoop - Rip out a natural loop into a new function. /// Function* ExtractLoop(DominatorTree& DT, Loop *L, bool AggregateArgs = false); - /// ExtractBasicBlock - rip out a basic block into a new function + /// ExtractBasicBlock - Rip out a basic block (and the associated landing pad) + /// into a new function. /// - Function* ExtractBasicBlock(BasicBlock *BB, bool AggregateArgs = false); + Function* ExtractBasicBlock(ArrayRef BBs, + bool AggregateArgs = false); } #endif diff --git a/include/llvm/Transforms/Utils/SSAUpdater.h b/include/llvm/Transforms/Utils/SSAUpdater.h index 063d41398958..064e5501a455 100644 --- a/include/llvm/Transforms/Utils/SSAUpdater.h +++ b/include/llvm/Transforms/Utils/SSAUpdater.h @@ -39,7 +39,7 @@ class SSAUpdater { void *AV; /// ProtoType holds the type of the values being rewritten. - const Type *ProtoType; + Type *ProtoType; // PHI nodes are given a name based on ProtoName. std::string ProtoName; @@ -56,7 +56,7 @@ class SSAUpdater { /// Initialize - Reset this object to get ready for a new set of SSA /// updates with type 'Ty'. PHI nodes get a name based on 'Name'. - void Initialize(const Type *Ty, StringRef Name); + void Initialize(Type *Ty, StringRef Name); /// AddAvailableValue - Indicate that a rewritten value is available at the /// end of the specified block with the specified value. diff --git a/include/llvm/Transforms/Utils/SimplifyIndVar.h b/include/llvm/Transforms/Utils/SimplifyIndVar.h new file mode 100644 index 000000000000..524cf5ad9793 --- /dev/null +++ b/include/llvm/Transforms/Utils/SimplifyIndVar.h @@ -0,0 +1,58 @@ +//===-- llvm/Transforms/Utils/SimplifyIndVar.h - Indvar Utils ---*- 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 in interface for induction variable simplification. It does +// not define any actual pass or policy, but provides a single function to +// simplify a loop's induction variables based on ScalarEvolution. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H +#define LLVM_TRANSFORMS_UTILS_SIMPLIFYINDVAR_H + +#include "llvm/Support/CommandLine.h" + +namespace llvm { + +extern cl::opt DisableIVRewrite; + +class Loop; +class LoopInfo; +class DominatorTree; +class ScalarEvolution; +class LPPassManager; +class IVUsers; + +/// Interface for visiting interesting IV users that are recognized but not +/// simplified by this utility. +class IVVisitor { +public: + virtual ~IVVisitor() {} + virtual void visitCast(CastInst *Cast) = 0; +}; + +/// simplifyUsersOfIV - Simplify instructions that use this induction variable +/// by using ScalarEvolution to analyze the IV's recurrence. +bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, LPPassManager *LPM, + SmallVectorImpl &Dead, IVVisitor *V = NULL); + +/// SimplifyLoopIVs - Simplify users of induction variables within this +/// loop. This does not actually change or add IVs. +bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, LPPassManager *LPM, + SmallVectorImpl &Dead); + +/// simplifyIVUsers - Simplify instructions recorded by the IVUsers pass. +/// This is a legacy implementation to reproduce the behavior of the +/// IndVarSimplify pass prior to DisableIVRewrite. +bool simplifyIVUsers(IVUsers *IU, ScalarEvolution *SE, LPPassManager *LPM, + SmallVectorImpl &Dead); + +} // namespace llvm + +#endif diff --git a/include/llvm/Transforms/Utils/UnrollLoop.h b/include/llvm/Transforms/Utils/UnrollLoop.h index 3d5ee1a62b8a..7212a8c76069 100644 --- a/include/llvm/Transforms/Utils/UnrollLoop.h +++ b/include/llvm/Transforms/Utils/UnrollLoop.h @@ -22,7 +22,8 @@ class Loop; class LoopInfo; class LPPassManager; -bool UnrollLoop(Loop *L, unsigned Count, LoopInfo* LI, LPPassManager* LPM); +bool UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, + unsigned TripMultiple, LoopInfo* LI, LPPassManager* LPM); } diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h index 2194373c45b3..03846567dbcc 100644 --- a/include/llvm/Transforms/Utils/ValueMapper.h +++ b/include/llvm/Transforms/Utils/ValueMapper.h @@ -66,12 +66,12 @@ namespace llvm { inline MDNode *MapValue(const MDNode *V, ValueToValueMapTy &VM, RemapFlags Flags = RF_None, ValueMapTypeRemapper *TypeMapper = 0) { - return (MDNode*)MapValue((const Value*)V, VM, Flags, TypeMapper); + return cast(MapValue((const Value*)V, VM, Flags, TypeMapper)); } inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM, RemapFlags Flags = RF_None, ValueMapTypeRemapper *TypeMapper = 0) { - return (Constant*)MapValue((const Value*)V, VM, Flags, TypeMapper); + return cast(MapValue((const Value*)V, VM, Flags, TypeMapper)); } diff --git a/include/llvm/Type.h b/include/llvm/Type.h index e4ff3e1c8d1b..43b7dc578886 100644 --- a/include/llvm/Type.h +++ b/include/llvm/Type.h @@ -193,7 +193,7 @@ class Type { /// are valid for types of the same size only where no re-interpretation of /// the bits is done. /// @brief Determine if this type could be losslessly bitcast to Ty - bool canLosslesslyBitCastTo(const Type *Ty) const; + bool canLosslesslyBitCastTo(Type *Ty) const; /// isEmptyTy - Return true if this type is empty, that is, it has no /// elements or all its elements are empty. @@ -262,7 +262,7 @@ class Type { /// getScalarSizeInBits - If this is a vector type, return the /// getPrimitiveSizeInBits value for the element type. Otherwise return the /// getPrimitiveSizeInBits value for this type. - unsigned getScalarSizeInBits() const; + unsigned getScalarSizeInBits(); /// getFPMantissaWidth - Return the width of the mantissa of this type. This /// is only valid on floating point types. If the FP type does not @@ -271,7 +271,7 @@ class Type { /// getScalarType - If this is a vector type, return the element type, /// otherwise return 'this'. - const Type *getScalarType() const; + Type *getScalarType(); //===--------------------------------------------------------------------===// // Type Iteration support. @@ -342,7 +342,7 @@ class Type { /// getPointerTo - Return a pointer to the current type. This is equivalent /// to PointerType::get(Foo, AddrSpace). - PointerType *getPointerTo(unsigned AddrSpace = 0) const; + PointerType *getPointerTo(unsigned AddrSpace = 0); private: /// isSizedDerivedType - Derived types like structures and arrays are sized @@ -352,7 +352,7 @@ class Type { }; // Printing of types. -static inline raw_ostream &operator<<(raw_ostream &OS, const Type &T) { +static inline raw_ostream &operator<<(raw_ostream &OS, Type &T) { T.print(OS); return OS; } @@ -387,7 +387,7 @@ template <> struct GraphTraits { typedef const Type NodeType; typedef Type::subtype_iterator ChildIteratorType; - static inline NodeType *getEntryNode(const Type *T) { return T; } + static inline NodeType *getEntryNode(NodeType *T) { return T; } static inline ChildIteratorType child_begin(NodeType *N) { return N->subtype_begin(); } diff --git a/include/llvm/User.h b/include/llvm/User.h index 3f9c28e7b381..62bc9f034618 100644 --- a/include/llvm/User.h +++ b/include/llvm/User.h @@ -47,7 +47,7 @@ class User : public Value { unsigned NumOperands; void *operator new(size_t s, unsigned Us); - User(const Type *ty, unsigned vty, Use *OpList, unsigned NumOps) + User(Type *ty, unsigned vty, Use *OpList, unsigned NumOps) : Value(ty, vty), OperandList(OpList), NumOperands(NumOps) {} Use *allocHungoffUses(unsigned) const; void dropHungoffUses() { diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 08fa1c90348b..a71e2fdefd72 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -91,7 +91,7 @@ class Value { /// printing behavior. virtual void printCustom(raw_ostream &O) const; - Value(const Type *Ty, unsigned scid); + Value(Type *Ty, unsigned scid); public: virtual ~Value(); @@ -183,7 +183,7 @@ class Value { bool isUsedInBasicBlock(const BasicBlock *BB) const; /// getNumUses - This method computes the number of uses of this Value. This - /// is a linear time operation. Use hasOneUse, hasNUses, or hasMoreThanNUses + /// is a linear time operation. Use hasOneUse, hasNUses, or hasNUsesOrMore /// to check for specific values. unsigned getNumUses() const; diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp index c189a0042928..bd132c05c327 100644 --- a/lib/Analysis/AliasAnalysis.cpp +++ b/lib/Analysis/AliasAnalysis.cpp @@ -237,6 +237,19 @@ AliasAnalysis::Location AliasAnalysis::getLocation(const VAArgInst *VI) { VI->getMetadata(LLVMContext::MD_tbaa)); } +AliasAnalysis::Location +AliasAnalysis::getLocation(const AtomicCmpXchgInst *CXI) { + return Location(CXI->getPointerOperand(), + getTypeStoreSize(CXI->getCompareOperand()->getType()), + CXI->getMetadata(LLVMContext::MD_tbaa)); +} + +AliasAnalysis::Location +AliasAnalysis::getLocation(const AtomicRMWInst *RMWI) { + return Location(RMWI->getPointerOperand(), + getTypeStoreSize(RMWI->getValOperand()->getType()), + RMWI->getMetadata(LLVMContext::MD_tbaa)); +} AliasAnalysis::Location AliasAnalysis::getLocationForSource(const MemTransferInst *MTI) { @@ -268,8 +281,8 @@ AliasAnalysis::getLocationForDest(const MemIntrinsic *MTI) { AliasAnalysis::ModRefResult AliasAnalysis::getModRefInfo(const LoadInst *L, const Location &Loc) { - // Be conservative in the face of volatile. - if (L->isVolatile()) + // Be conservative in the face of volatile/atomic. + if (!L->isUnordered()) return ModRef; // If the load address doesn't alias the given address, it doesn't read @@ -283,8 +296,8 @@ AliasAnalysis::getModRefInfo(const LoadInst *L, const Location &Loc) { AliasAnalysis::ModRefResult AliasAnalysis::getModRefInfo(const StoreInst *S, const Location &Loc) { - // Be conservative in the face of volatile. - if (S->isVolatile()) + // Be conservative in the face of volatile/atomic. + if (!S->isUnordered()) return ModRef; // If the store address cannot alias the pointer in question, then the @@ -317,6 +330,33 @@ AliasAnalysis::getModRefInfo(const VAArgInst *V, const Location &Loc) { return ModRef; } +AliasAnalysis::ModRefResult +AliasAnalysis::getModRefInfo(const AtomicCmpXchgInst *CX, const Location &Loc) { + // Acquire/Release cmpxchg has properties that matter for arbitrary addresses. + if (CX->getOrdering() > Monotonic) + return ModRef; + + // If the cmpxchg address does not alias the location, it does not access it. + if (!alias(getLocation(CX), Loc)) + return NoModRef; + + return ModRef; +} + +AliasAnalysis::ModRefResult +AliasAnalysis::getModRefInfo(const AtomicRMWInst *RMW, const Location &Loc) { + // Acquire/Release atomicrmw has properties that matter for arbitrary addresses. + if (RMW->getOrdering() > Monotonic) + return ModRef; + + // If the atomicrmw address does not alias the location, it does not access it. + if (!alias(getLocation(RMW), Loc)) + return NoModRef; + + return ModRef; +} + + // AliasAnalysis destructor: DO NOT move this to the header file for // AliasAnalysis or else clients of the AliasAnalysis class may not depend on // the AliasAnalysis.o file in the current .a file, causing alias analysis @@ -341,7 +381,7 @@ void AliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { /// getTypeStoreSize - Return the TargetData store size for the given type, /// if known, or a conservative value otherwise. /// -uint64_t AliasAnalysis::getTypeStoreSize(const Type *Ty) { +uint64_t AliasAnalysis::getTypeStoreSize(Type *Ty) { return TD ? TD->getTypeStoreSize(Ty) : UnknownSize; } diff --git a/lib/Analysis/AliasAnalysisEvaluator.cpp b/lib/Analysis/AliasAnalysisEvaluator.cpp index 1afc1b71d93e..37271b94a201 100644 --- a/lib/Analysis/AliasAnalysisEvaluator.cpp +++ b/lib/Analysis/AliasAnalysisEvaluator.cpp @@ -171,12 +171,12 @@ bool AAEval::runOnFunction(Function &F) { for (SetVector::iterator I1 = Pointers.begin(), E = Pointers.end(); I1 != E; ++I1) { uint64_t I1Size = AliasAnalysis::UnknownSize; - const Type *I1ElTy = cast((*I1)->getType())->getElementType(); + Type *I1ElTy = cast((*I1)->getType())->getElementType(); if (I1ElTy->isSized()) I1Size = AA.getTypeStoreSize(I1ElTy); for (SetVector::iterator I2 = Pointers.begin(); I2 != I1; ++I2) { uint64_t I2Size = AliasAnalysis::UnknownSize; - const Type *I2ElTy =cast((*I2)->getType())->getElementType(); + Type *I2ElTy =cast((*I2)->getType())->getElementType(); if (I2ElTy->isSized()) I2Size = AA.getTypeStoreSize(I2ElTy); switch (AA.alias(*I1, I1Size, *I2, I2Size)) { @@ -207,7 +207,7 @@ bool AAEval::runOnFunction(Function &F) { for (SetVector::iterator V = Pointers.begin(), Ve = Pointers.end(); V != Ve; ++V) { uint64_t Size = AliasAnalysis::UnknownSize; - const Type *ElTy = cast((*V)->getType())->getElementType(); + Type *ElTy = cast((*V)->getType())->getElementType(); if (ElTy->isSized()) Size = AA.getTypeStoreSize(ElTy); switch (AA.getModRefInfo(*C, *V, Size)) { diff --git a/lib/Analysis/AliasSetTracker.cpp b/lib/Analysis/AliasSetTracker.cpp index 2ed694941212..3fcd3b55de57 100644 --- a/lib/Analysis/AliasSetTracker.cpp +++ b/lib/Analysis/AliasSetTracker.cpp @@ -56,12 +56,12 @@ void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) { AliasTy = MayAlias; } - if (CallSites.empty()) { // Merge call sites... - if (!AS.CallSites.empty()) - std::swap(CallSites, AS.CallSites); - } else if (!AS.CallSites.empty()) { - CallSites.insert(CallSites.end(), AS.CallSites.begin(), AS.CallSites.end()); - AS.CallSites.clear(); + if (UnknownInsts.empty()) { // Merge call sites... + if (!AS.UnknownInsts.empty()) + std::swap(UnknownInsts, AS.UnknownInsts); + } else if (!AS.UnknownInsts.empty()) { + UnknownInsts.insert(UnknownInsts.end(), AS.UnknownInsts.begin(), AS.UnknownInsts.end()); + AS.UnknownInsts.clear(); } AS.Forward = this; // Forward across AS now... @@ -123,13 +123,10 @@ void AliasSet::addPointer(AliasSetTracker &AST, PointerRec &Entry, addRef(); // Entry points to alias set. } -void AliasSet::addCallSite(CallSite CS, AliasAnalysis &AA) { - CallSites.push_back(CS.getInstruction()); +void AliasSet::addUnknownInst(Instruction *I, AliasAnalysis &AA) { + UnknownInsts.push_back(I); - AliasAnalysis::ModRefBehavior Behavior = AA.getModRefBehavior(CS); - if (Behavior == AliasAnalysis::DoesNotAccessMemory) - return; - if (AliasAnalysis::onlyReadsMemory(Behavior)) { + if (!I->mayWriteToMemory()) { AliasTy = MayAlias; AccessTy |= Refs; return; @@ -147,7 +144,7 @@ bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size, const MDNode *TBAAInfo, AliasAnalysis &AA) const { if (AliasTy == MustAlias) { - assert(CallSites.empty() && "Illegal must alias set!"); + assert(UnknownInsts.empty() && "Illegal must alias set!"); // If this is a set of MustAliases, only check to see if the pointer aliases // SOME value in the set. @@ -167,10 +164,10 @@ bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size, I.getTBAAInfo()))) return true; - // Check the call sites list and invoke list... - if (!CallSites.empty()) { - for (unsigned i = 0, e = CallSites.size(); i != e; ++i) - if (AA.getModRefInfo(CallSites[i], + // Check the unknown instructions... + if (!UnknownInsts.empty()) { + for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) + if (AA.getModRefInfo(UnknownInsts[i], AliasAnalysis::Location(Ptr, Size, TBAAInfo)) != AliasAnalysis::NoModRef) return true; @@ -179,18 +176,20 @@ bool AliasSet::aliasesPointer(const Value *Ptr, uint64_t Size, return false; } -bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const { - if (AA.doesNotAccessMemory(CS)) +bool AliasSet::aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const { + if (!Inst->mayReadOrWriteMemory()) return false; - for (unsigned i = 0, e = CallSites.size(); i != e; ++i) { - if (AA.getModRefInfo(getCallSite(i), CS) != AliasAnalysis::NoModRef || - AA.getModRefInfo(CS, getCallSite(i)) != AliasAnalysis::NoModRef) + for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { + CallSite C1 = getUnknownInst(i), C2 = Inst; + if (!C1 || !C2 || + AA.getModRefInfo(C1, C2) != AliasAnalysis::NoModRef || + AA.getModRefInfo(C2, C1) != AliasAnalysis::NoModRef) return true; } for (iterator I = begin(), E = end(); I != E; ++I) - if (AA.getModRefInfo(CS, I.getPointer(), I.getSize()) != + if (AA.getModRefInfo(Inst, I.getPointer(), I.getSize()) != AliasAnalysis::NoModRef) return true; @@ -244,10 +243,10 @@ bool AliasSetTracker::containsPointer(Value *Ptr, uint64_t Size, -AliasSet *AliasSetTracker::findAliasSetForCallSite(CallSite CS) { +AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) { AliasSet *FoundSet = 0; for (iterator I = begin(), E = end(); I != E; ++I) { - if (I->Forward || !I->aliasesCallSite(CS, AA)) + if (I->Forward || !I->aliasesUnknownInst(Inst, AA)) continue; if (FoundSet == 0) // If this is the first alias set ptr can go into. @@ -296,22 +295,28 @@ bool AliasSetTracker::add(Value *Ptr, uint64_t Size, const MDNode *TBAAInfo) { bool AliasSetTracker::add(LoadInst *LI) { + if (LI->getOrdering() > Monotonic) return addUnknown(LI); + AliasSet::AccessType ATy = AliasSet::Refs; + if (!LI->isUnordered()) ATy = AliasSet::ModRef; bool NewPtr; AliasSet &AS = addPointer(LI->getOperand(0), AA.getTypeStoreSize(LI->getType()), LI->getMetadata(LLVMContext::MD_tbaa), - AliasSet::Refs, NewPtr); + ATy, NewPtr); if (LI->isVolatile()) AS.setVolatile(); return NewPtr; } bool AliasSetTracker::add(StoreInst *SI) { + if (SI->getOrdering() > Monotonic) return addUnknown(SI); + AliasSet::AccessType ATy = AliasSet::Mods; + if (!SI->isUnordered()) ATy = AliasSet::ModRef; bool NewPtr; Value *Val = SI->getOperand(0); AliasSet &AS = addPointer(SI->getOperand(1), AA.getTypeStoreSize(Val->getType()), SI->getMetadata(LLVMContext::MD_tbaa), - AliasSet::Mods, NewPtr); + ATy, NewPtr); if (SI->isVolatile()) AS.setVolatile(); return NewPtr; } @@ -325,20 +330,20 @@ bool AliasSetTracker::add(VAArgInst *VAAI) { } -bool AliasSetTracker::add(CallSite CS) { - if (isa(CS.getInstruction())) +bool AliasSetTracker::addUnknown(Instruction *Inst) { + if (isa(Inst)) return true; // Ignore DbgInfo Intrinsics. - if (AA.doesNotAccessMemory(CS)) + if (!Inst->mayReadOrWriteMemory()) return true; // doesn't alias anything - AliasSet *AS = findAliasSetForCallSite(CS); + AliasSet *AS = findAliasSetForUnknownInst(Inst); if (AS) { - AS->addCallSite(CS, AA); + AS->addUnknownInst(Inst, AA); return false; } AliasSets.push_back(new AliasSet()); AS = &AliasSets.back(); - AS->addCallSite(CS, AA); + AS->addUnknownInst(Inst, AA); return true; } @@ -348,13 +353,9 @@ bool AliasSetTracker::add(Instruction *I) { return add(LI); if (StoreInst *SI = dyn_cast(I)) return add(SI); - if (CallInst *CI = dyn_cast(I)) - return add(CI); - if (InvokeInst *II = dyn_cast(I)) - return add(II); if (VAArgInst *VAAI = dyn_cast(I)) return add(VAAI); - return true; + return addUnknown(I); } void AliasSetTracker::add(BasicBlock &BB) { @@ -375,8 +376,8 @@ void AliasSetTracker::add(const AliasSetTracker &AST) { AliasSet &AS = const_cast(*I); // If there are any call sites in the alias set, add them to this AST. - for (unsigned i = 0, e = AS.CallSites.size(); i != e; ++i) - add(AS.CallSites[i]); + for (unsigned i = 0, e = AS.UnknownInsts.size(); i != e; ++i) + add(AS.UnknownInsts[i]); // Loop over all of the pointers in this alias set. bool X; @@ -393,7 +394,7 @@ void AliasSetTracker::add(const AliasSetTracker &AST) { /// tracker. void AliasSetTracker::remove(AliasSet &AS) { // Drop all call sites. - AS.CallSites.clear(); + AS.UnknownInsts.clear(); // Clear the alias set. unsigned NumRefs = 0; @@ -453,11 +454,11 @@ bool AliasSetTracker::remove(VAArgInst *VAAI) { return true; } -bool AliasSetTracker::remove(CallSite CS) { - if (AA.doesNotAccessMemory(CS)) +bool AliasSetTracker::removeUnknown(Instruction *I) { + if (!I->mayReadOrWriteMemory()) return false; // doesn't alias anything - AliasSet *AS = findAliasSetForCallSite(CS); + AliasSet *AS = findAliasSetForUnknownInst(I); if (!AS) return false; remove(*AS); return true; @@ -469,11 +470,9 @@ bool AliasSetTracker::remove(Instruction *I) { return remove(LI); if (StoreInst *SI = dyn_cast(I)) return remove(SI); - if (CallInst *CI = dyn_cast(I)) - return remove(CI); if (VAArgInst *VAAI = dyn_cast(I)) return remove(VAAI); - return true; + return removeUnknown(I); } @@ -488,13 +487,13 @@ void AliasSetTracker::deleteValue(Value *PtrVal) { // If this is a call instruction, remove the callsite from the appropriate // AliasSet (if present). - if (CallSite CS = PtrVal) { - if (!AA.doesNotAccessMemory(CS)) { + if (Instruction *Inst = dyn_cast(PtrVal)) { + if (Inst->mayReadOrWriteMemory()) { // Scan all the alias sets to see if this call site is contained. for (iterator I = begin(), E = end(); I != E; ++I) { if (I->Forward) continue; - I->removeCallSite(CS); + I->removeUnknownInst(Inst); } } } @@ -571,11 +570,11 @@ void AliasSet::print(raw_ostream &OS) const { OS << ", " << I.getSize() << ")"; } } - if (!CallSites.empty()) { - OS << "\n " << CallSites.size() << " Call Sites: "; - for (unsigned i = 0, e = CallSites.size(); i != e; ++i) { + if (!UnknownInsts.empty()) { + OS << "\n " << UnknownInsts.size() << " Unknown instructions: "; + for (unsigned i = 0, e = UnknownInsts.size(); i != e; ++i) { if (i) OS << ", "; - WriteAsOperand(OS, CallSites[i]); + WriteAsOperand(OS, UnknownInsts[i]); } } OS << "\n"; diff --git a/lib/Analysis/Analysis.cpp b/lib/Analysis/Analysis.cpp index 71e0a832696c..0ba6af93b511 100644 --- a/lib/Analysis/Analysis.cpp +++ b/lib/Analysis/Analysis.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm-c/Analysis.h" +#include "llvm-c/Initialization.h" #include "llvm/InitializePasses.h" #include "llvm/Analysis/Verifier.h" #include @@ -23,7 +24,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) { initializeAliasSetPrinterPass(Registry); initializeNoAAPass(Registry); initializeBasicAliasAnalysisPass(Registry); - initializeBlockFrequencyPass(Registry); + initializeBlockFrequencyInfoPass(Registry); initializeBranchProbabilityInfoPass(Registry); initializeCFGViewerPass(Registry); initializeCFGPrinterPass(Registry); diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index 8330ea7c7036..af400ba7e70e 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -30,6 +30,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetLibraryInfo.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ErrorHandling.h" @@ -100,7 +101,7 @@ static bool isEscapeSource(const Value *V) { /// getObjectSize - Return the size of the object specified by V, or /// UnknownSize if unknown. static uint64_t getObjectSize(const Value *V, const TargetData &TD) { - const Type *AccessTy; + Type *AccessTy; if (const GlobalVariable *GV = dyn_cast(V)) { if (!GV->hasDefinitiveInitializer()) return AliasAnalysis::UnknownSize; @@ -317,7 +318,7 @@ DecomposeGEPExpression(const Value *V, int64_t &BaseOffs, E = GEPOp->op_end(); I != E; ++I) { Value *Index = *I; // Compute the (potentially symbolic) offset in bytes for this index. - if (const StructType *STy = dyn_cast(*GTI++)) { + if (StructType *STy = dyn_cast(*GTI++)) { // For a struct, add the member offset. unsigned FieldNo = cast(Index)->getZExtValue(); if (FieldNo == 0) continue; @@ -374,7 +375,8 @@ DecomposeGEPExpression(const Value *V, int64_t &BaseOffs, } if (Scale) { - VariableGEPIndex Entry = {Index, Extension, Scale}; + VariableGEPIndex Entry = {Index, Extension, + static_cast(Scale)}; VarIndices.push_back(Entry); } } @@ -467,6 +469,7 @@ namespace { virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); + AU.addRequired(); } virtual AliasResult alias(const Location &LocA, @@ -549,9 +552,14 @@ namespace { // Register this pass... char BasicAliasAnalysis::ID = 0; -INITIALIZE_AG_PASS(BasicAliasAnalysis, AliasAnalysis, "basicaa", +INITIALIZE_AG_PASS_BEGIN(BasicAliasAnalysis, AliasAnalysis, "basicaa", "Basic Alias Analysis (stateless AA impl)", false, true, false) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo) +INITIALIZE_AG_PASS_END(BasicAliasAnalysis, AliasAnalysis, "basicaa", + "Basic Alias Analysis (stateless AA impl)", + false, true, false) + ImmutablePass *llvm::createBasicAliasAnalysisPass() { return new BasicAliasAnalysis(); @@ -706,7 +714,7 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, // is impossible to alias the pointer we're checking. If not, we have to // assume that the call could touch the pointer, even though it doesn't // escape. - if (!isNoAlias(Location(cast(CI)), Loc)) { + if (!isNoAlias(Location(*CI), Location(Object))) { PassedAsArg = true; break; } @@ -716,6 +724,7 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, return NoModRef; } + const TargetLibraryInfo &TLI = getAnalysis(); ModRefResult Min = ModRef; // Finally, handle specific knowledge of intrinsics. @@ -754,26 +763,6 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, // We know that memset doesn't load anything. Min = Mod; break; - case Intrinsic::atomic_cmp_swap: - case Intrinsic::atomic_swap: - case Intrinsic::atomic_load_add: - case Intrinsic::atomic_load_sub: - case Intrinsic::atomic_load_and: - case Intrinsic::atomic_load_nand: - case Intrinsic::atomic_load_or: - case Intrinsic::atomic_load_xor: - case Intrinsic::atomic_load_max: - case Intrinsic::atomic_load_min: - case Intrinsic::atomic_load_umax: - case Intrinsic::atomic_load_umin: - if (TD) { - Value *Op1 = II->getArgOperand(0); - uint64_t Op1Size = TD->getTypeStoreSize(Op1->getType()); - MDNode *Tag = II->getMetadata(LLVMContext::MD_tbaa); - if (isNoAlias(Location(Op1, Op1Size, Tag), Loc)) - return NoModRef; - } - break; case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: case Intrinsic::invariant_start: { @@ -818,6 +807,39 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS, } } + // We can bound the aliasing properties of memset_pattern16 just as we can + // for memcpy/memset. This is particularly important because the + // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16 + // whenever possible. + else if (TLI.has(LibFunc::memset_pattern16) && + CS.getCalledFunction() && + CS.getCalledFunction()->getName() == "memset_pattern16") { + const Function *MS = CS.getCalledFunction(); + FunctionType *MemsetType = MS->getFunctionType(); + if (!MemsetType->isVarArg() && MemsetType->getNumParams() == 3 && + isa(MemsetType->getParamType(0)) && + isa(MemsetType->getParamType(1)) && + isa(MemsetType->getParamType(2))) { + uint64_t Len = UnknownSize; + if (const ConstantInt *LenCI = dyn_cast(CS.getArgument(2))) + Len = LenCI->getZExtValue(); + const Value *Dest = CS.getArgument(0); + const Value *Src = CS.getArgument(1); + // If it can't overlap the source dest, then it doesn't modref the loc. + if (isNoAlias(Location(Dest, Len), Loc)) { + // Always reads 16 bytes of the source. + if (isNoAlias(Location(Src, 16), Loc)) + return NoModRef; + // If it can't overlap the dest, then worst case it reads the loc. + Min = Ref; + // Always reads 16 bytes of the source. + } else if (isNoAlias(Location(Src, 16), Loc)) { + // If it can't overlap the source, then worst case it mutates the loc. + Min = Mod; + } + } + } + // The AliasAnalysis base class has some smarts, lets use them. return ModRefResult(AliasAnalysis::getModRefInfo(CS, Loc) & Min); } @@ -913,43 +935,43 @@ BasicAliasAnalysis::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size, if (GEP1BaseOffset == 0 && GEP1VariableIndices.empty()) return MustAlias; - // If there is a difference between the pointers, but the difference is - // less than the size of the associated memory object, then we know - // that the objects are partially overlapping. + // If there is a constant difference between the pointers, but the difference + // is less than the size of the associated memory object, then we know + // that the objects are partially overlapping. If the difference is + // greater, we know they do not overlap. if (GEP1BaseOffset != 0 && GEP1VariableIndices.empty()) { - if (GEP1BaseOffset >= 0 ? - (V2Size != UnknownSize && (uint64_t)GEP1BaseOffset < V2Size) : - (V1Size != UnknownSize && -(uint64_t)GEP1BaseOffset < V1Size && - GEP1BaseOffset != INT64_MIN)) - return PartialAlias; + if (GEP1BaseOffset >= 0) { + if (V2Size != UnknownSize) { + if ((uint64_t)GEP1BaseOffset < V2Size) + return PartialAlias; + return NoAlias; + } + } else { + if (V1Size != UnknownSize) { + if (-(uint64_t)GEP1BaseOffset < V1Size) + return PartialAlias; + return NoAlias; + } + } } - // If we have a known constant offset, see if this offset is larger than the - // access size being queried. If so, and if no variable indices can remove - // pieces of this constant, then we know we have a no-alias. For example, - // &A[100] != &A. - - // In order to handle cases like &A[100][i] where i is an out of range - // subscript, we have to ignore all constant offset pieces that are a multiple - // of a scaled index. Do this by removing constant offsets that are a - // multiple of any of our variable indices. This allows us to transform - // things like &A[i][1] because i has a stride of (e.g.) 8 bytes but the 1 - // provides an offset of 4 bytes (assuming a <= 4 byte access). - for (unsigned i = 0, e = GEP1VariableIndices.size(); - i != e && GEP1BaseOffset;++i) - if (int64_t RemovedOffset = GEP1BaseOffset/GEP1VariableIndices[i].Scale) - GEP1BaseOffset -= RemovedOffset*GEP1VariableIndices[i].Scale; - - // If our known offset is bigger than the access size, we know we don't have - // an alias. - if (GEP1BaseOffset) { - if (GEP1BaseOffset >= 0 ? - (V2Size != UnknownSize && (uint64_t)GEP1BaseOffset >= V2Size) : - (V1Size != UnknownSize && -(uint64_t)GEP1BaseOffset >= V1Size && - GEP1BaseOffset != INT64_MIN)) + // Try to distinguish something like &A[i][1] against &A[42][0]. + // Grab the least significant bit set in any of the scales. + if (!GEP1VariableIndices.empty()) { + uint64_t Modulo = 0; + for (unsigned i = 0, e = GEP1VariableIndices.size(); i != e; ++i) + Modulo |= (uint64_t)GEP1VariableIndices[i].Scale; + Modulo = Modulo ^ (Modulo & (Modulo - 1)); + + // We can compute the difference between the two addresses + // mod Modulo. Check whether that difference guarantees that the + // two locations do not alias. + uint64_t ModOffset = (uint64_t)GEP1BaseOffset & (Modulo - 1); + if (V1Size != UnknownSize && V2Size != UnknownSize && + ModOffset >= V2Size && V1Size <= Modulo - ModOffset) return NoAlias; } - + // Statically, we can see that the base objects are the same, but the // pointers have dynamic offsets which we can't resolve. And none of our // little tricks above worked. diff --git a/lib/Analysis/BlockFrequency.cpp b/lib/Analysis/BlockFrequency.cpp deleted file mode 100644 index 4b86d1db1f04..000000000000 --- a/lib/Analysis/BlockFrequency.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//=======-------- BlockFrequency.cpp - Block Frequency Analysis -------=======// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Loops should be simplified before this analysis. -// -//===----------------------------------------------------------------------===// - -#include "llvm/InitializePasses.h" -#include "llvm/Analysis/BlockFrequencyImpl.h" -#include "llvm/Analysis/BlockFrequency.h" -#include "llvm/Analysis/LoopInfo.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/BranchProbabilityInfo.h" - -using namespace llvm; - -INITIALIZE_PASS_BEGIN(BlockFrequency, "block-freq", "Block Frequency Analysis", - true, true) -INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfo) -INITIALIZE_PASS_END(BlockFrequency, "block-freq", "Block Frequency Analysis", - true, true) - -char BlockFrequency::ID = 0; - - -BlockFrequency::BlockFrequency() : FunctionPass(ID) { - initializeBlockFrequencyPass(*PassRegistry::getPassRegistry()); - BFI = new BlockFrequencyImpl(); -} - -BlockFrequency::~BlockFrequency() { - delete BFI; -} - -void BlockFrequency::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - AU.setPreservesAll(); -} - -bool BlockFrequency::runOnFunction(Function &F) { - BranchProbabilityInfo &BPI = getAnalysis(); - BFI->doFunction(&F, &BPI); - return false; -} - -/// getblockFreq - Return block frequency. Never return 0, value must be -/// positive. Please note that initial frequency is equal to 1024. It means that -/// we should not rely on the value itself, but only on the comparison to the -/// other block frequencies. We do this to avoid using of floating points. -/// -uint32_t BlockFrequency::getBlockFreq(BasicBlock *BB) { - return BFI->getBlockFreq(BB); -} diff --git a/lib/Analysis/BlockFrequencyInfo.cpp b/lib/Analysis/BlockFrequencyInfo.cpp new file mode 100644 index 000000000000..d16665fa55cf --- /dev/null +++ b/lib/Analysis/BlockFrequencyInfo.cpp @@ -0,0 +1,63 @@ +//=======-------- BlockFrequencyInfo.cpp - Block Frequency Analysis -------=======// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Loops should be simplified before this analysis. +// +//===----------------------------------------------------------------------===// + +#include "llvm/InitializePasses.h" +#include "llvm/Analysis/BlockFrequencyImpl.h" +#include "llvm/Analysis/BlockFrequencyInfo.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/Passes.h" +#include "llvm/Analysis/BranchProbabilityInfo.h" + +using namespace llvm; + +INITIALIZE_PASS_BEGIN(BlockFrequencyInfo, "block-freq", "Block Frequency Analysis", + true, true) +INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfo) +INITIALIZE_PASS_END(BlockFrequencyInfo, "block-freq", "Block Frequency Analysis", + true, true) + +char BlockFrequencyInfo::ID = 0; + + +BlockFrequencyInfo::BlockFrequencyInfo() : FunctionPass(ID) { + initializeBlockFrequencyInfoPass(*PassRegistry::getPassRegistry()); + BFI = new BlockFrequencyImpl(); +} + +BlockFrequencyInfo::~BlockFrequencyInfo() { + delete BFI; +} + +void BlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.setPreservesAll(); +} + +bool BlockFrequencyInfo::runOnFunction(Function &F) { + BranchProbabilityInfo &BPI = getAnalysis(); + BFI->doFunction(&F, &BPI); + return false; +} + +void BlockFrequencyInfo::print(raw_ostream &O, const Module *) const { + if (BFI) BFI->print(O); +} + +/// getblockFreq - Return block frequency. Return 0 if we don't have the +/// information. Please note that initial frequency is equal to 1024. It means +/// that we should not rely on the value itself, but only on the comparison to +/// the other block frequencies. We do this to avoid using of floating points. +/// +BlockFrequency BlockFrequencyInfo::getBlockFreq(BasicBlock *BB) const { + return BFI->getBlockFreq(BB); +} diff --git a/lib/Analysis/BranchProbabilityInfo.cpp b/lib/Analysis/BranchProbabilityInfo.cpp index e39cd221b5a7..bde3b76708fa 100644 --- a/lib/Analysis/BranchProbabilityInfo.cpp +++ b/lib/Analysis/BranchProbabilityInfo.cpp @@ -11,7 +11,10 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Constants.h" #include "llvm/Instructions.h" +#include "llvm/LLVMContext.h" +#include "llvm/Metadata.h" #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Support/Debug.h" @@ -33,7 +36,7 @@ namespace { // private methods are hidden in the .cpp file. class BranchProbabilityAnalysis { - typedef std::pair Edge; + typedef std::pair Edge; DenseMap *Weights; @@ -52,7 +55,7 @@ class BranchProbabilityAnalysis { // V // BB1<-+ // | | - // | | (Weight = 128) + // | | (Weight = 124) // V | // BB2--+ // | @@ -60,12 +63,21 @@ class BranchProbabilityAnalysis { // V // BB3 // - // Probability of the edge BB2->BB1 = 128 / (128 + 4) = 0.9696.. - // Probability of the edge BB2->BB3 = 4 / (128 + 4) = 0.0303.. + // Probability of the edge BB2->BB1 = 124 / (124 + 4) = 0.96875 + // Probability of the edge BB2->BB3 = 4 / (124 + 4) = 0.03125 - static const uint32_t LBH_TAKEN_WEIGHT = 128; + static const uint32_t LBH_TAKEN_WEIGHT = 124; static const uint32_t LBH_NONTAKEN_WEIGHT = 4; + static const uint32_t RH_TAKEN_WEIGHT = 24; + static const uint32_t RH_NONTAKEN_WEIGHT = 8; + + static const uint32_t PH_TAKEN_WEIGHT = 20; + static const uint32_t PH_NONTAKEN_WEIGHT = 12; + + static const uint32_t ZH_TAKEN_WEIGHT = 20; + static const uint32_t ZH_NONTAKEN_WEIGHT = 12; + // Standard weight value. Used when none of the heuristics set weight for // the edge. static const uint32_t NORMAL_WEIGHT = 16; @@ -100,29 +112,6 @@ class BranchProbabilityAnalysis { return false; } - // Multiply Edge Weight by two. - void incEdgeWeight(BasicBlock *Src, BasicBlock *Dst) { - uint32_t Weight = BP->getEdgeWeight(Src, Dst); - uint32_t MaxWeight = getMaxWeightFor(Src); - - if (Weight * 2 > MaxWeight) - BP->setEdgeWeight(Src, Dst, MaxWeight); - else - BP->setEdgeWeight(Src, Dst, Weight * 2); - } - - // Divide Edge Weight by two. - void decEdgeWeight(BasicBlock *Src, BasicBlock *Dst) { - uint32_t Weight = BP->getEdgeWeight(Src, Dst); - - assert(Weight > 0); - if (Weight / 2 < MIN_WEIGHT) - BP->setEdgeWeight(Src, Dst, MIN_WEIGHT); - else - BP->setEdgeWeight(Src, Dst, Weight / 2); - } - - uint32_t getMaxWeightFor(BasicBlock *BB) const { return UINT32_MAX / BB->getTerminator()->getNumSuccessors(); } @@ -133,49 +122,119 @@ class BranchProbabilityAnalysis { : Weights(W), BP(BP), LI(LI) { } + // Metadata Weights + bool calcMetadataWeights(BasicBlock *BB); + // Return Heuristics - void calcReturnHeuristics(BasicBlock *BB); + bool calcReturnHeuristics(BasicBlock *BB); // Pointer Heuristics - void calcPointerHeuristics(BasicBlock *BB); + bool calcPointerHeuristics(BasicBlock *BB); // Loop Branch Heuristics - void calcLoopBranchHeuristics(BasicBlock *BB); + bool calcLoopBranchHeuristics(BasicBlock *BB); + + // Zero Heurestics + bool calcZeroHeuristics(BasicBlock *BB); bool runOnFunction(Function &F); }; } // end anonymous namespace +// Propagate existing explicit probabilities from either profile data or +// 'expect' intrinsic processing. +bool BranchProbabilityAnalysis::calcMetadataWeights(BasicBlock *BB) { + TerminatorInst *TI = BB->getTerminator(); + if (TI->getNumSuccessors() == 1) + return false; + if (!isa(TI) && !isa(TI)) + return false; + + MDNode *WeightsNode = TI->getMetadata(LLVMContext::MD_prof); + if (!WeightsNode) + return false; + + // Ensure there are weights for all of the successors. Note that the first + // operand to the metadata node is a name, not a weight. + if (WeightsNode->getNumOperands() != TI->getNumSuccessors() + 1) + return false; + + // Build up the final weights that will be used in a temporary buffer, but + // don't add them until all weihts are present. Each weight value is clamped + // to [1, getMaxWeightFor(BB)]. + uint32_t WeightLimit = getMaxWeightFor(BB); + SmallVector Weights; + Weights.reserve(TI->getNumSuccessors()); + for (unsigned i = 1, e = WeightsNode->getNumOperands(); i != e; ++i) { + ConstantInt *Weight = dyn_cast(WeightsNode->getOperand(i)); + if (!Weight) + return false; + Weights.push_back( + std::max(1, Weight->getLimitedValue(WeightLimit))); + } + assert(Weights.size() == TI->getNumSuccessors() && "Checked above"); + for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) + BP->setEdgeWeight(BB, TI->getSuccessor(i), Weights[i]); + + return true; +} + // Calculate Edge Weights using "Return Heuristics". Predict a successor which // leads directly to Return Instruction will not be taken. -void BranchProbabilityAnalysis::calcReturnHeuristics(BasicBlock *BB){ +bool BranchProbabilityAnalysis::calcReturnHeuristics(BasicBlock *BB){ if (BB->getTerminator()->getNumSuccessors() == 1) - return; + return false; + + SmallPtrSet ReturningEdges; + SmallPtrSet StayEdges; for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) { BasicBlock *Succ = *I; - if (isReturningBlock(Succ)) { - decEdgeWeight(BB, Succ); + if (isReturningBlock(Succ)) + ReturningEdges.insert(Succ); + else + StayEdges.insert(Succ); + } + + if (uint32_t numStayEdges = StayEdges.size()) { + uint32_t stayWeight = RH_TAKEN_WEIGHT / numStayEdges; + if (stayWeight < NORMAL_WEIGHT) + stayWeight = NORMAL_WEIGHT; + + for (SmallPtrSet::iterator I = StayEdges.begin(), + E = StayEdges.end(); I != E; ++I) + BP->setEdgeWeight(BB, *I, stayWeight); + } + + if (uint32_t numRetEdges = ReturningEdges.size()) { + uint32_t retWeight = RH_NONTAKEN_WEIGHT / numRetEdges; + if (retWeight < MIN_WEIGHT) + retWeight = MIN_WEIGHT; + for (SmallPtrSet::iterator I = ReturningEdges.begin(), + E = ReturningEdges.end(); I != E; ++I) { + BP->setEdgeWeight(BB, *I, retWeight); } } + + return ReturningEdges.size() > 0; } // Calculate Edge Weights using "Pointer Heuristics". Predict a comparsion // between two pointer or pointer and NULL will fail. -void BranchProbabilityAnalysis::calcPointerHeuristics(BasicBlock *BB) { +bool BranchProbabilityAnalysis::calcPointerHeuristics(BasicBlock *BB) { BranchInst * BI = dyn_cast(BB->getTerminator()); if (!BI || !BI->isConditional()) - return; + return false; Value *Cond = BI->getCondition(); ICmpInst *CI = dyn_cast(Cond); if (!CI || !CI->isEquality()) - return; + return false; Value *LHS = CI->getOperand(0); if (!LHS->getType()->isPointerTy()) - return; + return false; assert(CI->getOperand(1)->getType()->isPointerTy()); @@ -190,29 +249,35 @@ void BranchProbabilityAnalysis::calcPointerHeuristics(BasicBlock *BB) { if (!isProb) std::swap(Taken, NonTaken); - incEdgeWeight(BB, Taken); - decEdgeWeight(BB, NonTaken); + BP->setEdgeWeight(BB, Taken, PH_TAKEN_WEIGHT); + BP->setEdgeWeight(BB, NonTaken, PH_NONTAKEN_WEIGHT); + return true; } // Calculate Edge Weights using "Loop Branch Heuristics". Predict backedges // as taken, exiting edges as not-taken. -void BranchProbabilityAnalysis::calcLoopBranchHeuristics(BasicBlock *BB) { +bool BranchProbabilityAnalysis::calcLoopBranchHeuristics(BasicBlock *BB) { uint32_t numSuccs = BB->getTerminator()->getNumSuccessors(); Loop *L = LI->getLoopFor(BB); if (!L) - return; + return false; - SmallVector BackEdges; - SmallVector ExitingEdges; + SmallPtrSet BackEdges; + SmallPtrSet ExitingEdges; + SmallPtrSet InEdges; // Edges from header to the loop. + + bool isHeader = BB == L->getHeader(); for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) { BasicBlock *Succ = *I; Loop *SuccL = LI->getLoopFor(Succ); if (SuccL != L) - ExitingEdges.push_back(Succ); + ExitingEdges.insert(Succ); else if (Succ == L->getHeader()) - BackEdges.push_back(Succ); + BackEdges.insert(Succ); + else if (isHeader) + InEdges.insert(Succ); } if (uint32_t numBackEdges = BackEdges.size()) { @@ -220,39 +285,121 @@ void BranchProbabilityAnalysis::calcLoopBranchHeuristics(BasicBlock *BB) { if (backWeight < NORMAL_WEIGHT) backWeight = NORMAL_WEIGHT; - for (SmallVector::iterator EI = BackEdges.begin(), + for (SmallPtrSet::iterator EI = BackEdges.begin(), EE = BackEdges.end(); EI != EE; ++EI) { BasicBlock *Back = *EI; BP->setEdgeWeight(BB, Back, backWeight); } } + if (uint32_t numInEdges = InEdges.size()) { + uint32_t inWeight = LBH_TAKEN_WEIGHT / numInEdges; + if (inWeight < NORMAL_WEIGHT) + inWeight = NORMAL_WEIGHT; + + for (SmallPtrSet::iterator EI = InEdges.begin(), + EE = InEdges.end(); EI != EE; ++EI) { + BasicBlock *Back = *EI; + BP->setEdgeWeight(BB, Back, inWeight); + } + } + uint32_t numExitingEdges = ExitingEdges.size(); if (uint32_t numNonExitingEdges = numSuccs - numExitingEdges) { uint32_t exitWeight = LBH_NONTAKEN_WEIGHT / numNonExitingEdges; if (exitWeight < MIN_WEIGHT) exitWeight = MIN_WEIGHT; - for (SmallVector::iterator EI = ExitingEdges.begin(), + for (SmallPtrSet::iterator EI = ExitingEdges.begin(), EE = ExitingEdges.end(); EI != EE; ++EI) { BasicBlock *Exiting = *EI; BP->setEdgeWeight(BB, Exiting, exitWeight); } } + + return true; } +bool BranchProbabilityAnalysis::calcZeroHeuristics(BasicBlock *BB) { + BranchInst * BI = dyn_cast(BB->getTerminator()); + if (!BI || !BI->isConditional()) + return false; + + Value *Cond = BI->getCondition(); + ICmpInst *CI = dyn_cast(Cond); + if (!CI) + return false; + + Value *RHS = CI->getOperand(1); + ConstantInt *CV = dyn_cast(RHS); + if (!CV) + return false; + + bool isProb; + if (CV->isZero()) { + switch (CI->getPredicate()) { + case CmpInst::ICMP_EQ: + // X == 0 -> Unlikely + isProb = false; + break; + case CmpInst::ICMP_NE: + // X != 0 -> Likely + isProb = true; + break; + case CmpInst::ICMP_SLT: + // X < 0 -> Unlikely + isProb = false; + break; + case CmpInst::ICMP_SGT: + // X > 0 -> Likely + isProb = true; + break; + default: + return false; + } + } else if (CV->isOne() && CI->getPredicate() == CmpInst::ICMP_SLT) { + // InstCombine canonicalizes X <= 0 into X < 1. + // X <= 0 -> Unlikely + isProb = false; + } else if (CV->isAllOnesValue() && CI->getPredicate() == CmpInst::ICMP_SGT) { + // InstCombine canonicalizes X >= 0 into X > -1. + // X >= 0 -> Likely + isProb = true; + } else { + return false; + } + + BasicBlock *Taken = BI->getSuccessor(0); + BasicBlock *NonTaken = BI->getSuccessor(1); + + if (!isProb) + std::swap(Taken, NonTaken); + + BP->setEdgeWeight(BB, Taken, ZH_TAKEN_WEIGHT); + BP->setEdgeWeight(BB, NonTaken, ZH_NONTAKEN_WEIGHT); + + return true; +} + + bool BranchProbabilityAnalysis::runOnFunction(Function &F) { for (Function::iterator I = F.begin(), E = F.end(); I != E; ) { BasicBlock *BB = I++; - // Only LBH uses setEdgeWeight method. - calcLoopBranchHeuristics(BB); + if (calcMetadataWeights(BB)) + continue; - // PH and RH use only incEdgeWeight and decEwdgeWeight methods to - // not efface LBH results. - calcPointerHeuristics(BB); - calcReturnHeuristics(BB); + if (calcLoopBranchHeuristics(BB)) + continue; + + if (calcReturnHeuristics(BB)) + continue; + + if (calcPointerHeuristics(BB)) + continue; + + calcZeroHeuristics(BB); } return false; @@ -269,11 +416,11 @@ bool BranchProbabilityInfo::runOnFunction(Function &F) { return BPA.runOnFunction(F); } -uint32_t BranchProbabilityInfo::getSumForBlock(BasicBlock *BB) const { +uint32_t BranchProbabilityInfo::getSumForBlock(const BasicBlock *BB) const { uint32_t Sum = 0; - for (succ_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) { - BasicBlock *Succ = *I; + for (succ_const_iterator I = succ_begin(BB), E = succ_end(BB); I != E; ++I) { + const BasicBlock *Succ = *I; uint32_t Weight = getEdgeWeight(BB, Succ); uint32_t PrevSum = Sum; @@ -284,7 +431,8 @@ uint32_t BranchProbabilityInfo::getSumForBlock(BasicBlock *BB) const { return Sum; } -bool BranchProbabilityInfo::isEdgeHot(BasicBlock *Src, BasicBlock *Dst) const { +bool BranchProbabilityInfo:: +isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const { // Hot probability is at least 4/5 = 80% uint32_t Weight = getEdgeWeight(Src, Dst); uint32_t Sum = getSumForBlock(Src); @@ -321,8 +469,8 @@ BasicBlock *BranchProbabilityInfo::getHotSucc(BasicBlock *BB) const { } // Return edge's weight. If can't find it, return DEFAULT_WEIGHT value. -uint32_t -BranchProbabilityInfo::getEdgeWeight(BasicBlock *Src, BasicBlock *Dst) const { +uint32_t BranchProbabilityInfo:: +getEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst) const { Edge E(Src, Dst); DenseMap::const_iterator I = Weights.find(E); @@ -332,8 +480,8 @@ BranchProbabilityInfo::getEdgeWeight(BasicBlock *Src, BasicBlock *Dst) const { return DEFAULT_WEIGHT; } -void BranchProbabilityInfo::setEdgeWeight(BasicBlock *Src, BasicBlock *Dst, - uint32_t Weight) { +void BranchProbabilityInfo:: +setEdgeWeight(const BasicBlock *Src, const BasicBlock *Dst, uint32_t Weight) { Weights[std::make_pair(Src, Dst)] = Weight; DEBUG(dbgs() << "set edge " << Src->getNameStr() << " -> " << Dst->getNameStr() << " weight to " << Weight @@ -342,7 +490,7 @@ void BranchProbabilityInfo::setEdgeWeight(BasicBlock *Src, BasicBlock *Dst, BranchProbability BranchProbabilityInfo:: -getEdgeProbability(BasicBlock *Src, BasicBlock *Dst) const { +getEdgeProbability(const BasicBlock *Src, const BasicBlock *Dst) const { uint32_t N = getEdgeWeight(Src, Dst); uint32_t D = getSumForBlock(Src); diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt index ab846a26b4db..e79459d7a409 100644 --- a/lib/Analysis/CMakeLists.txt +++ b/lib/Analysis/CMakeLists.txt @@ -6,7 +6,7 @@ add_llvm_library(LLVMAnalysis AliasSetTracker.cpp Analysis.cpp BasicAliasAnalysis.cpp - BlockFrequency.cpp + BlockFrequencyInfo.cpp BranchProbabilityInfo.cpp CFGPrinter.cpp CaptureTracking.cpp @@ -58,4 +58,10 @@ add_llvm_library(LLVMAnalysis ValueTracking.cpp ) +add_llvm_library_dependencies(LLVMAnalysis + LLVMCore + LLVMSupport + LLVMTarget + ) + add_subdirectory(IPA) diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 7fca17eb69f6..df79849c3cf4 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -43,11 +43,16 @@ using namespace llvm; /// FoldBitCast - Constant fold bitcast, symbolically evaluating it with /// TargetData. This always returns a non-null constant, but it may be a /// ConstantExpr if unfoldable. -static Constant *FoldBitCast(Constant *C, const Type *DestTy, +static Constant *FoldBitCast(Constant *C, Type *DestTy, const TargetData &TD) { - - // This only handles casts to vectors currently. - const VectorType *DestVTy = dyn_cast(DestTy); + // Catch the obvious splat cases. + if (C->isNullValue() && !DestTy->isX86_MMXTy()) + return Constant::getNullValue(DestTy); + if (C->isAllOnesValue() && !DestTy->isX86_MMXTy()) + return Constant::getAllOnesValue(DestTy); + + // The code below only handles casts to vectors currently. + VectorType *DestVTy = dyn_cast(DestTy); if (DestVTy == 0) return ConstantExpr::getBitCast(C, DestTy); @@ -69,8 +74,8 @@ static Constant *FoldBitCast(Constant *C, const Type *DestTy, if (NumDstElt == NumSrcElt) return ConstantExpr::getBitCast(C, DestTy); - const Type *SrcEltTy = CV->getType()->getElementType(); - const Type *DstEltTy = DestVTy->getElementType(); + Type *SrcEltTy = CV->getType()->getElementType(); + Type *DstEltTy = DestVTy->getElementType(); // Otherwise, we're changing the number of elements in a vector, which // requires endianness information to do the right thing. For example, @@ -85,7 +90,7 @@ static Constant *FoldBitCast(Constant *C, const Type *DestTy, if (DstEltTy->isFloatingPointTy()) { // Fold to an vector of integers with same size as our FP type. unsigned FPWidth = DstEltTy->getPrimitiveSizeInBits(); - const Type *DestIVTy = + Type *DestIVTy = VectorType::get(IntegerType::get(C->getContext(), FPWidth), NumDstElt); // Recursively handle this integer conversion, if possible. C = FoldBitCast(C, DestIVTy, TD); @@ -99,7 +104,7 @@ static Constant *FoldBitCast(Constant *C, const Type *DestTy, // it to integer first. if (SrcEltTy->isFloatingPointTy()) { unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits(); - const Type *SrcIVTy = + Type *SrcIVTy = VectorType::get(IntegerType::get(C->getContext(), FPWidth), NumSrcElt); // Ask VMCore to do the conversion now that #elts line up. C = ConstantExpr::getBitCast(C, SrcIVTy); @@ -212,11 +217,11 @@ static bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV, if (!CI) return false; // Index isn't a simple constant? if (CI->isZero()) continue; // Not adding anything. - if (const StructType *ST = dyn_cast(*GTI)) { + if (StructType *ST = dyn_cast(*GTI)) { // N = N + Offset Offset += TD.getStructLayout(ST)->getElementOffset(CI->getZExtValue()); } else { - const SequentialType *SQT = cast(*GTI); + SequentialType *SQT = cast(*GTI); Offset += TD.getTypeAllocSize(SQT->getElementType())*CI->getSExtValue(); } } @@ -354,8 +359,8 @@ static bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset, static Constant *FoldReinterpretLoadFromConstPtr(Constant *C, const TargetData &TD) { - const Type *LoadTy = cast(C->getType())->getElementType(); - const IntegerType *IntType = dyn_cast(LoadTy); + Type *LoadTy = cast(C->getType())->getElementType(); + IntegerType *IntType = dyn_cast(LoadTy); // If this isn't an integer load we can't fold it directly. if (!IntType) { @@ -363,7 +368,7 @@ static Constant *FoldReinterpretLoadFromConstPtr(Constant *C, // and then bitcast the result. This can be useful for union cases. Note // that address spaces don't matter here since we're not going to result in // an actual new load. - const Type *MapTy; + Type *MapTy; if (LoadTy->isFloatTy()) MapTy = Type::getInt32PtrTy(C->getContext()); else if (LoadTy->isDoubleTy()) @@ -443,7 +448,7 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, std::string Str; if (TD && GetConstantStringInfo(CE, Str) && !Str.empty()) { unsigned StrLen = Str.length(); - const Type *Ty = cast(CE->getType())->getElementType(); + Type *Ty = cast(CE->getType())->getElementType(); unsigned NumBits = Ty->getPrimitiveSizeInBits(); // Replace load with immediate integer if the result is an integer or fp // value. @@ -478,7 +483,7 @@ Constant *llvm::ConstantFoldLoadFromConstPtr(Constant *C, if (GlobalVariable *GV = dyn_cast(GetUnderlyingObject(CE, TD))) { if (GV->isConstant() && GV->hasDefinitiveInitializer()) { - const Type *ResTy = cast(C->getType())->getElementType(); + Type *ResTy = cast(C->getType())->getElementType(); if (GV->getInitializer()->isNullValue()) return Constant::getNullValue(ResTy); if (isa(GV->getInitializer())) @@ -536,19 +541,18 @@ static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0, /// 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, +static Constant *CastGEPIndices(ArrayRef Ops, + Type *ResultTy, const TargetData *TD) { if (!TD) return 0; - const Type *IntPtrTy = TD->getIntPtrType(ResultTy->getContext()); + Type *IntPtrTy = TD->getIntPtrType(ResultTy->getContext()); bool Any = false; SmallVector NewIdxs; - for (unsigned i = 1; i != NumOps; ++i) { + for (unsigned i = 1, e = Ops.size(); i != e; ++i) { if ((i == 1 || !isa(GetElementPtrInst::getIndexedType(Ops[0]->getType(), - reinterpret_cast(Ops+1), - i-1))) && + Ops.slice(1, i-1)))) && Ops[i]->getType() != IntPtrTy) { Any = true; NewIdxs.push_back(ConstantExpr::getCast(CastInst::getCastOpcode(Ops[i], @@ -562,7 +566,7 @@ static Constant *CastGEPIndices(Constant *const *Ops, unsigned NumOps, if (!Any) return 0; Constant *C = - ConstantExpr::getGetElementPtr(Ops[0], &NewIdxs[0], NewIdxs.size()); + ConstantExpr::getGetElementPtr(Ops[0], NewIdxs); if (ConstantExpr *CE = dyn_cast(C)) if (Constant *Folded = ConstantFoldConstantExpression(CE, TD)) C = Folded; @@ -571,23 +575,23 @@ static Constant *CastGEPIndices(Constant *const *Ops, unsigned NumOps, /// SymbolicallyEvaluateGEP - If we can symbolically evaluate the specified GEP /// constant expression, do so. -static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps, - const Type *ResultTy, +static Constant *SymbolicallyEvaluateGEP(ArrayRef Ops, + Type *ResultTy, const TargetData *TD) { Constant *Ptr = Ops[0]; if (!TD || !cast(Ptr->getType())->getElementType()->isSized()) return 0; - const Type *IntPtrTy = TD->getIntPtrType(Ptr->getContext()); + Type *IntPtrTy = TD->getIntPtrType(Ptr->getContext()); // If this is a constant expr gep that is effectively computing an // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12' - for (unsigned i = 1; i != NumOps; ++i) + for (unsigned i = 1, e = Ops.size(); i != e; ++i) if (!isa(Ops[i])) { // If this is "gep i8* Ptr, (sub 0, V)", fold this as: // "inttoptr (sub (ptrtoint Ptr), V)" - if (NumOps == 2 && + if (Ops.size() == 2 && cast(ResultTy)->getElementType()->isIntegerTy(8)) { ConstantExpr *CE = dyn_cast(Ops[1]); assert((CE == 0 || CE->getType() == IntPtrTy) && @@ -606,9 +610,10 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps, } unsigned BitWidth = TD->getTypeSizeInBits(IntPtrTy); - APInt Offset = APInt(BitWidth, - TD->getIndexedOffset(Ptr->getType(), - (Value**)Ops+1, NumOps-1)); + APInt Offset = + APInt(BitWidth, TD->getIndexedOffset(Ptr->getType(), + makeArrayRef((Value **)Ops.data() + 1, + Ops.size() - 1))); Ptr = cast(Ptr->stripPointerCasts()); // If this is a GEP of a GEP, fold it all into a single GEP. @@ -627,9 +632,7 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps, Ptr = cast(GEP->getOperand(0)); Offset += APInt(BitWidth, - TD->getIndexedOffset(Ptr->getType(), - (Value**)NestedOps.data(), - NestedOps.size())); + TD->getIndexedOffset(Ptr->getType(), NestedOps)); Ptr = cast(Ptr->stripPointerCasts()); } @@ -649,10 +652,10 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps, // we eliminate over-indexing of the notional static type array bounds. // This makes it easy to determine if the getelementptr is "inbounds". // Also, this helps GlobalOpt do SROA on GlobalVariables. - const Type *Ty = Ptr->getType(); + Type *Ty = Ptr->getType(); SmallVector NewIdxs; do { - if (const SequentialType *ATy = dyn_cast(Ty)) { + if (SequentialType *ATy = dyn_cast(Ty)) { if (ATy->isPointerTy()) { // The only pointer indexing we'll do is on the first index of the GEP. if (!NewIdxs.empty()) @@ -665,7 +668,7 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps, // Determine which element of the array the offset points into. APInt ElemSize(BitWidth, TD->getTypeAllocSize(ATy->getElementType())); - const IntegerType *IntPtrTy = TD->getIntPtrType(Ty->getContext()); + IntegerType *IntPtrTy = TD->getIntPtrType(Ty->getContext()); if (ElemSize == 0) // The element size is 0. This may be [0 x Ty]*, so just use a zero // index for this level and proceed to the next level to see if it can @@ -679,7 +682,7 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps, NewIdxs.push_back(ConstantInt::get(IntPtrTy, NewIdx)); } Ty = ATy->getElementType(); - } else if (const StructType *STy = dyn_cast(Ty)) { + } else if (StructType *STy = dyn_cast(Ty)) { // Determine which field of the struct the offset points into. The // getZExtValue is at least as safe as the StructLayout API because we // know the offset is within the struct at this point. @@ -703,7 +706,7 @@ static Constant *SymbolicallyEvaluateGEP(Constant *const *Ops, unsigned NumOps, // Create a GEP. Constant *C = - ConstantExpr::getGetElementPtr(Ptr, &NewIdxs[0], NewIdxs.size()); + ConstantExpr::getGetElementPtr(Ptr, NewIdxs); assert(cast(C->getType())->getElementType() == Ty && "Computed GetElementPtr has unexpected type!"); @@ -778,8 +781,7 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) { cast(EVI->getAggregateOperand()), EVI->getIndices()); - return ConstantFoldInstOperands(I->getOpcode(), I->getType(), - Ops.data(), Ops.size(), TD); + return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Ops, TD); } /// ConstantFoldConstantExpression - Attempt to fold the constant expression @@ -800,8 +802,7 @@ Constant *llvm::ConstantFoldConstantExpression(const ConstantExpr *CE, if (CE->isCompare()) return ConstantFoldCompareInstOperands(CE->getPredicate(), Ops[0], Ops[1], TD); - return ConstantFoldInstOperands(CE->getOpcode(), CE->getType(), - Ops.data(), Ops.size(), TD); + return ConstantFoldInstOperands(CE->getOpcode(), CE->getType(), Ops, TD); } /// ConstantFoldInstOperands - Attempt to constant fold an instruction with the @@ -814,8 +815,8 @@ Constant *llvm::ConstantFoldConstantExpression(const ConstantExpr *CE, /// information, due to only being passed an opcode and operands. Constant /// folding using this function strips this information. /// -Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, - Constant* const* Ops, unsigned NumOps, +Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, Type *DestTy, + ArrayRef Ops, const TargetData *TD) { // Handle easy binops first. if (Instruction::isBinaryOp(Opcode)) { @@ -831,9 +832,9 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, case Instruction::ICmp: case Instruction::FCmp: assert(0 && "Invalid for compares"); case Instruction::Call: - if (Function *F = dyn_cast(Ops[NumOps - 1])) + if (Function *F = dyn_cast(Ops.back())) if (canConstantFoldCallTo(F)) - return ConstantFoldCall(F, Ops, NumOps - 1); + return ConstantFoldCall(F, Ops.slice(0, Ops.size() - 1)); return 0; case Instruction::PtrToInt: // If the input is a inttoptr, eliminate the pair. This requires knowing @@ -887,12 +888,12 @@ 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)) + if (Constant *C = CastGEPIndices(Ops, DestTy, TD)) return C; - if (Constant *C = SymbolicallyEvaluateGEP(Ops, NumOps, DestTy, TD)) + if (Constant *C = SymbolicallyEvaluateGEP(Ops, DestTy, TD)) return C; - return ConstantExpr::getGetElementPtr(Ops[0], Ops+1, NumOps-1); + return ConstantExpr::getGetElementPtr(Ops[0], Ops.slice(1)); } } @@ -912,7 +913,7 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate, // around to know if bit truncation is happening. if (ConstantExpr *CE0 = dyn_cast(Ops0)) { if (TD && Ops1->isNullValue()) { - const Type *IntPtrTy = TD->getIntPtrType(CE0->getContext()); + Type *IntPtrTy = TD->getIntPtrType(CE0->getContext()); if (CE0->getOpcode() == Instruction::IntToPtr) { // Convert the integer value to the right size to ensure we get the // proper extension or truncation. @@ -934,7 +935,7 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate, if (ConstantExpr *CE1 = dyn_cast(Ops1)) { if (TD && CE0->getOpcode() == CE1->getOpcode()) { - const Type *IntPtrTy = TD->getIntPtrType(CE0->getContext()); + Type *IntPtrTy = TD->getIntPtrType(CE0->getContext()); if (CE0->getOpcode() == Instruction::IntToPtr) { // Convert the integer value to the right size to ensure we get the @@ -967,7 +968,7 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate, unsigned OpC = Predicate == ICmpInst::ICMP_EQ ? Instruction::And : Instruction::Or; Constant *Ops[] = { LHS, RHS }; - return ConstantFoldInstOperands(OpC, LHS->getType(), Ops, 2, TD); + return ConstantFoldInstOperands(OpC, LHS->getType(), Ops, TD); } } @@ -987,7 +988,7 @@ Constant *llvm::ConstantFoldLoadThroughGEPConstantExpr(Constant *C, // addressing... gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE); for (++I; I != E; ++I) - if (const StructType *STy = dyn_cast(*I)) { + if (StructType *STy = dyn_cast(*I)) { ConstantInt *CU = cast(I.getOperand()); assert(CU->getZExtValue() < STy->getNumElements() && "Struct index out of range!"); @@ -1002,7 +1003,7 @@ Constant *llvm::ConstantFoldLoadThroughGEPConstantExpr(Constant *C, return 0; } } else if (ConstantInt *CI = dyn_cast(I.getOperand())) { - if (const ArrayType *ATy = dyn_cast(*I)) { + if (ArrayType *ATy = dyn_cast(*I)) { if (CI->getZExtValue() >= ATy->getNumElements()) return 0; if (ConstantArray *CA = dyn_cast(C)) @@ -1013,7 +1014,7 @@ Constant *llvm::ConstantFoldLoadThroughGEPConstantExpr(Constant *C, C = UndefValue::get(ATy->getElementType()); else return 0; - } else if (const VectorType *VTy = dyn_cast(*I)) { + } else if (VectorType *VTy = dyn_cast(*I)) { if (CI->getZExtValue() >= VTy->getNumElements()) return 0; if (ConstantVector *CP = dyn_cast(C)) @@ -1101,7 +1102,7 @@ llvm::canConstantFoldCallTo(const Function *F) { } static Constant *ConstantFoldFP(double (*NativeFP)(double), double V, - const Type *Ty) { + Type *Ty) { sys::llvm_fenv_clearexcept(); V = NativeFP(V); if (sys::llvm_fenv_testexcept()) { @@ -1118,7 +1119,7 @@ static Constant *ConstantFoldFP(double (*NativeFP)(double), double V, } static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double), - double V, double W, const Type *Ty) { + double V, double W, Type *Ty) { sys::llvm_fenv_clearexcept(); V = NativeFP(V, W); if (sys::llvm_fenv_testexcept()) { @@ -1143,7 +1144,7 @@ static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double), /// performed, otherwise returns the Constant value resulting from the /// conversion. static Constant *ConstantFoldConvertToInt(ConstantFP *Op, bool roundTowardZero, - const Type *Ty) { + Type *Ty) { assert(Op && "Called with NULL operand"); APFloat Val(Op->getValueAPF()); @@ -1167,13 +1168,12 @@ static Constant *ConstantFoldConvertToInt(ConstantFP *Op, bool roundTowardZero, /// ConstantFoldCall - Attempt to constant fold a call to the specified function /// with the specified arguments, returning null if unsuccessful. Constant * -llvm::ConstantFoldCall(Function *F, - Constant *const *Operands, unsigned NumOperands) { +llvm::ConstantFoldCall(Function *F, ArrayRef Operands) { if (!F->hasName()) return 0; StringRef Name = F->getName(); - const Type *Ty = F->getReturnType(); - if (NumOperands == 1) { + Type *Ty = F->getReturnType(); + if (Operands.size() == 1) { if (ConstantFP *Op = dyn_cast(Operands[0])) { if (F->getIntrinsicID() == Intrinsic::convert_to_fp16) { APFloat Val(Op->getValueAPF()); @@ -1327,7 +1327,7 @@ llvm::ConstantFoldCall(Function *F, return 0; } - if (NumOperands == 2) { + if (Operands.size() == 2) { if (ConstantFP *Op1 = dyn_cast(Operands[0])) { if (!Ty->isFloatTy() && !Ty->isDoubleTy()) return 0; diff --git a/lib/Analysis/DIBuilder.cpp b/lib/Analysis/DIBuilder.cpp index ac5eeeb4706a..bfa429d54120 100644 --- a/lib/Analysis/DIBuilder.cpp +++ b/lib/Analysis/DIBuilder.cpp @@ -29,14 +29,74 @@ static Constant *GetTagConstant(LLVMContext &VMContext, unsigned Tag) { } DIBuilder::DIBuilder(Module &m) - : M(m), VMContext(M.getContext()), TheCU(0), DeclareFn(0), ValueFn(0) {} + : M(m), VMContext(M.getContext()), TheCU(0), TempEnumTypes(0), + TempRetainTypes(0), TempSubprograms(0), TempGVs(0), DeclareFn(0), + ValueFn(0) +{} + +/// finalize - Construct any deferred debug info descriptors. +void DIBuilder::finalize() { + DIArray Enums = getOrCreateArray(AllEnumTypes); + DIType(TempEnumTypes).replaceAllUsesWith(Enums); + + DIArray RetainTypes = getOrCreateArray(AllRetainTypes); + DIType(TempRetainTypes).replaceAllUsesWith(RetainTypes); + + DIArray SPs = getOrCreateArray(AllSubprograms); + DIType(TempSubprograms).replaceAllUsesWith(SPs); + for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { + DISubprogram SP(SPs.getElement(i)); + if (NamedMDNode *NMD = getFnSpecificMDNode(M, SP)) { + SmallVector Variables; + for (unsigned ii = 0, ee = NMD->getNumOperands(); ii != ee; ++ii) + Variables.push_back(NMD->getOperand(ii)); + if (MDNode *Temp = SP.getVariablesNodes()) { + DIArray AV = getOrCreateArray(Variables); + DIType(Temp).replaceAllUsesWith(AV); + } + NMD->eraseFromParent(); + } + } + + DIArray GVs = getOrCreateArray(AllGVs); + DIType(TempGVs).replaceAllUsesWith(GVs); +} + +/// getNonCompileUnitScope - If N is compile unit return NULL otherwise return +/// N. +static MDNode *getNonCompileUnitScope(MDNode *N) { + if (DIDescriptor(N).isCompileUnit()) + return NULL; + return N; +} /// createCompileUnit - A CompileUnit provides an anchor for all debugging /// information generated during this instance of compilation. -void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, - StringRef Directory, StringRef Producer, - bool isOptimized, StringRef Flags, +void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, + StringRef Directory, StringRef Producer, + bool isOptimized, StringRef Flags, unsigned RunTimeVer) { + assert (Lang <= dwarf::DW_LANG_D && Lang >= dwarf::DW_LANG_C89 + && "Invalid Language tag"); + assert (!Filename.empty() + && "Unable to create compile unit without filename"); + Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) }; + TempEnumTypes = MDNode::getTemporary(VMContext, TElts); + Value *THElts[] = { TempEnumTypes }; + MDNode *EnumHolder = MDNode::get(VMContext, THElts); + + TempRetainTypes = MDNode::getTemporary(VMContext, TElts); + Value *TRElts[] = { TempRetainTypes }; + MDNode *RetainHolder = MDNode::get(VMContext, TRElts); + + TempSubprograms = MDNode::getTemporary(VMContext, TElts); + Value *TSElts[] = { TempSubprograms }; + MDNode *SPHolder = MDNode::get(VMContext, TSElts); + + TempGVs = MDNode::getTemporary(VMContext, TElts); + Value *TVElts[] = { TempGVs }; + MDNode *GVHolder = MDNode::get(VMContext, TVElts); + Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_compile_unit), llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), @@ -48,7 +108,11 @@ void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, ConstantInt::get(Type::getInt1Ty(VMContext), true), // isMain ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized), MDString::get(VMContext, Flags), - ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeVer) + ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeVer), + EnumHolder, + RetainHolder, + SPHolder, + GVHolder }; TheCU = DICompileUnit(MDNode::get(VMContext, Elts)); @@ -61,17 +125,19 @@ void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename, /// for a file. DIFile DIBuilder::createFile(StringRef Filename, StringRef Directory) { assert(TheCU && "Unable to create DW_TAG_file_type without CompileUnit"); + assert(!Filename.empty() && "Unable to create file without name"); Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_file_type), MDString::get(VMContext, Filename), MDString::get(VMContext, Directory), - TheCU + NULL // TheCU }; return DIFile(MDNode::get(VMContext, Elts)); } /// createEnumerator - Create a single enumerator value. DIEnumerator DIBuilder::createEnumerator(StringRef Name, uint64_t Val) { + assert(!Name.empty() && "Unable to create enumerator without name"); Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_enumerator), MDString::get(VMContext, Name), @@ -80,16 +146,37 @@ DIEnumerator DIBuilder::createEnumerator(StringRef Name, uint64_t Val) { return DIEnumerator(MDNode::get(VMContext, Elts)); } -/// createBasicType - Create debugging information entry for a basic +/// createNullPtrType - Create C++0x nullptr type. +DIType DIBuilder::createNullPtrType(StringRef Name) { + assert(!Name.empty() && "Unable to create type without name"); + // nullptr is encoded in DIBasicType format. Line number, filename, + // ,size, alignment, offset and flags are always empty here. + Value *Elts[] = { + GetTagConstant(VMContext, dwarf::DW_TAG_unspecified_type), + NULL, //TheCU, + MDString::get(VMContext, Name), + NULL, // Filename + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align + ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags; + ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Encoding + }; + return DIType(MDNode::get(VMContext, Elts)); +} + +/// createBasicType - Create debugging information entry for a basic /// type, e.g 'char'. -DIType DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits, +DIType DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Encoding) { + assert(!Name.empty() && "Unable to create type without name"); // Basic types are encoded in DIBasicType format. Line number, filename, // offset and flags are always empty here. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_base_type), - TheCU, + NULL, //TheCU, MDString::get(VMContext, Name), NULL, // Filename ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line @@ -108,7 +195,7 @@ DIType DIBuilder::createQualifiedType(unsigned Tag, DIType FromTy) { // Qualified types are encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, Tag), - TheCU, + NULL, //TheCU, MDString::get(VMContext, StringRef()), // Empty name. NULL, // Filename ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line @@ -127,7 +214,7 @@ DIType DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits, // Pointer types are encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_pointer_type), - TheCU, + NULL, //TheCU, MDString::get(VMContext, Name), NULL, // Filename ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line @@ -142,10 +229,11 @@ DIType DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits, /// createReferenceType - Create debugging information entry for a reference. DIType DIBuilder::createReferenceType(DIType RTy) { + assert(RTy.Verify() && "Unable to create reference type"); // References are encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_reference_type), - TheCU, + NULL, // TheCU, NULL, // Name NULL, // Filename ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line @@ -165,7 +253,7 @@ DIType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File, assert(Ty.Verify() && "Invalid typedef type!"); Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_typedef), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), @@ -199,9 +287,10 @@ DIType DIBuilder::createFriend(DIType Ty, DIType FriendTy) { } /// createInheritance - Create debugging information entry to establish -/// inheritnace relationship between two types. -DIType DIBuilder::createInheritance(DIType Ty, DIType BaseTy, +/// inheritance relationship between two types. +DIType DIBuilder::createInheritance(DIType Ty, DIType BaseTy, uint64_t BaseOffset, unsigned Flags) { + assert(Ty.Verify() && "Unable to create inheritance"); // TAG_inheritance is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_inheritance), @@ -219,15 +308,15 @@ DIType DIBuilder::createInheritance(DIType Ty, DIType BaseTy, } /// createMemberType - Create debugging information entry for a member. -DIType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name, - DIFile File, unsigned LineNumber, +DIType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name, + DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, - uint64_t OffsetInBits, unsigned Flags, + uint64_t OffsetInBits, unsigned Flags, DIType Ty) { // TAG_member is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), - Scope, + getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), @@ -242,17 +331,17 @@ DIType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name, /// createObjCIVar - Create debugging information entry for Objective-C /// instance variable. -DIType DIBuilder::createObjCIVar(StringRef Name, - DIFile File, unsigned LineNumber, +DIType DIBuilder::createObjCIVar(StringRef Name, + DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, - uint64_t OffsetInBits, unsigned Flags, + uint64_t OffsetInBits, unsigned Flags, DIType Ty, StringRef PropertyName, StringRef GetterName, StringRef SetterName, unsigned PropertyAttributes) { // TAG_member is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), - File, // Or TheCU ? Ty ? + getNonCompileUnitScope(File), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), @@ -270,8 +359,8 @@ DIType DIBuilder::createObjCIVar(StringRef Name, } /// createClassType - Create debugging information entry for a class. -DIType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, - DIFile File, unsigned LineNumber, +DIType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, + DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom, DIArray Elements, @@ -279,7 +368,7 @@ DIType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, // TAG_class_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_class_type), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), @@ -298,13 +387,13 @@ DIType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, /// createTemplateTypeParameter - Create debugging information for template /// type parameter. -DITemplateTypeParameter +DITemplateTypeParameter DIBuilder::createTemplateTypeParameter(DIDescriptor Context, StringRef Name, DIType Ty, MDNode *File, unsigned LineNo, unsigned ColumnNo) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_template_type_parameter), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), Ty, File, @@ -316,14 +405,14 @@ DIBuilder::createTemplateTypeParameter(DIDescriptor Context, StringRef Name, /// createTemplateValueParameter - Create debugging information for template /// value parameter. -DITemplateValueParameter +DITemplateValueParameter DIBuilder::createTemplateValueParameter(DIDescriptor Context, StringRef Name, DIType Ty, uint64_t Val, MDNode *File, unsigned LineNo, unsigned ColumnNo) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_template_value_parameter), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), Ty, ConstantInt::get(Type::getInt64Ty(VMContext), Val), @@ -335,15 +424,15 @@ DIBuilder::createTemplateValueParameter(DIDescriptor Context, StringRef Name, } /// createStructType - Create debugging information entry for a struct. -DIType DIBuilder::createStructType(DIDescriptor Context, StringRef Name, - DIFile File, unsigned LineNumber, +DIType DIBuilder::createStructType(DIDescriptor Context, StringRef Name, + DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, - unsigned Flags, DIArray Elements, + unsigned Flags, DIArray Elements, unsigned RunTimeLang) { // TAG_structure_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_structure_type), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), @@ -360,7 +449,7 @@ DIType DIBuilder::createStructType(DIDescriptor Context, StringRef Name, } /// createUnionType - Create debugging information entry for an union. -DIType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name, +DIType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, @@ -368,7 +457,7 @@ DIType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name, // TAG_union_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_union_type), - Scope, + getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), @@ -389,9 +478,9 @@ DIType DIBuilder::createSubroutineType(DIFile File, DIArray ParameterTypes) { // TAG_subroutine_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subroutine_type), - File, + llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), MDString::get(VMContext, ""), - File, + llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), ConstantInt::get(Type::getInt32Ty(VMContext), 0), ConstantInt::get(Type::getInt64Ty(VMContext), 0), ConstantInt::get(Type::getInt64Ty(VMContext), 0), @@ -405,16 +494,17 @@ DIType DIBuilder::createSubroutineType(DIFile File, DIArray ParameterTypes) { return DIType(MDNode::get(VMContext, Elts)); } -/// createEnumerationType - Create debugging information entry for an +/// createEnumerationType - Create debugging information entry for an /// enumeration. -DIType DIBuilder::createEnumerationType(DIDescriptor Scope, StringRef Name, - DIFile File, unsigned LineNumber, - uint64_t SizeInBits, - uint64_t AlignInBits, DIArray Elements) { +DIType DIBuilder::createEnumerationType(DIDescriptor Scope, StringRef Name, + DIFile File, unsigned LineNumber, + uint64_t SizeInBits, + uint64_t AlignInBits, + DIArray Elements) { // TAG_enumeration_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_enumeration_type), - Scope, + getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), @@ -428,20 +518,19 @@ DIType DIBuilder::createEnumerationType(DIDescriptor Scope, StringRef Name, llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), }; MDNode *Node = MDNode::get(VMContext, Elts); - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.enum"); - NMD->addOperand(Node); + AllEnumTypes.push_back(Node); return DIType(Node); } /// createArrayType - Create debugging information entry for an array. -DIType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits, +DIType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits, DIType Ty, DIArray Subscripts) { // TAG_array_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_array_type), - TheCU, + NULL, //TheCU, MDString::get(VMContext, ""), - TheCU, + NULL, //TheCU, ConstantInt::get(Type::getInt32Ty(VMContext), 0), ConstantInt::get(Type::getInt64Ty(VMContext), Size), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), @@ -456,14 +545,14 @@ DIType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits, } /// createVectorType - Create debugging information entry for a vector. -DIType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits, +DIType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits, DIType Ty, DIArray Subscripts) { // TAG_vector_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_vector_type), - TheCU, + NULL, //TheCU, MDString::get(VMContext, ""), - TheCU, + NULL, //TheCU, ConstantInt::get(Type::getInt32Ty(VMContext), 0), ConstantInt::get(Type::getInt64Ty(VMContext), Size), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), @@ -501,18 +590,17 @@ DIType DIBuilder::createArtificialType(DIType Ty) { return DIType(MDNode::get(VMContext, Elts)); } -/// retainType - Retain DIType in a module even if it is not referenced +/// retainType - Retain DIType in a module even if it is not referenced /// through debug info anchors. void DIBuilder::retainType(DIType T) { - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.ty"); - NMD->addOperand(T); + AllRetainTypes.push_back(T); } /// createUnspecifiedParameter - Create unspeicified type descriptor /// for the subroutine type. DIDescriptor DIBuilder::createUnspecifiedParameter() { - Value *Elts[] = { - GetTagConstant(VMContext, dwarf::DW_TAG_unspecified_parameters) + Value *Elts[] = { + GetTagConstant(VMContext, dwarf::DW_TAG_unspecified_parameters) }; return DIDescriptor(MDNode::get(VMContext, Elts)); } @@ -532,7 +620,7 @@ DIType DIBuilder::createTemporaryType(DIFile F) { // use here as long as DIType accepts it. Value *Elts[] = { GetTagConstant(VMContext, DW_TAG_base_type), - F.getCompileUnit(), + TheCU, NULL, F }; @@ -563,12 +651,12 @@ DISubrange DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Hi) { /// createGlobalVariable - Create a new descriptor for the specified global. DIGlobalVariable DIBuilder:: -createGlobalVariable(StringRef Name, DIFile F, unsigned LineNumber, +createGlobalVariable(StringRef Name, DIFile F, unsigned LineNumber, DIType Ty, bool isLocalToUnit, llvm::Value *Val) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_variable), llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), - TheCU, + NULL, // TheCU, MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, Name), @@ -580,22 +668,20 @@ createGlobalVariable(StringRef Name, DIFile F, unsigned LineNumber, Val }; MDNode *Node = MDNode::get(VMContext, Elts); - // Create a named metadata so that we do not lose this mdnode. - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv"); - NMD->addOperand(Node); + AllGVs.push_back(Node); return DIGlobalVariable(Node); } /// createStaticVariable - Create a new descriptor for the specified static /// variable. DIGlobalVariable DIBuilder:: -createStaticVariable(DIDescriptor Context, StringRef Name, - StringRef LinkageName, DIFile F, unsigned LineNumber, +createStaticVariable(DIDescriptor Context, StringRef Name, + StringRef LinkageName, DIFile F, unsigned LineNumber, DIType Ty, bool isLocalToUnit, llvm::Value *Val) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_variable), llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), @@ -607,26 +693,25 @@ createStaticVariable(DIDescriptor Context, StringRef Name, Val }; MDNode *Node = MDNode::get(VMContext, Elts); - // Create a named metadata so that we do not lose this mdnode. - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv"); - NMD->addOperand(Node); + AllGVs.push_back(Node); return DIGlobalVariable(Node); } /// createVariable - Create a new descriptor for the specified variable. DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, StringRef Name, DIFile File, - unsigned LineNo, DIType Ty, + unsigned LineNo, DIType Ty, bool AlwaysPreserve, unsigned Flags, unsigned ArgNo) { Value *Elts[] = { GetTagConstant(VMContext, Tag), - Scope, + getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), (LineNo | (ArgNo << 24))), Ty, - ConstantInt::get(Type::getInt32Ty(VMContext), Flags) + ConstantInt::get(Type::getInt32Ty(VMContext), Flags), + Constant::getNullValue(Type::getInt32Ty(VMContext)), }; MDNode *Node = MDNode::get(VMContext, Elts); if (AlwaysPreserve) { @@ -634,13 +719,7 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, // to preserve variable info in such situation then stash it in a // named mdnode. DISubprogram Fn(getDISubprogram(Scope)); - StringRef FName = "fn"; - if (Fn.getFunction()) - FName = Fn.getFunction()->getName(); - char One = '\1'; - if (FName.startswith(StringRef(&One, 1))) - FName = FName.substr(1); - NamedMDNode *FnLocals = getOrInsertFnSpecificMDNode(M, FName); + NamedMDNode *FnLocals = getOrInsertFnSpecificMDNode(M, Fn); FnLocals->addOperand(Node); } return DIVariable(Node); @@ -655,12 +734,14 @@ DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope, unsigned ArgNo) { SmallVector Elts; Elts.push_back(GetTagConstant(VMContext, Tag)); - Elts.push_back(Scope); + Elts.push_back(getNonCompileUnitScope(Scope)), Elts.push_back(MDString::get(VMContext, Name)); Elts.push_back(F); - Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), (LineNo | (ArgNo << 24)))); + Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), + (LineNo | (ArgNo << 24)))); Elts.push_back(Ty); Elts.push_back(llvm::Constant::getNullValue(Type::getInt32Ty(VMContext))); + Elts.push_back(llvm::Constant::getNullValue(Type::getInt32Ty(VMContext))); Elts.append(Addr.begin(), Addr.end()); return DIVariable(MDNode::get(VMContext, Elts)); @@ -677,10 +758,15 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, Function *Fn, MDNode *TParams, MDNode *Decl) { + Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) }; + MDNode *Temp = MDNode::getTemporary(VMContext, TElts); + Value *TVElts[] = { Temp }; + MDNode *THolder = MDNode::get(VMContext, TVElts); + Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subprogram), llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), @@ -696,13 +782,13 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized), Fn, TParams, - Decl + Decl, + THolder }; MDNode *Node = MDNode::get(VMContext, Elts); // Create a named metadata so that we do not lose this mdnode. - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.sp"); - NMD->addOperand(Node); + AllSubprograms.push_back(Node); return DISubprogram(Node); } @@ -720,10 +806,15 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, bool isOptimized, Function *Fn, MDNode *TParam) { + Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) }; + MDNode *Temp = MDNode::getTemporary(VMContext, TElts); + Value *TVElts[] = { Temp }; + MDNode *THolder = MDNode::get(VMContext, TVElts); + Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subprogram), llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), - Context, + getNonCompileUnitScope(Context), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), @@ -739,12 +830,10 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized), Fn, TParam, + llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)), + THolder }; MDNode *Node = MDNode::get(VMContext, Elts); - - // Create a named metadata so that we do not lose this mdnode. - NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.sp"); - NMD->addOperand(Node); return DISubprogram(Node); } @@ -754,7 +843,7 @@ DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNo) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_namespace), - Scope, + getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), File, ConstantInt::get(Type::getInt32Ty(VMContext), LineNo) @@ -762,13 +851,25 @@ DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name, return DINameSpace(MDNode::get(VMContext, Elts)); } +/// createLexicalBlockFile - This creates a new MDNode that encapsulates +/// an existing scope with a new filename. +DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope, + DIFile File) { + Value *Elts[] = { + GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block), + Scope, + File + }; + return DILexicalBlockFile(MDNode::get(VMContext, Elts)); +} + DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File, unsigned Line, unsigned Col) { // Defeat MDNode uniqing for lexical blocks by using unique id. static unsigned int unique_id = 0; Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block), - Scope, + getNonCompileUnitScope(Scope), ConstantInt::get(Type::getInt32Ty(VMContext), Line), ConstantInt::get(Type::getInt32Ty(VMContext), Col), File, @@ -836,4 +937,3 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, VarInfo }; return CallInst::Create(ValueFn, Args, "", InsertAtEnd); } - diff --git a/lib/Analysis/DbgInfoPrinter.cpp b/lib/Analysis/DbgInfoPrinter.cpp index b23c3514d0bd..cd832abeba51 100644 --- a/lib/Analysis/DbgInfoPrinter.cpp +++ b/lib/Analysis/DbgInfoPrinter.cpp @@ -171,7 +171,7 @@ static bool getLocationInfo(const Value *V, std::string &DisplayName, void PrintDbgInfo::printVariableDeclaration(const Value *V) { std::string DisplayName, File, Directory, Type; - unsigned LineNo; + unsigned LineNo = 0; if (!getLocationInfo(V, DisplayName, Type, LineNo, File, Directory)) return; diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index b42e946f2ffa..44457d3c3de9 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -39,6 +39,9 @@ DIDescriptor::DIDescriptor(const DIFile F) : DbgNode(F.DbgNode) { DIDescriptor::DIDescriptor(const DISubprogram F) : DbgNode(F.DbgNode) { } +DIDescriptor::DIDescriptor(const DILexicalBlockFile F) : DbgNode(F.DbgNode) { +} + DIDescriptor::DIDescriptor(const DILexicalBlock F) : DbgNode(F.DbgNode) { } @@ -111,9 +114,17 @@ Function *DIDescriptor::getFunctionField(unsigned Elt) const { unsigned DIVariable::getNumAddrElements() const { if (getVersion() <= llvm::LLVMDebugVersion8) return DbgNode->getNumOperands()-6; - return DbgNode->getNumOperands()-7; + if (getVersion() == llvm::LLVMDebugVersion9) + return DbgNode->getNumOperands()-7; + return DbgNode->getNumOperands()-8; } +/// getInlinedAt - If this variable is inlined then return inline location. +MDNode *DIVariable::getInlinedAt() const { + if (getVersion() <= llvm::LLVMDebugVersion9) + return NULL; + return dyn_cast_or_null(DbgNode->getOperand(7)); +} //===----------------------------------------------------------------------===// // Predicates @@ -122,7 +133,14 @@ unsigned DIVariable::getNumAddrElements() const { /// isBasicType - Return true if the specified tag is legal for /// DIBasicType. bool DIDescriptor::isBasicType() const { - return DbgNode && getTag() == dwarf::DW_TAG_base_type; + if (!DbgNode) return false; + switch (getTag()) { + case dwarf::DW_TAG_base_type: + case dwarf::DW_TAG_unspecified_type: + return true; + default: + return false; + } } /// isDerivedType - Return true if the specified tag is legal for DIDerivedType. @@ -248,9 +266,17 @@ bool DIDescriptor::isNameSpace() const { return DbgNode && getTag() == dwarf::DW_TAG_namespace; } +/// isLexicalBlockFile - Return true if the specified descriptor is a +/// lexical block with an extra file. +bool DIDescriptor::isLexicalBlockFile() const { + return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && + (DbgNode->getNumOperands() == 3); +} + /// isLexicalBlock - Return true if the specified tag is DW_TAG_lexical_block. bool DIDescriptor::isLexicalBlock() const { - return DbgNode && getTag() == dwarf::DW_TAG_lexical_block; + return DbgNode && getTag() == dwarf::DW_TAG_lexical_block && + (DbgNode->getNumOperands() > 3); } /// isSubrange - Return true if the specified tag is DW_TAG_subrange_type. @@ -320,6 +346,22 @@ void DIType::replaceAllUsesWith(MDNode *D) { } } +/// isUnsignedDIType - Return true if type encoding is unsigned. +bool DIType::isUnsignedDIType() { + DIDerivedType DTy(DbgNode); + if (DTy.Verify()) + return DTy.getTypeDerivedFrom().isUnsignedDIType(); + + DIBasicType BTy(DbgNode); + if (BTy.Verify()) { + unsigned Encoding = BTy.getEncoding(); + if (Encoding == dwarf::DW_ATE_unsigned || + Encoding == dwarf::DW_ATE_unsigned_char) + return true; + } + return false; +} + /// Verify - Verify that a compile unit is well formed. bool DICompileUnit::Verify() const { if (!DbgNode) @@ -335,7 +377,7 @@ bool DICompileUnit::Verify() const { bool DIType::Verify() const { if (!DbgNode) return false; - if (!getContext().Verify()) + if (getContext() && !getContext().Verify()) return false; unsigned Tag = getTag(); if (!isBasicType() && Tag != dwarf::DW_TAG_const_type && @@ -343,6 +385,7 @@ bool DIType::Verify() const { Tag != dwarf::DW_TAG_reference_type && Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_vector_type && Tag != dwarf::DW_TAG_array_type && Tag != dwarf::DW_TAG_enumeration_type + && Tag != dwarf::DW_TAG_subroutine_type && getFilename().empty()) return false; return true; @@ -362,12 +405,9 @@ bool DIDerivedType::Verify() const { bool DICompositeType::Verify() const { if (!DbgNode) return false; - if (!getContext().Verify()) + if (getContext() && !getContext().Verify()) return false; - DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) - return false; return true; } @@ -376,11 +416,7 @@ bool DISubprogram::Verify() const { if (!DbgNode) return false; - if (!getContext().Verify()) - return false; - - DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) + if (getContext() && !getContext().Verify()) return false; DICompositeType Ty = getType(); @@ -397,11 +433,7 @@ bool DIGlobalVariable::Verify() const { if (getDisplayName().empty()) return false; - if (!getContext().Verify()) - return false; - - DICompileUnit CU = getCompileUnit(); - if (!CU.Verify()) + if (getContext() && !getContext().Verify()) return false; DIType Ty = getType(); @@ -419,10 +451,7 @@ bool DIVariable::Verify() const { if (!DbgNode) return false; - if (!getContext().Verify()) - return false; - - if (!getCompileUnit().Verify()) + if (getContext() && !getContext().Verify()) return false; DIType Ty = getType(); @@ -446,8 +475,6 @@ bool DINameSpace::Verify() const { return false; if (getName().empty()) return false; - if (!getCompileUnit().Verify()) - return false; return true; } @@ -504,9 +531,28 @@ unsigned DISubprogram::isOptimized() const { return 0; } +MDNode *DISubprogram::getVariablesNodes() const { + if (!DbgNode || DbgNode->getNumOperands() <= 19) + return NULL; + if (MDNode *Temp = dyn_cast_or_null(DbgNode->getOperand(19))) + return dyn_cast_or_null(Temp->getOperand(0)); + return NULL; +} + +DIArray DISubprogram::getVariables() const { + if (!DbgNode || DbgNode->getNumOperands() <= 19) + return DIArray(); + if (MDNode *T = dyn_cast_or_null(DbgNode->getOperand(19))) + if (MDNode *A = dyn_cast_or_null(T->getOperand(0))) + return DIArray(A); + return DIArray(); +} + StringRef DIScope::getFilename() const { if (!DbgNode) return StringRef(); + if (isLexicalBlockFile()) + return DILexicalBlockFile(DbgNode).getFilename(); if (isLexicalBlock()) return DILexicalBlock(DbgNode).getFilename(); if (isSubprogram()) @@ -526,6 +572,8 @@ StringRef DIScope::getFilename() const { StringRef DIScope::getDirectory() const { if (!DbgNode) return StringRef(); + if (isLexicalBlockFile()) + return DILexicalBlockFile(DbgNode).getDirectory(); if (isLexicalBlock()) return DILexicalBlock(DbgNode).getDirectory(); if (isSubprogram()) @@ -542,6 +590,47 @@ StringRef DIScope::getDirectory() const { return StringRef(); } +DIArray DICompileUnit::getEnumTypes() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(10))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + +DIArray DICompileUnit::getRetainedTypes() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(11))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + +DIArray DICompileUnit::getSubprograms() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(12))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + + +DIArray DICompileUnit::getGlobalVariables() const { + if (!DbgNode || DbgNode->getNumOperands() < 14) + return DIArray(); + + if (MDNode *N = dyn_cast_or_null(DbgNode->getOperand(13))) + if (MDNode *A = dyn_cast_or_null(N->getOperand(0))) + return DIArray(A); + return DIArray(); +} + //===----------------------------------------------------------------------===// // DIDescriptor: dump routines for all descriptors. //===----------------------------------------------------------------------===// @@ -573,7 +662,6 @@ void DIType::print(raw_ostream &OS) const { OS << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context - getCompileUnit().print(OS); OS << " [" << "line " << getLineNumber() << ", " << getSizeInBits() << " bits, " @@ -629,7 +717,6 @@ void DISubprogram::print(raw_ostream &OS) const { OS << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context - getCompileUnit().print(OS); OS << " [" << getLineNumber() << "] "; if (isLocalToUnit()) @@ -652,7 +739,6 @@ void DIGlobalVariable::print(raw_ostream &OS) const { OS << " [" << dwarf::TagString(Tag) << "] "; // TODO : Print context - getCompileUnit().print(OS); OS << " [" << getLineNumber() << "] "; if (isLocalToUnit()) @@ -666,13 +752,48 @@ void DIGlobalVariable::print(raw_ostream &OS) const { OS << "]\n"; } +static void printDebugLoc(DebugLoc DL, raw_ostream &CommentOS, + const LLVMContext &Ctx) { + if (!DL.isUnknown()) { // Print source line info. + DIScope Scope(DL.getScope(Ctx)); + // Omit the directory, because it's likely to be long and uninteresting. + if (Scope.Verify()) + CommentOS << Scope.getFilename(); + else + CommentOS << ""; + CommentOS << ':' << DL.getLine(); + if (DL.getCol() != 0) + CommentOS << ':' << DL.getCol(); + DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(DL.getInlinedAt(Ctx)); + if (!InlinedAtDL.isUnknown()) { + CommentOS << " @[ "; + printDebugLoc(InlinedAtDL, CommentOS, Ctx); + CommentOS << " ]"; + } + } +} + +void DIVariable::printExtendedName(raw_ostream &OS) const { + const LLVMContext &Ctx = DbgNode->getContext(); + StringRef Res = getName(); + if (!Res.empty()) + OS << Res << "," << getLineNumber(); + if (MDNode *InlinedAt = getInlinedAt()) { + DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt); + if (!InlinedAtDL.isUnknown()) { + OS << " @["; + printDebugLoc(InlinedAtDL, OS, Ctx); + OS << "]"; + } + } +} + /// print - Print variable. void DIVariable::print(raw_ostream &OS) const { StringRef Res = getName(); if (!Res.empty()) OS << " [" << Res << "] "; - getCompileUnit().print(OS); OS << " [" << getLineNumber() << "] "; getType().print(OS); OS << "\n"; @@ -744,22 +865,61 @@ static void fixupObjcLikeName(StringRef Str, SmallVectorImpl &Out) { /// getFnSpecificMDNode - Return a NameMDNode, if available, that is /// suitable to hold function specific information. -NamedMDNode *llvm::getFnSpecificMDNode(const Module &M, StringRef FuncName) { +NamedMDNode *llvm::getFnSpecificMDNode(const Module &M, DISubprogram Fn) { SmallString<32> Name = StringRef("llvm.dbg.lv."); - fixupObjcLikeName(FuncName, Name); - + StringRef FName = "fn"; + if (Fn.getFunction()) + FName = Fn.getFunction()->getName(); + else + FName = Fn.getName(); + char One = '\1'; + if (FName.startswith(StringRef(&One, 1))) + FName = FName.substr(1); + fixupObjcLikeName(FName, Name); return M.getNamedMetadata(Name.str()); } /// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable /// to hold function specific information. -NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, StringRef FuncName) { +NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, DISubprogram Fn) { SmallString<32> Name = StringRef("llvm.dbg.lv."); - fixupObjcLikeName(FuncName, Name); - + StringRef FName = "fn"; + if (Fn.getFunction()) + FName = Fn.getFunction()->getName(); + else + FName = Fn.getName(); + char One = '\1'; + if (FName.startswith(StringRef(&One, 1))) + FName = FName.substr(1); + fixupObjcLikeName(FName, Name); + return M.getOrInsertNamedMetadata(Name.str()); } +/// createInlinedVariable - Create a new inlined variable based on current +/// variable. +/// @param DV Current Variable. +/// @param InlinedScope Location at current variable is inlined. +DIVariable llvm::createInlinedVariable(MDNode *DV, MDNode *InlinedScope, + LLVMContext &VMContext) { + SmallVector Elts; + // Insert inlined scope as 7th element. + for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i) + i == 7 ? Elts.push_back(InlinedScope) : + Elts.push_back(DV->getOperand(i)); + return DIVariable(MDNode::get(VMContext, Elts)); +} + +/// cleanseInlinedVariable - Remove inlined scope from the variable. +DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) { + SmallVector Elts; + // Insert inlined scope as 7th element. + for (unsigned i = 0, e = DV->getNumOperands(); i != e; ++i) + i == 7 ? + Elts.push_back(llvm::Constant::getNullValue(Type::getInt32Ty(VMContext))): + Elts.push_back(DV->getOperand(i)); + return DIVariable(MDNode::get(VMContext, Elts)); +} //===----------------------------------------------------------------------===// // DebugInfoFinder implementations. @@ -767,6 +927,10 @@ NamedMDNode *llvm::getOrInsertFnSpecificMDNode(Module &M, StringRef FuncName) { /// processModule - Process entire module and collect debug info. void DebugInfoFinder::processModule(Module &M) { + if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) + for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) + addCompileUnit(DICompileUnit(CU_Nodes->getOperand(i))); + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI) for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end(); BI != BE; @@ -785,6 +949,10 @@ void DebugInfoFinder::processModule(Module &M) { addCompileUnit(DICompileUnit(Scope)); else if (Scope.isSubprogram()) processSubprogram(DISubprogram(Scope)); + else if (Scope.isLexicalBlockFile()) { + DILexicalBlockFile DBF = DILexicalBlockFile(Scope); + processLexicalBlock(DILexicalBlock(DBF.getScope())); + } else if (Scope.isLexicalBlock()) processLexicalBlock(DILexicalBlock(Scope)); @@ -796,7 +964,8 @@ void DebugInfoFinder::processModule(Module &M) { for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { DIGlobalVariable DIG(cast(NMD->getOperand(i))); if (addGlobalVariable(DIG)) { - addCompileUnit(DIG.getCompileUnit()); + if (DIG.getVersion() <= LLVMDebugVersion10) + addCompileUnit(DIG.getCompileUnit()); processType(DIG.getType()); } } @@ -817,6 +986,10 @@ void DebugInfoFinder::processLocation(DILocation Loc) { processSubprogram(DISubprogram(S)); else if (S.isLexicalBlock()) processLexicalBlock(DILexicalBlock(S)); + else if (S.isLexicalBlockFile()) { + DILexicalBlockFile DBF = DILexicalBlockFile(S); + processLexicalBlock(DILexicalBlock(DBF.getScope())); + } processLocation(Loc.getOrigLocation()); } @@ -824,8 +997,8 @@ void DebugInfoFinder::processLocation(DILocation Loc) { void DebugInfoFinder::processType(DIType DT) { if (!addType(DT)) return; - - addCompileUnit(DT.getCompileUnit()); + if (DT.getVersion() <= LLVMDebugVersion10) + addCompileUnit(DT.getCompileUnit()); if (DT.isCompositeType()) { DICompositeType DCT(DT); processType(DCT.getTypeDerivedFrom()); @@ -848,6 +1021,10 @@ void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { DIScope Context = LB.getContext(); if (Context.isLexicalBlock()) return processLexicalBlock(DILexicalBlock(Context)); + else if (Context.isLexicalBlockFile()) { + DILexicalBlockFile DBF = DILexicalBlockFile(Context); + return processLexicalBlock(DILexicalBlock(DBF.getScope())); + } else return processSubprogram(DISubprogram(Context)); } @@ -856,7 +1033,8 @@ void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { void DebugInfoFinder::processSubprogram(DISubprogram SP) { if (!addSubprogram(SP)) return; - addCompileUnit(SP.getCompileUnit()); + if (SP.getVersion() <= LLVMDebugVersion10) + addCompileUnit(SP.getCompileUnit()); processType(SP.getType()); } @@ -871,8 +1049,8 @@ void DebugInfoFinder::processDeclare(DbgDeclareInst *DDI) { if (!NodesSeen.insert(DV)) return; - - addCompileUnit(DIVariable(N).getCompileUnit()); + if (DIVariable(N).getVersion() <= LLVMDebugVersion10) + addCompileUnit(DIVariable(N).getCompileUnit()); processType(DIVariable(N).getType()); } @@ -930,6 +1108,9 @@ DISubprogram llvm::getDISubprogram(const MDNode *Scope) { if (D.isSubprogram()) return DISubprogram(Scope); + if (D.isLexicalBlockFile()) + return getDISubprogram(DILexicalBlockFile(Scope).getContext()); + if (D.isLexicalBlock()) return getDISubprogram(DILexicalBlock(Scope).getContext()); @@ -946,3 +1127,17 @@ DICompositeType llvm::getDICompositeType(DIType T) { return DICompositeType(); } + +/// isSubprogramContext - Return true if Context is either a subprogram +/// or another context nested inside a subprogram. +bool llvm::isSubprogramContext(const MDNode *Context) { + if (!Context) + return false; + DIDescriptor D(Context); + if (D.isSubprogram()) + return true; + if (D.isType()) + return isSubprogramContext(DIType(Context).getContext()); + return false; +} + diff --git a/lib/Analysis/IPA/CMakeLists.txt b/lib/Analysis/IPA/CMakeLists.txt index 8ffef29870ae..eae83fdc369c 100644 --- a/lib/Analysis/IPA/CMakeLists.txt +++ b/lib/Analysis/IPA/CMakeLists.txt @@ -5,3 +5,9 @@ add_llvm_library(LLVMipa GlobalsModRef.cpp IPA.cpp ) + +add_llvm_library_dependencies(LLVMipa + LLVMAnalysis + LLVMCore + LLVMSupport + ) diff --git a/lib/Analysis/IPA/CallGraphSCCPass.cpp b/lib/Analysis/IPA/CallGraphSCCPass.cpp index 659ffab0c6f0..963da752343b 100644 --- a/lib/Analysis/IPA/CallGraphSCCPass.cpp +++ b/lib/Analysis/IPA/CallGraphSCCPass.cpp @@ -44,8 +44,8 @@ namespace { class CGPassManager : public ModulePass, public PMDataManager { public: static char ID; - explicit CGPassManager(int Depth) - : ModulePass(ID), PMDataManager(Depth) { } + explicit CGPassManager() + : ModulePass(ID), PMDataManager() { } /// run - Execute all of the passes scheduled for execution. Keep track of /// whether any of the passes modifies the module, and if so, return true. @@ -350,6 +350,7 @@ bool CGPassManager::RefreshCallGraph(CallGraphSCC &CurSCC, dbgs() << "CGSCCPASSMGR: SCC Refresh didn't change call graph.\n"; } ); + (void)MadeChange; return DevirtualizedCall; } @@ -542,7 +543,7 @@ void CallGraphSCCPass::assignPassManager(PMStack &PMS, PMDataManager *PMD = PMS.top(); // [1] Create new Call Graph Pass Manager - CGP = new CGPassManager(PMD->getDepth() + 1); + CGP = new CGPassManager(); // [2] Set up new manager's top level manager PMTopLevelManager *TPM = PMD->getTopLevelManager(); diff --git a/lib/Analysis/IPA/FindUsedTypes.cpp b/lib/Analysis/IPA/FindUsedTypes.cpp index 6535786668bc..e9df3ca01022 100644 --- a/lib/Analysis/IPA/FindUsedTypes.cpp +++ b/lib/Analysis/IPA/FindUsedTypes.cpp @@ -29,7 +29,7 @@ INITIALIZE_PASS(FindUsedTypes, "print-used-types", // IncorporateType - Incorporate one type and all of its subtypes into the // collection of used types. // -void FindUsedTypes::IncorporateType(const Type *Ty) { +void FindUsedTypes::IncorporateType(Type *Ty) { // If ty doesn't already exist in the used types map, add it now, otherwise // return. if (!UsedTypes.insert(Ty)) return; // Already contain Ty. @@ -94,7 +94,7 @@ bool FindUsedTypes::runOnModule(Module &m) { // void FindUsedTypes::print(raw_ostream &OS, const Module *M) const { OS << "Types in use by this module:\n"; - for (SetVector::const_iterator I = UsedTypes.begin(), + for (SetVector::const_iterator I = UsedTypes.begin(), E = UsedTypes.end(); I != E; ++I) { OS << " " << **I << '\n'; } diff --git a/lib/Analysis/IVUsers.cpp b/lib/Analysis/IVUsers.cpp index e5f0a77ab67d..d0ca8920ab9f 100644 --- a/lib/Analysis/IVUsers.cpp +++ b/lib/Analysis/IVUsers.cpp @@ -146,7 +146,8 @@ bool IVUsers::AddUsersIfInteresting(Instruction *I) { ISE, User, I, NewUse.PostIncLoops, *SE, *DT); - DEBUG(dbgs() << " NORMALIZED TO: " << *ISE << '\n'); + DEBUG(if (SE->getSCEV(I) != ISE) + dbgs() << " NORMALIZED TO: " << *ISE << '\n'); } } return true; diff --git a/lib/Analysis/InlineCost.cpp b/lib/Analysis/InlineCost.cpp index efde5984c115..e12e322c2a99 100644 --- a/lib/Analysis/InlineCost.cpp +++ b/lib/Analysis/InlineCost.cpp @@ -15,6 +15,7 @@ #include "llvm/Support/CallSite.h" #include "llvm/CallingConv.h" #include "llvm/IntrinsicInst.h" +#include "llvm/Target/TargetData.h" #include "llvm/ADT/SmallPtrSet.h" using namespace llvm; @@ -24,13 +25,13 @@ using namespace llvm; /// TODO: Perhaps calls like memcpy, strcpy, etc? bool llvm::callIsSmall(const Function *F) { if (!F) return false; - + if (F->hasLocalLinkage()) return false; - + if (!F->hasName()) return false; - + StringRef Name = F->getName(); - + // These will all likely lower to a single selection DAG node. if (Name == "copysign" || Name == "copysignf" || Name == "copysignl" || Name == "fabs" || Name == "fabsf" || Name == "fabsl" || @@ -38,7 +39,7 @@ bool llvm::callIsSmall(const Function *F) { Name == "cos" || Name == "cosf" || Name == "cosl" || Name == "sqrt" || Name == "sqrtf" || Name == "sqrtl" ) return true; - + // These are all likely to be optimized into something smaller. if (Name == "pow" || Name == "powf" || Name == "powl" || Name == "exp2" || Name == "exp2l" || Name == "exp2f" || @@ -46,13 +47,14 @@ bool llvm::callIsSmall(const Function *F) { Name == "round" || Name == "ffs" || Name == "ffsl" || Name == "abs" || Name == "labs" || Name == "llabs") return true; - + return false; } /// analyzeBasicBlock - Fill in the current structure with information gleaned /// from the specified block. -void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) { +void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB, + const TargetData *TD) { ++NumBlocks; unsigned NumInstsBeforeThisBB = NumInsts; for (BasicBlock::const_iterator II = BB->begin(), E = BB->end(); @@ -67,8 +69,8 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) { ImmutableCallSite CS(cast(II)); if (const Function *F = CS.getCalledFunction()) { - // If a function is both internal and has a single use, then it is - // extremely likely to get inlined in the future (it was probably + // If a function is both internal and has a single use, then it is + // extremely likely to get inlined in the future (it was probably // exposed by an interleaved devirtualization pass). if (F->hasInternalLinkage() && F->hasOneUse()) ++NumInlineCandidates; @@ -91,20 +93,25 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) { ++NumCalls; } } - + if (const AllocaInst *AI = dyn_cast(II)) { if (!AI->isStaticAlloca()) this->usesDynamicAlloca = true; } if (isa(II) || II->getType()->isVectorTy()) - ++NumVectorInsts; - + ++NumVectorInsts; + if (const CastInst *CI = dyn_cast(II)) { // Noop casts, including ptr <-> int, don't count. - if (CI->isLosslessCast() || isa(CI) || + if (CI->isLosslessCast() || isa(CI) || isa(CI)) continue; + // trunc to a native type is free (assuming the target has compare and + // shift-right of the same width). + if (isa(CI) && TD && + TD->isLegalInteger(TD->getTypeSizeInBits(CI->getType()))) + continue; // Result of a cmp instruction is often extended (to be used by other // cmp instructions, logical or return instructions). These are usually // nop on most sane targets. @@ -119,10 +126,10 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) { ++NumInsts; } - + if (isa(BB->getTerminator())) ++NumRets; - + // We never want to inline functions that contain an indirectbr. This is // incorrect because all the blockaddress's (in static global initializers // for example) would be referring to the original function, and this indirect @@ -217,7 +224,7 @@ unsigned CodeMetrics::CountCodeReductionForAlloca(Value *V) { /// analyzeFunction - Fill in the current structure with information gleaned /// from the specified function. -void CodeMetrics::analyzeFunction(Function *F) { +void CodeMetrics::analyzeFunction(Function *F, const TargetData *TD) { // If this function contains a call to setjmp or _setjmp, never inline // it. This is a hack because we depend on the user marking their local // variables as volatile if they are live across a setjmp call, and they @@ -227,13 +234,14 @@ void CodeMetrics::analyzeFunction(Function *F) { // Look at the size of the callee. for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) - analyzeBasicBlock(&*BB); + analyzeBasicBlock(&*BB, TD); } /// analyzeFunction - Fill in the current structure with information gleaned /// from the specified function. -void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) { - Metrics.analyzeFunction(F); +void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F, + const TargetData *TD) { + Metrics.analyzeFunction(F, TD); // A function with exactly one return has it removed during the inlining // process (see InlineFunction), so don't count it. @@ -252,7 +260,7 @@ void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) { /// NeverInline - returns true if the function should never be inlined into /// any caller bool InlineCostAnalyzer::FunctionInfo::NeverInline() { - return (Metrics.callsSetJmp || Metrics.isRecursive || + return (Metrics.callsSetJmp || Metrics.isRecursive || Metrics.containsIndirectBr); } // getSpecializationBonus - The heuristic used to determine the per-call @@ -263,19 +271,19 @@ int InlineCostAnalyzer::getSpecializationBonus(Function *Callee, { if (Callee->mayBeOverridden()) return 0; - + int Bonus = 0; // If this function uses the coldcc calling convention, prefer not to // specialize it. if (Callee->getCallingConv() == CallingConv::Cold) Bonus -= InlineConstants::ColdccPenalty; - + // Get information about the callee. FunctionInfo *CalleeFI = &CachedFunctionInfo[Callee]; - + // If we haven't calculated this information yet, do so now. if (CalleeFI->Metrics.NumBlocks == 0) - CalleeFI->analyzeFunction(Callee); + CalleeFI->analyzeFunction(Callee, TD); unsigned ArgNo = 0; unsigned i = 0; @@ -286,7 +294,7 @@ int InlineCostAnalyzer::getSpecializationBonus(Function *Callee, Bonus += CountBonusForConstant(I); } - // Calls usually take a long time, so they make the specialization gain + // Calls usually take a long time, so they make the specialization gain // smaller. Bonus -= CalleeFI->Metrics.NumCalls * InlineConstants::CallPenalty; @@ -300,13 +308,13 @@ int InlineCostAnalyzer::getSpecializationBonus(Function *Callee, // inlining because we decide we don't want to give a bonus for // devirtualizing. int InlineCostAnalyzer::ConstantFunctionBonus(CallSite CS, Constant *C) { - + // This could just be NULL. if (!C) return 0; - + Function *F = dyn_cast(C); if (!F) return 0; - + int Bonus = InlineConstants::IndirectCallBonus + getInlineSize(CS, F); return (Bonus > 0) ? 0 : Bonus; } @@ -355,18 +363,18 @@ int InlineCostAnalyzer::CountBonusForConstant(Value *V, Constant *C) { Bonus += CountBonusForConstant(&Inst); } } - + return Bonus; } int InlineCostAnalyzer::getInlineSize(CallSite CS, Function *Callee) { // Get information about the callee. FunctionInfo *CalleeFI = &CachedFunctionInfo[Callee]; - + // If we haven't calculated this information yet, do so now. if (CalleeFI->Metrics.NumBlocks == 0) - CalleeFI->analyzeFunction(Callee); - + CalleeFI->analyzeFunction(Callee, TD); + // InlineCost - This value measures how good of an inline candidate this call // site is to inline. A lower inline cost make is more likely for the call to // be inlined. This value may go negative. @@ -392,9 +400,9 @@ int InlineCostAnalyzer::getInlineSize(CallSite CS, Function *Callee) { // weights calculated for the callee to determine how much will be folded // away with this information. else if (isa(I)) - InlineCost -= CalleeFI->ArgumentWeights[ArgNo].ConstantWeight; + InlineCost -= CalleeFI->ArgumentWeights[ArgNo].ConstantWeight; } - + // Each argument passed in has a cost at both the caller and the callee // sides. Measurements show that each argument costs about the same as an // instruction. @@ -408,28 +416,28 @@ int InlineCostAnalyzer::getInlineSize(CallSite CS, Function *Callee) { // Look at the size of the callee. Each instruction counts as 5. InlineCost += CalleeFI->Metrics.NumInsts*InlineConstants::InstrCost; - + return InlineCost; } int InlineCostAnalyzer::getInlineBonuses(CallSite CS, Function *Callee) { // Get information about the callee. FunctionInfo *CalleeFI = &CachedFunctionInfo[Callee]; - + // If we haven't calculated this information yet, do so now. if (CalleeFI->Metrics.NumBlocks == 0) - CalleeFI->analyzeFunction(Callee); - + CalleeFI->analyzeFunction(Callee, TD); + bool isDirectCall = CS.getCalledFunction() == Callee; Instruction *TheCall = CS.getInstruction(); int Bonus = 0; - + // If there is only one call of the function, and it has internal linkage, // make it almost guaranteed to be inlined. // if (Callee->hasLocalLinkage() && Callee->hasOneUse() && isDirectCall) Bonus += InlineConstants::LastCallToStaticBonus; - + // If the instruction after the call, or if the normal destination of the // invoke is an unreachable instruction, the function is noreturn. As such, // there is little point in inlining this. @@ -438,12 +446,12 @@ int InlineCostAnalyzer::getInlineBonuses(CallSite CS, Function *Callee) { Bonus += InlineConstants::NoreturnPenalty; } else if (isa(++BasicBlock::iterator(TheCall))) Bonus += InlineConstants::NoreturnPenalty; - + // If this function uses the coldcc calling convention, prefer not to inline // it. if (Callee->getCallingConv() == CallingConv::Cold) Bonus += InlineConstants::ColdccPenalty; - + // Add to the inline quality for properties that make the call valuable to // inline. This includes factors that indicate that the result of inlining // the function will be optimizable. Currently this just looks at arguments @@ -455,7 +463,7 @@ int InlineCostAnalyzer::getInlineBonuses(CallSite CS, Function *Callee) { // Compute any constant bonus due to inlining we want to give here. if (isa(I)) Bonus += CountBonusForConstant(FI, cast(I)); - + return Bonus; } @@ -483,10 +491,10 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS, // Get information about the callee. FunctionInfo *CalleeFI = &CachedFunctionInfo[Callee]; - + // If we haven't calculated this information yet, do so now. if (CalleeFI->Metrics.NumBlocks == 0) - CalleeFI->analyzeFunction(Callee); + CalleeFI->analyzeFunction(Callee, TD); // If we should never inline this, return a huge cost. if (CalleeFI->NeverInline()) @@ -498,15 +506,15 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS, // requires handling setjmp somewhere else, however. if (!Callee->isDeclaration() && Callee->hasFnAttr(Attribute::AlwaysInline)) return InlineCost::getAlways(); - + if (CalleeFI->Metrics.usesDynamicAlloca) { // Get information about the caller. FunctionInfo &CallerFI = CachedFunctionInfo[Caller]; // If we haven't calculated this information yet, do so now. if (CallerFI.Metrics.NumBlocks == 0) { - CallerFI.analyzeFunction(Caller); - + CallerFI.analyzeFunction(Caller, TD); + // Recompute the CalleeFI pointer, getting Caller could have invalidated // it. CalleeFI = &CachedFunctionInfo[Callee]; @@ -538,16 +546,16 @@ InlineCost InlineCostAnalyzer::getSpecializationCost(Function *Callee, // something else. if (Callee->mayBeOverridden()) return llvm::InlineCost::getNever(); - + // Get information about the callee. FunctionInfo *CalleeFI = &CachedFunctionInfo[Callee]; - + // If we haven't calculated this information yet, do so now. if (CalleeFI->Metrics.NumBlocks == 0) - CalleeFI->analyzeFunction(Callee); + CalleeFI->analyzeFunction(Callee, TD); int Cost = 0; - + // Look at the original size of the callee. Each instruction counts as 5. Cost += CalleeFI->Metrics.NumInsts * InlineConstants::InstrCost; @@ -564,13 +572,13 @@ InlineCost InlineCostAnalyzer::getSpecializationCost(Function *Callee, // higher threshold to determine if the function call should be inlined. float InlineCostAnalyzer::getInlineFudgeFactor(CallSite CS) { Function *Callee = CS.getCalledFunction(); - + // Get information about the callee. FunctionInfo &CalleeFI = CachedFunctionInfo[Callee]; - + // If we haven't calculated this information yet, do so now. if (CalleeFI.Metrics.NumBlocks == 0) - CalleeFI.analyzeFunction(Callee); + CalleeFI.analyzeFunction(Callee, TD); float Factor = 1.0f; // Single BB functions are often written to be inlined. @@ -604,7 +612,7 @@ InlineCostAnalyzer::growCachedCostInfo(Function *Caller, Function *Callee) { --CallerMetrics.NumCalls; if (Callee == 0) return; - + CodeMetrics &CalleeMetrics = CachedFunctionInfo[Callee].Metrics; // If we don't have metrics for the callee, don't recalculate them just to @@ -614,7 +622,7 @@ InlineCostAnalyzer::growCachedCostInfo(Function *Caller, Function *Callee) { resetCachedCostInfo(Caller); return; } - + // Since CalleeMetrics were already calculated, we know that the CallerMetrics // reference isn't invalidated: both were in the DenseMap. CallerMetrics.usesDynamicAlloca |= CalleeMetrics.usesDynamicAlloca; @@ -636,7 +644,7 @@ InlineCostAnalyzer::growCachedCostInfo(Function *Caller, Function *Callee) { CallerMetrics.NumInsts -= Callee->arg_size(); else CallerMetrics.NumInsts = 0; - + // We are not updating the argument weights. We have already determined that // Caller is a fairly large function, so we accept the loss of precision. } diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 8709f6bf9d26..131cc97d2379 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -48,6 +48,26 @@ static Value *SimplifyOrInst(Value *, Value *, const TargetData *, static Value *SimplifyXorInst(Value *, Value *, const TargetData *, const DominatorTree *, unsigned); +/// getFalse - For a boolean type, or a vector of boolean type, return false, or +/// a vector with every element false, as appropriate for the type. +static Constant *getFalse(Type *Ty) { + assert((Ty->isIntegerTy(1) || + (Ty->isVectorTy() && + cast(Ty)->getElementType()->isIntegerTy(1))) && + "Expected i1 type or a vector of i1!"); + return Constant::getNullValue(Ty); +} + +/// getTrue - For a boolean type, or a vector of boolean type, return true, or +/// a vector with every element true, as appropriate for the type. +static Constant *getTrue(Type *Ty) { + assert((Ty->isIntegerTy(1) || + (Ty->isVectorTy() && + cast(Ty)->getElementType()->isIntegerTy(1))) && + "Expected i1 type or a vector of i1!"); + return Constant::getAllOnesValue(Ty); +} + /// ValueDominatesPHI - Does the given value dominate the specified phi node? static bool ValueDominatesPHI(Value *V, PHINode *P, const DominatorTree *DT) { Instruction *I = dyn_cast(V); @@ -526,7 +546,7 @@ static Value *SimplifyAddInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; return ConstantFoldInstOperands(Instruction::Add, CLHS->getType(), - Ops, 2, TD); + Ops, TD); } // Canonicalize the constant to the RHS. @@ -595,7 +615,7 @@ static Value *SimplifySubInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW, if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; return ConstantFoldInstOperands(Instruction::Sub, CLHS->getType(), - Ops, 2, TD); + Ops, TD); } // X - undef -> undef @@ -715,7 +735,7 @@ static Value *SimplifyMulInst(Value *Op0, Value *Op1, const TargetData *TD, if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; return ConstantFoldInstOperands(Instruction::Mul, CLHS->getType(), - Ops, 2, TD); + Ops, TD); } // Canonicalize the constant to the RHS. @@ -788,7 +808,7 @@ static Value *SimplifyDiv(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, if (Constant *C0 = dyn_cast(Op0)) { if (Constant *C1 = dyn_cast(Op1)) { Constant *Ops[] = { C0, C1 }; - return ConstantFoldInstOperands(Opcode, C0->getType(), Ops, 2, TD); + return ConstantFoldInstOperands(Opcode, C0->getType(), Ops, TD); } } @@ -909,7 +929,7 @@ static Value *SimplifyRem(Instruction::BinaryOps Opcode, Value *Op0, Value *Op1, if (Constant *C0 = dyn_cast(Op0)) { if (Constant *C1 = dyn_cast(Op1)) { Constant *Ops[] = { C0, C1 }; - return ConstantFoldInstOperands(Opcode, C0->getType(), Ops, 2, TD); + return ConstantFoldInstOperands(Opcode, C0->getType(), Ops, TD); } } @@ -1012,7 +1032,7 @@ static Value *SimplifyShift(unsigned Opcode, Value *Op0, Value *Op1, if (Constant *C0 = dyn_cast(Op0)) { if (Constant *C1 = dyn_cast(Op1)) { Constant *Ops[] = { C0, C1 }; - return ConstantFoldInstOperands(Opcode, C0->getType(), Ops, 2, TD); + return ConstantFoldInstOperands(Opcode, C0->getType(), Ops, TD); } } @@ -1138,7 +1158,7 @@ static Value *SimplifyAndInst(Value *Op0, Value *Op1, const TargetData *TD, if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; return ConstantFoldInstOperands(Instruction::And, CLHS->getType(), - Ops, 2, TD); + Ops, TD); } // Canonicalize the constant to the RHS. @@ -1227,7 +1247,7 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const TargetData *TD, if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; return ConstantFoldInstOperands(Instruction::Or, CLHS->getType(), - Ops, 2, TD); + Ops, TD); } // Canonicalize the constant to the RHS. @@ -1321,7 +1341,7 @@ static Value *SimplifyXorInst(Value *Op0, Value *Op1, const TargetData *TD, if (Constant *CRHS = dyn_cast(Op1)) { Constant *Ops[] = { CLHS, CRHS }; return ConstantFoldInstOperands(Instruction::Xor, CLHS->getType(), - Ops, 2, TD); + Ops, TD); } // Canonicalize the constant to the RHS. @@ -1372,7 +1392,7 @@ Value *llvm::SimplifyXorInst(Value *Op0, Value *Op1, const TargetData *TD, return ::SimplifyXorInst(Op0, Op1, TD, DT, RecursionLimit); } -static const Type *GetCompareTy(Value *Op) { +static Type *GetCompareTy(Value *Op) { return CmpInst::makeCmpResultType(Op->getType()); } @@ -1413,8 +1433,8 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, Pred = CmpInst::getSwappedPredicate(Pred); } - const Type *ITy = GetCompareTy(LHS); // The return type. - const Type *OpTy = LHS->getType(); // The operand type. + Type *ITy = GetCompareTy(LHS); // The return type. + Type *OpTy = LHS->getType(); // The operand type. // icmp X, X -> true/false // X icmp undef -> true/false. For example, icmp ugt %X, undef -> false @@ -1478,48 +1498,46 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, default: assert(false && "Unknown ICmp predicate!"); case ICmpInst::ICMP_ULT: - // getNullValue also works for vectors, unlike getFalse. - return Constant::getNullValue(ITy); + return getFalse(ITy); case ICmpInst::ICMP_UGE: - // getAllOnesValue also works for vectors, unlike getTrue. - return ConstantInt::getAllOnesValue(ITy); + return getTrue(ITy); case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_ULE: if (isKnownNonZero(LHS, TD)) - return Constant::getNullValue(ITy); + return getFalse(ITy); break; case ICmpInst::ICMP_NE: case ICmpInst::ICMP_UGT: if (isKnownNonZero(LHS, TD)) - return ConstantInt::getAllOnesValue(ITy); + return getTrue(ITy); break; case ICmpInst::ICMP_SLT: ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, TD); if (LHSKnownNegative) - return ConstantInt::getAllOnesValue(ITy); + return getTrue(ITy); if (LHSKnownNonNegative) - return Constant::getNullValue(ITy); + return getFalse(ITy); break; case ICmpInst::ICMP_SLE: ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, TD); if (LHSKnownNegative) - return ConstantInt::getAllOnesValue(ITy); + return getTrue(ITy); if (LHSKnownNonNegative && isKnownNonZero(LHS, TD)) - return Constant::getNullValue(ITy); + return getFalse(ITy); break; case ICmpInst::ICMP_SGE: ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, TD); if (LHSKnownNegative) - return Constant::getNullValue(ITy); + return getFalse(ITy); if (LHSKnownNonNegative) - return ConstantInt::getAllOnesValue(ITy); + return getTrue(ITy); break; case ICmpInst::ICMP_SGT: ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, TD); if (LHSKnownNegative) - return Constant::getNullValue(ITy); + return getFalse(ITy); if (LHSKnownNonNegative && isKnownNonZero(LHS, TD)) - return ConstantInt::getAllOnesValue(ITy); + return getTrue(ITy); break; } } @@ -1593,8 +1611,8 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, if (isa(LHS) && (isa(RHS) || isa(RHS))) { Instruction *LI = cast(LHS); Value *SrcOp = LI->getOperand(0); - const Type *SrcTy = SrcOp->getType(); - const Type *DstTy = LI->getType(); + Type *SrcTy = SrcOp->getType(); + Type *DstTy = LI->getType(); // Turn icmp (ptrtoint x), (ptrtoint/constant) into a compare of the input // if the integer type is the same size as the pointer type. @@ -1811,8 +1829,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: - // getNullValue also works for vectors, unlike getFalse. - return Constant::getNullValue(ITy); + return getFalse(ITy); case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: ComputeSignBit(LHS, KnownNonNegative, KnownNegative, TD); @@ -1822,8 +1839,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, case ICmpInst::ICMP_NE: case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: - // getAllOnesValue also works for vectors, unlike getTrue. - return Constant::getAllOnesValue(ITy); + return getTrue(ITy); } } if (RBO && match(RBO, m_URem(m_Value(), m_Specific(LHS)))) { @@ -1840,8 +1856,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, case ICmpInst::ICMP_NE: case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: - // getAllOnesValue also works for vectors, unlike getTrue. - return Constant::getAllOnesValue(ITy); + return getTrue(ITy); case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: ComputeSignBit(RHS, KnownNonNegative, KnownNegative, TD); @@ -1851,8 +1866,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: - // getNullValue also works for vectors, unlike getFalse. - return Constant::getNullValue(ITy); + return getFalse(ITy); } } @@ -1874,7 +1888,7 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, return V; break; case Instruction::Shl: { - bool NUW = LBO->hasNoUnsignedWrap() && LBO->hasNoUnsignedWrap(); + bool NUW = LBO->hasNoUnsignedWrap() && RBO->hasNoUnsignedWrap(); bool NSW = LBO->hasNoSignedWrap() && RBO->hasNoSignedWrap(); if (!NUW && !NSW) break; @@ -1955,10 +1969,10 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, } case CmpInst::ICMP_SGE: // Always true. - return Constant::getAllOnesValue(ITy); + return getTrue(ITy); case CmpInst::ICMP_SLT: // Always false. - return Constant::getNullValue(ITy); + return getFalse(ITy); } } @@ -2025,10 +2039,10 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, } case CmpInst::ICMP_UGE: // Always true. - return Constant::getAllOnesValue(ITy); + return getTrue(ITy); case CmpInst::ICMP_ULT: // Always false. - return Constant::getNullValue(ITy); + return getFalse(ITy); } } @@ -2040,40 +2054,40 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, // max(x, ?) pred min(x, ?). if (Pred == CmpInst::ICMP_SGE) // Always true. - return Constant::getAllOnesValue(ITy); + return getTrue(ITy); if (Pred == CmpInst::ICMP_SLT) // Always false. - return Constant::getNullValue(ITy); + return getFalse(ITy); } else if (match(LHS, m_SMin(m_Value(A), m_Value(B))) && match(RHS, m_SMax(m_Value(C), m_Value(D))) && (A == C || A == D || B == C || B == D)) { // min(x, ?) pred max(x, ?). if (Pred == CmpInst::ICMP_SLE) // Always true. - return Constant::getAllOnesValue(ITy); + return getTrue(ITy); if (Pred == CmpInst::ICMP_SGT) // Always false. - return Constant::getNullValue(ITy); + return getFalse(ITy); } else if (match(LHS, m_UMax(m_Value(A), m_Value(B))) && match(RHS, m_UMin(m_Value(C), m_Value(D))) && (A == C || A == D || B == C || B == D)) { // max(x, ?) pred min(x, ?). if (Pred == CmpInst::ICMP_UGE) // Always true. - return Constant::getAllOnesValue(ITy); + return getTrue(ITy); if (Pred == CmpInst::ICMP_ULT) // Always false. - return Constant::getNullValue(ITy); + return getFalse(ITy); } else if (match(LHS, m_UMin(m_Value(A), m_Value(B))) && match(RHS, m_UMax(m_Value(C), m_Value(D))) && (A == C || A == D || B == C || B == D)) { // min(x, ?) pred max(x, ?). if (Pred == CmpInst::ICMP_ULE) // Always true. - return Constant::getAllOnesValue(ITy); + return getTrue(ITy); if (Pred == CmpInst::ICMP_UGT) // Always false. - return Constant::getNullValue(ITy); + return getFalse(ITy); } // If the comparison is with the result of a select instruction, check whether @@ -2219,43 +2233,71 @@ Value *llvm::SimplifySelectInst(Value *CondVal, Value *TrueVal, Value *FalseVal, /// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can /// fold the result. If not, this returns null. -Value *llvm::SimplifyGEPInst(Value *const *Ops, unsigned NumOps, +Value *llvm::SimplifyGEPInst(ArrayRef Ops, const TargetData *TD, const DominatorTree *) { // The type of the GEP pointer operand. - const PointerType *PtrTy = cast(Ops[0]->getType()); + PointerType *PtrTy = cast(Ops[0]->getType()); // getelementptr P -> P. - if (NumOps == 1) + if (Ops.size() == 1) return Ops[0]; if (isa(Ops[0])) { // Compute the (pointer) type returned by the GEP instruction. - const Type *LastType = GetElementPtrInst::getIndexedType(PtrTy, &Ops[1], - NumOps-1); - const Type *GEPTy = PointerType::get(LastType, PtrTy->getAddressSpace()); + Type *LastType = GetElementPtrInst::getIndexedType(PtrTy, Ops.slice(1)); + Type *GEPTy = PointerType::get(LastType, PtrTy->getAddressSpace()); return UndefValue::get(GEPTy); } - if (NumOps == 2) { + if (Ops.size() == 2) { // getelementptr P, 0 -> P. if (ConstantInt *C = dyn_cast(Ops[1])) if (C->isZero()) return Ops[0]; // getelementptr P, N -> P if P points to a type of zero size. if (TD) { - const Type *Ty = PtrTy->getElementType(); + Type *Ty = PtrTy->getElementType(); if (Ty->isSized() && TD->getTypeAllocSize(Ty) == 0) return Ops[0]; } } // Check to see if this is constant foldable. - for (unsigned i = 0; i != NumOps; ++i) + for (unsigned i = 0, e = Ops.size(); i != e; ++i) if (!isa(Ops[i])) return 0; - return ConstantExpr::getGetElementPtr(cast(Ops[0]), - (Constant *const*)Ops+1, NumOps-1); + return ConstantExpr::getGetElementPtr(cast(Ops[0]), Ops.slice(1)); +} + +/// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we +/// can fold the result. If not, this returns null. +Value *llvm::SimplifyInsertValueInst(Value *Agg, Value *Val, + ArrayRef Idxs, + const TargetData *, + const DominatorTree *) { + if (Constant *CAgg = dyn_cast(Agg)) + if (Constant *CVal = dyn_cast(Val)) + return ConstantFoldInsertValueInstruction(CAgg, CVal, Idxs); + + // insertvalue x, undef, n -> x + if (match(Val, m_Undef())) + return Agg; + + // insertvalue x, (extractvalue y, n), n + if (ExtractValueInst *EV = dyn_cast(Val)) + if (EV->getAggregateOperand()->getType() == Agg->getType() && + EV->getIndices() == Idxs) { + // insertvalue undef, (extractvalue y, n), n -> y + if (match(Agg, m_Undef())) + return EV->getAggregateOperand(); + + // insertvalue y, (extractvalue y, n), n -> y + if (Agg == EV->getAggregateOperand()) + return Agg; + } + + return 0; } /// SimplifyPHINode - See if we can fold the given phi. If not, returns null. @@ -2328,7 +2370,7 @@ static Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, if (Constant *CLHS = dyn_cast(LHS)) if (Constant *CRHS = dyn_cast(RHS)) { Constant *COps[] = {CLHS, CRHS}; - return ConstantFoldInstOperands(Opcode, LHS->getType(), COps, 2, TD); + return ConstantFoldInstOperands(Opcode, LHS->getType(), COps, TD); } // If the operation is associative, try some generic simplifications. @@ -2456,7 +2498,14 @@ Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD, break; case Instruction::GetElementPtr: { SmallVector Ops(I->op_begin(), I->op_end()); - Result = SimplifyGEPInst(&Ops[0], Ops.size(), TD, DT); + Result = SimplifyGEPInst(Ops, TD, DT); + break; + } + case Instruction::InsertValue: { + InsertValueInst *IV = cast(I); + Result = SimplifyInsertValueInst(IV->getAggregateOperand(), + IV->getInsertedValueOperand(), + IV->getIndices(), TD, DT); break; } case Instruction::PHI: diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index 6e275978276d..f80595c7dbed 100644 --- a/lib/Analysis/LazyValueInfo.cpp +++ b/lib/Analysis/LazyValueInfo.cpp @@ -630,7 +630,7 @@ bool LazyValueInfoCache::solveBlockValueNonLocal(LVILatticeVal &BBLV, if (BB == &BB->getParent()->getEntryBlock()) { assert(isa(Val) && "Unknown live-in to the entry block"); if (NotNull) { - const PointerType *PTy = cast(Val->getType()); + PointerType *PTy = cast(Val->getType()); Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy)); } else { Result.markOverdefined(); @@ -658,7 +658,7 @@ bool LazyValueInfoCache::solveBlockValueNonLocal(LVILatticeVal &BBLV, // If we previously determined that this is a pointer that can't be null // then return that rather than giving up entirely. if (NotNull) { - const PointerType *PTy = cast(Val->getType()); + PointerType *PTy = cast(Val->getType()); Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy)); } @@ -728,7 +728,7 @@ bool LazyValueInfoCache::solveBlockValueConstantRange(LVILatticeVal &BBLV, ConstantRange LHSRange = LHSVal.getConstantRange(); ConstantRange RHSRange(1); - const IntegerType *ResultTy = cast(BBI->getType()); + IntegerType *ResultTy = cast(BBI->getType()); if (isa(BBI)) { if (ConstantInt *RHS = dyn_cast(BBI->getOperand(1))) { RHSRange = ConstantRange(RHS->getValue()); diff --git a/lib/Analysis/Lint.cpp b/lib/Analysis/Lint.cpp index 89755da85097..38d677d502a7 100644 --- a/lib/Analysis/Lint.cpp +++ b/lib/Analysis/Lint.cpp @@ -71,7 +71,7 @@ namespace { void visitCallSite(CallSite CS); void visitMemoryReference(Instruction &I, Value *Ptr, uint64_t Size, unsigned Align, - const Type *Ty, unsigned Flags); + Type *Ty, unsigned Flags); void visitCallInst(CallInst &I); void visitInvokeInst(InvokeInst &I); @@ -201,7 +201,7 @@ void Lint::visitCallSite(CallSite CS) { "Undefined behavior: Caller and callee calling convention differ", &I); - const FunctionType *FT = F->getFunctionType(); + FunctionType *FT = F->getFunctionType(); unsigned NumActualArgs = unsigned(CS.arg_end()-CS.arg_begin()); Assert1(FT->isVarArg() ? @@ -240,7 +240,7 @@ void Lint::visitCallSite(CallSite CS) { // Check that an sret argument points to valid memory. if (Formal->hasStructRetAttr() && Actual->getType()->isPointerTy()) { - const Type *Ty = + Type *Ty = cast(Formal->getType())->getElementType(); visitMemoryReference(I, Actual, AA->getTypeStoreSize(Ty), TD ? TD->getABITypeAlignment(Ty) : 0, @@ -364,7 +364,7 @@ void Lint::visitReturnInst(ReturnInst &I) { // TODO: Check readnone/readonly function attributes. void Lint::visitMemoryReference(Instruction &I, Value *Ptr, uint64_t Size, unsigned Align, - const Type *Ty, unsigned Flags) { + Type *Ty, unsigned Flags) { // If no memory is being referenced, it doesn't matter if the pointer // is valid. if (Size == 0) diff --git a/lib/Analysis/Loads.cpp b/lib/Analysis/Loads.cpp index c5c676b5265f..0e6bcbfae4f6 100644 --- a/lib/Analysis/Loads.cpp +++ b/lib/Analysis/Loads.cpp @@ -63,7 +63,7 @@ static Value *getUnderlyingObjectWithOffset(Value *V, const TargetData *TD, return V; SmallVector Indices(GEP->op_begin() + 1, GEP->op_end()); ByteOffset += TD->getIndexedOffset(GEP->getPointerOperandType(), - &Indices[0], Indices.size()); + Indices); V = GEP->getPointerOperand(); } else if (Operator::getOpcode(V) == Instruction::BitCast) { V = cast(V)->getOperand(0); @@ -90,7 +90,7 @@ bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, if (TD) Base = getUnderlyingObjectWithOffset(V, TD, ByteOffset); - const Type *BaseType = 0; + Type *BaseType = 0; unsigned BaseAlign = 0; if (const AllocaInst *AI = dyn_cast(Base)) { // An alloca is safe to load from as load as it is suitably aligned. @@ -114,7 +114,7 @@ bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, 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(V->getType()); + PointerType *AddrTy = cast(V->getType()); uint64_t LoadSize = TD->getTypeStoreSize(AddrTy->getElementType()); if (ByteOffset + LoadSize <= TD->getTypeAllocSize(BaseType) && (Align == 0 || (ByteOffset % Align) == 0)) @@ -169,7 +169,7 @@ Value *llvm::FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, // If we're using alias analysis to disambiguate get the size of *Ptr. uint64_t AccessSize = 0; if (AA) { - const Type *AccessTy = cast(Ptr->getType())->getElementType(); + Type *AccessTy = cast(Ptr->getType())->getElementType(); AccessSize = AA->getTypeStoreSize(AccessTy); } @@ -188,12 +188,16 @@ Value *llvm::FindAvailableLoadedValue(Value *Ptr, BasicBlock *ScanBB, --ScanFrom; // If this is a load of Ptr, the loaded value is available. + // (This is true even if the load is volatile or atomic, although + // those cases are unlikely.) if (LoadInst *LI = dyn_cast(Inst)) if (AreEquivalentAddressValues(LI->getOperand(0), Ptr)) return LI; if (StoreInst *SI = dyn_cast(Inst)) { // If this is a store through Ptr, the value is available! + // (This is true even if the store is volatile or atomic, although + // those cases are unlikely.) if (AreEquivalentAddressValues(SI->getOperand(1), Ptr)) return SI->getOperand(0); diff --git a/lib/Analysis/LoopDependenceAnalysis.cpp b/lib/Analysis/LoopDependenceAnalysis.cpp index c1afe8fbd618..3997ac478b52 100644 --- a/lib/Analysis/LoopDependenceAnalysis.cpp +++ b/lib/Analysis/LoopDependenceAnalysis.cpp @@ -76,7 +76,13 @@ static void GetMemRefInstrs(const Loop *L, } static bool IsLoadOrStoreInst(Value *I) { - return isa(I) || isa(I); + // Returns true if the load or store can be analyzed. Atomic and volatile + // operations have properties which this analysis does not understand. + if (LoadInst *LI = dyn_cast(I)) + return LI->isUnordered(); + else if (StoreInst *SI = dyn_cast(I)) + return SI->isUnordered(); + return false; } static Value *GetPointerOperand(Value *I) { diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp index 05831402f409..85aaccaefc37 100644 --- a/lib/Analysis/LoopInfo.cpp +++ b/lib/Analysis/LoopInfo.cpp @@ -18,6 +18,7 @@ #include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/LoopIterator.h" #include "llvm/Assembly/Writer.h" #include "llvm/Support/CFG.h" #include "llvm/Support/CommandLine.h" @@ -55,12 +56,12 @@ bool Loop::isLoopInvariant(Value *V) const { } /// hasLoopInvariantOperands - Return true if all the operands of the -/// specified instruction are loop invariant. +/// specified instruction are loop invariant. bool Loop::hasLoopInvariantOperands(Instruction *I) const { for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) if (!isLoopInvariant(I->getOperand(i))) return false; - + return true; } @@ -98,6 +99,9 @@ bool Loop::makeLoopInvariant(Instruction *I, bool &Changed, return false; if (I->mayReadFromMemory()) return false; + // The landingpad instruction is immobile. + if (isa(I)) + return false; // Determine the insertion point, unless one was given. if (!InsertPt) { BasicBlock *Preheader = getLoopPreheader(); @@ -110,7 +114,7 @@ bool Loop::makeLoopInvariant(Instruction *I, bool &Changed, for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) if (!makeLoopInvariant(I->getOperand(i), Changed, InsertPt)) return false; - + // Hoist. I->moveBefore(InsertPt); Changed = true; @@ -382,6 +386,205 @@ void Loop::dump() const { print(dbgs()); } +//===----------------------------------------------------------------------===// +// UnloopUpdater implementation +// + +namespace { +/// Find the new parent loop for all blocks within the "unloop" whose last +/// backedges has just been removed. +class UnloopUpdater { + Loop *Unloop; + LoopInfo *LI; + + LoopBlocksDFS DFS; + + // Map unloop's immediate subloops to their nearest reachable parents. Nested + // loops within these subloops will not change parents. However, an immediate + // subloop's new parent will be the nearest loop reachable from either its own + // exits *or* any of its nested loop's exits. + DenseMap SubloopParents; + + // Flag the presence of an irreducible backedge whose destination is a block + // directly contained by the original unloop. + bool FoundIB; + +public: + UnloopUpdater(Loop *UL, LoopInfo *LInfo) : + Unloop(UL), LI(LInfo), DFS(UL), FoundIB(false) {} + + void updateBlockParents(); + + void removeBlocksFromAncestors(); + + void updateSubloopParents(); + +protected: + Loop *getNearestLoop(BasicBlock *BB, Loop *BBLoop); +}; +} // end anonymous namespace + +/// updateBlockParents - Update the parent loop for all blocks that are directly +/// contained within the original "unloop". +void UnloopUpdater::updateBlockParents() { + if (Unloop->getNumBlocks()) { + // Perform a post order CFG traversal of all blocks within this loop, + // propagating the nearest loop from sucessors to predecessors. + LoopBlocksTraversal Traversal(DFS, LI); + for (LoopBlocksTraversal::POTIterator POI = Traversal.begin(), + POE = Traversal.end(); POI != POE; ++POI) { + + Loop *L = LI->getLoopFor(*POI); + Loop *NL = getNearestLoop(*POI, L); + + if (NL != L) { + // For reducible loops, NL is now an ancestor of Unloop. + assert((NL != Unloop && (!NL || NL->contains(Unloop))) && + "uninitialized successor"); + LI->changeLoopFor(*POI, NL); + } + else { + // Or the current block is part of a subloop, in which case its parent + // is unchanged. + assert((FoundIB || Unloop->contains(L)) && "uninitialized successor"); + } + } + } + // Each irreducible loop within the unloop induces a round of iteration using + // the DFS result cached by Traversal. + bool Changed = FoundIB; + for (unsigned NIters = 0; Changed; ++NIters) { + assert(NIters < Unloop->getNumBlocks() && "runaway iterative algorithm"); + + // Iterate over the postorder list of blocks, propagating the nearest loop + // from successors to predecessors as before. + Changed = false; + for (LoopBlocksDFS::POIterator POI = DFS.beginPostorder(), + POE = DFS.endPostorder(); POI != POE; ++POI) { + + Loop *L = LI->getLoopFor(*POI); + Loop *NL = getNearestLoop(*POI, L); + if (NL != L) { + assert(NL != Unloop && (!NL || NL->contains(Unloop)) && + "uninitialized successor"); + LI->changeLoopFor(*POI, NL); + Changed = true; + } + } + } +} + +/// removeBlocksFromAncestors - Remove unloop's blocks from all ancestors below +/// their new parents. +void UnloopUpdater::removeBlocksFromAncestors() { + // Remove unloop's blocks from all ancestors below their new parents. + for (Loop::block_iterator BI = Unloop->block_begin(), + BE = Unloop->block_end(); BI != BE; ++BI) { + Loop *NewParent = LI->getLoopFor(*BI); + // If this block is an immediate subloop, remove all blocks (including + // nested subloops) from ancestors below the new parent loop. + // Otherwise, if this block is in a nested subloop, skip it. + if (SubloopParents.count(NewParent)) + NewParent = SubloopParents[NewParent]; + else if (Unloop->contains(NewParent)) + continue; + + // Remove blocks from former Ancestors except Unloop itself which will be + // deleted. + for (Loop *OldParent = Unloop->getParentLoop(); OldParent != NewParent; + OldParent = OldParent->getParentLoop()) { + assert(OldParent && "new loop is not an ancestor of the original"); + OldParent->removeBlockFromLoop(*BI); + } + } +} + +/// updateSubloopParents - Update the parent loop for all subloops directly +/// nested within unloop. +void UnloopUpdater::updateSubloopParents() { + while (!Unloop->empty()) { + Loop *Subloop = *llvm::prior(Unloop->end()); + Unloop->removeChildLoop(llvm::prior(Unloop->end())); + + assert(SubloopParents.count(Subloop) && "DFS failed to visit subloop"); + if (SubloopParents[Subloop]) + SubloopParents[Subloop]->addChildLoop(Subloop); + else + LI->addTopLevelLoop(Subloop); + } +} + +/// getNearestLoop - Return the nearest parent loop among this block's +/// successors. If a successor is a subloop header, consider its parent to be +/// the nearest parent of the subloop's exits. +/// +/// For subloop blocks, simply update SubloopParents and return NULL. +Loop *UnloopUpdater::getNearestLoop(BasicBlock *BB, Loop *BBLoop) { + + // Initially for blocks directly contained by Unloop, NearLoop == Unloop and + // is considered uninitialized. + Loop *NearLoop = BBLoop; + + Loop *Subloop = 0; + if (NearLoop != Unloop && Unloop->contains(NearLoop)) { + Subloop = NearLoop; + // Find the subloop ancestor that is directly contained within Unloop. + while (Subloop->getParentLoop() != Unloop) { + Subloop = Subloop->getParentLoop(); + assert(Subloop && "subloop is not an ancestor of the original loop"); + } + // Get the current nearest parent of the Subloop exits, initially Unloop. + if (!SubloopParents.count(Subloop)) + SubloopParents[Subloop] = Unloop; + NearLoop = SubloopParents[Subloop]; + } + + succ_iterator I = succ_begin(BB), E = succ_end(BB); + if (I == E) { + assert(!Subloop && "subloop blocks must have a successor"); + NearLoop = 0; // unloop blocks may now exit the function. + } + for (; I != E; ++I) { + if (*I == BB) + continue; // self loops are uninteresting + + Loop *L = LI->getLoopFor(*I); + if (L == Unloop) { + // This successor has not been processed. This path must lead to an + // irreducible backedge. + assert((FoundIB || !DFS.hasPostorder(*I)) && "should have seen IB"); + FoundIB = true; + } + if (L != Unloop && Unloop->contains(L)) { + // Successor is in a subloop. + if (Subloop) + continue; // Branching within subloops. Ignore it. + + // BB branches from the original into a subloop header. + assert(L->getParentLoop() == Unloop && "cannot skip into nested loops"); + + // Get the current nearest parent of the Subloop's exits. + L = SubloopParents[L]; + // L could be Unloop if the only exit was an irreducible backedge. + } + if (L == Unloop) { + continue; + } + // Handle critical edges from Unloop into a sibling loop. + if (L && !L->contains(Unloop)) { + L = L->getParentLoop(); + } + // Remember the nearest parent loop among successors or subloop exits. + if (NearLoop == Unloop || !NearLoop || NearLoop->contains(L)) + NearLoop = L; + } + if (Subloop) { + SubloopParents[Subloop] = NearLoop; + return BBLoop; + } + return NearLoop; +} + //===----------------------------------------------------------------------===// // LoopInfo implementation // @@ -391,6 +594,68 @@ bool LoopInfo::runOnFunction(Function &) { return false; } +/// updateUnloop - The last backedge has been removed from a loop--now the +/// "unloop". Find a new parent for the blocks contained within unloop and +/// update the loop tree. We don't necessarily have valid dominators at this +/// point, but LoopInfo is still valid except for the removal of this loop. +/// +/// Note that Unloop may now be an empty loop. Calling Loop::getHeader without +/// checking first is illegal. +void LoopInfo::updateUnloop(Loop *Unloop) { + + // First handle the special case of no parent loop to simplify the algorithm. + if (!Unloop->getParentLoop()) { + // Since BBLoop had no parent, Unloop blocks are no longer in a loop. + for (Loop::block_iterator I = Unloop->block_begin(), + E = Unloop->block_end(); I != E; ++I) { + + // Don't reparent blocks in subloops. + if (getLoopFor(*I) != Unloop) + continue; + + // Blocks no longer have a parent but are still referenced by Unloop until + // the Unloop object is deleted. + LI.changeLoopFor(*I, 0); + } + + // Remove the loop from the top-level LoopInfo object. + for (LoopInfo::iterator I = LI.begin();; ++I) { + assert(I != LI.end() && "Couldn't find loop"); + if (*I == Unloop) { + LI.removeLoop(I); + break; + } + } + + // Move all of the subloops to the top-level. + while (!Unloop->empty()) + LI.addTopLevelLoop(Unloop->removeChildLoop(llvm::prior(Unloop->end()))); + + return; + } + + // Update the parent loop for all blocks within the loop. Blocks within + // subloops will not change parents. + UnloopUpdater Updater(Unloop, this); + Updater.updateBlockParents(); + + // Remove blocks from former ancestor loops. + Updater.removeBlocksFromAncestors(); + + // Add direct subloops as children in their new parent loop. + Updater.updateSubloopParents(); + + // Remove unloop from its parent loop. + Loop *ParentLoop = Unloop->getParentLoop(); + for (Loop::iterator I = ParentLoop->begin();; ++I) { + assert(I != ParentLoop->end() && "Couldn't find loop"); + if (*I == Unloop) { + ParentLoop->removeChildLoop(I); + break; + } + } +} + void LoopInfo::verifyAnalysis() const { // LoopInfo is a FunctionPass, but verifying every loop in the function // each time verifyAnalysis is called is very expensive. The @@ -400,12 +665,21 @@ void LoopInfo::verifyAnalysis() const { if (!VerifyLoopInfo) return; + DenseSet Loops; for (iterator I = begin(), E = end(); I != E; ++I) { assert(!(*I)->getParentLoop() && "Top-level loop has a parent!"); - (*I)->verifyLoopNest(); + (*I)->verifyLoopNest(&Loops); } - // TODO: check BBMap consistency. + // Verify that blocks are mapped to valid loops. + // + // FIXME: With an up-to-date DFS (see LoopIterator.h) and DominatorTree, we + // could also verify that the blocks are still in the correct loops. + for (DenseMap::const_iterator I = LI.BBMap.begin(), + E = LI.BBMap.end(); I != E; ++I) { + assert(Loops.count(I->second) && "orphaned loop"); + assert(I->second->contains(I->first) && "orphaned block"); + } } void LoopInfo::getAnalysisUsage(AnalysisUsage &AU) const { @@ -417,3 +691,15 @@ void LoopInfo::print(raw_ostream &OS, const Module*) const { LI.print(OS); } +//===----------------------------------------------------------------------===// +// LoopBlocksDFS implementation +// + +/// Traverse the loop blocks and store the DFS result. +/// Useful for clients that just want the final DFS result and don't need to +/// visit blocks during the initial traversal. +void LoopBlocksDFS::perform(LoopInfo *LI) { + LoopBlocksTraversal Traversal(*this, LI); + for (LoopBlocksTraversal::POTIterator POI = Traversal.begin(), + POE = Traversal.end(); POI != POE; ++POI) ; +} diff --git a/lib/Analysis/LoopPass.cpp b/lib/Analysis/LoopPass.cpp index 10e3f297f9c5..5ba1f4045d1a 100644 --- a/lib/Analysis/LoopPass.cpp +++ b/lib/Analysis/LoopPass.cpp @@ -59,9 +59,9 @@ char PrintLoopPass::ID = 0; static DebugInfoProbeInfo *TheDebugProbe; static void createDebugInfoProbe() { if (TheDebugProbe) return; - - // Constructed the first time this is called. This guarantees that the - // object will be constructed, if -enable-debug-info-probe is set, + + // Constructed the first time this is called. This guarantees that the + // object will be constructed, if -enable-debug-info-probe is set, // before static globals, thus it will be destroyed before them. static ManagedStatic DIP; TheDebugProbe = &*DIP; @@ -73,73 +73,29 @@ static void createDebugInfoProbe() { char LPPassManager::ID = 0; -LPPassManager::LPPassManager(int Depth) - : FunctionPass(ID), PMDataManager(Depth) { +LPPassManager::LPPassManager() + : FunctionPass(ID), PMDataManager() { skipThisLoop = false; redoThisLoop = false; LI = NULL; CurrentLoop = NULL; } -/// Delete loop from the loop queue and loop hierarchy (LoopInfo). +/// Delete loop from the loop queue and loop hierarchy (LoopInfo). void LPPassManager::deleteLoopFromQueue(Loop *L) { - if (Loop *ParentLoop = L->getParentLoop()) { // Not a top-level loop. - // Reparent all of the blocks in this loop. Since BBLoop had a parent, - // they are now all in it. - for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); - I != E; ++I) - if (LI->getLoopFor(*I) == L) // Don't change blocks in subloops. - LI->changeLoopFor(*I, ParentLoop); - - // Remove the loop from its parent loop. - for (Loop::iterator I = ParentLoop->begin(), E = ParentLoop->end();; - ++I) { - assert(I != E && "Couldn't find loop"); - if (*I == L) { - ParentLoop->removeChildLoop(I); - break; - } - } - - // Move all subloops into the parent loop. - while (!L->empty()) - ParentLoop->addChildLoop(L->removeChildLoop(L->end()-1)); - } else { - // Reparent all of the blocks in this loop. Since BBLoop had no parent, - // they no longer in a loop at all. - - for (unsigned i = 0; i != L->getBlocks().size(); ++i) { - // Don't change blocks in subloops. - if (LI->getLoopFor(L->getBlocks()[i]) == L) { - LI->removeBlock(L->getBlocks()[i]); - --i; - } - } - - // Remove the loop from the top-level LoopInfo object. - for (LoopInfo::iterator I = LI->begin(), E = LI->end();; ++I) { - assert(I != E && "Couldn't find loop"); - if (*I == L) { - LI->removeLoop(I); - break; - } - } - - // Move all of the subloops to the top-level. - while (!L->empty()) - LI->addTopLevelLoop(L->removeChildLoop(L->end()-1)); - } - - delete L; + LI->updateUnloop(L); // If L is current loop then skip rest of the passes and let // runOnFunction remove L from LQ. Otherwise, remove L from LQ now // and continue applying other passes on CurrentLoop. - if (CurrentLoop == L) { + if (CurrentLoop == L) skipThisLoop = true; + + delete L; + + if (skipThisLoop) return; - } for (std::deque::iterator I = LQ.begin(), E = LQ.end(); I != E; ++I) { @@ -166,10 +122,10 @@ void LPPassManager::insertLoop(Loop *L, Loop *ParentLoop) { void LPPassManager::insertLoopIntoQueue(Loop *L) { // Insert L into loop queue - if (L == CurrentLoop) + if (L == CurrentLoop) redoLoop(L); else if (!L->getParentLoop()) - // This is top level loop. + // This is top level loop. LQ.push_front(L); else { // Insert L after the parent loop. @@ -195,9 +151,9 @@ void LPPassManager::redoLoop(Loop *L) { /// cloneBasicBlockSimpleAnalysis - Invoke cloneBasicBlockAnalysis hook for /// all loop passes. -void LPPassManager::cloneBasicBlockSimpleAnalysis(BasicBlock *From, +void LPPassManager::cloneBasicBlockSimpleAnalysis(BasicBlock *From, BasicBlock *To, Loop *L) { - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { LoopPass *LP = getContainedPass(Index); LP->cloneBasicBlockAnalysis(From, To, L); } @@ -206,13 +162,13 @@ void LPPassManager::cloneBasicBlockSimpleAnalysis(BasicBlock *From, /// deleteSimpleAnalysisValue - Invoke deleteAnalysisValue hook for all passes. void LPPassManager::deleteSimpleAnalysisValue(Value *V, Loop *L) { if (BasicBlock *BB = dyn_cast(V)) { - for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; + for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI) { Instruction &I = *BI; deleteSimpleAnalysisValue(&I, L); } } - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { LoopPass *LP = getContainedPass(Index); LP->deleteAnalysisValue(V, L); } @@ -228,7 +184,7 @@ static void addLoopIntoQueue(Loop *L, std::deque &LQ) { /// Pass Manager itself does not invalidate any analysis info. void LPPassManager::getAnalysisUsage(AnalysisUsage &Info) const { - // LPPassManager needs LoopInfo. In the long term LoopInfo class will + // LPPassManager needs LoopInfo. In the long term LoopInfo class will // become part of LPPassManager. Info.addRequired(); Info.setPreservesAll(); @@ -255,7 +211,7 @@ bool LPPassManager::runOnFunction(Function &F) { for (std::deque::const_iterator I = LQ.begin(), E = LQ.end(); I != E; ++I) { Loop *L = *I; - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { LoopPass *P = getContainedPass(Index); Changed |= P->doInitialization(L, *this); } @@ -263,13 +219,13 @@ bool LPPassManager::runOnFunction(Function &F) { // Walk Loops while (!LQ.empty()) { - + CurrentLoop = LQ.back(); skipThisLoop = false; redoThisLoop = false; // Run all passes on the current Loop. - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { LoopPass *P = getContainedPass(Index); dumpPassInfo(P, EXECUTION_MSG, ON_LOOP_MSG, CurrentLoop->getHeader()->getName()); @@ -319,23 +275,23 @@ bool LPPassManager::runOnFunction(Function &F) { // Do not run other passes on this loop. break; } - + // If the loop was deleted, release all the loop passes. This frees up // some memory, and avoids trouble with the pass manager trying to call // verifyAnalysis on them. if (skipThisLoop) - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { + for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { Pass *P = getContainedPass(Index); freePass(P, "", ON_LOOP_MSG); } // Pop the loop from queue after running all passes. LQ.pop_back(); - + if (redoThisLoop) LQ.push_back(CurrentLoop); } - + // Finalization for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { LoopPass *P = getContainedPass(Index); @@ -372,7 +328,7 @@ Pass *LoopPass::createPrinterPass(raw_ostream &O, // LPPassManger as expected. void LoopPass::preparePassManager(PMStack &PMS) { - // Find LPPassManager + // Find LPPassManager while (!PMS.empty() && PMS.top()->getPassManagerType() > PMT_LoopPassManager) PMS.pop(); @@ -381,14 +337,14 @@ void LoopPass::preparePassManager(PMStack &PMS) { // by other passes that are managed by LPM then do not insert // this pass in current LPM. Use new LPPassManager. if (PMS.top()->getPassManagerType() == PMT_LoopPassManager && - !PMS.top()->preserveHigherLevelAnalysis(this)) + !PMS.top()->preserveHigherLevelAnalysis(this)) PMS.pop(); } /// Assign pass manager to manage this pass. void LoopPass::assignPassManager(PMStack &PMS, PassManagerType PreferredType) { - // Find LPPassManager + // Find LPPassManager while (!PMS.empty() && PMS.top()->getPassManagerType() > PMT_LoopPassManager) PMS.pop(); @@ -397,12 +353,12 @@ void LoopPass::assignPassManager(PMStack &PMS, if (PMS.top()->getPassManagerType() == PMT_LoopPassManager) LPPM = (LPPassManager*)PMS.top(); else { - // Create new Loop Pass Manager if it does not exist. + // Create new Loop Pass Manager if it does not exist. assert (!PMS.empty() && "Unable to create Loop Pass Manager"); PMDataManager *PMD = PMS.top(); - // [1] Create new Call Graph Pass Manager - LPPM = new LPPassManager(PMD->getDepth() + 1); + // [1] Create new Loop Pass Manager + LPPM = new LPPassManager(); LPPM->populateInheritedAnalysis(PMS); // [2] Set up new manager's top level manager diff --git a/lib/Analysis/MemDepPrinter.cpp b/lib/Analysis/MemDepPrinter.cpp index 2283db0bc482..fde07ea4f98d 100644 --- a/lib/Analysis/MemDepPrinter.cpp +++ b/lib/Analysis/MemDepPrinter.cpp @@ -25,8 +25,17 @@ namespace { struct MemDepPrinter : public FunctionPass { const Function *F; - typedef PointerIntPair InstAndClobberFlag; - typedef std::pair Dep; + enum DepType { + Clobber = 0, + Def, + NonFuncLocal, + Unknown + }; + + static const char* DepTypeStr[]; + + typedef PointerIntPair InstTypePair; + typedef std::pair Dep; typedef SmallSetVector DepSet; typedef DenseMap DepSetMap; DepSetMap Deps; @@ -50,6 +59,21 @@ namespace { Deps.clear(); F = 0; } + + private: + static InstTypePair getInstTypePair(MemDepResult dep) { + if (dep.isClobber()) + return InstTypePair(dep.getInst(), Clobber); + if (dep.isDef()) + return InstTypePair(dep.getInst(), Def); + if (dep.isNonFuncLocal()) + return InstTypePair(dep.getInst(), NonFuncLocal); + assert(dep.isUnknown() && "unexptected dependence type"); + return InstTypePair(dep.getInst(), Unknown); + } + static InstTypePair getInstTypePair(const Instruction* inst, DepType type) { + return InstTypePair(inst, type); + } }; } @@ -64,6 +88,9 @@ FunctionPass *llvm::createMemDepPrinter() { return new MemDepPrinter(); } +const char* MemDepPrinter::DepTypeStr[] + = {"Clobber", "Def", "NonFuncLocal", "Unknown"}; + bool MemDepPrinter::runOnFunction(Function &F) { this->F = &F; AliasAnalysis &AA = getAnalysis(); @@ -79,10 +106,7 @@ bool MemDepPrinter::runOnFunction(Function &F) { MemDepResult Res = MDA.getDependency(Inst); if (!Res.isNonLocal()) { - assert((Res.isUnknown() || Res.isClobber() || Res.isDef()) && - "Local dep should be unknown, def or clobber!"); - Deps[Inst].insert(std::make_pair(InstAndClobberFlag(Res.getInst(), - Res.isClobber()), + Deps[Inst].insert(std::make_pair(getInstTypePair(Res), static_cast(0))); } else if (CallSite CS = cast(Inst)) { const MemoryDependenceAnalysis::NonLocalDepInfo &NLDI = @@ -92,22 +116,26 @@ bool MemDepPrinter::runOnFunction(Function &F) { for (MemoryDependenceAnalysis::NonLocalDepInfo::const_iterator I = NLDI.begin(), E = NLDI.end(); I != E; ++I) { const MemDepResult &Res = I->getResult(); - assert((Res.isUnknown() || Res.isClobber() || Res.isDef()) && - "Resolved non-local call dep should be unknown, def or " - "clobber!"); - InstDeps.insert(std::make_pair(InstAndClobberFlag(Res.getInst(), - Res.isClobber()), - I->getBB())); + InstDeps.insert(std::make_pair(getInstTypePair(Res), I->getBB())); } } else { SmallVector NLDI; if (LoadInst *LI = dyn_cast(Inst)) { - // FIXME: Volatile is not handled properly here. + if (!LI->isUnordered()) { + // FIXME: Handle atomic/volatile loads. + Deps[Inst].insert(std::make_pair(getInstTypePair(0, Unknown), + static_cast(0))); + continue; + } AliasAnalysis::Location Loc = AA.getLocation(LI); - MDA.getNonLocalPointerDependency(Loc, !LI->isVolatile(), - LI->getParent(), NLDI); + MDA.getNonLocalPointerDependency(Loc, true, LI->getParent(), NLDI); } else if (StoreInst *SI = dyn_cast(Inst)) { - // FIXME: Volatile is not handled properly here. + if (!LI->isUnordered()) { + // FIXME: Handle atomic/volatile stores. + Deps[Inst].insert(std::make_pair(getInstTypePair(0, Unknown), + static_cast(0))); + continue; + } AliasAnalysis::Location Loc = AA.getLocation(SI); MDA.getNonLocalPointerDependency(Loc, false, SI->getParent(), NLDI); } else if (VAArgInst *VI = dyn_cast(Inst)) { @@ -121,11 +149,7 @@ bool MemDepPrinter::runOnFunction(Function &F) { for (SmallVectorImpl::const_iterator I = NLDI.begin(), E = NLDI.end(); I != E; ++I) { const MemDepResult &Res = I->getResult(); - assert(Res.isClobber() != Res.isDef() && - "Resolved non-local pointer dep should be def or clobber!"); - InstDeps.insert(std::make_pair(InstAndClobberFlag(Res.getInst(), - Res.isClobber()), - I->getBB())); + InstDeps.insert(std::make_pair(getInstTypePair(Res), I->getBB())); } } } @@ -146,26 +170,18 @@ void MemDepPrinter::print(raw_ostream &OS, const Module *M) const { for (DepSet::const_iterator I = InstDeps.begin(), E = InstDeps.end(); I != E; ++I) { const Instruction *DepInst = I->first.getPointer(); - bool isClobber = I->first.getInt(); + DepType type = I->first.getInt(); const BasicBlock *DepBB = I->second; OS << " "; - if (!DepInst) - OS << "Unknown"; - else if (isClobber) - OS << "Clobber"; - else - OS << " Def"; + OS << DepTypeStr[type]; if (DepBB) { OS << " in block "; WriteAsOperand(OS, DepBB, /*PrintType=*/false, M); } if (DepInst) { OS << " from: "; - if (DepInst == Inst) - OS << ""; - else - DepInst->print(OS); + DepInst->print(OS); } OS << "\n"; } diff --git a/lib/Analysis/MemoryBuiltins.cpp b/lib/Analysis/MemoryBuiltins.cpp index 53d430491198..8d451c46f9b0 100644 --- a/lib/Analysis/MemoryBuiltins.cpp +++ b/lib/Analysis/MemoryBuiltins.cpp @@ -47,7 +47,7 @@ static bool isMallocCall(const CallInst *CI) { // Check malloc prototype. // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin // attribute will exist. - const FunctionType *FTy = Callee->getFunctionType(); + FunctionType *FTy = Callee->getFunctionType(); if (FTy->getNumParams() != 1) return false; return FTy->getParamType(0)->isIntegerTy(32) || @@ -94,12 +94,12 @@ static Value *computeArraySize(const CallInst *CI, const TargetData *TD, return NULL; // The size of the malloc's result type must be known to determine array size. - const Type *T = getMallocAllocatedType(CI); + Type *T = getMallocAllocatedType(CI); if (!T || !T->isSized() || !TD) return NULL; unsigned ElementSize = TD->getTypeAllocSize(T); - if (const StructType *ST = dyn_cast(T)) + if (StructType *ST = dyn_cast(T)) ElementSize = TD->getStructLayout(ST)->getSizeInBytes(); // If malloc call's arg can be determined to be a multiple of ElementSize, @@ -133,10 +133,10 @@ const CallInst *llvm::isArrayMalloc(const Value *I, const TargetData *TD) { /// 0: PointerType is the calls' return type. /// 1: PointerType is the bitcast's result type. /// >1: Unique PointerType cannot be determined, return NULL. -const PointerType *llvm::getMallocType(const CallInst *CI) { +PointerType *llvm::getMallocType(const CallInst *CI) { assert(isMalloc(CI) && "getMallocType and not malloc call"); - const PointerType *MallocType = NULL; + PointerType *MallocType = NULL; unsigned NumOfBitCastUses = 0; // Determine if CallInst has a bitcast use. @@ -164,8 +164,8 @@ const PointerType *llvm::getMallocType(const CallInst *CI) { /// 0: PointerType is the malloc calls' return type. /// 1: PointerType is the bitcast's result type. /// >1: Unique PointerType cannot be determined, return NULL. -const Type *llvm::getMallocAllocatedType(const CallInst *CI) { - const PointerType *PT = getMallocType(CI); +Type *llvm::getMallocAllocatedType(const CallInst *CI) { + PointerType *PT = getMallocType(CI); return PT ? PT->getElementType() : NULL; } @@ -201,7 +201,7 @@ const CallInst *llvm::isFreeCall(const Value *I) { // Check free prototype. // FIXME: workaround for PR5130, this will be obsolete when a nobuiltin // attribute will exist. - const FunctionType *FTy = Callee->getFunctionType(); + FunctionType *FTy = Callee->getFunctionType(); if (!FTy->getReturnType()->isVoidTy()) return 0; if (FTy->getNumParams() != 1) diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index bba4482f4da5..92967c08dc21 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -120,21 +120,27 @@ AliasAnalysis::ModRefResult GetLocation(const Instruction *Inst, AliasAnalysis::Location &Loc, AliasAnalysis *AA) { if (const LoadInst *LI = dyn_cast(Inst)) { - if (LI->isVolatile()) { - Loc = AliasAnalysis::Location(); + if (LI->isUnordered()) { + Loc = AA->getLocation(LI); + return AliasAnalysis::Ref; + } else if (LI->getOrdering() == Monotonic) { + Loc = AA->getLocation(LI); return AliasAnalysis::ModRef; } - Loc = AA->getLocation(LI); - return AliasAnalysis::Ref; + Loc = AliasAnalysis::Location(); + return AliasAnalysis::ModRef; } if (const StoreInst *SI = dyn_cast(Inst)) { - if (SI->isVolatile()) { - Loc = AliasAnalysis::Location(); + if (SI->isUnordered()) { + Loc = AA->getLocation(SI); + return AliasAnalysis::Mod; + } else if (SI->getOrdering() == Monotonic) { + Loc = AA->getLocation(SI); return AliasAnalysis::ModRef; } - Loc = AA->getLocation(SI); - return AliasAnalysis::Mod; + Loc = AliasAnalysis::Location(); + return AliasAnalysis::ModRef; } if (const VAArgInst *V = dyn_cast(Inst)) { @@ -232,7 +238,7 @@ getCallSiteDependencyFrom(CallSite CS, bool isReadOnlyCall, // unknown, otherwise it is non-local. if (BB != &BB->getParent()->getEntryBlock()) return MemDepResult::getNonLocal(); - return MemDepResult::getUnknown(); + return MemDepResult::getNonFuncLocal(); } /// isLoadLoadClobberIfExtendedToFullWidth - Return true if LI is a load that @@ -270,8 +276,8 @@ unsigned MemoryDependenceAnalysis:: getLoadLoadClobberFullWidthSize(const Value *MemLocBase, int64_t MemLocOffs, unsigned MemLocSize, const LoadInst *LI, const TargetData &TD) { - // We can only extend non-volatile integer loads. - if (!isa(LI->getType()) || LI->isVolatile()) return 0; + // We can only extend simple integer loads. + if (!isa(LI->getType()) || !LI->isSimple()) return 0; // Get the base of this load. int64_t LIOffs = 0; @@ -369,6 +375,11 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad, // Values depend on loads if the pointers are must aliased. This means that // a load depends on another must aliased load from the same value. if (LoadInst *LI = dyn_cast(Inst)) { + // Atomic loads have complications involved. + // FIXME: This is overly conservative. + if (!LI->isUnordered()) + return MemDepResult::getClobber(LI); + AliasAnalysis::Location LoadLoc = AA->getLocation(LI); // If we found a pointer, check if it could be the same as our pointer. @@ -382,7 +393,7 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad, // location is 1 byte at P+1). If so, return it as a load/load // clobber result, allowing the client to decide to widen the load if // it wants to. - if (const IntegerType *ITy = dyn_cast(LI->getType())) + if (IntegerType *ITy = dyn_cast(LI->getType())) if (LI->getAlignment()*8 > ITy->getPrimitiveSizeInBits() && isLoadLoadClobberIfExtendedToFullWidth(MemLoc, MemLocBase, MemLocOffset, LI, TD)) @@ -424,6 +435,11 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad, } if (StoreInst *SI = dyn_cast(Inst)) { + // Atomic stores have complications involved. + // FIXME: This is overly conservative. + if (!SI->isUnordered()) + return MemDepResult::getClobber(SI); + // If alias analysis can tell that this store is guaranteed to not modify // the query pointer, ignore it. Use getModRefInfo to handle cases where // the query pointer points to constant memory etc. @@ -483,7 +499,7 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad, // unknown, otherwise it is non-local. if (BB != &BB->getParent()->getEntryBlock()) return MemDepResult::getNonLocal(); - return MemDepResult::getUnknown(); + return MemDepResult::getNonFuncLocal(); } /// getDependency - Return the instruction on which a memory operation @@ -516,7 +532,7 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) { if (QueryParent != &QueryParent->getParent()->getEntryBlock()) LocalCache = MemDepResult::getNonLocal(); else - LocalCache = MemDepResult::getUnknown(); + LocalCache = MemDepResult::getNonFuncLocal(); } else { AliasAnalysis::Location MemLoc; AliasAnalysis::ModRefResult MR = GetLocation(QueryInst, MemLoc, AA); @@ -672,7 +688,7 @@ MemoryDependenceAnalysis::getNonLocalCallDependency(CallSite QueryCS) { // a clobber, otherwise it is unknown. Dep = MemDepResult::getNonLocal(); } else { - Dep = MemDepResult::getUnknown(); + Dep = MemDepResult::getNonFuncLocal(); } // If we had a dirty entry for the block, update it. Otherwise, just add @@ -790,7 +806,7 @@ GetNonLocalInfoForBlock(const AliasAnalysis::Location &Loc, // If the block has a dependency (i.e. it isn't completely transparent to // the value), remember the reverse association because we just added it // to Cache! - if (Dep.isNonLocal() || Dep.isUnknown()) + if (!Dep.isDef() && !Dep.isClobber()) return Dep; // Keep the ReverseNonLocalPtrDeps map up to date so we can efficiently diff --git a/lib/Analysis/PHITransAddr.cpp b/lib/Analysis/PHITransAddr.cpp index 70dcd0df242d..7e22ddc61c09 100644 --- a/lib/Analysis/PHITransAddr.cpp +++ b/lib/Analysis/PHITransAddr.cpp @@ -228,7 +228,7 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB, return GEP; // Simplify the GEP to handle 'gep x, 0' -> x etc. - if (Value *V = SimplifyGEPInst(&GEPOps[0], GEPOps.size(), TD, DT)) { + if (Value *V = SimplifyGEPInst(GEPOps, TD, DT)) { for (unsigned i = 0, e = GEPOps.size(); i != e; ++i) RemoveInstInputs(GEPOps[i], InstInputs); @@ -407,9 +407,9 @@ InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, } GetElementPtrInst *Result = - GetElementPtrInst::Create(GEPOps[0], GEPOps.begin()+1, GEPOps.end(), - InVal->getName()+".phi.trans.insert", - PredBB->getTerminator()); + GetElementPtrInst::Create(GEPOps[0], makeArrayRef(GEPOps).slice(1), + InVal->getName()+".phi.trans.insert", + PredBB->getTerminator()); Result->setIsInBounds(GEP->isInBounds()); NewInsts.push_back(Result); return Result; diff --git a/lib/Analysis/PathNumbering.cpp b/lib/Analysis/PathNumbering.cpp index 7c584daef734..0e3b6e69ce34 100644 --- a/lib/Analysis/PathNumbering.cpp +++ b/lib/Analysis/PathNumbering.cpp @@ -387,7 +387,7 @@ void BallLarusDag::buildNode(BLBlockNodeMap& inDag, BLNodeStack& dfsStack) { TerminatorInst* terminator = currentNode->getBlock()->getTerminator(); if(isa(terminator) || isa(terminator) - || isa(terminator)) + || isa(terminator) || isa(terminator)) addEdge(currentNode, getExit(),0); currentNode->setColor(BallLarusNode::GRAY); diff --git a/lib/Analysis/RegionPass.cpp b/lib/Analysis/RegionPass.cpp index 80eda79d8a42..3a3529baf93e 100644 --- a/lib/Analysis/RegionPass.cpp +++ b/lib/Analysis/RegionPass.cpp @@ -27,8 +27,8 @@ using namespace llvm; char RGPassManager::ID = 0; -RGPassManager::RGPassManager(int Depth) - : FunctionPass(ID), PMDataManager(Depth) { +RGPassManager::RGPassManager() + : FunctionPass(ID), PMDataManager() { skipThisRegion = false; redoThisRegion = false; RI = NULL; @@ -250,7 +250,7 @@ void RegionPass::assignPassManager(PMStack &PMS, PMDataManager *PMD = PMS.top(); // [1] Create new Region Pass Manager - RGPM = new RGPassManager(PMD->getDepth() + 1); + RGPM = new RGPassManager(); RGPM->populateInheritedAnalysis(PMS); // [2] Set up new manager's top level manager diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 025718e09feb..e0ac56c65e76 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -197,7 +197,7 @@ void SCEV::print(raw_ostream &OS) const { } case scUnknown: { const SCEVUnknown *U = cast(this); - const Type *AllocTy; + Type *AllocTy; if (U->isSizeOf(AllocTy)) { OS << "sizeof(" << *AllocTy << ")"; return; @@ -207,7 +207,7 @@ void SCEV::print(raw_ostream &OS) const { return; } - const Type *CTy; + Type *CTy; Constant *FieldNo; if (U->isOffsetOf(CTy, FieldNo)) { OS << "offsetof(" << *CTy << ", "; @@ -228,7 +228,7 @@ void SCEV::print(raw_ostream &OS) const { llvm_unreachable("Unknown SCEV kind!"); } -const Type *SCEV::getType() const { +Type *SCEV::getType() const { switch (getSCEVType()) { case scConstant: return cast(this)->getType(); @@ -297,17 +297,17 @@ const SCEV *ScalarEvolution::getConstant(const APInt& Val) { } const SCEV * -ScalarEvolution::getConstant(const Type *Ty, uint64_t V, bool isSigned) { - const IntegerType *ITy = cast(getEffectiveSCEVType(Ty)); +ScalarEvolution::getConstant(Type *Ty, uint64_t V, bool isSigned) { + IntegerType *ITy = cast(getEffectiveSCEVType(Ty)); return getConstant(ConstantInt::get(ITy, V, isSigned)); } SCEVCastExpr::SCEVCastExpr(const FoldingSetNodeIDRef ID, - unsigned SCEVTy, const SCEV *op, const Type *ty) + unsigned SCEVTy, const SCEV *op, Type *ty) : SCEV(ID, SCEVTy), Op(op), Ty(ty) {} SCEVTruncateExpr::SCEVTruncateExpr(const FoldingSetNodeIDRef ID, - const SCEV *op, const Type *ty) + const SCEV *op, Type *ty) : SCEVCastExpr(ID, scTruncate, op, ty) { assert((Op->getType()->isIntegerTy() || Op->getType()->isPointerTy()) && (Ty->isIntegerTy() || Ty->isPointerTy()) && @@ -315,7 +315,7 @@ SCEVTruncateExpr::SCEVTruncateExpr(const FoldingSetNodeIDRef ID, } SCEVZeroExtendExpr::SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID, - const SCEV *op, const Type *ty) + const SCEV *op, Type *ty) : SCEVCastExpr(ID, scZeroExtend, op, ty) { assert((Op->getType()->isIntegerTy() || Op->getType()->isPointerTy()) && (Ty->isIntegerTy() || Ty->isPointerTy()) && @@ -323,7 +323,7 @@ SCEVZeroExtendExpr::SCEVZeroExtendExpr(const FoldingSetNodeIDRef ID, } SCEVSignExtendExpr::SCEVSignExtendExpr(const FoldingSetNodeIDRef ID, - const SCEV *op, const Type *ty) + const SCEV *op, Type *ty) : SCEVCastExpr(ID, scSignExtend, op, ty) { assert((Op->getType()->isIntegerTy() || Op->getType()->isPointerTy()) && (Ty->isIntegerTy() || Ty->isPointerTy()) && @@ -354,7 +354,7 @@ void SCEVUnknown::allUsesReplacedWith(Value *New) { setValPtr(New); } -bool SCEVUnknown::isSizeOf(const Type *&AllocTy) const { +bool SCEVUnknown::isSizeOf(Type *&AllocTy) const { if (ConstantExpr *VCE = dyn_cast(getValue())) if (VCE->getOpcode() == Instruction::PtrToInt) if (ConstantExpr *CE = dyn_cast(VCE->getOperand(0))) @@ -371,15 +371,15 @@ bool SCEVUnknown::isSizeOf(const Type *&AllocTy) const { return false; } -bool SCEVUnknown::isAlignOf(const Type *&AllocTy) const { +bool SCEVUnknown::isAlignOf(Type *&AllocTy) const { if (ConstantExpr *VCE = dyn_cast(getValue())) if (VCE->getOpcode() == Instruction::PtrToInt) if (ConstantExpr *CE = dyn_cast(VCE->getOperand(0))) if (CE->getOpcode() == Instruction::GetElementPtr && CE->getOperand(0)->isNullValue()) { - const Type *Ty = + Type *Ty = cast(CE->getOperand(0)->getType())->getElementType(); - if (const StructType *STy = dyn_cast(Ty)) + if (StructType *STy = dyn_cast(Ty)) if (!STy->isPacked() && CE->getNumOperands() == 3 && CE->getOperand(1)->isNullValue()) { @@ -396,7 +396,7 @@ bool SCEVUnknown::isAlignOf(const Type *&AllocTy) const { return false; } -bool SCEVUnknown::isOffsetOf(const Type *&CTy, Constant *&FieldNo) const { +bool SCEVUnknown::isOffsetOf(Type *&CTy, Constant *&FieldNo) const { if (ConstantExpr *VCE = dyn_cast(getValue())) if (VCE->getOpcode() == Instruction::PtrToInt) if (ConstantExpr *CE = dyn_cast(VCE->getOperand(0))) @@ -404,7 +404,7 @@ bool SCEVUnknown::isOffsetOf(const Type *&CTy, Constant *&FieldNo) const { CE->getNumOperands() == 3 && CE->getOperand(0)->isNullValue() && CE->getOperand(1)->isNullValue()) { - const Type *Ty = + Type *Ty = cast(CE->getOperand(0)->getType())->getElementType(); // Ignore vector types here so that ScalarEvolutionExpander doesn't // emit getelementptrs that index into vectors. @@ -652,7 +652,7 @@ static void GroupByComplexity(SmallVectorImpl &Ops, /// Assume, K > 0. static const SCEV *BinomialCoefficient(const SCEV *It, unsigned K, ScalarEvolution &SE, - const Type* ResultTy) { + Type *ResultTy) { // Handle the simplest case efficiently. if (K == 1) return SE.getTruncateOrZeroExtend(It, ResultTy); @@ -742,7 +742,7 @@ static const SCEV *BinomialCoefficient(const SCEV *It, unsigned K, MultiplyFactor = MultiplyFactor.trunc(W); // Calculate the product, at width T+W - const IntegerType *CalculationTy = IntegerType::get(SE.getContext(), + IntegerType *CalculationTy = IntegerType::get(SE.getContext(), CalculationBits); const SCEV *Dividend = SE.getTruncateOrZeroExtend(It, CalculationTy); for (unsigned i = 1; i != K; ++i) { @@ -790,7 +790,7 @@ const SCEV *SCEVAddRecExpr::evaluateAtIteration(const SCEV *It, //===----------------------------------------------------------------------===// const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op, - const Type *Ty) { + Type *Ty) { assert(getTypeSizeInBits(Op->getType()) > getTypeSizeInBits(Ty) && "This is not a truncating conversion!"); assert(isSCEVable(Ty) && @@ -877,7 +877,7 @@ const SCEV *ScalarEvolution::getTruncateExpr(const SCEV *Op, } const SCEV *ScalarEvolution::getZeroExtendExpr(const SCEV *Op, - const Type *Ty) { + Type *Ty) { assert(getTypeSizeInBits(Op->getType()) < getTypeSizeInBits(Ty) && "This is not an extending conversion!"); assert(isSCEVable(Ty) && @@ -954,7 +954,7 @@ const SCEV *ScalarEvolution::getZeroExtendExpr(const SCEV *Op, const SCEV *RecastedMaxBECount = getTruncateOrZeroExtend(CastedMaxBECount, MaxBECount->getType()); if (MaxBECount == RecastedMaxBECount) { - const Type *WideTy = IntegerType::get(getContext(), BitWidth * 2); + Type *WideTy = IntegerType::get(getContext(), BitWidth * 2); // Check whether Start+Step*MaxBECount has no unsigned overflow. const SCEV *ZMul = getMulExpr(CastedMaxBECount, Step); const SCEV *Add = getAddExpr(Start, ZMul); @@ -1062,7 +1062,7 @@ static const SCEV *getOverflowLimitForStep(const SCEV *Step, // result, the expression "Step + sext(PreIncAR)" is congruent with // "sext(PostIncAR)" static const SCEV *getPreStartForSignExtend(const SCEVAddRecExpr *AR, - const Type *Ty, + Type *Ty, ScalarEvolution *SE) { const Loop *L = AR->getLoop(); const SCEV *Start = AR->getStart(); @@ -1070,14 +1070,26 @@ static const SCEV *getPreStartForSignExtend(const SCEVAddRecExpr *AR, // Check for a simple looking step prior to loop entry. const SCEVAddExpr *SA = dyn_cast(Start); - if (!SA || SA->getNumOperands() != 2 || SA->getOperand(0) != Step) + if (!SA) + return 0; + + // Create an AddExpr for "PreStart" after subtracting Step. Full SCEV + // subtraction is expensive. For this purpose, perform a quick and dirty + // difference, by checking for Step in the operand list. + SmallVector DiffOps; + for (SCEVAddExpr::op_iterator I = SA->op_begin(), E = SA->op_end(); + I != E; ++I) { + if (*I != Step) + DiffOps.push_back(*I); + } + if (DiffOps.size() == SA->getNumOperands()) return 0; // This is a postinc AR. Check for overflow on the preinc recurrence using the // same three conditions that getSignExtendedExpr checks. // 1. NSW flags on the step increment. - const SCEV *PreStart = SA->getOperand(1); + const SCEV *PreStart = SE->getAddExpr(DiffOps, SA->getNoWrapFlags()); const SCEVAddRecExpr *PreAR = dyn_cast( SE->getAddRecExpr(PreStart, Step, L, SCEV::FlagAnyWrap)); @@ -1086,7 +1098,7 @@ static const SCEV *getPreStartForSignExtend(const SCEVAddRecExpr *AR, // 2. Direct overflow check on the step operation's expression. unsigned BitWidth = SE->getTypeSizeInBits(AR->getType()); - const Type *WideTy = IntegerType::get(SE->getContext(), BitWidth * 2); + Type *WideTy = IntegerType::get(SE->getContext(), BitWidth * 2); const SCEV *OperandExtendedStart = SE->getAddExpr(SE->getSignExtendExpr(PreStart, WideTy), SE->getSignExtendExpr(Step, WideTy)); @@ -1112,7 +1124,7 @@ static const SCEV *getPreStartForSignExtend(const SCEVAddRecExpr *AR, // Get the normalized sign-extended expression for this AddRec's Start. static const SCEV *getSignExtendAddRecStart(const SCEVAddRecExpr *AR, - const Type *Ty, + Type *Ty, ScalarEvolution *SE) { const SCEV *PreStart = getPreStartForSignExtend(AR, Ty, SE); if (!PreStart) @@ -1123,7 +1135,7 @@ static const SCEV *getSignExtendAddRecStart(const SCEVAddRecExpr *AR, } const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op, - const Type *Ty) { + Type *Ty) { assert(getTypeSizeInBits(Op->getType()) < getTypeSizeInBits(Ty) && "This is not an extending conversion!"); assert(isSCEVable(Ty) && @@ -1208,7 +1220,7 @@ const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op, const SCEV *RecastedMaxBECount = getTruncateOrZeroExtend(CastedMaxBECount, MaxBECount->getType()); if (MaxBECount == RecastedMaxBECount) { - const Type *WideTy = IntegerType::get(getContext(), BitWidth * 2); + Type *WideTy = IntegerType::get(getContext(), BitWidth * 2); // Check whether Start+Step*MaxBECount has no signed overflow. const SCEV *SMul = getMulExpr(CastedMaxBECount, Step); const SCEV *Add = getAddExpr(Start, SMul); @@ -1275,7 +1287,7 @@ const SCEV *ScalarEvolution::getSignExtendExpr(const SCEV *Op, /// unspecified bits out to the given type. /// const SCEV *ScalarEvolution::getAnyExtendExpr(const SCEV *Op, - const Type *Ty) { + Type *Ty) { assert(getTypeSizeInBits(Op->getType()) < getTypeSizeInBits(Ty) && "This is not an extending conversion!"); assert(isSCEVable(Ty) && @@ -1438,7 +1450,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl &Ops, assert(!Ops.empty() && "Cannot get empty add!"); if (Ops.size() == 1) return Ops[0]; #ifndef NDEBUG - const Type *ETy = getEffectiveSCEVType(Ops[0]->getType()); + Type *ETy = getEffectiveSCEVType(Ops[0]->getType()); for (unsigned i = 1, e = Ops.size(); i != e; ++i) assert(getEffectiveSCEVType(Ops[i]->getType()) == ETy && "SCEVAddExpr operand types don't match!"); @@ -1488,7 +1500,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl &Ops, // Okay, check to see if the same value occurs in the operand list more than // once. If so, merge them together into an multiply expression. Since we // sorted the list, these values are required to be adjacent. - const Type *Ty = Ops[0]->getType(); + Type *Ty = Ops[0]->getType(); bool FoundMatch = false; for (unsigned i = 0, e = Ops.size(); i != e-1; ++i) if (Ops[i] == Ops[i+1]) { // X + Y + Y --> X + Y*2 @@ -1515,8 +1527,8 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl &Ops, // if the contents of the resulting outer trunc fold to something simple. for (; Idx < Ops.size() && isa(Ops[Idx]); ++Idx) { const SCEVTruncateExpr *Trunc = cast(Ops[Idx]); - const Type *DstType = Trunc->getType(); - const Type *SrcType = Trunc->getOperand()->getType(); + Type *DstType = Trunc->getType(); + Type *SrcType = Trunc->getOperand()->getType(); SmallVector LargeOps; bool Ok = true; // Check all the operands to see if they can be represented in the @@ -1735,7 +1747,7 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl &Ops, // If all of the other operands were loop invariant, we are done. if (Ops.size() == 1) return NewRec; - // Otherwise, add the folded AddRec by the non-liv parts. + // Otherwise, add the folded AddRec by the non-invariant parts. for (unsigned i = 0;; ++i) if (Ops[i] == AddRec) { Ops[i] = NewRec; @@ -1800,6 +1812,38 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl &Ops, return S; } +static uint64_t umul_ov(uint64_t i, uint64_t j, bool &Overflow) { + uint64_t k = i*j; + if (j > 1 && k / j != i) Overflow = true; + return k; +} + +/// Compute the result of "n choose k", the binomial coefficient. If an +/// intermediate computation overflows, Overflow will be set and the return will +/// be garbage. Overflow is not cleared on absense of overflow. +static uint64_t Choose(uint64_t n, uint64_t k, bool &Overflow) { + // We use the multiplicative formula: + // n(n-1)(n-2)...(n-(k-1)) / k(k-1)(k-2)...1 . + // At each iteration, we take the n-th term of the numeral and divide by the + // (k-n)th term of the denominator. This division will always produce an + // integral result, and helps reduce the chance of overflow in the + // intermediate computations. However, we can still overflow even when the + // final result would fit. + + if (n == 0 || n == k) return 1; + if (k > n) return 0; + + if (k > n/2) + k = n-k; + + uint64_t r = 1; + for (uint64_t i = 1; i <= k; ++i) { + r = umul_ov(r, n-(i-1), Overflow); + r /= i; + } + return r; +} + /// getMulExpr - Get a canonical multiply expression, or something simpler if /// possible. const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl &Ops, @@ -1809,7 +1853,7 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl &Ops, assert(!Ops.empty() && "Cannot get empty mul!"); if (Ops.size() == 1) return Ops[0]; #ifndef NDEBUG - const Type *ETy = getEffectiveSCEVType(Ops[0]->getType()); + Type *ETy = getEffectiveSCEVType(Ops[0]->getType()); for (unsigned i = 1, e = Ops.size(); i != e; ++i) assert(getEffectiveSCEVType(Ops[i]->getType()) == ETy && "SCEVMulExpr operand types don't match!"); @@ -1960,7 +2004,7 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl &Ops, // If all of the other operands were loop invariant, we are done. if (Ops.size() == 1) return NewRec; - // Otherwise, multiply the folded AddRec by the non-liv parts. + // Otherwise, multiply the folded AddRec by the non-invariant parts. for (unsigned i = 0;; ++i) if (Ops[i] == AddRec) { Ops[i] = NewRec; @@ -1974,31 +2018,65 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl &Ops, // multiplied together. If so, we can fold them. for (unsigned OtherIdx = Idx+1; OtherIdx < Ops.size() && isa(Ops[OtherIdx]); - ++OtherIdx) + ++OtherIdx) { if (AddRecLoop == cast(Ops[OtherIdx])->getLoop()) { - // F * G, where F = {A,+,B} and G = {C,+,D} --> - // {A*C,+,F*D + G*B + B*D} + // {A1,+,A2,+,...,+,An} * {B1,+,B2,+,...,+,Bn} + // = {x=1 in [ sum y=x..2x [ sum z=max(y-x, y-n)..min(x,n) [ + // choose(x, 2x)*choose(2x-y, x-z)*A_{y-z}*B_z + // ]]],+,...up to x=2n}. + // Note that the arguments to choose() are always integers with values + // known at compile time, never SCEV objects. + // + // The implementation avoids pointless extra computations when the two + // addrec's are of different length (mathematically, it's equivalent to + // an infinite stream of zeros on the right). + bool OpsModified = false; for (; OtherIdx != Ops.size() && isa(Ops[OtherIdx]); ++OtherIdx) if (const SCEVAddRecExpr *OtherAddRec = dyn_cast(Ops[OtherIdx])) if (OtherAddRec->getLoop() == AddRecLoop) { - const SCEVAddRecExpr *F = AddRec, *G = OtherAddRec; - const SCEV *NewStart = getMulExpr(F->getStart(), G->getStart()); - const SCEV *B = F->getStepRecurrence(*this); - const SCEV *D = G->getStepRecurrence(*this); - const SCEV *NewStep = getAddExpr(getMulExpr(F, D), - getMulExpr(G, B), - getMulExpr(B, D)); - const SCEV *NewAddRec = getAddRecExpr(NewStart, NewStep, - F->getLoop(), - SCEV::FlagAnyWrap); - if (Ops.size() == 2) return NewAddRec; - Ops[Idx] = AddRec = cast(NewAddRec); - Ops.erase(Ops.begin() + OtherIdx); --OtherIdx; + bool Overflow = false; + Type *Ty = AddRec->getType(); + bool LargerThan64Bits = getTypeSizeInBits(Ty) > 64; + SmallVector AddRecOps; + for (int x = 0, xe = AddRec->getNumOperands() + + OtherAddRec->getNumOperands() - 1; + x != xe && !Overflow; ++x) { + const SCEV *Term = getConstant(Ty, 0); + for (int y = x, ye = 2*x+1; y != ye && !Overflow; ++y) { + uint64_t Coeff1 = Choose(x, 2*x - y, Overflow); + for (int z = std::max(y-x, y-(int)AddRec->getNumOperands()+1), + ze = std::min(x+1, (int)OtherAddRec->getNumOperands()); + z < ze && !Overflow; ++z) { + uint64_t Coeff2 = Choose(2*x - y, x-z, Overflow); + uint64_t Coeff; + if (LargerThan64Bits) + Coeff = umul_ov(Coeff1, Coeff2, Overflow); + else + Coeff = Coeff1*Coeff2; + const SCEV *CoeffTerm = getConstant(Ty, Coeff); + const SCEV *Term1 = AddRec->getOperand(y-z); + const SCEV *Term2 = OtherAddRec->getOperand(z); + Term = getAddExpr(Term, getMulExpr(CoeffTerm, Term1,Term2)); + } + } + AddRecOps.push_back(Term); + } + if (!Overflow) { + const SCEV *NewAddRec = getAddRecExpr(AddRecOps, + AddRec->getLoop(), + SCEV::FlagAnyWrap); + if (Ops.size() == 2) return NewAddRec; + Ops[Idx] = AddRec = cast(NewAddRec); + Ops.erase(Ops.begin() + OtherIdx); --OtherIdx; + OpsModified = true; + } } - return getMulExpr(Ops); + if (OpsModified) + return getMulExpr(Ops); } + } // Otherwise couldn't fold anything into this recurrence. Move onto the // next one. @@ -2042,21 +2120,22 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS, // Determine if the division can be folded into the operands of // its operands. // TODO: Generalize this to non-constants by using known-bits information. - const Type *Ty = LHS->getType(); + Type *Ty = LHS->getType(); unsigned LZ = RHSC->getValue()->getValue().countLeadingZeros(); unsigned MaxShiftAmt = getTypeSizeInBits(Ty) - LZ - 1; // For non-power-of-two values, effectively round the value up to the // nearest power of two. if (!RHSC->getValue()->getValue().isPowerOf2()) ++MaxShiftAmt; - const IntegerType *ExtTy = + IntegerType *ExtTy = IntegerType::get(getContext(), getTypeSizeInBits(Ty) + MaxShiftAmt); - // {X,+,N}/C --> {X/C,+,N/C} if safe and N/C can be folded. if (const SCEVAddRecExpr *AR = dyn_cast(LHS)) if (const SCEVConstant *Step = - dyn_cast(AR->getStepRecurrence(*this))) - if (!Step->getValue()->getValue() - .urem(RHSC->getValue()->getValue()) && + dyn_cast(AR->getStepRecurrence(*this))) { + // {X,+,N}/C --> {X/C,+,N/C} if safe and N/C can be folded. + const APInt &StepInt = Step->getValue()->getValue(); + const APInt &DivInt = RHSC->getValue()->getValue(); + if (!StepInt.urem(DivInt) && getZeroExtendExpr(AR, ExtTy) == getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy), getZeroExtendExpr(Step, ExtTy), @@ -2067,6 +2146,22 @@ const SCEV *ScalarEvolution::getUDivExpr(const SCEV *LHS, return getAddRecExpr(Operands, AR->getLoop(), SCEV::FlagNW); } + /// Get a canonical UDivExpr for a recurrence. + /// {X,+,N}/C => {Y,+,N}/C where Y=X-(X%N). Safe when C%N=0. + // We can currently only fold X%N if X is constant. + const SCEVConstant *StartC = dyn_cast(AR->getStart()); + if (StartC && !DivInt.urem(StepInt) && + getZeroExtendExpr(AR, ExtTy) == + getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy), + getZeroExtendExpr(Step, ExtTy), + AR->getLoop(), SCEV::FlagAnyWrap)) { + const APInt &StartInt = StartC->getValue()->getValue(); + const APInt &StartRem = StartInt.urem(StepInt); + if (StartRem != 0) + LHS = getAddRecExpr(getConstant(StartInt - StartRem), Step, + AR->getLoop(), SCEV::FlagNW); + } + } // (A*B)/C --> A*(B/C) if safe and B/C can be folded. if (const SCEVMulExpr *M = dyn_cast(LHS)) { SmallVector Operands; @@ -2151,7 +2246,7 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl &Operands, const Loop *L, SCEV::NoWrapFlags Flags) { if (Operands.size() == 1) return Operands[0]; #ifndef NDEBUG - const Type *ETy = getEffectiveSCEVType(Operands[0]->getType()); + Type *ETy = getEffectiveSCEVType(Operands[0]->getType()); for (unsigned i = 1, e = Operands.size(); i != e; ++i) assert(getEffectiveSCEVType(Operands[i]->getType()) == ETy && "SCEVAddRecExpr operand types don't match!"); @@ -2269,7 +2364,7 @@ ScalarEvolution::getSMaxExpr(SmallVectorImpl &Ops) { assert(!Ops.empty() && "Cannot get empty smax!"); if (Ops.size() == 1) return Ops[0]; #ifndef NDEBUG - const Type *ETy = getEffectiveSCEVType(Ops[0]->getType()); + Type *ETy = getEffectiveSCEVType(Ops[0]->getType()); for (unsigned i = 1, e = Ops.size(); i != e; ++i) assert(getEffectiveSCEVType(Ops[i]->getType()) == ETy && "SCEVSMaxExpr operand types don't match!"); @@ -2373,7 +2468,7 @@ ScalarEvolution::getUMaxExpr(SmallVectorImpl &Ops) { assert(!Ops.empty() && "Cannot get empty umax!"); if (Ops.size() == 1) return Ops[0]; #ifndef NDEBUG - const Type *ETy = getEffectiveSCEVType(Ops[0]->getType()); + Type *ETy = getEffectiveSCEVType(Ops[0]->getType()); for (unsigned i = 1, e = Ops.size(); i != e; ++i) assert(getEffectiveSCEVType(Ops[i]->getType()) == ETy && "SCEVUMaxExpr operand types don't match!"); @@ -2476,7 +2571,7 @@ const SCEV *ScalarEvolution::getUMinExpr(const SCEV *LHS, return getNotSCEV(getUMaxExpr(getNotSCEV(LHS), getNotSCEV(RHS))); } -const SCEV *ScalarEvolution::getSizeOfExpr(const Type *AllocTy) { +const SCEV *ScalarEvolution::getSizeOfExpr(Type *AllocTy) { // If we have TargetData, we can bypass creating a target-independent // constant expression and then folding it back into a ConstantInt. // This is just a compile-time optimization. @@ -2488,20 +2583,20 @@ const SCEV *ScalarEvolution::getSizeOfExpr(const Type *AllocTy) { if (ConstantExpr *CE = dyn_cast(C)) if (Constant *Folded = ConstantFoldConstantExpression(CE, TD)) C = Folded; - const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(AllocTy)); + Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(AllocTy)); return getTruncateOrZeroExtend(getSCEV(C), Ty); } -const SCEV *ScalarEvolution::getAlignOfExpr(const Type *AllocTy) { +const SCEV *ScalarEvolution::getAlignOfExpr(Type *AllocTy) { Constant *C = ConstantExpr::getAlignOf(AllocTy); if (ConstantExpr *CE = dyn_cast(C)) if (Constant *Folded = ConstantFoldConstantExpression(CE, TD)) C = Folded; - const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(AllocTy)); + Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(AllocTy)); return getTruncateOrZeroExtend(getSCEV(C), Ty); } -const SCEV *ScalarEvolution::getOffsetOfExpr(const StructType *STy, +const SCEV *ScalarEvolution::getOffsetOfExpr(StructType *STy, unsigned FieldNo) { // If we have TargetData, we can bypass creating a target-independent // constant expression and then folding it back into a ConstantInt. @@ -2514,17 +2609,17 @@ const SCEV *ScalarEvolution::getOffsetOfExpr(const StructType *STy, if (ConstantExpr *CE = dyn_cast(C)) if (Constant *Folded = ConstantFoldConstantExpression(CE, TD)) C = Folded; - const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(STy)); + Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(STy)); return getTruncateOrZeroExtend(getSCEV(C), Ty); } -const SCEV *ScalarEvolution::getOffsetOfExpr(const Type *CTy, +const SCEV *ScalarEvolution::getOffsetOfExpr(Type *CTy, Constant *FieldNo) { Constant *C = ConstantExpr::getOffsetOf(CTy, FieldNo); if (ConstantExpr *CE = dyn_cast(C)) if (Constant *Folded = ConstantFoldConstantExpression(CE, TD)) C = Folded; - const Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(CTy)); + Type *Ty = getEffectiveSCEVType(PointerType::getUnqual(CTy)); return getTruncateOrZeroExtend(getSCEV(C), Ty); } @@ -2558,14 +2653,14 @@ const SCEV *ScalarEvolution::getUnknown(Value *V) { /// the SCEV framework. This primarily includes integer types, and it /// can optionally include pointer types if the ScalarEvolution class /// has access to target-specific information. -bool ScalarEvolution::isSCEVable(const Type *Ty) const { +bool ScalarEvolution::isSCEVable(Type *Ty) const { // Integers and pointers are always SCEVable. return Ty->isIntegerTy() || Ty->isPointerTy(); } /// getTypeSizeInBits - Return the size in bits of the specified type, /// for which isSCEVable must return true. -uint64_t ScalarEvolution::getTypeSizeInBits(const Type *Ty) const { +uint64_t ScalarEvolution::getTypeSizeInBits(Type *Ty) const { assert(isSCEVable(Ty) && "Type is not SCEVable!"); // If we have a TargetData, use it! @@ -2586,7 +2681,7 @@ uint64_t ScalarEvolution::getTypeSizeInBits(const Type *Ty) const { /// the given type and which represents how SCEV will treat the given /// type, for which isSCEVable must return true. For pointer types, /// this is the pointer-sized integer type. -const Type *ScalarEvolution::getEffectiveSCEVType(const Type *Ty) const { +Type *ScalarEvolution::getEffectiveSCEVType(Type *Ty) const { assert(isSCEVable(Ty) && "Type is not SCEVable!"); if (Ty->isIntegerTy()) @@ -2628,7 +2723,7 @@ const SCEV *ScalarEvolution::getNegativeSCEV(const SCEV *V) { return getConstant( cast(ConstantExpr::getNeg(VC->getValue()))); - const Type *Ty = V->getType(); + Type *Ty = V->getType(); Ty = getEffectiveSCEVType(Ty); return getMulExpr(V, getConstant(cast(Constant::getAllOnesValue(Ty)))); @@ -2640,7 +2735,7 @@ const SCEV *ScalarEvolution::getNotSCEV(const SCEV *V) { return getConstant( cast(ConstantExpr::getNot(VC->getValue()))); - const Type *Ty = V->getType(); + Type *Ty = V->getType(); Ty = getEffectiveSCEVType(Ty); const SCEV *AllOnes = getConstant(cast(Constant::getAllOnesValue(Ty))); @@ -2664,8 +2759,8 @@ const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS, /// input value to the specified type. If the type must be extended, it is zero /// extended. const SCEV * -ScalarEvolution::getTruncateOrZeroExtend(const SCEV *V, const Type *Ty) { - const Type *SrcTy = V->getType(); +ScalarEvolution::getTruncateOrZeroExtend(const SCEV *V, Type *Ty) { + Type *SrcTy = V->getType(); assert((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) && (Ty->isIntegerTy() || Ty->isPointerTy()) && "Cannot truncate or zero extend with non-integer arguments!"); @@ -2681,8 +2776,8 @@ ScalarEvolution::getTruncateOrZeroExtend(const SCEV *V, const Type *Ty) { /// extended. const SCEV * ScalarEvolution::getTruncateOrSignExtend(const SCEV *V, - const Type *Ty) { - const Type *SrcTy = V->getType(); + Type *Ty) { + Type *SrcTy = V->getType(); assert((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) && (Ty->isIntegerTy() || Ty->isPointerTy()) && "Cannot truncate or zero extend with non-integer arguments!"); @@ -2697,8 +2792,8 @@ ScalarEvolution::getTruncateOrSignExtend(const SCEV *V, /// input value to the specified type. If the type must be extended, it is zero /// extended. The conversion must not be narrowing. const SCEV * -ScalarEvolution::getNoopOrZeroExtend(const SCEV *V, const Type *Ty) { - const Type *SrcTy = V->getType(); +ScalarEvolution::getNoopOrZeroExtend(const SCEV *V, Type *Ty) { + Type *SrcTy = V->getType(); assert((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) && (Ty->isIntegerTy() || Ty->isPointerTy()) && "Cannot noop or zero extend with non-integer arguments!"); @@ -2713,8 +2808,8 @@ ScalarEvolution::getNoopOrZeroExtend(const SCEV *V, const Type *Ty) { /// input value to the specified type. If the type must be extended, it is sign /// extended. The conversion must not be narrowing. const SCEV * -ScalarEvolution::getNoopOrSignExtend(const SCEV *V, const Type *Ty) { - const Type *SrcTy = V->getType(); +ScalarEvolution::getNoopOrSignExtend(const SCEV *V, Type *Ty) { + Type *SrcTy = V->getType(); assert((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) && (Ty->isIntegerTy() || Ty->isPointerTy()) && "Cannot noop or sign extend with non-integer arguments!"); @@ -2730,8 +2825,8 @@ ScalarEvolution::getNoopOrSignExtend(const SCEV *V, const Type *Ty) { /// it is extended with unspecified bits. The conversion must not be /// narrowing. const SCEV * -ScalarEvolution::getNoopOrAnyExtend(const SCEV *V, const Type *Ty) { - const Type *SrcTy = V->getType(); +ScalarEvolution::getNoopOrAnyExtend(const SCEV *V, Type *Ty) { + Type *SrcTy = V->getType(); assert((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) && (Ty->isIntegerTy() || Ty->isPointerTy()) && "Cannot noop or any extend with non-integer arguments!"); @@ -2745,8 +2840,8 @@ ScalarEvolution::getNoopOrAnyExtend(const SCEV *V, const Type *Ty) { /// getTruncateOrNoop - Return a SCEV corresponding to a conversion of the /// input value to the specified type. The conversion must not be widening. const SCEV * -ScalarEvolution::getTruncateOrNoop(const SCEV *V, const Type *Ty) { - const Type *SrcTy = V->getType(); +ScalarEvolution::getTruncateOrNoop(const SCEV *V, Type *Ty) { + Type *SrcTy = V->getType(); assert((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) && (Ty->isIntegerTy() || Ty->isPointerTy()) && "Cannot truncate or noop with non-integer arguments!"); @@ -3032,7 +3127,7 @@ const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) { // context. bool isInBounds = GEP->isInBounds(); - const Type *IntPtrTy = getEffectiveSCEVType(GEP->getType()); + Type *IntPtrTy = getEffectiveSCEVType(GEP->getType()); Value *Base = GEP->getOperand(0); // Don't attempt to analyze GEPs over unsized objects. if (!cast(Base->getType())->getElementType()->isSized()) @@ -3044,7 +3139,7 @@ const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) { I != E; ++I) { Value *Index = *I; // Compute the (potentially symbolic) offset in bytes for this index. - if (const StructType *STy = dyn_cast(*GTI++)) { + if (StructType *STy = dyn_cast(*GTI++)) { // For a struct, add the member offset. unsigned FieldNo = cast(Index)->getZExtValue(); const SCEV *FieldOffset = getOffsetOfExpr(STy, FieldNo); @@ -3244,7 +3339,7 @@ ScalarEvolution::getUnsignedRange(const SCEV *S) { // TODO: non-affine addrec if (AddRec->isAffine()) { - const Type *Ty = AddRec->getType(); + Type *Ty = AddRec->getType(); const SCEV *MaxBECount = getMaxBackedgeTakenCount(AddRec->getLoop()); if (!isa(MaxBECount) && getTypeSizeInBits(MaxBECount->getType()) <= BitWidth) { @@ -3396,7 +3491,7 @@ ScalarEvolution::getSignedRange(const SCEV *S) { // TODO: non-affine addrec if (AddRec->isAffine()) { - const Type *Ty = AddRec->getType(); + Type *Ty = AddRec->getType(); const SCEV *MaxBECount = getMaxBackedgeTakenCount(AddRec->getLoop()); if (!isa(MaxBECount) && getTypeSizeInBits(MaxBECount->getType()) <= BitWidth) { @@ -3503,7 +3598,13 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) { AddOps.push_back(Op1); } AddOps.push_back(getSCEV(U->getOperand(0))); - return getAddExpr(AddOps); + SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap; + OverflowingBinaryOperator *OBO = cast(V); + if (OBO->hasNoSignedWrap()) + setFlags(Flags, SCEV::FlagNSW); + if (OBO->hasNoUnsignedWrap()) + setFlags(Flags, SCEV::FlagNUW); + return getAddExpr(AddOps, Flags); } case Instruction::Mul: { // See the Add code above. @@ -3601,9 +3702,9 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) { LCI->getValue() == CI->getValue()) if (const SCEVZeroExtendExpr *Z = dyn_cast(getSCEV(U->getOperand(0)))) { - const Type *UTy = U->getType(); + Type *UTy = U->getType(); const SCEV *Z0 = Z->getOperand(); - const Type *Z0Ty = Z0->getType(); + Type *Z0Ty = Z0->getType(); unsigned Z0TySize = getTypeSizeInBits(Z0Ty); // If C is a low-bits mask, the zero extend is serving to @@ -3813,6 +3914,70 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) { // Iteration Count Computation Code // +/// getSmallConstantTripCount - Returns the maximum trip count of this loop as a +/// normal unsigned value, if possible. Returns 0 if the trip count is unknown +/// or not constant. Will also return 0 if the maximum trip count is very large +/// (>= 2^32) +unsigned ScalarEvolution::getSmallConstantTripCount(Loop *L, + BasicBlock *ExitBlock) { + const SCEVConstant *ExitCount = + dyn_cast(getExitCount(L, ExitBlock)); + if (!ExitCount) + return 0; + + ConstantInt *ExitConst = ExitCount->getValue(); + + // Guard against huge trip counts. + if (ExitConst->getValue().getActiveBits() > 32) + return 0; + + // In case of integer overflow, this returns 0, which is correct. + return ((unsigned)ExitConst->getZExtValue()) + 1; +} + +/// getSmallConstantTripMultiple - Returns the largest constant divisor of the +/// trip count of this loop as a normal unsigned value, if possible. This +/// means that the actual trip count is always a multiple of the returned +/// value (don't forget the trip count could very well be zero as well!). +/// +/// Returns 1 if the trip count is unknown or not guaranteed to be the +/// multiple of a constant (which is also the case if the trip count is simply +/// constant, use getSmallConstantTripCount for that case), Will also return 1 +/// if the trip count is very large (>= 2^32). +unsigned ScalarEvolution::getSmallConstantTripMultiple(Loop *L, + BasicBlock *ExitBlock) { + const SCEV *ExitCount = getExitCount(L, ExitBlock); + if (ExitCount == getCouldNotCompute()) + return 1; + + // Get the trip count from the BE count by adding 1. + const SCEV *TCMul = getAddExpr(ExitCount, + getConstant(ExitCount->getType(), 1)); + // FIXME: SCEV distributes multiplication as V1*C1 + V2*C1. We could attempt + // to factor simple cases. + if (const SCEVMulExpr *Mul = dyn_cast(TCMul)) + TCMul = Mul->getOperand(0); + + const SCEVConstant *MulC = dyn_cast(TCMul); + if (!MulC) + return 1; + + ConstantInt *Result = MulC->getValue(); + + // Guard against huge trip counts. + if (!Result || Result->getValue().getActiveBits() > 32) + return 1; + + return (unsigned)Result->getZExtValue(); +} + +// getExitCount - Get the expression for the number of loop iterations for which +// this loop is guaranteed not to exit via ExitintBlock. Otherwise return +// SCEVCouldNotCompute. +const SCEV *ScalarEvolution::getExitCount(Loop *L, BasicBlock *ExitingBlock) { + return getBackedgeTakenInfo(L).getExact(ExitingBlock, this); +} + /// getBackedgeTakenCount - If the specified loop has a predictable /// backedge-taken count, return it, otherwise return a SCEVCouldNotCompute /// object. The backedge-taken count is the number of times the loop header @@ -3825,14 +3990,14 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) { /// hasLoopInvariantBackedgeTakenCount). /// const SCEV *ScalarEvolution::getBackedgeTakenCount(const Loop *L) { - return getBackedgeTakenInfo(L).Exact; + return getBackedgeTakenInfo(L).getExact(this); } /// getMaxBackedgeTakenCount - Similar to getBackedgeTakenCount, except /// return the least SCEV value that is known never to be less than the /// actual backedge taken count. const SCEV *ScalarEvolution::getMaxBackedgeTakenCount(const Loop *L) { - return getBackedgeTakenInfo(L).Max; + return getBackedgeTakenInfo(L).getMax(this); } /// PushLoopPHIs - Push PHI nodes in the header of the given loop @@ -3849,33 +4014,31 @@ PushLoopPHIs(const Loop *L, SmallVectorImpl &Worklist) { const ScalarEvolution::BackedgeTakenInfo & ScalarEvolution::getBackedgeTakenInfo(const Loop *L) { - // Initially insert a CouldNotCompute for this loop. If the insertion + // Initially insert an invalid entry for this loop. If the insertion // succeeds, proceed to actually compute a backedge-taken count and // update the value. The temporary CouldNotCompute value tells SCEV // code elsewhere that it shouldn't attempt to request a new // backedge-taken count, which could result in infinite recursion. std::pair::iterator, bool> Pair = - BackedgeTakenCounts.insert(std::make_pair(L, getCouldNotCompute())); + BackedgeTakenCounts.insert(std::make_pair(L, BackedgeTakenInfo())); if (!Pair.second) return Pair.first->second; - BackedgeTakenInfo Result = getCouldNotCompute(); - BackedgeTakenInfo Computed = ComputeBackedgeTakenCount(L); - if (Computed.Exact != getCouldNotCompute()) { - assert(isLoopInvariant(Computed.Exact, L) && - isLoopInvariant(Computed.Max, L) && + // ComputeBackedgeTakenCount may allocate memory for its result. Inserting it + // into the BackedgeTakenCounts map transfers ownership. Otherwise, the result + // must be cleared in this scope. + BackedgeTakenInfo Result = ComputeBackedgeTakenCount(L); + + if (Result.getExact(this) != getCouldNotCompute()) { + assert(isLoopInvariant(Result.getExact(this), L) && + isLoopInvariant(Result.getMax(this), L) && "Computed backedge-taken count isn't loop invariant for loop!"); ++NumTripCountsComputed; - - // Update the value in the map. - Result = Computed; - } else { - if (Computed.Max != getCouldNotCompute()) - // Update the value in the map. - Result = Computed; - if (isa(L->getHeader()->begin())) - // Only count loops that have phi nodes as not being computable. - ++NumTripCountsNotComputed; + } + else if (Result.getMax(this) == getCouldNotCompute() && + isa(L->getHeader()->begin())) { + // Only count loops that have phi nodes as not being computable. + ++NumTripCountsNotComputed; } // Now that we know more about the trip count for this loop, forget any @@ -3883,7 +4046,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 (Computed.hasAnyInfo()) { + if (Result.hasAnyInfo()) { SmallVector Worklist; PushLoopPHIs(L, Worklist); @@ -3928,7 +4091,12 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) { /// compute a trip count, or if the loop is deleted. void ScalarEvolution::forgetLoop(const Loop *L) { // Drop any stored trip count value. - BackedgeTakenCounts.erase(L); + DenseMap::iterator BTCPos = + BackedgeTakenCounts.find(L); + if (BTCPos != BackedgeTakenCounts.end()) { + BTCPos->second.clear(); + BackedgeTakenCounts.erase(BTCPos); + } // Drop information about expressions based on loop-header PHIs. SmallVector Worklist; @@ -3984,6 +4152,85 @@ void ScalarEvolution::forgetValue(Value *V) { } } +/// getExact - Get the exact loop backedge taken count considering all loop +/// exits. If all exits are computable, this is the minimum computed count. +const SCEV * +ScalarEvolution::BackedgeTakenInfo::getExact(ScalarEvolution *SE) const { + // If any exits were not computable, the loop is not computable. + if (!ExitNotTaken.isCompleteList()) return SE->getCouldNotCompute(); + + // We need at least one computable exit. + if (!ExitNotTaken.ExitingBlock) return SE->getCouldNotCompute(); + assert(ExitNotTaken.ExactNotTaken && "uninitialized not-taken info"); + + const SCEV *BECount = 0; + for (const ExitNotTakenInfo *ENT = &ExitNotTaken; + ENT != 0; ENT = ENT->getNextExit()) { + + assert(ENT->ExactNotTaken != SE->getCouldNotCompute() && "bad exit SCEV"); + + if (!BECount) + BECount = ENT->ExactNotTaken; + else + BECount = SE->getUMinFromMismatchedTypes(BECount, ENT->ExactNotTaken); + } + assert(BECount && "Invalid not taken count for loop exit"); + return BECount; +} + +/// getExact - Get the exact not taken count for this loop exit. +const SCEV * +ScalarEvolution::BackedgeTakenInfo::getExact(BasicBlock *ExitingBlock, + ScalarEvolution *SE) const { + for (const ExitNotTakenInfo *ENT = &ExitNotTaken; + ENT != 0; ENT = ENT->getNextExit()) { + + if (ENT->ExitingBlock == ExitingBlock) + return ENT->ExactNotTaken; + } + return SE->getCouldNotCompute(); +} + +/// getMax - Get the max backedge taken count for the loop. +const SCEV * +ScalarEvolution::BackedgeTakenInfo::getMax(ScalarEvolution *SE) const { + return Max ? Max : SE->getCouldNotCompute(); +} + +/// Allocate memory for BackedgeTakenInfo and copy the not-taken count of each +/// computable exit into a persistent ExitNotTakenInfo array. +ScalarEvolution::BackedgeTakenInfo::BackedgeTakenInfo( + SmallVectorImpl< std::pair > &ExitCounts, + bool Complete, const SCEV *MaxCount) : Max(MaxCount) { + + if (!Complete) + ExitNotTaken.setIncomplete(); + + unsigned NumExits = ExitCounts.size(); + if (NumExits == 0) return; + + ExitNotTaken.ExitingBlock = ExitCounts[0].first; + ExitNotTaken.ExactNotTaken = ExitCounts[0].second; + if (NumExits == 1) return; + + // Handle the rare case of multiple computable exits. + ExitNotTakenInfo *ENT = new ExitNotTakenInfo[NumExits-1]; + + ExitNotTakenInfo *PrevENT = &ExitNotTaken; + for (unsigned i = 1; i < NumExits; ++i, PrevENT = ENT, ++ENT) { + PrevENT->setNextExit(ENT); + ENT->ExitingBlock = ExitCounts[i].first; + ENT->ExactNotTaken = ExitCounts[i].second; + } +} + +/// clear - Invalidate this result and free the ExitNotTakenInfo array. +void ScalarEvolution::BackedgeTakenInfo::clear() { + ExitNotTaken.ExitingBlock = 0; + ExitNotTaken.ExactNotTaken = 0; + delete[] ExitNotTaken.getNextExit(); +} + /// ComputeBackedgeTakenCount - Compute the number of times the backedge /// of the specified loop will execute. ScalarEvolution::BackedgeTakenInfo @@ -3992,38 +4239,31 @@ ScalarEvolution::ComputeBackedgeTakenCount(const Loop *L) { L->getExitingBlocks(ExitingBlocks); // Examine all exits and pick the most conservative values. - const SCEV *BECount = getCouldNotCompute(); const SCEV *MaxBECount = getCouldNotCompute(); - bool CouldNotComputeBECount = false; + bool CouldComputeBECount = true; + SmallVector, 4> ExitCounts; for (unsigned i = 0, e = ExitingBlocks.size(); i != e; ++i) { - BackedgeTakenInfo NewBTI = - ComputeBackedgeTakenCountFromExit(L, ExitingBlocks[i]); - - if (NewBTI.Exact == getCouldNotCompute()) { + ExitLimit EL = ComputeExitLimit(L, ExitingBlocks[i]); + if (EL.Exact == getCouldNotCompute()) // We couldn't compute an exact value for this exit, so // we won't be able to compute an exact value for the loop. - CouldNotComputeBECount = true; - BECount = getCouldNotCompute(); - } else if (!CouldNotComputeBECount) { - if (BECount == getCouldNotCompute()) - BECount = NewBTI.Exact; - else - BECount = getUMinFromMismatchedTypes(BECount, NewBTI.Exact); - } + CouldComputeBECount = false; + else + ExitCounts.push_back(std::make_pair(ExitingBlocks[i], EL.Exact)); + if (MaxBECount == getCouldNotCompute()) - MaxBECount = NewBTI.Max; - else if (NewBTI.Max != getCouldNotCompute()) - MaxBECount = getUMinFromMismatchedTypes(MaxBECount, NewBTI.Max); + MaxBECount = EL.Max; + else if (EL.Max != getCouldNotCompute()) + MaxBECount = getUMinFromMismatchedTypes(MaxBECount, EL.Max); } - return BackedgeTakenInfo(BECount, MaxBECount); + return BackedgeTakenInfo(ExitCounts, CouldComputeBECount, MaxBECount); } -/// ComputeBackedgeTakenCountFromExit - Compute the number of times the backedge -/// of the specified loop will execute if it exits via the specified block. -ScalarEvolution::BackedgeTakenInfo -ScalarEvolution::ComputeBackedgeTakenCountFromExit(const Loop *L, - BasicBlock *ExitingBlock) { +/// ComputeExitLimit - Compute the number of times the backedge of the specified +/// loop will execute if it exits via the specified block. +ScalarEvolution::ExitLimit +ScalarEvolution::ComputeExitLimit(const Loop *L, BasicBlock *ExitingBlock) { // Okay, we've chosen an exiting block. See what condition causes us to // exit at this block. @@ -4081,95 +4321,91 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExit(const Loop *L, } // Proceed to the next level to examine the exit condition expression. - return ComputeBackedgeTakenCountFromExitCond(L, ExitBr->getCondition(), - ExitBr->getSuccessor(0), - ExitBr->getSuccessor(1)); + return ComputeExitLimitFromCond(L, ExitBr->getCondition(), + ExitBr->getSuccessor(0), + ExitBr->getSuccessor(1)); } -/// ComputeBackedgeTakenCountFromExitCond - Compute the number of times the +/// ComputeExitLimitFromCond - Compute the number of times the /// backedge of the specified loop will execute if its exit condition /// were a conditional branch of ExitCond, TBB, and FBB. -ScalarEvolution::BackedgeTakenInfo -ScalarEvolution::ComputeBackedgeTakenCountFromExitCond(const Loop *L, - Value *ExitCond, - BasicBlock *TBB, - BasicBlock *FBB) { +ScalarEvolution::ExitLimit +ScalarEvolution::ComputeExitLimitFromCond(const Loop *L, + Value *ExitCond, + BasicBlock *TBB, + BasicBlock *FBB) { // Check if the controlling expression for this loop is an And or Or. if (BinaryOperator *BO = dyn_cast(ExitCond)) { if (BO->getOpcode() == Instruction::And) { // Recurse on the operands of the and. - BackedgeTakenInfo BTI0 = - ComputeBackedgeTakenCountFromExitCond(L, BO->getOperand(0), TBB, FBB); - BackedgeTakenInfo BTI1 = - ComputeBackedgeTakenCountFromExitCond(L, BO->getOperand(1), TBB, FBB); + ExitLimit EL0 = ComputeExitLimitFromCond(L, BO->getOperand(0), TBB, FBB); + ExitLimit EL1 = ComputeExitLimitFromCond(L, BO->getOperand(1), TBB, FBB); const SCEV *BECount = getCouldNotCompute(); const SCEV *MaxBECount = getCouldNotCompute(); if (L->contains(TBB)) { // Both conditions must be true for the loop to continue executing. // Choose the less conservative count. - if (BTI0.Exact == getCouldNotCompute() || - BTI1.Exact == getCouldNotCompute()) + if (EL0.Exact == getCouldNotCompute() || + EL1.Exact == getCouldNotCompute()) BECount = getCouldNotCompute(); else - BECount = getUMinFromMismatchedTypes(BTI0.Exact, BTI1.Exact); - if (BTI0.Max == getCouldNotCompute()) - MaxBECount = BTI1.Max; - else if (BTI1.Max == getCouldNotCompute()) - MaxBECount = BTI0.Max; + BECount = getUMinFromMismatchedTypes(EL0.Exact, EL1.Exact); + if (EL0.Max == getCouldNotCompute()) + MaxBECount = EL1.Max; + else if (EL1.Max == getCouldNotCompute()) + MaxBECount = EL0.Max; else - MaxBECount = getUMinFromMismatchedTypes(BTI0.Max, BTI1.Max); + MaxBECount = getUMinFromMismatchedTypes(EL0.Max, EL1.Max); } else { // Both conditions must be true at the same time for the loop to exit. // For now, be conservative. assert(L->contains(FBB) && "Loop block has no successor in loop!"); - if (BTI0.Max == BTI1.Max) - MaxBECount = BTI0.Max; - if (BTI0.Exact == BTI1.Exact) - BECount = BTI0.Exact; + if (EL0.Max == EL1.Max) + MaxBECount = EL0.Max; + if (EL0.Exact == EL1.Exact) + BECount = EL0.Exact; } - return BackedgeTakenInfo(BECount, MaxBECount); + return ExitLimit(BECount, MaxBECount); } if (BO->getOpcode() == Instruction::Or) { // Recurse on the operands of the or. - BackedgeTakenInfo BTI0 = - ComputeBackedgeTakenCountFromExitCond(L, BO->getOperand(0), TBB, FBB); - BackedgeTakenInfo BTI1 = - ComputeBackedgeTakenCountFromExitCond(L, BO->getOperand(1), TBB, FBB); + ExitLimit EL0 = ComputeExitLimitFromCond(L, BO->getOperand(0), TBB, FBB); + ExitLimit EL1 = ComputeExitLimitFromCond(L, BO->getOperand(1), TBB, FBB); const SCEV *BECount = getCouldNotCompute(); const SCEV *MaxBECount = getCouldNotCompute(); if (L->contains(FBB)) { // Both conditions must be false for the loop to continue executing. // Choose the less conservative count. - if (BTI0.Exact == getCouldNotCompute() || - BTI1.Exact == getCouldNotCompute()) + if (EL0.Exact == getCouldNotCompute() || + EL1.Exact == getCouldNotCompute()) BECount = getCouldNotCompute(); else - BECount = getUMinFromMismatchedTypes(BTI0.Exact, BTI1.Exact); - if (BTI0.Max == getCouldNotCompute()) - MaxBECount = BTI1.Max; - else if (BTI1.Max == getCouldNotCompute()) - MaxBECount = BTI0.Max; + BECount = getUMinFromMismatchedTypes(EL0.Exact, EL1.Exact); + if (EL0.Max == getCouldNotCompute()) + MaxBECount = EL1.Max; + else if (EL1.Max == getCouldNotCompute()) + MaxBECount = EL0.Max; else - MaxBECount = getUMinFromMismatchedTypes(BTI0.Max, BTI1.Max); + MaxBECount = getUMinFromMismatchedTypes(EL0.Max, EL1.Max); } else { // Both conditions must be false at the same time for the loop to exit. // For now, be conservative. assert(L->contains(TBB) && "Loop block has no successor in loop!"); - if (BTI0.Max == BTI1.Max) - MaxBECount = BTI0.Max; - if (BTI0.Exact == BTI1.Exact) - BECount = BTI0.Exact; + if (EL0.Max == EL1.Max) + MaxBECount = EL0.Max; + if (EL0.Exact == EL1.Exact) + BECount = EL0.Exact; } - return BackedgeTakenInfo(BECount, MaxBECount); + return ExitLimit(BECount, MaxBECount); } } // With an icmp, it may be feasible to compute an exact backedge-taken count. // Proceed to the next level to examine the icmp. if (ICmpInst *ExitCondICmp = dyn_cast(ExitCond)) - return ComputeBackedgeTakenCountFromExitCondICmp(L, ExitCondICmp, TBB, FBB); + return ComputeExitLimitFromICmp(L, ExitCondICmp, TBB, FBB); // Check for a constant condition. These are normally stripped out by // SimplifyCFG, but ScalarEvolution may be used by a pass which wishes to @@ -4185,17 +4421,17 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExitCond(const Loop *L, } // If it's not an integer or pointer comparison then compute it the hard way. - return ComputeBackedgeTakenCountExhaustively(L, ExitCond, !L->contains(TBB)); + return ComputeExitCountExhaustively(L, ExitCond, !L->contains(TBB)); } -/// ComputeBackedgeTakenCountFromExitCondICmp - Compute the number of times the +/// ComputeExitLimitFromICmp - Compute the number of times the /// backedge of the specified loop will execute if its exit condition /// were a conditional branch of the ICmpInst ExitCond, TBB, and FBB. -ScalarEvolution::BackedgeTakenInfo -ScalarEvolution::ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L, - ICmpInst *ExitCond, - BasicBlock *TBB, - BasicBlock *FBB) { +ScalarEvolution::ExitLimit +ScalarEvolution::ComputeExitLimitFromICmp(const Loop *L, + ICmpInst *ExitCond, + BasicBlock *TBB, + BasicBlock *FBB) { // If the condition was exit on true, convert the condition to exit on false ICmpInst::Predicate Cond; @@ -4207,8 +4443,8 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L, // Handle common loops like: for (X = "string"; *X; ++X) if (LoadInst *LI = dyn_cast(ExitCond->getOperand(0))) if (Constant *RHS = dyn_cast(ExitCond->getOperand(1))) { - BackedgeTakenInfo ItCnt = - ComputeLoadConstantCompareBackedgeTakenCount(LI, RHS, L, Cond); + ExitLimit ItCnt = + ComputeLoadConstantCompareExitLimit(LI, RHS, L, Cond); if (ItCnt.hasAnyInfo()) return ItCnt; } @@ -4247,36 +4483,36 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L, switch (Cond) { case ICmpInst::ICMP_NE: { // while (X != Y) // Convert to: while (X-Y != 0) - BackedgeTakenInfo BTI = HowFarToZero(getMinusSCEV(LHS, RHS), L); - if (BTI.hasAnyInfo()) return BTI; + ExitLimit EL = HowFarToZero(getMinusSCEV(LHS, RHS), L); + if (EL.hasAnyInfo()) return EL; break; } case ICmpInst::ICMP_EQ: { // while (X == Y) // Convert to: while (X-Y == 0) - BackedgeTakenInfo BTI = HowFarToNonZero(getMinusSCEV(LHS, RHS), L); - if (BTI.hasAnyInfo()) return BTI; + ExitLimit EL = HowFarToNonZero(getMinusSCEV(LHS, RHS), L); + if (EL.hasAnyInfo()) return EL; break; } case ICmpInst::ICMP_SLT: { - BackedgeTakenInfo BTI = HowManyLessThans(LHS, RHS, L, true); - if (BTI.hasAnyInfo()) return BTI; + ExitLimit EL = HowManyLessThans(LHS, RHS, L, true); + if (EL.hasAnyInfo()) return EL; break; } case ICmpInst::ICMP_SGT: { - BackedgeTakenInfo BTI = HowManyLessThans(getNotSCEV(LHS), + ExitLimit EL = HowManyLessThans(getNotSCEV(LHS), getNotSCEV(RHS), L, true); - if (BTI.hasAnyInfo()) return BTI; + if (EL.hasAnyInfo()) return EL; break; } case ICmpInst::ICMP_ULT: { - BackedgeTakenInfo BTI = HowManyLessThans(LHS, RHS, L, false); - if (BTI.hasAnyInfo()) return BTI; + ExitLimit EL = HowManyLessThans(LHS, RHS, L, false); + if (EL.hasAnyInfo()) return EL; break; } case ICmpInst::ICMP_UGT: { - BackedgeTakenInfo BTI = HowManyLessThans(getNotSCEV(LHS), + ExitLimit EL = HowManyLessThans(getNotSCEV(LHS), getNotSCEV(RHS), L, false); - if (BTI.hasAnyInfo()) return BTI; + if (EL.hasAnyInfo()) return EL; break; } default: @@ -4290,8 +4526,7 @@ ScalarEvolution::ComputeBackedgeTakenCountFromExitCondICmp(const Loop *L, #endif break; } - return - ComputeBackedgeTakenCountExhaustively(L, ExitCond, !L->contains(TBB)); + return ComputeExitCountExhaustively(L, ExitCond, !L->contains(TBB)); } static ConstantInt * @@ -4321,10 +4556,10 @@ GetAddressedElementFromGlobal(GlobalVariable *GV, if (Idx >= CA->getNumOperands()) return 0; // Bogus program Init = cast(CA->getOperand(Idx)); } else if (isa(Init)) { - if (const StructType *STy = dyn_cast(Init->getType())) { + if (StructType *STy = dyn_cast(Init->getType())) { assert(Idx < STy->getNumElements() && "Bad struct index!"); Init = Constant::getNullValue(STy->getElementType(Idx)); - } else if (const ArrayType *ATy = dyn_cast(Init->getType())) { + } else if (ArrayType *ATy = dyn_cast(Init->getType())) { if (Idx >= ATy->getNumElements()) return 0; // Bogus program Init = Constant::getNullValue(ATy->getElementType()); } else { @@ -4338,15 +4573,16 @@ GetAddressedElementFromGlobal(GlobalVariable *GV, return Init; } -/// ComputeLoadConstantCompareBackedgeTakenCount - Given an exit condition of +/// ComputeLoadConstantCompareExitLimit - Given an exit condition of /// 'icmp op load X, cst', try to see if we can compute the backedge /// execution count. -ScalarEvolution::BackedgeTakenInfo -ScalarEvolution::ComputeLoadConstantCompareBackedgeTakenCount( - LoadInst *LI, - Constant *RHS, - const Loop *L, - ICmpInst::Predicate predicate) { +ScalarEvolution::ExitLimit +ScalarEvolution::ComputeLoadConstantCompareExitLimit( + LoadInst *LI, + Constant *RHS, + const Loop *L, + ICmpInst::Predicate predicate) { + if (LI->isVolatile()) return getCouldNotCompute(); // Check to see if the loaded pointer is a getelementptr of a global. @@ -4431,69 +4667,117 @@ static bool CanConstantFold(const Instruction *I) { return false; } +/// Determine whether this instruction can constant evolve within this loop +/// assuming its operands can all constant evolve. +static bool canConstantEvolve(Instruction *I, const Loop *L) { + // An instruction outside of the loop can't be derived from a loop PHI. + if (!L->contains(I)) return false; + + if (isa(I)) { + if (L->getHeader() == I->getParent()) + return true; + else + // We don't currently keep track of the control flow needed to evaluate + // PHIs, so we cannot handle PHIs inside of loops. + return false; + } + + // If we won't be able to constant fold this expression even if the operands + // are constants, bail early. + return CanConstantFold(I); +} + +/// getConstantEvolvingPHIOperands - Implement getConstantEvolvingPHI by +/// recursing through each instruction operand until reaching a loop header phi. +static PHINode * +getConstantEvolvingPHIOperands(Instruction *UseInst, const Loop *L, + DenseMap &PHIMap) { + + // Otherwise, we can evaluate this instruction if all of its operands are + // constant or derived from a PHI node themselves. + PHINode *PHI = 0; + for (Instruction::op_iterator OpI = UseInst->op_begin(), + OpE = UseInst->op_end(); OpI != OpE; ++OpI) { + + if (isa(*OpI)) continue; + + Instruction *OpInst = dyn_cast(*OpI); + if (!OpInst || !canConstantEvolve(OpInst, L)) return 0; + + PHINode *P = dyn_cast(OpInst); + if (!P) + // If this operand is already visited, reuse the prior result. + // We may have P != PHI if this is the deepest point at which the + // inconsistent paths meet. + P = PHIMap.lookup(OpInst); + if (!P) { + // Recurse and memoize the results, whether a phi is found or not. + // This recursive call invalidates pointers into PHIMap. + P = getConstantEvolvingPHIOperands(OpInst, L, PHIMap); + PHIMap[OpInst] = P; + } + if (P == 0) return 0; // Not evolving from PHI + if (PHI && PHI != P) return 0; // Evolving from multiple different PHIs. + PHI = P; + } + // This is a expression evolving from a constant PHI! + return PHI; +} + /// getConstantEvolvingPHI - Given an LLVM value and a loop, return a PHI node /// in the loop that V is derived from. We allow arbitrary operations along the /// way, but the operands of an operation must either be constants or a value /// derived from a constant PHI. If this expression does not fit with these /// constraints, return null. static PHINode *getConstantEvolvingPHI(Value *V, const Loop *L) { - // If this is not an instruction, or if this is an instruction outside of the - // loop, it can't be derived from a loop PHI. Instruction *I = dyn_cast(V); - if (I == 0 || !L->contains(I)) return 0; + if (I == 0 || !canConstantEvolve(I, L)) return 0; if (PHINode *PN = dyn_cast(I)) { - if (L->getHeader() == I->getParent()) - return PN; - else - // We don't currently keep track of the control flow needed to evaluate - // PHIs, so we cannot handle PHIs inside of loops. - return 0; + return PN; } - // If we won't be able to constant fold this expression even if the operands - // are constants, return early. - if (!CanConstantFold(I)) return 0; - - // Otherwise, we can evaluate this instruction if all of its operands are - // constant or derived from a PHI node themselves. - PHINode *PHI = 0; - for (unsigned Op = 0, e = I->getNumOperands(); Op != e; ++Op) - if (!isa(I->getOperand(Op))) { - PHINode *P = getConstantEvolvingPHI(I->getOperand(Op), L); - if (P == 0) return 0; // Not evolving from PHI - if (PHI == 0) - PHI = P; - else if (PHI != P) - return 0; // Evolving from multiple different PHIs. - } - - // This is a expression evolving from a constant PHI! - return PHI; + // Record non-constant instructions contained by the loop. + DenseMap PHIMap; + return getConstantEvolvingPHIOperands(I, L, PHIMap); } /// EvaluateExpression - Given an expression that passes the /// getConstantEvolvingPHI predicate, evaluate its value assuming the PHI node /// in the loop has the value PHIVal. If we can't fold this expression for some /// reason, return null. -static Constant *EvaluateExpression(Value *V, Constant *PHIVal, +static Constant *EvaluateExpression(Value *V, const Loop *L, + DenseMap &Vals, const TargetData *TD) { - if (isa(V)) return PHIVal; + // Convenient constant check, but redundant for recursive calls. if (Constant *C = dyn_cast(V)) return C; + Instruction *I = cast(V); + if (Constant *C = Vals.lookup(I)) return C; + + assert(!isa(I) && "loop header phis should be mapped to constant"); + assert(canConstantEvolve(I, L) && "cannot evaluate expression in this loop"); + (void)L; std::vector Operands(I->getNumOperands()); for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { - Operands[i] = EvaluateExpression(I->getOperand(i), PHIVal, TD); - if (Operands[i] == 0) return 0; + Instruction *Operand = dyn_cast(I->getOperand(i)); + if (!Operand) { + Operands[i] = dyn_cast(I->getOperand(i)); + if (!Operands[i]) return 0; + continue; + } + Constant *C = EvaluateExpression(Operand, L, Vals, TD); + Vals[Operand] = C; + if (!C) return 0; + Operands[i] = C; } if (const CmpInst *CI = dyn_cast(I)) return ConstantFoldCompareInstOperands(CI->getPredicate(), Operands[0], Operands[1], TD); - return ConstantFoldInstOperands(I->getOpcode(), I->getType(), - &Operands[0], Operands.size(), TD); + return ConstantFoldInstOperands(I->getOpcode(), I->getType(), Operands, TD); } /// getConstantEvolutionLoopExitValue - If we know that the specified Phi is @@ -4514,6 +4798,9 @@ ScalarEvolution::getConstantEvolutionLoopExitValue(PHINode *PN, Constant *&RetVal = ConstantEvolutionLoopExitValue[PN]; + // FIXME: Nick's fix for PR11034 will seed constants for multiple header phis. + DenseMap CurrentIterVals; + // Since the loop is canonicalized, the PHI node must have two entries. One // entry must be a constant (coming in from outside of the loop), and the // second must be derived from the same PHI. @@ -4522,6 +4809,7 @@ ScalarEvolution::getConstantEvolutionLoopExitValue(PHINode *PN, dyn_cast(PN->getIncomingValue(!SecondIsBackedge)); if (StartCST == 0) return RetVal = 0; // Must be a constant. + CurrentIterVals[PN] = StartCST; Value *BEValue = PN->getIncomingValue(SecondIsBackedge); if (getConstantEvolvingPHI(BEValue, L) != PN && @@ -4534,29 +4822,31 @@ ScalarEvolution::getConstantEvolutionLoopExitValue(PHINode *PN, unsigned NumIterations = BEs.getZExtValue(); // must be in range unsigned IterationNum = 0; - for (Constant *PHIVal = StartCST; ; ++IterationNum) { + for (; ; ++IterationNum) { if (IterationNum == NumIterations) - return RetVal = PHIVal; // Got exit value! + return RetVal = CurrentIterVals[PN]; // Got exit value! // Compute the value of the PHI node for the next iteration. - Constant *NextPHI = EvaluateExpression(BEValue, PHIVal, TD); - if (NextPHI == PHIVal) + // EvaluateExpression adds non-phi values to the CurrentIterVals map. + Constant *NextPHI = EvaluateExpression(BEValue, L, CurrentIterVals, TD); + if (NextPHI == CurrentIterVals[PN]) return RetVal = NextPHI; // Stopped evolving! if (NextPHI == 0) return 0; // Couldn't evaluate! - PHIVal = NextPHI; + DenseMap NextIterVals; + NextIterVals[PN] = NextPHI; + CurrentIterVals.swap(NextIterVals); } } -/// ComputeBackedgeTakenCountExhaustively - If the loop is known to execute a +/// ComputeExitCountExhaustively - If the loop is known to execute a /// constant number of times (the condition evolves only from constants), /// try to evaluate a few iterations of the loop until we get the exit /// condition gets a value of ExitWhen (true or false). If we cannot /// evaluate the trip count of the loop, return getCouldNotCompute(). -const SCEV * -ScalarEvolution::ComputeBackedgeTakenCountExhaustively(const Loop *L, - Value *Cond, - bool ExitWhen) { +const SCEV * ScalarEvolution::ComputeExitCountExhaustively(const Loop *L, + Value *Cond, + bool ExitWhen) { PHINode *PN = getConstantEvolvingPHI(Cond, L); if (PN == 0) return getCouldNotCompute(); @@ -4583,8 +4873,10 @@ ScalarEvolution::ComputeBackedgeTakenCountExhaustively(const Loop *L, unsigned MaxIterations = MaxBruteForceIterations; // Limit analysis. for (Constant *PHIVal = StartCST; IterationNum != MaxIterations; ++IterationNum) { + DenseMap PHIValMap; + PHIValMap[PN] = PHIVal; ConstantInt *CondVal = - dyn_cast_or_null(EvaluateExpression(Cond, PHIVal, TD)); + dyn_cast_or_null(EvaluateExpression(Cond, L, PHIValMap, TD)); // Couldn't symbolically evaluate. if (!CondVal) return getCouldNotCompute(); @@ -4595,7 +4887,7 @@ ScalarEvolution::ComputeBackedgeTakenCountExhaustively(const Loop *L, } // Compute the value of the PHI node for the next iteration. - Constant *NextPHI = EvaluateExpression(BEValue, PHIVal, TD); + Constant *NextPHI = EvaluateExpression(BEValue, L, PHIValMap, TD); if (NextPHI == 0 || NextPHI == PHIVal) return getCouldNotCompute();// Couldn't evaluate or not making progress... PHIVal = NextPHI; @@ -4703,7 +4995,7 @@ const SCEV *ScalarEvolution::computeSCEVAtScope(const SCEV *V, const Loop *L) { Operands[0], Operands[1], TD); else C = ConstantFoldInstOperands(I->getOpcode(), I->getType(), - &Operands[0], Operands.size(), TD); + Operands, TD); if (!C) return V; return getSCEV(C); } @@ -4925,7 +5217,7 @@ SolveQuadraticEquation(const SCEVAddRecExpr *AddRec, ScalarEvolution &SE) { // Compute the two solutions for the quadratic formula. // The divisions must be performed as signed divisions. APInt NegB(-B); - APInt TwoA( A << 1 ); + APInt TwoA(A << 1); if (TwoA.isMinValue()) { const SCEV *CNC = SE.getCouldNotCompute(); return std::make_pair(CNC, CNC); @@ -4940,7 +5232,7 @@ SolveQuadraticEquation(const SCEVAddRecExpr *AddRec, ScalarEvolution &SE) { return std::make_pair(SE.getConstant(Solution1), SE.getConstant(Solution2)); - } // end APIntOps namespace + } // end APIntOps namespace } /// HowFarToZero - Return the number of times a backedge comparing the specified @@ -4950,7 +5242,7 @@ SolveQuadraticEquation(const SCEVAddRecExpr *AddRec, ScalarEvolution &SE) { /// now expressed as a single expression, V = x-y. So the exit test is /// effectively V != 0. We know and take advantage of the fact that this /// expression only being used in a comparison by zero context. -ScalarEvolution::BackedgeTakenInfo +ScalarEvolution::ExitLimit ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) { // If the value is a constant if (const SCEVConstant *C = dyn_cast(V)) { @@ -5034,8 +5326,19 @@ ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) { // Handle unitary steps, which cannot wraparound. // 1*N = -Start; -1*N = Start (mod 2^BW), so: // N = Distance (as unsigned) - if (StepC->getValue()->equalsInt(1) || StepC->getValue()->isAllOnesValue()) - return Distance; + if (StepC->getValue()->equalsInt(1) || StepC->getValue()->isAllOnesValue()) { + ConstantRange CR = getUnsignedRange(Start); + const SCEV *MaxBECount; + if (!CountDown && CR.getUnsignedMin().isMinValue()) + // When counting up, the worst starting value is 1, not 0. + MaxBECount = CR.getUnsignedMax().isMinValue() + ? getConstant(APInt::getMinValue(CR.getBitWidth())) + : getConstant(APInt::getMaxValue(CR.getBitWidth())); + else + MaxBECount = getConstant(CountDown ? CR.getUnsignedMax() + : -CR.getUnsignedMin()); + return ExitLimit(Distance, MaxBECount); + } // If the recurrence is known not to wraparound, unsigned divide computes the // back edge count. We know that the value will either become zero (and thus @@ -5062,7 +5365,7 @@ ScalarEvolution::HowFarToZero(const SCEV *V, const Loop *L) { /// HowFarToNonZero - Return the number of times a backedge checking the /// specified value for nonzero will execute. If not computable, return /// CouldNotCompute -ScalarEvolution::BackedgeTakenInfo +ScalarEvolution::ExitLimit ScalarEvolution::HowFarToNonZero(const SCEV *V, const Loop *L) { // Loops that look like: while (X == 0) are very strange indeed. We don't // handle them yet except for the trivial case. This could be expanded in the @@ -5741,7 +6044,7 @@ const SCEV *ScalarEvolution::getBECount(const SCEV *Start, assert(!isKnownNegative(Step) && "This code doesn't handle negative strides yet!"); - const Type *Ty = Start->getType(); + Type *Ty = Start->getType(); // When Start == End, we have an exact BECount == 0. Short-circuit this case // here because SCEV may not be able to determine that the unsigned division @@ -5760,7 +6063,7 @@ const SCEV *ScalarEvolution::getBECount(const SCEV *Start, if (!NoWrap) { // Check Add for unsigned overflow. // TODO: More sophisticated things could be done here. - const Type *WideTy = IntegerType::get(getContext(), + Type *WideTy = IntegerType::get(getContext(), getTypeSizeInBits(Ty) + 1); const SCEV *EDiff = getZeroExtendExpr(Diff, WideTy); const SCEV *ERoundUp = getZeroExtendExpr(RoundUp, WideTy); @@ -5775,7 +6078,7 @@ const SCEV *ScalarEvolution::getBECount(const SCEV *Start, /// HowManyLessThans - Return the number of times a backedge containing the /// specified less-than comparison will execute. If not computable, return /// CouldNotCompute. -ScalarEvolution::BackedgeTakenInfo +ScalarEvolution::ExitLimit ScalarEvolution::HowManyLessThans(const SCEV *LHS, const SCEV *RHS, const Loop *L, bool isSigned) { // Only handle: "ADDREC < LoopInvariant". @@ -5882,7 +6185,7 @@ ScalarEvolution::HowManyLessThans(const SCEV *LHS, const SCEV *RHS, if (isa(MaxBECount)) MaxBECount = BECount; - return BackedgeTakenInfo(BECount, MaxBECount); + return ExitLimit(BECount, MaxBECount); } return getCouldNotCompute(); @@ -6090,6 +6393,15 @@ void ScalarEvolution::releaseMemory() { FirstUnknown = 0; ValueExprMap.clear(); + + // Free any extra memory created for ExitNotTakenInfo in the unlikely event + // that a loop had multiple computable exits. + for (DenseMap::iterator I = + BackedgeTakenCounts.begin(), E = BackedgeTakenCounts.end(); + I != E; ++I) { + I->second.clear(); + } + BackedgeTakenCounts.clear(); ConstantEvolutionLoopExitValue.clear(); ValuesAtScopes.clear(); diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index befe6d2599d6..47f0f321161b 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -17,6 +17,7 @@ #include "llvm/Analysis/LoopInfo.h" #include "llvm/IntrinsicInst.h" #include "llvm/LLVMContext.h" +#include "llvm/Support/Debug.h" #include "llvm/Target/TargetData.h" #include "llvm/ADT/STLExtras.h" @@ -26,7 +27,7 @@ using namespace llvm; /// reusing an existing cast if a suitable one exists, moving an existing /// cast if a suitable one exists but isn't in the right place, or /// creating a new one. -Value *SCEVExpander::ReuseOrCreateCast(Value *V, const Type *Ty, +Value *SCEVExpander::ReuseOrCreateCast(Value *V, Type *Ty, Instruction::CastOps Op, BasicBlock::iterator IP) { // Check to see if there is already a cast! @@ -62,7 +63,7 @@ Value *SCEVExpander::ReuseOrCreateCast(Value *V, const Type *Ty, /// InsertNoopCastOfTo - Insert a cast of V to the specified type, /// which must be possible with a noop cast, doing what we can to share /// the casts. -Value *SCEVExpander::InsertNoopCastOfTo(Value *V, const Type *Ty) { +Value *SCEVExpander::InsertNoopCastOfTo(Value *V, Type *Ty) { Instruction::CastOps Op = CastInst::getCastOpcode(V, false, Ty, false); assert((Op == Instruction::BitCast || Op == Instruction::PtrToInt || @@ -103,7 +104,8 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, const Type *Ty) { while ((isa(IP) && isa(cast(IP)->getOperand(0)) && cast(IP)->getOperand(0) != A) || - isa(IP)) + isa(IP) || + isa(IP)) ++IP; return ReuseOrCreateCast(A, Ty, Op, IP); } @@ -113,7 +115,9 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, const Type *Ty) { BasicBlock::iterator IP = I; ++IP; if (InvokeInst *II = dyn_cast(I)) IP = II->getNormalDest()->begin(); - while (isa(IP) || isa(IP)) ++IP; + while (isa(IP) || isa(IP) || + isa(IP)) + ++IP; return ReuseOrCreateCast(I, Ty, Op, IP); } @@ -160,7 +164,7 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, } // If we haven't found this binop, insert it. - Instruction *BO = cast(Builder.CreateBinOp(Opcode, LHS, RHS, "tmp")); + Instruction *BO = cast(Builder.CreateBinOp(Opcode, LHS, RHS)); BO->setDebugLoc(SaveInsertPt->getDebugLoc()); rememberInstruction(BO); @@ -277,7 +281,7 @@ static bool FactorOutConstant(const SCEV *&S, /// the list. /// static void SimplifyAddOperands(SmallVectorImpl &Ops, - const Type *Ty, + Type *Ty, ScalarEvolution &SE) { unsigned NumAddRecs = 0; for (unsigned i = Ops.size(); i > 0 && isa(Ops[i-1]); --i) @@ -306,7 +310,7 @@ static void SimplifyAddOperands(SmallVectorImpl &Ops, /// into GEP indices. /// static void SplitAddRecs(SmallVectorImpl &Ops, - const Type *Ty, + Type *Ty, ScalarEvolution &SE) { // Find the addrecs. SmallVector AddRecs; @@ -365,10 +369,10 @@ static void SplitAddRecs(SmallVectorImpl &Ops, /// Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin, const SCEV *const *op_end, - const PointerType *PTy, - const Type *Ty, + PointerType *PTy, + Type *Ty, Value *V) { - const Type *ElTy = PTy->getElementType(); + Type *ElTy = PTy->getElementType(); SmallVector GepIndices; SmallVector Ops(op_begin, op_end); bool AnyNonZeroIndices = false; @@ -423,7 +427,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin, GepIndices.push_back(Scaled); // Collect struct field index operands. - while (const StructType *STy = dyn_cast(ElTy)) { + while (StructType *STy = dyn_cast(ElTy)) { bool FoundFieldNo = false; // An empty struct has no fields. if (STy->getNumElements() == 0) break; @@ -451,7 +455,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin, // appropriate struct type. for (unsigned i = 0, e = Ops.size(); i != e; ++i) if (const SCEVUnknown *U = dyn_cast(Ops[i])) { - const Type *CTy; + Type *CTy; Constant *FieldNo; if (U->isOffsetOf(CTy, FieldNo) && CTy == STy) { GepIndices.push_back(FieldNo); @@ -474,7 +478,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin, } } - if (const ArrayType *ATy = dyn_cast(ElTy)) + if (ArrayType *ATy = dyn_cast(ElTy)) ElTy = ATy->getElementType(); else break; @@ -494,7 +498,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin, // Fold a GEP with constant operands. if (Constant *CLHS = dyn_cast(V)) if (Constant *CRHS = dyn_cast(Idx)) - return ConstantExpr::getGetElementPtr(CLHS, &CRHS, 1); + return ConstantExpr::getGetElementPtr(CLHS, CRHS); // Do a quick scan to see if we have this GEP nearby. If so, reuse it. unsigned ScanLimit = 6; @@ -572,8 +576,7 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin, if (V->getType() != PTy) Casted = InsertNoopCastOfTo(Casted, PTy); Value *GEP = Builder.CreateGEP(Casted, - GepIndices.begin(), - GepIndices.end(), + GepIndices, "scevgep"); Ops.push_back(SE.getUnknown(GEP)); rememberInstruction(GEP); @@ -691,7 +694,7 @@ class LoopCompare { } Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) { - const Type *Ty = SE.getEffectiveSCEVType(S->getType()); + Type *Ty = SE.getEffectiveSCEVType(S->getType()); // Collect all the add operands in a loop, along with their associated loops. // Iterate in reverse so that constants are emitted last, all else equal, and @@ -717,7 +720,7 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) { // This is the first operand. Just expand it. Sum = expand(Op); ++I; - } else if (const PointerType *PTy = dyn_cast(Sum->getType())) { + } else if (PointerType *PTy = dyn_cast(Sum->getType())) { // The running sum expression is a pointer. Try to form a getelementptr // at this level with that as the base. SmallVector NewOps; @@ -731,7 +734,7 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) { NewOps.push_back(X); } Sum = expandAddToGEP(NewOps.begin(), NewOps.end(), PTy, Ty, Sum); - } else if (const PointerType *PTy = dyn_cast(Op->getType())) { + } else if (PointerType *PTy = dyn_cast(Op->getType())) { // The running sum is an integer, and there's a pointer at this level. // Try to form a getelementptr. If the running sum is instructions, // use a SCEVUnknown to avoid re-analyzing them. @@ -762,7 +765,7 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) { } Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) { - const Type *Ty = SE.getEffectiveSCEVType(S->getType()); + Type *Ty = SE.getEffectiveSCEVType(S->getType()); // Collect all the mul operands in a loop, along with their associated loops. // Iterate in reverse so that constants are emitted last, all else equal. @@ -804,7 +807,7 @@ Value *SCEVExpander::visitMulExpr(const SCEVMulExpr *S) { } Value *SCEVExpander::visitUDivExpr(const SCEVUDivExpr *S) { - const Type *Ty = SE.getEffectiveSCEVType(S->getType()); + Type *Ty = SE.getEffectiveSCEVType(S->getType()); Value *LHS = expandCodeFor(S->getLHS(), Ty); if (const SCEVConstant *SC = dyn_cast(S->getRHS())) { @@ -841,81 +844,141 @@ static void ExposePointerBase(const SCEV *&Base, const SCEV *&Rest, } } +/// Determine if this is a well-behaved chain of instructions leading back to +/// the PHI. If so, it may be reused by expanded expressions. +bool SCEVExpander::isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV, + const Loop *L) { + if (IncV->getNumOperands() == 0 || isa(IncV) || + (isa(IncV) && !isa(IncV))) + return false; + // If any of the operands don't dominate the insert position, bail. + // Addrec operands are always loop-invariant, so this can only happen + // if there are instructions which haven't been hoisted. + if (L == IVIncInsertLoop) { + for (User::op_iterator OI = IncV->op_begin()+1, + OE = IncV->op_end(); OI != OE; ++OI) + if (Instruction *OInst = dyn_cast(OI)) + if (!SE.DT->dominates(OInst, IVIncInsertPos)) + return false; + } + // Advance to the next instruction. + IncV = dyn_cast(IncV->getOperand(0)); + if (!IncV) + return false; + + if (IncV->mayHaveSideEffects()) + return false; + + if (IncV != PN) + return true; + + return isNormalAddRecExprPHI(PN, IncV, L); +} + +/// Determine if this cyclic phi is in a form that would have been generated by +/// LSR. We don't care if the phi was actually expanded in this pass, as long +/// as it is in a low-cost form, for example, no implied multiplication. This +/// should match any patterns generated by getAddRecExprPHILiterally and +/// expandAddtoGEP. +bool SCEVExpander::isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, + const Loop *L) { + switch (IncV->getOpcode()) { + // Check for a simple Add/Sub or GEP of a loop invariant step. + case Instruction::Add: + case Instruction::Sub: + return IncV->getOperand(0) == PN + && L->isLoopInvariant(IncV->getOperand(1)); + case Instruction::BitCast: + IncV = dyn_cast(IncV->getOperand(0)); + if (!IncV) + return false; + // fall-thru to GEP handling + case Instruction::GetElementPtr: { + // This must be a pointer addition of constants (pretty) or some number of + // address-size elements (ugly). + for (Instruction::op_iterator I = IncV->op_begin()+1, E = IncV->op_end(); + I != E; ++I) { + if (isa(*I)) + continue; + // ugly geps have 2 operands. + // i1* is used by the expander to represent an address-size element. + if (IncV->getNumOperands() != 2) + return false; + unsigned AS = cast(IncV->getType())->getAddressSpace(); + if (IncV->getType() != Type::getInt1PtrTy(SE.getContext(), AS) + && IncV->getType() != Type::getInt8PtrTy(SE.getContext(), AS)) + return false; + // Ensure the operands dominate the insertion point. I don't know of a + // case when this would not be true, so this is somewhat untested. + if (L == IVIncInsertLoop) { + for (User::op_iterator OI = IncV->op_begin()+1, + OE = IncV->op_end(); OI != OE; ++OI) + if (Instruction *OInst = dyn_cast(OI)) + if (!SE.DT->dominates(OInst, IVIncInsertPos)) + return false; + } + break; + } + IncV = dyn_cast(IncV->getOperand(0)); + if (IncV && IncV->getOpcode() == Instruction::BitCast) + IncV = dyn_cast(IncV->getOperand(0)); + return IncV == PN; + } + default: + return false; + } +} + /// getAddRecExprPHILiterally - Helper for expandAddRecExprLiterally. Expand /// the base addrec, which is the addrec without any non-loop-dominating /// values, and return the PHI. PHINode * SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, const Loop *L, - const Type *ExpandTy, - const Type *IntTy) { + Type *ExpandTy, + Type *IntTy) { assert((!IVIncInsertLoop||IVIncInsertPos) && "Uninitialized insert position"); // Reuse a previously-inserted PHI, if present. - for (BasicBlock::iterator I = L->getHeader()->begin(); - PHINode *PN = dyn_cast(I); ++I) - 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(PN->getIncomingValueForBlock(LatchBlock)); + BasicBlock *LatchBlock = L->getLoopLatch(); + if (LatchBlock) { + for (BasicBlock::iterator I = L->getHeader()->begin(); + PHINode *PN = dyn_cast(I); ++I) { + if (!SE.isSCEVable(PN->getType()) || + (SE.getEffectiveSCEVType(PN->getType()) != + SE.getEffectiveSCEVType(Normalized->getType())) || + SE.getSCEV(PN) != Normalized) + continue; - // 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(IncV) || - (isa(IncV) && !isa(IncV))) { - IncV = 0; - break; - } - // If any of the operands don't dominate the insert position, bail. - // Addrec operands are always loop-invariant, so this can only happen - // if there are instructions which haven't been hoisted. - if (L == IVIncInsertLoop) { - for (User::op_iterator OI = IncV->op_begin()+1, - OE = IncV->op_end(); OI != OE; ++OI) - if (Instruction *OInst = dyn_cast(OI)) - if (!SE.DT->dominates(OInst, IVIncInsertPos)) { - IncV = 0; - break; - } - } - if (!IncV) - break; - // Advance to the next instruction. - IncV = dyn_cast(IncV->getOperand(0)); - if (!IncV) - break; - if (IncV->mayHaveSideEffects()) { - IncV = 0; - break; - } - } while (IncV != PN); + Instruction *IncV = + cast(PN->getIncomingValueForBlock(LatchBlock)); - if (IncV) { - // Ok, the add recurrence looks usable. - // Remember this PHI, even in post-inc mode. - InsertedValues.insert(PN); - // Remember the increment. - IncV = cast(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(IncV->getOperand(0)); - } while (IncV != PN); - return PN; - } + if (LSRMode) { + if (!isExpandedAddRecExprPHI(PN, IncV, L)) + continue; } + else { + if (!isNormalAddRecExprPHI(PN, IncV, L)) + continue; + } + // Ok, the add recurrence looks usable. + // Remember this PHI, even in post-inc mode. + InsertedValues.insert(PN); + // Remember the increment. + 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(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(); @@ -969,7 +1032,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, Value *IncV; // If the PHI is a pointer, use a GEP, otherwise use an add or sub. if (isPointer) { - const PointerType *GEPPtrTy = cast(ExpandTy); + PointerType *GEPPtrTy = cast(ExpandTy); // If the step isn't constant, don't use an implicitly scaled GEP, because // that would require a multiply inside the loop. if (!isa(StepV)) @@ -978,7 +1041,7 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, const SCEV *const StepArray[1] = { SE.getSCEV(StepV) }; IncV = expandAddToGEP(StepArray, StepArray+1, GEPPtrTy, IntTy, PN); if (IncV->getType() != PN->getType()) { - IncV = Builder.CreateBitCast(IncV, PN->getType(), "tmp"); + IncV = Builder.CreateBitCast(IncV, PN->getType()); rememberInstruction(IncV); } } else { @@ -1001,8 +1064,8 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, } Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) { - const Type *STy = S->getType(); - const Type *IntTy = SE.getEffectiveSCEVType(STy); + Type *STy = S->getType(); + Type *IntTy = SE.getEffectiveSCEVType(STy); const Loop *L = S->getLoop(); // Determine a normalized form of this expression, which is the expression @@ -1045,7 +1108,7 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) { // Expand the core addrec. If we need post-loop scaling, force it to // expand to an integer type to avoid the need for additional casting. - const Type *ExpandTy = PostLoopScale ? IntTy : STy; + Type *ExpandTy = PostLoopScale ? IntTy : STy; PHINode *PN = getAddRecExprPHILiterally(Normalized, L, ExpandTy, IntTy); // Accommodate post-inc mode, if necessary. @@ -1057,6 +1120,14 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) { BasicBlock *LatchBlock = L->getLoopLatch(); assert(LatchBlock && "PostInc mode requires a unique loop latch!"); Result = PN->getIncomingValueForBlock(LatchBlock); + + // For an expansion to use the postinc form, the client must call + // expandCodeFor with an InsertPoint that is either outside the PostIncLoop + // or dominated by IVIncInsertPos. + assert((!isa(Result) || + SE.DT->dominates(cast(Result), + Builder.GetInsertPoint())) && + "postinc expansion does not dominate use"); } // Re-apply any non-loop-dominating scale. @@ -1069,7 +1140,7 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) { // Re-apply any non-loop-dominating offset. if (PostLoopOffset) { - if (const PointerType *PTy = dyn_cast(ExpandTy)) { + if (PointerType *PTy = dyn_cast(ExpandTy)) { const SCEV *const OffsetArray[1] = { PostLoopOffset }; Result = expandAddToGEP(OffsetArray, OffsetArray+1, PTy, IntTy, Result); } else { @@ -1086,7 +1157,7 @@ Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) { Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { if (!CanonicalMode) return expandAddRecExprLiterally(S); - const Type *Ty = SE.getEffectiveSCEVType(S->getType()); + Type *Ty = SE.getEffectiveSCEVType(S->getType()); const Loop *L = S->getLoop(); // First check for an existing canonical IV in a suitable type. @@ -1110,7 +1181,8 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint(); BasicBlock::iterator NewInsertPt = llvm::next(BasicBlock::iterator(cast(V))); - while (isa(NewInsertPt) || isa(NewInsertPt)) + while (isa(NewInsertPt) || isa(NewInsertPt) || + isa(NewInsertPt)) ++NewInsertPt; V = expandCodeFor(SE.getTruncateExpr(SE.getUnknown(V), Ty), 0, NewInsertPt); @@ -1132,7 +1204,7 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { // Dig into the expression to find the pointer base for a GEP. ExposePointerBase(Base, RestArray[0], SE); // If we found a pointer, expand the AddRec with a GEP. - if (const PointerType *PTy = dyn_cast(Base->getType())) { + if (PointerType *PTy = dyn_cast(Base->getType())) { // Make sure the Base isn't something exotic, such as a multiplied // or divided pointer value. In those cases, the result type isn't // actually a pointer type. @@ -1216,35 +1288,35 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { } Value *SCEVExpander::visitTruncateExpr(const SCEVTruncateExpr *S) { - const Type *Ty = SE.getEffectiveSCEVType(S->getType()); + Type *Ty = SE.getEffectiveSCEVType(S->getType()); Value *V = expandCodeFor(S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType())); - Value *I = Builder.CreateTrunc(V, Ty, "tmp"); + Value *I = Builder.CreateTrunc(V, Ty); rememberInstruction(I); return I; } Value *SCEVExpander::visitZeroExtendExpr(const SCEVZeroExtendExpr *S) { - const Type *Ty = SE.getEffectiveSCEVType(S->getType()); + Type *Ty = SE.getEffectiveSCEVType(S->getType()); Value *V = expandCodeFor(S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType())); - Value *I = Builder.CreateZExt(V, Ty, "tmp"); + Value *I = Builder.CreateZExt(V, Ty); rememberInstruction(I); return I; } Value *SCEVExpander::visitSignExtendExpr(const SCEVSignExtendExpr *S) { - const Type *Ty = SE.getEffectiveSCEVType(S->getType()); + Type *Ty = SE.getEffectiveSCEVType(S->getType()); Value *V = expandCodeFor(S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType())); - Value *I = Builder.CreateSExt(V, Ty, "tmp"); + Value *I = Builder.CreateSExt(V, Ty); rememberInstruction(I); return I; } Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) { Value *LHS = expand(S->getOperand(S->getNumOperands()-1)); - const Type *Ty = LHS->getType(); + Type *Ty = LHS->getType(); for (int i = S->getNumOperands()-2; i >= 0; --i) { // In the case of mixed integer and pointer types, do the // rest of the comparisons as integer. @@ -1253,7 +1325,7 @@ Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) { LHS = InsertNoopCastOfTo(LHS, Ty); } Value *RHS = expandCodeFor(S->getOperand(i), Ty); - Value *ICmp = Builder.CreateICmpSGT(LHS, RHS, "tmp"); + Value *ICmp = Builder.CreateICmpSGT(LHS, RHS); rememberInstruction(ICmp); Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smax"); rememberInstruction(Sel); @@ -1268,7 +1340,7 @@ Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) { Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) { Value *LHS = expand(S->getOperand(S->getNumOperands()-1)); - const Type *Ty = LHS->getType(); + Type *Ty = LHS->getType(); for (int i = S->getNumOperands()-2; i >= 0; --i) { // In the case of mixed integer and pointer types, do the // rest of the comparisons as integer. @@ -1277,7 +1349,7 @@ Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) { LHS = InsertNoopCastOfTo(LHS, Ty); } Value *RHS = expandCodeFor(S->getOperand(i), Ty); - Value *ICmp = Builder.CreateICmpUGT(LHS, RHS, "tmp"); + Value *ICmp = Builder.CreateICmpUGT(LHS, RHS); rememberInstruction(ICmp); Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umax"); rememberInstruction(Sel); @@ -1290,7 +1362,7 @@ Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) { return LHS; } -Value *SCEVExpander::expandCodeFor(const SCEV *SH, const Type *Ty, +Value *SCEVExpander::expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I) { BasicBlock::iterator IP = I; while (isInsertedInstruction(IP) || isa(IP)) @@ -1299,7 +1371,7 @@ Value *SCEVExpander::expandCodeFor(const SCEV *SH, const Type *Ty, return expandCodeFor(SH, Ty); } -Value *SCEVExpander::expandCodeFor(const SCEV *SH, const Type *Ty) { +Value *SCEVExpander::expandCodeFor(const SCEV *SH, Type *Ty) { // Expand the code for this SCEV. Value *V = expand(SH); if (Ty) { @@ -1325,7 +1397,7 @@ Value *SCEVExpander::expand(const SCEV *S) { // after the PHIs (and after any other instructions that we've inserted // there) so that it is guaranteed to dominate any user inside the loop. if (L && SE.hasComputableLoopEvolution(S, L) && !PostIncLoops.count(L)) - InsertPt = L->getHeader()->getFirstNonPHI(); + InsertPt = L->getHeader()->getFirstInsertionPt(); while (isInsertedInstruction(InsertPt) || isa(InsertPt)) InsertPt = llvm::next(BasicBlock::iterator(InsertPt)); break; @@ -1346,8 +1418,12 @@ Value *SCEVExpander::expand(const SCEV *S) { Value *V = visit(S); // Remember the expanded value for this SCEV at this location. - if (PostIncLoops.empty()) - InsertedExpressions[std::make_pair(S, InsertPt)] = V; + // + // This is independent of PostIncLoops. The mapped value simply materializes + // the expression at this insertion point. If the mapped value happened to be + // a postinc expansion, it could be reused by a non postinc user, but only if + // its insertion point was already at the head of the loop. + InsertedExpressions[std::make_pair(S, InsertPt)] = V; restoreInsertPoint(SaveInsertBB, SaveInsertPt); return V; @@ -1384,7 +1460,7 @@ void SCEVExpander::restoreInsertPoint(BasicBlock *BB, BasicBlock::iterator I) { /// starts at zero and steps by one on each iteration. PHINode * SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L, - const Type *Ty) { + Type *Ty) { assert(Ty->isIntegerTy() && "Can only insert integer induction variables!"); // Build a SCEV for {0,+,1}. @@ -1401,3 +1477,102 @@ SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L, return V; } + +/// hoistStep - Attempt to hoist an IV increment above a potential use. +/// +/// To successfully hoist, two criteria must be met: +/// - IncV operands dominate InsertPos and +/// - InsertPos dominates IncV +/// +/// Meeting the second condition means that we don't need to check all of IncV's +/// existing uses (it's moving up in the domtree). +/// +/// This does not yet recursively hoist the operands, although that would +/// not be difficult. +/// +/// This does not require a SCEVExpander instance and could be replaced by a +/// general code-insertion helper. +bool SCEVExpander::hoistStep(Instruction *IncV, Instruction *InsertPos, + const DominatorTree *DT) { + if (DT->dominates(IncV, InsertPos)) + return true; + + if (!DT->dominates(InsertPos->getParent(), IncV->getParent())) + return false; + + if (IncV->mayHaveSideEffects()) + return false; + + // Attempt to hoist IncV + for (User::op_iterator OI = IncV->op_begin(), OE = IncV->op_end(); + OI != OE; ++OI) { + Instruction *OInst = dyn_cast(OI); + if (OInst && !DT->dominates(OInst, InsertPos)) + return false; + } + IncV->moveBefore(InsertPos); + return true; +} + +/// replaceCongruentIVs - Check for congruent phis in this loop header and +/// replace them with their most canonical representative. Return the number of +/// phis eliminated. +/// +/// This does not depend on any SCEVExpander state but should be used in +/// the same context that SCEVExpander is used. +unsigned SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT, + SmallVectorImpl &DeadInsts) { + unsigned NumElim = 0; + DenseMap ExprToIVMap; + for (BasicBlock::iterator I = L->getHeader()->begin(); isa(I); ++I) { + PHINode *Phi = cast(I); + if (!SE.isSCEVable(Phi->getType())) + continue; + + PHINode *&OrigPhiRef = ExprToIVMap[SE.getSCEV(Phi)]; + if (!OrigPhiRef) { + OrigPhiRef = Phi; + continue; + } + + // If one phi derives from the other via GEPs, types may differ. + // We could consider adding a bitcast here to handle it. + if (OrigPhiRef->getType() != Phi->getType()) + continue; + + if (BasicBlock *LatchBlock = L->getLoopLatch()) { + Instruction *OrigInc = + cast(OrigPhiRef->getIncomingValueForBlock(LatchBlock)); + Instruction *IsomorphicInc = + cast(Phi->getIncomingValueForBlock(LatchBlock)); + + // If this phi is more canonical, swap it with the original. + if (!isExpandedAddRecExprPHI(OrigPhiRef, OrigInc, L) + && isExpandedAddRecExprPHI(Phi, IsomorphicInc, L)) { + std::swap(OrigPhiRef, Phi); + std::swap(OrigInc, IsomorphicInc); + } + // Replacing the congruent phi is sufficient because acyclic redundancy + // elimination, CSE/GVN, should handle the rest. However, once SCEV proves + // that a phi is congruent, it's often the head of an IV user cycle that + // is isomorphic with the original phi. So it's worth eagerly cleaning up + // the common case of a single IV increment. + if (OrigInc != IsomorphicInc && + OrigInc->getType() == IsomorphicInc->getType() && + SE.getSCEV(OrigInc) == SE.getSCEV(IsomorphicInc) && + hoistStep(OrigInc, IsomorphicInc, DT)) { + DEBUG_WITH_TYPE(DebugType, dbgs() + << "INDVARS: Eliminated congruent iv.inc: " + << *IsomorphicInc << '\n'); + IsomorphicInc->replaceAllUsesWith(OrigInc); + DeadInsts.push_back(IsomorphicInc); + } + } + DEBUG_WITH_TYPE(DebugType, dbgs() + << "INDVARS: Eliminated congruent iv: " << *Phi << '\n'); + ++NumElim; + Phi->replaceAllUsesWith(OrigPhiRef); + DeadInsts.push_back(Phi); + } + return NumElim; +} diff --git a/lib/Analysis/ScalarEvolutionNormalization.cpp b/lib/Analysis/ScalarEvolutionNormalization.cpp index 60e630aaab88..c66ecd6e8727 100644 --- a/lib/Analysis/ScalarEvolutionNormalization.cpp +++ b/lib/Analysis/ScalarEvolutionNormalization.cpp @@ -60,20 +60,40 @@ static bool IVUseShouldUsePostIncValue(Instruction *User, Value *Operand, return true; } -const SCEV *llvm::TransformForPostIncUse(TransformKind Kind, - const SCEV *S, - Instruction *User, - Value *OperandValToReplace, - PostIncLoopSet &Loops, - ScalarEvolution &SE, - DominatorTree &DT) { - if (isa(S) || isa(S)) - return S; +namespace { + +/// Hold the state used during post-inc expression transformation, including a +/// map of transformed expressions. +class PostIncTransform { + TransformKind Kind; + PostIncLoopSet &Loops; + ScalarEvolution &SE; + DominatorTree &DT; + + DenseMap Transformed; + +public: + PostIncTransform(TransformKind kind, PostIncLoopSet &loops, + ScalarEvolution &se, DominatorTree &dt): + Kind(kind), Loops(loops), SE(se), DT(dt) {} + + const SCEV *TransformSubExpr(const SCEV *S, Instruction *User, + Value *OperandValToReplace); + +protected: + const SCEV *TransformImpl(const SCEV *S, Instruction *User, + Value *OperandValToReplace); +}; + +} // namespace + +/// Implement post-inc transformation for all valid expression types. +const SCEV *PostIncTransform:: +TransformImpl(const SCEV *S, Instruction *User, Value *OperandValToReplace) { if (const SCEVCastExpr *X = dyn_cast(S)) { const SCEV *O = X->getOperand(); - const SCEV *N = TransformForPostIncUse(Kind, O, User, OperandValToReplace, - Loops, SE, DT); + const SCEV *N = TransformSubExpr(O, User, OperandValToReplace); if (O != N) switch (S->getSCEVType()) { case scZeroExtend: return SE.getZeroExtendExpr(N, S->getType()); @@ -93,9 +113,7 @@ const SCEV *llvm::TransformForPostIncUse(TransformKind Kind, // Transform each operand. for (SCEVNAryExpr::op_iterator I = AR->op_begin(), E = AR->op_end(); I != E; ++I) { - const SCEV *O = *I; - const SCEV *N = TransformForPostIncUse(Kind, O, LUser, 0, Loops, SE, DT); - Operands.push_back(N); + Operands.push_back(TransformSubExpr(*I, LUser, 0)); } // Conservatively use AnyWrap until/unless we need FlagNW. const SCEV *Result = SE.getAddRecExpr(Operands, L, SCEV::FlagAnyWrap); @@ -104,8 +122,8 @@ const SCEV *llvm::TransformForPostIncUse(TransformKind Kind, case NormalizeAutodetect: if (IVUseShouldUsePostIncValue(User, OperandValToReplace, L, &DT)) { const SCEV *TransformedStep = - TransformForPostIncUse(Kind, AR->getStepRecurrence(SE), - User, OperandValToReplace, Loops, SE, DT); + TransformSubExpr(AR->getStepRecurrence(SE), + User, OperandValToReplace); Result = SE.getMinusSCEV(Result, TransformedStep); Loops.insert(L); } @@ -114,24 +132,20 @@ const SCEV *llvm::TransformForPostIncUse(TransformKind Kind, // sometimes fails to canonicalize two equal SCEVs to exactly the same // form. It's possibly a pessimization when this happens, but it isn't a // correctness problem, so disable this assert for now. - assert(S == TransformForPostIncUse(Denormalize, Result, - User, OperandValToReplace, - Loops, SE, DT) && + assert(S == TransformSubExpr(Result, User, OperandValToReplace) && "SCEV normalization is not invertible!"); #endif break; case Normalize: if (Loops.count(L)) { const SCEV *TransformedStep = - TransformForPostIncUse(Kind, AR->getStepRecurrence(SE), - User, OperandValToReplace, Loops, SE, DT); + TransformSubExpr(AR->getStepRecurrence(SE), + User, OperandValToReplace); Result = SE.getMinusSCEV(Result, TransformedStep); } #if 0 // See the comment on the assert above. - assert(S == TransformForPostIncUse(Denormalize, Result, - User, OperandValToReplace, - Loops, SE, DT) && + assert(S == TransformSubExpr(Result, User, OperandValToReplace) && "SCEV normalization is not invertible!"); #endif break; @@ -150,8 +164,7 @@ const SCEV *llvm::TransformForPostIncUse(TransformKind Kind, for (SCEVNAryExpr::op_iterator I = X->op_begin(), E = X->op_end(); I != E; ++I) { const SCEV *O = *I; - const SCEV *N = TransformForPostIncUse(Kind, O, User, OperandValToReplace, - Loops, SE, DT); + const SCEV *N = TransformSubExpr(O, User, OperandValToReplace); Changed |= N != O; Operands.push_back(N); } @@ -170,10 +183,8 @@ const SCEV *llvm::TransformForPostIncUse(TransformKind Kind, if (const SCEVUDivExpr *X = dyn_cast(S)) { const SCEV *LO = X->getLHS(); const SCEV *RO = X->getRHS(); - const SCEV *LN = TransformForPostIncUse(Kind, LO, User, OperandValToReplace, - Loops, SE, DT); - const SCEV *RN = TransformForPostIncUse(Kind, RO, User, OperandValToReplace, - Loops, SE, DT); + const SCEV *LN = TransformSubExpr(LO, User, OperandValToReplace); + const SCEV *RN = TransformSubExpr(RO, User, OperandValToReplace); if (LO != LN || RO != RN) return SE.getUDivExpr(LN, RN); return S; @@ -182,3 +193,33 @@ const SCEV *llvm::TransformForPostIncUse(TransformKind Kind, llvm_unreachable("Unexpected SCEV kind!"); return 0; } + +/// Manage recursive transformation across an expression DAG. Revisiting +/// expressions would lead to exponential recursion. +const SCEV *PostIncTransform:: +TransformSubExpr(const SCEV *S, Instruction *User, Value *OperandValToReplace) { + + if (isa(S) || isa(S)) + return S; + + const SCEV *Result = Transformed.lookup(S); + if (Result) + return Result; + + Result = TransformImpl(S, User, OperandValToReplace); + Transformed[S] = Result; + return Result; +} + +/// Top level driver for transforming an expression DAG into its requested +/// post-inc form (either "Normalized" or "Denormalized". +const SCEV *llvm::TransformForPostIncUse(TransformKind Kind, + const SCEV *S, + Instruction *User, + Value *OperandValToReplace, + PostIncLoopSet &Loops, + ScalarEvolution &SE, + DominatorTree &DT) { + PostIncTransform Transform(Kind, Loops, SE, DT); + return Transform.TransformSubExpr(S, User, OperandValToReplace); +} diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 455c91077dfb..4d94f619fda1 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -34,7 +34,7 @@ const unsigned MaxDepth = 6; /// getBitWidth - Returns the bitwidth of the given scalar or pointer type (if /// unknown returns 0). For vector types, returns the element type's bitwidth. -static unsigned getBitWidth(const Type *Ty, const TargetData *TD) { +static unsigned getBitWidth(Type *Ty, const TargetData *TD) { if (unsigned BitWidth = Ty->getScalarSizeInBits()) return BitWidth; assert(isa(Ty) && "Expected a pointer type!"); @@ -103,7 +103,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask, if (GlobalValue *GV = dyn_cast(V)) { unsigned Align = GV->getAlignment(); if (Align == 0 && TD && GV->getType()->getElementType()->isSized()) { - const Type *ObjectType = GV->getType()->getElementType(); + Type *ObjectType = GV->getType()->getElementType(); // If the object is defined in the current Module, we'll be giving // it the preferred alignment. Otherwise, we have to assume that it // may only have the minimum ABI alignment. @@ -268,7 +268,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask, // FALL THROUGH and handle them the same as zext/trunc. case Instruction::ZExt: case Instruction::Trunc: { - const Type *SrcTy = I->getOperand(0)->getType(); + Type *SrcTy = I->getOperand(0)->getType(); unsigned SrcBitWidth; // Note that we handle pointer operands here because of inttoptr/ptrtoint @@ -291,7 +291,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask, return; } case Instruction::BitCast: { - const Type *SrcTy = I->getOperand(0)->getType(); + Type *SrcTy = I->getOperand(0)->getType(); if ((SrcTy->isIntegerTy() || SrcTy->isPointerTy()) && // TODO: For now, not handling conversions like: // (bitcast i64 %x to <2 x i32>) @@ -559,7 +559,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask, gep_type_iterator GTI = gep_type_begin(I); for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i, ++GTI) { Value *Index = I->getOperand(i); - if (const StructType *STy = dyn_cast(*GTI)) { + if (StructType *STy = dyn_cast(*GTI)) { // Handle struct member offset arithmetic. if (!TD) return; const StructLayout *SL = TD->getStructLayout(STy); @@ -569,7 +569,7 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask, CountTrailingZeros_64(Offset)); } else { // Handle array index arithmetic. - const Type *IndexedTy = GTI.getIndexedType(); + Type *IndexedTy = GTI.getIndexedType(); if (!IndexedTy->isSized()) return; unsigned GEPOpiBits = Index->getType()->getScalarSizeInBits(); uint64_t TypeSize = TD ? TD->getTypeAllocSize(IndexedTy) : 1; @@ -898,7 +898,7 @@ unsigned llvm::ComputeNumSignBits(Value *V, const TargetData *TD, assert((TD || V->getType()->isIntOrIntVectorTy()) && "ComputeNumSignBits requires a TargetData object to operate " "on non-integer values!"); - const Type *Ty = V->getType(); + Type *Ty = V->getType(); unsigned TyBits = TD ? TD->getTypeSizeInBits(V->getType()->getScalarType()) : Ty->getScalarSizeInBits(); unsigned Tmp, Tmp2; @@ -1078,7 +1078,7 @@ bool llvm::ComputeMultiple(Value *V, unsigned Base, Value *&Multiple, assert(Depth <= MaxDepth && "Limit Search Depth"); assert(V->getType()->isIntegerTy() && "Not integer or pointer type!"); - const Type *T = V->getType(); + Type *T = V->getType(); ConstantInt *CI = dyn_cast(V); @@ -1315,11 +1315,11 @@ Value *llvm::isBytewiseValue(Value *V) { // indices from Idxs that should be left out when inserting into the resulting // struct. To is the result struct built so far, new insertvalue instructions // build on that. -static Value *BuildSubAggregate(Value *From, Value* To, const Type *IndexedType, +static Value *BuildSubAggregate(Value *From, Value* To, Type *IndexedType, SmallVector &Idxs, unsigned IdxSkip, Instruction *InsertBefore) { - const llvm::StructType *STy = llvm::dyn_cast(IndexedType); + llvm::StructType *STy = llvm::dyn_cast(IndexedType); if (STy) { // Save the original To argument so we can modify it Value *OrigTo = To; @@ -1358,8 +1358,7 @@ static Value *BuildSubAggregate(Value *From, Value* To, const Type *IndexedType, return NULL; // Insert the value in the new (sub) aggregrate - return llvm::InsertValueInst::Create(To, V, - ArrayRef(Idxs).slice(IdxSkip), + return llvm::InsertValueInst::Create(To, V, makeArrayRef(Idxs).slice(IdxSkip), "tmp", InsertBefore); } @@ -1378,7 +1377,7 @@ static Value *BuildSubAggregate(Value *From, Value* To, const Type *IndexedType, static Value *BuildSubAggregate(Value *From, ArrayRef idx_range, Instruction *InsertBefore) { assert(InsertBefore && "Must have someplace to insert!"); - const Type *IndexedType = ExtractValueInst::getIndexedType(From->getType(), + Type *IndexedType = ExtractValueInst::getIndexedType(From->getType(), idx_range); Value *To = UndefValue::get(IndexedType); SmallVector Idxs(idx_range.begin(), idx_range.end()); @@ -1404,7 +1403,7 @@ Value *llvm::FindInsertedValue(Value *V, ArrayRef idx_range, && "Not looking at a struct or array?"); assert(ExtractValueInst::getIndexedType(V->getType(), idx_range) && "Invalid indices for type?"); - const CompositeType *PTy = cast(V->getType()); + CompositeType *PTy = cast(V->getType()); if (isa(V)) return UndefValue::get(ExtractValueInst::getIndexedType(PTy, @@ -1435,9 +1434,7 @@ Value *llvm::FindInsertedValue(Value *V, ArrayRef idx_range, // %C = insertvalue {i32, i32 } %A, i32 11, 1 // which allows the unused 0,0 element from the nested struct to be // removed. - return BuildSubAggregate(V, - ArrayRef(idx_range.begin(), - req_idx), + return BuildSubAggregate(V, makeArrayRef(idx_range.begin(), req_idx), InsertBefore); else // We can't handle this without inserting insertvalues @@ -1455,7 +1452,7 @@ Value *llvm::FindInsertedValue(Value *V, ArrayRef idx_range, // requested (though possibly only partially). Now we recursively look at // the inserted value, passing any remaining indices. return FindInsertedValue(I->getInsertedValueOperand(), - ArrayRef(req_idx, idx_range.end()), + makeArrayRef(req_idx, idx_range.end()), InsertBefore); } else if (ExtractValueInst *I = dyn_cast(V)) { // If we're extracting a value from an aggregrate that was extracted from @@ -1506,7 +1503,7 @@ Value *llvm::GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, if (OpC->isZero()) continue; // Handle a struct and array indices which add their offset to the pointer. - if (const StructType *STy = dyn_cast(*GTI)) { + if (StructType *STy = dyn_cast(*GTI)) { Offset += TD.getStructLayout(STy)->getElementOffset(OpC->getZExtValue()); } else { uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()); @@ -1557,8 +1554,8 @@ bool llvm::GetConstantStringInfo(const Value *V, std::string &Str, return false; // Make sure the index-ee is a pointer to array of i8. - const PointerType *PT = cast(GEP->getOperand(0)->getType()); - const ArrayType *AT = dyn_cast(PT->getElementType()); + PointerType *PT = cast(GEP->getOperand(0)->getType()); + ArrayType *AT = dyn_cast(PT->getElementType()); if (AT == 0 || !AT->getElementType()->isIntegerTy(8)) return false; diff --git a/lib/Archive/CMakeLists.txt b/lib/Archive/CMakeLists.txt index 7ff478a41a59..b52974e0753d 100644 --- a/lib/Archive/CMakeLists.txt +++ b/lib/Archive/CMakeLists.txt @@ -3,3 +3,9 @@ add_llvm_library(LLVMArchive ArchiveReader.cpp ArchiveWriter.cpp ) + +add_llvm_library_dependencies(LLVMArchive + LLVMBitReader + LLVMCore + LLVMSupport + ) diff --git a/lib/AsmParser/CMakeLists.txt b/lib/AsmParser/CMakeLists.txt index 985ebe200988..749601510b5b 100644 --- a/lib/AsmParser/CMakeLists.txt +++ b/lib/AsmParser/CMakeLists.txt @@ -4,3 +4,8 @@ add_llvm_library(LLVMAsmParser LLParser.cpp Parser.cpp ) + +add_llvm_library_dependencies(LLVMAsmParser + LLVMCore + LLVMSupport + ) diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 3c63106e8c3b..d0dd98627bab 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -506,6 +506,15 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(deplibs); KEYWORD(datalayout); KEYWORD(volatile); + KEYWORD(atomic); + KEYWORD(unordered); + KEYWORD(monotonic); + KEYWORD(acquire); + KEYWORD(release); + KEYWORD(acq_rel); + KEYWORD(seq_cst); + KEYWORD(singlethread); + KEYWORD(nuw); KEYWORD(nsw); KEYWORD(exact); @@ -549,6 +558,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(readnone); KEYWORD(readonly); KEYWORD(uwtable); + KEYWORD(returns_twice); KEYWORD(inlinehint); KEYWORD(noinline); @@ -559,7 +569,6 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(noredzone); KEYWORD(noimplicitfloat); KEYWORD(naked); - KEYWORD(hotpatch); KEYWORD(nonlazybind); KEYWORD(type); @@ -570,8 +579,16 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(oeq); KEYWORD(one); KEYWORD(olt); KEYWORD(ogt); KEYWORD(ole); KEYWORD(oge); KEYWORD(ord); KEYWORD(uno); KEYWORD(ueq); KEYWORD(une); + KEYWORD(xchg); KEYWORD(nand); KEYWORD(max); KEYWORD(min); KEYWORD(umax); + KEYWORD(umin); + KEYWORD(x); KEYWORD(blockaddress); + + KEYWORD(personality); + KEYWORD(cleanup); + KEYWORD(catch); + KEYWORD(filter); #undef KEYWORD // Keywords for types. @@ -624,12 +641,16 @@ lltok::Kind LLLexer::LexIdentifier() { INSTKEYWORD(switch, Switch); INSTKEYWORD(indirectbr, IndirectBr); INSTKEYWORD(invoke, Invoke); + INSTKEYWORD(resume, Resume); INSTKEYWORD(unwind, Unwind); INSTKEYWORD(unreachable, Unreachable); INSTKEYWORD(alloca, Alloca); INSTKEYWORD(load, Load); INSTKEYWORD(store, Store); + INSTKEYWORD(cmpxchg, AtomicCmpXchg); + INSTKEYWORD(atomicrmw, AtomicRMW); + INSTKEYWORD(fence, Fence); INSTKEYWORD(getelementptr, GetElementPtr); INSTKEYWORD(extractelement, ExtractElement); @@ -637,6 +658,7 @@ lltok::Kind LLLexer::LexIdentifier() { INSTKEYWORD(shufflevector, ShuffleVector); INSTKEYWORD(extractvalue, ExtractValue); INSTKEYWORD(insertvalue, InsertValue); + INSTKEYWORD(landingpad, LandingPad); #undef INSTKEYWORD // Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by @@ -704,17 +726,17 @@ lltok::Kind LLLexer::Lex0x() { case 'K': // F80HexFPConstant - x87 long double in hexadecimal format (10 bytes) FP80HexToIntPair(TokStart+3, CurPtr, Pair); - APFloatVal = APFloat(APInt(80, 2, Pair)); + APFloatVal = APFloat(APInt(80, Pair)); return lltok::APFloat; case 'L': // F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes) HexToIntPair(TokStart+3, CurPtr, Pair); - APFloatVal = APFloat(APInt(128, 2, Pair), true); + APFloatVal = APFloat(APInt(128, Pair), true); return lltok::APFloat; case 'M': // PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes) HexToIntPair(TokStart+3, CurPtr, Pair); - APFloatVal = APFloat(APInt(128, 2, Pair)); + APFloatVal = APFloat(APInt(128, Pair)); return lltok::APFloat; } } diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index cfc31f3db8a7..cafaab01afd9 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -26,7 +26,7 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; -static std::string getTypeString(const Type *T) { +static std::string getTypeString(Type *T) { std::string Result; raw_string_ostream Tmp(Result); Tmp << *T; @@ -120,6 +120,9 @@ bool LLParser::ValidateEndOfModule() { for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ) UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove + // Upgrade to new EH scheme. N.B. This will go away in 3.1. + UpgradeExceptionHandling(M); + // Check debug info intrinsics. CheckDebugInfoIntrinsics(M); return false; @@ -744,9 +747,9 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, /// GetGlobalVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. -GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty, +GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, LocTy Loc) { - const PointerType *PTy = dyn_cast(Ty); + PointerType *PTy = dyn_cast(Ty); if (PTy == 0) { Error(Loc, "global variable reference must have pointer type"); return 0; @@ -775,7 +778,7 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty, // Otherwise, create a new forward reference for this value and remember it. GlobalValue *FwdVal; - if (const FunctionType *FT = dyn_cast(PTy->getElementType())) + if (FunctionType *FT = dyn_cast(PTy->getElementType())) FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); else FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, @@ -785,8 +788,8 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty, return FwdVal; } -GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) { - const PointerType *PTy = dyn_cast(Ty); +GlobalValue *LLParser::GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc) { + PointerType *PTy = dyn_cast(Ty); if (PTy == 0) { Error(Loc, "global variable reference must have pointer type"); return 0; @@ -813,7 +816,7 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) { // Otherwise, create a new forward reference for this value and remember it. GlobalValue *FwdVal; - if (const FunctionType *FT = dyn_cast(PTy->getElementType())) + if (FunctionType *FT = dyn_cast(PTy->getElementType())) FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M); else FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, @@ -908,6 +911,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break; case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break; case lltok::kw_uwtable: Attrs |= Attribute::UWTable; break; + case lltok::kw_returns_twice: Attrs |= Attribute::ReturnsTwice; break; case lltok::kw_noinline: Attrs |= Attribute::NoInline; break; case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break; case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break; @@ -919,7 +923,6 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break; case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break; case lltok::kw_naked: Attrs |= Attribute::Naked; break; - case lltok::kw_hotpatch: Attrs |= Attribute::Hotpatch; break; case lltok::kw_nonlazybind: Attrs |= Attribute::NonLazyBind; break; case lltok::kw_alignstack: { @@ -1145,6 +1148,32 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment, return false; } +/// ParseScopeAndOrdering +/// if isAtomic: ::= 'singlethread'? AtomicOrdering +/// else: ::= +/// +/// This sets Scope and Ordering to the parsed values. +bool LLParser::ParseScopeAndOrdering(bool isAtomic, SynchronizationScope &Scope, + AtomicOrdering &Ordering) { + if (!isAtomic) + return false; + + Scope = CrossThread; + if (EatIfPresent(lltok::kw_singlethread)) + Scope = SingleThread; + switch (Lex.getKind()) { + default: return TokError("Expected ordering on atomic instruction"); + case lltok::kw_unordered: Ordering = Unordered; break; + case lltok::kw_monotonic: Ordering = Monotonic; break; + case lltok::kw_acquire: Ordering = Acquire; break; + case lltok::kw_release: Ordering = Release; break; + case lltok::kw_acq_rel: Ordering = AcquireRelease; break; + case lltok::kw_seq_cst: Ordering = SequentiallyConsistent; break; + } + Lex.Lex(); + return false; +} + /// ParseOptionalStackAlignment /// ::= /* empty */ /// ::= 'alignstack' '(' 4 ')' @@ -1237,7 +1266,7 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) { // If the type hasn't been defined yet, create a forward definition and // remember where that forward def'n was seen (in case it never is defined). if (Entry.first == 0) { - Entry.first = StructType::createNamed(Context, Lex.getStrVal()); + Entry.first = StructType::create(Context, Lex.getStrVal()); Entry.second = Lex.getLoc(); } Result = Entry.first; @@ -1254,7 +1283,7 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) { // If the type hasn't been defined yet, create a forward definition and // remember where that forward def'n was seen (in case it never is defined). if (Entry.first == 0) { - Entry.first = StructType::createNamed(Context, ""); + Entry.first = StructType::create(Context); Entry.second = Lex.getLoc(); } Result = Entry.first; @@ -1476,7 +1505,7 @@ bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name, // If this type number has never been uttered, create it. if (Entry.first == 0) - Entry.first = StructType::createNamed(Context, Name); + Entry.first = StructType::create(Context, Name); ResultTy = Entry.first; return false; } @@ -1502,7 +1531,7 @@ bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name, // If this type number has never been uttered, create it. if (Entry.first == 0) - Entry.first = StructType::createNamed(Context, Name); + Entry.first = StructType::create(Context, Name); StructType *STy = cast(Entry.first); @@ -1668,7 +1697,7 @@ bool LLParser::PerFunctionState::FinishFunction() { /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. Value *LLParser::PerFunctionState::GetVal(const std::string &Name, - const Type *Ty, LocTy Loc) { + Type *Ty, LocTy Loc) { // Look this name up in the normal function symbol table. Value *Val = F.getValueSymbolTable().lookup(Name); @@ -1709,7 +1738,7 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, return FwdVal; } -Value *LLParser::PerFunctionState::GetVal(unsigned ID, const Type *Ty, +Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc) { // Look this name up in the normal function symbol table. Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : 0; @@ -2273,16 +2302,11 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { if (Elts.size() == 0 || !Elts[0]->getType()->isPointerTy()) return Error(ID.Loc, "getelementptr requires pointer operand"); - if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(), - (Value**)(Elts.data() + 1), - Elts.size() - 1)) + ArrayRef Indices(Elts.begin() + 1, Elts.end()); + if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(), Indices)) return Error(ID.Loc, "invalid indices for getelementptr"); - ID.ConstantVal = InBounds ? - ConstantExpr::getInBoundsGetElementPtr(Elts[0], - Elts.data() + 1, - Elts.size() - 1) : - ConstantExpr::getGetElementPtr(Elts[0], - Elts.data() + 1, Elts.size() - 1); + ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0], Indices, + InBounds); } else if (Opc == Instruction::Select) { if (Elts.size() != 3) return Error(ID.Loc, "expected three operands to select"); @@ -2323,7 +2347,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { } /// ParseGlobalValue - Parse a global value with the specified type. -bool LLParser::ParseGlobalValue(const Type *Ty, Constant *&C) { +bool LLParser::ParseGlobalValue(Type *Ty, Constant *&C) { C = 0; ValID ID; Value *V = NULL; @@ -2410,7 +2434,7 @@ bool LLParser::ParseMetadataValue(ValID &ID, PerFunctionState *PFS) { // Function Parsing. //===----------------------------------------------------------------------===// -bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, +bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, PerFunctionState *PFS) { if (Ty->isFunctionTy()) return Error(ID.Loc, "functions are not values, refer to them as pointers"); @@ -2426,8 +2450,8 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, V = PFS->GetVal(ID.StrVal, Ty, ID.Loc); return (V == 0); case ValID::t_InlineAsm: { - const PointerType *PTy = dyn_cast(Ty); - const FunctionType *FTy = + PointerType *PTy = dyn_cast(Ty); + FunctionType *FTy = PTy ? dyn_cast(PTy->getElementType()) : 0; if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2)) return Error(ID.Loc, "invalid type for inline asm constraint string"); @@ -2506,7 +2530,7 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, return false; case ValID::t_ConstantStruct: case ValID::t_PackedConstantStruct: - if (const StructType *ST = dyn_cast(Ty)) { + if (StructType *ST = dyn_cast(Ty)) { if (ST->getNumElements() != ID.UIntVal) return Error(ID.Loc, "initializer with struct type has wrong # elements"); @@ -2519,15 +2543,15 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, return Error(ID.Loc, "element " + Twine(i) + " of struct initializer doesn't match struct element type"); - V = ConstantStruct::get(ST, ArrayRef(ID.ConstantStructElts, - ID.UIntVal)); + V = ConstantStruct::get(ST, makeArrayRef(ID.ConstantStructElts, + ID.UIntVal)); } else return Error(ID.Loc, "constant expression type mismatch"); return false; } } -bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState *PFS) { +bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS) { V = 0; ValID ID; return ParseValID(ID, PFS) || @@ -2671,9 +2695,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { if (PAL.paramHasAttr(1, Attribute::StructRet) && !RetType->isVoidTy()) return Error(RetTypeLoc, "functions with 'sret' argument must return void"); - const FunctionType *FT = + FunctionType *FT = FunctionType::get(RetType, ParamTypeList, isVarArg); - const PointerType *PFT = PointerType::getUnqual(FT); + PointerType *PFT = PointerType::getUnqual(FT); Fn = 0; if (!FunctionName.empty()) { @@ -2864,6 +2888,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_switch: return ParseSwitch(Inst, PFS); case lltok::kw_indirectbr: return ParseIndirectBr(Inst, PFS); case lltok::kw_invoke: return ParseInvoke(Inst, PFS); + case lltok::kw_resume: return ParseResume(Inst, PFS); // Binary Operators. case lltok::kw_add: case lltok::kw_sub: @@ -2923,13 +2948,18 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_insertelement: return ParseInsertElement(Inst, PFS); case lltok::kw_shufflevector: return ParseShuffleVector(Inst, PFS); case lltok::kw_phi: return ParsePHI(Inst, PFS); + case lltok::kw_landingpad: return ParseLandingPad(Inst, PFS); case lltok::kw_call: return ParseCall(Inst, PFS, false); case lltok::kw_tail: return ParseCall(Inst, PFS, true); // Memory. case lltok::kw_alloca: return ParseAlloc(Inst, PFS); case lltok::kw_load: return ParseLoad(Inst, PFS, false); case lltok::kw_store: return ParseStore(Inst, PFS, false); + case lltok::kw_cmpxchg: return ParseCmpXchg(Inst, PFS); + case lltok::kw_atomicrmw: return ParseAtomicRMW(Inst, PFS); + case lltok::kw_fence: return ParseFence(Inst, PFS); case lltok::kw_volatile: + // For compatibility; canonical location is after load if (EatIfPresent(lltok::kw_load)) return ParseLoad(Inst, PFS, true); else if (EatIfPresent(lltok::kw_store)) @@ -3162,8 +3192,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { // If RetType is a non-function pointer type, then this is the short syntax // for the call, which means that RetType is just the return type. Infer the // rest of the function argument types from the arguments that are present. - const PointerType *PFTy = 0; - const FunctionType *Ty = 0; + PointerType *PFTy = 0; + FunctionType *Ty = 0; if (!(PFTy = dyn_cast(RetType)) || !(Ty = dyn_cast(PFTy->getElementType()))) { // Pull out the types of all of the arguments... @@ -3194,7 +3224,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { FunctionType::param_iterator I = Ty->param_begin(); FunctionType::param_iterator E = Ty->param_end(); for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { - const Type *ExpectedTy = 0; + Type *ExpectedTy = 0; if (I != E) { ExpectedTy = *I++; } else if (!Ty->isVarArg()) { @@ -3225,7 +3255,17 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return false; } +/// ParseResume +/// ::= 'resume' TypeAndValue +bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) { + Value *Exn; LocTy ExnLoc; + if (ParseTypeAndValue(Exn, ExnLoc, PFS)) + return true; + ResumeInst *RI = ResumeInst::Create(Exn); + Inst = RI; + return false; +} //===----------------------------------------------------------------------===// // Binary Operators. @@ -3473,6 +3513,56 @@ int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) { return AteExtraComma ? InstExtraComma : InstNormal; } +/// ParseLandingPad +/// ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'? Clause+ +/// Clause +/// ::= 'catch' TypeAndValue +/// ::= 'filter' +/// ::= 'filter' TypeAndValue ( ',' TypeAndValue )* +bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { + Type *Ty = 0; LocTy TyLoc; + Value *PersFn; LocTy PersFnLoc; + + if (ParseType(Ty, TyLoc) || + ParseToken(lltok::kw_personality, "expected 'personality'") || + ParseTypeAndValue(PersFn, PersFnLoc, PFS)) + return true; + + LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, 0); + LP->setCleanup(EatIfPresent(lltok::kw_cleanup)); + + while (Lex.getKind() == lltok::kw_catch || Lex.getKind() == lltok::kw_filter){ + LandingPadInst::ClauseType CT; + if (EatIfPresent(lltok::kw_catch)) + CT = LandingPadInst::Catch; + else if (EatIfPresent(lltok::kw_filter)) + CT = LandingPadInst::Filter; + else + return TokError("expected 'catch' or 'filter' clause type"); + + Value *V; LocTy VLoc; + if (ParseTypeAndValue(V, VLoc, PFS)) { + delete LP; + return true; + } + + // A 'catch' type expects a non-array constant. A filter clause expects an + // array constant. + if (CT == LandingPadInst::Catch) { + if (isa(V->getType())) + Error(VLoc, "'catch' clause has an invalid type"); + } else { + if (!isa(V->getType())) + Error(VLoc, "'filter' clause has an invalid type"); + } + + LP->addClause(V); + } + + Inst = LP; + return false; +} + /// ParseCall /// ::= 'tail'? 'call' OptionalCallingConv OptionalAttrs Type Value /// ParameterList OptionalAttrs @@ -3498,8 +3588,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, // If RetType is a non-function pointer type, then this is the short syntax // for the call, which means that RetType is just the return type. Infer the // rest of the function argument types from the arguments that are present. - const PointerType *PFTy = 0; - const FunctionType *Ty = 0; + PointerType *PFTy = 0; + FunctionType *Ty = 0; if (!(PFTy = dyn_cast(RetType)) || !(Ty = dyn_cast(PFTy->getElementType()))) { // Pull out the types of all of the arguments... @@ -3530,7 +3620,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, FunctionType::param_iterator I = Ty->param_begin(); FunctionType::param_iterator E = Ty->param_end(); for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { - const Type *ExpectedTy = 0; + Type *ExpectedTy = 0; if (I != E) { ExpectedTy = *I++; } else if (!Ty->isVarArg()) { @@ -3596,34 +3686,85 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { } /// ParseLoad -/// ::= 'volatile'? 'load' TypeAndValue (',' OptionalInfo)? +/// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)? +/// ::= 'load' 'atomic' 'volatile'? TypeAndValue +/// 'singlethread'? AtomicOrdering (',' 'align' i32)? +/// Compatibility: +/// ::= 'volatile' 'load' TypeAndValue (',' 'align' i32)? int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS, bool isVolatile) { Value *Val; LocTy Loc; unsigned Alignment = 0; bool AteExtraComma = false; + bool isAtomic = false; + AtomicOrdering Ordering = NotAtomic; + SynchronizationScope Scope = CrossThread; + + if (Lex.getKind() == lltok::kw_atomic) { + if (isVolatile) + return TokError("mixing atomic with old volatile placement"); + isAtomic = true; + Lex.Lex(); + } + + if (Lex.getKind() == lltok::kw_volatile) { + if (isVolatile) + return TokError("duplicate volatile before and after store"); + isVolatile = true; + Lex.Lex(); + } + if (ParseTypeAndValue(Val, Loc, PFS) || + ParseScopeAndOrdering(isAtomic, Scope, Ordering) || ParseOptionalCommaAlign(Alignment, AteExtraComma)) return true; if (!Val->getType()->isPointerTy() || !cast(Val->getType())->getElementType()->isFirstClassType()) return Error(Loc, "load operand must be a pointer to a first class type"); + if (isAtomic && !Alignment) + return Error(Loc, "atomic load must have explicit non-zero alignment"); + if (Ordering == Release || Ordering == AcquireRelease) + return Error(Loc, "atomic load cannot use Release ordering"); - Inst = new LoadInst(Val, "", isVolatile, Alignment); + Inst = new LoadInst(Val, "", isVolatile, Alignment, Ordering, Scope); return AteExtraComma ? InstExtraComma : InstNormal; } /// ParseStore -/// ::= 'volatile'? 'store' TypeAndValue ',' TypeAndValue (',' 'align' i32)? + +/// ::= 'store' 'volatile'? TypeAndValue ',' TypeAndValue (',' 'align' i32)? +/// ::= 'store' 'atomic' 'volatile'? TypeAndValue ',' TypeAndValue +/// 'singlethread'? AtomicOrdering (',' 'align' i32)? +/// Compatibility: +/// ::= 'volatile' 'store' TypeAndValue ',' TypeAndValue (',' 'align' i32)? int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS, bool isVolatile) { Value *Val, *Ptr; LocTy Loc, PtrLoc; unsigned Alignment = 0; bool AteExtraComma = false; + bool isAtomic = false; + AtomicOrdering Ordering = NotAtomic; + SynchronizationScope Scope = CrossThread; + + if (Lex.getKind() == lltok::kw_atomic) { + if (isVolatile) + return TokError("mixing atomic with old volatile placement"); + isAtomic = true; + Lex.Lex(); + } + + if (Lex.getKind() == lltok::kw_volatile) { + if (isVolatile) + return TokError("duplicate volatile before and after store"); + isVolatile = true; + Lex.Lex(); + } + if (ParseTypeAndValue(Val, Loc, PFS) || ParseToken(lltok::comma, "expected ',' after store operand") || ParseTypeAndValue(Ptr, PtrLoc, PFS) || + ParseScopeAndOrdering(isAtomic, Scope, Ordering) || ParseOptionalCommaAlign(Alignment, AteExtraComma)) return true; @@ -3633,11 +3774,131 @@ int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS, return Error(Loc, "store operand must be a first class value"); if (cast(Ptr->getType())->getElementType() != Val->getType()) return Error(Loc, "stored value and pointer type do not match"); + if (isAtomic && !Alignment) + return Error(Loc, "atomic store must have explicit non-zero alignment"); + if (Ordering == Acquire || Ordering == AcquireRelease) + return Error(Loc, "atomic store cannot use Acquire ordering"); - Inst = new StoreInst(Val, Ptr, isVolatile, Alignment); + Inst = new StoreInst(Val, Ptr, isVolatile, Alignment, Ordering, Scope); return AteExtraComma ? InstExtraComma : InstNormal; } +/// ParseCmpXchg +/// ::= 'cmpxchg' 'volatile'? TypeAndValue ',' TypeAndValue ',' TypeAndValue +/// 'singlethread'? AtomicOrdering +int LLParser::ParseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) { + Value *Ptr, *Cmp, *New; LocTy PtrLoc, CmpLoc, NewLoc; + bool AteExtraComma = false; + AtomicOrdering Ordering = NotAtomic; + SynchronizationScope Scope = CrossThread; + bool isVolatile = false; + + if (EatIfPresent(lltok::kw_volatile)) + isVolatile = true; + + if (ParseTypeAndValue(Ptr, PtrLoc, PFS) || + ParseToken(lltok::comma, "expected ',' after cmpxchg address") || + ParseTypeAndValue(Cmp, CmpLoc, PFS) || + ParseToken(lltok::comma, "expected ',' after cmpxchg cmp operand") || + ParseTypeAndValue(New, NewLoc, PFS) || + ParseScopeAndOrdering(true /*Always atomic*/, Scope, Ordering)) + return true; + + if (Ordering == Unordered) + return TokError("cmpxchg cannot be unordered"); + if (!Ptr->getType()->isPointerTy()) + return Error(PtrLoc, "cmpxchg operand must be a pointer"); + if (cast(Ptr->getType())->getElementType() != Cmp->getType()) + return Error(CmpLoc, "compare value and pointer type do not match"); + if (cast(Ptr->getType())->getElementType() != New->getType()) + return Error(NewLoc, "new value and pointer type do not match"); + if (!New->getType()->isIntegerTy()) + return Error(NewLoc, "cmpxchg operand must be an integer"); + unsigned Size = New->getType()->getPrimitiveSizeInBits(); + if (Size < 8 || (Size & (Size - 1))) + return Error(NewLoc, "cmpxchg operand must be power-of-two byte-sized" + " integer"); + + AtomicCmpXchgInst *CXI = + new AtomicCmpXchgInst(Ptr, Cmp, New, Ordering, Scope); + CXI->setVolatile(isVolatile); + Inst = CXI; + return AteExtraComma ? InstExtraComma : InstNormal; +} + +/// ParseAtomicRMW +/// ::= 'atomicrmw' 'volatile'? BinOp TypeAndValue ',' TypeAndValue +/// 'singlethread'? AtomicOrdering +int LLParser::ParseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) { + Value *Ptr, *Val; LocTy PtrLoc, ValLoc; + bool AteExtraComma = false; + AtomicOrdering Ordering = NotAtomic; + SynchronizationScope Scope = CrossThread; + bool isVolatile = false; + AtomicRMWInst::BinOp Operation; + + if (EatIfPresent(lltok::kw_volatile)) + isVolatile = true; + + switch (Lex.getKind()) { + default: return TokError("expected binary operation in atomicrmw"); + case lltok::kw_xchg: Operation = AtomicRMWInst::Xchg; break; + case lltok::kw_add: Operation = AtomicRMWInst::Add; break; + case lltok::kw_sub: Operation = AtomicRMWInst::Sub; break; + case lltok::kw_and: Operation = AtomicRMWInst::And; break; + case lltok::kw_nand: Operation = AtomicRMWInst::Nand; break; + case lltok::kw_or: Operation = AtomicRMWInst::Or; break; + case lltok::kw_xor: Operation = AtomicRMWInst::Xor; break; + case lltok::kw_max: Operation = AtomicRMWInst::Max; break; + case lltok::kw_min: Operation = AtomicRMWInst::Min; break; + case lltok::kw_umax: Operation = AtomicRMWInst::UMax; break; + case lltok::kw_umin: Operation = AtomicRMWInst::UMin; break; + } + Lex.Lex(); // Eat the operation. + + if (ParseTypeAndValue(Ptr, PtrLoc, PFS) || + ParseToken(lltok::comma, "expected ',' after atomicrmw address") || + ParseTypeAndValue(Val, ValLoc, PFS) || + ParseScopeAndOrdering(true /*Always atomic*/, Scope, Ordering)) + return true; + + if (Ordering == Unordered) + return TokError("atomicrmw cannot be unordered"); + if (!Ptr->getType()->isPointerTy()) + return Error(PtrLoc, "atomicrmw operand must be a pointer"); + if (cast(Ptr->getType())->getElementType() != Val->getType()) + return Error(ValLoc, "atomicrmw value and pointer type do not match"); + if (!Val->getType()->isIntegerTy()) + return Error(ValLoc, "atomicrmw operand must be an integer"); + unsigned Size = Val->getType()->getPrimitiveSizeInBits(); + if (Size < 8 || (Size & (Size - 1))) + return Error(ValLoc, "atomicrmw operand must be power-of-two byte-sized" + " integer"); + + AtomicRMWInst *RMWI = + new AtomicRMWInst(Operation, Ptr, Val, Ordering, Scope); + RMWI->setVolatile(isVolatile); + Inst = RMWI; + return AteExtraComma ? InstExtraComma : InstNormal; +} + +/// ParseFence +/// ::= 'fence' 'singlethread'? AtomicOrdering +int LLParser::ParseFence(Instruction *&Inst, PerFunctionState &PFS) { + AtomicOrdering Ordering = NotAtomic; + SynchronizationScope Scope = CrossThread; + if (ParseScopeAndOrdering(true /*Always atomic*/, Scope, Ordering)) + return true; + + if (Ordering == Unordered) + return TokError("fence cannot be unordered"); + if (Ordering == Monotonic) + return TokError("fence cannot be monotonic"); + + Inst = new FenceInst(Context, Ordering, Scope); + return InstNormal; +} + /// ParseGetElementPtr /// ::= 'getelementptr' 'inbounds'? TypeAndValue (',' TypeAndValue)* int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { @@ -3663,10 +3924,9 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { Indices.push_back(Val); } - if (!GetElementPtrInst::getIndexedType(Ptr->getType(), - Indices.begin(), Indices.end())) + if (!GetElementPtrInst::getIndexedType(Ptr->getType(), Indices)) return Error(Loc, "invalid getelementptr indices"); - Inst = GetElementPtrInst::Create(Ptr, Indices.begin(), Indices.end()); + Inst = GetElementPtrInst::Create(Ptr, Indices); if (InBounds) cast(Inst)->setIsInBounds(true); return AteExtraComma ? InstExtraComma : InstNormal; diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index 963065785061..cbc3c23e8631 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -15,6 +15,7 @@ #define LLVM_ASMPARSER_LLPARSER_H #include "LLLexer.h" +#include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Type.h" #include "llvm/ADT/DenseMap.h" @@ -142,8 +143,8 @@ namespace llvm { /// GetGlobalVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. - GlobalValue *GetGlobalVal(const std::string &N, const Type *Ty, LocTy Loc); - GlobalValue *GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc); + GlobalValue *GetGlobalVal(const std::string &N, Type *Ty, LocTy Loc); + GlobalValue *GetGlobalVal(unsigned ID, Type *Ty, LocTy Loc); // Helper Routines. bool ParseToken(lltok::Kind T, const char *ErrMsg); @@ -178,6 +179,8 @@ namespace llvm { bool ParseOptionalVisibility(unsigned &Visibility); bool ParseOptionalCallingConv(CallingConv::ID &CC); bool ParseOptionalAlignment(unsigned &Alignment); + bool ParseScopeAndOrdering(bool isAtomic, SynchronizationScope &Scope, + AtomicOrdering &Ordering); bool ParseOptionalStackAlignment(unsigned &Alignment); bool ParseOptionalCommaAlign(unsigned &Alignment, bool &AteExtraComma); bool ParseIndexList(SmallVectorImpl &Indices,bool &AteExtraComma); @@ -249,8 +252,8 @@ namespace llvm { /// GetVal - Get a value with the specified name or ID, creating a /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. - Value *GetVal(const std::string &Name, const Type *Ty, LocTy Loc); - Value *GetVal(unsigned ID, const Type *Ty, LocTy Loc); + Value *GetVal(const std::string &Name, Type *Ty, LocTy Loc); + Value *GetVal(unsigned ID, Type *Ty, LocTy Loc); /// SetInstName - After an instruction is parsed and inserted into its /// basic block, this installs its name. @@ -269,14 +272,14 @@ namespace llvm { BasicBlock *DefineBB(const std::string &Name, LocTy Loc); }; - bool ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, + bool ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, PerFunctionState *PFS); - bool ParseValue(const Type *Ty, Value *&V, PerFunctionState *PFS); - bool ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) { + bool ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS); + bool ParseValue(Type *Ty, Value *&V, PerFunctionState &PFS) { return ParseValue(Ty, V, &PFS); } - bool ParseValue(const Type *Ty, Value *&V, LocTy &Loc, + bool ParseValue(Type *Ty, Value *&V, LocTy &Loc, PerFunctionState &PFS) { Loc = Lex.getLoc(); return ParseValue(Ty, V, &PFS); @@ -310,7 +313,7 @@ namespace llvm { // Constant Parsing. bool ParseValID(ValID &ID, PerFunctionState *PFS = NULL); - bool ParseGlobalValue(const Type *Ty, Constant *&V); + bool ParseGlobalValue(Type *Ty, Constant *&V); bool ParseGlobalTypeAndValue(Constant *&V); bool ParseGlobalValueVector(SmallVectorImpl &Elts); bool ParseMetadataListValue(ValID &ID, PerFunctionState *PFS); @@ -344,6 +347,7 @@ namespace llvm { bool ParseSwitch(Instruction *&Inst, PerFunctionState &PFS); bool ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS); bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS); + bool ParseResume(Instruction *&Inst, PerFunctionState &PFS); bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc, unsigned OperandType); @@ -356,10 +360,14 @@ namespace llvm { bool ParseInsertElement(Instruction *&I, PerFunctionState &PFS); bool ParseShuffleVector(Instruction *&I, PerFunctionState &PFS); int ParsePHI(Instruction *&I, PerFunctionState &PFS); + bool ParseLandingPad(Instruction *&I, PerFunctionState &PFS); bool ParseCall(Instruction *&I, PerFunctionState &PFS, bool isTail); int ParseAlloc(Instruction *&I, PerFunctionState &PFS); int ParseLoad(Instruction *&I, PerFunctionState &PFS, bool isVolatile); int ParseStore(Instruction *&I, PerFunctionState &PFS, bool isVolatile); + int ParseCmpXchg(Instruction *&I, PerFunctionState &PFS); + int ParseAtomicRMW(Instruction *&I, PerFunctionState &PFS); + int ParseFence(Instruction *&I, PerFunctionState &PFS); int ParseGetElementPtr(Instruction *&I, PerFunctionState &PFS); int ParseExtractValue(Instruction *&I, PerFunctionState &PFS); int ParseInsertValue(Instruction *&I, PerFunctionState &PFS); diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index a5f89fcce0c0..8f167725ed58 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -53,6 +53,9 @@ namespace lltok { kw_deplibs, kw_datalayout, kw_volatile, + kw_atomic, + kw_unordered, kw_monotonic, kw_acquire, kw_release, kw_acq_rel, kw_seq_cst, + kw_singlethread, kw_nuw, kw_nsw, kw_exact, @@ -87,6 +90,7 @@ namespace lltok { kw_readnone, kw_readonly, kw_uwtable, + kw_returns_twice, kw_inlinehint, kw_noinline, @@ -97,7 +101,6 @@ namespace lltok { kw_noredzone, kw_noimplicitfloat, kw_naked, - kw_hotpatch, kw_nonlazybind, kw_type, @@ -107,6 +110,9 @@ namespace lltok { kw_uge, kw_oeq, kw_one, kw_olt, kw_ogt, kw_ole, kw_oge, kw_ord, kw_uno, kw_ueq, kw_une, + // atomicrmw operations that aren't also instruction keywords. + kw_xchg, kw_nand, kw_max, kw_min, kw_umax, kw_umin, + // Instruction Opcodes (Opcode in UIntVal). kw_add, kw_fadd, kw_sub, kw_fsub, kw_mul, kw_fmul, kw_udiv, kw_sdiv, kw_fdiv, @@ -118,10 +124,13 @@ namespace lltok { kw_fptoui, kw_fptosi, kw_inttoptr, kw_ptrtoint, kw_bitcast, kw_select, kw_va_arg, - kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_unwind, + kw_landingpad, kw_personality, kw_cleanup, kw_catch, kw_filter, + + kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_unwind, kw_resume, kw_unreachable, - kw_alloca, kw_load, kw_store, kw_getelementptr, + kw_alloca, kw_load, kw_store, kw_fence, kw_cmpxchg, kw_atomicrmw, + kw_getelementptr, kw_extractelement, kw_insertelement, kw_shufflevector, kw_extractvalue, kw_insertvalue, kw_blockaddress, diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 24c29941cf16..46565f36af16 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -107,7 +107,7 @@ static int GetDecodedCastOpcode(unsigned Val) { case bitc::CAST_BITCAST : return Instruction::BitCast; } } -static int GetDecodedBinaryOpcode(unsigned Val, const Type *Ty) { +static int GetDecodedBinaryOpcode(unsigned Val, Type *Ty) { switch (Val) { default: return -1; case bitc::BINOP_ADD: @@ -131,6 +131,44 @@ static int GetDecodedBinaryOpcode(unsigned Val, const Type *Ty) { } } +static AtomicRMWInst::BinOp GetDecodedRMWOperation(unsigned Val) { + switch (Val) { + default: return AtomicRMWInst::BAD_BINOP; + case bitc::RMW_XCHG: return AtomicRMWInst::Xchg; + case bitc::RMW_ADD: return AtomicRMWInst::Add; + case bitc::RMW_SUB: return AtomicRMWInst::Sub; + case bitc::RMW_AND: return AtomicRMWInst::And; + case bitc::RMW_NAND: return AtomicRMWInst::Nand; + case bitc::RMW_OR: return AtomicRMWInst::Or; + case bitc::RMW_XOR: return AtomicRMWInst::Xor; + case bitc::RMW_MAX: return AtomicRMWInst::Max; + case bitc::RMW_MIN: return AtomicRMWInst::Min; + case bitc::RMW_UMAX: return AtomicRMWInst::UMax; + case bitc::RMW_UMIN: return AtomicRMWInst::UMin; + } +} + +static AtomicOrdering GetDecodedOrdering(unsigned Val) { + switch (Val) { + case bitc::ORDERING_NOTATOMIC: return NotAtomic; + case bitc::ORDERING_UNORDERED: return Unordered; + case bitc::ORDERING_MONOTONIC: return Monotonic; + case bitc::ORDERING_ACQUIRE: return Acquire; + case bitc::ORDERING_RELEASE: return Release; + case bitc::ORDERING_ACQREL: return AcquireRelease; + default: // Map unknown orderings to sequentially-consistent. + case bitc::ORDERING_SEQCST: return SequentiallyConsistent; + } +} + +static SynchronizationScope GetDecodedSynchScope(unsigned Val) { + switch (Val) { + case bitc::SYNCHSCOPE_SINGLETHREAD: return SingleThread; + default: // Map unknown scopes to cross-thread. + case bitc::SYNCHSCOPE_CROSSTHREAD: return CrossThread; + } +} + namespace llvm { namespace { /// @brief A class for maintaining the slot number definition @@ -142,7 +180,7 @@ namespace { void *operator new(size_t s) { return User::operator new(s, 1); } - explicit ConstantPlaceHolder(const Type *Ty, LLVMContext& Context) + explicit ConstantPlaceHolder(Type *Ty, LLVMContext& Context) : ConstantExpr(Ty, Instruction::UserOp1, &Op<0>(), 1) { Op<0>() = UndefValue::get(Type::getInt32Ty(Context)); } @@ -198,7 +236,7 @@ void BitcodeReaderValueList::AssignValue(Value *V, unsigned Idx) { Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, - const Type *Ty) { + Type *Ty) { if (Idx >= size()) resize(Idx + 1); @@ -213,7 +251,7 @@ Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, return C; } -Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, const Type *Ty) { +Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) { if (Idx >= size()) resize(Idx + 1); @@ -362,7 +400,7 @@ Type *BitcodeReader::getTypeByID(unsigned ID) { // If we have a forward reference, the only possible case is when it is to a // named struct. Just create a placeholder for now. - return TypeList[ID] = StructType::createNamed(Context, ""); + return TypeList[ID] = StructType::create(Context); } /// FIXME: Remove in LLVM 3.1, only used by ParseOldTypeTable. @@ -630,7 +668,7 @@ bool BitcodeReader::ParseTypeTableBody() { Res->setName(TypeName); TypeList[NumRecords] = 0; } else // Otherwise, create a new struct. - Res = StructType::createNamed(Context, TypeName); + Res = StructType::create(Context, TypeName); TypeName.clear(); SmallVector EltTys; @@ -659,7 +697,7 @@ bool BitcodeReader::ParseTypeTableBody() { Res->setName(TypeName); TypeList[NumRecords] = 0; } else // Otherwise, create a new struct with no body. - Res = StructType::createNamed(Context, TypeName); + Res = StructType::create(Context, TypeName); TypeName.clear(); ResultTy = Res; break; @@ -793,7 +831,7 @@ bool BitcodeReader::ParseOldTypeTable() { break; case bitc::TYPE_CODE_OPAQUE: // OPAQUE if (NextTypeID < TypeList.size() && TypeList[NextTypeID] == 0) - ResultTy = StructType::createNamed(Context, ""); + ResultTy = StructType::create(Context); break; case bitc::TYPE_CODE_STRUCT_OLD: {// STRUCT_OLD if (NextTypeID >= TypeList.size()) break; @@ -804,7 +842,7 @@ bool BitcodeReader::ParseOldTypeTable() { // Set a type. if (TypeList[NextTypeID] == 0) - TypeList[NextTypeID] = StructType::createNamed(Context, ""); + TypeList[NextTypeID] = StructType::create(Context); std::vector EltTys; for (unsigned i = 1, e = Record.size(); i != e; ++i) { @@ -923,7 +961,7 @@ bool BitcodeReader::ParseOldTypeSymbolTable() { // Only apply the type name to a struct type with no name. if (StructType *STy = dyn_cast(TypeList[TypeID])) - if (!STy->isAnonymous() && !STy->hasName()) + if (!STy->isLiteral() && !STy->hasName()) STy->setName(TypeName); TypeName.clear(); break; @@ -1063,7 +1101,7 @@ bool BitcodeReader::ParseMetadata() { unsigned Size = Record.size(); SmallVector Elts; for (unsigned i = 0; i != Size; i += 2) { - const Type *Ty = getTypeByID(Record[i]); + Type *Ty = getTypeByID(Record[i]); if (!Ty) return Error("Invalid METADATA_NODE record"); if (Ty->isMetadataTy()) Elts.push_back(MDValueList.getValueFwdRef(Record[i+1])); @@ -1163,7 +1201,7 @@ bool BitcodeReader::ParseConstants() { SmallVector Record; // Read all the records for this value table. - const Type *CurTy = Type::getInt32Ty(Context); + Type *CurTy = Type::getInt32Ty(Context); unsigned NextCstNo = ValueList.size(); while (1) { unsigned Code = Stream.ReadCode(); @@ -1218,7 +1256,7 @@ bool BitcodeReader::ParseConstants() { Words[i] = DecodeSignRotatedValue(Record[i]); V = ConstantInt::get(Context, APInt(cast(CurTy)->getBitWidth(), - NumWords, &Words[0])); + Words)); break; } case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval] @@ -1233,11 +1271,11 @@ bool BitcodeReader::ParseConstants() { uint64_t Rearrange[2]; Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16); Rearrange[1] = Record[0] >> 48; - V = ConstantFP::get(Context, APFloat(APInt(80, 2, Rearrange))); + V = ConstantFP::get(Context, APFloat(APInt(80, Rearrange))); } else if (CurTy->isFP128Ty()) - V = ConstantFP::get(Context, APFloat(APInt(128, 2, &Record[0]), true)); + V = ConstantFP::get(Context, APFloat(APInt(128, Record), true)); else if (CurTy->isPPC_FP128Ty()) - V = ConstantFP::get(Context, APFloat(APInt(128, 2, &Record[0]))); + V = ConstantFP::get(Context, APFloat(APInt(128, Record))); else V = UndefValue::get(CurTy); break; @@ -1250,18 +1288,18 @@ bool BitcodeReader::ParseConstants() { unsigned Size = Record.size(); std::vector Elts; - if (const StructType *STy = dyn_cast(CurTy)) { + if (StructType *STy = dyn_cast(CurTy)) { for (unsigned i = 0; i != Size; ++i) Elts.push_back(ValueList.getConstantFwdRef(Record[i], STy->getElementType(i))); V = ConstantStruct::get(STy, Elts); - } else if (const ArrayType *ATy = dyn_cast(CurTy)) { - const Type *EltTy = ATy->getElementType(); + } else if (ArrayType *ATy = dyn_cast(CurTy)) { + Type *EltTy = ATy->getElementType(); for (unsigned i = 0; i != Size; ++i) Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy)); V = ConstantArray::get(ATy, Elts); - } else if (const VectorType *VTy = dyn_cast(CurTy)) { - const Type *EltTy = VTy->getElementType(); + } else if (VectorType *VTy = dyn_cast(CurTy)) { + Type *EltTy = VTy->getElementType(); for (unsigned i = 0; i != Size; ++i) Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy)); V = ConstantVector::get(Elts); @@ -1274,8 +1312,8 @@ bool BitcodeReader::ParseConstants() { if (Record.empty()) return Error("Invalid CST_AGGREGATE record"); - const ArrayType *ATy = cast(CurTy); - const Type *EltTy = ATy->getElementType(); + ArrayType *ATy = cast(CurTy); + Type *EltTy = ATy->getElementType(); unsigned Size = Record.size(); std::vector Elts; @@ -1288,8 +1326,8 @@ bool BitcodeReader::ParseConstants() { if (Record.empty()) return Error("Invalid CST_AGGREGATE record"); - const ArrayType *ATy = cast(CurTy); - const Type *EltTy = ATy->getElementType(); + ArrayType *ATy = cast(CurTy); + Type *EltTy = ATy->getElementType(); unsigned Size = Record.size(); std::vector Elts; @@ -1335,7 +1373,7 @@ bool BitcodeReader::ParseConstants() { if (Opc < 0) { V = UndefValue::get(CurTy); // Unknown cast. } else { - const Type *OpTy = getTypeByID(Record[1]); + Type *OpTy = getTypeByID(Record[1]); if (!OpTy) return Error("Invalid CE_CAST record"); Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy); V = ConstantExpr::getCast(Opc, Op, CurTy); @@ -1347,16 +1385,14 @@ bool BitcodeReader::ParseConstants() { if (Record.size() & 1) return Error("Invalid CE_GEP record"); SmallVector Elts; for (unsigned i = 0, e = Record.size(); i != e; i += 2) { - const Type *ElTy = getTypeByID(Record[i]); + Type *ElTy = getTypeByID(Record[i]); if (!ElTy) return Error("Invalid CE_GEP record"); Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy)); } - if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP) - V = ConstantExpr::getInBoundsGetElementPtr(Elts[0], &Elts[1], - Elts.size()-1); - else - V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], - Elts.size()-1); + ArrayRef Indices(Elts.begin() + 1, Elts.end()); + V = ConstantExpr::getGetElementPtr(Elts[0], Indices, + BitCode == + bitc::CST_CODE_CE_INBOUNDS_GEP); break; } case bitc::CST_CODE_CE_SELECT: // CE_SELECT: [opval#, opval#, opval#] @@ -1368,7 +1404,7 @@ bool BitcodeReader::ParseConstants() { break; case bitc::CST_CODE_CE_EXTRACTELT: { // CE_EXTRACTELT: [opty, opval, opval] if (Record.size() < 3) return Error("Invalid CE_EXTRACTELT record"); - const VectorType *OpTy = + VectorType *OpTy = dyn_cast_or_null(getTypeByID(Record[0])); if (OpTy == 0) return Error("Invalid CE_EXTRACTELT record"); Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); @@ -1377,7 +1413,7 @@ bool BitcodeReader::ParseConstants() { break; } case bitc::CST_CODE_CE_INSERTELT: { // CE_INSERTELT: [opval, opval, opval] - const VectorType *OpTy = dyn_cast(CurTy); + VectorType *OpTy = dyn_cast(CurTy); if (Record.size() < 3 || OpTy == 0) return Error("Invalid CE_INSERTELT record"); Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy); @@ -1388,26 +1424,26 @@ bool BitcodeReader::ParseConstants() { break; } case bitc::CST_CODE_CE_SHUFFLEVEC: { // CE_SHUFFLEVEC: [opval, opval, opval] - const VectorType *OpTy = dyn_cast(CurTy); + VectorType *OpTy = dyn_cast(CurTy); if (Record.size() < 3 || OpTy == 0) return Error("Invalid CE_SHUFFLEVEC record"); Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy); Constant *Op1 = ValueList.getConstantFwdRef(Record[1], OpTy); - const Type *ShufTy = VectorType::get(Type::getInt32Ty(Context), + Type *ShufTy = VectorType::get(Type::getInt32Ty(Context), OpTy->getNumElements()); Constant *Op2 = ValueList.getConstantFwdRef(Record[2], ShufTy); V = ConstantExpr::getShuffleVector(Op0, Op1, Op2); break; } case bitc::CST_CODE_CE_SHUFVEC_EX: { // [opty, opval, opval, opval] - const VectorType *RTy = dyn_cast(CurTy); - const VectorType *OpTy = + VectorType *RTy = dyn_cast(CurTy); + VectorType *OpTy = dyn_cast_or_null(getTypeByID(Record[0])); if (Record.size() < 4 || RTy == 0 || OpTy == 0) return Error("Invalid CE_SHUFVEC_EX record"); Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy); - const Type *ShufTy = VectorType::get(Type::getInt32Ty(Context), + Type *ShufTy = VectorType::get(Type::getInt32Ty(Context), RTy->getNumElements()); Constant *Op2 = ValueList.getConstantFwdRef(Record[3], ShufTy); V = ConstantExpr::getShuffleVector(Op0, Op1, Op2); @@ -1415,7 +1451,7 @@ bool BitcodeReader::ParseConstants() { } case bitc::CST_CODE_CE_CMP: { // CE_CMP: [opty, opval, opval, pred] if (Record.size() < 4) return Error("Invalid CE_CMP record"); - const Type *OpTy = getTypeByID(Record[0]); + Type *OpTy = getTypeByID(Record[0]); if (OpTy == 0) return Error("Invalid CE_CMP record"); Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy); @@ -1442,14 +1478,14 @@ bool BitcodeReader::ParseConstants() { AsmStr += (char)Record[2+i]; for (unsigned i = 0; i != ConstStrSize; ++i) ConstrStr += (char)Record[3+AsmStrSize+i]; - const PointerType *PTy = cast(CurTy); + PointerType *PTy = cast(CurTy); V = InlineAsm::get(cast(PTy->getElementType()), AsmStr, ConstrStr, HasSideEffects, IsAlignStack); break; } case bitc::CST_CODE_BLOCKADDRESS:{ if (Record.size() < 3) return Error("Invalid CE_BLOCKADDRESS record"); - const Type *FnTy = getTypeByID(Record[0]); + Type *FnTy = getTypeByID(Record[0]); if (FnTy == 0) return Error("Invalid CE_BLOCKADDRESS record"); Function *Fn = dyn_cast_or_null(ValueList.getConstantFwdRef(Record[1],FnTy)); @@ -1662,7 +1698,7 @@ bool BitcodeReader::ParseModule() { case bitc::MODULE_CODE_GLOBALVAR: { if (Record.size() < 6) return Error("Invalid MODULE_CODE_GLOBALVAR record"); - const Type *Ty = getTypeByID(Record[0]); + Type *Ty = getTypeByID(Record[0]); if (!Ty) return Error("Invalid MODULE_CODE_GLOBALVAR record"); if (!Ty->isPointerTy()) return Error("Global not a pointer type!"); @@ -1711,11 +1747,11 @@ bool BitcodeReader::ParseModule() { case bitc::MODULE_CODE_FUNCTION: { if (Record.size() < 8) return Error("Invalid MODULE_CODE_FUNCTION record"); - const Type *Ty = getTypeByID(Record[0]); + Type *Ty = getTypeByID(Record[0]); if (!Ty) return Error("Invalid MODULE_CODE_FUNCTION record"); if (!Ty->isPointerTy()) return Error("Function not a pointer type!"); - const FunctionType *FTy = + FunctionType *FTy = dyn_cast(cast(Ty)->getElementType()); if (!FTy) return Error("Function not a pointer to function type!"); @@ -1757,7 +1793,7 @@ bool BitcodeReader::ParseModule() { case bitc::MODULE_CODE_ALIAS: { if (Record.size() < 3) return Error("Invalid MODULE_ALIAS record"); - const Type *Ty = getTypeByID(Record[0]); + Type *Ty = getTypeByID(Record[0]); if (!Ty) return Error("Invalid MODULE_ALIAS record"); if (!Ty->isPointerTy()) return Error("Function not a pointer type!"); @@ -1823,9 +1859,9 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) { if (Code != bitc::ENTER_SUBBLOCK) { - // The ranlib in xcode 4 will align archive members by appending newlines to the - // end of them. If this file size is a multiple of 4 but not 8, we have to read and - // ignore these final 4 bytes :-( + // The ranlib in xcode 4 will align archive members by appending newlines + // to the end of them. If this file size is a multiple of 4 but not 8, we + // have to read and ignore these final 4 bytes :-( if (Stream.GetAbbrevIDWidth() == 2 && Code == 2 && Stream.Read(6) == 2 && Stream.Read(24) == 0xa0a0a && Stream.AtEndOfStream()) @@ -2160,7 +2196,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { OpNum+2 != Record.size()) return Error("Invalid CAST record"); - const Type *ResTy = getTypeByID(Record[OpNum]); + Type *ResTy = getTypeByID(Record[OpNum]); int Opc = GetDecodedCastOpcode(Record[OpNum+1]); if (Opc == -1 || ResTy == 0) return Error("Invalid CAST record"); @@ -2183,7 +2219,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { GEPIdx.push_back(Op); } - I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end()); + I = GetElementPtrInst::Create(BasePtr, GEPIdx); InstructionList.push_back(I); if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP) cast(I)->setIsInBounds(true); @@ -2261,8 +2297,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { return Error("Invalid SELECT record"); // select condition can be either i1 or [N x i1] - if (const VectorType* vector_type = - dyn_cast(Cond->getType())) { + if (VectorType* vector_type = + dyn_cast(Cond->getType())) { // expect if (vector_type->getElementType() != Type::getInt1Ty(Context)) return Error("Invalid SELECT condition type"); @@ -2381,7 +2417,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...] if (Record.size() < 3 || (Record.size() & 1) == 0) return Error("Invalid SWITCH record"); - const Type *OpTy = getTypeByID(Record[0]); + Type *OpTy = getTypeByID(Record[0]); Value *Cond = getFnValueByID(Record[1], OpTy); BasicBlock *Default = getBasicBlock(Record[2]); if (OpTy == 0 || Cond == 0 || Default == 0) @@ -2405,7 +2441,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_INDIRECTBR: { // INDIRECTBR: [opty, op0, op1, ...] if (Record.size() < 2) return Error("Invalid INDIRECTBR record"); - const Type *OpTy = getTypeByID(Record[0]); + Type *OpTy = getTypeByID(Record[0]); Value *Address = getFnValueByID(Record[1], OpTy); if (OpTy == 0 || Address == 0) return Error("Invalid INDIRECTBR record"); @@ -2437,8 +2473,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) return Error("Invalid INVOKE record"); - const PointerType *CalleeTy = dyn_cast(Callee->getType()); - const FunctionType *FTy = !CalleeTy ? 0 : + PointerType *CalleeTy = dyn_cast(Callee->getType()); + FunctionType *FTy = !CalleeTy ? 0 : dyn_cast(CalleeTy->getElementType()); // Check that the right number of fixed parameters are here. @@ -2472,6 +2508,15 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { cast(I)->setAttributes(PAL); break; } + case bitc::FUNC_CODE_INST_RESUME: { // RESUME: [opval] + unsigned Idx = 0; + Value *Val = 0; + if (getValueTypePair(Record, Idx, NextValueNo, Val)) + return Error("Invalid RESUME record"); + I = ResumeInst::Create(Val); + InstructionList.push_back(I); + break; + } case bitc::FUNC_CODE_INST_UNWIND: // UNWIND I = new UnwindInst(Context); InstructionList.push_back(I); @@ -2483,7 +2528,7 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...] if (Record.size() < 1 || ((Record.size()-1)&1)) return Error("Invalid PHI record"); - const Type *Ty = getTypeByID(Record[0]); + Type *Ty = getTypeByID(Record[0]); if (!Ty) return Error("Invalid PHI record"); PHINode *PN = PHINode::Create(Ty, (Record.size()-1)/2); @@ -2499,12 +2544,51 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { break; } + case bitc::FUNC_CODE_INST_LANDINGPAD: { + // LANDINGPAD: [ty, val, val, num, (id0,val0 ...)?] + unsigned Idx = 0; + if (Record.size() < 4) + return Error("Invalid LANDINGPAD record"); + Type *Ty = getTypeByID(Record[Idx++]); + if (!Ty) return Error("Invalid LANDINGPAD record"); + Value *PersFn = 0; + if (getValueTypePair(Record, Idx, NextValueNo, PersFn)) + return Error("Invalid LANDINGPAD record"); + + bool IsCleanup = !!Record[Idx++]; + unsigned NumClauses = Record[Idx++]; + LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, NumClauses); + LP->setCleanup(IsCleanup); + for (unsigned J = 0; J != NumClauses; ++J) { + LandingPadInst::ClauseType CT = + LandingPadInst::ClauseType(Record[Idx++]); (void)CT; + Value *Val; + + if (getValueTypePair(Record, Idx, NextValueNo, Val)) { + delete LP; + return Error("Invalid LANDINGPAD record"); + } + + assert((CT != LandingPadInst::Catch || + !isa(Val->getType())) && + "Catch clause has a invalid type!"); + assert((CT != LandingPadInst::Filter || + isa(Val->getType())) && + "Filter clause has invalid type!"); + LP->addClause(Val); + } + + I = LP; + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align] if (Record.size() != 4) return Error("Invalid ALLOCA record"); - const PointerType *Ty = + PointerType *Ty = dyn_cast_or_null(getTypeByID(Record[0])); - const Type *OpTy = getTypeByID(Record[1]); + Type *OpTy = getTypeByID(Record[1]); Value *Size = getFnValueByID(Record[2], OpTy); unsigned Align = Record[3]; if (!Ty || !Size) return Error("Invalid ALLOCA record"); @@ -2523,6 +2607,28 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { InstructionList.push_back(I); break; } + case bitc::FUNC_CODE_INST_LOADATOMIC: { + // LOADATOMIC: [opty, op, align, vol, ordering, synchscope] + unsigned OpNum = 0; + Value *Op; + if (getValueTypePair(Record, OpNum, NextValueNo, Op) || + OpNum+4 != Record.size()) + return Error("Invalid LOADATOMIC record"); + + + AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]); + if (Ordering == NotAtomic || Ordering == Release || + Ordering == AcquireRelease) + return Error("Invalid LOADATOMIC record"); + if (Ordering != NotAtomic && Record[OpNum] == 0) + return Error("Invalid LOADATOMIC record"); + SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]); + + I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1, + Ordering, SynchScope); + InstructionList.push_back(I); + break; + } case bitc::FUNC_CODE_INST_STORE: { // STORE2:[ptrty, ptr, val, align, vol] unsigned OpNum = 0; Value *Val, *Ptr; @@ -2536,6 +2642,83 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { InstructionList.push_back(I); break; } + case bitc::FUNC_CODE_INST_STOREATOMIC: { + // STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, synchscope] + unsigned OpNum = 0; + Value *Val, *Ptr; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || + getValue(Record, OpNum, + cast(Ptr->getType())->getElementType(), Val) || + OpNum+4 != Record.size()) + return Error("Invalid STOREATOMIC record"); + + AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]); + if (Ordering == NotAtomic || Ordering == Acquire || + Ordering == AcquireRelease) + return Error("Invalid STOREATOMIC record"); + SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]); + if (Ordering != NotAtomic && Record[OpNum] == 0) + return Error("Invalid STOREATOMIC record"); + + I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1, + Ordering, SynchScope); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_CMPXCHG: { + // CMPXCHG:[ptrty, ptr, cmp, new, vol, ordering, synchscope] + unsigned OpNum = 0; + Value *Ptr, *Cmp, *New; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || + getValue(Record, OpNum, + cast(Ptr->getType())->getElementType(), Cmp) || + getValue(Record, OpNum, + cast(Ptr->getType())->getElementType(), New) || + OpNum+3 != Record.size()) + return Error("Invalid CMPXCHG record"); + AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+1]); + if (Ordering == NotAtomic || Ordering == Unordered) + return Error("Invalid CMPXCHG record"); + SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+2]); + I = new AtomicCmpXchgInst(Ptr, Cmp, New, Ordering, SynchScope); + cast(I)->setVolatile(Record[OpNum]); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_ATOMICRMW: { + // ATOMICRMW:[ptrty, ptr, val, op, vol, ordering, synchscope] + unsigned OpNum = 0; + Value *Ptr, *Val; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || + getValue(Record, OpNum, + cast(Ptr->getType())->getElementType(), Val) || + OpNum+4 != Record.size()) + return Error("Invalid ATOMICRMW record"); + AtomicRMWInst::BinOp Operation = GetDecodedRMWOperation(Record[OpNum]); + if (Operation < AtomicRMWInst::FIRST_BINOP || + Operation > AtomicRMWInst::LAST_BINOP) + return Error("Invalid ATOMICRMW record"); + AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]); + if (Ordering == NotAtomic || Ordering == Unordered) + return Error("Invalid ATOMICRMW record"); + SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]); + I = new AtomicRMWInst(Operation, Ptr, Val, Ordering, SynchScope); + cast(I)->setVolatile(Record[OpNum+1]); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_FENCE: { // FENCE:[ordering, synchscope] + if (2 != Record.size()) + return Error("Invalid FENCE record"); + AtomicOrdering Ordering = GetDecodedOrdering(Record[0]); + if (Ordering == NotAtomic || Ordering == Unordered || + Ordering == Monotonic) + return Error("Invalid FENCE record"); + SynchronizationScope SynchScope = GetDecodedSynchScope(Record[1]); + I = new FenceInst(Context, Ordering, SynchScope); + InstructionList.push_back(I); + break; + } case bitc::FUNC_CODE_INST_CALL: { // CALL: [paramattrs, cc, fnty, fnid, arg0, arg1...] if (Record.size() < 3) @@ -2549,8 +2732,8 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) return Error("Invalid CALL record"); - const PointerType *OpTy = dyn_cast(Callee->getType()); - const FunctionType *FTy = 0; + PointerType *OpTy = dyn_cast(Callee->getType()); + FunctionType *FTy = 0; if (OpTy) FTy = dyn_cast(OpTy->getElementType()); if (!FTy || Record.size() < FTy->getNumParams()+OpNum) return Error("Invalid CALL record"); @@ -2589,9 +2772,9 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { case bitc::FUNC_CODE_INST_VAARG: { // VAARG: [valistty, valist, instty] if (Record.size() < 3) return Error("Invalid VAARG record"); - const Type *OpTy = getTypeByID(Record[0]); + Type *OpTy = getTypeByID(Record[0]); Value *Op = getFnValueByID(Record[1], OpTy); - const Type *ResTy = getTypeByID(Record[2]); + Type *ResTy = getTypeByID(Record[2]); if (!OpTy || !Op || !ResTy) return Error("Invalid VAARG record"); I = new VAArgInst(Op, ResTy); @@ -2756,6 +2939,9 @@ bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) { } std::vector >().swap(UpgradedIntrinsics); + // Upgrade to new EH scheme. N.B. This will go away in 3.1. + UpgradeExceptionHandling(M); + // Check debug info intrinsics. CheckDebugInfoIntrinsics(TheModule); diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 1b3bf1a1854a..6e6118cac0dc 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -76,8 +76,8 @@ class BitcodeReaderValueList { ValuePtrs.resize(N); } - Constant *getConstantFwdRef(unsigned Idx, const Type *Ty); - Value *getValueFwdRef(unsigned Idx, const Type *Ty); + Constant *getConstantFwdRef(unsigned Idx, Type *Ty); + Value *getValueFwdRef(unsigned Idx, Type *Ty); void AssignValue(Value *V, unsigned Idx); @@ -212,7 +212,7 @@ class BitcodeReader : public GVMaterializer { private: Type *getTypeByID(unsigned ID); Type *getTypeByIDOrNull(unsigned ID); - Value *getFnValueByID(unsigned ID, const Type *Ty) { + Value *getFnValueByID(unsigned ID, Type *Ty) { if (Ty && Ty->isMetadataTy()) return MDValueList.getValueFwdRef(ID); return ValueList.getValueFwdRef(ID, Ty); @@ -248,7 +248,7 @@ class BitcodeReader : public GVMaterializer { return ResVal == 0; } bool getValue(SmallVector &Record, unsigned &Slot, - const Type *Ty, Value *&ResVal) { + Type *Ty, Value *&ResVal) { if (Slot == Record.size()) return true; unsigned ValNo = (unsigned)Record[Slot++]; ResVal = getFnValueByID(ValNo, Ty); diff --git a/lib/Bitcode/Reader/CMakeLists.txt b/lib/Bitcode/Reader/CMakeLists.txt index 693d4310b834..37bebc449635 100644 --- a/lib/Bitcode/Reader/CMakeLists.txt +++ b/lib/Bitcode/Reader/CMakeLists.txt @@ -2,3 +2,8 @@ add_llvm_library(LLVMBitReader BitReader.cpp BitcodeReader.cpp ) + +add_llvm_library_dependencies(LLVMBitReader + LLVMCore + LLVMSupport + ) diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 85d67ce62b9f..5b3d96953a0e 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -58,7 +58,6 @@ enum { FUNCTION_INST_UNREACHABLE_ABBREV }; - static unsigned GetEncodedCastOpcode(unsigned Opcode) { switch (Opcode) { default: llvm_unreachable("Unknown cast instruction!"); @@ -101,6 +100,44 @@ static unsigned GetEncodedBinaryOpcode(unsigned Opcode) { } } +static unsigned GetEncodedRMWOperation(AtomicRMWInst::BinOp Op) { + switch (Op) { + default: llvm_unreachable("Unknown RMW operation!"); + case AtomicRMWInst::Xchg: return bitc::RMW_XCHG; + case AtomicRMWInst::Add: return bitc::RMW_ADD; + case AtomicRMWInst::Sub: return bitc::RMW_SUB; + case AtomicRMWInst::And: return bitc::RMW_AND; + case AtomicRMWInst::Nand: return bitc::RMW_NAND; + case AtomicRMWInst::Or: return bitc::RMW_OR; + case AtomicRMWInst::Xor: return bitc::RMW_XOR; + case AtomicRMWInst::Max: return bitc::RMW_MAX; + case AtomicRMWInst::Min: return bitc::RMW_MIN; + case AtomicRMWInst::UMax: return bitc::RMW_UMAX; + case AtomicRMWInst::UMin: return bitc::RMW_UMIN; + } +} + +static unsigned GetEncodedOrdering(AtomicOrdering Ordering) { + switch (Ordering) { + default: llvm_unreachable("Unknown atomic ordering"); + case NotAtomic: return bitc::ORDERING_NOTATOMIC; + case Unordered: return bitc::ORDERING_UNORDERED; + case Monotonic: return bitc::ORDERING_MONOTONIC; + case Acquire: return bitc::ORDERING_ACQUIRE; + case Release: return bitc::ORDERING_RELEASE; + case AcquireRelease: return bitc::ORDERING_ACQREL; + case SequentiallyConsistent: return bitc::ORDERING_SEQCST; + } +} + +static unsigned GetEncodedSynchScope(SynchronizationScope SynchScope) { + switch (SynchScope) { + default: llvm_unreachable("Unknown synchronization scope"); + case SingleThread: return bitc::SYNCHSCOPE_SINGLETHREAD; + case CrossThread: return bitc::SYNCHSCOPE_CROSSTHREAD; + } +} + static void WriteStringRecord(unsigned Code, StringRef Str, unsigned AbbrevToUse, BitstreamWriter &Stream) { SmallVector Vals; @@ -199,7 +236,6 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(VE.getTypes().size()+1))); unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv); - // Abbrev for TYPE_CODE_ARRAY. Abbv = new BitCodeAbbrev(); @@ -216,7 +252,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { // Loop over all of the types, emitting each in turn. for (unsigned i = 0, e = TypeList.size(); i != e; ++i) { - const Type *T = TypeList[i]; + Type *T = TypeList[i]; int AbbrevToUse = 0; unsigned Code = 0; @@ -237,7 +273,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { TypeVals.push_back(cast(T)->getBitWidth()); break; case Type::PointerTyID: { - const PointerType *PTy = cast(T); + PointerType *PTy = cast(T); // POINTER: [pointee type, address space] Code = bitc::TYPE_CODE_POINTER; TypeVals.push_back(VE.getTypeID(PTy->getElementType())); @@ -247,7 +283,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { break; } case Type::FunctionTyID: { - const FunctionType *FT = cast(T); + FunctionType *FT = cast(T); // FUNCTION: [isvararg, attrid, retty, paramty x N] Code = bitc::TYPE_CODE_FUNCTION; TypeVals.push_back(FT->isVarArg()); @@ -259,7 +295,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { break; } case Type::StructTyID: { - const StructType *ST = cast(T); + StructType *ST = cast(T); // STRUCT: [ispacked, eltty x N] TypeVals.push_back(ST->isPacked()); // Output all of the element types. @@ -267,7 +303,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { E = ST->element_end(); I != E; ++I) TypeVals.push_back(VE.getTypeID(*I)); - if (ST->isAnonymous()) { + if (ST->isLiteral()) { Code = bitc::TYPE_CODE_STRUCT_ANON; AbbrevToUse = StructAnonAbbrev; } else { @@ -286,7 +322,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { break; } case Type::ArrayTyID: { - const ArrayType *AT = cast(T); + ArrayType *AT = cast(T); // ARRAY: [numelts, eltty] Code = bitc::TYPE_CODE_ARRAY; TypeVals.push_back(AT->getNumElements()); @@ -295,7 +331,7 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { break; } case Type::VectorTyID: { - const VectorType *VT = cast(T); + VectorType *VT = cast(T); // VECTOR [numelts, eltty] Code = bitc::TYPE_CODE_VECTOR; TypeVals.push_back(VT->getNumElements()); @@ -372,14 +408,15 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, GV != E; ++GV) { MaxAlignment = std::max(MaxAlignment, GV->getAlignment()); MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV->getType())); - - if (!GV->hasSection()) continue; - // Give section names unique ID's. - unsigned &Entry = SectionMap[GV->getSection()]; - if (Entry != 0) continue; - WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV->getSection(), - 0/*TODO*/, Stream); - Entry = SectionMap.size(); + if (GV->hasSection()) { + // Give section names unique ID's. + unsigned &Entry = SectionMap[GV->getSection()]; + if (!Entry) { + WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV->getSection(), + 0/*TODO*/, Stream); + Entry = SectionMap.size(); + } + } } for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) { MaxAlignment = std::max(MaxAlignment, F->getAlignment()); @@ -716,7 +753,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, SmallVector Record; const ValueEnumerator::ValueList &Vals = VE.getValues(); - const Type *LastTy = 0; + Type *LastTy = 0; for (unsigned i = FirstVal; i != LastVal; ++i) { const Value *V = Vals[i].first; // If we need to switch types, do so now. @@ -781,7 +818,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, } } else if (const ConstantFP *CFP = dyn_cast(C)) { Code = bitc::CST_CODE_FLOAT; - const Type *Ty = CFP->getType(); + Type *Ty = CFP->getType(); if (Ty->isFloatTy() || Ty->isDoubleTy()) { Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue()); } else if (Ty->isX86_FP80Ty()) { @@ -1083,8 +1120,8 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, case Instruction::Invoke: { const InvokeInst *II = cast(&I); const Value *Callee(II->getCalledValue()); - const PointerType *PTy = cast(Callee->getType()); - const FunctionType *FTy = cast(PTy->getElementType()); + PointerType *PTy = cast(Callee->getType()); + FunctionType *FTy = cast(PTy->getElementType()); Code = bitc::FUNC_CODE_INST_INVOKE; Vals.push_back(VE.getAttributeID(II->getAttributes())); @@ -1105,6 +1142,10 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, } break; } + case Instruction::Resume: + Code = bitc::FUNC_CODE_INST_RESUME; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + break; case Instruction::Unwind: Code = bitc::FUNC_CODE_INST_UNWIND; break; @@ -1124,6 +1165,23 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, break; } + case Instruction::LandingPad: { + const LandingPadInst &LP = cast(I); + Code = bitc::FUNC_CODE_INST_LANDINGPAD; + Vals.push_back(VE.getTypeID(LP.getType())); + PushValueAndType(LP.getPersonalityFn(), InstID, Vals, VE); + Vals.push_back(LP.isCleanup()); + Vals.push_back(LP.getNumClauses()); + for (unsigned I = 0, E = LP.getNumClauses(); I != E; ++I) { + if (LP.isCatch(I)) + Vals.push_back(LandingPadInst::Catch); + else + Vals.push_back(LandingPadInst::Filter); + PushValueAndType(LP.getClause(I), InstID, Vals, VE); + } + break; + } + case Instruction::Alloca: Code = bitc::FUNC_CODE_INST_ALLOCA; Vals.push_back(VE.getTypeID(I.getType())); @@ -1133,24 +1191,66 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, break; case Instruction::Load: - Code = bitc::FUNC_CODE_INST_LOAD; - if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) // ptr - AbbrevToUse = FUNCTION_INST_LOAD_ABBREV; - + if (cast(I).isAtomic()) { + Code = bitc::FUNC_CODE_INST_LOADATOMIC; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + } else { + Code = bitc::FUNC_CODE_INST_LOAD; + if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) // ptr + AbbrevToUse = FUNCTION_INST_LOAD_ABBREV; + } Vals.push_back(Log2_32(cast(I).getAlignment())+1); Vals.push_back(cast(I).isVolatile()); + if (cast(I).isAtomic()) { + Vals.push_back(GetEncodedOrdering(cast(I).getOrdering())); + Vals.push_back(GetEncodedSynchScope(cast(I).getSynchScope())); + } break; case Instruction::Store: - Code = bitc::FUNC_CODE_INST_STORE; + if (cast(I).isAtomic()) + Code = bitc::FUNC_CODE_INST_STOREATOMIC; + else + Code = bitc::FUNC_CODE_INST_STORE; PushValueAndType(I.getOperand(1), InstID, Vals, VE); // ptrty + ptr Vals.push_back(VE.getValueID(I.getOperand(0))); // val. Vals.push_back(Log2_32(cast(I).getAlignment())+1); Vals.push_back(cast(I).isVolatile()); + if (cast(I).isAtomic()) { + Vals.push_back(GetEncodedOrdering(cast(I).getOrdering())); + Vals.push_back(GetEncodedSynchScope(cast(I).getSynchScope())); + } + break; + case Instruction::AtomicCmpXchg: + Code = bitc::FUNC_CODE_INST_CMPXCHG; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); // ptrty + ptr + Vals.push_back(VE.getValueID(I.getOperand(1))); // cmp. + Vals.push_back(VE.getValueID(I.getOperand(2))); // newval. + Vals.push_back(cast(I).isVolatile()); + Vals.push_back(GetEncodedOrdering( + cast(I).getOrdering())); + Vals.push_back(GetEncodedSynchScope( + cast(I).getSynchScope())); + break; + case Instruction::AtomicRMW: + Code = bitc::FUNC_CODE_INST_ATOMICRMW; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); // ptrty + ptr + Vals.push_back(VE.getValueID(I.getOperand(1))); // val. + Vals.push_back(GetEncodedRMWOperation( + cast(I).getOperation())); + Vals.push_back(cast(I).isVolatile()); + Vals.push_back(GetEncodedOrdering(cast(I).getOrdering())); + Vals.push_back(GetEncodedSynchScope( + cast(I).getSynchScope())); + break; + case Instruction::Fence: + Code = bitc::FUNC_CODE_INST_FENCE; + Vals.push_back(GetEncodedOrdering(cast(I).getOrdering())); + Vals.push_back(GetEncodedSynchScope(cast(I).getSynchScope())); break; case Instruction::Call: { const CallInst &CI = cast(I); - const PointerType *PTy = cast(CI.getCalledValue()->getType()); - const FunctionType *FTy = cast(PTy->getElementType()); + PointerType *PTy = cast(CI.getCalledValue()->getType()); + FunctionType *FTy = cast(PTy->getElementType()); Code = bitc::FUNC_CODE_INST_CALL; diff --git a/lib/Bitcode/Writer/CMakeLists.txt b/lib/Bitcode/Writer/CMakeLists.txt index f097b097c337..3cf905697a42 100644 --- a/lib/Bitcode/Writer/CMakeLists.txt +++ b/lib/Bitcode/Writer/CMakeLists.txt @@ -4,3 +4,8 @@ add_llvm_library(LLVMBitWriter BitcodeWriterPass.cpp ValueEnumerator.cpp ) + +add_llvm_library_dependencies(LLVMBitWriter + LLVMCore + LLVMSupport + ) diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index b68bf92d51b2..9ae9905b9f1d 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -315,7 +315,7 @@ void ValueEnumerator::EnumerateValue(const Value *V) { } -void ValueEnumerator::EnumerateType(const Type *Ty) { +void ValueEnumerator::EnumerateType(Type *Ty) { unsigned *TypeID = &TypeMap[Ty]; // We've already seen this type. @@ -325,8 +325,8 @@ void ValueEnumerator::EnumerateType(const Type *Ty) { // If it is a non-anonymous struct, mark the type as being visited so that we // don't recursively visit it. This is safe because we allow forward // references of these in the bitcode reader. - if (const StructType *STy = dyn_cast(Ty)) - if (!STy->isAnonymous()) + if (StructType *STy = dyn_cast(Ty)) + if (!STy->isLiteral()) *TypeID = ~0U; // Enumerate all of the subtypes before we enumerate this type. This ensures diff --git a/lib/Bitcode/Writer/ValueEnumerator.h b/lib/Bitcode/Writer/ValueEnumerator.h index 6617b60deb26..b6fc920e412b 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.h +++ b/lib/Bitcode/Writer/ValueEnumerator.h @@ -35,12 +35,12 @@ class MDSymbolTable; class ValueEnumerator { public: - typedef std::vector TypeList; + typedef std::vector TypeList; // For each value, we remember its Value* and occurrence frequency. typedef std::vector > ValueList; private: - typedef DenseMap TypeMapType; + typedef DenseMap TypeMapType; TypeMapType TypeMap; TypeList Types; @@ -85,7 +85,7 @@ class ValueEnumerator { unsigned getValueID(const Value *V) const; - unsigned getTypeID(const Type *T) const { + unsigned getTypeID(Type *T) const { TypeMapType::const_iterator I = TypeMap.find(T); assert(I != TypeMap.end() && "Type not in ValueEnumerator!"); return I->second-1; @@ -140,7 +140,7 @@ class ValueEnumerator { void EnumerateFunctionLocalMetadata(const MDNode *N); void EnumerateNamedMDNode(const NamedMDNode *NMD); void EnumerateValue(const Value *V); - void EnumerateType(const Type *T); + void EnumerateType(Type *T); void EnumerateOperandType(const Value *V); void EnumerateAttributes(const AttrListPtr &PAL); diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 80118f081913..fb63c63f327c 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,4 +1,4 @@ -# `Support' library is added on the top-level CMakeLists.txt +# `Support' and `TableGen' libraries are added on the top-level CMakeLists.txt add_subdirectory(VMCore) add_subdirectory(CodeGen) @@ -7,8 +7,8 @@ add_subdirectory(Transforms) add_subdirectory(Linker) add_subdirectory(Analysis) add_subdirectory(MC) -add_subdirectory(CompilerDriver) add_subdirectory(Object) +add_subdirectory(DebugInfo) add_subdirectory(ExecutionEngine) add_subdirectory(Target) add_subdirectory(AsmParser) diff --git a/lib/CodeGen/Analysis.cpp b/lib/CodeGen/Analysis.cpp index 125e64196f15..fafc01044d4f 100644 --- a/lib/CodeGen/Analysis.cpp +++ b/lib/CodeGen/Analysis.cpp @@ -31,7 +31,7 @@ using namespace llvm; /// of insertvalue or extractvalue indices that identify a member, return /// the linearized index of the start of the member. /// -unsigned llvm::ComputeLinearIndex(const Type *Ty, +unsigned llvm::ComputeLinearIndex(Type *Ty, const unsigned *Indices, const unsigned *IndicesEnd, unsigned CurIndex) { @@ -40,7 +40,7 @@ unsigned llvm::ComputeLinearIndex(const Type *Ty, return CurIndex; // Given a struct type, recursively traverse the elements. - if (const StructType *STy = dyn_cast(Ty)) { + if (StructType *STy = dyn_cast(Ty)) { for (StructType::element_iterator EB = STy->element_begin(), EI = EB, EE = STy->element_end(); @@ -52,8 +52,8 @@ unsigned llvm::ComputeLinearIndex(const Type *Ty, return CurIndex; } // Given an array type, recursively traverse the elements. - else if (const ArrayType *ATy = dyn_cast(Ty)) { - const Type *EltTy = ATy->getElementType(); + else if (ArrayType *ATy = dyn_cast(Ty)) { + Type *EltTy = ATy->getElementType(); for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) { if (Indices && *Indices == i) return ComputeLinearIndex(EltTy, Indices+1, IndicesEnd, CurIndex); @@ -72,12 +72,12 @@ unsigned llvm::ComputeLinearIndex(const Type *Ty, /// If Offsets is non-null, it points to a vector to be filled in /// with the in-memory offsets of each of the individual values. /// -void llvm::ComputeValueVTs(const TargetLowering &TLI, const Type *Ty, +void llvm::ComputeValueVTs(const TargetLowering &TLI, Type *Ty, SmallVectorImpl &ValueVTs, SmallVectorImpl *Offsets, uint64_t StartingOffset) { // Given a struct type, recursively traverse the elements. - if (const StructType *STy = dyn_cast(Ty)) { + if (StructType *STy = dyn_cast(Ty)) { const StructLayout *SL = TLI.getTargetData()->getStructLayout(STy); for (StructType::element_iterator EB = STy->element_begin(), EI = EB, @@ -88,8 +88,8 @@ void llvm::ComputeValueVTs(const TargetLowering &TLI, const Type *Ty, return; } // Given an array type, recursively traverse the elements. - if (const ArrayType *ATy = dyn_cast(Ty)) { - const Type *EltTy = ATy->getElementType(); + if (ArrayType *ATy = dyn_cast(Ty)) { + Type *EltTy = ATy->getElementType(); uint64_t EltSize = TLI.getTargetData()->getTypeAllocSize(EltTy); for (unsigned i = 0, e = ATy->getNumElements(); i != e; ++i) ComputeValueVTs(TLI, EltTy, ValueVTs, Offsets, diff --git a/lib/CodeGen/AsmPrinter/ARMException.cpp b/lib/CodeGen/AsmPrinter/ARMException.cpp index 5861fa4817f6..3f2387325360 100644 --- a/lib/CodeGen/AsmPrinter/ARMException.cpp +++ b/lib/CodeGen/AsmPrinter/ARMException.cpp @@ -17,7 +17,6 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineLocation.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" @@ -27,7 +26,6 @@ #include "llvm/Target/Mangler.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameLowering.h" -#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetRegisterInfo.h" diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 7f314eed3ae6..1999f3608788 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -33,7 +33,6 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Target/Mangler.h" -#include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" @@ -45,6 +44,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/Timer.h" using namespace llvm; @@ -290,10 +290,10 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { // Handle common and BSS local symbols (.lcomm). if (GVKind.isCommon() || GVKind.isBSSLocal()) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. + unsigned Align = 1 << AlignLog; // Handle common symbols. if (GVKind.isCommon()) { - unsigned Align = 1 << AlignLog; if (!getObjFileLowering().getCommDirectiveSupportsAlignment()) Align = 0; @@ -307,17 +307,17 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { const MCSection *TheSection = getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM); // .zerofill __DATA, __bss, _foo, 400, 5 - OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog); + OutStreamer.EmitZerofill(TheSection, GVSym, Size, Align); return; } - if (MAI->hasLCOMMDirective()) { + if (MAI->getLCOMMDirectiveType() != LCOMM::None && + (MAI->getLCOMMDirectiveType() != LCOMM::NoAlignment || Align == 1)) { // .lcomm _foo, 42 - OutStreamer.EmitLocalCommonSymbol(GVSym, Size); + OutStreamer.EmitLocalCommonSymbol(GVSym, Size, Align); return; } - unsigned Align = 1 << AlignLog; if (!getObjFileLowering().getCommDirectiveSupportsAlignment()) Align = 0; @@ -474,8 +474,10 @@ void AsmPrinter::EmitFunctionHeader() { void AsmPrinter::EmitFunctionEntryLabel() { // The function label could have already been emitted if two symbols end up // conflicting due to asm renaming. Detect this and emit an error. - if (CurrentFnSym->isUndefined()) + if (CurrentFnSym->isUndefined()) { + OutStreamer.ForceCodeRegion(); return OutStreamer.EmitLabel(CurrentFnSym); + } report_fatal_error("'" + Twine(CurrentFnSym->getName()) + "' label emitted multiple times to assembly file"); @@ -620,6 +622,9 @@ void AsmPrinter::emitPrologLabel(const MachineInstr &MI) { if (needsCFIMoves() == CFI_M_None) return; + if (MMI->getCompactUnwindEncoding() != 0) + OutStreamer.EmitCompactUnwindEncoding(MMI->getCompactUnwindEncoding()); + MachineModuleInfo &MMI = MF->getMMI(); std::vector &Moves = MMI.getFrameMoves(); bool FoundOne = false; @@ -878,7 +883,7 @@ bool AsmPrinter::doFinalization(Module &M) { I != E; ++I) { MCSymbol *Name = Mang->getSymbol(I); - const GlobalValue *GV = cast(I->getAliasedGlobal()); + const GlobalValue *GV = I->getAliasedGlobal(); MCSymbol *Target = Mang->getSymbol(GV); if (I->hasExternalLinkage() || !MAI->getWeakRefDirective()) @@ -1009,7 +1014,7 @@ void AsmPrinter::EmitConstantPool() { unsigned NewOffset = (Offset + AlignMask) & ~AlignMask; OutStreamer.EmitFill(NewOffset - Offset, 0/*fillval*/, 0/*addrspace*/); - const Type *Ty = CPE.getType(); + Type *Ty = CPE.getType(); Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty); OutStreamer.EmitLabel(GetCPISymbol(CPI)); @@ -1055,6 +1060,15 @@ void AsmPrinter::EmitJumpTableInfo() { EmitAlignment(Log2_32(MJTI->getEntryAlignment(*TM.getTargetData()))); + // If we know the form of the jump table, go ahead and tag it as such. + if (!JTInDiffSection) { + if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32) { + OutStreamer.EmitJumpTable32Region(); + } else { + OutStreamer.EmitDataRegion(); + } + } + for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) { const std::vector &JTBBs = JT[JTI].MBBs; @@ -1226,22 +1240,53 @@ void AsmPrinter::EmitLLVMUsedList(const Constant *List) { } } -/// EmitXXStructorList - Emit the ctor or dtor list. This just prints out the -/// function pointers, ignoring the init priority. +typedef std::pair Structor; + +static bool priority_order(const Structor& lhs, const Structor& rhs) { + return lhs.first < rhs.first; +} + +/// EmitXXStructorList - Emit the ctor or dtor list taking into account the init +/// priority. void AsmPrinter::EmitXXStructorList(const Constant *List) { // Should be an array of '{ int, void ()* }' structs. The first value is the - // init priority, which we ignore. + // init priority. if (!isa(List)) return; - const ConstantArray *InitList = cast(List); - for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) - if (ConstantStruct *CS = dyn_cast(InitList->getOperand(i))){ - if (CS->getNumOperands() != 2) return; // Not array of 2-element structs. - if (CS->getOperand(1)->isNullValue()) - return; // Found a null terminator, exit printing. - // Emit the function pointer. - EmitGlobalConstant(CS->getOperand(1)); - } + // Sanity check the structors list. + const ConstantArray *InitList = dyn_cast(List); + if (!InitList) return; // Not an array! + StructType *ETy = dyn_cast(InitList->getType()->getElementType()); + if (!ETy || ETy->getNumElements() != 2) return; // Not an array of pairs! + if (!isa(ETy->getTypeAtIndex(0U)) || + !isa(ETy->getTypeAtIndex(1U))) return; // Not (int, ptr). + + // Gather the structors in a form that's convenient for sorting by priority. + SmallVector Structors; + for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { + ConstantStruct *CS = dyn_cast(InitList->getOperand(i)); + if (!CS) continue; // Malformed. + if (CS->getOperand(1)->isNullValue()) + break; // Found a null terminator, skip the rest. + ConstantInt *Priority = dyn_cast(CS->getOperand(0)); + if (!Priority) continue; // Malformed. + Structors.push_back(std::make_pair(Priority->getLimitedValue(65535), + CS->getOperand(1))); + } + + // Emit the function pointers in reverse priority order. + switch (MAI->getStructorOutputOrder()) { + case Structors::None: + break; + case Structors::PriorityOrder: + std::sort(Structors.begin(), Structors.end(), priority_order); + break; + case Structors::ReversePriorityOrder: + std::sort(Structors.rbegin(), Structors.rend(), priority_order); + break; + } + for (unsigned i = 0, e = Structors.size(); i != e; ++i) + EmitGlobalConstant(Structors[i].second); } //===--------------------------------------------------------------------===// @@ -1406,8 +1451,7 @@ static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { // Generate a symbolic expression for the byte address const Constant *PtrVal = CE->getOperand(0); SmallVector IdxVec(CE->op_begin()+1, CE->op_end()); - int64_t Offset = TD.getIndexedOffset(PtrVal->getType(), &IdxVec[0], - IdxVec.size()); + int64_t Offset = TD.getIndexedOffset(PtrVal->getType(), IdxVec); const MCExpr *Base = LowerConstant(CE->getOperand(0), AP); if (Offset == 0) @@ -1447,7 +1491,7 @@ static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { // Support only foldable casts to/from pointers that can be eliminated by // changing the pointer to the appropriately sized integer type. Constant *Op = CE->getOperand(0); - const Type *Ty = CE->getType(); + Type *Ty = CE->getType(); const MCExpr *OpExpr = LowerConstant(Op, AP); @@ -1496,12 +1540,67 @@ static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { static void EmitGlobalConstantImpl(const Constant *C, unsigned AddrSpace, AsmPrinter &AP); +/// isRepeatedByteSequence - Determine whether the given value is +/// composed of a repeated sequence of identical bytes and return the +/// byte value. If it is not a repeated sequence, return -1. +static int isRepeatedByteSequence(const Value *V, TargetMachine &TM) { + + if (const ConstantInt *CI = dyn_cast(V)) { + if (CI->getBitWidth() > 64) return -1; + + uint64_t Size = TM.getTargetData()->getTypeAllocSize(V->getType()); + uint64_t Value = CI->getZExtValue(); + + // Make sure the constant is at least 8 bits long and has a power + // of 2 bit width. This guarantees the constant bit width is + // always a multiple of 8 bits, avoiding issues with padding out + // to Size and other such corner cases. + if (CI->getBitWidth() < 8 || !isPowerOf2_64(CI->getBitWidth())) return -1; + + uint8_t Byte = static_cast(Value); + + for (unsigned i = 1; i < Size; ++i) { + Value >>= 8; + if (static_cast(Value) != Byte) return -1; + } + return Byte; + } + if (const ConstantArray *CA = dyn_cast(V)) { + // Make sure all array elements are sequences of the same repeated + // byte. + if (CA->getNumOperands() == 0) return -1; + + int Byte = isRepeatedByteSequence(CA->getOperand(0), TM); + if (Byte == -1) return -1; + + for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { + int ThisByte = isRepeatedByteSequence(CA->getOperand(i), TM); + if (ThisByte == -1) return -1; + if (Byte != ThisByte) return -1; + } + return Byte; + } + + return -1; +} + static void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace, AsmPrinter &AP) { if (AddrSpace != 0 || !CA->isString()) { - // Not a string. Print the values in successive locations - for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) - EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP); + // Not a string. Print the values in successive locations. + + // See if we can aggregate some values. Make sure it can be + // represented as a series of bytes of the constant value. + int Value = isRepeatedByteSequence(CA, AP.TM); + + if (Value != -1) { + uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CA->getType()); + AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace); + } + else { + for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) + EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP); + } return; } diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index dd5b0e261490..4d6c28118427 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -13,7 +13,7 @@ #define DEBUG_TYPE "asm-printer" #include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineLocation.h" +#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp index 5ac455e1a1a1..8eda889155a2 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -23,15 +23,15 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/Target/TargetAsmParser.h" +#include "llvm/MC/MCTargetAsmParser.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegistry.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -49,7 +49,7 @@ namespace { static void SrcMgrDiagHandler(const SMDiagnostic &Diag, void *diagInfo) { SrcMgrDiagInfo *DiagInfo = static_cast(diagInfo); assert(DiagInfo && "Diagnostic context not passed down?"); - + // If the inline asm had metadata associated with it, pull out a location // cookie corresponding to which line the error occurred on. unsigned LocCookie = 0; @@ -57,13 +57,13 @@ static void SrcMgrDiagHandler(const SMDiagnostic &Diag, void *diagInfo) { unsigned ErrorLine = Diag.getLineNo()-1; if (ErrorLine >= LocInfo->getNumOperands()) ErrorLine = 0; - + if (LocInfo->getNumOperands() != 0) if (const ConstantInt *CI = dyn_cast(LocInfo->getOperand(ErrorLine))) LocCookie = CI->getZExtValue(); } - + DiagInfo->DiagHandler(Diag, DiagInfo->DiagContext, LocCookie); } @@ -109,7 +109,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode) const { // Tell SrcMgr about this buffer, it takes ownership of the buffer. SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); - OwningPtr Parser(createMCAsmParser(TM.getTarget(), SrcMgr, + OwningPtr Parser(createMCAsmParser(SrcMgr, OutContext, OutStreamer, *MAI)); @@ -121,7 +121,8 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode) const { STI(TM.getTarget().createMCSubtargetInfo(TM.getTargetTriple(), TM.getTargetCPU(), TM.getTargetFeatureString())); - OwningPtr TAP(TM.getTarget().createAsmParser(*STI, *Parser)); + OwningPtr + TAP(TM.getTarget().createMCAsmParser(*STI, *Parser)); if (!TAP) report_fatal_error("Inline asm not supported by this streamer because" " we don't have an asm parser for this target\n"); diff --git a/lib/CodeGen/AsmPrinter/CMakeLists.txt b/lib/CodeGen/AsmPrinter/CMakeLists.txt index 4da7876ea4fc..67d927348b54 100644 --- a/lib/CodeGen/AsmPrinter/CMakeLists.txt +++ b/lib/CodeGen/AsmPrinter/CMakeLists.txt @@ -12,3 +12,12 @@ add_llvm_library(LLVMAsmPrinter Win64Exception.cpp ) +add_llvm_library_dependencies(LLVMAsmPrinter + LLVMAnalysis + LLVMCodeGen + LLVMCore + LLVMMC + LLVMMCParser + LLVMSupport + LLVMTarget + ) diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index 21396ca37f06..9c1ce761b0c5 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -69,7 +69,7 @@ void DIEAbbrev::Emit(AsmPrinter *AP) const { // Emit attribute type. // FIXME: Doing work even in non-asm-verbose runs. AP->EmitULEB128(AttrData.getAttribute(), - dwarf::AttributeString(AttrData.getAttribute())); + dwarf::AttributeString(AttrData.getAttribute())); // Emit form type. // FIXME: Doing work even in non-asm-verbose runs. diff --git a/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp index 91b7d08c6ae2..8ed4f4c43a7c 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp @@ -17,7 +17,7 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineLocation.h" +#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" @@ -77,7 +77,8 @@ void DwarfCFIException::EndModule() { // This is a temporary hack to keep sections in the same order they // were before. This lets us produce bit identical outputs while // transitioning to CFI. - Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection()); + Asm->OutStreamer.SwitchSection( + const_cast(TLOF).getEHFrameSection()); } } diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 1fe035efde3e..88b752473073 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -16,7 +16,10 @@ #include "DwarfCompileUnit.h" #include "DwarfDebug.h" #include "llvm/Constants.h" +#include "llvm/GlobalVariable.h" +#include "llvm/Instructions.h" #include "llvm/Analysis/DIBuilder.h" +#include "llvm/Target/Mangler.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetMachine.h" @@ -132,8 +135,8 @@ void CompileUnit::addSourceLine(DIE *Die, DIGlobalVariable G) { unsigned Line = G.getLineNumber(); if (Line == 0) return; - unsigned FileID = DD->GetOrCreateSourceID(G.getContext().getFilename(), - G.getContext().getDirectory()); + unsigned FileID = DD->GetOrCreateSourceID(G.getFilename(), + G.getDirectory()); assert(FileID && "Invalid file id"); addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); @@ -439,27 +442,36 @@ void CompileUnit::addBlockByrefAddress(DbgVariable *&DV, DIE *Die, addBlock(Die, Attribute, 0, Block); } +/// isTypeSigned - Return true if the type is signed. +static bool isTypeSigned(DIType Ty, int *SizeInBits) { + if (Ty.isDerivedType()) + return isTypeSigned(DIDerivedType(Ty).getTypeDerivedFrom(), SizeInBits); + if (Ty.isBasicType()) + if (DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed + || DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed_char) { + *SizeInBits = Ty.getSizeInBits(); + return true; + } + return false; +} + /// addConstantValue - Add constant value entry in variable DIE. bool CompileUnit::addConstantValue(DIE *Die, const MachineOperand &MO, DIType Ty) { assert (MO.isImm() && "Invalid machine operand!"); DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); - unsigned form = dwarf::DW_FORM_udata; - switch (Ty.getSizeInBits()) { - case 8: form = dwarf::DW_FORM_data1; break; - case 16: form = dwarf::DW_FORM_data2; break; - case 32: form = dwarf::DW_FORM_data4; break; - case 64: form = dwarf::DW_FORM_data8; break; + int SizeInBits = -1; + bool SignedConstant = isTypeSigned(Ty, &SizeInBits); + unsigned Form = SignedConstant ? dwarf::DW_FORM_sdata : dwarf::DW_FORM_udata; + switch (SizeInBits) { + case 8: Form = dwarf::DW_FORM_data1; break; + case 16: Form = dwarf::DW_FORM_data2; break; + case 32: Form = dwarf::DW_FORM_data4; break; + case 64: Form = dwarf::DW_FORM_data8; break; default: break; } - - DIBasicType BTy(Ty); - if (BTy.Verify() && - (BTy.getEncoding() == dwarf::DW_ATE_signed - || BTy.getEncoding() == dwarf::DW_ATE_signed_char)) - addSInt(Block, 0, form, MO.getImm()); - else - addUInt(Block, 0, form, MO.getImm()); + SignedConstant ? addSInt(Block, 0, Form, MO.getImm()) + : addUInt(Block, 0, Form, MO.getImm()); addBlock(Die, dwarf::DW_AT_const_value, 0, Block); return true; @@ -555,7 +567,7 @@ void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) { DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context)); ContextDIE->addChild(Die); } else if (Context.isSubprogram()) { - DIE *ContextDIE = DD->createSubprogramDIE(DISubprogram(Context)); + DIE *ContextDIE = getOrCreateSubprogramDIE(DISubprogram(Context)); ContextDIE->addChild(Die); } else if (DIE *ContextDIE = getDIE(Context)) ContextDIE->addChild(Die); @@ -565,7 +577,10 @@ void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) { /// getOrCreateTypeDIE - Find existing DIE or create new DIE for the /// given DIType. -DIE *CompileUnit::getOrCreateTypeDIE(DIType Ty) { +DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) { + DIType Ty(TyNode); + if (!Ty.Verify()) + return NULL; DIE *TyDIE = getDIE(Ty); if (TyDIE) return TyDIE; @@ -617,7 +632,8 @@ void CompileUnit::addType(DIE *Entity, DIType Ty) { void CompileUnit::addGlobalType(DIType Ty) { DIDescriptor Context = Ty.getContext(); if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl() - && (Context.isCompileUnit() || Context.isFile() || Context.isNameSpace())) + && (!Context || Context.isCompileUnit() || Context.isFile() + || Context.isNameSpace())) if (DIEEntry *Entry = getDIEEntry(Ty)) GlobalTypes[Ty.getName()] = Entry->getEntry(); } @@ -642,13 +658,20 @@ void CompileUnit::addPubTypes(DISubprogram SP) { void CompileUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) { // Get core information. StringRef Name = BTy.getName(); - Buffer.setTag(dwarf::DW_TAG_base_type); - addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, - BTy.getEncoding()); - // Add name if not anonymous or intermediate type. if (!Name.empty()) addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); + + if (BTy.getTag() == dwarf::DW_TAG_unspecified_type) { + Buffer.setTag(dwarf::DW_TAG_unspecified_type); + // Unspecified types has only name, nothing else. + return; + } + + Buffer.setTag(dwarf::DW_TAG_base_type); + addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, + BTy.getEncoding()); + uint64_t Size = BTy.getSizeInBits() >> 3; addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size); } @@ -752,7 +775,7 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { DIE *ElemDie = NULL; if (Element.isSubprogram()) { DISubprogram SP(Element); - ElemDie = DD->createSubprogramDIE(DISubprogram(Element)); + ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element)); if (SP.isProtected()) addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, dwarf::DW_ACCESS_protected); @@ -880,6 +903,218 @@ DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) { return NDie; } +/// getRealLinkageName - If special LLVM prefix that is used to inform the asm +/// printer to not emit usual symbol prefix before the symbol name is used then +/// return linkage name after skipping this special LLVM prefix. +static StringRef getRealLinkageName(StringRef LinkageName) { + char One = '\1'; + if (LinkageName.startswith(StringRef(&One, 1))) + return LinkageName.substr(1); + return LinkageName; +} + +/// getOrCreateSubprogramDIE - Create new DIE using SP. +DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) { + DIE *SPDie = getDIE(SP); + if (SPDie) + return SPDie; + + SPDie = new DIE(dwarf::DW_TAG_subprogram); + + // DW_TAG_inlined_subroutine may refer to this DIE. + insertDIE(SP, SPDie); + + // Add to context owner. + addToContextOwner(SPDie, SP.getContext()); + + // Add function template parameters. + addTemplateParams(*SPDie, SP.getTemplateParams()); + + StringRef LinkageName = SP.getLinkageName(); + if (!LinkageName.empty()) + addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, + dwarf::DW_FORM_string, + getRealLinkageName(LinkageName)); + + // If this DIE is going to refer declaration info using AT_specification + // then there is no need to add other attributes. + if (SP.getFunctionDeclaration().isSubprogram()) + return SPDie; + + // Constructors and operators for anonymous aggregates do not have names. + if (!SP.getName().empty()) + addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, + SP.getName()); + + addSourceLine(SPDie, SP); + + if (SP.isPrototyped()) + addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1); + + // Add Return Type. + DICompositeType SPTy = SP.getType(); + DIArray Args = SPTy.getTypeArray(); + unsigned SPTag = SPTy.getTag(); + + if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type) + addType(SPDie, SPTy); + else + addType(SPDie, DIType(Args.getElement(0))); + + unsigned VK = SP.getVirtuality(); + if (VK) { + addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK); + DIEBlock *Block = getDIEBlock(); + addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); + addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex()); + addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block); + ContainingTypeMap.insert(std::make_pair(SPDie, + SP.getContainingType())); + } + + if (!SP.isDefinition()) { + addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); + + // Add arguments. Do not add arguments for subprogram definition. They will + // be handled while processing variables. + DICompositeType SPTy = SP.getType(); + DIArray Args = SPTy.getTypeArray(); + unsigned SPTag = SPTy.getTag(); + + 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); + DIType ATy = DIType(DIType(Args.getElement(i))); + 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); + + if (!SP.isLocalToUnit()) + addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); + + if (SP.isOptimized()) + addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1); + + if (unsigned isa = Asm->getISAEncoding()) { + addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa); + } + + return SPDie; +} + +// Return const expression if value is a GEP to access merged global +// constant. e.g. +// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0) +static const ConstantExpr *getMergedGlobalExpr(const Value *V) { + const ConstantExpr *CE = dyn_cast_or_null(V); + if (!CE || CE->getNumOperands() != 3 || + CE->getOpcode() != Instruction::GetElementPtr) + return NULL; + + // First operand points to a global struct. + Value *Ptr = CE->getOperand(0); + if (!isa(Ptr) || + !isa(cast(Ptr->getType())->getElementType())) + return NULL; + + // Second operand is zero. + const ConstantInt *CI = dyn_cast_or_null(CE->getOperand(1)); + if (!CI || !CI->isZero()) + return NULL; + + // Third operand is offset. + if (!isa(CE->getOperand(2))) + return NULL; + + return CE; +} + +/// createGlobalVariableDIE - create global variable DIE. +void CompileUnit::createGlobalVariableDIE(const MDNode *N) { + // Check for pre-existence. + if (getDIE(N)) + return; + + DIGlobalVariable GV(N); + if (!GV.Verify()) + return; + + DIE *VariableDIE = new DIE(GV.getTag()); + // Add to map. + insertDIE(N, VariableDIE); + + // Add name. + addString(VariableDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, + GV.getDisplayName()); + StringRef LinkageName = GV.getLinkageName(); + bool isGlobalVariable = GV.getGlobal() != NULL; + if (!LinkageName.empty() && isGlobalVariable) + addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name, + dwarf::DW_FORM_string, + getRealLinkageName(LinkageName)); + // Add type. + DIType GTy = GV.getType(); + addType(VariableDIE, GTy); + + // Add scoping info. + if (!GV.isLocalToUnit()) { + addUInt(VariableDIE, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); + // Expose as global. + addGlobal(GV.getName(), VariableDIE); + } + // Add line number info. + addSourceLine(VariableDIE, GV); + // Add to context owner. + DIDescriptor GVContext = GV.getContext(); + addToContextOwner(VariableDIE, GVContext); + // Add location. + if (isGlobalVariable) { + DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); + addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); + addLabel(Block, 0, dwarf::DW_FORM_udata, + Asm->Mang->getSymbol(GV.getGlobal())); + // Do not create specification DIE if context is either compile unit + // or a subprogram. + if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() && + !GVContext.isFile() && !isSubprogramContext(GVContext)) { + // Create specification DIE. + DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable); + addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification, + dwarf::DW_FORM_ref4, VariableDIE); + addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block); + addUInt(VariableDIE, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, + 1); + addDie(VariableSpecDIE); + } else { + addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block); + } + } else if (const ConstantInt *CI = + dyn_cast_or_null(GV.getConstant())) + addConstantValue(VariableDIE, CI, GTy.isUnsignedDIType()); + else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) { + // GV is a merged global. + DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); + Value *Ptr = CE->getOperand(0); + addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); + addLabel(Block, 0, dwarf::DW_FORM_udata, + Asm->Mang->getSymbol(cast(Ptr))); + addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); + SmallVector Idx(CE->op_begin()+1, CE->op_end()); + addUInt(Block, 0, dwarf::DW_FORM_udata, + Asm->getTargetData().getIndexedOffset(Ptr->getType(), Idx)); + addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); + addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block); + } + + return; +} + /// constructSubrangeDIE - Construct subrange DIE from DISubrange. void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){ DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type); @@ -944,6 +1179,128 @@ DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) { return Enumerator; } +/// constructContainingTypeDIEs - Construct DIEs for types that contain +/// vtables. +void CompileUnit::constructContainingTypeDIEs() { + for (DenseMap::iterator CI = ContainingTypeMap.begin(), + CE = ContainingTypeMap.end(); CI != CE; ++CI) { + DIE *SPDie = CI->first; + const MDNode *N = CI->second; + if (!N) continue; + DIE *NDie = getDIE(N); + if (!NDie) continue; + addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie); + } +} + +/// constructVariableDIE - Construct a DIE for the given DbgVariable. +DIE *CompileUnit::constructVariableDIE(DbgVariable *DV, bool isScopeAbstract) { + StringRef Name = DV->getName(); + if (Name.empty()) + return NULL; + + // Translate tag to proper Dwarf tag. + unsigned Tag = DV->getTag(); + + // Define variable debug information entry. + DIE *VariableDie = new DIE(Tag); + DbgVariable *AbsVar = DV->getAbstractVariable(); + DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : NULL; + if (AbsDIE) + addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin, + dwarf::DW_FORM_ref4, AbsDIE); + else { + addString(VariableDie, dwarf::DW_AT_name, + dwarf::DW_FORM_string, Name); + addSourceLine(VariableDie, DV->getVariable()); + addType(VariableDie, DV->getType()); + } + + if (DV->isArtificial()) + addUInt(VariableDie, dwarf::DW_AT_artificial, + dwarf::DW_FORM_flag, 1); + + if (isScopeAbstract) { + DV->setDIE(VariableDie); + return VariableDie; + } + + // Add variable address. + + unsigned Offset = DV->getDotDebugLocOffset(); + if (Offset != ~0U) { + addLabel(VariableDie, dwarf::DW_AT_location, + dwarf::DW_FORM_data4, + Asm->GetTempSymbol("debug_loc", Offset)); + DV->setDIE(VariableDie); + return VariableDie; + } + + // Check if variable is described by a DBG_VALUE instruction. + if (const MachineInstr *DVInsn = DV->getMInsn()) { + bool updated = false; + if (DVInsn->getNumOperands() == 3) { + if (DVInsn->getOperand(0).isReg()) { + const MachineOperand RegOp = DVInsn->getOperand(0); + const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo(); + if (DVInsn->getOperand(1).isImm() && + TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) { + unsigned FrameReg = 0; + const TargetFrameLowering *TFI = Asm->TM.getFrameLowering(); + int Offset = + TFI->getFrameIndexReference(*Asm->MF, + DVInsn->getOperand(1).getImm(), + FrameReg); + MachineLocation Location(FrameReg, Offset); + addVariableAddress(DV, VariableDie, Location); + + } else if (RegOp.getReg()) + addVariableAddress(DV, VariableDie, + MachineLocation(RegOp.getReg())); + updated = true; + } + else if (DVInsn->getOperand(0).isImm()) + updated = + addConstantValue(VariableDie, DVInsn->getOperand(0), + DV->getType()); + else if (DVInsn->getOperand(0).isFPImm()) + updated = + addConstantFPValue(VariableDie, DVInsn->getOperand(0)); + else if (DVInsn->getOperand(0).isCImm()) + updated = + addConstantValue(VariableDie, + DVInsn->getOperand(0).getCImm(), + DV->getType().isUnsignedDIType()); + } else { + addVariableAddress(DV, VariableDie, + Asm->getDebugValueLocation(DVInsn)); + updated = true; + } + if (!updated) { + // If variableDie is not updated then DBG_VALUE instruction does not + // have valid variable info. + delete VariableDie; + return NULL; + } + DV->setDIE(VariableDie); + return VariableDie; + } else { + // .. else use frame index. + int FI = DV->getFrameIndex(); + if (FI != ~0) { + unsigned FrameReg = 0; + const TargetFrameLowering *TFI = Asm->TM.getFrameLowering(); + int Offset = + TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg); + MachineLocation Location(FrameReg, Offset); + addVariableAddress(DV, VariableDie, Location); + } + } + + DV->setDIE(VariableDie); + return VariableDie; +} + /// createMemberDIE - Create new member DIE. DIE *CompileUnit::createMemberDIE(DIDerivedType DT) { DIE *MemberDie = new DIE(DT.getTag()); @@ -1013,7 +1370,7 @@ DIE *CompileUnit::createMemberDIE(DIDerivedType DT) { addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, dwarf::DW_ACCESS_private); // Otherwise C++ member and base classes are considered public. - else if (DT.getCompileUnit().getLanguage() == dwarf::DW_LANG_C_plus_plus) + else addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, dwarf::DW_ACCESS_public); if (DT.isVirtual()) diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index 213c7fc630d3..785926579fa4 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -67,6 +67,11 @@ class CompileUnit { /// DIEBlocks - A list of all the DIEBlocks in use. std::vector DIEBlocks; + /// ContainingTypeMap - This map is used to keep track of subprogram DIEs that + /// need DW_AT_containing_type attribute. This attribute points to a DIE that + /// corresponds to the MDNode mapped with the subprogram DIE. + DenseMap ContainingTypeMap; + public: CompileUnit(unsigned I, DIE *D, AsmPrinter *A, DwarfDebug *DW); ~CompileUnit(); @@ -226,9 +231,12 @@ class CompileUnit { /// getOrCreateNameSpace - Create a DIE for DINameSpace. DIE *getOrCreateNameSpace(DINameSpace NS); + /// getOrCreateSubprogramDIE - Create new DIE using SP. + DIE *getOrCreateSubprogramDIE(DISubprogram SP); + /// getOrCreateTypeDIE - Find existing DIE or create new DIE for the /// given DIType. - DIE *getOrCreateTypeDIE(DIType Ty); + DIE *getOrCreateTypeDIE(const MDNode *N); /// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE /// for the given DITemplateTypeParameter. @@ -242,6 +250,9 @@ class CompileUnit { /// information entry. DIEEntry *createDIEEntry(DIE *Entry); + /// createGlobalVariableDIE - create global variable DIE. + void createGlobalVariableDIE(const MDNode *N); + void addPubTypes(DISubprogram SP); /// constructTypeDIE - Construct basic type die from DIBasicType. @@ -266,6 +277,13 @@ class CompileUnit { /// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. DIE *constructEnumTypeDIE(DIEnumerator ETy); + /// constructContainingTypeDIEs - Construct DIEs for types that contain + /// vtables. + void constructContainingTypeDIEs(); + + /// constructVariableDIE - Construct a DIE for the given DbgVariable. + DIE *constructVariableDIE(DbgVariable *DV, bool isScopeAbstract); + /// createMemberDIE - Create new member DIE. DIE *createMemberDIE(DIDerivedType DT); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 125e1e86b12f..1b7e370fca09 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -24,7 +24,6 @@ #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/Target/Mangler.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetLoweringObjectFile.h" @@ -45,9 +44,6 @@ #include "llvm/Support/Path.h" using namespace llvm; -static cl::opt PrintDbgScope("print-dbgscope", cl::Hidden, - cl::desc("Print DbgScope information for each machine instruction")); - static cl::opt DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden, cl::desc("Disable debug info printing")); @@ -69,7 +65,7 @@ static const unsigned InitAbbreviationsSetSize = 9; // log2(512) namespace llvm { -DIType DbgVariable::getType() const { +DIType DbgVariable::getType() const { DIType Ty = Var.getType(); // FIXME: isBlockByrefVariable should be reformulated in terms of complex // addresses instead. @@ -120,141 +116,12 @@ DIType DbgVariable::getType() const { return Ty; } -//===----------------------------------------------------------------------===// -/// DbgRange - This is used to track range of instructions with identical -/// debug info scope. -/// -typedef std::pair DbgRange; - -//===----------------------------------------------------------------------===// -/// DbgScope - This class is used to track scope information. -/// -class DbgScope { - DbgScope *Parent; // Parent to this scope. - DIDescriptor Desc; // Debug info descriptor for scope. - // Location at which this scope is inlined. - AssertingVH InlinedAtLocation; - bool AbstractScope; // Abstract Scope - const MachineInstr *LastInsn; // Last instruction of this scope. - const MachineInstr *FirstInsn; // First instruction of this scope. - unsigned DFSIn, DFSOut; - // Scopes defined in scope. Contents not owned. - SmallVector Scopes; - // Variables declared in scope. Contents owned. - SmallVector Variables; - SmallVector Ranges; - // Private state for dump() - mutable unsigned IndentLevel; -public: - DbgScope(DbgScope *P, DIDescriptor D, const MDNode *I = 0) - : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(false), - LastInsn(0), FirstInsn(0), - DFSIn(0), DFSOut(0), IndentLevel(0) {} - virtual ~DbgScope(); - - // Accessors. - DbgScope *getParent() const { return Parent; } - void setParent(DbgScope *P) { Parent = P; } - DIDescriptor getDesc() const { return Desc; } - const MDNode *getInlinedAt() const { return InlinedAtLocation; } - const MDNode *getScopeNode() const { return Desc; } - const SmallVector &getScopes() { return Scopes; } - const SmallVector &getDbgVariables() { return Variables; } - const SmallVector &getRanges() { return Ranges; } - - /// openInsnRange - This scope covers instruction range starting from MI. - void openInsnRange(const MachineInstr *MI) { - if (!FirstInsn) - FirstInsn = MI; - - if (Parent) - Parent->openInsnRange(MI); - } - - /// extendInsnRange - Extend the current instruction range covered by - /// this scope. - void extendInsnRange(const MachineInstr *MI) { - assert (FirstInsn && "MI Range is not open!"); - LastInsn = MI; - if (Parent) - Parent->extendInsnRange(MI); - } - - /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected - /// until now. This is used when a new scope is encountered while walking - /// machine instructions. - void closeInsnRange(DbgScope *NewScope = NULL) { - assert (LastInsn && "Last insn missing!"); - Ranges.push_back(DbgRange(FirstInsn, LastInsn)); - FirstInsn = NULL; - LastInsn = NULL; - // If Parent dominates NewScope then do not close Parent's instruction - // range. - if (Parent && (!NewScope || !Parent->dominates(NewScope))) - Parent->closeInsnRange(NewScope); - } - - void setAbstractScope() { AbstractScope = true; } - bool isAbstractScope() const { return AbstractScope; } - - // Depth First Search support to walk and mainpluate DbgScope hierarchy. - unsigned getDFSOut() const { return DFSOut; } - void setDFSOut(unsigned O) { DFSOut = O; } - unsigned getDFSIn() const { return DFSIn; } - void setDFSIn(unsigned I) { DFSIn = I; } - bool dominates(const DbgScope *S) { - if (S == this) - return true; - if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut()) - return true; - return false; - } - - /// addScope - Add a scope to the scope. - /// - void addScope(DbgScope *S) { Scopes.push_back(S); } - - /// addVariable - Add a variable to the scope. - /// - void addVariable(DbgVariable *V) { Variables.push_back(V); } - -#ifndef NDEBUG - void dump() const; -#endif -}; - } // end llvm namespace -#ifndef NDEBUG -void DbgScope::dump() const { - raw_ostream &err = dbgs(); - err.indent(IndentLevel); - err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n"; - const MDNode *N = Desc; - N->dump(); - if (AbstractScope) - err << "Abstract Scope\n"; - - IndentLevel += 2; - if (!Scopes.empty()) - err << "Children ...\n"; - for (unsigned i = 0, e = Scopes.size(); i != e; ++i) - if (Scopes[i] != this) - Scopes[i]->dump(); - - IndentLevel -= 2; -} -#endif - -DbgScope::~DbgScope() { - for (unsigned j = 0, M = Variables.size(); j < M; ++j) - delete Variables[j]; -} - DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) : Asm(A), MMI(Asm->MMI), FirstCU(0), AbbreviationsSet(InitAbbreviationsSetSize), - CurrentFnDbgScope(0), PrevLabel(NULL) { + PrevLabel(NULL) { NextStringPoolNumber = 0; DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0; @@ -311,147 +178,12 @@ static StringRef getRealLinkageName(StringRef LinkageName) { return LinkageName; } -/// createSubprogramDIE - Create new DIE using SP. -DIE *DwarfDebug::createSubprogramDIE(DISubprogram SP) { - CompileUnit *SPCU = getCompileUnit(SP); - DIE *SPDie = SPCU->getDIE(SP); - if (SPDie) - return SPDie; - - SPDie = new DIE(dwarf::DW_TAG_subprogram); - - // DW_TAG_inlined_subroutine may refer to this DIE. - SPCU->insertDIE(SP, SPDie); - - // Add to context owner. - SPCU->addToContextOwner(SPDie, SP.getContext()); - - // Add function template parameters. - SPCU->addTemplateParams(*SPDie, SP.getTemplateParams()); - - StringRef LinkageName = SP.getLinkageName(); - if (!LinkageName.empty()) - SPCU->addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string, - getRealLinkageName(LinkageName)); - - // If this DIE is going to refer declaration info using AT_specification - // then there is no need to add other attributes. - if (SP.getFunctionDeclaration().isSubprogram()) - return SPDie; - - // Constructors and operators for anonymous aggregates do not have names. - if (!SP.getName().empty()) - SPCU->addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, - SP.getName()); - - SPCU->addSourceLine(SPDie, SP); - - if (SP.isPrototyped()) - SPCU->addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1); - - // Add Return Type. - DICompositeType SPTy = SP.getType(); - DIArray Args = SPTy.getTypeArray(); - unsigned SPTag = SPTy.getTag(); - - if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type) - SPCU->addType(SPDie, SPTy); - else - SPCU->addType(SPDie, DIType(Args.getElement(0))); - - unsigned VK = SP.getVirtuality(); - if (VK) { - SPCU->addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK); - DIEBlock *Block = SPCU->getDIEBlock(); - SPCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); - SPCU->addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex()); - SPCU->addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block); - ContainingTypeMap.insert(std::make_pair(SPDie, - SP.getContainingType())); - } - - if (!SP.isDefinition()) { - SPCU->addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); - - // Add arguments. Do not add arguments for subprogram definition. They will - // be handled while processing variables. - DICompositeType SPTy = SP.getType(); - DIArray Args = SPTy.getTypeArray(); - unsigned SPTag = SPTy.getTag(); - - 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); - DIType ATy = DIType(DIType(Args.getElement(i))); - SPCU->addType(Arg, ATy); - if (ATy.isArtificial()) - SPCU->addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); - SPDie->addChild(Arg); - } - } - - if (SP.isArtificial()) - SPCU->addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); - - if (!SP.isLocalToUnit()) - SPCU->addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); - - if (SP.isOptimized()) - SPCU->addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1); - - if (unsigned isa = Asm->getISAEncoding()) { - SPCU->addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa); - } - - return SPDie; -} - -DbgScope *DwarfDebug::getOrCreateAbstractScope(const MDNode *N) { - assert(N && "Invalid Scope encoding!"); - - DbgScope *AScope = AbstractScopes.lookup(N); - if (AScope) - return AScope; - - DbgScope *Parent = NULL; - - DIDescriptor Scope(N); - if (Scope.isLexicalBlock()) { - DILexicalBlock DB(N); - DIDescriptor ParentDesc = DB.getContext(); - Parent = getOrCreateAbstractScope(ParentDesc); - } - - AScope = new DbgScope(Parent, DIDescriptor(N), NULL); - - if (Parent) - Parent->addScope(AScope); - AScope->setAbstractScope(); - AbstractScopes[N] = AScope; - if (DIDescriptor(N).isSubprogram()) - AbstractScopesList.push_back(AScope); - return AScope; -} - -/// isSubprogramContext - Return true if Context is either a subprogram -/// or another context nested inside a subprogram. -static bool isSubprogramContext(const MDNode *Context) { - if (!Context) - return false; - DIDescriptor D(Context); - if (D.isSubprogram()) - return true; - if (D.isType()) - return isSubprogramContext(DIType(Context).getContext()); - return false; -} - /// updateSubprogramScopeDIE - Find DIE for the given subprogram and /// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes. /// If there are global variables in this scope then create and insert /// DIEs for these variables. -DIE *DwarfDebug::updateSubprogramScopeDIE(const MDNode *SPNode) { - CompileUnit *SPCU = getCompileUnit(SPNode); +DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, + const MDNode *SPNode) { DIE *SPDie = SPCU->getDIE(SPNode); assert(SPDie && "Unable to find subprogram DIE!"); @@ -461,7 +193,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(const MDNode *SPNode) { if (SPDecl.isSubprogram()) // Refer function declaration directly. SPCU->addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4, - createSubprogramDIE(SPDecl)); + SPCU->getOrCreateSubprogramDIE(SPDecl)); else { // There is not any need to generate specification DIE for a function // defined at compile unit level. If a function is defined inside another @@ -514,25 +246,26 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(const MDNode *SPNode) { /// constructLexicalScope - Construct new DW_TAG_lexical_block /// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels. -DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) { +DIE *DwarfDebug::constructLexicalScopeDIE(CompileUnit *TheCU, + LexicalScope *Scope) { DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block); if (Scope->isAbstractScope()) return ScopeDIE; - const SmallVector &Ranges = Scope->getRanges(); + const SmallVector &Ranges = Scope->getRanges(); if (Ranges.empty()) return 0; - CompileUnit *TheCU = getCompileUnit(Scope->getScopeNode()); - SmallVector::const_iterator RI = Ranges.begin(); + SmallVector::const_iterator RI = Ranges.begin(); if (Ranges.size() > 1) { // .debug_range section has not been laid out yet. Emit offset in // .debug_range as a uint, size 4, for now. emitDIE will handle // DW_AT_ranges appropriately. TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4, - DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize()); - for (SmallVector::const_iterator RI = Ranges.begin(), + DebugRangeSymbols.size() + * Asm->getTargetData().getPointerSize()); + for (SmallVector::const_iterator RI = Ranges.begin(), RE = Ranges.end(); RI != RE; ++RI) { DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first)); DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second)); @@ -559,22 +292,29 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) { /// constructInlinedScopeDIE - This scope represents inlined body of /// a function. Construct DIE to represent this concrete inlined copy /// of the function. -DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { +DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, + LexicalScope *Scope) { - const SmallVector &Ranges = Scope->getRanges(); + const SmallVector &Ranges = Scope->getRanges(); assert (Ranges.empty() == false - && "DbgScope does not have instruction markers!"); + && "LexicalScope does not have instruction markers!"); - // FIXME : .debug_inlined section specification does not clearly state how - // to emit inlined scope that is split into multiple instruction ranges. - // For now, use first instruction range and emit low_pc/high_pc pair and - // corresponding .debug_inlined section entry for this pair. - SmallVector::const_iterator RI = Ranges.begin(); + if (!Scope->getScopeNode()) + return NULL; + DIScope DS(Scope->getScopeNode()); + DISubprogram InlinedSP = getDISubprogram(DS); + DIE *OriginDIE = TheCU->getDIE(InlinedSP); + if (!OriginDIE) { + DEBUG(dbgs() << "Unable to find original DIE for inlined subprogram."); + return NULL; + } + + SmallVector::const_iterator RI = Ranges.begin(); const MCSymbol *StartLabel = getLabelBeforeInsn(RI->first); const MCSymbol *EndLabel = getLabelAfterInsn(RI->second); if (StartLabel == 0 || EndLabel == 0) { - assert (0 && "Unexpected Start and End labels for a inlined scope!"); + assert (0 && "Unexpected Start and End labels for a inlined scope!"); return 0; } assert(StartLabel->isDefined() && @@ -582,26 +322,38 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { assert(EndLabel->isDefined() && "Invalid end label for an inlined scope!"); - if (!Scope->getScopeNode()) - return NULL; - DIScope DS(Scope->getScopeNode()); - DISubprogram InlinedSP = getDISubprogram(DS); - CompileUnit *TheCU = getCompileUnit(InlinedSP); - DIE *OriginDIE = TheCU->getDIE(InlinedSP); - if (!OriginDIE) { - DEBUG(dbgs() << "Unable to find original DIE for inlined subprogram."); - return NULL; - } DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine); TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin, dwarf::DW_FORM_ref4, OriginDIE); - TheCU->addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, StartLabel); - TheCU->addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, EndLabel); + if (Ranges.size() > 1) { + // .debug_range section has not been laid out yet. Emit offset in + // .debug_range as a uint, size 4, for now. emitDIE will handle + // DW_AT_ranges appropriately. + TheCU->addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4, + DebugRangeSymbols.size() + * Asm->getTargetData().getPointerSize()); + for (SmallVector::const_iterator RI = Ranges.begin(), + RE = Ranges.end(); RI != RE; ++RI) { + DebugRangeSymbols.push_back(getLabelBeforeInsn(RI->first)); + DebugRangeSymbols.push_back(getLabelAfterInsn(RI->second)); + } + DebugRangeSymbols.push_back(NULL); + DebugRangeSymbols.push_back(NULL); + } else { + TheCU->addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, + StartLabel); + TheCU->addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, + EndLabel); + } InlinedSubprogramDIEs.insert(OriginDIE); // Track the start label for this inlined function. + //.debug_inlined section specification does not clearly state how + // to emit inlined scope that is split into multiple instruction ranges. + // For now, use first instruction range and emit low_pc/high_pc pair and + // corresponding .debug_inlined section entry for this pair. DenseMap >::iterator I = InlineInfo.find(InlinedSP); @@ -619,200 +371,51 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { return ScopeDIE; } -/// isUnsignedDIType - Return true if type encoding is unsigned. -static bool isUnsignedDIType(DIType Ty) { - DIDerivedType DTy(Ty); - if (DTy.Verify()) - return isUnsignedDIType(DTy.getTypeDerivedFrom()); - - DIBasicType BTy(Ty); - if (BTy.Verify()) { - unsigned Encoding = BTy.getEncoding(); - if (Encoding == dwarf::DW_ATE_unsigned || - Encoding == dwarf::DW_ATE_unsigned_char) - return true; - } - return false; -} - -/// constructVariableDIE - Construct a DIE for the given DbgVariable. -DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) { - StringRef Name = DV->getName(); - if (Name.empty()) - return NULL; - - // Translate tag to proper Dwarf tag. The result variable is dropped for - // now. - unsigned Tag; - switch (DV->getTag()) { - case dwarf::DW_TAG_return_variable: - return NULL; - case dwarf::DW_TAG_arg_variable: - Tag = dwarf::DW_TAG_formal_parameter; - break; - case dwarf::DW_TAG_auto_variable: // fall thru - default: - Tag = dwarf::DW_TAG_variable; - break; - } - - // Define variable debug information entry. - DIE *VariableDie = new DIE(Tag); - CompileUnit *VariableCU = getCompileUnit(DV->getVariable()); - DIE *AbsDIE = NULL; - DenseMap::iterator - V2AVI = VarToAbstractVarMap.find(DV); - if (V2AVI != VarToAbstractVarMap.end()) - AbsDIE = V2AVI->second->getDIE(); - - if (AbsDIE) - VariableCU->addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin, - dwarf::DW_FORM_ref4, AbsDIE); - else { - VariableCU->addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, - Name); - VariableCU->addSourceLine(VariableDie, DV->getVariable()); - - // Add variable type. - VariableCU->addType(VariableDie, DV->getType()); - } - - if (Tag == dwarf::DW_TAG_formal_parameter && DV->getType().isArtificial()) - VariableCU->addUInt(VariableDie, dwarf::DW_AT_artificial, - dwarf::DW_FORM_flag, 1); - else if (DIVariable(DV->getVariable()).isArtificial()) - VariableCU->addUInt(VariableDie, dwarf::DW_AT_artificial, - dwarf::DW_FORM_flag, 1); - - if (Scope->isAbstractScope()) { - DV->setDIE(VariableDie); - return VariableDie; - } - - // Add variable address. - - unsigned Offset = DV->getDotDebugLocOffset(); - if (Offset != ~0U) { - VariableCU->addLabel(VariableDie, dwarf::DW_AT_location, dwarf::DW_FORM_data4, - Asm->GetTempSymbol("debug_loc", Offset)); - DV->setDIE(VariableDie); - UseDotDebugLocEntry.insert(VariableDie); - return VariableDie; - } - - // Check if variable is described by a DBG_VALUE instruction. - DenseMap::iterator DVI = - DbgVariableToDbgInstMap.find(DV); - if (DVI != DbgVariableToDbgInstMap.end()) { - const MachineInstr *DVInsn = DVI->second; - bool updated = false; - // FIXME : Handle getNumOperands != 3 - if (DVInsn->getNumOperands() == 3) { - if (DVInsn->getOperand(0).isReg()) { - const MachineOperand RegOp = DVInsn->getOperand(0); - const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo(); - if (DVInsn->getOperand(1).isImm() && - TRI->getFrameRegister(*Asm->MF) == RegOp.getReg()) { - unsigned FrameReg = 0; - const TargetFrameLowering *TFI = Asm->TM.getFrameLowering(); - int Offset = - TFI->getFrameIndexReference(*Asm->MF, - DVInsn->getOperand(1).getImm(), - FrameReg); - MachineLocation Location(FrameReg, Offset); - VariableCU->addVariableAddress(DV, VariableDie, Location); - - } else if (RegOp.getReg()) - VariableCU->addVariableAddress(DV, VariableDie, - MachineLocation(RegOp.getReg())); - updated = true; - } - else if (DVInsn->getOperand(0).isImm()) - updated = - VariableCU->addConstantValue(VariableDie, DVInsn->getOperand(0), - DV->getType()); - else if (DVInsn->getOperand(0).isFPImm()) - updated = - VariableCU->addConstantFPValue(VariableDie, DVInsn->getOperand(0)); - else if (DVInsn->getOperand(0).isCImm()) - updated = - VariableCU->addConstantValue(VariableDie, - DVInsn->getOperand(0).getCImm(), - isUnsignedDIType(DV->getType())); - } else { - VariableCU->addVariableAddress(DV, VariableDie, - Asm->getDebugValueLocation(DVInsn)); - updated = true; - } - if (!updated) { - // If variableDie is not updated then DBG_VALUE instruction does not - // have valid variable info. - delete VariableDie; - return NULL; - } - DV->setDIE(VariableDie); - return VariableDie; - } - - // .. else use frame index, if available. - int FI = 0; - if (findVariableFrameIndex(DV, &FI)) { - unsigned FrameReg = 0; - const TargetFrameLowering *TFI = Asm->TM.getFrameLowering(); - int Offset = - TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg); - MachineLocation Location(FrameReg, Offset); - VariableCU->addVariableAddress(DV, VariableDie, Location); - } - - DV->setDIE(VariableDie); - return VariableDie; - -} - /// constructScopeDIE - Construct a DIE for this scope. -DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) { +DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { if (!Scope || !Scope->getScopeNode()) return NULL; SmallVector Children; // Collect arguments for current function. - if (Scope == CurrentFnDbgScope) + if (LScopes.isCurrentFunctionScope(Scope)) for (unsigned i = 0, N = CurrentFnArguments.size(); i < N; ++i) if (DbgVariable *ArgDV = CurrentFnArguments[i]) - if (DIE *Arg = constructVariableDIE(ArgDV, Scope)) + if (DIE *Arg = + TheCU->constructVariableDIE(ArgDV, Scope->isAbstractScope())) Children.push_back(Arg); - // Collect lexical scope childrens first. - const SmallVector &Variables = Scope->getDbgVariables(); + // Collect lexical scope children first. + const SmallVector &Variables = ScopeVariables.lookup(Scope); for (unsigned i = 0, N = Variables.size(); i < N; ++i) - if (DIE *Variable = constructVariableDIE(Variables[i], Scope)) + if (DIE *Variable = + TheCU->constructVariableDIE(Variables[i], Scope->isAbstractScope())) Children.push_back(Variable); - const SmallVector &Scopes = Scope->getScopes(); + const SmallVector &Scopes = Scope->getChildren(); for (unsigned j = 0, M = Scopes.size(); j < M; ++j) - if (DIE *Nested = constructScopeDIE(Scopes[j])) + if (DIE *Nested = constructScopeDIE(TheCU, Scopes[j])) Children.push_back(Nested); DIScope DS(Scope->getScopeNode()); DIE *ScopeDIE = NULL; if (Scope->getInlinedAt()) - ScopeDIE = constructInlinedScopeDIE(Scope); + ScopeDIE = constructInlinedScopeDIE(TheCU, Scope); else if (DS.isSubprogram()) { ProcessedSPNodes.insert(DS); if (Scope->isAbstractScope()) { - ScopeDIE = getCompileUnit(DS)->getDIE(DS); + ScopeDIE = TheCU->getDIE(DS); // Note down abstract DIE. if (ScopeDIE) AbstractSPDies.insert(std::make_pair(DS, ScopeDIE)); } else - ScopeDIE = updateSubprogramScopeDIE(DS); + ScopeDIE = updateSubprogramScopeDIE(TheCU, DS); } else { // There is no need to emit empty lexical block DIE. if (Children.empty()) return NULL; - ScopeDIE = constructLexicalScopeDIE(Scope); + ScopeDIE = constructLexicalScopeDIE(TheCU, Scope); } if (!ScopeDIE) return NULL; @@ -823,7 +426,7 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) { ScopeDIE->addChild(*I); if (DS.isSubprogram()) - getCompileUnit(DS)->addPubTypes(DISubprogram(DS)); + TheCU->addPubTypes(DISubprogram(DS)); return ScopeDIE; } @@ -862,7 +465,7 @@ unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName, /// constructCompileUnit - Create new CompileUnit for the given /// metadata node with tag DW_TAG_compile_unit. -void DwarfDebug::constructCompileUnit(const MDNode *N) { +CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) { DICompileUnit DIUnit(N); StringRef FN = DIUnit.getFilename(); StringRef Dir = DIUnit.getDirectory(); @@ -893,7 +496,8 @@ void DwarfDebug::constructCompileUnit(const MDNode *N) { StringRef Flags = DIUnit.getFlags(); if (!Flags.empty()) - NewCU->addString(Die, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string, Flags); + NewCU->addString(Die, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string, + Flags); unsigned RVer = DIUnit.getRunTimeVersion(); if (RVer) @@ -903,159 +507,19 @@ void DwarfDebug::constructCompileUnit(const MDNode *N) { if (!FirstCU) FirstCU = NewCU; CUMap.insert(std::make_pair(N, NewCU)); -} - -/// getCompielUnit - Get CompileUnit DIE. -CompileUnit *DwarfDebug::getCompileUnit(const MDNode *N) const { - assert (N && "Invalid DwarfDebug::getCompileUnit argument!"); - DIDescriptor D(N); - const MDNode *CUNode = NULL; - if (D.isCompileUnit()) - CUNode = N; - else if (D.isSubprogram()) - CUNode = DISubprogram(N).getCompileUnit(); - else if (D.isType()) - CUNode = DIType(N).getCompileUnit(); - else if (D.isGlobalVariable()) - CUNode = DIGlobalVariable(N).getCompileUnit(); - else if (D.isVariable()) - CUNode = DIVariable(N).getCompileUnit(); - else if (D.isNameSpace()) - CUNode = DINameSpace(N).getCompileUnit(); - else if (D.isFile()) - CUNode = DIFile(N).getCompileUnit(); - else - return FirstCU; - - DenseMap::const_iterator I - = CUMap.find(CUNode); - if (I == CUMap.end()) - return FirstCU; - return I->second; -} - -// Return const exprssion if value is a GEP to access merged global -// constant. e.g. -// i8* getelementptr ({ i8, i8, i8, i8 }* @_MergedGlobals, i32 0, i32 0) -static const ConstantExpr *getMergedGlobalExpr(const Value *V) { - const ConstantExpr *CE = dyn_cast_or_null(V); - if (!CE || CE->getNumOperands() != 3 || - CE->getOpcode() != Instruction::GetElementPtr) - return NULL; - - // First operand points to a global value. - if (!isa(CE->getOperand(0))) - return NULL; - - // Second operand is zero. - const ConstantInt *CI = - dyn_cast_or_null(CE->getOperand(1)); - if (!CI || !CI->isZero()) - return NULL; - - // Third operand is offset. - if (!isa(CE->getOperand(2))) - return NULL; - - return CE; -} - -/// constructGlobalVariableDIE - Construct global variable DIE. -void DwarfDebug::constructGlobalVariableDIE(const MDNode *N) { - DIGlobalVariable GV(N); - - // If debug information is malformed then ignore it. - if (GV.Verify() == false) - return; - - // Check for pre-existence. - CompileUnit *TheCU = getCompileUnit(N); - if (TheCU->getDIE(GV)) - return; - - DIType GTy = GV.getType(); - DIE *VariableDIE = new DIE(GV.getTag()); - - bool isGlobalVariable = GV.getGlobal() != NULL; - - // Add name. - TheCU->addString(VariableDIE, dwarf::DW_AT_name, dwarf::DW_FORM_string, - GV.getDisplayName()); - StringRef LinkageName = GV.getLinkageName(); - if (!LinkageName.empty() && isGlobalVariable) - TheCU->addString(VariableDIE, dwarf::DW_AT_MIPS_linkage_name, - dwarf::DW_FORM_string, - getRealLinkageName(LinkageName)); - // Add type. - TheCU->addType(VariableDIE, GTy); - - // Add scoping info. - if (!GV.isLocalToUnit()) { - TheCU->addUInt(VariableDIE, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); - // Expose as global. - TheCU->addGlobal(GV.getName(), VariableDIE); - } - // Add line number info. - TheCU->addSourceLine(VariableDIE, GV); - // Add to map. - TheCU->insertDIE(N, VariableDIE); - // Add to context owner. - DIDescriptor GVContext = GV.getContext(); - TheCU->addToContextOwner(VariableDIE, GVContext); - // Add location. - if (isGlobalVariable) { - DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); - TheCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); - TheCU->addLabel(Block, 0, dwarf::DW_FORM_udata, - Asm->Mang->getSymbol(GV.getGlobal())); - // Do not create specification DIE if context is either compile unit - // or a subprogram. - if (GV.isDefinition() && !GVContext.isCompileUnit() && - !GVContext.isFile() && !isSubprogramContext(GVContext)) { - // Create specification DIE. - DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable); - TheCU->addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification, - dwarf::DW_FORM_ref4, VariableDIE); - TheCU->addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block); - TheCU->addUInt(VariableDIE, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); - TheCU->addDie(VariableSpecDIE); - } else { - TheCU->addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block); - } - } else if (const ConstantInt *CI = - dyn_cast_or_null(GV.getConstant())) - TheCU->addConstantValue(VariableDIE, CI, isUnsignedDIType(GTy)); - else if (const ConstantExpr *CE = getMergedGlobalExpr(N->getOperand(11))) { - // GV is a merged global. - DIEBlock *Block = new (DIEValueAllocator) DIEBlock(); - TheCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); - TheCU->addLabel(Block, 0, dwarf::DW_FORM_udata, - Asm->Mang->getSymbol(cast(CE->getOperand(0)))); - ConstantInt *CII = cast(CE->getOperand(2)); - TheCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); - TheCU->addUInt(Block, 0, dwarf::DW_FORM_udata, CII->getZExtValue()); - TheCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); - TheCU->addBlock(VariableDIE, dwarf::DW_AT_location, 0, Block); - } - - return; + return NewCU; } /// construct SubprogramDIE - Construct subprogram DIE. -void DwarfDebug::constructSubprogramDIE(const MDNode *N) { +void DwarfDebug::constructSubprogramDIE(CompileUnit *TheCU, + const MDNode *N) { DISubprogram SP(N); - - // Check for pre-existence. - CompileUnit *TheCU = getCompileUnit(N); - if (TheCU->getDIE(N)) - return; - if (!SP.isDefinition()) // This is a method declaration which will be handled while constructing // class type. return; - DIE *SubprogramDie = createSubprogramDIE(SP); + DIE *SubprogramDie = TheCU->getOrCreateSubprogramDIE(SP); // Add to map. TheCU->insertDIE(N, SubprogramDie); @@ -1066,71 +530,115 @@ void DwarfDebug::constructSubprogramDIE(const MDNode *N) { // Expose as global. TheCU->addGlobal(SP.getName(), SubprogramDie); + SPMap[N] = TheCU; return; } +/// collectInfoFromNamedMDNodes - Collect debug info from named mdnodes such +/// as llvm.dbg.enum and llvm.dbg.ty +void DwarfDebug::collectInfoFromNamedMDNodes(Module *M) { + if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.sp")) + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + const MDNode *N = NMD->getOperand(i); + if (CompileUnit *CU = CUMap.lookup(DISubprogram(N).getCompileUnit())) + constructSubprogramDIE(CU, N); + } + + if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv")) + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + const MDNode *N = NMD->getOperand(i); + if (CompileUnit *CU = CUMap.lookup(DIGlobalVariable(N).getCompileUnit())) + CU->createGlobalVariableDIE(N); + } + + if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.enum")) + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + DIType Ty(NMD->getOperand(i)); + if (CompileUnit *CU = CUMap.lookup(Ty.getCompileUnit())) + CU->getOrCreateTypeDIE(Ty); + } + + if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.ty")) + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + DIType Ty(NMD->getOperand(i)); + if (CompileUnit *CU = CUMap.lookup(Ty.getCompileUnit())) + CU->getOrCreateTypeDIE(Ty); + } +} + +/// collectLegacyDebugInfo - Collect debug info using DebugInfoFinder. +/// FIXME - Remove this when dragon-egg and llvm-gcc switch to DIBuilder. +bool DwarfDebug::collectLegacyDebugInfo(Module *M) { + DebugInfoFinder DbgFinder; + DbgFinder.processModule(*M); + + bool HasDebugInfo = false; + // Scan all the compile-units to see if there are any marked as the main + // unit. If not, we do not generate debug info. + for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(), + E = DbgFinder.compile_unit_end(); I != E; ++I) { + if (DICompileUnit(*I).isMain()) { + HasDebugInfo = true; + break; + } + } + if (!HasDebugInfo) return false; + + // Create all the compile unit DIEs. + for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(), + E = DbgFinder.compile_unit_end(); I != E; ++I) + constructCompileUnit(*I); + + // Create DIEs for each global variable. + for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(), + E = DbgFinder.global_variable_end(); I != E; ++I) { + const MDNode *N = *I; + if (CompileUnit *CU = CUMap.lookup(DIGlobalVariable(N).getCompileUnit())) + CU->createGlobalVariableDIE(N); + } + + // Create DIEs for each subprogram. + for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(), + E = DbgFinder.subprogram_end(); I != E; ++I) { + const MDNode *N = *I; + if (CompileUnit *CU = CUMap.lookup(DISubprogram(N).getCompileUnit())) + constructSubprogramDIE(CU, N); + } + + return HasDebugInfo; +} + /// beginModule - Emit all Dwarf sections that should come prior to the /// content. Create global DIEs and emit initial debug info sections. -/// This is inovked by the target AsmPrinter. +/// This is invoked by the target AsmPrinter. void DwarfDebug::beginModule(Module *M) { if (DisableDebugInfoPrinting) return; - // If module has named metadata anchors then use them, otherwise scan the module - // using debug info finder to collect debug info. + // If module has named metadata anchors then use them, otherwise scan the + // module using debug info finder to collect debug info. NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); if (CU_Nodes) { - - NamedMDNode *GV_Nodes = M->getNamedMetadata("llvm.dbg.gv"); - NamedMDNode *SP_Nodes = M->getNamedMetadata("llvm.dbg.sp"); - if (!GV_Nodes && !SP_Nodes) - // If there are not any global variables or any functions then - // there is not any debug info in this module. - return; - - for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) - constructCompileUnit(CU_Nodes->getOperand(i)); - - if (GV_Nodes) - for (unsigned i = 0, e = GV_Nodes->getNumOperands(); i != e; ++i) - constructGlobalVariableDIE(GV_Nodes->getOperand(i)); - - if (SP_Nodes) - for (unsigned i = 0, e = SP_Nodes->getNumOperands(); i != e; ++i) - constructSubprogramDIE(SP_Nodes->getOperand(i)); - - } else { - - DebugInfoFinder DbgFinder; - DbgFinder.processModule(*M); - - bool HasDebugInfo = false; - // Scan all the compile-units to see if there are any marked as the main unit. - // if not, we do not generate debug info. - for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(), - E = DbgFinder.compile_unit_end(); I != E; ++I) { - if (DICompileUnit(*I).isMain()) { - HasDebugInfo = true; - break; - } + for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { + DICompileUnit CUNode(CU_Nodes->getOperand(i)); + CompileUnit *CU = constructCompileUnit(CUNode); + DIArray GVs = CUNode.getGlobalVariables(); + for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) + CU->createGlobalVariableDIE(GVs.getElement(i)); + DIArray SPs = CUNode.getSubprograms(); + for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) + constructSubprogramDIE(CU, SPs.getElement(i)); + DIArray EnumTypes = CUNode.getEnumTypes(); + for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) + CU->getOrCreateTypeDIE(EnumTypes.getElement(i)); + DIArray RetainedTypes = CUNode.getRetainedTypes(); + for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) + CU->getOrCreateTypeDIE(RetainedTypes.getElement(i)); } - if (!HasDebugInfo) return; - - // Create all the compile unit DIEs. - for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(), - E = DbgFinder.compile_unit_end(); I != E; ++I) - constructCompileUnit(*I); - - // Create DIEs for each global variable. - for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(), - E = DbgFinder.global_variable_end(); I != E; ++I) - constructGlobalVariableDIE(*I); - - // Create DIEs for each subprogram. - for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(), - E = DbgFinder.subprogram_end(); I != E; ++I) - constructSubprogramDIE(*I); - } + } else if (!collectLegacyDebugInfo(M)) + return; + + collectInfoFromNamedMDNodes(M); // Tell MMI that we have debug info. MMI->setDebugInfoAvailability(true); @@ -1138,19 +646,6 @@ void DwarfDebug::beginModule(Module *M) { // Emit initial sections. EmitSectionLabels(); - //getOrCreateTypeDIE - if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.enum")) - for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { - DIType Ty(NMD->getOperand(i)); - getCompileUnit(Ty)->getOrCreateTypeDIE(Ty); - } - - if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.ty")) - for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { - DIType Ty(NMD->getOperand(i)); - getCompileUnit(Ty)->getOrCreateTypeDIE(Ty); - } - // Prime section data. SectionMap.insert(Asm->getObjFileLowering().getTextSection()); } @@ -1160,38 +655,38 @@ void DwarfDebug::beginModule(Module *M) { void DwarfDebug::endModule() { if (!FirstCU) return; const Module *M = MMI->getModule(); - DenseMap DeadFnScopeMap; - if (NamedMDNode *AllSPs = M->getNamedMetadata("llvm.dbg.sp")) { - for (unsigned SI = 0, SE = AllSPs->getNumOperands(); SI != SE; ++SI) { - if (ProcessedSPNodes.count(AllSPs->getOperand(SI)) != 0) continue; - DISubprogram SP(AllSPs->getOperand(SI)); - if (!SP.Verify()) continue; + DenseMap DeadFnScopeMap; - // Collect info for variables that were optimized out. - if (!SP.isDefinition()) continue; - StringRef FName = SP.getLinkageName(); - if (FName.empty()) - FName = SP.getName(); - NamedMDNode *NMD = getFnSpecificMDNode(*(MMI->getModule()), FName); - if (!NMD) continue; - unsigned E = NMD->getNumOperands(); - if (!E) continue; - DbgScope *Scope = new DbgScope(NULL, DIDescriptor(SP), NULL); - DeadFnScopeMap[SP] = Scope; - for (unsigned I = 0; I != E; ++I) { - DIVariable DV(NMD->getOperand(I)); - if (!DV.Verify()) continue; - Scope->addVariable(new DbgVariable(DV)); - } + // Collect info for variables that were optimized out. + if (NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu")) { + for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { + DICompileUnit TheCU(CU_Nodes->getOperand(i)); + DIArray Subprograms = TheCU.getSubprograms(); + for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) { + DISubprogram SP(Subprograms.getElement(i)); + if (ProcessedSPNodes.count(SP) != 0) continue; + if (!SP.Verify()) continue; + if (!SP.isDefinition()) continue; + DIArray Variables = SP.getVariables(); + if (Variables.getNumElements() == 0) continue; - // Construct subprogram DIE and add variables DIEs. - constructSubprogramDIE(SP); - DIE *ScopeDIE = getCompileUnit(SP)->getDIE(SP); - const SmallVector &Variables = Scope->getDbgVariables(); - for (unsigned i = 0, N = Variables.size(); i < N; ++i) { - DIE *VariableDIE = constructVariableDIE(Variables[i], Scope); - if (VariableDIE) - ScopeDIE->addChild(VariableDIE); + LexicalScope *Scope = + new LexicalScope(NULL, DIDescriptor(SP), NULL, false); + DeadFnScopeMap[SP] = Scope; + + // Construct subprogram DIE and add variables DIEs. + CompileUnit *SPCU = CUMap.lookup(TheCU); + assert (SPCU && "Unable to find Compile Unit!"); + constructSubprogramDIE(SPCU, SP); + DIE *ScopeDIE = SPCU->getDIE(SP); + for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) { + DIVariable DV(Variables.getElement(vi)); + if (!DV.Verify()) continue; + DbgVariable *NewVar = new DbgVariable(DV, NULL); + if (DIE *VariableDIE = + SPCU->constructVariableDIE(NewVar, Scope->isAbstractScope())) + ScopeDIE->addChild(VariableDIE); + } } } } @@ -1203,15 +698,12 @@ void DwarfDebug::endModule() { FirstCU->addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined); } - for (DenseMap::iterator CI = ContainingTypeMap.begin(), - CE = ContainingTypeMap.end(); CI != CE; ++CI) { - DIE *SPDie = CI->first; - const MDNode *N = dyn_cast_or_null(CI->second); - if (!N) continue; - DIE *NDie = getCompileUnit(N)->getDIE(N); - if (!NDie) continue; - getCompileUnit(N)->addDIEEntry(SPDie, dwarf::DW_AT_containing_type, - dwarf::DW_FORM_ref4, NDie); + // Emit DW_AT_containing_type attribute to connect types with their + // vtable holding type. + for (DenseMap::iterator CUI = CUMap.begin(), + CUE = CUMap.end(); CUI != CUE; ++CUI) { + CompileUnit *TheCU = CUI->second; + TheCU->constructContainingTypeDIEs(); } // Standard sections final addresses. @@ -1261,6 +753,7 @@ void DwarfDebug::endModule() { // clean up. DeleteContainerSeconds(DeadFnScopeMap); + SPMap.clear(); for (DenseMap::iterator I = CUMap.begin(), E = CUMap.end(); I != E; ++I) delete I->second; @@ -1268,29 +761,30 @@ void DwarfDebug::endModule() { } /// findAbstractVariable - Find abstract variable, if any, associated with Var. -DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var, +DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, DebugLoc ScopeLoc) { - + LLVMContext &Ctx = DV->getContext(); + // More then one inlined variable corresponds to one abstract variable. + DIVariable Var = cleanseInlinedVariable(DV, Ctx); DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var); if (AbsDbgVariable) return AbsDbgVariable; - LLVMContext &Ctx = Var->getContext(); - DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx)); + LexicalScope *Scope = LScopes.findAbstractScope(ScopeLoc.getScope(Ctx)); if (!Scope) return NULL; - AbsDbgVariable = new DbgVariable(Var); - Scope->addVariable(AbsDbgVariable); + AbsDbgVariable = new DbgVariable(Var, NULL); + addScopeVariable(Scope, AbsDbgVariable); AbstractVariables[Var] = AbsDbgVariable; return AbsDbgVariable; } -/// addCurrentFnArgument - If Var is an current function argument that add -/// it in CurrentFnArguments list. +/// addCurrentFnArgument - If Var is a current function argument then add +/// it to CurrentFnArguments list. bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, - DbgVariable *Var, DbgScope *Scope) { - if (Scope != CurrentFnDbgScope) + DbgVariable *Var, LexicalScope *Scope) { + if (!LScopes.isCurrentFunctionScope(Scope)) return false; DIVariable DV = Var->getVariable(); if (DV.getTag() != dwarf::DW_TAG_arg_variable) @@ -1313,7 +807,7 @@ bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF, /// collectVariableInfoFromMMITable - Collect variable information from /// side table maintained by MMI. void -DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction * MF, +DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction *MF, SmallPtrSet &Processed) { MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo(); for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(), @@ -1324,21 +818,19 @@ DwarfDebug::collectVariableInfoFromMMITable(const MachineFunction * MF, DIVariable DV(Var); const std::pair &VP = VI->second; - DbgScope *Scope = findDbgScope(VP.second); + LexicalScope *Scope = LScopes.findLexicalScope(VP.second); // If variable scope is not found then skip this variable. if (Scope == 0) continue; DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.second); - DbgVariable *RegVar = new DbgVariable(DV); - recordVariableFrameIndex(RegVar, VP.first); + DbgVariable *RegVar = new DbgVariable(DV, AbsDbgVariable); + RegVar->setFrameIndex(VP.first); if (!addCurrentFnArgument(MF, RegVar, Scope)) - Scope->addVariable(RegVar); - if (AbsDbgVariable) { - recordVariableFrameIndex(AbsDbgVariable, VP.first); - VarToAbstractVarMap[RegVar] = AbsDbgVariable; - } + addScopeVariable(Scope, RegVar); + if (AbsDbgVariable) + AbsDbgVariable->setFrameIndex(VP.first); } } @@ -1351,7 +843,7 @@ static bool isDbgValueInDefinedReg(const MachineInstr *MI) { MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0; } -/// getDebugLocEntry - Get .debug_loc entry for the instraction range starting +/// getDebugLocEntry - Get .debug_loc entry for the instruction range starting /// at MI. static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm, const MCSymbol *FLabel, @@ -1379,7 +871,7 @@ static DotDebugLocEntry getDebugLocEntry(AsmPrinter *Asm, return DotDebugLocEntry(); } -/// collectVariableInfo - Populate DbgScope entries with variables' info. +/// collectVariableInfo - Find variables for each lexical scope. void DwarfDebug::collectVariableInfo(const MachineFunction *MF, SmallPtrSet &Processed) { @@ -1402,30 +894,37 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, const MachineInstr *MInsn = History.front(); DIVariable DV(Var); - DbgScope *Scope = NULL; + LexicalScope *Scope = NULL; if (DV.getTag() == dwarf::DW_TAG_arg_variable && DISubprogram(DV.getContext()).describes(MF->getFunction())) - Scope = CurrentFnDbgScope; - else - Scope = findDbgScope(MInsn->getDebugLoc()); + Scope = LScopes.getCurrentFunctionScope(); + else { + if (DV.getVersion() <= LLVMDebugVersion9) + Scope = LScopes.findLexicalScope(MInsn->getDebugLoc()); + else { + if (MDNode *IA = DV.getInlinedAt()) + Scope = LScopes.findInlinedScope(DebugLoc::getFromDILocation(IA)); + else + Scope = LScopes.findLexicalScope(cast(DV->getOperand(1))); + } + } // If variable scope is not found then skip this variable. if (!Scope) continue; Processed.insert(DV); assert(MInsn->isDebugValue() && "History must begin with debug value"); - DbgVariable *RegVar = new DbgVariable(DV); + DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc()); + DbgVariable *RegVar = new DbgVariable(DV, AbsVar); if (!addCurrentFnArgument(MF, RegVar, Scope)) - Scope->addVariable(RegVar); - if (DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc())) { - DbgVariableToDbgInstMap[AbsVar] = MInsn; - VarToAbstractVarMap[RegVar] = AbsVar; - } + addScopeVariable(Scope, RegVar); + if (AbsVar) + AbsVar->setMInsn(MInsn); // Simple ranges that are fully coalesced. if (History.size() <= 1 || (History.size() == 2 && MInsn->isIdenticalTo(History.back()))) { - DbgVariableToDbgInstMap[RegVar] = MInsn; + RegVar->setMInsn(MInsn); continue; } @@ -1471,16 +970,14 @@ DwarfDebug::collectVariableInfo(const MachineFunction *MF, } // Collect info for variables that were optimized out. - const Function *F = MF->getFunction(); - if (NamedMDNode *NMD = getFnSpecificMDNode(*(F->getParent()), F->getName())) { - for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { - DIVariable DV(cast(NMD->getOperand(i))); - if (!DV || !Processed.insert(DV)) - continue; - DbgScope *Scope = DbgScopeMap.lookup(DV.getContext()); - if (Scope) - Scope->addVariable(new DbgVariable(DV)); - } + LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); + DIArray Variables = DISubprogram(FnScope->getScopeNode()).getVariables(); + for (unsigned i = 0, e = Variables.getNumElements(); i != e; ++i) { + DIVariable DV(Variables.getElement(i)); + if (!DV || !DV.Verify() || !Processed.insert(DV)) + continue; + if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext())) + addScopeVariable(Scope, new DbgVariable(DV, NULL)); } } @@ -1561,237 +1058,33 @@ void DwarfDebug::endInstruction(const MachineInstr *MI) { I->second = PrevLabel; } -/// getOrCreateDbgScope - Create DbgScope for the scope. -DbgScope *DwarfDebug::getOrCreateDbgScope(DebugLoc DL) { - LLVMContext &Ctx = Asm->MF->getFunction()->getContext(); - MDNode *Scope = NULL; - MDNode *InlinedAt = NULL; - DL.getScopeAndInlinedAt(Scope, InlinedAt, Ctx); - - if (!InlinedAt) { - DbgScope *WScope = DbgScopeMap.lookup(Scope); - if (WScope) - return WScope; - WScope = new DbgScope(NULL, DIDescriptor(Scope), NULL); - DbgScopeMap.insert(std::make_pair(Scope, WScope)); - if (DIDescriptor(Scope).isLexicalBlock()) { - DbgScope *Parent = - getOrCreateDbgScope(DebugLoc::getFromDILexicalBlock(Scope)); - WScope->setParent(Parent); - Parent->addScope(WScope); - } else if (DIDescriptor(Scope).isSubprogram() - && DISubprogram(Scope).describes(Asm->MF->getFunction())) - CurrentFnDbgScope = WScope; - - return WScope; - } - - getOrCreateAbstractScope(Scope); - DbgScope *WScope = DbgScopeMap.lookup(InlinedAt); - if (WScope) - return WScope; - - WScope = new DbgScope(NULL, DIDescriptor(Scope), InlinedAt); - DbgScopeMap.insert(std::make_pair(InlinedAt, WScope)); - InlinedDbgScopeMap[DebugLoc::getFromDILocation(InlinedAt)] = WScope; - DbgScope *Parent = - getOrCreateDbgScope(DebugLoc::getFromDILocation(InlinedAt)); - WScope->setParent(Parent); - Parent->addScope(WScope); - return WScope; -} - -/// calculateDominanceGraph - Calculate dominance graph for DbgScope -/// hierarchy. -static void calculateDominanceGraph(DbgScope *Scope) { - assert (Scope && "Unable to calculate scop edominance graph!"); - SmallVector WorkStack; - WorkStack.push_back(Scope); - unsigned Counter = 0; - while (!WorkStack.empty()) { - DbgScope *WS = WorkStack.back(); - const SmallVector &Children = WS->getScopes(); - bool visitedChildren = false; - for (SmallVector::const_iterator SI = Children.begin(), - SE = Children.end(); SI != SE; ++SI) { - DbgScope *ChildScope = *SI; - if (!ChildScope->getDFSOut()) { - WorkStack.push_back(ChildScope); - visitedChildren = true; - ChildScope->setDFSIn(++Counter); - break; - } - } - if (!visitedChildren) { - WorkStack.pop_back(); - WS->setDFSOut(++Counter); - } - } -} - -/// printDbgScopeInfo - Print DbgScope info for each machine instruction. -static -void printDbgScopeInfo(const MachineFunction *MF, - DenseMap &MI2ScopeMap) -{ -#ifndef NDEBUG - LLVMContext &Ctx = MF->getFunction()->getContext(); - unsigned PrevDFSIn = 0; - for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); - I != E; ++I) { - for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); - II != IE; ++II) { - const MachineInstr *MInsn = II; - MDNode *Scope = NULL; - MDNode *InlinedAt = NULL; - - // Check if instruction has valid location information. - DebugLoc MIDL = MInsn->getDebugLoc(); - if (!MIDL.isUnknown()) { - MIDL.getScopeAndInlinedAt(Scope, InlinedAt, Ctx); - dbgs() << " [ "; - if (InlinedAt) - dbgs() << "*"; - DenseMap::iterator DI = - MI2ScopeMap.find(MInsn); - if (DI != MI2ScopeMap.end()) { - DbgScope *S = DI->second; - dbgs() << S->getDFSIn(); - PrevDFSIn = S->getDFSIn(); - } else - dbgs() << PrevDFSIn; - } else - dbgs() << " [ x" << PrevDFSIn; - dbgs() << " ]"; - MInsn->dump(); - } - dbgs() << "\n"; - } -#endif -} -/// extractScopeInformation - Scan machine instructions in this function -/// and collect DbgScopes. Return true, if at least one scope was found. -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()) - return false; - - // Scan each instruction and create scopes. First build working set of scopes. - SmallVector MIRanges; - DenseMap MI2ScopeMap; - DebugLoc PrevDL; - const MachineInstr *RangeBeginMI = NULL; - const MachineInstr *PrevMI = NULL; - for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end(); - I != E; ++I) { - for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); - II != IE; ++II) { - const MachineInstr *MInsn = II; - - // Check if instruction has valid location information. - const DebugLoc MIDL = MInsn->getDebugLoc(); - if (MIDL.isUnknown()) { - PrevMI = MInsn; - continue; - } - - // If scope has not changed then skip this instruction. - if (MIDL == PrevDL) { - PrevMI = MInsn; - continue; - } - - // Ignore DBG_VALUE. It does not contribute any instruction in output. - if (MInsn->isDebugValue()) - continue; - - if (RangeBeginMI) { - // If we have alread seen a beginning of a instruction range and - // current instruction scope does not match scope of first instruction - // in this range then create a new instruction range. - DEBUG(dbgs() << "Creating new instruction range :\n"); - DEBUG(dbgs() << "Begin Range at " << *RangeBeginMI); - DEBUG(dbgs() << "End Range at " << *PrevMI); - DEBUG(dbgs() << "Next Range starting at " << *MInsn); - DEBUG(dbgs() << "------------------------\n"); - DbgRange R(RangeBeginMI, PrevMI); - MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevDL); - MIRanges.push_back(R); - } - - // This is a beginning of a new instruction range. - RangeBeginMI = MInsn; - - // Reset previous markers. - PrevMI = MInsn; - PrevDL = MIDL; - } - } - - // Create last instruction range. - if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) { - DbgRange R(RangeBeginMI, PrevMI); - MIRanges.push_back(R); - MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevDL); - } - - if (!CurrentFnDbgScope) - return false; - - calculateDominanceGraph(CurrentFnDbgScope); - if (PrintDbgScope) - printDbgScopeInfo(Asm->MF, MI2ScopeMap); - - // Find ranges of instructions covered by each DbgScope; - DbgScope *PrevDbgScope = NULL; - for (SmallVector::const_iterator RI = MIRanges.begin(), - RE = MIRanges.end(); RI != RE; ++RI) { - const DbgRange &R = *RI; - DbgScope *S = MI2ScopeMap.lookup(R.first); - assert (S && "Lost DbgScope for a machine instruction!"); - if (PrevDbgScope && !PrevDbgScope->dominates(S)) - PrevDbgScope->closeInsnRange(S); - S->openInsnRange(R.first); - S->extendInsnRange(R.second); - PrevDbgScope = S; - } - - if (PrevDbgScope) - PrevDbgScope->closeInsnRange(); - - identifyScopeMarkers(); - - return !DbgScopeMap.empty(); -} - /// identifyScopeMarkers() - -/// Each DbgScope has first instruction and last instruction to mark beginning -/// and end of a scope respectively. Create an inverse map that list scopes -/// starts (and ends) with an instruction. One instruction may start (or end) -/// multiple scopes. Ignore scopes that are not reachable. +/// Each LexicalScope has first instruction and last instruction to mark +/// beginning and end of a scope respectively. Create an inverse map that list +/// scopes starts (and ends) with an instruction. One instruction may start (or +/// end) multiple scopes. Ignore scopes that are not reachable. void DwarfDebug::identifyScopeMarkers() { - SmallVector WorkList; - WorkList.push_back(CurrentFnDbgScope); + SmallVector WorkList; + WorkList.push_back(LScopes.getCurrentFunctionScope()); while (!WorkList.empty()) { - DbgScope *S = WorkList.pop_back_val(); + LexicalScope *S = WorkList.pop_back_val(); - const SmallVector &Children = S->getScopes(); + const SmallVector &Children = S->getChildren(); if (!Children.empty()) - for (SmallVector::const_iterator SI = Children.begin(), + for (SmallVector::const_iterator SI = Children.begin(), SE = Children.end(); SI != SE; ++SI) WorkList.push_back(*SI); if (S->isAbstractScope()) continue; - const SmallVector &Ranges = S->getRanges(); + const SmallVector &Ranges = S->getRanges(); if (Ranges.empty()) continue; - for (SmallVector::const_iterator RI = Ranges.begin(), + for (SmallVector::const_iterator RI = Ranges.begin(), RE = Ranges.end(); RI != RE; ++RI) { - assert(RI->first && "DbgRange does not have first instruction!"); - assert(RI->second && "DbgRange does not have second instruction!"); + assert(RI->first && "InsnRange does not have first instruction!"); + assert(RI->second && "InsnRange does not have second instruction!"); requestLabelBeforeInsn(RI->first); requestLabelAfterInsn(RI->second); } @@ -1819,7 +1112,9 @@ static DebugLoc getFnDebugLoc(DebugLoc DL, const LLVMContext &Ctx) { /// emitted immediately after the function entry point. void DwarfDebug::beginFunction(const MachineFunction *MF) { if (!MMI->hasDebugInfo()) return; - if (!extractScopeInformation()) return; + LScopes.initialize(*MF); + if (LScopes.empty()) return; + identifyScopeMarkers(); FunctionBeginSym = Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()); @@ -1953,7 +1248,8 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { const MachineInstr *Prev = History.back(); if (Prev->isDebugValue() && isDbgValueInDefinedReg(Prev)) { const MachineBasicBlock *PrevMBB = Prev->getParent(); - MachineBasicBlock::const_iterator LastMI = PrevMBB->getLastNonDebugInstr(); + MachineBasicBlock::const_iterator LastMI = + PrevMBB->getLastNonDebugInstr(); if (LastMI == PrevMBB->end()) // Drop DBG_VALUE for empty range. History.pop_back(); @@ -1985,110 +1281,73 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { } } +void DwarfDebug::addScopeVariable(LexicalScope *LS, DbgVariable *Var) { +// SmallVector &Vars = ScopeVariables.lookup(LS); + ScopeVariables[LS].push_back(Var); +// Vars.push_back(Var); +} + /// endFunction - Gather and emit post-function debug information. /// void DwarfDebug::endFunction(const MachineFunction *MF) { - if (!MMI->hasDebugInfo() || DbgScopeMap.empty()) return; + if (!MMI->hasDebugInfo() || LScopes.empty()) return; - if (CurrentFnDbgScope) { + // Define end label for subprogram. + FunctionEndSym = Asm->GetTempSymbol("func_end", + Asm->getFunctionNumber()); + // Assumes in correct section after the entry point. + Asm->OutStreamer.EmitLabel(FunctionEndSym); + + SmallPtrSet ProcessedVars; + collectVariableInfo(MF, ProcessedVars); + + LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); + CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); + assert (TheCU && "Unable to find compile unit!"); - // Define end label for subprogram. - FunctionEndSym = Asm->GetTempSymbol("func_end", - Asm->getFunctionNumber()); - // Assumes in correct section after the entry point. - Asm->OutStreamer.EmitLabel(FunctionEndSym); - - SmallPtrSet ProcessedVars; - collectVariableInfo(MF, ProcessedVars); - - // Construct abstract scopes. - for (SmallVector::iterator AI = AbstractScopesList.begin(), - AE = AbstractScopesList.end(); AI != AE; ++AI) { - DISubprogram SP((*AI)->getScopeNode()); - if (SP.Verify()) { - // Collect info for variables that were optimized out. - StringRef FName = SP.getLinkageName(); - if (FName.empty()) - FName = SP.getName(); - if (NamedMDNode *NMD = - getFnSpecificMDNode(*(MF->getFunction()->getParent()), FName)) { - for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { - DIVariable DV(cast(NMD->getOperand(i))); - if (!DV || !ProcessedVars.insert(DV)) - continue; - DbgScope *Scope = AbstractScopes.lookup(DV.getContext()); - if (Scope) - Scope->addVariable(new DbgVariable(DV)); - } - } + // Construct abstract scopes. + ArrayRef AList = LScopes.getAbstractScopesList(); + for (unsigned i = 0, e = AList.size(); i != e; ++i) { + LexicalScope *AScope = AList[i]; + DISubprogram SP(AScope->getScopeNode()); + if (SP.Verify()) { + // Collect info for variables that were optimized out. + DIArray Variables = SP.getVariables(); + for (unsigned i = 0, e = Variables.getNumElements(); i != e; ++i) { + DIVariable DV(Variables.getElement(i)); + if (!DV || !DV.Verify() || !ProcessedVars.insert(DV)) + continue; + if (LexicalScope *Scope = LScopes.findAbstractScope(DV.getContext())) + addScopeVariable(Scope, new DbgVariable(DV, NULL)); } - if (ProcessedSPNodes.count((*AI)->getScopeNode()) == 0) - constructScopeDIE(*AI); } - - DIE *CurFnDIE = constructScopeDIE(CurrentFnDbgScope); - - if (!DisableFramePointerElim(*MF)) - getCompileUnit(CurrentFnDbgScope->getScopeNode())->addUInt(CurFnDIE, - dwarf::DW_AT_APPLE_omit_frame_ptr, - dwarf::DW_FORM_flag, 1); - - - DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(), - MMI->getFrameMoves())); + if (ProcessedSPNodes.count(AScope->getScopeNode()) == 0) + constructScopeDIE(TheCU, AScope); } + + DIE *CurFnDIE = constructScopeDIE(TheCU, FnScope); + + if (!DisableFramePointerElim(*MF)) + TheCU->addUInt(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr, + dwarf::DW_FORM_flag, 1); + + DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(), + MMI->getFrameMoves())); // Clear debug info - CurrentFnDbgScope = NULL; + for (DenseMap >::iterator + I = ScopeVariables.begin(), E = ScopeVariables.end(); I != E; ++I) + DeleteContainerPointers(I->second); + ScopeVariables.clear(); DeleteContainerPointers(CurrentFnArguments); - DbgVariableToFrameIndexMap.clear(); - VarToAbstractVarMap.clear(); - DbgVariableToDbgInstMap.clear(); - InlinedDbgScopeMap.clear(); - DeleteContainerSeconds(DbgScopeMap); UserVariables.clear(); DbgValues.clear(); - DeleteContainerSeconds(AbstractScopes); - AbstractScopesList.clear(); AbstractVariables.clear(); LabelsBeforeInsn.clear(); LabelsAfterInsn.clear(); PrevLabel = NULL; } -/// recordVariableFrameIndex - Record a variable's index. -void DwarfDebug::recordVariableFrameIndex(const DbgVariable *V, int Index) { - assert (V && "Invalid DbgVariable!"); - DbgVariableToFrameIndexMap[V] = Index; -} - -/// findVariableFrameIndex - Return true if frame index for the variable -/// is found. Update FI to hold value of the index. -bool DwarfDebug::findVariableFrameIndex(const DbgVariable *V, int *FI) { - assert (V && "Invalid DbgVariable!"); - DenseMap::iterator I = - DbgVariableToFrameIndexMap.find(V); - if (I == DbgVariableToFrameIndexMap.end()) - return false; - *FI = I->second; - return true; -} - -/// findDbgScope - Find DbgScope for the debug loc. -DbgScope *DwarfDebug::findDbgScope(DebugLoc DL) { - if (DL.isUnknown()) - return NULL; - - DbgScope *Scope = NULL; - LLVMContext &Ctx = Asm->MF->getFunction()->getContext(); - if (MDNode *IA = DL.getInlinedAt(Ctx)) - Scope = InlinedDbgScopeMap.lookup(DebugLoc::getFromDILocation(IA)); - else - Scope = DbgScopeMap.lookup(DL.getScope(Ctx)); - return Scope; -} - - /// recordSourceLine - Register a source line with debug info. Returns the /// unique label that was emitted and which provides correspondence to /// the source line list. @@ -2112,6 +1371,10 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, DISubprogram SP(S); Fn = SP.getFilename(); Dir = SP.getDirectory(); + } else if (Scope.isLexicalBlockFile()) { + DILexicalBlockFile DBF(S); + Fn = DBF.getFilename(); + Dir = DBF.getDirectory(); } else if (Scope.isLexicalBlock()) { DILexicalBlock DB(S); Fn = DB.getFilename(); @@ -2121,8 +1384,7 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S, Src = GetOrCreateSourceID(Fn, Dir); } - Asm->OutStreamer.EmitDwarfLocDirective(Src, Line, Col, Flags, - 0, 0, Fn); + Asm->OutStreamer.EmitDwarfLocDirective(Src, Line, Col, Flags, 0, 0, Fn); } //===----------------------------------------------------------------------===// @@ -2235,7 +1497,7 @@ void DwarfDebug::EmitSectionLabels() { EmitSectionSym(Asm, TLOF.getDataSection()); } -/// emitDIE - Recusively Emits a debug information entry. +/// emitDIE - Recursively emits a debug information entry. /// void DwarfDebug::emitDIE(DIE *Die) { // Get the abbreviation for this DIE. @@ -2290,10 +1552,9 @@ void DwarfDebug::emitDIE(DIE *Die) { break; } case dwarf::DW_AT_location: { - if (UseDotDebugLocEntry.count(Die) != 0) { - DIELabel *L = cast(Values[i]); + if (DIELabel *L = dyn_cast(Values[i])) Asm->EmitLabelDifference(L->getValue(), DwarfDebugLocSectionSym, 4); - } else + else Values[i]->EmitValue(Asm, Form); break; } @@ -2464,7 +1725,7 @@ void DwarfDebug::emitDebugPubNames() { Asm->OutStreamer.AddComment("End Mark"); Asm->EmitInt32(0); Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_end", - TheCU->getID())); + TheCU->getID())); } } @@ -2499,7 +1760,7 @@ void DwarfDebug::emitDebugPubTypes() { for (StringMap::const_iterator GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) { const char *Name = GI->getKeyData(); - DIE * Entity = GI->second; + DIE *Entity = GI->second; if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset"); Asm->EmitInt32(Entity->getOffset()); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index b2450064e3d0..35653be5c897 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -15,7 +15,8 @@ #define CODEGEN_ASMPRINTER_DWARFDEBUG_H__ #include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineLocation.h" +#include "llvm/CodeGen/LexicalScopes.h" +#include "llvm/MC/MachineLocation.h" #include "llvm/Analysis/DebugInfo.h" #include "DIE.h" #include "llvm/ADT/DenseMap.h" @@ -30,7 +31,6 @@ namespace llvm { class CompileUnit; class DbgConcreteScope; -class DbgScope; class DbgVariable; class MachineFrameInfo; class MachineModuleInfo; @@ -125,9 +125,14 @@ class DbgVariable { DIVariable Var; // Variable Descriptor. DIE *TheDIE; // Variable DIE. unsigned DotDebugLocOffset; // Offset in DotDebugLocEntries. + DbgVariable *AbsVar; // Corresponding Abstract variable, if any. + const MachineInstr *MInsn; // DBG_VALUE instruction of the variable. + int FrameIndex; public: // AbsVar may be NULL. - DbgVariable(DIVariable V) : Var(V), TheDIE(0), DotDebugLocOffset(~0U) {} + DbgVariable(DIVariable V, DbgVariable *AV) + : Var(V), TheDIE(0), DotDebugLocOffset(~0U), AbsVar(AV), MInsn(0), + FrameIndex(~0) {} // Accessors. DIVariable getVariable() const { return Var; } @@ -136,7 +141,27 @@ class DbgVariable { void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; } unsigned getDotDebugLocOffset() const { return DotDebugLocOffset; } StringRef getName() const { return Var.getName(); } - unsigned getTag() const { return Var.getTag(); } + DbgVariable *getAbstractVariable() const { return AbsVar; } + const MachineInstr *getMInsn() const { return MInsn; } + void setMInsn(const MachineInstr *M) { MInsn = M; } + int getFrameIndex() const { return FrameIndex; } + void setFrameIndex(int FI) { FrameIndex = FI; } + // Translate tag to proper Dwarf tag. + unsigned getTag() const { + if (Var.getTag() == dwarf::DW_TAG_arg_variable) + return dwarf::DW_TAG_formal_parameter; + + return dwarf::DW_TAG_variable; + } + /// isArtificial - Return true if DbgVariable is artificial. + bool isArtificial() const { + if (Var.isArtificial()) + return true; + if (Var.getTag() == dwarf::DW_TAG_arg_variable + && getType().isArtificial()) + return true; + return false; + } bool variableHasComplexAddress() const { assert(Var.Verify() && "Invalid complex DbgVariable!"); return Var.hasComplexAddress(); @@ -167,8 +192,13 @@ class DwarfDebug { // CompileUnit *FirstCU; + + /// Maps MDNode with its corresponding CompileUnit. DenseMap CUMap; + /// Maps subprogram MDNode with its corresponding CompileUnit. + DenseMap SPMap; + /// AbbreviationsSet - Used to uniquely define abbreviations. /// FoldingSet AbbreviationsSet; @@ -192,63 +222,27 @@ class DwarfDebug { /// UniqueVector SectionMap; - /// CurrentFnDbgScope - Top level scope for the current function. - /// - DbgScope *CurrentFnDbgScope; - /// CurrentFnArguments - List of Arguments (DbgValues) for current function. SmallVector CurrentFnArguments; - /// DbgScopeMap - Tracks the scopes in the current function. Owns the - /// contained DbgScope*s. - DenseMap DbgScopeMap; - - /// InlinedDbgScopeMap - Tracks inlined function scopes in current function. - DenseMap InlinedDbgScopeMap; - - /// AbstractScopes - Tracks the abstract scopes a module. These scopes are - /// not included DbgScopeMap. AbstractScopes owns its DbgScope*s. - DenseMap AbstractScopes; + LexicalScopes LScopes; /// AbstractSPDies - Collection of abstract subprogram DIEs. DenseMap AbstractSPDies; - /// AbstractScopesList - Tracks abstract scopes constructed while processing - /// a function. This list is cleared during endFunction(). - SmallVectorAbstractScopesList; + /// ScopeVariables - Collection of dbg variables of a scope. + DenseMap > ScopeVariables; - /// AbstractVariables - Collection on abstract variables. Owned by the - /// DbgScopes in AbstractScopes. + /// AbstractVariables - Collection on abstract variables. DenseMap AbstractVariables; - /// DbgVariableToFrameIndexMap - Tracks frame index used to find - /// variable's value. - DenseMap DbgVariableToFrameIndexMap; - - /// DbgVariableToDbgInstMap - Maps DbgVariable to corresponding DBG_VALUE - /// machine instruction. - DenseMap DbgVariableToDbgInstMap; - /// DotDebugLocEntries - Collection of DotDebugLocEntry. SmallVector DotDebugLocEntries; - /// UseDotDebugLocEntry - DW_AT_location attributes for the DIEs in this set - /// idetifies corresponding .debug_loc entry offset. - SmallPtrSet UseDotDebugLocEntry; - - /// VarToAbstractVarMap - Maps DbgVariable with corresponding Abstract - /// DbgVariable, if any. - DenseMap VarToAbstractVarMap; - /// InliendSubprogramDIEs - Collection of subprgram DIEs that are marked /// (at the end of the module) as DW_AT_inline. SmallPtrSet InlinedSubprogramDIEs; - /// ContainingTypeMap - This map is used to keep track of subprogram DIEs that - /// need DW_AT_containing_type attribute. This attribute points to a DIE that - /// corresponds to the MDNode mapped with the subprogram DIE. - DenseMap ContainingTypeMap; - /// InlineInfo - Keep track of inlined functions and their location. This /// information is used to populate debug_inlined section. typedef std::pair InlineInfoLabels; @@ -316,10 +310,7 @@ class DwarfDebug { /// void assignAbbrevNumber(DIEAbbrev &Abbrev); - /// getOrCreateDbgScope - Create DbgScope for the scope. - DbgScope *getOrCreateDbgScope(DebugLoc DL); - - DbgScope *getOrCreateAbstractScope(const MDNode *N); + void addScopeVariable(LexicalScope *LS, DbgVariable *Var); /// findAbstractVariable - Find abstract variable associated with Var. DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc); @@ -328,22 +319,22 @@ class DwarfDebug { /// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes. /// If there are global variables in this scope then create and insert /// DIEs for these variables. - DIE *updateSubprogramScopeDIE(const MDNode *SPNode); + DIE *updateSubprogramScopeDIE(CompileUnit *SPCU, const MDNode *SPNode); /// constructLexicalScope - Construct new DW_TAG_lexical_block /// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels. - DIE *constructLexicalScopeDIE(DbgScope *Scope); + DIE *constructLexicalScopeDIE(CompileUnit *TheCU, LexicalScope *Scope); /// constructInlinedScopeDIE - This scope represents inlined body of /// a function. Construct DIE to represent this concrete inlined copy /// of the function. - DIE *constructInlinedScopeDIE(DbgScope *Scope); + DIE *constructInlinedScopeDIE(CompileUnit *TheCU, LexicalScope *Scope); /// constructVariableDIE - Construct a DIE for the given DbgVariable. - DIE *constructVariableDIE(DbgVariable *DV, DbgScope *S); + DIE *constructVariableDIE(DbgVariable *DV, LexicalScope *S); /// constructScopeDIE - Construct a DIE for this scope. - DIE *constructScopeDIE(DbgScope *Scope); + DIE *constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope); /// EmitSectionLabels - Emit initial Dwarf sections with a label at /// the start of each one. @@ -424,16 +415,10 @@ class DwarfDebug { /// constructCompileUnit - Create new CompileUnit for the given /// metadata node with tag DW_TAG_compile_unit. - void constructCompileUnit(const MDNode *N); - - /// getCompielUnit - Get CompileUnit DIE. - CompileUnit *getCompileUnit(const MDNode *N) const; - - /// constructGlobalVariableDIE - Construct global variable DIE. - void constructGlobalVariableDIE(const MDNode *N); + CompileUnit *constructCompileUnit(const MDNode *N); /// construct SubprogramDIE - Construct subprogram DIE. - void constructSubprogramDIE(const MDNode *N); + void constructSubprogramDIE(CompileUnit *TheCU, const MDNode *N); /// recordSourceLine - Register a source line with debug info. Returns the /// unique label that was emitted and which provides correspondence to @@ -441,30 +426,16 @@ class DwarfDebug { void recordSourceLine(unsigned Line, unsigned Col, const MDNode *Scope, unsigned Flags); - /// recordVariableFrameIndex - Record a variable's index. - void recordVariableFrameIndex(const DbgVariable *V, int Index); - - /// findVariableFrameIndex - Return true if frame index for the variable - /// is found. Update FI to hold value of the index. - bool findVariableFrameIndex(const DbgVariable *V, int *FI); - - /// findDbgScope - Find DbgScope for the debug loc. - DbgScope *findDbgScope(DebugLoc DL); - /// identifyScopeMarkers() - Indentify instructions that are marking /// beginning of or end of a scope. void identifyScopeMarkers(); - /// extractScopeInformation - Scan machine instructions in this function - /// and collect DbgScopes. Return true, if atleast one scope was found. - bool extractScopeInformation(); - /// addCurrentFnArgument - If Var is an current function argument that add /// it in CurrentFnArguments list. bool addCurrentFnArgument(const MachineFunction *MF, - DbgVariable *Var, DbgScope *Scope); + DbgVariable *Var, LexicalScope *Scope); - /// collectVariableInfo - Populate DbgScope entries with variables' info. + /// collectVariableInfo - Populate LexicalScope entries with variables' info. void collectVariableInfo(const MachineFunction *, SmallPtrSet &ProcessedVars); @@ -496,6 +467,14 @@ class DwarfDebug { DwarfDebug(AsmPrinter *A, Module *M); ~DwarfDebug(); + /// collectInfoFromNamedMDNodes - Collect debug info from named mdnodes such + /// as llvm.dbg.enum and llvm.dbg.ty + void collectInfoFromNamedMDNodes(Module *M); + + /// collectLegacyDebugInfo - Collect debug info using DebugInfoFinder. + /// FIXME - Remove this when dragon-egg and llvm-gcc switch to DIBuilder. + bool collectLegacyDebugInfo(Module *M); + /// beginModule - Emit all Dwarf sections that should come prior to the /// content. void beginModule(Module *M); diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp index 1f992faaadb5..18b726b173dc 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -17,7 +17,6 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineLocation.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" @@ -527,29 +526,26 @@ void DwarfException::EmitExceptionTable() { I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) { const CallSiteEntry &S = *I; + // Offset of the landing pad, counted in 16-byte bundles relative to the + // @LPStart address. if (VerboseAsm) { - // Emit comments that decode the call site. Asm->OutStreamer.AddComment(Twine(">> Call Site ") + llvm::utostr(idx) + " <<"); Asm->OutStreamer.AddComment(Twine(" On exception at call site ") + llvm::utostr(idx)); - - if (S.Action == 0) - Asm->OutStreamer.AddComment(" Action: cleanup"); - else - Asm->OutStreamer.AddComment(Twine(" Action: ") + - llvm::utostr((S.Action - 1) / 2 + 1)); - - Asm->OutStreamer.AddBlankLine(); } - - // Offset of the landing pad, counted in 16-byte bundles relative to the - // @LPStart address. Asm->EmitULEB128(idx); // 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 // the action table), and 0 indicates that there are no actions. + if (VerboseAsm) { + if (S.Action == 0) + Asm->OutStreamer.AddComment(" Action: cleanup"); + else + Asm->OutStreamer.AddComment(Twine(" Action: ") + + llvm::utostr((S.Action - 1) / 2 + 1)); + } Asm->EmitULEB128(S.Action); } } else { @@ -595,46 +591,43 @@ void DwarfException::EmitExceptionTable() { if (EndLabel == 0) EndLabel = Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber()); - if (VerboseAsm) { - // Emit comments that decode the call site. - Asm->OutStreamer.AddComment(Twine(">> Call Site ") + - llvm::utostr(++Entry) + " <<"); - Asm->OutStreamer.AddComment(Twine(" Call between ") + - BeginLabel->getName() + " and " + - EndLabel->getName()); - - if (!S.PadLabel) { - Asm->OutStreamer.AddComment(" has no landing pad"); - } else { - Asm->OutStreamer.AddComment(Twine(" jumps to ") + - S.PadLabel->getName()); - - if (S.Action == 0) - Asm->OutStreamer.AddComment(" On action: cleanup"); - else - Asm->OutStreamer.AddComment(Twine(" On action: ") + - llvm::utostr((S.Action - 1) / 2 + 1)); - } - - Asm->OutStreamer.AddBlankLine(); - } // Offset of the call site relative to the previous call site, counted in // number of 16-byte bundles. The first call site is counted relative to // the start of the procedure fragment. + if (VerboseAsm) + Asm->OutStreamer.AddComment(Twine(">> Call Site ") + + llvm::utostr(++Entry) + " <<"); Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4); + if (VerboseAsm) + Asm->OutStreamer.AddComment(Twine(" Call between ") + + BeginLabel->getName() + " and " + + EndLabel->getName()); Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); // Offset of the landing pad, counted in 16-byte bundles relative to the // @LPStart address. - if (!S.PadLabel) + if (!S.PadLabel) { + if (VerboseAsm) + Asm->OutStreamer.AddComment(" has no landing pad"); Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); - else + } else { + if (VerboseAsm) + Asm->OutStreamer.AddComment(Twine(" jumps to ") + + S.PadLabel->getName()); Asm->EmitLabelDifference(S.PadLabel, EHFuncBeginSym, 4); + } // 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 // the action table), and 0 indicates that there are no actions. + if (VerboseAsm) { + if (S.Action == 0) + Asm->OutStreamer.AddComment(" On action: cleanup"); + else + Asm->OutStreamer.AddComment(Twine(" On action: ") + + llvm::utostr((S.Action - 1) / 2 + 1)); + } Asm->EmitULEB128(S.Action); } } @@ -649,13 +642,29 @@ void DwarfException::EmitExceptionTable() { // Emit comments that decode the action table. Asm->OutStreamer.AddComment(Twine(">> Action Record ") + llvm::utostr(++Entry) + " <<"); - if (Action.ValueForTypeID >= 0) + } + + // 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. + if (VerboseAsm) { + if (Action.ValueForTypeID > 0) Asm->OutStreamer.AddComment(Twine(" Catch TypeInfo ") + llvm::itostr(Action.ValueForTypeID)); - else + else if (Action.ValueForTypeID < 0) Asm->OutStreamer.AddComment(Twine(" Filter TypeInfo ") + llvm::itostr(Action.ValueForTypeID)); + else + Asm->OutStreamer.AddComment(" Cleanup"); + } + Asm->EmitSLEB128(Action.ValueForTypeID); + // Action Record + // + // Self-relative signed displacement in bytes of the next action record, + // or 0 if there is no next action record. + if (VerboseAsm) { if (Action.NextAction == 0) { Asm->OutStreamer.AddComment(" No further actions"); } else { @@ -663,20 +672,7 @@ void DwarfException::EmitExceptionTable() { Asm->OutStreamer.AddComment(Twine(" Continue to action ") + llvm::utostr(NextAction)); } - - Asm->OutStreamer.AddBlankLine(); } - - // 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. - Asm->EmitSLEB128(Action.ValueForTypeID); - - // Action Record - // - // Self-relative signed displacement in bytes of the next action record, - // or 0 if there is no next action record. Asm->EmitSLEB128(Action.NextAction); } diff --git a/lib/CodeGen/AsmPrinter/Win64Exception.cpp b/lib/CodeGen/AsmPrinter/Win64Exception.cpp index c2ad5eba3b3c..b83aa5ae3a1b 100644 --- a/lib/CodeGen/AsmPrinter/Win64Exception.cpp +++ b/lib/CodeGen/AsmPrinter/Win64Exception.cpp @@ -17,7 +17,6 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineLocation.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index 99090a8269d4..75288b0934cb 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -1624,26 +1624,29 @@ bool BranchFolder::HoistCommonCodeInSuccs(MachineBasicBlock *MBB) { if (!TIB->isSafeToMove(TII, 0, DontMoveAcrossStore)) break; + // Remove kills from LocalDefsSet, these registers had short live ranges. + for (unsigned i = 0, e = TIB->getNumOperands(); i != e; ++i) { + MachineOperand &MO = TIB->getOperand(i); + if (!MO.isReg() || !MO.isUse() || !MO.isKill()) + continue; + unsigned Reg = MO.getReg(); + if (!Reg || !LocalDefsSet.count(Reg)) + continue; + for (const unsigned *OR = TRI->getOverlaps(Reg); *OR; ++OR) + LocalDefsSet.erase(*OR); + } + // Track local defs so we can update liveins. for (unsigned i = 0, e = TIB->getNumOperands(); i != e; ++i) { MachineOperand &MO = TIB->getOperand(i); - if (!MO.isReg()) + if (!MO.isReg() || !MO.isDef() || MO.isDead()) continue; unsigned Reg = MO.getReg(); if (!Reg) continue; - if (MO.isDef()) { - if (!MO.isDead()) { - LocalDefs.push_back(Reg); - LocalDefsSet.insert(Reg); - for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR) - LocalDefsSet.insert(*SR); - } - } else if (MO.isKill() && LocalDefsSet.count(Reg)) { - LocalDefsSet.erase(Reg); - for (const unsigned *SR = TRI->getSubRegisters(Reg); *SR; ++SR) - LocalDefsSet.erase(*SR); - } + LocalDefs.push_back(Reg); + for (const unsigned *OR = TRI->getOverlaps(Reg); *OR; ++OR) + LocalDefsSet.insert(*OR); } HasDups = true;; diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index 06d2a959ac84..9a5e55160114 100644 --- a/lib/CodeGen/CMakeLists.txt +++ b/lib/CodeGen/CMakeLists.txt @@ -13,7 +13,9 @@ add_llvm_library(LLVMCodeGen EdgeBundles.cpp ELFCodeEmitter.cpp ELFWriter.cpp + ExecutionDepsFix.cpp ExpandISelPseudos.cpp + ExpandPostRAPseudos.cpp GCMetadata.cpp GCMetadataPrinter.cpp GCStrategy.cpp @@ -23,17 +25,18 @@ add_llvm_library(LLVMCodeGen IntrinsicLowering.cpp LLVMTargetMachine.cpp LatencyPriorityQueue.cpp + LexicalScopes.cpp LiveDebugVariables.cpp LiveInterval.cpp LiveIntervalAnalysis.cpp LiveIntervalUnion.cpp LiveStackAnalysis.cpp LiveVariables.cpp + LiveRangeCalc.cpp LiveRangeEdit.cpp LocalStackSlotAllocation.cpp - LowerSubregs.cpp MachineBasicBlock.cpp - MachineBlockFrequency.cpp + MachineBlockFrequencyInfo.cpp MachineBranchProbabilityInfo.cpp MachineCSE.cpp MachineDominators.cpp @@ -97,5 +100,15 @@ add_llvm_library(LLVMCodeGen VirtRegRewriter.cpp ) +add_llvm_library_dependencies(LLVMCodeGen + LLVMAnalysis + LLVMCore + LLVMMC + LLVMScalarOpts + LLVMSupport + LLVMTarget + LLVMTransformUtils + ) + add_subdirectory(SelectionDAG) add_subdirectory(AsmPrinter) diff --git a/lib/CodeGen/CalcSpillWeights.cpp b/lib/CodeGen/CalcSpillWeights.cpp index e6b3bbca2068..ea16a253a348 100644 --- a/lib/CodeGen/CalcSpillWeights.cpp +++ b/lib/CodeGen/CalcSpillWeights.cpp @@ -185,35 +185,3 @@ void VirtRegAuxInfo::CalculateWeightAndHint(LiveInterval &li) { li.weight = normalizeSpillWeight(totalWeight, li.getSize()); } - -void VirtRegAuxInfo::CalculateRegClass(unsigned reg) { - MachineRegisterInfo &MRI = MF.getRegInfo(); - const TargetInstrInfo *TII = MF.getTarget().getInstrInfo(); - const TargetRegisterInfo *TRI = MF.getTarget().getRegisterInfo(); - const TargetRegisterClass *OldRC = MRI.getRegClass(reg); - const TargetRegisterClass *NewRC = TRI->getLargestLegalSuperClass(OldRC); - - // Stop early if there is no room to grow. - if (NewRC == OldRC) - return; - - // Accumulate constraints from all uses. - for (MachineRegisterInfo::reg_nodbg_iterator I = MRI.reg_nodbg_begin(reg), - E = MRI.reg_nodbg_end(); I != E; ++I) { - // TRI doesn't have accurate enough information to model this yet. - if (I.getOperand().getSubReg()) - return; - // Inline asm instuctions don't remember their constraints. - if (I->isInlineAsm()) - return; - const TargetRegisterClass *OpRC = - TII->getRegClass(I->getDesc(), I.getOperandNo(), TRI); - if (OpRC) - NewRC = getCommonSubClass(NewRC, OpRC); - if (!NewRC || NewRC == OldRC) - return; - } - DEBUG(dbgs() << "Inflating " << OldRC->getName() << ':' << PrintReg(reg) - << " to " << NewRC->getName() <<".\n"); - MRI.setRegClass(reg, NewRC); -} diff --git a/lib/CodeGen/CodeGen.cpp b/lib/CodeGen/CodeGen.cpp index 489746cf3c72..424535ba2a1c 100644 --- a/lib/CodeGen/CodeGen.cpp +++ b/lib/CodeGen/CodeGen.cpp @@ -27,6 +27,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) { initializeLiveIntervalsPass(Registry); initializeLiveStacksPass(Registry); initializeLiveVariablesPass(Registry); + initializeMachineBlockFrequencyInfoPass(Registry); initializeMachineCSEPass(Registry); initializeMachineDominatorTreePass(Registry); initializeMachineLICMPass(Registry); diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp index 03604b0a170f..ed9e409d3e5a 100644 --- a/lib/CodeGen/DwarfEHPrepare.cpp +++ b/lib/CodeGen/DwarfEHPrepare.cpp @@ -63,6 +63,8 @@ namespace { typedef SmallPtrSet BBSet; BBSet LandingPads; + bool InsertUnwindResumeCalls(); + bool NormalizeLandingPads(); bool LowerUnwindsAndResumes(); bool MoveExceptionValueCalls(); @@ -658,13 +660,76 @@ Instruction *DwarfEHPrepare::CreateExceptionValueCall(BasicBlock *BB) { return CallInst::Create(ExceptionValueIntrinsic, "eh.value.call", Start); } +/// InsertUnwindResumeCalls - Convert the ResumeInsts that are still present +/// into calls to the appropriate _Unwind_Resume function. +bool DwarfEHPrepare::InsertUnwindResumeCalls() { + bool UsesNewEH = false; + SmallVector Resumes; + for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { + TerminatorInst *TI = I->getTerminator(); + if (ResumeInst *RI = dyn_cast(TI)) + Resumes.push_back(RI); + else if (InvokeInst *II = dyn_cast(TI)) + UsesNewEH = II->getUnwindDest()->isLandingPad(); + } + + if (Resumes.empty()) + return UsesNewEH; + + // Find the rewind function if we didn't already. + if (!RewindFunction) { + LLVMContext &Ctx = Resumes[0]->getContext(); + FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx), + Type::getInt8PtrTy(Ctx), false); + const char *RewindName = TLI->getLibcallName(RTLIB::UNWIND_RESUME); + RewindFunction = F->getParent()->getOrInsertFunction(RewindName, FTy); + } + + // Create the basic block where the _Unwind_Resume call will live. + LLVMContext &Ctx = F->getContext(); + BasicBlock *UnwindBB = BasicBlock::Create(Ctx, "unwind_resume", F); + PHINode *PN = PHINode::Create(Type::getInt8PtrTy(Ctx), Resumes.size(), + "exn.obj", UnwindBB); + + // Extract the exception object from the ResumeInst and add it to the PHI node + // that feeds the _Unwind_Resume call. + BasicBlock *UnwindBBDom = Resumes[0]->getParent(); + for (SmallVectorImpl::iterator + I = Resumes.begin(), E = Resumes.end(); I != E; ++I) { + ResumeInst *RI = *I; + BranchInst::Create(UnwindBB, RI->getParent()); + ExtractValueInst *ExnObj = ExtractValueInst::Create(RI->getOperand(0), + 0, "exn.obj", RI); + PN->addIncoming(ExnObj, RI->getParent()); + UnwindBBDom = DT->findNearestCommonDominator(RI->getParent(), UnwindBBDom); + RI->eraseFromParent(); + } + + // Call the function. + CallInst *CI = CallInst::Create(RewindFunction, PN, "", UnwindBB); + CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME)); + + // We never expect _Unwind_Resume to return. + new UnreachableInst(Ctx, UnwindBB); + + // Now update DominatorTree analysis information. + DT->addNewBlock(UnwindBB, UnwindBBDom); + return true; +} + bool DwarfEHPrepare::runOnFunction(Function &Fn) { bool Changed = false; // Initialize internal state. - DT = &getAnalysis(); + DT = &getAnalysis(); // FIXME: We won't need this with the new EH. F = &Fn; + if (InsertUnwindResumeCalls()) { + // FIXME: The reset of this function can go once the new EH is done. + LandingPads.clear(); + return true; + } + // Ensure that only unwind edges end at landing pads (a landing pad is a // basic block where an invoke unwind edge ends). Changed |= NormalizeLandingPads(); diff --git a/lib/CodeGen/ELFCodeEmitter.cpp b/lib/CodeGen/ELFCodeEmitter.cpp index 3fb087c5ea8b..660424c3c141 100644 --- a/lib/CodeGen/ELFCodeEmitter.cpp +++ b/lib/CodeGen/ELFCodeEmitter.cpp @@ -155,7 +155,7 @@ void ELFCodeEmitter::emitConstantPool(MachineConstantPool *MCP) { CPSections.push_back(CstPool.SectionIdx); if (CPE.isMachineConstantPoolEntry()) - assert("CPE.isMachineConstantPoolEntry not supported yet"); + assert(0 && "CPE.isMachineConstantPoolEntry not supported yet"); // Emit the constant to constant pool section EW.EmitGlobalConstant(CPE.Val.ConstVal, CstPool); diff --git a/lib/CodeGen/ELFCodeEmitter.h b/lib/CodeGen/ELFCodeEmitter.h index 2ec1f6e873d6..8671c674eecf 100644 --- a/lib/CodeGen/ELFCodeEmitter.h +++ b/lib/CodeGen/ELFCodeEmitter.h @@ -58,13 +58,13 @@ namespace llvm { /// emitLabel - Emits a label virtual void emitLabel(MCSymbol *Label) { - assert("emitLabel not implemented"); + assert(0 && "emitLabel not implemented"); } /// getLabelAddress - Return the address of the specified LabelID, /// only usable after the LabelID has been emitted. virtual uintptr_t getLabelAddress(MCSymbol *Label) const { - assert("getLabelAddress not implemented"); + assert(0 && "getLabelAddress not implemented"); return 0; } diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp index d977651c32f7..f2c218565854 100644 --- a/lib/CodeGen/ELFWriter.cpp +++ b/lib/CodeGen/ELFWriter.cpp @@ -45,12 +45,12 @@ #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/Target/Mangler.h" -#include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetELFWriterInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -65,7 +65,8 @@ char ELFWriter::ID = 0; ELFWriter::ELFWriter(raw_ostream &o, TargetMachine &tm) : MachineFunctionPass(ID), O(o), TM(tm), - OutContext(*new MCContext(*TM.getMCAsmInfo(), new TargetAsmInfo(tm))), + OutContext(*new MCContext(*TM.getMCAsmInfo(), *TM.getRegisterInfo(), + &TM.getTargetLowering()->getObjFileLowering())), TLOF(TM.getTargetLowering()->getObjFileLowering()), is64Bit(TM.getTargetData()->getPointerSizeInBits() == 64), isLittleEndian(TM.getTargetData()->isLittleEndian()), @@ -482,7 +483,7 @@ void ELFWriter::EmitGlobalConstant(const Constant *CV, ELFSection &GblS) { EmitGlobalConstantLargeInt(CI, GblS); return; } else if (const ConstantVector *CP = dyn_cast(CV)) { - const VectorType *PTy = CP->getType(); + VectorType *PTy = CP->getType(); for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I) EmitGlobalConstant(CP->getOperand(I), GblS); return; @@ -540,8 +541,7 @@ CstExprResTy ELFWriter::ResolveConstantExpr(const Constant *CV) { case Instruction::GetElementPtr: { const Constant *ptrVal = CE->getOperand(0); SmallVector idxVec(CE->op_begin()+1, CE->op_end()); - int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0], - idxVec.size()); + int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), idxVec); return std::make_pair(ptrVal, Offset); } case Instruction::IntToPtr: { @@ -552,7 +552,7 @@ CstExprResTy ELFWriter::ResolveConstantExpr(const Constant *CV) { } case Instruction::PtrToInt: { Constant *Op = CE->getOperand(0); - const Type *Ty = CE->getType(); + Type *Ty = CE->getType(); // We can emit the pointer value into this slot if the slot is an // integer slot greater or equal to the size of the pointer. diff --git a/lib/Target/X86/SSEDomainFix.cpp b/lib/CodeGen/ExecutionDepsFix.cpp similarity index 84% rename from lib/Target/X86/SSEDomainFix.cpp rename to lib/CodeGen/ExecutionDepsFix.cpp index 13680c592e01..01dccdb71e4b 100644 --- a/lib/Target/X86/SSEDomainFix.cpp +++ b/lib/CodeGen/ExecutionDepsFix.cpp @@ -1,4 +1,4 @@ -//===- SSEDomainFix.cpp - Use proper int/float domain for SSE ---*- C++ -*-===// +//===- ExecutionDepsFix.cpp - Fix execution dependecy issues ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,21 +7,25 @@ // //===----------------------------------------------------------------------===// // -// This file contains the SSEDomainFix pass. +// This file contains the execution dependency fix pass. // -// Some SSE instructions like mov, and, or, xor are available in different +// Some X86 SSE instructions like mov, and, or, xor are available in different // variants for different operand types. These variant instructions are // equivalent, but on Nehalem and newer cpus there is extra latency -// transferring data between integer and floating point domains. +// transferring data between integer and floating point domains. ARM cores +// have similar issues when they are configured with both VFP and NEON +// pipelines. // // This pass changes the variant instructions to minimize domain crossings. // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "sse-domain-fix" -#include "X86InstrInfo.h" +#define DEBUG_TYPE "execution-fix" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Debug.h" @@ -97,25 +101,27 @@ struct DomainValue { }; } -static const unsigned NumRegs = 16; - namespace { -class SSEDomainFixPass : public MachineFunctionPass { +class ExeDepsFix : public MachineFunctionPass { static char ID; SpecificBumpPtrAllocator Allocator; SmallVector Avail; + const TargetRegisterClass *const RC; MachineFunction *MF; - const X86InstrInfo *TII; + const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; MachineBasicBlock *MBB; + std::vector AliasMap; + const unsigned NumRegs; DomainValue **LiveRegs; typedef DenseMap LiveOutMap; LiveOutMap LiveOuts; unsigned Distance; public: - SSEDomainFixPass() : MachineFunctionPass(ID) {} + ExeDepsFix(const TargetRegisterClass *rc) + : MachineFunctionPass(ID), RC(rc), NumRegs(RC->getNumRegs()) {} virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); @@ -150,17 +156,16 @@ class SSEDomainFixPass : public MachineFunctionPass { }; } -char SSEDomainFixPass::ID = 0; +char ExeDepsFix::ID = 0; /// Translate TRI register number to an index into our smaller tables of /// interesting registers. Return -1 for boring registers. -int SSEDomainFixPass::RegIndex(unsigned reg) { - assert(X86::XMM15 == X86::XMM0+NumRegs-1 && "Unexpected sort"); - reg -= X86::XMM0; - return reg < NumRegs ? (int) reg : -1; +int ExeDepsFix::RegIndex(unsigned Reg) { + assert(Reg < AliasMap.size() && "Invalid register"); + return AliasMap[Reg]; } -DomainValue *SSEDomainFixPass::Alloc(int domain) { +DomainValue *ExeDepsFix::Alloc(int domain) { DomainValue *dv = Avail.empty() ? new(Allocator.Allocate()) DomainValue : Avail.pop_back_val(); @@ -170,14 +175,14 @@ DomainValue *SSEDomainFixPass::Alloc(int domain) { return dv; } -void SSEDomainFixPass::Recycle(DomainValue *dv) { +void ExeDepsFix::Recycle(DomainValue *dv) { assert(dv && "Cannot recycle NULL"); dv->clear(); Avail.push_back(dv); } /// Set LiveRegs[rx] = dv, updating reference counts. -void SSEDomainFixPass::SetLiveReg(int rx, DomainValue *dv) { +void ExeDepsFix::SetLiveReg(int rx, DomainValue *dv) { assert(unsigned(rx) < NumRegs && "Invalid index"); if (!LiveRegs) { LiveRegs = new DomainValue*[NumRegs]; @@ -195,7 +200,7 @@ void SSEDomainFixPass::SetLiveReg(int rx, DomainValue *dv) { } // Kill register rx, recycle or collapse any DomainValue. -void SSEDomainFixPass::Kill(int rx) { +void ExeDepsFix::Kill(int rx) { assert(unsigned(rx) < NumRegs && "Invalid index"); if (!LiveRegs || !LiveRegs[rx]) return; @@ -208,7 +213,7 @@ void SSEDomainFixPass::Kill(int rx) { } /// Force register rx into domain. -void SSEDomainFixPass::Force(int rx, unsigned domain) { +void ExeDepsFix::Force(int rx, unsigned domain) { assert(unsigned(rx) < NumRegs && "Invalid index"); DomainValue *dv; if (LiveRegs && (dv = LiveRegs[rx])) { @@ -217,8 +222,8 @@ void SSEDomainFixPass::Force(int rx, unsigned domain) { else if (dv->hasDomain(domain)) Collapse(dv, domain); else { - // This is an incompatible open DomainValue. Collapse it to whatever and force - // the new value into domain. This costs a domain crossing. + // This is an incompatible open DomainValue. Collapse it to whatever and + // force the new value into domain. This costs a domain crossing. Collapse(dv, dv->getFirstDomain()); assert(LiveRegs[rx] && "Not live after collapse?"); LiveRegs[rx]->addDomain(domain); @@ -231,12 +236,12 @@ void SSEDomainFixPass::Force(int rx, unsigned domain) { /// Collapse open DomainValue into given domain. If there are multiple /// registers using dv, they each get a unique collapsed DomainValue. -void SSEDomainFixPass::Collapse(DomainValue *dv, unsigned domain) { +void ExeDepsFix::Collapse(DomainValue *dv, unsigned domain) { assert(dv->hasDomain(domain) && "Cannot collapse"); // Collapse all the instructions. while (!dv->Instrs.empty()) - TII->SetSSEDomain(dv->Instrs.pop_back_val(), domain); + TII->setExecutionDomain(dv->Instrs.pop_back_val(), domain); dv->setSingleDomain(domain); // If there are multiple users, give them new, unique DomainValues. @@ -248,7 +253,7 @@ void SSEDomainFixPass::Collapse(DomainValue *dv, unsigned domain) { /// Merge - All instructions and registers in B are moved to A, and B is /// released. -bool SSEDomainFixPass::Merge(DomainValue *A, DomainValue *B) { +bool ExeDepsFix::Merge(DomainValue *A, DomainValue *B) { assert(!A->isCollapsed() && "Cannot merge into collapsed"); assert(!B->isCollapsed() && "Cannot merge from collapsed"); if (A == B) @@ -266,7 +271,7 @@ bool SSEDomainFixPass::Merge(DomainValue *A, DomainValue *B) { return true; } -void SSEDomainFixPass::enterBasicBlock() { +void ExeDepsFix::enterBasicBlock() { // Try to coalesce live-out registers from predecessors. for (MachineBasicBlock::livein_iterator i = MBB->livein_begin(), e = MBB->livein_end(); i != e; ++i) { @@ -303,7 +308,7 @@ void SSEDomainFixPass::enterBasicBlock() { // A hard instruction only works in one domain. All input registers will be // forced into that domain. -void SSEDomainFixPass::visitHardInstr(MachineInstr *mi, unsigned domain) { +void ExeDepsFix::visitHardInstr(MachineInstr *mi, unsigned domain) { // Collapse all uses. for (unsigned i = mi->getDesc().getNumDefs(), e = mi->getDesc().getNumOperands(); i != e; ++i) { @@ -326,7 +331,7 @@ void SSEDomainFixPass::visitHardInstr(MachineInstr *mi, unsigned domain) { } // A soft instruction can be changed to work in other domains given by mask. -void SSEDomainFixPass::visitSoftInstr(MachineInstr *mi, unsigned mask) { +void ExeDepsFix::visitSoftInstr(MachineInstr *mi, unsigned mask) { // Bitmask of available domains for this instruction after taking collapsed // operands into account. unsigned available = mask; @@ -362,7 +367,7 @@ void SSEDomainFixPass::visitSoftInstr(MachineInstr *mi, unsigned mask) { // If the collapsed operands force a single domain, propagate the collapse. if (isPowerOf2_32(available)) { unsigned domain = CountTrailingZeros_32(available); - TII->SetSSEDomain(mi, domain); + TII->setExecutionDomain(mi, domain); visitHardInstr(mi, domain); return; } @@ -431,8 +436,8 @@ void SSEDomainFixPass::visitSoftInstr(MachineInstr *mi, unsigned mask) { } } -void SSEDomainFixPass::visitGenericInstr(MachineInstr *mi) { - // Process explicit defs, kill any XMM registers redefined. +void ExeDepsFix::visitGenericInstr(MachineInstr *mi) { + // Process explicit defs, kill any relevant registers redefined. for (unsigned i = 0, e = mi->getDesc().getNumDefs(); i != e; ++i) { MachineOperand &mo = mi->getOperand(i); if (!mo.isReg()) continue; @@ -442,25 +447,36 @@ void SSEDomainFixPass::visitGenericInstr(MachineInstr *mi) { } } -bool SSEDomainFixPass::runOnMachineFunction(MachineFunction &mf) { +bool ExeDepsFix::runOnMachineFunction(MachineFunction &mf) { MF = &mf; - TII = static_cast(MF->getTarget().getInstrInfo()); + TII = MF->getTarget().getInstrInfo(); TRI = MF->getTarget().getRegisterInfo(); MBB = 0; LiveRegs = 0; Distance = 0; - assert(NumRegs == X86::VR128RegClass.getNumRegs() && "Bad regclass"); + assert(NumRegs == RC->getNumRegs() && "Bad regclass"); - // If no XMM registers are used in the function, we can skip it completely. + // If no relevant registers are used in the function, we can skip it + // completely. bool anyregs = false; - for (TargetRegisterClass::const_iterator I = X86::VR128RegClass.begin(), - E = X86::VR128RegClass.end(); I != E; ++I) + for (TargetRegisterClass::const_iterator I = RC->begin(), E = RC->end(); + I != E; ++I) if (MF->getRegInfo().isPhysRegUsed(*I)) { anyregs = true; break; } if (!anyregs) return false; + // Initialize the AliasMap on the first use. + if (AliasMap.empty()) { + // Given a PhysReg, AliasMap[PhysReg] is either the relevant index into RC, + // or -1. + AliasMap.resize(TRI->getNumRegs(), -1); + for (unsigned i = 0, e = RC->getNumRegs(); i != e; ++i) + for (const unsigned *AI = TRI->getOverlaps(RC->getRegister(i)); *AI; ++AI) + AliasMap[*AI] = i; + } + MachineBasicBlock *Entry = MF->begin(); SmallPtrSet Visited; for (df_ext_iterator > @@ -473,7 +489,7 @@ bool SSEDomainFixPass::runOnMachineFunction(MachineFunction &mf) { MachineInstr *mi = I; if (mi->isDebugValue()) continue; ++Distance; - std::pair domp = TII->GetSSEDomain(mi); + std::pair domp = TII->getExecutionDomain(mi); if (domp.first) if (domp.second) visitSoftInstr(mi, domp.second); @@ -501,6 +517,7 @@ bool SSEDomainFixPass::runOnMachineFunction(MachineFunction &mf) { return false; } -FunctionPass *llvm::createSSEDomainFixPass() { - return new SSEDomainFixPass(); +FunctionPass * +llvm::createExecutionDependencyFixPass(const TargetRegisterClass *RC) { + return new ExeDepsFix(RC); } diff --git a/lib/CodeGen/LowerSubregs.cpp b/lib/CodeGen/ExpandPostRAPseudos.cpp similarity index 69% rename from lib/CodeGen/LowerSubregs.cpp rename to lib/CodeGen/ExpandPostRAPseudos.cpp index 7871ba9c17e4..e2a14a8dfd97 100644 --- a/lib/CodeGen/LowerSubregs.cpp +++ b/lib/CodeGen/ExpandPostRAPseudos.cpp @@ -1,4 +1,4 @@ -//===-- LowerSubregs.cpp - Subregister Lowering instruction pass ----------===// +//===-- ExpandPostRAPseudos.cpp - Pseudo instruction expansion pass -------===// // // The LLVM Compiler Infrastructure // @@ -7,14 +7,12 @@ // //===----------------------------------------------------------------------===// // -// This file defines a MachineFunction pass which runs after register -// allocation that turns subreg insert/extract instructions into register -// copies, as needed. This ensures correct codegen even if the coalescer -// isn't able to remove all subreg instructions. +// This file defines a pass that expands COPY and SUBREG_TO_REG pseudo +// instructions after register allocation. // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "lowersubregs" +#define DEBUG_TYPE "postrapseudos" #include "llvm/CodeGen/Passes.h" #include "llvm/Function.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -29,52 +27,51 @@ using namespace llvm; namespace { - struct LowerSubregsInstructionPass : public MachineFunctionPass { - private: - const TargetRegisterInfo *TRI; - const TargetInstrInfo *TII; +struct ExpandPostRA : public MachineFunctionPass { +private: + const TargetRegisterInfo *TRI; + const TargetInstrInfo *TII; - public: - static char ID; // Pass identification, replacement for typeid - LowerSubregsInstructionPass() : MachineFunctionPass(ID) {} +public: + static char ID; // Pass identification, replacement for typeid + ExpandPostRA() : MachineFunctionPass(ID) {} - const char *getPassName() const { - return "Subregister lowering instruction pass"; - } + const char *getPassName() const { + return "Post-RA pseudo instruction expansion pass"; + } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesCFG(); - AU.addPreservedID(MachineLoopInfoID); - AU.addPreservedID(MachineDominatorsID); - MachineFunctionPass::getAnalysisUsage(AU); - } + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); + AU.addPreservedID(MachineLoopInfoID); + AU.addPreservedID(MachineDominatorsID); + MachineFunctionPass::getAnalysisUsage(AU); + } - /// runOnMachineFunction - pass entry point - bool runOnMachineFunction(MachineFunction&); + /// runOnMachineFunction - pass entry point + bool runOnMachineFunction(MachineFunction&); - private: - bool LowerSubregToReg(MachineInstr *MI); - bool LowerCopy(MachineInstr *MI); +private: + bool LowerSubregToReg(MachineInstr *MI); + bool LowerCopy(MachineInstr *MI); - void TransferDeadFlag(MachineInstr *MI, unsigned DstReg, - const TargetRegisterInfo *TRI); - void TransferImplicitDefs(MachineInstr *MI); - }; + void TransferDeadFlag(MachineInstr *MI, unsigned DstReg, + const TargetRegisterInfo *TRI); + void TransferImplicitDefs(MachineInstr *MI); +}; +} // end anonymous namespace - char LowerSubregsInstructionPass::ID = 0; -} +char ExpandPostRA::ID = 0; -FunctionPass *llvm::createLowerSubregsPass() { - return new LowerSubregsInstructionPass(); +FunctionPass *llvm::createExpandPostRAPseudosPass() { + return new ExpandPostRA(); } /// TransferDeadFlag - MI is a pseudo-instruction with DstReg dead, /// and the lowered replacement instructions immediately precede it. /// Mark the replacement instructions with the dead flag. void -LowerSubregsInstructionPass::TransferDeadFlag(MachineInstr *MI, - unsigned DstReg, - const TargetRegisterInfo *TRI) { +ExpandPostRA::TransferDeadFlag(MachineInstr *MI, unsigned DstReg, + const TargetRegisterInfo *TRI) { for (MachineBasicBlock::iterator MII = prior(MachineBasicBlock::iterator(MI)); ; --MII) { if (MII->addRegisterDead(DstReg, TRI)) @@ -88,7 +85,7 @@ LowerSubregsInstructionPass::TransferDeadFlag(MachineInstr *MI, /// replacement instructions immediately precede it. Copy any implicit-def /// operands from MI to the replacement instruction. void -LowerSubregsInstructionPass::TransferImplicitDefs(MachineInstr *MI) { +ExpandPostRA::TransferImplicitDefs(MachineInstr *MI) { MachineBasicBlock::iterator CopyMI = MI; --CopyMI; @@ -100,7 +97,7 @@ LowerSubregsInstructionPass::TransferImplicitDefs(MachineInstr *MI) { } } -bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) { +bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) { MachineBasicBlock *MBB = MI->getParent(); assert((MI->getOperand(0).isReg() && MI->getOperand(0).isDef()) && MI->getOperand(1).isImm() && @@ -152,7 +149,7 @@ bool LowerSubregsInstructionPass::LowerSubregToReg(MachineInstr *MI) { return true; } -bool LowerSubregsInstructionPass::LowerCopy(MachineInstr *MI) { +bool ExpandPostRA::LowerCopy(MachineInstr *MI) { MachineOperand &DstMO = MI->getOperand(0); MachineOperand &SrcMO = MI->getOperand(1); @@ -191,9 +188,9 @@ bool LowerSubregsInstructionPass::LowerCopy(MachineInstr *MI) { /// runOnMachineFunction - Reduce subregister inserts and extracts to register /// copies. /// -bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) { +bool ExpandPostRA::runOnMachineFunction(MachineFunction &MF) { DEBUG(dbgs() << "Machine Function\n" - << "********** LOWERING SUBREG INSTRS **********\n" + << "********** EXPANDING POST-RA PSEUDO INSTRS **********\n" << "********** Function: " << MF.getFunction()->getName() << '\n'); TRI = MF.getTarget().getRegisterInfo(); @@ -205,17 +202,34 @@ bool LowerSubregsInstructionPass::runOnMachineFunction(MachineFunction &MF) { mbbi != mbbe; ++mbbi) { for (MachineBasicBlock::iterator mi = mbbi->begin(), me = mbbi->end(); mi != me;) { - MachineBasicBlock::iterator nmi = llvm::next(mi); MachineInstr *MI = mi; - assert(!MI->isInsertSubreg() && "INSERT_SUBREG should no longer appear"); - assert(MI->getOpcode() != TargetOpcode::EXTRACT_SUBREG && - "EXTRACT_SUBREG should no longer appear"); - if (MI->isSubregToReg()) { - MadeChange |= LowerSubregToReg(MI); - } else if (MI->isCopy()) { - MadeChange |= LowerCopy(MI); + // Advance iterator here because MI may be erased. + ++mi; + + // Only expand pseudos. + if (!MI->getDesc().isPseudo()) + continue; + + // Give targets a chance to expand even standard pseudos. + if (TII->expandPostRAPseudo(MI)) { + MadeChange = true; + continue; + } + + // Expand standard pseudos. + switch (MI->getOpcode()) { + case TargetOpcode::SUBREG_TO_REG: + MadeChange |= LowerSubregToReg(MI); + break; + case TargetOpcode::COPY: + MadeChange |= LowerCopy(MI); + break; + case TargetOpcode::DBG_VALUE: + continue; + case TargetOpcode::INSERT_SUBREG: + case TargetOpcode::EXTRACT_SUBREG: + llvm_unreachable("Sub-register pseudos should have been eliminated."); } - mi = nmi; } } diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp index 6cb22778caf9..ce7ed293daac 100644 --- a/lib/CodeGen/IfConversion.cpp +++ b/lib/CodeGen/IfConversion.cpp @@ -16,14 +16,13 @@ #include "llvm/Function.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineBranchProbabilityInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/MC/MCInstrItineraries.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Support/BranchProbability.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -154,7 +153,8 @@ namespace { const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; const InstrItineraryData *InstrItins; - const MachineLoopInfo *MLI; + const MachineBranchProbabilityInfo *MBPI; + bool MadeChange; int FnNum; public: @@ -162,9 +162,9 @@ namespace { IfConverter() : MachineFunctionPass(ID), FnNum(-1) { initializeIfConverterPass(*PassRegistry::getPassRegistry()); } - + virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); + AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -252,7 +252,7 @@ namespace { } INITIALIZE_PASS_BEGIN(IfConverter, "if-converter", "If Converter", false, false) -INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) +INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) INITIALIZE_PASS_END(IfConverter, "if-converter", "If Converter", false, false) FunctionPass *llvm::createIfConverterPass() { return new IfConverter(); } @@ -261,7 +261,7 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) { TLI = MF.getTarget().getTargetLowering(); TII = MF.getTarget().getInstrInfo(); TRI = MF.getTarget().getRegisterInfo(); - MLI = &getAnalysis(); + MBPI = &getAnalysis(); InstrItins = MF.getTarget().getInstrItineraryData(); if (!TII) return false; @@ -790,28 +790,9 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB, bool TNeedSub = TrueBBI.Predicate.size() > 0; bool FNeedSub = FalseBBI.Predicate.size() > 0; bool Enqueued = false; - - // Try to predict the branch, using loop info to guide us. - // General heuristics are: - // - backedge -> 90% taken - // - early exit -> 20% taken - // - branch predictor confidence -> 90% - BranchProbability Prediction(5, 10); - MachineLoop *Loop = MLI->getLoopFor(BB); - if (Loop) { - if (TrueBBI.BB == Loop->getHeader()) - Prediction = BranchProbability(9, 10); - else if (FalseBBI.BB == Loop->getHeader()) - Prediction = BranchProbability(1, 10); - MachineLoop *TrueLoop = MLI->getLoopFor(TrueBBI.BB); - MachineLoop *FalseLoop = MLI->getLoopFor(FalseBBI.BB); - if (!TrueLoop || TrueLoop->getParentLoop() == Loop) - Prediction = BranchProbability(2, 10); - else if (!FalseLoop || FalseLoop->getParentLoop() == Loop) - Prediction = BranchProbability(8, 10); - } - + BranchProbability Prediction = MBPI->getEdgeProbability(BB, TrueBBI.BB); + if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2) && MeetIfcvtSizeLimit(*TrueBBI.BB, (TrueBBI.NonPredSize - (Dups + Dups2) + TrueBBI.ExtraCost), TrueBBI.ExtraCost2, diff --git a/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp index 5547f735ba5e..726af4696578 100644 --- a/lib/CodeGen/InlineSpiller.cpp +++ b/lib/CodeGen/InlineSpiller.cpp @@ -17,6 +17,7 @@ #include "LiveRangeEdit.h" #include "VirtRegMap.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/LiveStackAnalysis.h" @@ -27,22 +28,26 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; STATISTIC(NumSpilledRanges, "Number of spilled live ranges"); -STATISTIC(NumSnippets, "Number of snippets included in spills"); +STATISTIC(NumSnippets, "Number of spilled snippets"); STATISTIC(NumSpills, "Number of spills inserted"); +STATISTIC(NumSpillsRemoved, "Number of spills removed"); STATISTIC(NumReloads, "Number of reloads inserted"); +STATISTIC(NumReloadsRemoved, "Number of reloads removed"); STATISTIC(NumFolded, "Number of folded stack accesses"); STATISTIC(NumFoldedLoads, "Number of folded loads"); STATISTIC(NumRemats, "Number of rematerialized defs for spilling"); -STATISTIC(NumOmitReloadSpill, "Number of omitted spills after reloads"); -STATISTIC(NumHoistLocal, "Number of locally hoisted spills"); -STATISTIC(NumHoistGlobal, "Number of globally hoisted spills"); -STATISTIC(NumRedundantSpills, "Number of redundant spills identified"); +STATISTIC(NumOmitReloadSpill, "Number of omitted spills of reloads"); +STATISTIC(NumHoists, "Number of hoisted spills"); + +static cl::opt DisableHoisting("disable-spill-hoist", cl::Hidden, + cl::desc("Disable inline spill hoisting")); namespace { class InlineSpiller : public Spiller { @@ -75,26 +80,49 @@ class InlineSpiller : public Spiller { // Values that failed to remat at some point. SmallPtrSet UsedValues; +public: // Information about a value that was defined by a copy from a sibling // register. struct SibValueInfo { // True when all reaching defs were reloads: No spill is necessary. bool AllDefsAreReloads; + // True when value is defined by an original PHI not from splitting. + bool DefByOrigPHI; + + // True when the COPY defining this value killed its source. + bool KillsSource; + // The preferred register to spill. unsigned SpillReg; // The value of SpillReg that should be spilled. VNInfo *SpillVNI; + // The block where SpillVNI should be spilled. Currently, this must be the + // block containing SpillVNI->def. + MachineBasicBlock *SpillMBB; + // A defining instruction that is not a sibling copy or a reload, or NULL. // This can be used as a template for rematerialization. MachineInstr *DefMI; + // List of values that depend on this one. These values are actually the + // same, but live range splitting has placed them in different registers, + // or SSA update needed to insert PHI-defs to preserve SSA form. This is + // copies of the current value and phi-kills. Usually only phi-kills cause + // more than one dependent value. + TinyPtrVector Deps; + SibValueInfo(unsigned Reg, VNInfo *VNI) - : AllDefsAreReloads(false), SpillReg(Reg), SpillVNI(VNI), DefMI(0) {} + : AllDefsAreReloads(true), DefByOrigPHI(false), KillsSource(false), + SpillReg(Reg), SpillVNI(VNI), SpillMBB(0), DefMI(0) {} + + // Returns true when a def has been found. + bool hasDef() const { return DefByOrigPHI || DefMI; } }; +private: // Values in RegsToSpill defined by sibling copies. typedef DenseMap SibValueMap; SibValueMap SibValues; @@ -134,6 +162,7 @@ class InlineSpiller : public Spiller { bool isSibling(unsigned Reg); MachineInstr *traceSiblingValue(unsigned, VNInfo*, VNInfo*); + void propagateSiblingValue(SibValueMap::iterator, VNInfo *VNI = 0); void analyzeSiblingValues(); bool hoistSpill(LiveInterval &SpillLI, MachineInstr *CopyMI); @@ -282,6 +311,156 @@ bool InlineSpiller::isSibling(unsigned Reg) { VRM.getOriginal(Reg) == Original; } +#ifndef NDEBUG +static raw_ostream &operator<<(raw_ostream &OS, + const InlineSpiller::SibValueInfo &SVI) { + OS << "spill " << PrintReg(SVI.SpillReg) << ':' + << SVI.SpillVNI->id << '@' << SVI.SpillVNI->def; + if (SVI.SpillMBB) + OS << " in BB#" << SVI.SpillMBB->getNumber(); + if (SVI.AllDefsAreReloads) + OS << " all-reloads"; + if (SVI.DefByOrigPHI) + OS << " orig-phi"; + if (SVI.KillsSource) + OS << " kill"; + OS << " deps["; + for (unsigned i = 0, e = SVI.Deps.size(); i != e; ++i) + OS << ' ' << SVI.Deps[i]->id << '@' << SVI.Deps[i]->def; + OS << " ]"; + if (SVI.DefMI) + OS << " def: " << *SVI.DefMI; + else + OS << '\n'; + return OS; +} +#endif + +/// propagateSiblingValue - Propagate the value in SVI to dependents if it is +/// known. Otherwise remember the dependency for later. +/// +/// @param SVI SibValues entry to propagate. +/// @param VNI Dependent value, or NULL to propagate to all saved dependents. +void InlineSpiller::propagateSiblingValue(SibValueMap::iterator SVI, + VNInfo *VNI) { + // When VNI is non-NULL, add it to SVI's deps, and only propagate to that. + TinyPtrVector FirstDeps; + if (VNI) { + FirstDeps.push_back(VNI); + SVI->second.Deps.push_back(VNI); + } + + // Has the value been completely determined yet? If not, defer propagation. + if (!SVI->second.hasDef()) + return; + + // Work list of values to propagate. It would be nice to use a SetVector + // here, but then we would be forced to use a SmallSet. + SmallVector WorkList(1, SVI); + SmallPtrSet WorkSet; + + do { + SVI = WorkList.pop_back_val(); + WorkSet.erase(SVI->first); + TinyPtrVector *Deps = VNI ? &FirstDeps : &SVI->second.Deps; + VNI = 0; + + SibValueInfo &SV = SVI->second; + if (!SV.SpillMBB) + SV.SpillMBB = LIS.getMBBFromIndex(SV.SpillVNI->def); + + DEBUG(dbgs() << " prop to " << Deps->size() << ": " + << SVI->first->id << '@' << SVI->first->def << ":\t" << SV); + + assert(SV.hasDef() && "Propagating undefined value"); + + // Should this value be propagated as a preferred spill candidate? We don't + // propagate values of registers that are about to spill. + bool PropSpill = !DisableHoisting && !isRegToSpill(SV.SpillReg); + unsigned SpillDepth = ~0u; + + for (TinyPtrVector::iterator DepI = Deps->begin(), + DepE = Deps->end(); DepI != DepE; ++DepI) { + SibValueMap::iterator DepSVI = SibValues.find(*DepI); + assert(DepSVI != SibValues.end() && "Dependent value not in SibValues"); + SibValueInfo &DepSV = DepSVI->second; + if (!DepSV.SpillMBB) + DepSV.SpillMBB = LIS.getMBBFromIndex(DepSV.SpillVNI->def); + + bool Changed = false; + + // Propagate defining instruction. + if (!DepSV.hasDef()) { + Changed = true; + DepSV.DefMI = SV.DefMI; + DepSV.DefByOrigPHI = SV.DefByOrigPHI; + } + + // Propagate AllDefsAreReloads. For PHI values, this computes an AND of + // all predecessors. + if (!SV.AllDefsAreReloads && DepSV.AllDefsAreReloads) { + Changed = true; + DepSV.AllDefsAreReloads = false; + } + + // Propagate best spill value. + if (PropSpill && SV.SpillVNI != DepSV.SpillVNI) { + if (SV.SpillMBB == DepSV.SpillMBB) { + // DepSV is in the same block. Hoist when dominated. + if (DepSV.KillsSource && SV.SpillVNI->def < DepSV.SpillVNI->def) { + // This is an alternative def earlier in the same MBB. + // Hoist the spill as far as possible in SpillMBB. This can ease + // register pressure: + // + // x = def + // y = use x + // s = copy x + // + // Hoisting the spill of s to immediately after the def removes the + // interference between x and y: + // + // x = def + // spill x + // y = use x + // + // This hoist only helps when the DepSV copy kills its source. + Changed = true; + DepSV.SpillReg = SV.SpillReg; + DepSV.SpillVNI = SV.SpillVNI; + DepSV.SpillMBB = SV.SpillMBB; + } + } else { + // DepSV is in a different block. + if (SpillDepth == ~0u) + SpillDepth = Loops.getLoopDepth(SV.SpillMBB); + + // Also hoist spills to blocks with smaller loop depth, but make sure + // that the new value dominates. Non-phi dependents are always + // dominated, phis need checking. + if ((Loops.getLoopDepth(DepSV.SpillMBB) > SpillDepth) && + (!DepSVI->first->isPHIDef() || + MDT.dominates(SV.SpillMBB, DepSV.SpillMBB))) { + Changed = true; + DepSV.SpillReg = SV.SpillReg; + DepSV.SpillVNI = SV.SpillVNI; + DepSV.SpillMBB = SV.SpillMBB; + } + } + } + + if (!Changed) + continue; + + // Something changed in DepSVI. Propagate to dependents. + if (WorkSet.insert(DepSVI->first)) + WorkList.push_back(DepSVI); + + DEBUG(dbgs() << " update " << DepSVI->first->id << '@' + << DepSVI->first->def << " to:\t" << DepSV); + } + } while (!WorkList.empty()); +} + /// traceSiblingValue - Trace a value that is about to be spilled back to the /// real defining instructions by looking through sibling copies. Always stay /// within the range of OrigVNI so the registers are known to carry the same @@ -294,84 +473,101 @@ bool InlineSpiller::isSibling(unsigned Reg) { /// MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI, VNInfo *OrigVNI) { + // Check if a cached value already exists. + SibValueMap::iterator SVI; + bool Inserted; + tie(SVI, Inserted) = + SibValues.insert(std::make_pair(UseVNI, SibValueInfo(UseReg, UseVNI))); + if (!Inserted) { + DEBUG(dbgs() << "Cached value " << PrintReg(UseReg) << ':' + << UseVNI->id << '@' << UseVNI->def << ' ' << SVI->second); + return SVI->second.DefMI; + } + DEBUG(dbgs() << "Tracing value " << PrintReg(UseReg) << ':' << UseVNI->id << '@' << UseVNI->def << '\n'); - SmallPtrSet Visited; + + // List of (Reg, VNI) that have been inserted into SibValues, but need to be + // processed. SmallVector, 8> WorkList; WorkList.push_back(std::make_pair(UseReg, UseVNI)); - // Best spill candidate seen so far. This must dominate UseVNI. - SibValueInfo SVI(UseReg, UseVNI); - MachineBasicBlock *UseMBB = LIS.getMBBFromIndex(UseVNI->def); - MachineBasicBlock *SpillMBB = UseMBB; - unsigned SpillDepth = Loops.getLoopDepth(SpillMBB); - bool SeenOrigPHI = false; // Original PHI met. - do { unsigned Reg; VNInfo *VNI; tie(Reg, VNI) = WorkList.pop_back_val(); - if (!Visited.insert(VNI)) - continue; + DEBUG(dbgs() << " " << PrintReg(Reg) << ':' << VNI->id << '@' << VNI->def + << ":\t"); - // Is this value a better spill candidate? - if (!isRegToSpill(Reg)) { - MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def); - if (MBB == SpillMBB) { - // This is an alternative def earlier in the same MBB. - // Hoist the spill as far as possible in SpillMBB. This can ease - // register pressure: - // - // x = def - // y = use x - // s = copy x - // - // Hoisting the spill of s to immediately after the def removes the - // interference between x and y: - // - // x = def - // spill x - // y = use x - // - if (VNI->def < SVI.SpillVNI->def) { - DEBUG(dbgs() << " hoist in BB#" << MBB->getNumber() << ": " - << PrintReg(Reg) << ':' << VNI->id << '@' << VNI->def - << '\n'); - SVI.SpillReg = Reg; - SVI.SpillVNI = VNI; - } - } else if (MBB != UseMBB && MDT.dominates(MBB, UseMBB)) { - // This is a valid spill location dominating UseVNI. - // Prefer to spill at a smaller loop depth. - unsigned Depth = Loops.getLoopDepth(MBB); - if (Depth < SpillDepth) { - DEBUG(dbgs() << " spill depth " << Depth << ": " << PrintReg(Reg) - << ':' << VNI->id << '@' << VNI->def << '\n'); - SVI.SpillReg = Reg; - SVI.SpillVNI = VNI; - SpillMBB = MBB; - SpillDepth = Depth; - } - } - } + // First check if this value has already been computed. + SVI = SibValues.find(VNI); + assert(SVI != SibValues.end() && "Missing SibValues entry"); // Trace through PHI-defs created by live range splitting. if (VNI->isPHIDef()) { + // Stop at original PHIs. We don't know the value at the predecessors. if (VNI->def == OrigVNI->def) { - DEBUG(dbgs() << " orig phi value " << PrintReg(Reg) << ':' - << VNI->id << '@' << VNI->def << '\n'); - SeenOrigPHI = true; + DEBUG(dbgs() << "orig phi value\n"); + SVI->second.DefByOrigPHI = true; + SVI->second.AllDefsAreReloads = false; + propagateSiblingValue(SVI); continue; } - // Get values live-out of predecessors. + + // This is a PHI inserted by live range splitting. We could trace the + // live-out value from predecessor blocks, but that search can be very + // expensive if there are many predecessors and many more PHIs as + // generated by tail-dup when it sees an indirectbr. Instead, look at + // all the non-PHI defs that have the same value as OrigVNI. They must + // jointly dominate VNI->def. This is not optimal since VNI may actually + // be jointly dominated by a smaller subset of defs, so there is a change + // we will miss a AllDefsAreReloads optimization. + + // Separate all values dominated by OrigVNI into PHIs and non-PHIs. + SmallVector PHIs, NonPHIs; LiveInterval &LI = LIS.getInterval(Reg); - MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def); - for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), - PE = MBB->pred_end(); PI != PE; ++PI) { - VNInfo *PVNI = LI.getVNInfoAt(LIS.getMBBEndIdx(*PI).getPrevSlot()); - if (PVNI) - WorkList.push_back(std::make_pair(Reg, PVNI)); + LiveInterval &OrigLI = LIS.getInterval(Original); + + for (LiveInterval::vni_iterator VI = LI.vni_begin(), VE = LI.vni_end(); + VI != VE; ++VI) { + VNInfo *VNI2 = *VI; + if (VNI2->isUnused()) + continue; + if (!OrigLI.containsOneValue() && + OrigLI.getVNInfoAt(VNI2->def) != OrigVNI) + continue; + if (VNI2->isPHIDef() && VNI2->def != OrigVNI->def) + PHIs.push_back(VNI2); + else + NonPHIs.push_back(VNI2); } + DEBUG(dbgs() << "split phi value, checking " << PHIs.size() + << " phi-defs, and " << NonPHIs.size() + << " non-phi/orig defs\n"); + + // Create entries for all the PHIs. Don't add them to the worklist, we + // are processing all of them in one go here. + for (unsigned i = 0, e = PHIs.size(); i != e; ++i) + SibValues.insert(std::make_pair(PHIs[i], SibValueInfo(Reg, PHIs[i]))); + + // Add every PHI as a dependent of all the non-PHIs. + for (unsigned i = 0, e = NonPHIs.size(); i != e; ++i) { + VNInfo *NonPHI = NonPHIs[i]; + // Known value? Try an insertion. + tie(SVI, Inserted) = + SibValues.insert(std::make_pair(NonPHI, SibValueInfo(Reg, NonPHI))); + // Add all the PHIs as dependents of NonPHI. + for (unsigned pi = 0, pe = PHIs.size(); pi != pe; ++pi) + SVI->second.Deps.push_back(PHIs[pi]); + // This is the first time we see NonPHI, add it to the worklist. + if (Inserted) + WorkList.push_back(std::make_pair(Reg, NonPHI)); + else + // Propagate to all inserted PHIs, not just VNI. + propagateSiblingValue(SVI); + } + + // Next work list item. continue; } @@ -382,48 +578,49 @@ MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI, if (unsigned SrcReg = isFullCopyOf(MI, Reg)) { if (isSibling(SrcReg)) { LiveInterval &SrcLI = LIS.getInterval(SrcReg); - VNInfo *SrcVNI = SrcLI.getVNInfoAt(VNI->def.getUseIndex()); - assert(SrcVNI && "Copy from non-existing value"); - DEBUG(dbgs() << " copy of " << PrintReg(SrcReg) << ':' - << SrcVNI->id << '@' << SrcVNI->def << '\n'); - WorkList.push_back(std::make_pair(SrcReg, SrcVNI)); + LiveRange *SrcLR = SrcLI.getLiveRangeContaining(VNI->def.getUseIndex()); + assert(SrcLR && "Copy from non-existing value"); + // Check if this COPY kills its source. + SVI->second.KillsSource = (SrcLR->end == VNI->def); + VNInfo *SrcVNI = SrcLR->valno; + DEBUG(dbgs() << "copy of " << PrintReg(SrcReg) << ':' + << SrcVNI->id << '@' << SrcVNI->def + << " kill=" << unsigned(SVI->second.KillsSource) << '\n'); + // Known sibling source value? Try an insertion. + tie(SVI, Inserted) = SibValues.insert(std::make_pair(SrcVNI, + SibValueInfo(SrcReg, SrcVNI))); + // This is the first time we see Src, add it to the worklist. + if (Inserted) + WorkList.push_back(std::make_pair(SrcReg, SrcVNI)); + propagateSiblingValue(SVI, VNI); + // Next work list item. continue; } } // Track reachable reloads. + SVI->second.DefMI = MI; + SVI->second.SpillMBB = MI->getParent(); int FI; if (Reg == TII.isLoadFromStackSlot(MI, FI) && FI == StackSlot) { - DEBUG(dbgs() << " reload " << PrintReg(Reg) << ':' - << VNI->id << "@" << VNI->def << '\n'); - SVI.AllDefsAreReloads = true; + DEBUG(dbgs() << "reload\n"); + propagateSiblingValue(SVI); + // Next work list item. continue; } - // We have an 'original' def. Don't record trivial cases. - if (VNI == UseVNI) { - DEBUG(dbgs() << "Not a sibling copy.\n"); - return MI; - } - // Potential remat candidate. - DEBUG(dbgs() << " def " << PrintReg(Reg) << ':' - << VNI->id << '@' << VNI->def << '\t' << *MI); - SVI.DefMI = MI; + DEBUG(dbgs() << "def " << *MI); + SVI->second.AllDefsAreReloads = false; + propagateSiblingValue(SVI); } while (!WorkList.empty()); - if (SeenOrigPHI || SVI.DefMI) - SVI.AllDefsAreReloads = false; - - DEBUG({ - if (SVI.AllDefsAreReloads) - dbgs() << "All defs are reloads.\n"; - else - dbgs() << "Prefer to spill " << PrintReg(SVI.SpillReg) << ':' - << SVI.SpillVNI->id << '@' << SVI.SpillVNI->def << '\n'; - }); - SibValues.insert(std::make_pair(UseVNI, SVI)); - return SVI.DefMI; + // Look up the value we were looking for. We already did this lokup at the + // top of the function, but SibValues may have been invalidated. + SVI = SibValues.find(UseVNI); + assert(SVI != SibValues.end() && "Didn't compute requested info"); + DEBUG(dbgs() << " traced to:\t" << SVI->second); + return SVI->second.DefMI; } /// analyzeSiblingValues - Trace values defined by sibling copies back to @@ -506,6 +703,7 @@ bool InlineSpiller::hoistSpill(LiveInterval &SpillLI, MachineInstr *CopyMI) { // Already spilled everywhere. if (SVI.AllDefsAreReloads) { + DEBUG(dbgs() << "\tno spill needed: " << SVI); ++NumOmitReloadSpill; return true; } @@ -531,10 +729,8 @@ bool InlineSpiller::hoistSpill(LiveInterval &SpillLI, MachineInstr *CopyMI) { VRM.addSpillSlotUse(StackSlot, MII); DEBUG(dbgs() << "\thoisted: " << SVI.SpillVNI->def << '\t' << *MII); - if (MBB == CopyMI->getParent()) - ++NumHoistLocal; - else - ++NumHoistGlobal; + ++NumSpills; + ++NumHoists; return true; } @@ -589,7 +785,8 @@ void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, VNInfo *VNI) { // eliminateDeadDefs won't normally remove stores, so switch opcode. MI->setDesc(TII.get(TargetOpcode::KILL)); DeadDefs.push_back(MI); - ++NumRedundantSpills; + ++NumSpillsRemoved; + --NumSpills; } } } while (!WorkList.empty()); @@ -637,7 +834,7 @@ void InlineSpiller::markValueUsed(LiveInterval *LI, VNInfo *VNI) { bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg, MachineBasicBlock::iterator MI) { SlotIndex UseIdx = LIS.getInstructionIndex(MI).getUseIndex(); - VNInfo *ParentVNI = VirtReg.getVNInfoAt(UseIdx); + VNInfo *ParentVNI = VirtReg.getVNInfoAt(UseIdx.getBaseIndex()); if (!ParentVNI) { DEBUG(dbgs() << "\tadding flags: "); @@ -787,10 +984,10 @@ void InlineSpiller::reMaterializeAll() { /// If MI is a load or store of StackSlot, it can be removed. bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, unsigned Reg) { int FI = 0; - unsigned InstrReg; - if (!(InstrReg = TII.isLoadFromStackSlot(MI, FI)) && - !(InstrReg = TII.isStoreToStackSlot(MI, FI))) - return false; + unsigned InstrReg = TII.isLoadFromStackSlot(MI, FI); + bool IsLoad = InstrReg; + if (!IsLoad) + InstrReg = TII.isStoreToStackSlot(MI, FI); // We have a stack access. Is it the right register and slot? if (InstrReg != Reg || FI != StackSlot) @@ -799,6 +996,15 @@ bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, unsigned Reg) { DEBUG(dbgs() << "Coalescing stack access: " << *MI); LIS.RemoveMachineInstrFromMaps(MI); MI->eraseFromParent(); + + if (IsLoad) { + ++NumReloadsRemoved; + --NumReloads; + } else { + ++NumSpillsRemoved; + --NumSpills; + } + return true; } @@ -810,6 +1016,7 @@ bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, unsigned Reg) { bool InlineSpiller::foldMemoryOperand(MachineBasicBlock::iterator MI, const SmallVectorImpl &Ops, MachineInstr *LoadMI) { + bool WasCopy = MI->isCopy(); // TargetInstrInfo::foldMemoryOperand only expects explicit, non-tied // operands. SmallVector FoldOps; @@ -839,7 +1046,12 @@ bool InlineSpiller::foldMemoryOperand(MachineBasicBlock::iterator MI, VRM.addSpillSlotUse(StackSlot, FoldMI); MI->eraseFromParent(); DEBUG(dbgs() << "\tfolded: " << *FoldMI); - ++NumFolded; + if (!WasCopy) + ++NumFolded; + else if (Ops.front() == 0) + ++NumSpills; + else + ++NumReloads; return true; } @@ -975,8 +1187,16 @@ void InlineSpiller::spillAroundUses(unsigned Reg) { DEBUG(dbgs() << "\trewrite: " << Idx << '\t' << *MI); // FIXME: Use a second vreg if instruction has no tied ops. - if (Writes && hasLiveDef) + if (Writes) { + if (hasLiveDef) insertSpill(NewLI, OldLI, Idx, MI); + else { + // This instruction defines a dead value. We don't need to spill it, + // but do create a live range for the dead value. + VNInfo *VNI = NewLI.getNextValue(Idx, 0, LIS.getVNInfoAllocator()); + NewLI.addRange(LiveRange(Idx, Idx.getNextSlot(), VNI)); + } + } DEBUG(dbgs() << "\tinterval: " << NewLI << '\n'); } diff --git a/lib/CodeGen/InterferenceCache.cpp b/lib/CodeGen/InterferenceCache.cpp index a09bb39f8336..29b47bd67ece 100644 --- a/lib/CodeGen/InterferenceCache.cpp +++ b/lib/CodeGen/InterferenceCache.cpp @@ -18,10 +18,13 @@ using namespace llvm; +// Static member used for null interference cursors. +InterferenceCache::BlockInterference InterferenceCache::Cursor::NoInterference; + void InterferenceCache::init(MachineFunction *mf, LiveIntervalUnion *liuarray, SlotIndexes *indexes, - const TargetRegisterInfo *tri) { + const TargetRegisterInfo *tri) { MF = mf; LIUArray = liuarray; TRI = tri; diff --git a/lib/CodeGen/InterferenceCache.h b/lib/CodeGen/InterferenceCache.h index 7f0a27a41baa..4df0a9e5c393 100644 --- a/lib/CodeGen/InterferenceCache.h +++ b/lib/CodeGen/InterferenceCache.h @@ -138,6 +138,7 @@ class InterferenceCache { class Cursor { Entry *CacheEntry; BlockInterference *Current; + static BlockInterference NoInterference; void setEntry(Entry *E) { Current = 0; @@ -175,7 +176,7 @@ class InterferenceCache { /// moveTo - Move cursor to basic block MBBNum. void moveToBlock(unsigned MBBNum) { - Current = CacheEntry->get(MBBNum); + Current = CacheEntry ? CacheEntry->get(MBBNum) : &NoInterference; } /// hasInterference - Return true if the current block has any interference. diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp index 611886ff16a1..0f92c2d06bdd 100644 --- a/lib/CodeGen/IntrinsicLowering.cpp +++ b/lib/CodeGen/IntrinsicLowering.cpp @@ -27,7 +27,7 @@ using namespace llvm; template static void EnsureFunctionExists(Module &M, const char *Name, ArgIt ArgBegin, ArgIt ArgEnd, - const Type *RetTy) { + Type *RetTy) { // Insert a correctly-typed definition now. std::vector ParamTys; for (ArgIt I = ArgBegin; I != ArgEnd; ++I) @@ -64,7 +64,7 @@ static void EnsureFPIntrinsicsExist(Module &M, Function *Fn, template static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, ArgIt ArgBegin, ArgIt ArgEnd, - const Type *RetTy) { + Type *RetTy) { // If we haven't already looked up this function, check to see if the // program already contains a function with this name. Module *M = CI->getParent()->getParent()->getParent(); @@ -462,7 +462,7 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { break; // Strip out annotate intrinsic case Intrinsic::memcpy: { - const IntegerType *IntPtr = TD.getIntPtrType(Context); + IntegerType *IntPtr = TD.getIntPtrType(Context); Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, /* isSigned */ false); Value *Ops[3]; @@ -473,7 +473,7 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { break; } case Intrinsic::memmove: { - const IntegerType *IntPtr = TD.getIntPtrType(Context); + IntegerType *IntPtr = TD.getIntPtrType(Context); Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, /* isSigned */ false); Value *Ops[3]; @@ -484,7 +484,7 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { break; } case Intrinsic::memset: { - const IntegerType *IntPtr = TD.getIntPtrType(Context); + IntegerType *IntPtr = TD.getIntPtrType(Context); Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, /* isSigned */ false); Value *Ops[3]; diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index f985af8ba83e..80ecc224810c 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -27,16 +27,18 @@ #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetRegistry.h" +#include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetSubtargetInfo.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" +#include "llvm/Support/TargetRegistry.h" using namespace llvm; namespace llvm { @@ -55,8 +57,12 @@ static cl::opt DisableCodePlace("disable-code-place", cl::Hidden, cl::desc("Disable code placement")); static cl::opt DisableSSC("disable-ssc", cl::Hidden, cl::desc("Disable Stack Slot Coloring")); +static cl::opt DisableMachineDCE("disable-machine-dce", cl::Hidden, + cl::desc("Disable Machine Dead Code Elimination")); static cl::opt DisableMachineLICM("disable-machine-licm", cl::Hidden, cl::desc("Disable Machine LICM")); +static cl::opt DisableMachineCSE("disable-machine-cse", cl::Hidden, + cl::desc("Disable Machine Common Subexpression Elimination")); static cl::opt DisablePostRAMachineLICM("disable-postra-machine-licm", cl::Hidden, cl::desc("Disable Machine LICM")); @@ -103,20 +109,17 @@ EnableFastISelOption("fast-isel", cl::Hidden, cl::desc("Enable the \"fast\" instruction selector")); LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple, - StringRef CPU, StringRef FS) + StringRef CPU, StringRef FS, + Reloc::Model RM, CodeModel::Model CM) : TargetMachine(T, Triple, CPU, FS) { + CodeGenInfo = T.createMCCodeGenInfo(Triple, RM, CM); AsmInfo = T.createMCAsmInfo(Triple); -} - -// Set the default code model for the JIT for a generic target. -// FIXME: Is small right here? or .is64Bit() ? Large : Small? -void LLVMTargetMachine::setCodeModelForJIT() { - setCodeModel(CodeModel::Small); -} - -// Set the default code model for static compilation for a generic target. -void LLVMTargetMachine::setCodeModelForStatic() { - setCodeModel(CodeModel::Small); + // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0, + // and if the old one gets included then MCAsmInfo will be NULL and + // we'll crash later. + // Provide the user with a useful error message about what's wrong. + assert(AsmInfo && "MCAsmInfo not initialized." + "Make sure you include the correct TargetSelect.h!"); } bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, @@ -134,21 +137,22 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, Context->setAllowTemporaryLabels(false); const MCAsmInfo &MAI = *getMCAsmInfo(); + const MCSubtargetInfo &STI = getSubtarget(); OwningPtr AsmStreamer; switch (FileType) { default: return true; case CGFT_AssemblyFile: { MCInstPrinter *InstPrinter = - getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI); + getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, STI); // Create a code emitter if asked to show the encoding. MCCodeEmitter *MCE = 0; - TargetAsmBackend *TAB = 0; + MCAsmBackend *MAB = 0; if (ShowMCEncoding) { const MCSubtargetInfo &STI = getSubtarget(); - MCE = getTarget().createCodeEmitter(*getInstrInfo(), STI, *Context); - TAB = getTarget().createAsmBackend(getTargetTriple()); + MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), STI, *Context); + MAB = getTarget().createMCAsmBackend(getTargetTriple()); } MCStreamer *S = getTarget().createAsmStreamer(*Context, Out, @@ -156,7 +160,7 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, hasMCUseLoc(), hasMCUseCFI(), InstPrinter, - MCE, TAB, + MCE, MAB, ShowMCInst); AsmStreamer.reset(S); break; @@ -164,17 +168,16 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, case CGFT_ObjectFile: { // Create the code emitter for the target if it exists. If not, .o file // emission fails. - const MCSubtargetInfo &STI = getSubtarget(); - MCCodeEmitter *MCE = getTarget().createCodeEmitter(*getInstrInfo(), STI, - *Context); - TargetAsmBackend *TAB = getTarget().createAsmBackend(getTargetTriple()); - if (MCE == 0 || TAB == 0) + MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), STI, + *Context); + MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple()); + if (MCE == 0 || MAB == 0) return true; - AsmStreamer.reset(getTarget().createObjectStreamer(getTargetTriple(), - *Context, *TAB, Out, MCE, - hasMCRelaxAll(), - hasMCNoExecStack())); + AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(), + *Context, *MAB, Out, + MCE, hasMCRelaxAll(), + hasMCNoExecStack())); AsmStreamer.get()->InitSections(); break; } @@ -198,8 +201,6 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, PM.add(Printer); - // Make sure the code model is set. - setCodeModelForStatic(); PM.add(createGCInfoDeleter()); return false; } @@ -214,9 +215,6 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM, JITCodeEmitter &JCE, CodeGenOpt::Level OptLevel, bool DisableVerify) { - // Make sure the code model is set. - setCodeModelForJIT(); - // Add common CodeGen passes. MCContext *Ctx = 0; if (addCommonCodeGenPasses(PM, OptLevel, DisableVerify, Ctx)) @@ -248,16 +246,16 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, // Create the code emitter for the target if it exists. If not, .o file // emission fails. const MCSubtargetInfo &STI = getSubtarget(); - MCCodeEmitter *MCE = getTarget().createCodeEmitter(*getInstrInfo(),STI, *Ctx); - TargetAsmBackend *TAB = getTarget().createAsmBackend(getTargetTriple()); - if (MCE == 0 || TAB == 0) + MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(),STI, *Ctx); + MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple()); + if (MCE == 0 || MAB == 0) return true; OwningPtr AsmStreamer; - AsmStreamer.reset(getTarget().createObjectStreamer(getTargetTriple(), *Ctx, - *TAB, Out, MCE, - hasMCRelaxAll(), - hasMCNoExecStack())); + AsmStreamer.reset(getTarget().createMCObjectStreamer(getTargetTriple(), *Ctx, + *MAB, Out, MCE, + hasMCRelaxAll(), + hasMCNoExecStack())); AsmStreamer.get()->InitSections(); // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. @@ -270,9 +268,6 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, PM.add(Printer); - // Make sure the code model is set. - setCodeModelForJIT(); - return false; // success! } @@ -369,8 +364,9 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // Install a MachineModuleInfo class, which is an immutable pass that holds // all the per-module stuff we're generating, including MCContext. - TargetAsmInfo *TAI = new TargetAsmInfo(*this); - MachineModuleInfo *MMI = new MachineModuleInfo(*getMCAsmInfo(), TAI); + MachineModuleInfo *MMI = new MachineModuleInfo(*getMCAsmInfo(), + *getRegisterInfo(), + &getTargetLowering()->getObjFileLowering()); PM.add(MMI); OutContext = &MMI->getContext(); // Return the MCContext specifically by-ref. @@ -412,12 +408,14 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // there is one known exception: lowered code for arguments that are only // used by tail calls, where the tail calls reuse the incoming stack // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll). - PM.add(createDeadMachineInstructionElimPass()); + if (!DisableMachineDCE) + PM.add(createDeadMachineInstructionElimPass()); printAndVerify(PM, "After codegen DCE pass"); if (!DisableMachineLICM) PM.add(createMachineLICMPass()); - PM.add(createMachineCSEPass()); + if (!DisableMachineCSE) + PM.add(createMachineCSEPass()); if (!DisableMachineSink) PM.add(createMachineSinkingPass()); printAndVerify(PM, "After Machine LICM, CSE and Sinking passes"); @@ -452,8 +450,8 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, if (addPostRegAlloc(PM, OptLevel)) printAndVerify(PM, "After PostRegAlloc passes"); - PM.add(createLowerSubregsPass()); - printAndVerify(PM, "After LowerSubregs"); + PM.add(createExpandPostRAPseudosPass()); + printAndVerify(PM, "After ExpandPostRAPseudos"); // Insert prolog/epilog code. Eliminate abstract frame index references... PM.add(createPrologEpilogCodeInserter()); diff --git a/lib/CodeGen/LexicalScopes.cpp b/lib/CodeGen/LexicalScopes.cpp new file mode 100644 index 000000000000..a12e1a36d113 --- /dev/null +++ b/lib/CodeGen/LexicalScopes.cpp @@ -0,0 +1,335 @@ +//===- LexicalScopes.cpp - Collecting lexical scope 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 LexicalScopes analysis. +// +// This pass collects lexical scope information and maps machine instructions +// to respective lexical scopes. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "lexicalscopes" +#include "llvm/CodeGen/LexicalScopes.h" +#include "llvm/Function.h" +#include "llvm/Analysis/DebugInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" +using namespace llvm; + +LexicalScopes::~LexicalScopes() { + releaseMemory(); +} + +/// releaseMemory - release memory. +void LexicalScopes::releaseMemory() { + MF = NULL; + CurrentFnLexicalScope = NULL; + DeleteContainerSeconds(LexicalScopeMap); + DeleteContainerSeconds(AbstractScopeMap); + InlinedLexicalScopeMap.clear(); + AbstractScopesList.clear(); +} + +/// initialize - Scan machine function and constuct lexical scope nest. +void LexicalScopes::initialize(const MachineFunction &Fn) { + releaseMemory(); + MF = &Fn; + SmallVector MIRanges; + DenseMap MI2ScopeMap; + extractLexicalScopes(MIRanges, MI2ScopeMap); + if (CurrentFnLexicalScope) { + constructScopeNest(CurrentFnLexicalScope); + assignInstructionRanges(MIRanges, MI2ScopeMap); + } +} + +/// extractLexicalScopes - Extract instruction ranges for each lexical scopes +/// for the given machine function. +void LexicalScopes:: +extractLexicalScopes(SmallVectorImpl &MIRanges, + DenseMap &MI2ScopeMap) { + + // Scan each instruction and create scopes. First build working set of scopes. + for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); + I != E; ++I) { + const MachineInstr *RangeBeginMI = NULL; + const MachineInstr *PrevMI = NULL; + DebugLoc PrevDL; + for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); + II != IE; ++II) { + const MachineInstr *MInsn = II; + + // Check if instruction has valid location information. + const DebugLoc MIDL = MInsn->getDebugLoc(); + if (MIDL.isUnknown()) { + PrevMI = MInsn; + continue; + } + + // If scope has not changed then skip this instruction. + if (MIDL == PrevDL) { + PrevMI = MInsn; + continue; + } + + // Ignore DBG_VALUE. It does not contribute to any instruction in output. + if (MInsn->isDebugValue()) + continue; + + if (RangeBeginMI) { + // If we have already seen a beginning of an instruction range and + // current instruction scope does not match scope of first instruction + // in this range then create a new instruction range. + InsnRange R(RangeBeginMI, PrevMI); + MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL); + MIRanges.push_back(R); + } + + // This is a beginning of a new instruction range. + RangeBeginMI = MInsn; + + // Reset previous markers. + PrevMI = MInsn; + PrevDL = MIDL; + } + + // Create last instruction range. + if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) { + InsnRange R(RangeBeginMI, PrevMI); + MIRanges.push_back(R); + MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL); + } + } +} + +/// findLexicalScope - Find lexical scope, either regular or inlined, for the +/// given DebugLoc. Return NULL if not found. +LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) { + MDNode *Scope = NULL; + MDNode *IA = NULL; + DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext()); + if (!Scope) return NULL; + + // The scope that we were created with could have an extra file - which + // isn't what we care about in this case. + DIDescriptor D = DIDescriptor(Scope); + if (D.isLexicalBlockFile()) + Scope = DILexicalBlockFile(Scope).getScope(); + + if (IA) + return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA)); + return LexicalScopeMap.lookup(Scope); +} + +/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If +/// not available then create new lexical scope. +LexicalScope *LexicalScopes::getOrCreateLexicalScope(DebugLoc DL) { + MDNode *Scope = NULL; + MDNode *InlinedAt = NULL; + DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext()); + + if (InlinedAt) { + // Create an abstract scope for inlined function. + getOrCreateAbstractScope(Scope); + // Create an inlined scope for inlined function. + return getOrCreateInlinedScope(Scope, InlinedAt); + } + + return getOrCreateRegularScope(Scope); +} + +/// getOrCreateRegularScope - Find or create a regular lexical scope. +LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) { + DIDescriptor D = DIDescriptor(Scope); + if (D.isLexicalBlockFile()) { + Scope = DILexicalBlockFile(Scope).getScope(); + D = DIDescriptor(Scope); + } + + LexicalScope *WScope = LexicalScopeMap.lookup(Scope); + if (WScope) + return WScope; + + LexicalScope *Parent = NULL; + if (D.isLexicalBlock()) + Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope)); + WScope = new LexicalScope(Parent, DIDescriptor(Scope), NULL, false); + LexicalScopeMap.insert(std::make_pair(Scope, WScope)); + if (!Parent && DIDescriptor(Scope).isSubprogram() + && DISubprogram(Scope).describes(MF->getFunction())) + CurrentFnLexicalScope = WScope; + + return WScope; +} + +/// getOrCreateInlinedScope - Find or create an inlined lexical scope. +LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope, + MDNode *InlinedAt) { + LexicalScope *InlinedScope = LexicalScopeMap.lookup(InlinedAt); + if (InlinedScope) + return InlinedScope; + + DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt); + InlinedScope = new LexicalScope(getOrCreateLexicalScope(InlinedLoc), + DIDescriptor(Scope), InlinedAt, false); + InlinedLexicalScopeMap[InlinedLoc] = InlinedScope; + LexicalScopeMap[InlinedAt] = InlinedScope; + return InlinedScope; +} + +/// getOrCreateAbstractScope - Find or create an abstract lexical scope. +LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) { + assert(N && "Invalid Scope encoding!"); + + DIDescriptor Scope(N); + if (Scope.isLexicalBlockFile()) + Scope = DILexicalBlockFile(Scope).getScope(); + LexicalScope *AScope = AbstractScopeMap.lookup(N); + if (AScope) + return AScope; + + LexicalScope *Parent = NULL; + if (Scope.isLexicalBlock()) { + DILexicalBlock DB(N); + DIDescriptor ParentDesc = DB.getContext(); + Parent = getOrCreateAbstractScope(ParentDesc); + } + AScope = new LexicalScope(Parent, DIDescriptor(N), NULL, true); + AbstractScopeMap[N] = AScope; + if (DIDescriptor(N).isSubprogram()) + AbstractScopesList.push_back(AScope); + return AScope; +} + +/// constructScopeNest +void LexicalScopes::constructScopeNest(LexicalScope *Scope) { + assert (Scope && "Unable to calculate scop edominance graph!"); + SmallVector WorkStack; + WorkStack.push_back(Scope); + unsigned Counter = 0; + while (!WorkStack.empty()) { + LexicalScope *WS = WorkStack.back(); + const SmallVector &Children = WS->getChildren(); + bool visitedChildren = false; + for (SmallVector::const_iterator SI = Children.begin(), + SE = Children.end(); SI != SE; ++SI) { + LexicalScope *ChildScope = *SI; + if (!ChildScope->getDFSOut()) { + WorkStack.push_back(ChildScope); + visitedChildren = true; + ChildScope->setDFSIn(++Counter); + break; + } + } + if (!visitedChildren) { + WorkStack.pop_back(); + WS->setDFSOut(++Counter); + } + } +} + +/// assignInstructionRanges - Find ranges of instructions covered by each +/// lexical scope. +void LexicalScopes:: +assignInstructionRanges(SmallVectorImpl &MIRanges, + DenseMap &MI2ScopeMap) +{ + + LexicalScope *PrevLexicalScope = NULL; + for (SmallVectorImpl::const_iterator RI = MIRanges.begin(), + RE = MIRanges.end(); RI != RE; ++RI) { + const InsnRange &R = *RI; + LexicalScope *S = MI2ScopeMap.lookup(R.first); + assert (S && "Lost LexicalScope for a machine instruction!"); + if (PrevLexicalScope && !PrevLexicalScope->dominates(S)) + PrevLexicalScope->closeInsnRange(S); + S->openInsnRange(R.first); + S->extendInsnRange(R.second); + PrevLexicalScope = S; + } + + if (PrevLexicalScope) + PrevLexicalScope->closeInsnRange(); +} + +/// getMachineBasicBlocks - Populate given set using machine basic blocks which +/// have machine instructions that belong to lexical scope identified by +/// DebugLoc. +void LexicalScopes:: +getMachineBasicBlocks(DebugLoc DL, + SmallPtrSet &MBBs) { + MBBs.clear(); + LexicalScope *Scope = getOrCreateLexicalScope(DL); + if (!Scope) + return; + + if (Scope == CurrentFnLexicalScope) { + for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); + I != E; ++I) + MBBs.insert(I); + return; + } + + SmallVector &InsnRanges = Scope->getRanges(); + for (SmallVector::iterator I = InsnRanges.begin(), + E = InsnRanges.end(); I != E; ++I) { + InsnRange &R = *I; + MBBs.insert(R.first->getParent()); + } +} + +/// dominates - Return true if DebugLoc's lexical scope dominates at least one +/// machine instruction's lexical scope in a given machine basic block. +bool LexicalScopes::dominates(DebugLoc DL, MachineBasicBlock *MBB) { + LexicalScope *Scope = getOrCreateLexicalScope(DL); + if (!Scope) + return false; + + // Current function scope covers all basic blocks in the function. + if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF) + return true; + + bool Result = false; + for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); + I != E; ++I) { + DebugLoc IDL = I->getDebugLoc(); + if (IDL.isUnknown()) + continue; + if (LexicalScope *IScope = getOrCreateLexicalScope(IDL)) + if (Scope->dominates(IScope)) + return true; + } + return Result; +} + +/// dump - Print data structures. +void LexicalScope::dump() const { +#ifndef NDEBUG + raw_ostream &err = dbgs(); + err.indent(IndentLevel); + err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n"; + const MDNode *N = Desc; + N->dump(); + if (AbstractScope) + err << "Abstract Scope\n"; + + IndentLevel += 2; + if (!Children.empty()) + err << "Children ...\n"; + for (unsigned i = 0, e = Children.size(); i != e; ++i) + if (Children[i] != this) + Children[i]->dump(); + + IndentLevel -= 2; +#endif +} + diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp index 5d38c83b49c2..3dfe4c0e8cfa 100644 --- a/lib/CodeGen/LiveDebugVariables.cpp +++ b/lib/CodeGen/LiveDebugVariables.cpp @@ -25,7 +25,10 @@ #include "llvm/Constants.h" #include "llvm/Metadata.h" #include "llvm/Value.h" +#include "llvm/Analysis/DebugInfo.h" #include "llvm/ADT/IntervalMap.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/LexicalScopes.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" @@ -44,6 +47,7 @@ static cl::opt EnableLDV("live-debug-variables", cl::init(true), cl::desc("Enable the live debug variables pass"), cl::Hidden); +STATISTIC(NumInsertedDebugValues, "Number of DBG_VALUEs inserted"); char LiveDebugVariables::ID = 0; INITIALIZE_PASS_BEGIN(LiveDebugVariables, "livedebugvars", @@ -67,6 +71,29 @@ LiveDebugVariables::LiveDebugVariables() : MachineFunctionPass(ID), pImpl(0) { /// LocMap - Map of where a user value is live, and its location. typedef IntervalMap LocMap; +namespace { +/// UserValueScopes - Keeps track of lexical scopes associated with an +/// user value's source location. +class UserValueScopes { + DebugLoc DL; + LexicalScopes &LS; + SmallPtrSet LBlocks; + +public: + UserValueScopes(DebugLoc D, LexicalScopes &L) : DL(D), LS(L) {} + + /// dominates - Return true if current scope dominates at least one machine + /// instruction in a given machine basic block. + bool dominates(MachineBasicBlock *MBB) { + if (LBlocks.empty()) + LS.getMachineBasicBlocks(DL, LBlocks); + if (LBlocks.count(MBB) != 0 || LS.dominates(DL, MBB)) + return true; + return false; + } +}; +} // end anonymous namespace + /// UserValue - A user value is a part of a debug info user variable. /// /// A DBG_VALUE instruction notes that (a sub-register of) a virtual register @@ -179,6 +206,9 @@ class UserValue { LocMap::iterator I = locInts.find(Idx); if (!I.valid() || I.start() != Idx) I.insert(Idx, Idx.getNextSlot(), getLocationNo(LocMO)); + else + // A later DBG_VALUE at the same SlotIndex overrides the old location. + I.setValue(getLocationNo(LocMO)); } /// extendDef - Extend the current definition as far as possible down the @@ -195,7 +225,8 @@ class UserValue { void extendDef(SlotIndex Idx, unsigned LocNo, LiveInterval *LI, const VNInfo *VNI, SmallVectorImpl *Kills, - LiveIntervals &LIS, MachineDominatorTree &MDT); + LiveIntervals &LIS, MachineDominatorTree &MDT, + UserValueScopes &UVS); /// addDefsFromCopies - The value in LI/LocNo may be copies to other /// registers. Determine if any of the copies are available at the kill @@ -213,7 +244,8 @@ class UserValue { /// computeIntervals - Compute the live intervals of all locations after /// collecting all their def points. void computeIntervals(MachineRegisterInfo &MRI, - LiveIntervals &LIS, MachineDominatorTree &MDT); + LiveIntervals &LIS, MachineDominatorTree &MDT, + UserValueScopes &UVS); /// renameRegister - Update locations to rewrite OldReg as NewReg:SubIdx. void renameRegister(unsigned OldReg, unsigned NewReg, unsigned SubIdx, @@ -236,6 +268,9 @@ class UserValue { /// Only first one needs DebugLoc to identify variable's lexical scope /// in source file. DebugLoc findDebugLoc(); + + /// getDebugLoc - Return DebugLoc of this UserValue. + DebugLoc getDebugLoc() { return dl;} void print(raw_ostream&, const TargetMachine*); }; } // namespace @@ -247,6 +282,7 @@ class LDVImpl { LocMap::Allocator allocator; MachineFunction *MF; LiveIntervals *LIS; + LexicalScopes LS; MachineDominatorTree *MDT; const TargetRegisterInfo *TRI; @@ -312,8 +348,10 @@ class LDVImpl { } // namespace void UserValue::print(raw_ostream &OS, const TargetMachine *TM) { - if (const MDString *MDS = dyn_cast(variable->getOperand(2))) - OS << "!\"" << MDS->getString() << "\"\t"; + DIVariable DV(variable); + OS << "!\""; + DV.printExtendedName(OS); + OS << "\"\t"; if (offset) OS << '+' << offset; for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I) { @@ -447,10 +485,10 @@ bool LDVImpl::collectDebugValues(MachineFunction &mf) { void UserValue::extendDef(SlotIndex Idx, unsigned LocNo, LiveInterval *LI, const VNInfo *VNI, SmallVectorImpl *Kills, - LiveIntervals &LIS, MachineDominatorTree &MDT) { + LiveIntervals &LIS, MachineDominatorTree &MDT, + UserValueScopes &UVS) { SmallVector Todo; Todo.push_back(Idx); - do { SlotIndex Start = Todo.pop_back_val(); MachineBasicBlock *MBB = LIS.getMBBFromIndex(Start); @@ -497,8 +535,11 @@ void UserValue::extendDef(SlotIndex Idx, unsigned LocNo, continue; const std::vector &Children = MDT.getNode(MBB)->getChildren(); - for (unsigned i = 0, e = Children.size(); i != e; ++i) - Todo.push_back(LIS.getMBBStartIdx(Children[i]->getBlock())); + for (unsigned i = 0, e = Children.size(); i != e; ++i) { + MachineBasicBlock *MBB = Children[i]->getBlock(); + if (UVS.dominates(MBB)) + Todo.push_back(LIS.getMBBStartIdx(MBB)); + } } while (!Todo.empty()); } @@ -578,7 +619,8 @@ UserValue::addDefsFromCopies(LiveInterval *LI, unsigned LocNo, void UserValue::computeIntervals(MachineRegisterInfo &MRI, LiveIntervals &LIS, - MachineDominatorTree &MDT) { + MachineDominatorTree &MDT, + UserValueScopes &UVS) { SmallVector, 16> Defs; // Collect all defs to be extended (Skipping undefs). @@ -597,10 +639,10 @@ UserValue::computeIntervals(MachineRegisterInfo &MRI, LiveInterval *LI = &LIS.getInterval(Loc.getReg()); const VNInfo *VNI = LI->getVNInfoAt(Idx); SmallVector Kills; - extendDef(Idx, LocNo, LI, VNI, &Kills, LIS, MDT); + extendDef(Idx, LocNo, LI, VNI, &Kills, LIS, MDT, UVS); addDefsFromCopies(LI, LocNo, Kills, Defs, MRI, LIS); } else - extendDef(Idx, LocNo, 0, 0, 0, LIS, MDT); + extendDef(Idx, LocNo, 0, 0, 0, LIS, MDT, UVS); } // Finally, erase all the undefs. @@ -613,7 +655,8 @@ UserValue::computeIntervals(MachineRegisterInfo &MRI, void LDVImpl::computeIntervals() { for (unsigned i = 0, e = userValues.size(); i != e; ++i) { - userValues[i]->computeIntervals(MF->getRegInfo(), *LIS, *MDT); + UserValueScopes UVS(userValues[i]->getDebugLoc(), LS); + userValues[i]->computeIntervals(MF->getRegInfo(), *LIS, *MDT, UVS); userValues[i]->mapVirtRegs(this); } } @@ -624,6 +667,7 @@ bool LDVImpl::runOnMachineFunction(MachineFunction &mf) { MDT = &pass.getAnalysis(); TRI = mf.getTarget().getRegisterInfo(); clear(); + LS.initialize(mf); DEBUG(dbgs() << "********** COMPUTING LIVE DEBUG VARIABLES: " << ((Value*)mf.getFunction())->getName() << " **********\n"); @@ -631,6 +675,7 @@ bool LDVImpl::runOnMachineFunction(MachineFunction &mf) { bool Changed = collectDebugValues(mf); computeIntervals(); DEBUG(print(dbgs())); + LS.releaseMemory(); return Changed; } @@ -891,6 +936,7 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, const TargetInstrInfo &TII) { MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, LIS); MachineOperand &Loc = locations[LocNo]; + ++NumInsertedDebugValues; // Frame index locations may require a target callback. if (Loc.isFI()) { @@ -921,7 +967,6 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS, DEBUG(dbgs() << " BB#" << MBB->getNumber() << '-' << MBBEnd); insertDebugValue(MBB, Start, LocNo, LIS, TII); - // This interval may span multiple basic blocks. // Insert a DBG_VALUE into each one. while(Stop > MBBEnd) { diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index cfade24b8d87..b69945aea98f 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -148,7 +148,6 @@ void LiveInterval::markValNoForDeletion(VNInfo *ValNo) { /// remaining unused values. void LiveInterval::RenumberValues(LiveIntervals &lis) { SmallPtrSet Seen; - bool seenPHIDef = false; valnos.clear(); for (const_iterator I = begin(), E = end(); I != E; ++I) { VNInfo *VNI = I->valno; @@ -157,26 +156,6 @@ void LiveInterval::RenumberValues(LiveIntervals &lis) { assert(!VNI->isUnused() && "Unused valno used by live range"); VNI->id = (unsigned)valnos.size(); valnos.push_back(VNI); - VNI->setHasPHIKill(false); - if (VNI->isPHIDef()) - seenPHIDef = true; - } - - // Recompute phi kill flags. - if (!seenPHIDef) - return; - for (const_vni_iterator I = vni_begin(), E = vni_end(); I != E; ++I) { - VNInfo *VNI = *I; - if (!VNI->isPHIDef()) - continue; - const MachineBasicBlock *PHIBB = lis.getMBBFromIndex(VNI->def); - assert(PHIBB && "No basic block for phi-def"); - for (MachineBasicBlock::const_pred_iterator PI = PHIBB->pred_begin(), - PE = PHIBB->pred_end(); PI != PE; ++PI) { - VNInfo *KVNI = getVNInfoAt(lis.getMBBEndIdx(*PI).getPrevSlot()); - if (KVNI) - KVNI->setHasPHIKill(true); - } } } @@ -294,20 +273,20 @@ LiveInterval::addRangeFrom(LiveRange LR, iterator From) { return ranges.insert(it, LR); } -/// extendInBlock - If this interval is live before UseIdx in the basic -/// block that starts at StartIdx, extend it to be live at UseIdx and return -/// the value. If there is no live range before UseIdx, return NULL. -VNInfo *LiveInterval::extendInBlock(SlotIndex StartIdx, SlotIndex UseIdx) { +/// extendInBlock - If this interval is live before Kill in the basic +/// block that starts at StartIdx, extend it to be live up to Kill and return +/// the value. If there is no live range before Kill, return NULL. +VNInfo *LiveInterval::extendInBlock(SlotIndex StartIdx, SlotIndex Kill) { if (empty()) return 0; - iterator I = std::upper_bound(begin(), end(), UseIdx); + iterator I = std::upper_bound(begin(), end(), Kill.getPrevSlot()); if (I == begin()) return 0; --I; if (I->end <= StartIdx) return 0; - if (I->end <= UseIdx) - extendIntervalEndTo(I, UseIdx.getNextSlot()); + if (I->end < Kill) + extendIntervalEndTo(I, Kill); return I->valno; } diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 9257191f7fc0..b1e202a273d3 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -304,8 +304,19 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // Make sure the first definition is not a partial redefinition. Add an // of the full register. - if (MO.getSubReg()) + // FIXME: LiveIntervals shouldn't modify the code like this. Whoever + // created the machine instruction should annotate it with flags + // as needed. Then we can simply assert here. The REG_SEQUENCE lowering + // is the main suspect. + if (MO.getSubReg()) { mi->addRegisterDefined(interval.reg); + // Mark all defs of interval.reg on this instruction as reading . + for (unsigned i = MOIdx, e = mi->getNumOperands(); i != e; ++i) { + MachineOperand &MO2 = mi->getOperand(i); + if (MO2.isReg() && MO2.getReg() == interval.reg && MO2.getSubReg()) + MO2.setIsUndef(); + } + } MachineInstr *CopyMI = NULL; if (mi->isCopyLike()) { @@ -747,6 +758,9 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li, // Find all the values used, including PHI kills. SmallVector, 16> WorkList; + // Blocks that have already been added to WorkList as live-out. + SmallPtrSet LiveOut; + // Visit all instructions reading li->reg. for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(li->reg); MachineInstr *UseMI = I.skipInstruction();) { @@ -780,8 +794,6 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li, VNInfo *VNI = *I; if (VNI->isUnused()) continue; - // We may eliminate PHI values, so recompute PHIKill flags. - VNI->setHasPHIKill(false); NewLI.addRange(LiveRange(VNI->def, VNI->def.getNextSlot(), VNI)); // A use tied to an early-clobber def ends at the load slot and isn't caught @@ -804,7 +816,7 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li, SlotIndex BlockStart = getMBBStartIdx(MBB); // Extend the live range for VNI to be live at Idx. - if (VNInfo *ExtVNI = NewLI.extendInBlock(BlockStart, Idx)) { + if (VNInfo *ExtVNI = NewLI.extendInBlock(BlockStart, Idx.getNextSlot())) { (void)ExtVNI; assert(ExtVNI == VNI && "Unexpected existing value number"); // Is this a PHIDef we haven't seen before? @@ -813,13 +825,12 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li, // The PHI is live, make sure the predecessors are live-out. for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PE = MBB->pred_end(); PI != PE; ++PI) { + if (!LiveOut.insert(*PI)) + continue; SlotIndex Stop = getMBBEndIdx(*PI).getPrevSlot(); - VNInfo *PVNI = li->getVNInfoAt(Stop); // A predecessor is not required to have a live-out value for a PHI. - if (PVNI) { - PVNI->setHasPHIKill(true); + if (VNInfo *PVNI = li->getVNInfoAt(Stop)) WorkList.push_back(std::make_pair(Stop, PVNI)); - } } continue; } @@ -831,6 +842,8 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li, // Make sure VNI is live-out from the predecessors. for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PE = MBB->pred_end(); PI != PE; ++PI) { + if (!LiveOut.insert(*PI)) + continue; SlotIndex Stop = getMBBEndIdx(*PI).getPrevSlot(); assert(li->getVNInfoAt(Stop) == VNI && "Wrong value out of predecessor"); WorkList.push_back(std::make_pair(Stop, VNI)); diff --git a/lib/CodeGen/LiveIntervalUnion.cpp b/lib/CodeGen/LiveIntervalUnion.cpp index 70003e7cc86a..110fe1e62024 100644 --- a/lib/CodeGen/LiveIntervalUnion.cpp +++ b/lib/CodeGen/LiveIntervalUnion.cpp @@ -91,25 +91,6 @@ LiveIntervalUnion::print(raw_ostream &OS, const TargetRegisterInfo *TRI) const { OS << '\n'; } -void LiveIntervalUnion::InterferenceResult::print(raw_ostream &OS, - const TargetRegisterInfo *TRI) const { - OS << '[' << start() << ';' << stop() << "):" - << PrintReg(interference()->reg, TRI); -} - -void LiveIntervalUnion::Query::print(raw_ostream &OS, - const TargetRegisterInfo *TRI) { - OS << "Interferences with "; - LiveUnion->print(OS, TRI); - InterferenceResult IR = firstInterference(); - while (isInterference(IR)) { - OS << " "; - IR.print(OS, TRI); - OS << '\n'; - nextInterference(IR); - } -} - #ifndef NDEBUG // Verify the live intervals in this union and add them to the visited set. void LiveIntervalUnion::verify(LiveVirtRegBitSet& VisitedVRegs) { @@ -118,114 +99,6 @@ void LiveIntervalUnion::verify(LiveVirtRegBitSet& VisitedVRegs) { } #endif //!NDEBUG -// Private interface accessed by Query. -// -// Find a pair of segments that intersect, one in the live virtual register -// (LiveInterval), and the other in this LiveIntervalUnion. The caller (Query) -// is responsible for advancing the LiveIntervalUnion segments to find a -// "notable" intersection, which requires query-specific logic. -// -// This design assumes only a fast mechanism for intersecting a single live -// virtual register segment with a set of LiveIntervalUnion segments. This may -// be ok since most virtual registers have very few segments. If we had a data -// structure that optimizd MxN intersection of segments, then we would bypass -// the loop that advances within the LiveInterval. -// -// If no intersection exists, set VirtRegI = VirtRegEnd, and set SI to the first -// segment whose start point is greater than LiveInterval's end point. -// -// Assumes that segments are sorted by start position in both -// LiveInterval and LiveSegments. -void LiveIntervalUnion::Query::findIntersection(InterferenceResult &IR) const { - // Search until reaching the end of the LiveUnion segments. - LiveInterval::iterator VirtRegEnd = VirtReg->end(); - if (IR.VirtRegI == VirtRegEnd) - return; - while (IR.LiveUnionI.valid()) { - // Slowly advance the live virtual reg iterator until we surpass the next - // segment in LiveUnion. - // - // Note: If this is ever used for coalescing of fixed registers and we have - // a live vreg with thousands of segments, then change this code to use - // upperBound instead. - IR.VirtRegI = VirtReg->advanceTo(IR.VirtRegI, IR.LiveUnionI.start()); - if (IR.VirtRegI == VirtRegEnd) - break; // Retain current (nonoverlapping) LiveUnionI - - // VirtRegI may have advanced far beyond LiveUnionI, catch up. - IR.LiveUnionI.advanceTo(IR.VirtRegI->start); - - // Check if no LiveUnionI exists with VirtRegI->Start < LiveUnionI.end - if (!IR.LiveUnionI.valid()) - break; - if (IR.LiveUnionI.start() < IR.VirtRegI->end) { - assert(overlap(*IR.VirtRegI, IR.LiveUnionI) && - "upperBound postcondition"); - break; - } - } - if (!IR.LiveUnionI.valid()) - IR.VirtRegI = VirtRegEnd; -} - -// Find the first intersection, and cache interference info -// (retain segment iterators into both VirtReg and LiveUnion). -const LiveIntervalUnion::InterferenceResult & -LiveIntervalUnion::Query::firstInterference() { - if (CheckedFirstInterference) - return FirstInterference; - CheckedFirstInterference = true; - InterferenceResult &IR = FirstInterference; - IR.LiveUnionI.setMap(LiveUnion->getMap()); - - // Quickly skip interference check for empty sets. - if (VirtReg->empty() || LiveUnion->empty()) { - IR.VirtRegI = VirtReg->end(); - } else if (VirtReg->beginIndex() < LiveUnion->startIndex()) { - // VirtReg starts first, perform double binary search. - IR.VirtRegI = VirtReg->find(LiveUnion->startIndex()); - if (IR.VirtRegI != VirtReg->end()) - IR.LiveUnionI.find(IR.VirtRegI->start); - } else { - // LiveUnion starts first, perform double binary search. - IR.LiveUnionI.find(VirtReg->beginIndex()); - if (IR.LiveUnionI.valid()) - IR.VirtRegI = VirtReg->find(IR.LiveUnionI.start()); - else - IR.VirtRegI = VirtReg->end(); - } - findIntersection(FirstInterference); - assert((IR.VirtRegI == VirtReg->end() || IR.LiveUnionI.valid()) - && "Uninitialized iterator"); - return FirstInterference; -} - -// Treat the result as an iterator and advance to the next interfering pair -// of segments. This is a plain iterator with no filter. -bool LiveIntervalUnion::Query::nextInterference(InterferenceResult &IR) const { - assert(isInterference(IR) && "iteration past end of interferences"); - - // Advance either the VirtReg or LiveUnion segment to ensure that we visit all - // unique overlapping pairs. - if (IR.VirtRegI->end < IR.LiveUnionI.stop()) { - if (++IR.VirtRegI == VirtReg->end()) - return false; - } - else { - if (!(++IR.LiveUnionI).valid()) { - IR.VirtRegI = VirtReg->end(); - return false; - } - } - // Short-circuit findIntersection() if possible. - if (overlap(*IR.VirtRegI, IR.LiveUnionI)) - return true; - - // Find the next intersection. - findIntersection(IR); - return isInterference(IR); -} - // Scan the vector of interfering virtual registers in this union. Assume it's // quite small. bool LiveIntervalUnion::Query::isSeenInterference(LiveInterval *VirtReg) const { @@ -234,64 +107,75 @@ bool LiveIntervalUnion::Query::isSeenInterference(LiveInterval *VirtReg) const { return I != InterferingVRegs.end(); } -// Count the number of virtual registers in this union that interfere with this +// Collect virtual registers in this union that interfere with this // query's live virtual register. // -// The number of times that we either advance IR.VirtRegI or call -// LiveUnion.upperBound() will be no more than the number of holes in -// VirtReg. So each invocation of collectInterferingVRegs() takes -// time proportional to |VirtReg Holes| * time(LiveUnion.upperBound()). +// The query state is one of: +// +// 1. CheckedFirstInterference == false: Iterators are uninitialized. +// 2. SeenAllInterferences == true: InterferingVRegs complete, iterators unused. +// 3. Iterators left at the last seen intersection. // -// For comments on how to speed it up, see Query::findIntersection(). unsigned LiveIntervalUnion::Query:: collectInterferingVRegs(unsigned MaxInterferingRegs) { - InterferenceResult IR = firstInterference(); - LiveInterval::iterator VirtRegEnd = VirtReg->end(); - LiveInterval *RecentInterferingVReg = NULL; - if (IR.VirtRegI != VirtRegEnd) while (IR.LiveUnionI.valid()) { - // Advance the union's iterator to reach an unseen interfering vreg. - do { - if (IR.LiveUnionI.value() == RecentInterferingVReg) - continue; + // Fast path return if we already have the desired information. + if (SeenAllInterferences || InterferingVRegs.size() >= MaxInterferingRegs) + return InterferingVRegs.size(); - if (!isSeenInterference(IR.LiveUnionI.value())) - break; + // Set up iterators on the first call. + if (!CheckedFirstInterference) { + CheckedFirstInterference = true; - // Cache the most recent interfering vreg to bypass isSeenInterference. - RecentInterferingVReg = IR.LiveUnionI.value(); - - } while ((++IR.LiveUnionI).valid()); - if (!IR.LiveUnionI.valid()) - break; - - // Advance the VirtReg iterator until surpassing the next segment in - // LiveUnion. - IR.VirtRegI = VirtReg->advanceTo(IR.VirtRegI, IR.LiveUnionI.start()); - if (IR.VirtRegI == VirtRegEnd) - break; - - // Check for intersection with the union's segment. - if (overlap(*IR.VirtRegI, IR.LiveUnionI)) { - - if (!IR.LiveUnionI.value()->isSpillable()) - SeenUnspillableVReg = true; - - if (InterferingVRegs.size() == MaxInterferingRegs) - // Leave SeenAllInterferences set to false to indicate that at least one - // interference exists beyond those we collected. - return MaxInterferingRegs; - - InterferingVRegs.push_back(IR.LiveUnionI.value()); - - // Cache the most recent interfering vreg to bypass isSeenInterference. - RecentInterferingVReg = IR.LiveUnionI.value(); - ++IR.LiveUnionI; - - continue; + // Quickly skip interference check for empty sets. + if (VirtReg->empty() || LiveUnion->empty()) { + SeenAllInterferences = true; + return 0; } - // VirtRegI may have advanced far beyond LiveUnionI, - // do a fast intersection test to "catch up" - IR.LiveUnionI.advanceTo(IR.VirtRegI->start); + + // In most cases, the union will start before VirtReg. + VirtRegI = VirtReg->begin(); + LiveUnionI.setMap(LiveUnion->getMap()); + LiveUnionI.find(VirtRegI->start); + } + + LiveInterval::iterator VirtRegEnd = VirtReg->end(); + LiveInterval *RecentReg = 0; + while (LiveUnionI.valid()) { + assert(VirtRegI != VirtRegEnd && "Reached end of VirtReg"); + + // Check for overlapping interference. + while (VirtRegI->start < LiveUnionI.stop() && + VirtRegI->end > LiveUnionI.start()) { + // This is an overlap, record the interfering register. + LiveInterval *VReg = LiveUnionI.value(); + if (VReg != RecentReg && !isSeenInterference(VReg)) { + RecentReg = VReg; + InterferingVRegs.push_back(VReg); + if (InterferingVRegs.size() >= MaxInterferingRegs) + return InterferingVRegs.size(); + } + // This LiveUnion segment is no longer interesting. + if (!(++LiveUnionI).valid()) { + SeenAllInterferences = true; + return InterferingVRegs.size(); + } + } + + // The iterators are now not overlapping, LiveUnionI has been advanced + // beyond VirtRegI. + assert(VirtRegI->end <= LiveUnionI.start() && "Expected non-overlap"); + + // Advance the iterator that ends first. + VirtRegI = VirtReg->advanceTo(VirtRegI, LiveUnionI.start()); + if (VirtRegI == VirtRegEnd) + break; + + // Detect overlap, handle above. + if (VirtRegI->start < LiveUnionI.stop()) + continue; + + // Still not overlapping. Catch up LiveUnionI. + LiveUnionI.advanceTo(VirtRegI->start); } SeenAllInterferences = true; return InterferingVRegs.size(); diff --git a/lib/CodeGen/LiveIntervalUnion.h b/lib/CodeGen/LiveIntervalUnion.h index 5e78d5e85029..5d64d285f39a 100644 --- a/lib/CodeGen/LiveIntervalUnion.h +++ b/lib/CodeGen/LiveIntervalUnion.h @@ -59,7 +59,6 @@ class LiveIntervalUnion { // LiveIntervalUnions share an external allocator. typedef LiveSegments::Allocator Allocator; - class InterferenceResult; class Query; private: @@ -106,62 +105,13 @@ class LiveIntervalUnion { void verify(LiveVirtRegBitSet& VisitedVRegs); #endif - /// Cache a single interference test result in the form of two intersecting - /// segments. This allows efficiently iterating over the interferences. The - /// iteration logic is handled by LiveIntervalUnion::Query which may - /// filter interferences depending on the type of query. - class InterferenceResult { - friend class Query; - - LiveInterval::iterator VirtRegI; // current position in VirtReg - SegmentIter LiveUnionI; // current position in LiveUnion - - // Internal ctor. - InterferenceResult(LiveInterval::iterator VRegI, SegmentIter UnionI) - : VirtRegI(VRegI), LiveUnionI(UnionI) {} - - public: - // Public default ctor. - InterferenceResult(): VirtRegI(), LiveUnionI() {} - - /// start - Return the start of the current overlap. - SlotIndex start() const { - return std::max(VirtRegI->start, LiveUnionI.start()); - } - - /// stop - Return the end of the current overlap. - SlotIndex stop() const { - return std::min(VirtRegI->end, LiveUnionI.stop()); - } - - /// interference - Return the register that is interfering here. - LiveInterval *interference() const { return LiveUnionI.value(); } - - // Note: this interface provides raw access to the iterators because the - // result has no way to tell if it's valid to dereference them. - - // Access the VirtReg segment. - LiveInterval::iterator virtRegPos() const { return VirtRegI; } - - // Access the LiveUnion segment. - const SegmentIter &liveUnionPos() const { return LiveUnionI; } - - bool operator==(const InterferenceResult &IR) const { - return VirtRegI == IR.VirtRegI && LiveUnionI == IR.LiveUnionI; - } - bool operator!=(const InterferenceResult &IR) const { - return !operator==(IR); - } - - void print(raw_ostream &OS, const TargetRegisterInfo *TRI) const; - }; - /// Query interferences between a single live virtual register and a live /// interval union. class Query { LiveIntervalUnion *LiveUnion; LiveInterval *VirtReg; - InterferenceResult FirstInterference; + LiveInterval::iterator VirtRegI; // current position in VirtReg + SegmentIter LiveUnionI; // current position in LiveUnion SmallVector InterferingVRegs; bool CheckedFirstInterference; bool SeenAllInterferences; @@ -206,26 +156,8 @@ class LiveIntervalUnion { return *VirtReg; } - bool isInterference(const InterferenceResult &IR) const { - if (IR.VirtRegI != VirtReg->end()) { - assert(overlap(*IR.VirtRegI, IR.LiveUnionI) && - "invalid segment iterators"); - return true; - } - return false; - } - // Does this live virtual register interfere with the union? - bool checkInterference() { return isInterference(firstInterference()); } - - // Get the first pair of interfering segments, or a noninterfering result. - // This initializes the firstInterference_ cache. - const InterferenceResult &firstInterference(); - - // Treat the result as an iterator and advance to the next interfering pair - // of segments. Visiting each unique interfering pairs means that the same - // VirtReg or LiveUnion segment may be visited multiple times. - bool nextInterference(InterferenceResult &IR) const; + bool checkInterference() { return collectInterferingVRegs(1); } // Count the virtual registers in this union that interfere with this // query's live virtual register, up to maxInterferingRegs. @@ -249,13 +181,9 @@ class LiveIntervalUnion { /// Loop. bool checkLoopInterference(MachineLoopRange*); - void print(raw_ostream &OS, const TargetRegisterInfo *TRI); private: Query(const Query&); // DO NOT IMPLEMENT void operator=(const Query&); // DO NOT IMPLEMENT - - // Private interface for queries - void findIntersection(InterferenceResult &IR) const; }; }; diff --git a/lib/CodeGen/LiveRangeCalc.cpp b/lib/CodeGen/LiveRangeCalc.cpp new file mode 100644 index 000000000000..a7d5af5198e5 --- /dev/null +++ b/lib/CodeGen/LiveRangeCalc.cpp @@ -0,0 +1,270 @@ +//===---- LiveRangeCalc.cpp - Calculate live ranges -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implementation of the LiveRangeCalc class. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "regalloc" +#include "LiveRangeCalc.h" +#include "llvm/CodeGen/MachineDominators.h" + +using namespace llvm; + +void LiveRangeCalc::reset(const MachineFunction *MF) { + unsigned N = MF->getNumBlockIDs(); + Seen.clear(); + Seen.resize(N); + LiveOut.resize(N); + LiveIn.clear(); +} + + +// Transfer information from the LiveIn vector to the live ranges. +void LiveRangeCalc::updateLiveIns(VNInfo *OverrideVNI, SlotIndexes *Indexes) { + for (SmallVectorImpl::iterator I = LiveIn.begin(), + E = LiveIn.end(); I != E; ++I) { + if (!I->DomNode) + continue; + MachineBasicBlock *MBB = I->DomNode->getBlock(); + + VNInfo *VNI = OverrideVNI ? OverrideVNI : I->Value; + assert(VNI && "No live-in value found"); + + SlotIndex Start, End; + tie(Start, End) = Indexes->getMBBRange(MBB); + + if (I->Kill.isValid()) + I->LI->addRange(LiveRange(Start, I->Kill, VNI)); + else { + I->LI->addRange(LiveRange(Start, End, VNI)); + // The value is live-through, update LiveOut as well. Defer the Domtree + // lookup until it is needed. + assert(Seen.test(MBB->getNumber())); + LiveOut[MBB] = LiveOutPair(VNI, (MachineDomTreeNode *)0); + } + } + LiveIn.clear(); +} + + +void LiveRangeCalc::extend(LiveInterval *LI, + SlotIndex Kill, + SlotIndexes *Indexes, + MachineDominatorTree *DomTree, + VNInfo::Allocator *Alloc) { + assert(LI && "Missing live range"); + assert(Kill.isValid() && "Invalid SlotIndex"); + assert(Indexes && "Missing SlotIndexes"); + assert(DomTree && "Missing dominator tree"); + + MachineBasicBlock *KillMBB = Indexes->getMBBFromIndex(Kill.getPrevSlot()); + assert(Kill && "No MBB at Kill"); + + // Is there a def in the same MBB we can extend? + if (LI->extendInBlock(Indexes->getMBBStartIdx(KillMBB), Kill)) + return; + + // Find the single reaching def, or determine if Kill is jointly dominated by + // multiple values, and we may need to create even more phi-defs to preserve + // VNInfo SSA form. Perform a search for all predecessor blocks where we + // know the dominating VNInfo. + VNInfo *VNI = findReachingDefs(LI, KillMBB, Kill, Indexes, DomTree); + + // When there were multiple different values, we may need new PHIs. + if (!VNI) + updateSSA(Indexes, DomTree, Alloc); + + updateLiveIns(VNI, Indexes); +} + + +// This function is called by a client after using the low-level API to add +// live-out and live-in blocks. The unique value optimization is not +// available, SplitEditor::transferValues handles that case directly anyway. +void LiveRangeCalc::calculateValues(SlotIndexes *Indexes, + MachineDominatorTree *DomTree, + VNInfo::Allocator *Alloc) { + assert(Indexes && "Missing SlotIndexes"); + assert(DomTree && "Missing dominator tree"); + updateSSA(Indexes, DomTree, Alloc); + updateLiveIns(0, Indexes); +} + + +VNInfo *LiveRangeCalc::findReachingDefs(LiveInterval *LI, + MachineBasicBlock *KillMBB, + SlotIndex Kill, + SlotIndexes *Indexes, + MachineDominatorTree *DomTree) { + // Blocks where LI should be live-in. + SmallVector WorkList(1, KillMBB); + + // Remember if we have seen more than one value. + bool UniqueVNI = true; + VNInfo *TheVNI = 0; + + // Using Seen as a visited set, perform a BFS for all reaching defs. + for (unsigned i = 0; i != WorkList.size(); ++i) { + MachineBasicBlock *MBB = WorkList[i]; + assert(!MBB->pred_empty() && "Value live-in to entry block?"); + for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), + PE = MBB->pred_end(); PI != PE; ++PI) { + MachineBasicBlock *Pred = *PI; + + // Is this a known live-out block? + if (Seen.test(Pred->getNumber())) { + if (VNInfo *VNI = LiveOut[Pred].first) { + if (TheVNI && TheVNI != VNI) + UniqueVNI = false; + TheVNI = VNI; + } + continue; + } + + SlotIndex Start, End; + tie(Start, End) = Indexes->getMBBRange(Pred); + + // First time we see Pred. Try to determine the live-out value, but set + // it as null if Pred is live-through with an unknown value. + VNInfo *VNI = LI->extendInBlock(Start, End); + setLiveOutValue(Pred, VNI); + if (VNI) { + if (TheVNI && TheVNI != VNI) + UniqueVNI = false; + TheVNI = VNI; + continue; + } + + // No, we need a live-in value for Pred as well + if (Pred != KillMBB) + WorkList.push_back(Pred); + else + // Loopback to KillMBB, so value is really live through. + Kill = SlotIndex(); + } + } + + // Transfer WorkList to LiveInBlocks in reverse order. + // This ordering works best with updateSSA(). + LiveIn.clear(); + LiveIn.reserve(WorkList.size()); + while(!WorkList.empty()) + addLiveInBlock(LI, DomTree->getNode(WorkList.pop_back_val())); + + // The kill block may not be live-through. + assert(LiveIn.back().DomNode->getBlock() == KillMBB); + LiveIn.back().Kill = Kill; + + return UniqueVNI ? TheVNI : 0; +} + + +// This is essentially the same iterative algorithm that SSAUpdater uses, +// except we already have a dominator tree, so we don't have to recompute it. +void LiveRangeCalc::updateSSA(SlotIndexes *Indexes, + MachineDominatorTree *DomTree, + VNInfo::Allocator *Alloc) { + assert(Indexes && "Missing SlotIndexes"); + assert(DomTree && "Missing dominator tree"); + + // Interate until convergence. + unsigned Changes; + do { + Changes = 0; + // Propagate live-out values down the dominator tree, inserting phi-defs + // when necessary. + for (SmallVectorImpl::iterator I = LiveIn.begin(), + E = LiveIn.end(); I != E; ++I) { + MachineDomTreeNode *Node = I->DomNode; + // Skip block if the live-in value has already been determined. + if (!Node) + continue; + MachineBasicBlock *MBB = Node->getBlock(); + MachineDomTreeNode *IDom = Node->getIDom(); + LiveOutPair IDomValue; + + // We need a live-in value to a block with no immediate dominator? + // This is probably an unreachable block that has survived somehow. + bool needPHI = !IDom || !Seen.test(IDom->getBlock()->getNumber()); + + // IDom dominates all of our predecessors, but it may not be their + // immediate dominator. Check if any of them have live-out values that are + // properly dominated by IDom. If so, we need a phi-def here. + if (!needPHI) { + IDomValue = LiveOut[IDom->getBlock()]; + + // Cache the DomTree node that defined the value. + if (IDomValue.first && !IDomValue.second) + LiveOut[IDom->getBlock()].second = IDomValue.second = + DomTree->getNode(Indexes->getMBBFromIndex(IDomValue.first->def)); + + for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), + PE = MBB->pred_end(); PI != PE; ++PI) { + LiveOutPair &Value = LiveOut[*PI]; + if (!Value.first || Value.first == IDomValue.first) + continue; + + // Cache the DomTree node that defined the value. + if (!Value.second) + Value.second = + DomTree->getNode(Indexes->getMBBFromIndex(Value.first->def)); + + // This predecessor is carrying something other than IDomValue. + // It could be because IDomValue hasn't propagated yet, or it could be + // because MBB is in the dominance frontier of that value. + if (DomTree->dominates(IDom, Value.second)) { + needPHI = true; + break; + } + } + } + + // The value may be live-through even if Kill is set, as can happen when + // we are called from extendRange. In that case LiveOutSeen is true, and + // LiveOut indicates a foreign or missing value. + LiveOutPair &LOP = LiveOut[MBB]; + + // Create a phi-def if required. + if (needPHI) { + ++Changes; + assert(Alloc && "Need VNInfo allocator to create PHI-defs"); + SlotIndex Start, End; + tie(Start, End) = Indexes->getMBBRange(MBB); + VNInfo *VNI = I->LI->getNextValue(Start, 0, *Alloc); + VNI->setIsPHIDef(true); + I->Value = VNI; + // This block is done, we know the final value. + I->DomNode = 0; + + // Add liveness since updateLiveIns now skips this node. + if (I->Kill.isValid()) + I->LI->addRange(LiveRange(Start, I->Kill, VNI)); + else { + I->LI->addRange(LiveRange(Start, End, VNI)); + LOP = LiveOutPair(VNI, Node); + } + } else if (IDomValue.first) { + // No phi-def here. Remember incoming value. + I->Value = IDomValue.first; + + // If the IDomValue is killed in the block, don't propagate through. + if (I->Kill.isValid()) + continue; + + // Propagate IDomValue if it isn't killed: + // MBB is live-out and doesn't define its own value. + if (LOP.first == IDomValue.first) + continue; + ++Changes; + LOP = IDomValue; + } + } + } while (Changes); +} diff --git a/lib/CodeGen/LiveRangeCalc.h b/lib/CodeGen/LiveRangeCalc.h new file mode 100644 index 000000000000..b8c8585846fa --- /dev/null +++ b/lib/CodeGen/LiveRangeCalc.h @@ -0,0 +1,226 @@ +//===---- LiveRangeCalc.h - Calculate live ranges ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The LiveRangeCalc class can be used to compute live ranges from scratch. It +// caches information about values in the CFG to speed up repeated operations +// on the same live range. The cache can be shared by non-overlapping live +// ranges. SplitKit uses that when computing the live range of split products. +// +// A low-level interface is available to clients that know where a variable is +// live, but don't know which value it has as every point. LiveRangeCalc will +// propagate values down the dominator tree, and even insert PHI-defs where +// needed. SplitKit uses this faster interface when possible. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_LIVERANGECALC_H +#define LLVM_CODEGEN_LIVERANGECALC_H + +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/IndexedMap.h" +#include "llvm/CodeGen/LiveInterval.h" + +namespace llvm { + +/// Forward declarations for MachineDominators.h: +class MachineDominatorTree; +template class DomTreeNodeBase; +typedef DomTreeNodeBase MachineDomTreeNode; + +class LiveRangeCalc { + /// Seen - Bit vector of active entries in LiveOut, also used as a visited + /// set by findReachingDefs. One entry per basic block, indexed by block + /// number. This is kept as a separate bit vector because it can be cleared + /// quickly when switching live ranges. + BitVector Seen; + + /// LiveOutPair - A value and the block that defined it. The domtree node is + /// redundant, it can be computed as: MDT[Indexes.getMBBFromIndex(VNI->def)]. + typedef std::pair LiveOutPair; + + /// LiveOutMap - Map basic blocks to the value leaving the block. + typedef IndexedMap LiveOutMap; + + /// LiveOut - Map each basic block where a live range is live out to the + /// live-out value and its defining block. + /// + /// For every basic block, MBB, one of these conditions shall be true: + /// + /// 1. !Seen.count(MBB->getNumber()) + /// Blocks without a Seen bit are ignored. + /// 2. LiveOut[MBB].second.getNode() == MBB + /// The live-out value is defined in MBB. + /// 3. forall P in preds(MBB): LiveOut[P] == LiveOut[MBB] + /// The live-out value passses through MBB. All predecessors must carry + /// the same value. + /// + /// The domtree node may be null, it can be computed. + /// + /// The map can be shared by multiple live ranges as long as no two are + /// live-out of the same block. + LiveOutMap LiveOut; + + /// LiveInBlock - Information about a basic block where a live range is known + /// to be live-in, but the value has not yet been determined. + struct LiveInBlock { + // LI - The live range that is live-in to this block. The algorithms can + // handle multiple non-overlapping live ranges simultaneously. + LiveInterval *LI; + + // DomNode - Dominator tree node for the block. + // Cleared when the final value has been determined and LI has been updated. + MachineDomTreeNode *DomNode; + + // Position in block where the live-in range ends, or SlotIndex() if the + // range passes through the block. When the final value has been + // determined, the range from the block start to Kill will be added to LI. + SlotIndex Kill; + + // Live-in value filled in by updateSSA once it is known. + VNInfo *Value; + + LiveInBlock(LiveInterval *li, MachineDomTreeNode *node, SlotIndex kill) + : LI(li), DomNode(node), Kill(kill), Value(0) {} + }; + + /// LiveIn - Work list of blocks where the live-in value has yet to be + /// determined. This list is typically computed by findReachingDefs() and + /// used as a work list by updateSSA(). The low-level interface may also be + /// used to add entries directly. + SmallVector LiveIn; + + /// findReachingDefs - Assuming that LI is live-in to KillMBB and killed at + /// Kill, search for values that can reach KillMBB. All blocks that need LI + /// to be live-in are added to LiveIn. If a unique reaching def is found, + /// its value is returned, if Kill is jointly dominated by multiple values, + /// NULL is returned. + VNInfo *findReachingDefs(LiveInterval *LI, + MachineBasicBlock *KillMBB, + SlotIndex Kill, + SlotIndexes *Indexes, + MachineDominatorTree *DomTree); + + /// updateSSA - Compute the values that will be live in to all requested + /// blocks in LiveIn. Create PHI-def values as required to preserve SSA form. + /// + /// Every live-in block must be jointly dominated by the added live-out + /// blocks. No values are read from the live ranges. + void updateSSA(SlotIndexes *Indexes, + MachineDominatorTree *DomTree, + VNInfo::Allocator *Alloc); + + /// updateLiveIns - Add liveness as specified in the LiveIn vector, using VNI + /// as a wildcard value for LiveIn entries without a value. + void updateLiveIns(VNInfo *VNI, SlotIndexes*); + +public: + //===--------------------------------------------------------------------===// + // High-level interface. + //===--------------------------------------------------------------------===// + // + // Calculate live ranges from scratch. + // + + /// reset - Prepare caches for a new set of non-overlapping live ranges. The + /// caches must be reset before attempting calculations with a live range + /// that may overlap a previously computed live range, and before the first + /// live range in a function. If live ranges are not known to be + /// non-overlapping, call reset before each. + void reset(const MachineFunction *MF); + + /// calculate - Calculate the live range of a virtual register from its defs + /// and uses. LI must be empty with no values. + void calculate(LiveInterval *LI, + MachineRegisterInfo *MRI, + SlotIndexes *Indexes, + VNInfo::Allocator *Alloc); + + //===--------------------------------------------------------------------===// + // Mid-level interface. + //===--------------------------------------------------------------------===// + // + // Modify existing live ranges. + // + + /// extend - Extend the live range of LI to reach Kill. + /// + /// The existing values in LI must be live so they jointly dominate Kill. If + /// Kill is not dominated by a single existing value, PHI-defs are inserted + /// as required to preserve SSA form. If Kill is known to be dominated by a + /// single existing value, Alloc may be null. + void extend(LiveInterval *LI, + SlotIndex Kill, + SlotIndexes *Indexes, + MachineDominatorTree *DomTree, + VNInfo::Allocator *Alloc); + + /// extendToUses - Extend the live range of LI to reach all uses. + /// + /// All uses must be jointly dominated by existing liveness. PHI-defs are + /// inserted as needed to preserve SSA form. + void extendToUses(LiveInterval *LI, + MachineRegisterInfo *MRI, + SlotIndexes *Indexes, + MachineDominatorTree *DomTree, + VNInfo::Allocator *Alloc); + + //===--------------------------------------------------------------------===// + // Low-level interface. + //===--------------------------------------------------------------------===// + // + // These functions can be used to compute live ranges where the live-in and + // live-out blocks are already known, but the SSA value in each block is + // unknown. + // + // After calling reset(), add known live-out values and known live-in blocks. + // Then call calculateValues() to compute the actual value that is + // live-in to each block, and add liveness to the live ranges. + // + + /// setLiveOutValue - Indicate that VNI is live out from MBB. The + /// calculateValues() function will not add liveness for MBB, the caller + /// should take care of that. + /// + /// VNI may be null only if MBB is a live-through block also passed to + /// addLiveInBlock(). + void setLiveOutValue(MachineBasicBlock *MBB, VNInfo *VNI) { + Seen.set(MBB->getNumber()); + LiveOut[MBB] = LiveOutPair(VNI, (MachineDomTreeNode *)0); + } + + /// addLiveInBlock - Add a block with an unknown live-in value. This + /// function can only be called once per basic block. Once the live-in value + /// has been determined, calculateValues() will add liveness to LI. + /// + /// @param LI The live range that is live-in to the block. + /// @param DomNode The domtree node for the block. + /// @param Kill Index in block where LI is killed. If the value is + /// live-through, set Kill = SLotIndex() and also call + /// setLiveOutValue(MBB, 0). + void addLiveInBlock(LiveInterval *LI, + MachineDomTreeNode *DomNode, + SlotIndex Kill = SlotIndex()) { + LiveIn.push_back(LiveInBlock(LI, DomNode, Kill)); + } + + /// calculateValues - Calculate the value that will be live-in to each block + /// added with addLiveInBlock. Add PHI-def values as needed to preserve SSA + /// form. Add liveness to all live-in blocks up to the Kill point, or the + /// whole block for live-through blocks. + /// + /// Every predecessor of a live-in block must have been given a value with + /// setLiveOutValue, the value may be null for live-trough blocks. + void calculateValues(SlotIndexes *Indexes, + MachineDominatorTree *DomTree, + VNInfo::Allocator *Alloc); +}; + +} // end namespace llvm + +#endif diff --git a/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp index b385fb36bbf1..b23f85165360 100644 --- a/lib/CodeGen/LiveRangeEdit.cpp +++ b/lib/CodeGen/LiveRangeEdit.cpp @@ -319,9 +319,12 @@ void LiveRangeEdit::calculateRegClassAndHint(MachineFunction &MF, LiveIntervals &LIS, const MachineLoopInfo &Loops) { VirtRegAuxInfo VRAI(MF, LIS, Loops); + MachineRegisterInfo &MRI = MF.getRegInfo(); for (iterator I = begin(), E = end(); I != E; ++I) { LiveInterval &LI = **I; - VRAI.CalculateRegClass(LI.reg); + if (MRI.recomputeRegClass(LI.reg, MF.getTarget())) + DEBUG(dbgs() << "Inflated " << PrintReg(LI.reg) << " to " + << MRI.getRegClass(LI.reg)->getName() << '\n'); VRAI.CalculateWeightAndHint(LI); } } diff --git a/lib/CodeGen/LiveRangeEdit.h b/lib/CodeGen/LiveRangeEdit.h index db6740c1fbcd..9b0a671ea9e5 100644 --- a/lib/CodeGen/LiveRangeEdit.h +++ b/lib/CodeGen/LiveRangeEdit.h @@ -115,7 +115,7 @@ class LiveRangeEdit { LiveInterval *get(unsigned idx) const { return newRegs_[idx+firstNew_]; } ArrayRef regs() const { - return ArrayRef(newRegs_).slice(firstNew_); + return makeArrayRef(newRegs_).slice(firstNew_); } /// FIXME: Temporary accessors until we can get rid of diff --git a/lib/CodeGen/LiveStackAnalysis.cpp b/lib/CodeGen/LiveStackAnalysis.cpp index c75196a47210..939e795b4a38 100644 --- a/lib/CodeGen/LiveStackAnalysis.cpp +++ b/lib/CodeGen/LiveStackAnalysis.cpp @@ -44,7 +44,8 @@ void LiveStacks::releaseMemory() { S2RCMap.clear(); } -bool LiveStacks::runOnMachineFunction(MachineFunction &) { +bool LiveStacks::runOnMachineFunction(MachineFunction &MF) { + TRI = MF.getTarget().getRegisterInfo(); // FIXME: No analysis is being done right now. We are relying on the // register allocators to provide the information. return false; @@ -61,7 +62,7 @@ LiveStacks::getOrCreateInterval(int Slot, const TargetRegisterClass *RC) { } else { // Use the largest common subclass register class. const TargetRegisterClass *OldRC = S2RCMap[Slot]; - S2RCMap[Slot] = getCommonSubClass(OldRC, RC); + S2RCMap[Slot] = TRI->getCommonSubClass(OldRC, RC); } return I->second; } diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp index 20bad60dedda..2ca90f9f05c0 100644 --- a/lib/CodeGen/LiveVariables.cpp +++ b/lib/CodeGen/LiveVariables.cpp @@ -662,7 +662,7 @@ void LiveVariables::removeVirtualRegistersKilled(MachineInstr *MI) { if (TargetRegisterInfo::isVirtualRegister(Reg)) { bool removed = getVarInfo(Reg).removeKill(MI); assert(removed && "kill not in register's VarInfo?"); - removed = true; + (void)removed; } } } diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index 8f0fb46879ac..4c5fe4c480a6 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -571,6 +571,11 @@ MachineBasicBlock::SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P) { if (i->getOperand(ni+1).getMBB() == this) i->getOperand(ni+1).setMBB(NMBB); + // Inherit live-ins from the successor + for (MachineBasicBlock::livein_iterator I = Succ->livein_begin(), + E = Succ->livein_end(); I != E; ++I) + NMBB->addLiveIn(*I); + // Update LiveVariables. if (LV) { // Restore kills of virtual registers that were killed by the terminators. diff --git a/lib/CodeGen/MachineBlockFrequency.cpp b/lib/CodeGen/MachineBlockFrequencyInfo.cpp similarity index 51% rename from lib/CodeGen/MachineBlockFrequency.cpp rename to lib/CodeGen/MachineBlockFrequencyInfo.cpp index 893a320a6a63..b92cda961474 100644 --- a/lib/CodeGen/MachineBlockFrequency.cpp +++ b/lib/CodeGen/MachineBlockFrequencyInfo.cpp @@ -1,4 +1,4 @@ -//====----- MachineBlockFrequency.cpp - Machine Block Frequency Analysis ----====// +//====----- MachineBlockFrequencyInfo.cpp - Machine Block Frequency Analysis ----====// // // The LLVM Compiler Infrastructure // @@ -13,47 +13,49 @@ #include "llvm/InitializePasses.h" #include "llvm/Analysis/BlockFrequencyImpl.h" -#include "llvm/CodeGen/MachineBlockFrequency.h" +#include "llvm/CodeGen/MachineBlockFrequencyInfo.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" using namespace llvm; -INITIALIZE_PASS_BEGIN(MachineBlockFrequency, "machine-block-freq", +INITIALIZE_PASS_BEGIN(MachineBlockFrequencyInfo, "machine-block-freq", "Machine Block Frequency Analysis", true, true) INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) -INITIALIZE_PASS_END(MachineBlockFrequency, "machine-block-freq", +INITIALIZE_PASS_END(MachineBlockFrequencyInfo, "machine-block-freq", "Machine Block Frequency Analysis", true, true) -char MachineBlockFrequency::ID = 0; +char MachineBlockFrequencyInfo::ID = 0; -MachineBlockFrequency::MachineBlockFrequency() : MachineFunctionPass(ID) { - initializeMachineBlockFrequencyPass(*PassRegistry::getPassRegistry()); +MachineBlockFrequencyInfo::MachineBlockFrequencyInfo() : MachineFunctionPass(ID) { + initializeMachineBlockFrequencyInfoPass(*PassRegistry::getPassRegistry()); MBFI = new BlockFrequencyImpl(); } -MachineBlockFrequency::~MachineBlockFrequency() { +MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() { delete MBFI; } -void MachineBlockFrequency::getAnalysisUsage(AnalysisUsage &AU) const { +void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); } -bool MachineBlockFrequency::runOnMachineFunction(MachineFunction &F) { +bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) { MachineBranchProbabilityInfo &MBPI = getAnalysis(); MBFI->doFunction(&F, &MBPI); return false; } -/// getblockFreq - Return block frequency. Never return 0, value must be -/// positive. Please note that initial frequency is equal to 1024. It means that -/// we should not rely on the value itself, but only on the comparison to the -/// other block frequencies. We do this to avoid using of floating points. +/// getblockFreq - Return block frequency. Return 0 if we don't have the +/// information. Please note that initial frequency is equal to 1024. It means +/// that we should not rely on the value itself, but only on the comparison to +/// the other block frequencies. We do this to avoid using of floating points. /// -uint32_t MachineBlockFrequency::getBlockFreq(MachineBasicBlock *MBB) { +BlockFrequency MachineBlockFrequencyInfo:: +getBlockFreq(MachineBasicBlock *MBB) const { return MBFI->getBlockFreq(MBB); } diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp index 3a60a37af443..7eda8c129dc4 100644 --- a/lib/CodeGen/MachineCSE.cpp +++ b/lib/CodeGen/MachineCSE.cpp @@ -430,13 +430,24 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) { unsigned NewReg = CSMI->getOperand(i).getReg(); if (OldReg == NewReg) continue; + assert(TargetRegisterInfo::isVirtualRegister(OldReg) && TargetRegisterInfo::isVirtualRegister(NewReg) && "Do not CSE physical register defs!"); + if (!isProfitableToCSE(NewReg, OldReg, CSMI, MI)) { DoCSE = false; break; } + + // Don't perform CSE if the result of the old instruction cannot exist + // within the register class of the new instruction. + const TargetRegisterClass *OldRC = MRI->getRegClass(OldReg); + if (!MRI->constrainRegClass(NewReg, OldRC)) { + DoCSE = false; + break; + } + CSEPairs.push_back(std::make_pair(OldReg, NewReg)); --NumDefs; } diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index cd2515652831..20066a067b8f 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -619,7 +619,7 @@ void MachineJumpTableInfo::dump() const { print(dbgs()); } // MachineConstantPool implementation //===----------------------------------------------------------------------===// -const Type *MachineConstantPoolEntry::getType() const { +Type *MachineConstantPoolEntry::getType() const { if (isMachineConstantPoolEntry()) return Val.MachineCPVal->getType(); return Val.ConstVal->getType(); diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 143a29b08a1e..a240667f7d6a 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -51,7 +51,7 @@ using namespace llvm; /// explicitly nulled out. void MachineOperand::AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo) { assert(isReg() && "Can only add reg operand to use lists"); - + // If the reginfo pointer is null, just explicitly null out or next/prev // pointers, to ensure they are not garbage. if (RegInfo == 0) { @@ -59,23 +59,23 @@ void MachineOperand::AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo) { Contents.Reg.Next = 0; return; } - + // Otherwise, add this operand to the head of the registers use/def list. MachineOperand **Head = &RegInfo->getRegUseDefListHead(getReg()); - + // For SSA values, we prefer to keep the definition at the start of the list. // we do this by skipping over the definition if it is at the head of the // list. if (*Head && (*Head)->isDef()) Head = &(*Head)->Contents.Reg.Next; - + Contents.Reg.Next = *Head; if (Contents.Reg.Next) { assert(getReg() == Contents.Reg.Next->getReg() && "Different regs on the same list!"); Contents.Reg.Next->Contents.Reg.Prev = &Contents.Reg.Next; } - + Contents.Reg.Prev = Head; *Head = this; } @@ -86,7 +86,7 @@ void MachineOperand::RemoveRegOperandFromRegInfo() { assert(isOnRegUseList() && "Reg operand is not on a use list"); // Unlink this from the doubly linked list of operands. MachineOperand *NextOp = Contents.Reg.Next; - *Contents.Reg.Prev = NextOp; + *Contents.Reg.Prev = NextOp; if (NextOp) { assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!"); NextOp->Contents.Reg.Prev = Contents.Reg.Prev; @@ -97,7 +97,7 @@ void MachineOperand::RemoveRegOperandFromRegInfo() { void MachineOperand::setReg(unsigned Reg) { if (getReg() == Reg) return; // No change. - + // Otherwise, we have to change the register. If this operand is embedded // into a machine function, we need to update the old and new register's // use/def lists. @@ -109,7 +109,7 @@ void MachineOperand::setReg(unsigned Reg) { AddRegOperandToRegInfo(&MF->getRegInfo()); return; } - + // Otherwise, just change the register, no problem. :) SmallContents.RegNo = Reg; } @@ -144,7 +144,7 @@ void MachineOperand::ChangeToImmediate(int64_t ImmVal) { if (isReg() && getParent() && getParent()->getParent() && getParent()->getParent()->getParent()) RemoveRegOperandFromRegInfo(); - + OpKind = MO_Immediate; Contents.ImmVal = ImmVal; } @@ -155,7 +155,7 @@ void MachineOperand::ChangeToImmediate(int64_t ImmVal) { void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, bool isKill, bool isDead, bool isUndef, bool isDebug) { - // If this operand is already a register operand, use setReg to update the + // If this operand is already a register operand, use setReg to update the // register's use/def lists. if (isReg()) { assert(!isEarlyClobber()); @@ -189,7 +189,7 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { if (getType() != Other.getType() || getTargetFlags() != Other.getTargetFlags()) return false; - + switch (getType()) { default: llvm_unreachable("Unrecognized operand type"); case MachineOperand::MO_Register: @@ -322,7 +322,7 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { default: llvm_unreachable("Unrecognized operand type"); } - + if (unsigned TF = getTargetFlags()) OS << "[TF=" << TF << ']'; } @@ -408,7 +408,7 @@ uint64_t MachineMemOperand::getAlignment() const { raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { assert((MMO.isLoad() || MMO.isStore()) && "SV has to be a load, store or both."); - + if (MMO.isVolatile()) OS << "Volatile "; @@ -417,7 +417,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { if (MMO.isStore()) OS << "ST"; OS << MMO.getSize(); - + // Print the address information. OS << "["; if (!MMO.getValue()) @@ -464,7 +464,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { /// MachineInstr ctor - This constructor creates a dummy MachineInstr with /// MCID NULL and no operands. MachineInstr::MachineInstr() - : MCID(0), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), + : MCID(0), Flags(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), Parent(0) { // Make sure that we get added to a machine basicblock @@ -484,8 +484,9 @@ void MachineInstr::addImplicitDefUseOperands() { /// implicit operands. It reserves space for the number of operands specified by /// the MCInstrDesc. MachineInstr::MachineInstr(const MCInstrDesc &tid, bool NoImp) - : MCID(&tid), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), + : MCID(&tid), Flags(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), Parent(0) { + unsigned NumImplicitOps = 0; if (!NoImp) NumImplicitOps = MCID->getNumImplicitDefs() + MCID->getNumImplicitUses(); Operands.reserve(NumImplicitOps + MCID->getNumOperands()); @@ -498,8 +499,9 @@ MachineInstr::MachineInstr(const MCInstrDesc &tid, bool NoImp) /// MachineInstr ctor - As above, but with a DebugLoc. MachineInstr::MachineInstr(const MCInstrDesc &tid, const DebugLoc dl, bool NoImp) - : MCID(&tid), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), + : MCID(&tid), Flags(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), Parent(0), debugLoc(dl) { + unsigned NumImplicitOps = 0; if (!NoImp) NumImplicitOps = MCID->getNumImplicitDefs() + MCID->getNumImplicitUses(); Operands.reserve(NumImplicitOps + MCID->getNumOperands()); @@ -510,13 +512,14 @@ MachineInstr::MachineInstr(const MCInstrDesc &tid, const DebugLoc dl, } /// MachineInstr ctor - Work exactly the same as the ctor two above, except -/// that the MachineInstr is created and added to the end of the specified +/// that the MachineInstr is created and added to the end of the specified /// basic block. MachineInstr::MachineInstr(MachineBasicBlock *MBB, const MCInstrDesc &tid) - : MCID(&tid), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), + : MCID(&tid), Flags(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), Parent(0) { assert(MBB && "Cannot use inserting ctor with null basic block!"); - NumImplicitOps = MCID->getNumImplicitDefs() + MCID->getNumImplicitUses(); + unsigned NumImplicitOps = + MCID->getNumImplicitDefs() + MCID->getNumImplicitUses(); Operands.reserve(NumImplicitOps + MCID->getNumOperands()); addImplicitDefUseOperands(); // Make sure that we get added to a machine basicblock @@ -528,10 +531,11 @@ MachineInstr::MachineInstr(MachineBasicBlock *MBB, const MCInstrDesc &tid) /// MachineInstr::MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, const MCInstrDesc &tid) - : MCID(&tid), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), + : MCID(&tid), Flags(0), AsmPrinterFlags(0), MemRefs(0), MemRefsEnd(0), Parent(0), debugLoc(dl) { assert(MBB && "Cannot use inserting ctor with null basic block!"); - NumImplicitOps = MCID->getNumImplicitDefs() + MCID->getNumImplicitUses(); + unsigned NumImplicitOps = + MCID->getNumImplicitDefs() + MCID->getNumImplicitUses(); Operands.reserve(NumImplicitOps + MCID->getNumOperands()); addImplicitDefUseOperands(); // Make sure that we get added to a machine basicblock @@ -542,7 +546,7 @@ MachineInstr::MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, /// MachineInstr ctor - Copies MachineInstr arg exactly /// MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) - : MCID(&MI.getDesc()), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), + : MCID(&MI.getDesc()), Flags(0), AsmPrinterFlags(0), MemRefs(MI.MemRefs), MemRefsEnd(MI.MemRefsEnd), Parent(0), debugLoc(MI.getDebugLoc()) { Operands.reserve(MI.getNumOperands()); @@ -550,7 +554,6 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) // Add operands for (unsigned i = 0; i != MI.getNumOperands(); ++i) addOperand(MI.getOperand(i)); - NumImplicitOps = MI.NumImplicitOps; // Copy all the flags. Flags = MI.Flags; @@ -605,102 +608,74 @@ void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo) { /// addOperand - Add the specified operand to the instruction. If it is an /// implicit operand, it is added to the end of the operand list. If it is /// an explicit operand it is added at the end of the explicit operand list -/// (before the first implicit operand). +/// (before the first implicit operand). void MachineInstr::addOperand(const MachineOperand &Op) { + assert(MCID && "Cannot add operands before providing an instr descriptor"); bool isImpReg = Op.isReg() && Op.isImplicit(); - assert((isImpReg || !OperandsComplete()) && - "Trying to add an operand to a machine instr that is already done!"); - MachineRegisterInfo *RegInfo = getRegInfo(); - // If we are adding the operand to the end of the list, our job is simpler. - // This is true most of the time, so this is a reasonable optimization. - if (isImpReg || NumImplicitOps == 0) { - // We can only do this optimization if we know that the operand list won't - // reallocate. - if (Operands.empty() || Operands.size()+1 <= Operands.capacity()) { - Operands.push_back(Op); - - // Set the parent of the operand. - Operands.back().ParentMI = this; - - // If the operand is a register, update the operand's use list. - if (Op.isReg()) { - Operands.back().AddRegOperandToRegInfo(RegInfo); - // If the register operand is flagged as early, mark the operand as such - unsigned OpNo = Operands.size() - 1; - if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) - Operands[OpNo].setIsEarlyClobber(true); - } - return; + // If the Operands backing store is reallocated, all register operands must + // be removed and re-added to RegInfo. It is storing pointers to operands. + bool Reallocate = RegInfo && + !Operands.empty() && Operands.size() == Operands.capacity(); + + // Find the insert location for the new operand. Implicit registers go at + // the end, everything goes before the implicit regs. + unsigned OpNo = Operands.size(); + + // Remove all the implicit operands from RegInfo if they need to be shifted. + // FIXME: Allow mixed explicit and implicit operands on inline asm. + // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as + // implicit-defs, but they must not be moved around. See the FIXME in + // InstrEmitter.cpp. + if (!isImpReg && !isInlineAsm()) { + while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) { + --OpNo; + if (RegInfo) + Operands[OpNo].RemoveRegOperandFromRegInfo(); } } - - // Otherwise, we have to insert a real operand before any implicit ones. - unsigned OpNo = Operands.size()-NumImplicitOps; - // If this instruction isn't embedded into a function, then we don't need to - // update any operand lists. - if (RegInfo == 0) { - // Simple insertion, no reginfo update needed for other register operands. - Operands.insert(Operands.begin()+OpNo, Op); - Operands[OpNo].ParentMI = this; + // OpNo now points as the desired insertion point. Unless this is a variadic + // instruction, only implicit regs are allowed beyond MCID->getNumOperands(). + assert((isImpReg || MCID->isVariadic() || OpNo < MCID->getNumOperands()) && + "Trying to add an operand to a machine instr that is already done!"); - // Do explicitly set the reginfo for this operand though, to ensure the - // next/prev fields are properly nulled out. - if (Operands[OpNo].isReg()) { - Operands[OpNo].AddRegOperandToRegInfo(0); - // If the register operand is flagged as early, mark the operand as such - if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) - Operands[OpNo].setIsEarlyClobber(true); - } + // All operands from OpNo have been removed from RegInfo. If the Operands + // backing store needs to be reallocated, we also need to remove any other + // register operands. + if (Reallocate) + for (unsigned i = 0; i != OpNo; ++i) + if (Operands[i].isReg()) + Operands[i].RemoveRegOperandFromRegInfo(); - } else if (Operands.size()+1 <= Operands.capacity()) { - // Otherwise, we have to remove register operands from their register use - // list, add the operand, then add the register operands back to their use - // list. This also must handle the case when the operand list reallocates - // to somewhere else. - - // If insertion of this operand won't cause reallocation of the operand - // list, just remove the implicit operands, add the operand, then re-add all - // the rest of the operands. - for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) { - assert(Operands[i].isReg() && "Should only be an implicit reg!"); - Operands[i].RemoveRegOperandFromRegInfo(); - } - - // Add the operand. If it is a register, add it to the reg list. - Operands.insert(Operands.begin()+OpNo, Op); - Operands[OpNo].ParentMI = this; + // Insert the new operand at OpNo. + Operands.insert(Operands.begin() + OpNo, Op); + Operands[OpNo].ParentMI = this; - if (Operands[OpNo].isReg()) { - Operands[OpNo].AddRegOperandToRegInfo(RegInfo); - // If the register operand is flagged as early, mark the operand as such - if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) - Operands[OpNo].setIsEarlyClobber(true); - } - - // Re-add all the implicit ops. - for (unsigned i = OpNo+1, e = Operands.size(); i != e; ++i) { + // The Operands backing store has now been reallocated, so we can re-add the + // operands before OpNo. + if (Reallocate) + for (unsigned i = 0; i != OpNo; ++i) + if (Operands[i].isReg()) + Operands[i].AddRegOperandToRegInfo(RegInfo); + + // When adding a register operand, tell RegInfo about it. + if (Operands[OpNo].isReg()) { + // Add the new operand to RegInfo, even when RegInfo is NULL. + // This will initialize the linked list pointers. + Operands[OpNo].AddRegOperandToRegInfo(RegInfo); + // If the register operand is flagged as early, mark the operand as such. + if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) + Operands[OpNo].setIsEarlyClobber(true); + } + + // Re-add all the implicit ops. + if (RegInfo) { + for (unsigned i = OpNo + 1, e = Operands.size(); i != e; ++i) { assert(Operands[i].isReg() && "Should only be an implicit reg!"); Operands[i].AddRegOperandToRegInfo(RegInfo); } - } else { - // Otherwise, we will be reallocating the operand list. Remove all reg - // operands from their list, then readd them after the operand list is - // reallocated. - RemoveRegOperandsFromUseLists(); - - Operands.insert(Operands.begin()+OpNo, Op); - Operands[OpNo].ParentMI = this; - - // Re-add all the operands. - AddRegOperandsToUseLists(*RegInfo); - - // If the register operand is flagged as early, mark the operand as such - if (Operands[OpNo].isReg() - && MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) - Operands[OpNo].setIsEarlyClobber(true); } } @@ -709,13 +684,13 @@ void MachineInstr::addOperand(const MachineOperand &Op) { /// void MachineInstr::RemoveOperand(unsigned OpNo) { assert(OpNo < Operands.size() && "Invalid operand number"); - + // Special case removing the last one. if (OpNo == Operands.size()-1) { // If needed, remove from the reg def/use list. if (Operands.back().isReg() && Operands.back().isOnRegUseList()) Operands.back().RemoveRegOperandFromRegInfo(); - + Operands.pop_back(); return; } @@ -730,7 +705,7 @@ void MachineInstr::RemoveOperand(unsigned OpNo) { Operands[i].RemoveRegOperandFromRegInfo(); } } - + Operands.erase(Operands.begin()+OpNo); if (RegInfo) { @@ -827,15 +802,6 @@ void MachineInstr::eraseFromParent() { } -/// OperandComplete - Return true if it's illegal to add a new operand -/// -bool MachineInstr::OperandsComplete() const { - unsigned short NumOperands = MCID->getNumOperands(); - if (!MCID->isVariadic() && getNumOperands()-NumImplicitOps >= NumOperands) - return true; // Broken: we have all the operands of this instruction! - return false; -} - /// getNumExplicitOperands - Returns the number of non-implicit operands. /// unsigned MachineInstr::getNumExplicitOperands() const { @@ -860,6 +826,67 @@ bool MachineInstr::isStackAligningInlineAsm() const { return false; } +int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx, + unsigned *GroupNo) const { + assert(isInlineAsm() && "Expected an inline asm instruction"); + assert(OpIdx < getNumOperands() && "OpIdx out of range"); + + // Ignore queries about the initial operands. + if (OpIdx < InlineAsm::MIOp_FirstOperand) + return -1; + + unsigned Group = 0; + unsigned NumOps; + for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; + i += NumOps) { + const MachineOperand &FlagMO = getOperand(i); + // If we reach the implicit register operands, stop looking. + if (!FlagMO.isImm()) + return -1; + NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); + if (i + NumOps > OpIdx) { + if (GroupNo) + *GroupNo = Group; + return i; + } + ++Group; + } + return -1; +} + +const TargetRegisterClass* +MachineInstr::getRegClassConstraint(unsigned OpIdx, + const TargetInstrInfo *TII, + const TargetRegisterInfo *TRI) const { + // Most opcodes have fixed constraints in their MCInstrDesc. + if (!isInlineAsm()) + return TII->getRegClass(getDesc(), OpIdx, TRI); + + if (!getOperand(OpIdx).isReg()) + return NULL; + + // For tied uses on inline asm, get the constraint from the def. + unsigned DefIdx; + if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx)) + OpIdx = DefIdx; + + // Inline asm stores register class constraints in the flag word. + int FlagIdx = findInlineAsmFlagIdx(OpIdx); + if (FlagIdx < 0) + return NULL; + + unsigned Flag = getOperand(FlagIdx).getImm(); + unsigned RCID; + if (InlineAsm::hasRegClassConstraint(Flag, RCID)) + return TRI->getRegClass(RCID); + + // Assume that all registers in a memory operand are pointers. + if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem) + return TRI->getPointerRegClass(); + + return NULL; +} + /// 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. @@ -901,7 +928,8 @@ MachineInstr::readsWritesVirtualRegister(unsigned Reg, Ops->push_back(i); if (MO.isUse()) Use |= !MO.isUndef(); - else if (MO.getSubReg()) + else if (MO.getSubReg() && !MO.isUndef()) + // A partial doesn't count as reading the register. PartDef = true; else FullDef = true; @@ -941,6 +969,10 @@ MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead, bool Overlap, /// operand list that is used to represent the predicate. It returns -1 if /// none is found. int MachineInstr::findFirstPredOperandIdx() const { + // Don't call MCID.findFirstPredOperandIdx() because this variant + // is sometimes called on an instruction that's not yet complete, and + // so the number of operands is less than the MCID indicates. In + // particular, the PTX target does this. const MCInstrDesc &MCID = getDesc(); if (MCID.isPredicable()) { for (unsigned i = 0, e = getNumOperands(); i != e; ++i) @@ -950,7 +982,7 @@ int MachineInstr::findFirstPredOperandIdx() const { return -1; } - + /// isRegTiedToUseOperand - Given the index of a register def operand, /// check if the register def is tied to a source operand, due to either /// two-address elimination or inline assembly constraints. Returns the @@ -964,23 +996,13 @@ isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const { return false; // Determine the actual operand index that corresponds to this index. unsigned DefNo = 0; - unsigned DefPart = 0; - for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); - i < e; ) { - const MachineOperand &FMO = getOperand(i); - // After the normal asm operands there may be additional imp-def regs. - if (!FMO.isImm()) - return false; - // Skip over this def. - unsigned NumOps = InlineAsm::getNumOperandRegisters(FMO.getImm()); - unsigned PrevDef = i + 1; - i = PrevDef + NumOps; - if (i > DefOpIdx) { - DefPart = DefOpIdx - PrevDef; - break; - } - ++DefNo; - } + int FlagIdx = findInlineAsmFlagIdx(DefOpIdx, &DefNo); + if (FlagIdx < 0) + return false; + + // Which part of the group is DefOpIdx? + unsigned DefPart = DefOpIdx - (FlagIdx + 1); + for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i != e; ++i) { const MachineOperand &FMO = getOperand(i); @@ -1024,20 +1046,10 @@ isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const { return false; // Find the flag operand corresponding to UseOpIdx - unsigned FlagIdx, NumOps=0; - for (FlagIdx = InlineAsm::MIOp_FirstOperand; - FlagIdx < UseOpIdx; FlagIdx += NumOps+1) { - const MachineOperand &UFMO = getOperand(FlagIdx); - // After the normal asm operands there may be additional imp-def regs. - if (!UFMO.isImm()) - return false; - NumOps = InlineAsm::getNumOperandRegisters(UFMO.getImm()); - assert(NumOps < getNumOperands() && "Invalid inline asm flag"); - if (UseOpIdx < FlagIdx+NumOps+1) - break; - } - if (FlagIdx >= UseOpIdx) + int FlagIdx = findInlineAsmFlagIdx(UseOpIdx); + if (FlagIdx < 0) return false; + const MachineOperand &UFMO = getOperand(FlagIdx); unsigned DefNo; if (InlineAsm::isUseOperandTiedToDef(UFMO.getImm(), DefNo)) { @@ -1211,7 +1223,7 @@ bool MachineInstr::hasVolatileMemoryRef() const { // conservatively assume it wasn't preserved. if (memoperands_empty()) return true; - + // Check the memory reference information for volatile references. for (mmo_iterator I = memoperands_begin(), E = memoperands_end(); I != E; ++I) if ((*I)->isVolatile()) @@ -1318,7 +1330,7 @@ void MachineInstr::dump() const { dbgs() << " " << *this; } -static void printDebugLoc(DebugLoc DL, const MachineFunction *MF, +static void printDebugLoc(DebugLoc DL, const MachineFunction *MF, raw_ostream &CommentOS) { const LLVMContext &Ctx = MF->getFunction()->getContext(); if (!DL.isUnknown()) { // Print source line info. @@ -1380,7 +1392,7 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { unsigned AsmDescOp = ~0u; unsigned AsmOpCount = 0; - if (isInlineAsm()) { + if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) { // Print asm string. OS << " "; getOperand(InlineAsm::MIOp_AsmString).print(OS, TM); @@ -1451,18 +1463,28 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { OS << '$' << AsmOpCount++; unsigned Flag = MO.getImm(); switch (InlineAsm::getKind(Flag)) { - case InlineAsm::Kind_RegUse: OS << ":[reguse]"; break; - case InlineAsm::Kind_RegDef: OS << ":[regdef]"; break; - case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec]"; break; - case InlineAsm::Kind_Clobber: OS << ":[clobber]"; break; - case InlineAsm::Kind_Imm: OS << ":[imm]"; break; - case InlineAsm::Kind_Mem: OS << ":[mem]"; break; - default: OS << ":[??" << InlineAsm::getKind(Flag) << ']'; break; + case InlineAsm::Kind_RegUse: OS << ":[reguse"; break; + case InlineAsm::Kind_RegDef: OS << ":[regdef"; break; + case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec"; break; + case InlineAsm::Kind_Clobber: OS << ":[clobber"; break; + case InlineAsm::Kind_Imm: OS << ":[imm"; break; + case InlineAsm::Kind_Mem: OS << ":[mem"; break; + default: OS << ":[??" << InlineAsm::getKind(Flag); break; + } + + unsigned RCID = 0; + if (InlineAsm::hasRegClassConstraint(Flag, RCID)) { + if (TM) + OS << ':' << TM->getRegisterInfo()->getRegClass(RCID)->getName(); + else + OS << ":RC" << RCID; } unsigned TiedTo = 0; if (InlineAsm::isUseOperandTiedToDef(Flag, TiedTo)) - OS << " [tiedto:$" << TiedTo << ']'; + OS << " tiedto:$" << TiedTo; + + OS << ']'; // Compute the index of the next operand descriptor. AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag); @@ -1516,7 +1538,19 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { } // Print debug location information. - if (!debugLoc.isUnknown() && MF) { + if (isDebugValue() && getOperand(e - 1).isMetadata()) { + if (!HaveSemi) OS << ";"; HaveSemi = true; + DIVariable DV(getOperand(e - 1).getMetadata()); + OS << " line no:" << DV.getLineNumber(); + if (MDNode *InlinedAt = DV.getInlinedAt()) { + DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt); + if (!InlinedAtDL.isUnknown()) { + OS << " inlined @[ "; + printDebugLoc(InlinedAtDL, MF, OS); + OS << " ]"; + } + } + } else if (!debugLoc.isUnknown() && MF) { if (!HaveSemi) OS << ";"; HaveSemi = true; OS << " dbg:"; printDebugLoc(debugLoc, MF, OS); @@ -1627,7 +1661,7 @@ bool MachineInstr::addRegisterDead(unsigned IncomingReg, // new implicit operand if required. if (Found || !AddIfNotFound) return Found; - + addOperand(MachineOperand::CreateReg(IncomingReg, true /*IsDef*/, true /*IsImp*/, diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp index 722ceb202439..a1f80d5282e0 100644 --- a/lib/CodeGen/MachineLICM.cpp +++ b/lib/CodeGen/MachineLICM.cpp @@ -37,10 +37,16 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; +static cl::opt +AvoidSpeculation("avoid-speculation", + cl::desc("MachineLICM should avoid speculation"), + cl::init(false), cl::Hidden); + STATISTIC(NumHoisted, "Number of machine instructions hoisted out of loops"); STATISTIC(NumLowRP, @@ -91,6 +97,17 @@ namespace { // For each opcode, keep a list of potential CSE instructions. DenseMap > CSEMap; + enum { + SpeculateFalse = 0, + SpeculateTrue = 1, + SpeculateUnknown = 2 + }; + + // If a MBB does not dominate loop exiting blocks then it may not safe + // to hoist loads from this block. + // Tri-state: 0 - false, 1 - true, 2 - unknown + unsigned SpeculationState; + public: static char ID; // Pass identification, replacement for typeid MachineLICM() : @@ -194,6 +211,10 @@ namespace { /// hoist the given loop invariant. bool IsProfitableToHoist(MachineInstr &MI); + /// IsGuaranteedToExecute - Check if this mbb is guaranteed to execute. + /// If not then a load from this mbb may not be safe to hoist. + bool IsGuaranteedToExecute(MachineBasicBlock *BB); + /// HoistRegion - Walk the specified region of the CFG (defined by all /// blocks dominated by the specified block, and that are in the current /// loop) in depth first order w.r.t the DominatorTree. This allows us to @@ -202,6 +223,13 @@ namespace { /// void HoistRegion(MachineDomTreeNode *N, bool IsHeader = false); + /// getRegisterClassIDAndCost - For a given MI, register, and the operand + /// index, return the ID and cost of its representative register class by + /// reference. + void getRegisterClassIDAndCost(const MachineInstr *MI, + unsigned Reg, unsigned OpIdx, + unsigned &RCId, unsigned &RCCost) const; + /// InitRegPressure - Find all virtual register references that are liveout /// of the preheader to initialize the starting "register pressure". Note /// this does not count live through (livein but not used) registers. @@ -229,6 +257,10 @@ namespace { bool EliminateCSE(MachineInstr *MI, DenseMap >::iterator &CI); + /// MayCSE - Return true if the given instruction will be CSE'd if it's + /// hoisted out of the loop. + bool MayCSE(MachineInstr *MI); + /// Hoist - When an instruction is found to only use loop invariant operands /// that is safe to hoist, this instruction is called to do the dirty work. /// It returns true if the instruction is hoisted. @@ -441,6 +473,12 @@ void MachineLICM::HoistRegionPostRA() { const std::vector Blocks = CurLoop->getBlocks(); for (unsigned i = 0, e = Blocks.size(); i != e; ++i) { MachineBasicBlock *BB = Blocks[i]; + + // If the header of the loop containing this basic block is a landing pad, + // then don't try to hoist instructions out of this loop. + const MachineLoop *ML = MLI->getLoopFor(BB); + if (ML && ML->getHeader()->isLandingPad()) continue; + // Conservatively treat live-in's as an external def. // FIXME: That means a reload that're reused in successor block(s) will not // be LICM'ed. @@ -452,6 +490,7 @@ void MachineLICM::HoistRegionPostRA() { ++PhysRegDefs[*AS]; } + SpeculationState = SpeculateUnknown; for (MachineBasicBlock::iterator MII = BB->begin(), E = BB->end(); MII != E; ++MII) { MachineInstr *MI = &*MII; @@ -545,6 +584,27 @@ void MachineLICM::HoistPostRA(MachineInstr *MI, unsigned Def) { Changed = true; } +// IsGuaranteedToExecute - Check if this mbb is guaranteed to execute. +// If not then a load from this mbb may not be safe to hoist. +bool MachineLICM::IsGuaranteedToExecute(MachineBasicBlock *BB) { + if (SpeculationState != SpeculateUnknown) + return SpeculationState == SpeculateFalse; + + if (BB != CurLoop->getHeader()) { + // Check loop exiting blocks. + SmallVector CurrentLoopExitingBlocks; + CurLoop->getExitingBlocks(CurrentLoopExitingBlocks); + for (unsigned i = 0, e = CurrentLoopExitingBlocks.size(); i != e; ++i) + if (!DT->dominates(BB, CurrentLoopExitingBlocks[i])) { + SpeculationState = SpeculateTrue; + return false; + } + } + + SpeculationState = SpeculateFalse; + return true; +} + /// HoistRegion - Walk the specified region of the CFG (defined by all blocks /// dominated by the specified block, and that are in the current loop) in depth /// first order w.r.t the DominatorTree. This allows us to visit definitions @@ -554,6 +614,11 @@ void MachineLICM::HoistRegion(MachineDomTreeNode *N, bool IsHeader) { assert(N != 0 && "Null dominator tree node?"); MachineBasicBlock *BB = N->getBlock(); + // If the header of the loop containing this basic block is a landing pad, + // then don't try to hoist instructions out of this loop. + const MachineLoop *ML = MLI->getLoopFor(BB); + if (ML && ML->getHeader()->isLandingPad()) return; + // If this subregion is not in the top level loop at all, exit. if (!CurLoop->contains(BB)) return; @@ -571,6 +636,7 @@ void MachineLICM::HoistRegion(MachineDomTreeNode *N, bool IsHeader) { // Remember livein register pressure. BackTrace.push_back(RegPressure); + SpeculationState = SpeculateUnknown; for (MachineBasicBlock::iterator MII = BB->begin(), E = BB->end(); MII != E; ) { MachineBasicBlock::iterator NextMII = MII; ++NextMII; @@ -596,6 +662,23 @@ static bool isOperandKill(const MachineOperand &MO, MachineRegisterInfo *MRI) { return MO.isKill() || MRI->hasOneNonDBGUse(MO.getReg()); } +/// getRegisterClassIDAndCost - For a given MI, register, and the operand +/// index, return the ID and cost of its representative register class. +void +MachineLICM::getRegisterClassIDAndCost(const MachineInstr *MI, + unsigned Reg, unsigned OpIdx, + unsigned &RCId, unsigned &RCCost) const { + const TargetRegisterClass *RC = MRI->getRegClass(Reg); + EVT VT = *RC->vt_begin(); + if (VT == MVT::untyped) { + RCId = RC->getID(); + RCCost = 1; + } else { + RCId = TLI->getRepRegClassFor(VT)->getID(); + RCCost = TLI->getRepRegClassCostFor(VT); + } +} + /// InitRegPressure - Find all virtual register references that are liveout of /// the preheader to initialize the starting "register pressure". Note this /// does not count live through (livein but not used) registers. @@ -625,18 +708,17 @@ void MachineLICM::InitRegPressure(MachineBasicBlock *BB) { continue; bool isNew = RegSeen.insert(Reg); - const TargetRegisterClass *RC = MRI->getRegClass(Reg); - EVT VT = *RC->vt_begin(); - unsigned RCId = TLI->getRepRegClassFor(VT)->getID(); + unsigned RCId, RCCost; + getRegisterClassIDAndCost(MI, Reg, i, RCId, RCCost); if (MO.isDef()) - RegPressure[RCId] += TLI->getRepRegClassCostFor(VT); + RegPressure[RCId] += RCCost; else { bool isKill = isOperandKill(MO, MRI); if (isNew && !isKill) // Haven't seen this, it must be a livein. - RegPressure[RCId] += TLI->getRepRegClassCostFor(VT); + RegPressure[RCId] += RCCost; else if (!isNew && isKill) - RegPressure[RCId] -= TLI->getRepRegClassCostFor(VT); + RegPressure[RCId] -= RCCost; } } } @@ -661,11 +743,8 @@ void MachineLICM::UpdateRegPressure(const MachineInstr *MI) { if (MO.isDef()) Defs.push_back(Reg); else if (!isNew && isOperandKill(MO, MRI)) { - const TargetRegisterClass *RC = MRI->getRegClass(Reg); - EVT VT = *RC->vt_begin(); - unsigned RCId = TLI->getRepRegClassFor(VT)->getID(); - unsigned RCCost = TLI->getRepRegClassCostFor(VT); - + unsigned RCId, RCCost; + getRegisterClassIDAndCost(MI, Reg, i, RCId, RCCost); if (RCCost > RegPressure[RCId]) RegPressure[RCId] = 0; else @@ -673,13 +752,13 @@ void MachineLICM::UpdateRegPressure(const MachineInstr *MI) { } } + unsigned Idx = 0; while (!Defs.empty()) { unsigned Reg = Defs.pop_back_val(); - const TargetRegisterClass *RC = MRI->getRegClass(Reg); - EVT VT = *RC->vt_begin(); - unsigned RCId = TLI->getRepRegClassFor(VT)->getID(); - unsigned RCCost = TLI->getRepRegClassCostFor(VT); + unsigned RCId, RCCost; + getRegisterClassIDAndCost(MI, Reg, Idx, RCId, RCCost); RegPressure[RCId] += RCCost; + ++Idx; } } @@ -691,7 +770,14 @@ bool MachineLICM::IsLICMCandidate(MachineInstr &I) { bool DontMoveAcrossStore = true; if (!I.isSafeToMove(TII, AA, DontMoveAcrossStore)) return false; - + + // If it is load then check if it is guaranteed to execute by making sure that + // it dominates all exiting blocks. If it doesn't, then there is a path out of + // the loop which does not execute this load, so we can't hoist it. + // Stores and side effects are already checked by isSafeToMove. + if (I.getDesc().mayLoad() && !IsGuaranteedToExecute(I.getParent())) + return false; + return true; } @@ -879,10 +965,8 @@ void MachineLICM::UpdateBackTraceRegPressure(const MachineInstr *MI) { if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; - const TargetRegisterClass *RC = MRI->getRegClass(Reg); - EVT VT = *RC->vt_begin(); - unsigned RCId = TLI->getRepRegClassFor(VT)->getID(); - unsigned RCCost = TLI->getRepRegClassCostFor(VT); + unsigned RCId, RCCost; + getRegisterClassIDAndCost(MI, Reg, i, RCId, RCCost); if (MO.isDef()) { DenseMap::iterator CI = Cost.find(RCId); if (CI != Cost.end()) @@ -941,16 +1025,15 @@ bool MachineLICM::IsProfitableToHoist(MachineInstr &MI) { unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; + + unsigned RCId, RCCost; + getRegisterClassIDAndCost(&MI, Reg, i, RCId, RCCost); if (MO.isDef()) { if (HasHighOperandLatency(MI, i, Reg)) { ++NumHighLatency; return true; } - const TargetRegisterClass *RC = MRI->getRegClass(Reg); - EVT VT = *RC->vt_begin(); - unsigned RCId = TLI->getRepRegClassFor(VT)->getID(); - unsigned RCCost = TLI->getRepRegClassCostFor(VT); DenseMap::iterator CI = Cost.find(RCId); if (CI != Cost.end()) CI->second += RCCost; @@ -960,10 +1043,6 @@ bool MachineLICM::IsProfitableToHoist(MachineInstr &MI) { // Is a virtual register use is a kill, hoisting it out of the loop // may actually reduce register pressure or be register pressure // neutral. - const TargetRegisterClass *RC = MRI->getRegClass(Reg); - EVT VT = *RC->vt_begin(); - unsigned RCId = TLI->getRepRegClassFor(VT)->getID(); - unsigned RCCost = TLI->getRepRegClassCostFor(VT); DenseMap::iterator CI = Cost.find(RCId); if (CI != Cost.end()) CI->second -= RCCost; @@ -979,6 +1058,13 @@ bool MachineLICM::IsProfitableToHoist(MachineInstr &MI) { return true; } + // Do not "speculate" in high register pressure situation. If an + // instruction is not guaranteed to be executed in the loop, it's best to be + // conservative. + if (AvoidSpeculation && + (!IsGuaranteedToExecute(MI.getParent()) && !MayCSE(&MI))) + return false; + // High register pressure situation, only hoist if the instruction is going to // be remat'ed. if (!TII->isTriviallyReMaterializable(&MI, AA) && @@ -1116,6 +1202,20 @@ bool MachineLICM::EliminateCSE(MachineInstr *MI, return false; } +/// MayCSE - Return true if the given instruction will be CSE'd if it's +/// hoisted out of the loop. +bool MachineLICM::MayCSE(MachineInstr *MI) { + unsigned Opcode = MI->getOpcode(); + DenseMap >::iterator + CI = CSEMap.find(Opcode); + // Do not CSE implicit_def so ProcessImplicitDefs can properly propagate + // the undef property onto uses. + if (CI == CSEMap.end() || MI->isImplicitDef()) + return false; + + return LookForDuplicate(MI, CI->second) != 0; +} + /// Hoist - When an instruction is found to use only loop invariant operands /// that are safe to hoist, this instruction is called to do the dirty work. /// diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index fadc594efcb2..80c4854238af 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -17,9 +17,7 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" +#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/Support/Dwarf.h" @@ -254,11 +252,12 @@ void MMIAddrLabelMapCallbackPtr::allUsesReplacedWith(Value *V2) { //===----------------------------------------------------------------------===// MachineModuleInfo::MachineModuleInfo(const MCAsmInfo &MAI, - const TargetAsmInfo *TAI) -: ImmutablePass(ID), Context(MAI, TAI), - ObjFileMMI(0), - CurCallSite(0), CallsEHReturn(0), CallsUnwindInit(0), DbgInfoAvailable(false), - CallsExternalVAFunctionWithFloatingPointArguments(false) { + const MCRegisterInfo &MRI, + const MCObjectFileInfo *MOFI) + : ImmutablePass(ID), Context(MAI, MRI, MOFI), + ObjFileMMI(0), CompactUnwindEncoding(0), CurCallSite(0), CallsEHReturn(0), + CallsUnwindInit(0), DbgInfoAvailable(false), + CallsExternalVAFunctionWithFloatingPointArguments(false) { initializeMachineModuleInfoPass(*PassRegistry::getPassRegistry()); // Always emit some info, by default "no personality" info. Personalities.push_back(NULL); @@ -267,7 +266,8 @@ MachineModuleInfo::MachineModuleInfo(const MCAsmInfo &MAI, } MachineModuleInfo::MachineModuleInfo() -: ImmutablePass(ID), Context(*(MCAsmInfo*)0, NULL) { + : ImmutablePass(ID), + Context(*(MCAsmInfo*)0, *(MCRegisterInfo*)0, (MCObjectFileInfo*)0) { assert(0 && "This MachineModuleInfo constructor should never be called, MMI " "should always be explicitly constructed by LLVMTargetMachine"); abort(); @@ -311,6 +311,7 @@ void MachineModuleInfo::EndFunction() { FilterEnds.clear(); CallsEHReturn = 0; CallsUnwindInit = 0; + CompactUnwindEncoding = 0; VariableDbgInfo.clear(); } @@ -426,8 +427,9 @@ void MachineModuleInfo::addPersonality(MachineBasicBlock *LandingPad, /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad. /// -void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad, - std::vector &TyInfo) { +void MachineModuleInfo:: +addCatchTypeInfo(MachineBasicBlock *LandingPad, + ArrayRef TyInfo) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); for (unsigned N = TyInfo.size(); N; --N) LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1])); @@ -435,8 +437,9 @@ void MachineModuleInfo::addCatchTypeInfo(MachineBasicBlock *LandingPad, /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad. /// -void MachineModuleInfo::addFilterTypeInfo(MachineBasicBlock *LandingPad, - std::vector &TyInfo) { +void MachineModuleInfo:: +addFilterTypeInfo(MachineBasicBlock *LandingPad, + ArrayRef TyInfo) { LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad); std::vector IdsInFilter(TyInfo.size()); for (unsigned I = 0, E = TyInfo.size(); I != E; ++I) @@ -496,6 +499,14 @@ void MachineModuleInfo::TidyLandingPads(DenseMap *LPMap) { } } +/// setCallSiteLandingPad - Map the landing pad's EH symbol to the call site +/// indexes. +void MachineModuleInfo::setCallSiteLandingPad(MCSymbol *Sym, + ArrayRef Sites) { + for (unsigned I = 0, E = Sites.size(); I != E; ++I) + LPadToCallSiteMap[Sym].push_back(Sites[I]); +} + /// getTypeIDFor - Return the type id for the specified typeinfo. This is /// function wide. unsigned MachineModuleInfo::getTypeIDFor(const GlobalVariable *TI) { diff --git a/lib/CodeGen/MachineRegisterInfo.cpp b/lib/CodeGen/MachineRegisterInfo.cpp index 4b3e64c25f60..266ebf64a3fc 100644 --- a/lib/CodeGen/MachineRegisterInfo.cpp +++ b/lib/CodeGen/MachineRegisterInfo.cpp @@ -14,10 +14,11 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Support/CommandLine.h" +#include "llvm/Target/TargetMachine.h" using namespace llvm; -MachineRegisterInfo::MachineRegisterInfo(const TargetRegisterInfo &TRI) { +MachineRegisterInfo::MachineRegisterInfo(const TargetRegisterInfo &TRI) + : TRI(&TRI), IsSSA(true) { VRegInfo.reserve(256); RegAllocHints.reserve(256); UsedPhysRegs.resize(TRI.getNumRegs()); @@ -48,18 +49,47 @@ MachineRegisterInfo::setRegClass(unsigned Reg, const TargetRegisterClass *RC) { const TargetRegisterClass * MachineRegisterInfo::constrainRegClass(unsigned Reg, - const TargetRegisterClass *RC) { + const TargetRegisterClass *RC, + unsigned MinNumRegs) { const TargetRegisterClass *OldRC = getRegClass(Reg); if (OldRC == RC) return RC; - const TargetRegisterClass *NewRC = getCommonSubClass(OldRC, RC); - if (!NewRC) + const TargetRegisterClass *NewRC = TRI->getCommonSubClass(OldRC, RC); + if (!NewRC || NewRC == OldRC) + return NewRC; + if (NewRC->getNumRegs() < MinNumRegs) return 0; - if (NewRC != OldRC) - setRegClass(Reg, NewRC); + setRegClass(Reg, NewRC); return NewRC; } +bool +MachineRegisterInfo::recomputeRegClass(unsigned Reg, const TargetMachine &TM) { + const TargetInstrInfo *TII = TM.getInstrInfo(); + const TargetRegisterClass *OldRC = getRegClass(Reg); + const TargetRegisterClass *NewRC = TRI->getLargestLegalSuperClass(OldRC); + + // Stop early if there is no room to grow. + if (NewRC == OldRC) + return false; + + // Accumulate constraints from all uses. + for (reg_nodbg_iterator I = reg_nodbg_begin(Reg), E = reg_nodbg_end(); I != E; + ++I) { + // TRI doesn't have accurate enough information to model this yet. + if (I.getOperand().getSubReg()) + return false; + const TargetRegisterClass *OpRC = + I->getRegClassConstraint(I.getOperandNo(), TII, TRI); + if (OpRC) + NewRC = TRI->getCommonSubClass(NewRC, OpRC); + if (!NewRC || NewRC == OldRC) + return false; + } + setRegClass(Reg, NewRC); + return true; +} + /// createVirtualRegister - Create and return a new virtual register in the /// function with the specified register class. /// diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp index 916dff70a41e..29cfb49953b9 100644 --- a/lib/CodeGen/MachineSink.cpp +++ b/lib/CodeGen/MachineSink.cpp @@ -382,6 +382,25 @@ static bool AvoidsSinking(MachineInstr *MI, MachineRegisterInfo *MRI) { return MI->isInsertSubreg() || MI->isSubregToReg() || MI->isRegSequence(); } +/// collectDebgValues - Scan instructions following MI and collect any +/// matching DBG_VALUEs. +static void collectDebugValues(MachineInstr *MI, + SmallVector & DbgValues) { + DbgValues.clear(); + if (!MI->getOperand(0).isReg()) + return; + + MachineBasicBlock::iterator DI = MI; ++DI; + for (MachineBasicBlock::iterator DE = MI->getParent()->end(); + DI != DE; ++DI) { + if (!DI->isDebugValue()) + return; + if (DI->getOperand(0).isReg() && + DI->getOperand(0).getReg() == MI->getOperand(0).getReg()) + DbgValues.push_back(DI); + } +} + /// SinkInstruction - Determine whether it is safe to sink the specified machine /// instruction out of its current block into a successor. bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) { @@ -598,10 +617,22 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) { while (InsertPos != SuccToSinkTo->end() && InsertPos->isPHI()) ++InsertPos; + // collect matching debug values. + SmallVector DbgValuesToSink; + collectDebugValues(MI, DbgValuesToSink); + // Move the instruction. SuccToSinkTo->splice(InsertPos, ParentBlock, MI, ++MachineBasicBlock::iterator(MI)); + // Move debug values. + for (SmallVector::iterator DBI = DbgValuesToSink.begin(), + DBE = DbgValuesToSink.end(); DBI != DBE; ++DBI) { + MachineInstr *DbgMI = *DBI; + SuccToSinkTo->splice(InsertPos, ParentBlock, DbgMI, + ++MachineBasicBlock::iterator(DbgMI)); + } + // Conservatively, clear any kill flags, since it's possible that they are no // longer correct. MI->clearKillInfo(); diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index 7a55852a1315..26847d39e7ad 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -72,6 +72,8 @@ namespace { typedef DenseSet RegSet; typedef DenseMap RegMap; + const MachineInstr *FirstTerminator; + BitVector regsReserved; RegSet regsLive; RegVector regsDefined, regsDead, regsKilled; @@ -389,6 +391,8 @@ static bool matchPair(MachineBasicBlock::const_succ_iterator i, void MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { + FirstTerminator = 0; + // Count the number of landing pad successors. SmallPtrSet LandingPadSuccs; for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(), @@ -570,6 +574,18 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { } } + // Ensure non-terminators don't follow terminators. + if (MCID.isTerminator()) { + if (!FirstTerminator) + FirstTerminator = MI; + } else if (FirstTerminator) { + report("Non-terminator instruction after the first terminator", MI); + *OS << "First terminator was:\t" << *FirstTerminator; + } + + StringRef ErrorInfo; + if (!TII->verifyInstruction(MI, ErrorInfo)) + report(ErrorInfo.data(), MI); } void @@ -686,6 +702,11 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { else addRegWithSubRegs(regsDefined, Reg); + // Verify SSA form. + if (MRI->isSSA() && TargetRegisterInfo::isVirtualRegister(Reg) && + llvm::next(MRI->def_begin(Reg)) != MRI->def_end()) + report("Multiple virtual register defs in SSA form", MO, MONum); + // Check LiveInts for a live range, but only for virtual registers. if (LiveInts && TargetRegisterInfo::isVirtualRegister(Reg) && !LiveInts->isNotInMIMap(MI)) { @@ -714,20 +735,14 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { unsigned SubIdx = MO->getSubReg(); if (TargetRegisterInfo::isPhysicalRegister(Reg)) { - unsigned sr = Reg; if (SubIdx) { - unsigned s = TRI->getSubReg(Reg, SubIdx); - if (!s) { - report("Invalid subregister index for physical register", - MO, MONum); - return; - } - sr = s; + report("Illegal subregister index for physical register", MO, MONum); + return; } if (const TargetRegisterClass *DRC = TII->getRegClass(MCID,MONum,TRI)) { - if (!DRC->contains(sr)) { + if (!DRC->contains(Reg)) { report("Illegal physical register for instruction", MO, MONum); - *OS << TRI->getName(sr) << " is not a " + *OS << TRI->getName(Reg) << " is not a " << DRC->getName() << " register.\n"; } } @@ -735,16 +750,35 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { // Virtual register. const TargetRegisterClass *RC = MRI->getRegClass(Reg); if (SubIdx) { - const TargetRegisterClass *SRC = RC->getSubRegisterRegClass(SubIdx); + const TargetRegisterClass *SRC = + TRI->getSubClassWithSubReg(RC, SubIdx); if (!SRC) { report("Invalid subregister index for virtual register", MO, MONum); *OS << "Register class " << RC->getName() << " does not support subreg index " << SubIdx << "\n"; return; } - RC = SRC; + if (RC != SRC) { + report("Invalid register class for subregister index", MO, MONum); + *OS << "Register class " << RC->getName() + << " does not fully support subreg index " << SubIdx << "\n"; + return; + } } if (const TargetRegisterClass *DRC = TII->getRegClass(MCID,MONum,TRI)) { + if (SubIdx) { + const TargetRegisterClass *SuperRC = + TRI->getLargestLegalSuperClass(RC); + if (!SuperRC) { + report("No largest legal super class exists.", MO, MONum); + return; + } + DRC = TRI->getMatchingSuperRegClass(SuperRC, DRC, SubIdx); + if (!DRC) { + report("No matching super-reg register class.", MO, MONum); + return; + } + } if (!RC->hasSuperClassEq(DRC)) { report("Illegal virtual register for instruction", MO, MONum); *OS << "Expected a " << DRC->getName() << " register, but got a " @@ -1161,18 +1195,8 @@ void MachineVerifier::verifyLiveIntervals() { SlotIndex PEnd = LiveInts->getMBBEndIdx(*PI).getPrevSlot(); const VNInfo *PVNI = LI.getVNInfoAt(PEnd); - if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI)) { - if (PVNI && !PVNI->hasPHIKill()) { - report("Value live out of predecessor doesn't have PHIKill", MF); - *OS << "Valno #" << PVNI->id << " live out of BB#" - << (*PI)->getNumber() << '@' << PEnd - << " doesn't have PHIKill, but Valno #" << VNI->id - << " is PHIDef and defined at the beginning of BB#" - << MFI->getNumber() << '@' << LiveInts->getMBBStartIdx(MFI) - << " in " << LI << '\n'; - } + if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI)) continue; - } if (!PVNI) { report("Register not marked live out of predecessor", *PI); diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp index af65f13bf065..6994aa58fbd5 100644 --- a/lib/CodeGen/PHIElimination.cpp +++ b/lib/CodeGen/PHIElimination.cpp @@ -109,6 +109,9 @@ bool PHIElimination::runOnMachineFunction(MachineFunction &MF) { bool Changed = false; + // This pass takes the function out of SSA form. + MRI->leaveSSA(); + // Split critical edges to help the coalescer if (!DisableEdgeSplitting) { if (LiveVariables *LV = getAnalysisIfAvailable()) { diff --git a/lib/CodeGen/PeepholeOptimizer.cpp b/lib/CodeGen/PeepholeOptimizer.cpp index c523e39bc258..bbc7ce2d0a42 100644 --- a/lib/CodeGen/PeepholeOptimizer.cpp +++ b/lib/CodeGen/PeepholeOptimizer.cpp @@ -295,7 +295,6 @@ bool PeepholeOptimizer::OptimizeBitcastInstr(MachineInstr *MI, if (!DefMI || !DefMI->getDesc().isBitcast()) return false; - unsigned SrcDef = 0; unsigned SrcSrc = 0; NumDefs = DefMI->getDesc().getNumDefs(); NumSrcs = DefMI->getDesc().getNumOperands() - NumDefs; @@ -308,13 +307,13 @@ bool PeepholeOptimizer::OptimizeBitcastInstr(MachineInstr *MI, unsigned Reg = MO.getReg(); if (!Reg) continue; - if (MO.isDef()) - SrcDef = Reg; - else if (SrcSrc) - // Multiple sources? - return false; - else - SrcSrc = Reg; + if (!MO.isDef()) { + if (SrcSrc) + // Multiple sources? + return false; + else + SrcSrc = Reg; + } } if (MRI->getRegClass(SrcSrc) != MRI->getRegClass(Def)) @@ -434,6 +433,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) { if (MCID.isBitcast()) { if (OptimizeBitcastInstr(MI, MBB)) { // MI is deleted. + LocalMIs.erase(MI); Changed = true; MII = First ? I->begin() : llvm::next(PMII); continue; @@ -441,6 +441,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) { } else if (MCID.isCompare()) { if (OptimizeCmpInstr(MI, MBB)) { // MI is deleted. + LocalMIs.erase(MI); Changed = true; MII = First ? I->begin() : llvm::next(PMII); continue; diff --git a/lib/CodeGen/ProcessImplicitDefs.cpp b/lib/CodeGen/ProcessImplicitDefs.cpp index c04d65637c94..b1d8c9760225 100644 --- a/lib/CodeGen/ProcessImplicitDefs.cpp +++ b/lib/CodeGen/ProcessImplicitDefs.cpp @@ -125,8 +125,14 @@ bool ProcessImplicitDefs::runOnMachineFunction(MachineFunction &fn) { LiveVariables::VarInfo& vi = LV->getVarInfo(MO.getReg()); vi.removeKill(MI); } + unsigned Reg = MI->getOperand(0).getReg(); MI->eraseFromParent(); Changed = true; + + // A REG_SEQUENCE may have been expanded into partial definitions. + // If this was the last one, mark Reg as implicitly defined. + if (TargetRegisterInfo::isVirtualRegister(Reg) && MRI->def_empty(Reg)) + ImpDefRegs.insert(Reg); continue; } } diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index a901c5fefa3e..32c932552bed 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -29,6 +29,7 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetInstrInfo.h" @@ -54,6 +55,8 @@ INITIALIZE_PASS_END(PEI, "prologepilog", STATISTIC(NumVirtualFrameRegs, "Number of virtual frame regs encountered"); STATISTIC(NumScavengedRegs, "Number of frame index regs scavenged"); +STATISTIC(NumBytesStackSpace, + "Number of bytes used for stack in all functions"); /// createPrologEpilogCodeInserter - This function returns a pass that inserts /// prolog and epilog code, and eliminates abstract frame references. @@ -677,7 +680,9 @@ void PEI::calculateFrameObjectOffsets(MachineFunction &Fn) { } // Update frame info to pretend that this is part of the stack... - MFI->setStackSize(Offset - LocalAreaOffset); + int64_t StackSize = Offset - LocalAreaOffset; + MFI->setStackSize(StackSize); + NumBytesStackSpace += StackSize; } /// insertPrologEpilogCode - Scan the function for modified callee saved @@ -696,6 +701,13 @@ void PEI::insertPrologEpilogCode(MachineFunction &Fn) { if (!I->empty() && I->back().getDesc().isReturn()) TFI.emitEpilogue(Fn, *I); } + + // Emit additional code that is required to support segmented stacks, if + // we've been asked for it. This, when linked with a runtime with support + // for segmented stacks (libgcc is one), will result in allocating stack + // space in small chunks instead of one large contiguous block. + if (EnableSegmentedStacks) + TFI.adjustForSegmentedStacks(Fn); } /// replaceFrameIndices - Replace all MO_FrameIndex operands with physical diff --git a/lib/CodeGen/RegAllocBasic.cpp b/lib/CodeGen/RegAllocBasic.cpp index 5ea26adc7644..5496d69fd3df 100644 --- a/lib/CodeGen/RegAllocBasic.cpp +++ b/lib/CodeGen/RegAllocBasic.cpp @@ -20,7 +20,6 @@ #include "RenderMachineFunction.h" #include "Spiller.h" #include "VirtRegMap.h" -#include "RegisterCoalescer.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" @@ -160,7 +159,7 @@ void RABasic::getAnalysisUsage(AnalysisUsage &AU) const { AU.addPreserved(); if (StrongPHIElim) AU.addRequiredID(StrongPHIEliminationID); - AU.addRequiredTransitive(); + AU.addRequiredTransitiveID(RegisterCoalescerPassID); AU.addRequired(); AU.addRequired(); AU.addPreserved(); @@ -439,6 +438,7 @@ void RegAllocBase::addMBBLiveIns(MachineFunction *MF) { LiveIntervalUnion &LiveUnion = PhysReg2LiveUnion[PhysReg]; if (LiveUnion.empty()) continue; + DEBUG(dbgs() << PrintReg(PhysReg, TRI) << " live-in:"); MachineFunction::iterator MBB = llvm::next(MF->begin()); MachineFunction::iterator MFE = MF->end(); SlotIndex Start, Stop; @@ -449,6 +449,8 @@ void RegAllocBase::addMBBLiveIns(MachineFunction *MF) { if (SI.start() <= Start) { if (!MBB->isLiveIn(PhysReg)) MBB->addLiveIn(PhysReg); + DEBUG(dbgs() << "\tBB#" << MBB->getNumber() << ':' + << PrintReg(SI.value()->reg, TRI)); } else if (SI.start() > Stop) MBB = Indexes->getMBBFromIndex(SI.start().getPrevIndex()); if (++MBB == MFE) @@ -456,6 +458,7 @@ void RegAllocBase::addMBBLiveIns(MachineFunction *MF) { tie(Start, Stop) = Indexes->getMBBRange(MBB); SI.advanceTo(Start); } + DEBUG(dbgs() << '\n'); } } @@ -495,8 +498,9 @@ unsigned RABasic::selectOrSplit(LiveInterval &VirtReg, // Found an available register. return PhysReg; } + Queries[interfReg].collectInterferingVRegs(1); LiveInterval *interferingVirtReg = - Queries[interfReg].firstInterference().liveUnionPos().value(); + Queries[interfReg].interferingVRegs().front(); // The current VirtReg must either be spillable, or one of its interferences // must have less spill weight. diff --git a/lib/CodeGen/RegAllocGreedy.cpp b/lib/CodeGen/RegAllocGreedy.cpp index e235e87b54f3..f54a2c85d100 100644 --- a/lib/CodeGen/RegAllocGreedy.cpp +++ b/lib/CodeGen/RegAllocGreedy.cpp @@ -22,7 +22,6 @@ #include "SpillPlacement.h" #include "SplitKit.h" #include "VirtRegMap.h" -#include "RegisterCoalescer.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Function.h" @@ -38,6 +37,7 @@ #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/RegAllocRegistry.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -51,6 +51,15 @@ STATISTIC(NumGlobalSplits, "Number of split global live ranges"); STATISTIC(NumLocalSplits, "Number of split local live ranges"); STATISTIC(NumEvicted, "Number of interferences evicted"); +static cl::opt +SplitSpillMode("split-spill-mode", cl::Hidden, + cl::desc("Spill mode for splitting live ranges"), + cl::values(clEnumValN(SplitEditor::SM_Partition, "default", "Default"), + clEnumValN(SplitEditor::SM_Size, "size", "Optimize for size"), + clEnumValN(SplitEditor::SM_Speed, "speed", "Optimize for speed"), + clEnumValEnd), + cl::init(SplitEditor::SM_Partition)); + static RegisterRegAlloc greedyRegAlloc("greedy", "greedy register allocator", createGreedyRegisterAllocator); @@ -90,12 +99,26 @@ class RAGreedy : public MachineFunctionPass, // range splitting algorithm terminates, something that is otherwise hard to // ensure. enum LiveRangeStage { - RS_New, ///< Never seen before. - RS_First, ///< First time in the queue. - RS_Second, ///< Second time in the queue. - RS_Global, ///< Produced by global splitting. - RS_Local, ///< Produced by local splitting. - RS_Spill ///< Produced by spilling. + /// Newly created live range that has never been queued. + RS_New, + + /// Only attempt assignment and eviction. Then requeue as RS_Split. + RS_Assign, + + /// Attempt live range splitting if assignment is impossible. + RS_Split, + + /// Attempt more aggressive live range splitting that is guaranteed to make + /// progress. This is used for split products that may not be making + /// progress. + RS_Split2, + + /// Live range will be spilled. No more splitting will be attempted. + RS_Spill, + + /// There is nothing more we can do to this live range. Abort compilation + /// if it can't be assigned. + RS_Done }; static const char *const StageName[]; @@ -157,17 +180,38 @@ class RAGreedy : public MachineFunctionPass, /// Global live range splitting candidate info. struct GlobalSplitCandidate { + // Register intended for assignment, or 0. unsigned PhysReg; + + // SplitKit interval index for this candidate. + unsigned IntvIdx; + + // Interference for PhysReg. InterferenceCache::Cursor Intf; + + // Bundles where this candidate should be live. BitVector LiveBundles; SmallVector ActiveBlocks; void reset(InterferenceCache &Cache, unsigned Reg) { PhysReg = Reg; + IntvIdx = 0; Intf.setPhysReg(Cache, Reg); LiveBundles.clear(); ActiveBlocks.clear(); } + + // Set B[i] = C for every live bundle where B[i] was NoCand. + unsigned getBundles(SmallVectorImpl &B, unsigned C) { + unsigned Count = 0; + for (int i = LiveBundles.find_first(); i >= 0; + i = LiveBundles.find_next(i)) + if (B[i] == NoCand) { + B[i] = C; + Count++; + } + return Count; + } }; /// Candidate info for for each PhysReg in AllocationOrder. @@ -175,6 +219,12 @@ class RAGreedy : public MachineFunctionPass, /// class. SmallVector GlobalCand; + enum { NoCand = ~0u }; + + /// Candidate map. Each edge bundle is assigned to a GlobalCand entry, or to + /// NoCand which indicates the stack interval. + SmallVector BundleCand; + public: RAGreedy(); @@ -208,8 +258,8 @@ class RAGreedy : public MachineFunctionPass, void addThroughConstraints(InterferenceCache::Cursor, ArrayRef); void growRegion(GlobalSplitCandidate &Cand); float calcGlobalSplitCost(GlobalSplitCandidate&); - void splitAroundRegion(LiveInterval&, GlobalSplitCandidate&, - SmallVectorImpl&); + bool calcCompactRegion(GlobalSplitCandidate&); + void splitAroundRegion(LiveRangeEdit&, ArrayRef); void calcGapWeights(unsigned, SmallVectorImpl&); bool shouldEvict(LiveInterval &A, bool, LiveInterval &B, bool); bool canEvictInterference(LiveInterval&, unsigned, bool, EvictionCost&); @@ -222,6 +272,8 @@ class RAGreedy : public MachineFunctionPass, SmallVectorImpl&, unsigned = ~0u); unsigned tryRegionSplit(LiveInterval&, AllocationOrder&, SmallVectorImpl&); + unsigned tryBlockSplit(LiveInterval&, AllocationOrder&, + SmallVectorImpl&); unsigned tryLocalSplit(LiveInterval&, AllocationOrder&, SmallVectorImpl&); unsigned trySplit(LiveInterval&, AllocationOrder&, @@ -233,12 +285,12 @@ char RAGreedy::ID = 0; #ifndef NDEBUG const char *const RAGreedy::StageName[] = { - "RS_New", - "RS_First", - "RS_Second", - "RS_Global", - "RS_Local", - "RS_Spill" + "RS_New", + "RS_Assign", + "RS_Split", + "RS_Split2", + "RS_Spill", + "RS_Done" }; #endif @@ -278,7 +330,7 @@ void RAGreedy::getAnalysisUsage(AnalysisUsage &AU) const { AU.addPreserved(); if (StrongPHIElim) AU.addRequiredID(StrongPHIEliminationID); - AU.addRequiredTransitive(); + AU.addRequiredTransitiveID(RegisterCoalescerPassID); AU.addRequired(); AU.addRequired(); AU.addPreserved(); @@ -325,9 +377,15 @@ void RAGreedy::LRE_WillShrinkVirtReg(unsigned VirtReg) { } void RAGreedy::LRE_DidCloneVirtReg(unsigned New, unsigned Old) { + // Cloning a register we haven't even heard about yet? Just ignore it. + if (!ExtraRegInfo.inBounds(Old)) + return; + // LRE may clone a virtual register because dead code elimination causes it to - // be split into connected components. Ensure that the new register gets the + // be split into connected components. The new components are much smaller + // than the original, so they should get a new chance at being assigned. // same stage as the parent. + ExtraRegInfo[Old].Stage = RS_Assign; ExtraRegInfo.grow(New); ExtraRegInfo[New] = ExtraRegInfo[Old]; } @@ -350,16 +408,15 @@ void RAGreedy::enqueue(LiveInterval *LI) { ExtraRegInfo.grow(Reg); if (ExtraRegInfo[Reg].Stage == RS_New) - ExtraRegInfo[Reg].Stage = RS_First; + ExtraRegInfo[Reg].Stage = RS_Assign; - if (ExtraRegInfo[Reg].Stage == RS_Second) + if (ExtraRegInfo[Reg].Stage == RS_Split) { // Unsplit ranges that couldn't be allocated immediately are deferred until - // everything else has been allocated. Long ranges are allocated last so - // they are split against realistic interference. - Prio = (1u << 31) - Size; - else { - // Everything else is allocated in long->short order. Long ranges that don't - // fit should be spilled ASAP so they don't create interference. + // everything else has been allocated. + Prio = Size; + } else { + // Everything is allocated in long->short order. Long ranges that don't fit + // should be spilled (or split) ASAP so they don't create interference. Prio = (1u << 31) + Size; // Boost ranges that have a physical register hint. @@ -442,7 +499,7 @@ unsigned RAGreedy::tryAssign(LiveInterval &VirtReg, /// @param BreaksHint True when B is already assigned to its preferred register. bool RAGreedy::shouldEvict(LiveInterval &A, bool IsHint, LiveInterval &B, bool BreaksHint) { - bool CanSplit = getStage(B) <= RS_Second; + bool CanSplit = getStage(B) < RS_Spill; // Be fairly aggressive about following hints as long as the evictee can be // split. @@ -487,7 +544,7 @@ bool RAGreedy::canEvictInterference(LiveInterval &VirtReg, unsigned PhysReg, if (TargetRegisterInfo::isPhysicalRegister(Intf->reg)) return false; // Never evict spill products. They cannot split or spill. - if (getStage(*Intf) == RS_Spill) + if (getStage(*Intf) == RS_Done) return false; // Once a live range becomes small enough, it is urgent that we find a // register for it. This is indicated by an infinite spill weight. These @@ -627,6 +684,7 @@ bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf, Intf.moveToBlock(BC.Number); BC.Entry = BI.LiveIn ? SpillPlacement::PrefReg : SpillPlacement::DontCare; BC.Exit = BI.LiveOut ? SpillPlacement::PrefReg : SpillPlacement::DontCare; + BC.ChangesValue = BI.FirstDef; if (!Intf.hasInterference()) continue; @@ -638,9 +696,9 @@ bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf, if (BI.LiveIn) { if (Intf.first() <= Indexes->getMBBStartIdx(BC.Number)) BC.Entry = SpillPlacement::MustSpill, ++Ins; - else if (Intf.first() < BI.FirstUse) + else if (Intf.first() < BI.FirstInstr) BC.Entry = SpillPlacement::PrefSpill, ++Ins; - else if (Intf.first() < BI.LastUse) + else if (Intf.first() < BI.LastInstr) ++Ins; } @@ -648,9 +706,9 @@ bool RAGreedy::addSplitConstraints(InterferenceCache::Cursor Intf, if (BI.LiveOut) { if (Intf.last() >= SA->getLastSplitPoint(BC.Number)) BC.Exit = SpillPlacement::MustSpill, ++Ins; - else if (Intf.last() > BI.LastUse) + else if (Intf.last() > BI.LastInstr) BC.Exit = SpillPlacement::PrefSpill, ++Ins; - else if (Intf.last() > BI.FirstUse) + else if (Intf.last() > BI.FirstInstr) ++Ins; } @@ -684,7 +742,7 @@ void RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf, assert(T < GroupSize && "Array overflow"); TBS[T] = Number; if (++T == GroupSize) { - SpillPlacer->addLinks(ArrayRef(TBS, T)); + SpillPlacer->addLinks(makeArrayRef(TBS, T)); T = 0; } continue; @@ -714,7 +772,7 @@ void RAGreedy::addThroughConstraints(InterferenceCache::Cursor Intf, ArrayRef Array(BCS, B); SpillPlacer->addConstraints(Array); - SpillPlacer->addLinks(ArrayRef(TBS, T)); + SpillPlacer->addLinks(makeArrayRef(TBS, T)); } void RAGreedy::growRegion(GlobalSplitCandidate &Cand) { @@ -749,8 +807,16 @@ void RAGreedy::growRegion(GlobalSplitCandidate &Cand) { // Any new blocks to add? if (ActiveBlocks.size() == AddedTo) break; - addThroughConstraints(Cand.Intf, - ArrayRef(ActiveBlocks).slice(AddedTo)); + + // Compute through constraints from the interference, or assume that all + // through blocks prefer spilling when forming compact regions. + ArrayRef NewBlocks = makeArrayRef(ActiveBlocks).slice(AddedTo); + if (Cand.PhysReg) + addThroughConstraints(Cand.Intf, NewBlocks); + else + // Provide a strong negative bias on through blocks to prevent unwanted + // liveness on loop backedges. + SpillPlacer->addPrefSpill(NewBlocks, /* Strong= */ true); AddedTo = ActiveBlocks.size(); // Perhaps iterating can enable more bundles? @@ -759,11 +825,55 @@ void RAGreedy::growRegion(GlobalSplitCandidate &Cand) { DEBUG(dbgs() << ", v=" << Visited); } +/// calcCompactRegion - Compute the set of edge bundles that should be live +/// when splitting the current live range into compact regions. Compact +/// regions can be computed without looking at interference. They are the +/// regions formed by removing all the live-through blocks from the live range. +/// +/// Returns false if the current live range is already compact, or if the +/// compact regions would form single block regions anyway. +bool RAGreedy::calcCompactRegion(GlobalSplitCandidate &Cand) { + // Without any through blocks, the live range is already compact. + if (!SA->getNumThroughBlocks()) + return false; + + // Compact regions don't correspond to any physreg. + Cand.reset(IntfCache, 0); + + DEBUG(dbgs() << "Compact region bundles"); + + // Use the spill placer to determine the live bundles. GrowRegion pretends + // that all the through blocks have interference when PhysReg is unset. + SpillPlacer->prepare(Cand.LiveBundles); + + // The static split cost will be zero since Cand.Intf reports no interference. + float Cost; + if (!addSplitConstraints(Cand.Intf, Cost)) { + DEBUG(dbgs() << ", none.\n"); + return false; + } + + growRegion(Cand); + SpillPlacer->finish(); + + if (!Cand.LiveBundles.any()) { + DEBUG(dbgs() << ", none.\n"); + return false; + } + + DEBUG({ + for (int i = Cand.LiveBundles.find_first(); i>=0; + i = Cand.LiveBundles.find_next(i)) + dbgs() << " EB#" << i; + dbgs() << ".\n"; + }); + return true; +} + /// calcSpillCost - Compute how expensive it would be to split the live range in /// SA around all use blocks instead of forming bundle regions. float RAGreedy::calcSpillCost() { float Cost = 0; - const LiveInterval &LI = SA->getParent(); ArrayRef UseBlocks = SA->getUseBlocks(); for (unsigned i = 0; i != UseBlocks.size(); ++i) { const SplitAnalysis::BlockInfo &BI = UseBlocks[i]; @@ -772,16 +882,8 @@ float RAGreedy::calcSpillCost() { Cost += SpillPlacer->getBlockFrequency(Number); // Unless the value is redefined in the block. - if (BI.LiveIn && BI.LiveOut) { - SlotIndex Start, Stop; - tie(Start, Stop) = Indexes->getMBBRange(Number); - LiveInterval::const_iterator I = LI.find(Start); - assert(I != LI.end() && "Expected live-in value"); - // Is there a different live-out value? If so, we need an extra spill - // instruction. - if (I->end < Stop) - Cost += SpillPlacer->getBlockFrequency(Number); - } + if (BI.LiveIn && BI.LiveOut && BI.FirstDef) + Cost += SpillPlacer->getBlockFrequency(Number); } return Cost; } @@ -828,81 +930,115 @@ float RAGreedy::calcGlobalSplitCost(GlobalSplitCandidate &Cand) { return GlobalCost; } -/// splitAroundRegion - Split VirtReg around the region determined by -/// LiveBundles. Make an effort to avoid interference from PhysReg. +/// splitAroundRegion - Split the current live range around the regions +/// determined by BundleCand and GlobalCand. /// -/// The 'register' interval is going to contain as many uses as possible while -/// avoiding interference. The 'stack' interval is the complement constructed by -/// SplitEditor. It will contain the rest. +/// Before calling this function, GlobalCand and BundleCand must be initialized +/// so each bundle is assigned to a valid candidate, or NoCand for the +/// stack-bound bundles. The shared SA/SE SplitAnalysis and SplitEditor +/// objects must be initialized for the current live range, and intervals +/// created for the used candidates. /// -void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, - GlobalSplitCandidate &Cand, - SmallVectorImpl &NewVRegs) { - const BitVector &LiveBundles = Cand.LiveBundles; +/// @param LREdit The LiveRangeEdit object handling the current split. +/// @param UsedCands List of used GlobalCand entries. Every BundleCand value +/// must appear in this list. +void RAGreedy::splitAroundRegion(LiveRangeEdit &LREdit, + ArrayRef UsedCands) { + // These are the intervals created for new global ranges. We may create more + // intervals for local ranges. + const unsigned NumGlobalIntvs = LREdit.size(); + DEBUG(dbgs() << "splitAroundRegion with " << NumGlobalIntvs << " globals.\n"); + assert(NumGlobalIntvs && "No global intervals configured"); - DEBUG({ - dbgs() << "Splitting around region for " << PrintReg(Cand.PhysReg, TRI) - << " with bundles"; - for (int i = LiveBundles.find_first(); i>=0; i = LiveBundles.find_next(i)) - dbgs() << " EB#" << i; - dbgs() << ".\n"; - }); - - InterferenceCache::Cursor &Intf = Cand.Intf; - LiveRangeEdit LREdit(VirtReg, NewVRegs, this); - SE->reset(LREdit); - - // Create the main cross-block interval. - const unsigned MainIntv = SE->openIntv(); + // Isolate even single instructions when dealing with a proper sub-class. + // That guarantees register class inflation for the stack interval because it + // is all copies. + unsigned Reg = SA->getParent().reg; + bool SingleInstrs = RegClassInfo.isProperSubClass(MRI->getRegClass(Reg)); // First handle all the blocks with uses. ArrayRef UseBlocks = SA->getUseBlocks(); for (unsigned i = 0; i != UseBlocks.size(); ++i) { const SplitAnalysis::BlockInfo &BI = UseBlocks[i]; - bool RegIn = BI.LiveIn && - LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 0)]; - bool RegOut = BI.LiveOut && - LiveBundles[Bundles->getBundle(BI.MBB->getNumber(), 1)]; + unsigned Number = BI.MBB->getNumber(); + unsigned IntvIn = 0, IntvOut = 0; + SlotIndex IntfIn, IntfOut; + if (BI.LiveIn) { + unsigned CandIn = BundleCand[Bundles->getBundle(Number, 0)]; + if (CandIn != NoCand) { + GlobalSplitCandidate &Cand = GlobalCand[CandIn]; + IntvIn = Cand.IntvIdx; + Cand.Intf.moveToBlock(Number); + IntfIn = Cand.Intf.first(); + } + } + if (BI.LiveOut) { + unsigned CandOut = BundleCand[Bundles->getBundle(Number, 1)]; + if (CandOut != NoCand) { + GlobalSplitCandidate &Cand = GlobalCand[CandOut]; + IntvOut = Cand.IntvIdx; + Cand.Intf.moveToBlock(Number); + IntfOut = Cand.Intf.last(); + } + } // Create separate intervals for isolated blocks with multiple uses. - if (!RegIn && !RegOut) { + if (!IntvIn && !IntvOut) { DEBUG(dbgs() << "BB#" << BI.MBB->getNumber() << " isolated.\n"); - if (!BI.isOneInstr()) { + if (SA->shouldSplitSingleBlock(BI, SingleInstrs)) SE->splitSingleBlock(BI); - SE->selectIntv(MainIntv); - } continue; } - Intf.moveToBlock(BI.MBB->getNumber()); - - if (RegIn && RegOut) - SE->splitLiveThroughBlock(BI.MBB->getNumber(), - MainIntv, Intf.first(), - MainIntv, Intf.last()); - else if (RegIn) - SE->splitRegInBlock(BI, MainIntv, Intf.first()); + if (IntvIn && IntvOut) + SE->splitLiveThroughBlock(Number, IntvIn, IntfIn, IntvOut, IntfOut); + else if (IntvIn) + SE->splitRegInBlock(BI, IntvIn, IntfIn); else - SE->splitRegOutBlock(BI, MainIntv, Intf.last()); + SE->splitRegOutBlock(BI, IntvOut, IntfOut); } - // Handle live-through blocks. - for (unsigned i = 0, e = Cand.ActiveBlocks.size(); i != e; ++i) { - unsigned Number = Cand.ActiveBlocks[i]; - bool RegIn = LiveBundles[Bundles->getBundle(Number, 0)]; - bool RegOut = LiveBundles[Bundles->getBundle(Number, 1)]; - if (!RegIn && !RegOut) - continue; - Intf.moveToBlock(Number); - SE->splitLiveThroughBlock(Number, RegIn ? MainIntv : 0, Intf.first(), - RegOut ? MainIntv : 0, Intf.last()); + // Handle live-through blocks. The relevant live-through blocks are stored in + // the ActiveBlocks list with each candidate. We need to filter out + // duplicates. + BitVector Todo = SA->getThroughBlocks(); + for (unsigned c = 0; c != UsedCands.size(); ++c) { + ArrayRef Blocks = GlobalCand[UsedCands[c]].ActiveBlocks; + for (unsigned i = 0, e = Blocks.size(); i != e; ++i) { + unsigned Number = Blocks[i]; + if (!Todo.test(Number)) + continue; + Todo.reset(Number); + + unsigned IntvIn = 0, IntvOut = 0; + SlotIndex IntfIn, IntfOut; + + unsigned CandIn = BundleCand[Bundles->getBundle(Number, 0)]; + if (CandIn != NoCand) { + GlobalSplitCandidate &Cand = GlobalCand[CandIn]; + IntvIn = Cand.IntvIdx; + Cand.Intf.moveToBlock(Number); + IntfIn = Cand.Intf.first(); + } + + unsigned CandOut = BundleCand[Bundles->getBundle(Number, 1)]; + if (CandOut != NoCand) { + GlobalSplitCandidate &Cand = GlobalCand[CandOut]; + IntvOut = Cand.IntvIdx; + Cand.Intf.moveToBlock(Number); + IntfOut = Cand.Intf.last(); + } + if (!IntvIn && !IntvOut) + continue; + SE->splitLiveThroughBlock(Number, IntvIn, IntfIn, IntvOut, IntfOut); + } } ++NumGlobalSplits; SmallVector IntvMap; SE->finish(&IntvMap); - DebugVars->splitRegister(VirtReg.reg, LREdit.regs()); + DebugVars->splitRegister(Reg, LREdit.regs()); ExtraRegInfo.resize(MRI->getNumVirtRegs()); unsigned OrigBlocks = SA->getNumLiveBlocks(); @@ -922,18 +1058,18 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, // Remainder interval. Don't try splitting again, spill if it doesn't // allocate. if (IntvMap[i] == 0) { - setStage(Reg, RS_Global); + setStage(Reg, RS_Spill); continue; } - // Main interval. Allow repeated splitting as long as the number of live + // Global intervals. Allow repeated splitting as long as the number of live // blocks is strictly decreasing. - if (IntvMap[i] == MainIntv) { + if (IntvMap[i] < NumGlobalIntvs) { if (SA->countLiveBlocks(&Reg) >= OrigBlocks) { DEBUG(dbgs() << "Main interval covers the same " << OrigBlocks << " blocks as original.\n"); // Don't allow repeated splitting as a safe guard against looping. - setStage(Reg, RS_Global); + setStage(Reg, RS_Split2); } continue; } @@ -948,11 +1084,23 @@ void RAGreedy::splitAroundRegion(LiveInterval &VirtReg, unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order, SmallVectorImpl &NewVRegs) { - float BestCost = Hysteresis * calcSpillCost(); - DEBUG(dbgs() << "Cost of isolating all blocks = " << BestCost << '\n'); - const unsigned NoCand = ~0u; - unsigned BestCand = NoCand; unsigned NumCands = 0; + unsigned BestCand = NoCand; + float BestCost; + SmallVector UsedCands; + + // Check if we can split this live range around a compact region. + bool HasCompact = calcCompactRegion(GlobalCand.front()); + if (HasCompact) { + // Yes, keep GlobalCand[0] as the compact region candidate. + NumCands = 1; + BestCost = HUGE_VALF; + } else { + // No benefit from the compact region, our fallback will be per-block + // splitting. Make sure we find a solution that is cheaper than spilling. + BestCost = Hysteresis * calcSpillCost(); + DEBUG(dbgs() << "Cost of isolating all blocks = " << BestCost << '\n'); + } Order.rewind(); while (unsigned PhysReg = Order.next()) { @@ -962,7 +1110,7 @@ unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order, unsigned WorstCount = ~0u; unsigned Worst = 0; for (unsigned i = 0; i != NumCands; ++i) { - if (i == BestCand) + if (i == BestCand || !GlobalCand[i].PhysReg) continue; unsigned Count = GlobalCand[i].LiveBundles.count(); if (Count < WorstCount) @@ -1019,14 +1167,93 @@ unsigned RAGreedy::tryRegionSplit(LiveInterval &VirtReg, AllocationOrder &Order, ++NumCands; } - if (BestCand == NoCand) + // No solutions found, fall back to single block splitting. + if (!HasCompact && BestCand == NoCand) return 0; - splitAroundRegion(VirtReg, GlobalCand[BestCand], NewVRegs); + // Prepare split editor. + LiveRangeEdit LREdit(VirtReg, NewVRegs, this); + SE->reset(LREdit, SplitSpillMode); + + // Assign all edge bundles to the preferred candidate, or NoCand. + BundleCand.assign(Bundles->getNumBundles(), NoCand); + + // Assign bundles for the best candidate region. + if (BestCand != NoCand) { + GlobalSplitCandidate &Cand = GlobalCand[BestCand]; + if (unsigned B = Cand.getBundles(BundleCand, BestCand)) { + UsedCands.push_back(BestCand); + Cand.IntvIdx = SE->openIntv(); + DEBUG(dbgs() << "Split for " << PrintReg(Cand.PhysReg, TRI) << " in " + << B << " bundles, intv " << Cand.IntvIdx << ".\n"); + (void)B; + } + } + + // Assign bundles for the compact region. + if (HasCompact) { + GlobalSplitCandidate &Cand = GlobalCand.front(); + assert(!Cand.PhysReg && "Compact region has no physreg"); + if (unsigned B = Cand.getBundles(BundleCand, 0)) { + UsedCands.push_back(0); + Cand.IntvIdx = SE->openIntv(); + DEBUG(dbgs() << "Split for compact region in " << B << " bundles, intv " + << Cand.IntvIdx << ".\n"); + (void)B; + } + } + + splitAroundRegion(LREdit, UsedCands); return 0; } +//===----------------------------------------------------------------------===// +// Per-Block Splitting +//===----------------------------------------------------------------------===// + +/// tryBlockSplit - Split a global live range around every block with uses. This +/// creates a lot of local live ranges, that will be split by tryLocalSplit if +/// they don't allocate. +unsigned RAGreedy::tryBlockSplit(LiveInterval &VirtReg, AllocationOrder &Order, + SmallVectorImpl &NewVRegs) { + assert(&SA->getParent() == &VirtReg && "Live range wasn't analyzed"); + unsigned Reg = VirtReg.reg; + bool SingleInstrs = RegClassInfo.isProperSubClass(MRI->getRegClass(Reg)); + LiveRangeEdit LREdit(VirtReg, NewVRegs, this); + SE->reset(LREdit, SplitSpillMode); + ArrayRef UseBlocks = SA->getUseBlocks(); + for (unsigned i = 0; i != UseBlocks.size(); ++i) { + const SplitAnalysis::BlockInfo &BI = UseBlocks[i]; + if (SA->shouldSplitSingleBlock(BI, SingleInstrs)) + SE->splitSingleBlock(BI); + } + // No blocks were split. + if (LREdit.empty()) + return 0; + + // We did split for some blocks. + SmallVector IntvMap; + SE->finish(&IntvMap); + + // Tell LiveDebugVariables about the new ranges. + DebugVars->splitRegister(Reg, LREdit.regs()); + + ExtraRegInfo.resize(MRI->getNumVirtRegs()); + + // Sort out the new intervals created by splitting. The remainder interval + // goes straight to spilling, the new local ranges get to stay RS_New. + for (unsigned i = 0, e = LREdit.size(); i != e; ++i) { + LiveInterval &LI = *LREdit.get(i); + if (getStage(LI) == RS_New && IntvMap[i] == 0) + setStage(LI, RS_Spill); + } + + if (VerifyEnabled) + MF->verify(this, "After splitting live range around basic blocks"); + return 0; +} + //===----------------------------------------------------------------------===// // Local Splitting //===----------------------------------------------------------------------===// @@ -1045,8 +1272,10 @@ void RAGreedy::calcGapWeights(unsigned PhysReg, const unsigned NumGaps = Uses.size()-1; // Start and end points for the interference check. - SlotIndex StartIdx = BI.LiveIn ? BI.FirstUse.getBaseIndex() : BI.FirstUse; - SlotIndex StopIdx = BI.LiveOut ? BI.LastUse.getBoundaryIndex() : BI.LastUse; + SlotIndex StartIdx = + BI.LiveIn ? BI.FirstInstr.getBaseIndex() : BI.FirstInstr; + SlotIndex StopIdx = + BI.LiveOut ? BI.LastInstr.getBoundaryIndex() : BI.LastInstr; GapWeight.assign(NumGaps, 0.0f); @@ -1056,8 +1285,8 @@ void RAGreedy::calcGapWeights(unsigned PhysReg, .checkInterference()) continue; - // We know that VirtReg is a continuous interval from FirstUse to LastUse, - // so we don't need InterferenceQuery. + // We know that VirtReg is a continuous interval from FirstInstr to + // LastInstr, so we don't need InterferenceQuery. // // Interference that overlaps an instruction is counted in both gaps // surrounding the instruction. The exception is interference before @@ -1097,8 +1326,8 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order, // while only covering a single block - A phi-def can use undef values from // predecessors, and the block could be a single-block loop. // We don't bother doing anything clever about such a case, we simply assume - // that the interval is continuous from FirstUse to LastUse. We should make - // sure that we don't do anything illegal to such an interval, though. + // that the interval is continuous from FirstInstr to LastInstr. We should + // make sure that we don't do anything illegal to such an interval, though. const SmallVectorImpl &Uses = SA->UseSlots; if (Uses.size() <= 2) @@ -1120,17 +1349,17 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order, // // Instead we use these rules: // - // 1. Allow any split for ranges with getStage() < RS_Local. (Except for the + // 1. Allow any split for ranges with getStage() < RS_Split2. (Except for the // noop split, of course). - // 2. Require progress be made for ranges with getStage() >= RS_Local. All + // 2. Require progress be made for ranges with getStage() == RS_Split2. All // the new ranges must have fewer instructions than before the split. - // 3. New ranges with the same number of instructions are marked RS_Local, + // 3. New ranges with the same number of instructions are marked RS_Split2, // smaller ranges are marked RS_New. // // These rules allow a 3 -> 2+3 split once, which we need. They also prevent // excessive splitting and infinite loops. // - bool ProgressRequired = getStage(VirtReg) >= RS_Local; + bool ProgressRequired = getStage(VirtReg) >= RS_Split2; // Best split candidate. unsigned BestBefore = NumGaps; @@ -1249,7 +1478,7 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order, DebugVars->splitRegister(VirtReg.reg, LREdit.regs()); // If the new range has the same number of instructions as before, mark it as - // RS_Local so the next split will be forced to make progress. Otherwise, + // RS_Split2 so the next split will be forced to make progress. Otherwise, // leave the new intervals as RS_New so they can compete. bool LiveBefore = BestBefore != 0 || BI.LiveIn; bool LiveAfter = BestAfter != NumGaps || BI.LiveOut; @@ -1259,7 +1488,7 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order, assert(!ProgressRequired && "Didn't make progress when it was required."); for (unsigned i = 0, e = IntvMap.size(); i != e; ++i) if (IntvMap[i] == 1) { - setStage(*LREdit.get(i), RS_Local); + setStage(*LREdit.get(i), RS_Split2); DEBUG(dbgs() << PrintReg(LREdit.get(i)->reg)); } DEBUG(dbgs() << '\n'); @@ -1278,6 +1507,10 @@ unsigned RAGreedy::tryLocalSplit(LiveInterval &VirtReg, AllocationOrder &Order, /// @return Physreg when VirtReg may be assigned and/or new NewVRegs. unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order, SmallVectorImpl&NewVRegs) { + // Ranges must be Split2 or less. + if (getStage(VirtReg) >= RS_Spill) + return 0; + // Local intervals are handled separately. if (LIS->intervalIsInOneMBB(VirtReg)) { NamedRegionTimer T("Local Splitting", TimerGroupName, TimePassesIsEnabled); @@ -1287,11 +1520,6 @@ unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order, NamedRegionTimer T("Global Splitting", TimerGroupName, TimePassesIsEnabled); - // Don't iterate global splitting. - // Move straight to spilling if this range was produced by a global split. - if (getStage(VirtReg) >= RS_Global) - return 0; - SA->analyze(&VirtReg); // FIXME: SplitAnalysis may repair broken live ranges coming from the @@ -1305,24 +1533,17 @@ unsigned RAGreedy::trySplit(LiveInterval &VirtReg, AllocationOrder &Order, return PhysReg; } - // First try to split around a region spanning multiple blocks. - unsigned PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs); - if (PhysReg || !NewVRegs.empty()) - return PhysReg; - - // Then isolate blocks with multiple uses. - SplitAnalysis::BlockPtrSet Blocks; - if (SA->getMultiUseBlocks(Blocks)) { - LiveRangeEdit LREdit(VirtReg, NewVRegs, this); - SE->reset(LREdit); - SE->splitSingleBlocks(Blocks); - setStage(NewVRegs.begin(), NewVRegs.end(), RS_Global); - if (VerifyEnabled) - MF->verify(this, "After splitting live range around basic blocks"); + // First try to split around a region spanning multiple blocks. RS_Split2 + // ranges already made dubious progress with region splitting, so they go + // straight to single block splitting. + if (getStage(VirtReg) < RS_Split2) { + unsigned PhysReg = tryRegionSplit(VirtReg, Order, NewVRegs); + if (PhysReg || !NewVRegs.empty()) + return PhysReg; } - // Don't assign any physregs. - return 0; + // Then isolate blocks. + return tryBlockSplit(VirtReg, Order, NewVRegs); } @@ -1342,9 +1563,9 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, << " Cascade " << ExtraRegInfo[VirtReg.reg].Cascade << '\n'); // Try to evict a less worthy live range, but only for ranges from the primary - // queue. The RS_Second ranges already failed to do this, and they should not + // queue. The RS_Split ranges already failed to do this, and they should not // get a second chance until they have been split. - if (Stage != RS_Second) + if (Stage != RS_Split) if (unsigned PhysReg = tryEvict(VirtReg, Order, NewVRegs)) return PhysReg; @@ -1353,8 +1574,8 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, // The first time we see a live range, don't try to split or spill. // Wait until the second time, when all smaller ranges have been allocated. // This gives a better picture of the interference to split around. - if (Stage == RS_First) { - setStage(VirtReg, RS_Second); + if (Stage < RS_Split) { + setStage(VirtReg, RS_Split); DEBUG(dbgs() << "wait for second round\n"); NewVRegs.push_back(&VirtReg); return 0; @@ -1362,7 +1583,7 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, // If we couldn't allocate a register from spilling, there is probably some // invalid inline assembly. The base class wil report it. - if (Stage >= RS_Spill || !VirtReg.isSpillable()) + if (Stage >= RS_Done || !VirtReg.isSpillable()) return ~0u; // Try splitting VirtReg or interferences. @@ -1374,7 +1595,7 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, NamedRegionTimer T("Spiller", TimerGroupName, TimePassesIsEnabled); LiveRangeEdit LRE(VirtReg, NewVRegs, this); spiller().spill(LRE); - setStage(NewVRegs.begin(), NewVRegs.end(), RS_Spill); + setStage(NewVRegs.begin(), NewVRegs.end(), RS_Done); if (VerifyEnabled) MF->verify(this, "After spilling"); @@ -1408,6 +1629,7 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) { ExtraRegInfo.resize(MRI->getNumVirtRegs()); NextCascade = 1; IntfCache.init(MF, &PhysReg2LiveUnion[0], Indexes, TRI); + GlobalCand.resize(32); // This will grow as needed. allocatePhysRegs(); addMBBLiveIns(MF); @@ -1420,7 +1642,10 @@ bool RAGreedy::runOnMachineFunction(MachineFunction &mf) { } // Write out new DBG_VALUE instructions. - DebugVars->emitDebugValues(VRM); + { + NamedRegionTimer T("Emit Debug Info", TimerGroupName, TimePassesIsEnabled); + DebugVars->emitDebugValues(VRM); + } // The pass output is in VirtRegMap. Release all the transient data. releaseMemory(); diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp index 0dd3c598c154..ce3fb90b1126 100644 --- a/lib/CodeGen/RegAllocLinearScan.cpp +++ b/lib/CodeGen/RegAllocLinearScan.cpp @@ -18,7 +18,6 @@ #include "VirtRegRewriter.h" #include "RegisterClassInfo.h" #include "Spiller.h" -#include "RegisterCoalescer.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Function.h" #include "llvm/CodeGen/CalcSpillWeights.h" @@ -209,7 +208,7 @@ namespace { AU.addRequiredID(StrongPHIEliminationID); // Make sure PassManager knows which analyses to make available // to coalescing and which analyses coalescing invalidates. - AU.addRequiredTransitive(); + AU.addRequiredTransitiveID(RegisterCoalescerPassID); AU.addRequired(); AU.addRequiredID(LiveStacksID); AU.addPreservedID(LiveStacksID); diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp index 72230d4b0c5c..0d2cf2d6184c 100644 --- a/lib/CodeGen/RegAllocPBQP.cpp +++ b/lib/CodeGen/RegAllocPBQP.cpp @@ -450,7 +450,7 @@ void RegAllocPBQP::getAnalysisUsage(AnalysisUsage &au) const { au.addPreserved(); au.addRequired(); //au.addRequiredID(SplitCriticalEdgesID); - au.addRequired(); + au.addRequiredID(RegisterCoalescerPassID); if (customPassID) au.addRequiredID(*customPassID); au.addRequired(); diff --git a/lib/CodeGen/RegisterClassInfo.cpp b/lib/CodeGen/RegisterClassInfo.cpp index 5a77e47bc591..786d279c2b8c 100644 --- a/lib/CodeGen/RegisterClassInfo.cpp +++ b/lib/CodeGen/RegisterClassInfo.cpp @@ -99,11 +99,16 @@ void RegisterClassInfo::compute(const TargetRegisterClass *RC) const { // CSR aliases go after the volatile registers, preserve the target's order. std::copy(CSRAlias.begin(), CSRAlias.end(), &RCI.Order[N]); + // Check if RC is a proper sub-class. + if (const TargetRegisterClass *Super = TRI->getLargestLegalSuperClass(RC)) + if (Super != RC && getNumAllocatableRegs(Super) > RCI.NumRegs) + RCI.ProperSubClass = true; + DEBUG({ dbgs() << "AllocationOrder(" << RC->getName() << ") = ["; for (unsigned I = 0; I != RCI.NumRegs; ++I) dbgs() << ' ' << PrintReg(RCI.Order[I], TRI); - dbgs() << " ]\n"; + dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n"); }); // RCI is now up-to-date. diff --git a/lib/CodeGen/RegisterClassInfo.h b/lib/CodeGen/RegisterClassInfo.h index d21fd67efe8b..2c1407096cd7 100644 --- a/lib/CodeGen/RegisterClassInfo.h +++ b/lib/CodeGen/RegisterClassInfo.h @@ -28,11 +28,12 @@ class RegisterClassInfo { struct RCInfo { unsigned Tag; unsigned NumRegs; + bool ProperSubClass; OwningArrayPtr Order; - RCInfo() : Tag(0), NumRegs(0) {} + RCInfo() : Tag(0), NumRegs(0), ProperSubClass(false) {} operator ArrayRef() const { - return ArrayRef(Order.get(), NumRegs); + return makeArrayRef(Order.get(), NumRegs); } }; @@ -87,6 +88,16 @@ class RegisterClassInfo { return get(RC); } + /// isProperSubClass - Returns true if RC has a legal super-class with more + /// allocatable registers. + /// + /// Register classes like GR32_NOSP are not proper sub-classes because %esp + /// is not allocatable. Similarly, tGPR is not a proper sub-class in Thumb + /// mode because the GPR super-class is not legal. + bool isProperSubClass(const TargetRegisterClass *RC) const { + return get(RC).ProperSubClass; + } + /// getLastCalleeSavedAlias - Returns the last callee saved register that /// overlaps PhysReg, or 0 if Reg doesn't overlap a CSR. unsigned getLastCalleeSavedAlias(unsigned PhysReg) const { diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp index b91f92c6aa5a..9b414d6212c7 100644 --- a/lib/CodeGen/RegisterCoalescer.cpp +++ b/lib/CodeGen/RegisterCoalescer.cpp @@ -15,8 +15,9 @@ #define DEBUG_TYPE "regcoalescing" #include "RegisterCoalescer.h" -#include "VirtRegMap.h" #include "LiveDebugVariables.h" +#include "RegisterClassInfo.h" +#include "VirtRegMap.h" #include "llvm/Pass.h" #include "llvm/Value.h" @@ -54,6 +55,7 @@ STATISTIC(numExtends , "Number of copies extended"); STATISTIC(NumReMats , "Number of instructions re-materialized"); STATISTIC(numPeep , "Number of identity moves eliminated after coalescing"); STATISTIC(numAborts , "Number of times interval joining aborted"); +STATISTIC(NumInflated , "Number of register classes inflated"); static cl::opt EnableJoining("join-liveintervals", @@ -75,6 +77,128 @@ VerifyCoalescing("verify-coalescing", cl::desc("Verify machine instrs before and after register coalescing"), cl::Hidden); +namespace { + class RegisterCoalescer : public MachineFunctionPass { + MachineFunction* MF; + MachineRegisterInfo* MRI; + const TargetMachine* TM; + const TargetRegisterInfo* TRI; + const TargetInstrInfo* TII; + LiveIntervals *LIS; + LiveDebugVariables *LDV; + const MachineLoopInfo* Loops; + AliasAnalysis *AA; + RegisterClassInfo RegClassInfo; + + /// JoinedCopies - Keep track of copies eliminated due to coalescing. + /// + SmallPtrSet JoinedCopies; + + /// ReMatCopies - Keep track of copies eliminated due to remat. + /// + SmallPtrSet ReMatCopies; + + /// ReMatDefs - Keep track of definition instructions which have + /// been remat'ed. + SmallPtrSet ReMatDefs; + + /// joinIntervals - join compatible live intervals + void joinIntervals(); + + /// CopyCoalesceInMBB - Coalesce copies in the specified MBB, putting + /// copies that cannot yet be coalesced into the "TryAgain" list. + void CopyCoalesceInMBB(MachineBasicBlock *MBB, + std::vector &TryAgain); + + /// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg, + /// which are the src/dst of the copy instruction CopyMI. This returns + /// true if the copy was successfully coalesced away. If it is not + /// currently possible to coalesce this interval, but it may be possible if + /// other things get coalesced, then it returns true by reference in + /// 'Again'. + bool JoinCopy(MachineInstr *TheCopy, bool &Again); + + /// JoinIntervals - Attempt to join these two intervals. On failure, this + /// returns false. The output "SrcInt" will not have been modified, so we + /// can use this information below to update aliases. + bool JoinIntervals(CoalescerPair &CP); + + /// AdjustCopiesBackFrom - We found a non-trivially-coalescable copy. If + /// the source value number is defined by a copy from the destination reg + /// see if we can merge these two destination reg valno# into a single + /// value number, eliminating a copy. + bool AdjustCopiesBackFrom(const CoalescerPair &CP, MachineInstr *CopyMI); + + /// HasOtherReachingDefs - Return true if there are definitions of IntB + /// other than BValNo val# that can reach uses of AValno val# of IntA. + bool HasOtherReachingDefs(LiveInterval &IntA, LiveInterval &IntB, + VNInfo *AValNo, VNInfo *BValNo); + + /// RemoveCopyByCommutingDef - We found a non-trivially-coalescable copy. + /// If the source value number is defined by a commutable instruction and + /// its other operand is coalesced to the copy dest register, see if we + /// can transform the copy into a noop by commuting the definition. + bool RemoveCopyByCommutingDef(const CoalescerPair &CP,MachineInstr *CopyMI); + + /// ReMaterializeTrivialDef - If the source of a copy is defined by a + /// trivial computation, replace the copy by rematerialize the definition. + /// If PreserveSrcInt is true, make sure SrcInt is valid after the call. + bool ReMaterializeTrivialDef(LiveInterval &SrcInt, bool PreserveSrcInt, + unsigned DstReg, MachineInstr *CopyMI); + + /// shouldJoinPhys - Return true if a physreg copy should be joined. + bool shouldJoinPhys(CoalescerPair &CP); + + /// isWinToJoinCrossClass - Return true if it's profitable to coalesce + /// two virtual registers from different register classes. + bool isWinToJoinCrossClass(unsigned SrcReg, + unsigned DstReg, + const TargetRegisterClass *SrcRC, + const TargetRegisterClass *DstRC, + const TargetRegisterClass *NewRC); + + /// UpdateRegDefsUses - Replace all defs and uses of SrcReg to DstReg and + /// update the subregister number if it is not zero. If DstReg is a + /// physical register and the existing subregister number of the def / use + /// being updated is not zero, make sure to set it to the correct physical + /// subregister. + void UpdateRegDefsUses(const CoalescerPair &CP); + + /// RemoveDeadDef - If a def of a live interval is now determined dead, + /// remove the val# it defines. If the live interval becomes empty, remove + /// it as well. + bool RemoveDeadDef(LiveInterval &li, MachineInstr *DefMI); + + /// RemoveCopyFlag - If DstReg is no longer defined by CopyMI, clear the + /// VNInfo copy flag for DstReg and all aliases. + void RemoveCopyFlag(unsigned DstReg, const MachineInstr *CopyMI); + + /// markAsJoined - Remember that CopyMI has already been joined. + void markAsJoined(MachineInstr *CopyMI); + + /// eliminateUndefCopy - Handle copies of undef values. + bool eliminateUndefCopy(MachineInstr *CopyMI, const CoalescerPair &CP); + + public: + static char ID; // Class identification, replacement for typeinfo + RegisterCoalescer() : MachineFunctionPass(ID) { + initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry()); + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + + virtual void releaseMemory(); + + /// runOnMachineFunction - pass entry point + virtual bool runOnMachineFunction(MachineFunction&); + + /// print - Implement the dump method. + virtual void print(raw_ostream &O, const Module* = 0) const; + }; +} /// end anonymous namespace + +char &llvm::RegisterCoalescerPassID = RegisterCoalescer::ID; + INITIALIZE_PASS_BEGIN(RegisterCoalescer, "simple-register-coalescing", "Simple Register Coalescing", false, false) INITIALIZE_PASS_DEPENDENCY(LiveIntervals) @@ -116,14 +240,14 @@ static bool isMoveInstr(const TargetRegisterInfo &tri, const MachineInstr *MI, } bool CoalescerPair::setRegisters(const MachineInstr *MI) { - srcReg_ = dstReg_ = subIdx_ = 0; - newRC_ = 0; - flipped_ = crossClass_ = false; + SrcReg = DstReg = SubIdx = 0; + NewRC = 0; + Flipped = CrossClass = false; unsigned Src, Dst, SrcSub, DstSub; - if (!isMoveInstr(tri_, MI, Src, Dst, SrcSub, DstSub)) + if (!isMoveInstr(TRI, MI, Src, Dst, SrcSub, DstSub)) return false; - partial_ = SrcSub || DstSub; + Partial = SrcSub || DstSub; // If one register is a physreg, it must be Dst. if (TargetRegisterInfo::isPhysicalRegister(Src)) { @@ -131,7 +255,7 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) { return false; std::swap(Src, Dst); std::swap(SrcSub, DstSub); - flipped_ = true; + Flipped = true; } const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo(); @@ -139,14 +263,14 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) { if (TargetRegisterInfo::isPhysicalRegister(Dst)) { // Eliminate DstSub on a physreg. if (DstSub) { - Dst = tri_.getSubReg(Dst, DstSub); + Dst = TRI.getSubReg(Dst, DstSub); if (!Dst) return false; DstSub = 0; } // Eliminate SrcSub by picking a corresponding Dst superregister. if (SrcSub) { - Dst = tri_.getMatchingSuperReg(Dst, SrcSub, MRI.getRegClass(Src)); + Dst = TRI.getMatchingSuperReg(Dst, SrcSub, MRI.getRegClass(Src)); if (!Dst) return false; SrcSub = 0; } else if (!MRI.getRegClass(Src)->contains(Dst)) { @@ -164,7 +288,7 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) { return false; const TargetRegisterClass *SrcRC = MRI.getRegClass(Src); const TargetRegisterClass *DstRC = MRI.getRegClass(Dst); - if (!getCommonSubClass(DstRC, SrcRC)) + if (!TRI.getCommonSubClass(DstRC, SrcRC)) return false; SrcSub = DstSub = 0; } @@ -174,36 +298,36 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) { std::swap(Src, Dst); DstSub = SrcSub; SrcSub = 0; - assert(!flipped_ && "Unexpected flip"); - flipped_ = true; + assert(!Flipped && "Unexpected flip"); + Flipped = true; } // Find the new register class. const TargetRegisterClass *SrcRC = MRI.getRegClass(Src); const TargetRegisterClass *DstRC = MRI.getRegClass(Dst); if (DstSub) - newRC_ = tri_.getMatchingSuperRegClass(DstRC, SrcRC, DstSub); + NewRC = TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSub); else - newRC_ = getCommonSubClass(DstRC, SrcRC); - if (!newRC_) + NewRC = TRI.getCommonSubClass(DstRC, SrcRC); + if (!NewRC) return false; - crossClass_ = newRC_ != DstRC || newRC_ != SrcRC; + CrossClass = NewRC != DstRC || NewRC != SrcRC; } // Check our invariants assert(TargetRegisterInfo::isVirtualRegister(Src) && "Src must be virtual"); assert(!(TargetRegisterInfo::isPhysicalRegister(Dst) && DstSub) && "Cannot have a physical SubIdx"); - srcReg_ = Src; - dstReg_ = Dst; - subIdx_ = DstSub; + SrcReg = Src; + DstReg = Dst; + SubIdx = DstSub; return true; } bool CoalescerPair::flip() { - if (subIdx_ || TargetRegisterInfo::isPhysicalRegister(dstReg_)) + if (SubIdx || TargetRegisterInfo::isPhysicalRegister(DstReg)) return false; - std::swap(srcReg_, dstReg_); - flipped_ = !flipped_; + std::swap(SrcReg, DstReg); + Flipped = !Flipped; return true; } @@ -211,36 +335,36 @@ bool CoalescerPair::isCoalescable(const MachineInstr *MI) const { if (!MI) return false; unsigned Src, Dst, SrcSub, DstSub; - if (!isMoveInstr(tri_, MI, Src, Dst, SrcSub, DstSub)) + if (!isMoveInstr(TRI, MI, Src, Dst, SrcSub, DstSub)) return false; - // Find the virtual register that is srcReg_. - if (Dst == srcReg_) { + // Find the virtual register that is SrcReg. + if (Dst == SrcReg) { std::swap(Src, Dst); std::swap(SrcSub, DstSub); - } else if (Src != srcReg_) { + } else if (Src != SrcReg) { return false; } - // Now check that Dst matches dstReg_. - if (TargetRegisterInfo::isPhysicalRegister(dstReg_)) { + // Now check that Dst matches DstReg. + if (TargetRegisterInfo::isPhysicalRegister(DstReg)) { if (!TargetRegisterInfo::isPhysicalRegister(Dst)) return false; - assert(!subIdx_ && "Inconsistent CoalescerPair state."); + assert(!SubIdx && "Inconsistent CoalescerPair state."); // DstSub could be set for a physreg from INSERT_SUBREG. if (DstSub) - Dst = tri_.getSubReg(Dst, DstSub); + Dst = TRI.getSubReg(Dst, DstSub); // Full copy of Src. if (!SrcSub) - return dstReg_ == Dst; + return DstReg == Dst; // This is a partial register copy. Check that the parts match. - return tri_.getSubReg(dstReg_, SrcSub) == Dst; + return TRI.getSubReg(DstReg, SrcSub) == Dst; } else { - // dstReg_ is virtual. - if (dstReg_ != Dst) + // DstReg is virtual. + if (DstReg != Dst) return false; // Registers match, do the subregisters line up? - return compose(tri_, subIdx_, SrcSub) == DstSub; + return compose(TRI, SubIdx, SrcSub) == DstSub; } } @@ -292,14 +416,14 @@ bool RegisterCoalescer::AdjustCopiesBackFrom(const CoalescerPair &CP, MachineInstr *CopyMI) { // Bail if there is no dst interval - can happen when merging physical subreg // operations. - if (!li_->hasInterval(CP.getDstReg())) + if (!LIS->hasInterval(CP.getDstReg())) return false; LiveInterval &IntA = - li_->getInterval(CP.isFlipped() ? CP.getDstReg() : CP.getSrcReg()); + LIS->getInterval(CP.isFlipped() ? CP.getDstReg() : CP.getSrcReg()); LiveInterval &IntB = - li_->getInterval(CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg()); - SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI).getDefIndex(); + LIS->getInterval(CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg()); + SlotIndex CopyIdx = LIS->getInstructionIndex(CopyMI).getDefIndex(); // BValNo is a value number in B that is defined by a copy from A. 'B3' in // the example above. @@ -355,7 +479,7 @@ bool RegisterCoalescer::AdjustCopiesBackFrom(const CoalescerPair &CP, // Make sure that the end of the live range is inside the same block as // CopyMI. MachineInstr *ValLREndInst = - li_->getInstructionFromIndex(ValLR->end.getPrevSlot()); + LIS->getInstructionFromIndex(ValLR->end.getPrevSlot()); if (!ValLREndInst || ValLREndInst->getParent() != CopyMI->getParent()) return false; @@ -368,11 +492,11 @@ bool RegisterCoalescer::AdjustCopiesBackFrom(const CoalescerPair &CP, // of its aliases is overlapping the live interval of the virtual register. // If so, do not coalesce. if (TargetRegisterInfo::isPhysicalRegister(IntB.reg)) { - for (const unsigned *AS = tri_->getAliasSet(IntB.reg); *AS; ++AS) - if (li_->hasInterval(*AS) && IntA.overlaps(li_->getInterval(*AS))) { + for (const unsigned *AS = TRI->getAliasSet(IntB.reg); *AS; ++AS) + if (LIS->hasInterval(*AS) && IntA.overlaps(LIS->getInterval(*AS))) { DEBUG({ dbgs() << "\t\tInterfere with alias "; - li_->getInterval(*AS).print(dbgs(), tri_); + LIS->getInterval(*AS).print(dbgs(), TRI); }); return false; } @@ -380,7 +504,7 @@ bool RegisterCoalescer::AdjustCopiesBackFrom(const CoalescerPair &CP, DEBUG({ dbgs() << "Extending: "; - IntB.print(dbgs(), tri_); + IntB.print(dbgs(), TRI); }); SlotIndex FillerStart = ValLR->end, FillerEnd = BLR->start; @@ -398,13 +522,13 @@ bool RegisterCoalescer::AdjustCopiesBackFrom(const CoalescerPair &CP, // If the IntB live range is assigned to a physical register, and if that // physreg has sub-registers, update their live intervals as well. if (TargetRegisterInfo::isPhysicalRegister(IntB.reg)) { - for (const unsigned *SR = tri_->getSubRegisters(IntB.reg); *SR; ++SR) { - if (!li_->hasInterval(*SR)) + for (const unsigned *SR = TRI->getSubRegisters(IntB.reg); *SR; ++SR) { + if (!LIS->hasInterval(*SR)) continue; - LiveInterval &SRLI = li_->getInterval(*SR); + LiveInterval &SRLI = LIS->getInterval(*SR); SRLI.addRange(LiveRange(FillerStart, FillerEnd, SRLI.getNextValue(FillerStart, 0, - li_->getVNInfoAllocator()))); + LIS->getVNInfoAllocator()))); } } @@ -419,7 +543,7 @@ bool RegisterCoalescer::AdjustCopiesBackFrom(const CoalescerPair &CP, } DEBUG({ dbgs() << " result = "; - IntB.print(dbgs(), tri_); + IntB.print(dbgs(), TRI); dbgs() << "\n"; }); @@ -434,7 +558,7 @@ bool RegisterCoalescer::AdjustCopiesBackFrom(const CoalescerPair &CP, // merge, find the last use and trim the live range. That will also add the // isKill marker. if (ALR->end == CopyIdx) - li_->shrinkToUses(&IntA); + LIS->shrinkToUses(&IntA); ++numExtends; return true; @@ -498,15 +622,15 @@ bool RegisterCoalescer::RemoveCopyByCommutingDef(const CoalescerPair &CP, return false; // Bail if there is no dst interval. - if (!li_->hasInterval(CP.getDstReg())) + if (!LIS->hasInterval(CP.getDstReg())) return false; - SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI).getDefIndex(); + SlotIndex CopyIdx = LIS->getInstructionIndex(CopyMI).getDefIndex(); LiveInterval &IntA = - li_->getInterval(CP.isFlipped() ? CP.getDstReg() : CP.getSrcReg()); + LIS->getInterval(CP.isFlipped() ? CP.getDstReg() : CP.getSrcReg()); LiveInterval &IntB = - li_->getInterval(CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg()); + LIS->getInterval(CP.isFlipped() ? CP.getSrcReg() : CP.getDstReg()); // BValNo is a value number in B that is defined by a copy from A. 'B3' in // the example above. @@ -524,7 +648,7 @@ bool RegisterCoalescer::RemoveCopyByCommutingDef(const CoalescerPair &CP, // the optimization. if (AValNo->isPHIDef() || AValNo->isUnused() || AValNo->hasPHIKill()) return false; - MachineInstr *DefMI = li_->getInstructionFromIndex(AValNo->def); + MachineInstr *DefMI = LIS->getInstructionFromIndex(AValNo->def); if (!DefMI) return false; const MCInstrDesc &MCID = DefMI->getDesc(); @@ -538,7 +662,7 @@ bool RegisterCoalescer::RemoveCopyByCommutingDef(const CoalescerPair &CP, if (!DefMI->isRegTiedToUseOperand(DefIdx, &UseOpIdx)) return false; unsigned Op1, Op2, NewDstIdx; - if (!tii_->findCommutedOpIndices(DefMI, Op1, Op2)) + if (!TII->findCommutedOpIndices(DefMI, Op1, Op2)) return false; if (Op1 == UseOpIdx) NewDstIdx = Op2; @@ -560,18 +684,18 @@ bool RegisterCoalescer::RemoveCopyByCommutingDef(const CoalescerPair &CP, // Abort if the aliases of IntB.reg have values that are not simply the // clobbers from the superreg. if (TargetRegisterInfo::isPhysicalRegister(IntB.reg)) - for (const unsigned *AS = tri_->getAliasSet(IntB.reg); *AS; ++AS) - if (li_->hasInterval(*AS) && - HasOtherReachingDefs(IntA, li_->getInterval(*AS), AValNo, 0)) + for (const unsigned *AS = TRI->getAliasSet(IntB.reg); *AS; ++AS) + if (LIS->hasInterval(*AS) && + HasOtherReachingDefs(IntA, LIS->getInterval(*AS), AValNo, 0)) return false; // 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_nodbg_iterator UI = - mri_->use_nodbg_begin(IntA.reg), - UE = mri_->use_nodbg_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); + SlotIndex UseIdx = LIS->getInstructionIndex(UseMI); LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx); if (ULR == IntA.end()) continue; @@ -585,15 +709,15 @@ bool RegisterCoalescer::RemoveCopyByCommutingDef(const CoalescerPair &CP, // At this point we have decided that it is legal to do this // transformation. Start by commuting the instruction. MachineBasicBlock *MBB = DefMI->getParent(); - MachineInstr *NewMI = tii_->commuteInstruction(DefMI); + MachineInstr *NewMI = TII->commuteInstruction(DefMI); if (!NewMI) return false; if (TargetRegisterInfo::isVirtualRegister(IntA.reg) && TargetRegisterInfo::isVirtualRegister(IntB.reg) && - !mri_->constrainRegClass(IntB.reg, mri_->getRegClass(IntA.reg))) + !MRI->constrainRegClass(IntB.reg, MRI->getRegClass(IntA.reg))) return false; if (NewMI != DefMI) { - li_->ReplaceMachineInstrInMaps(DefMI, NewMI); + LIS->ReplaceMachineInstrInMaps(DefMI, NewMI); MBB->insert(DefMI, NewMI); MBB->erase(DefMI); } @@ -610,8 +734,8 @@ bool RegisterCoalescer::RemoveCopyByCommutingDef(const CoalescerPair &CP, // = B // Update uses of IntA of the specific Val# with IntB. - for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(IntA.reg), - UE = mri_->use_end(); UI != UE;) { + for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(IntA.reg), + UE = MRI->use_end(); UI != UE;) { MachineOperand &UseMO = UI.getOperand(); MachineInstr *UseMI = &*UI; ++UI; @@ -623,12 +747,12 @@ bool RegisterCoalescer::RemoveCopyByCommutingDef(const CoalescerPair &CP, UseMO.setReg(NewReg); continue; } - SlotIndex UseIdx = li_->getInstructionIndex(UseMI).getUseIndex(); + SlotIndex UseIdx = LIS->getInstructionIndex(UseMI).getUseIndex(); LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx); if (ULR == IntA.end() || ULR->valno != AValNo) continue; if (TargetRegisterInfo::isPhysicalRegister(NewReg)) - UseMO.substPhysReg(NewReg, *tri_); + UseMO.substPhysReg(NewReg, *TRI); else UseMO.setReg(NewReg); if (UseMI == CopyMI) @@ -674,27 +798,24 @@ bool RegisterCoalescer::RemoveCopyByCommutingDef(const CoalescerPair &CP, bool RegisterCoalescer::ReMaterializeTrivialDef(LiveInterval &SrcInt, bool preserveSrcInt, unsigned DstReg, - unsigned DstSubIdx, MachineInstr *CopyMI) { - SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI).getUseIndex(); + SlotIndex CopyIdx = LIS->getInstructionIndex(CopyMI).getUseIndex(); LiveInterval::iterator SrcLR = SrcInt.FindLiveRangeContaining(CopyIdx); assert(SrcLR != SrcInt.end() && "Live range not found!"); VNInfo *ValNo = SrcLR->valno; - // If other defs can reach uses of this def, then it's not safe to perform - // the optimization. - if (ValNo->isPHIDef() || ValNo->isUnused() || ValNo->hasPHIKill()) + if (ValNo->isPHIDef() || ValNo->isUnused()) return false; - MachineInstr *DefMI = li_->getInstructionFromIndex(ValNo->def); + MachineInstr *DefMI = LIS->getInstructionFromIndex(ValNo->def); if (!DefMI) return false; assert(DefMI && "Defining instruction disappeared"); const MCInstrDesc &MCID = DefMI->getDesc(); if (!MCID.isAsCheapAsAMove()) return false; - if (!tii_->isTriviallyReMaterializable(DefMI, AA)) + if (!TII->isTriviallyReMaterializable(DefMI, AA)) return false; bool SawStore = false; - if (!DefMI->isSafeToMove(tii_, AA, SawStore)) + if (!DefMI->isSafeToMove(TII, AA, SawStore)) return false; if (MCID.getNumDefs() != 1) return false; @@ -702,36 +823,20 @@ bool RegisterCoalescer::ReMaterializeTrivialDef(LiveInterval &SrcInt, // 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. - const TargetRegisterClass *RC = tii_->getRegClass(MCID, 0, tri_); + const TargetRegisterClass *RC = TII->getRegClass(MCID, 0, TRI); if (TargetRegisterInfo::isVirtualRegister(DstReg)) { - if (mri_->getRegClass(DstReg) != RC) + if (MRI->getRegClass(DstReg) != RC) return false; } else if (!RC->contains(DstReg)) return false; } - // If destination register has a sub-register index on it, make sure it - // matches the instruction register class. - if (DstSubIdx) { - const MCInstrDesc &MCID = DefMI->getDesc(); - if (MCID.getNumDefs() != 1) - return false; - const TargetRegisterClass *DstRC = mri_->getRegClass(DstReg); - const TargetRegisterClass *DstSubRC = - DstRC->getSubRegisterRegClass(DstSubIdx); - const TargetRegisterClass *DefRC = tii_->getRegClass(MCID, 0, tri_); - if (DefRC == DstRC) - DstSubIdx = 0; - else if (DefRC != DstSubRC) - return false; - } - RemoveCopyFlag(DstReg, CopyMI); MachineBasicBlock *MBB = CopyMI->getParent(); MachineBasicBlock::iterator MII = llvm::next(MachineBasicBlock::iterator(CopyMI)); - tii_->reMaterialize(*MBB, MII, DstReg, DstSubIdx, DefMI, *tri_); + TII->reMaterialize(*MBB, MII, DstReg, 0, DefMI, *TRI); MachineInstr *NewMI = prior(MII); // CopyMI may have implicit operands, transfer them over to the newly @@ -746,7 +851,7 @@ bool RegisterCoalescer::ReMaterializeTrivialDef(LiveInterval &SrcInt, } NewMI->copyImplicitOps(CopyMI); - li_->ReplaceMachineInstrInMaps(CopyMI, NewMI); + LIS->ReplaceMachineInstrInMaps(CopyMI, NewMI); CopyMI->eraseFromParent(); ReMatCopies.insert(CopyMI); ReMatDefs.insert(DefMI); @@ -755,11 +860,54 @@ bool RegisterCoalescer::ReMaterializeTrivialDef(LiveInterval &SrcInt, // The source interval can become smaller because we removed a use. if (preserveSrcInt) - li_->shrinkToUses(&SrcInt); + LIS->shrinkToUses(&SrcInt); return true; } +/// eliminateUndefCopy - ProcessImpicitDefs may leave some copies of +/// values, it only removes local variables. When we have a copy like: +/// +/// %vreg1 = COPY %vreg2 +/// +/// We delete the copy and remove the corresponding value number from %vreg1. +/// Any uses of that value number are marked as . +bool RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI, + const CoalescerPair &CP) { + SlotIndex Idx = LIS->getInstructionIndex(CopyMI); + LiveInterval *SrcInt = &LIS->getInterval(CP.getSrcReg()); + if (SrcInt->liveAt(Idx)) + return false; + LiveInterval *DstInt = &LIS->getInterval(CP.getDstReg()); + if (DstInt->liveAt(Idx)) + return false; + + // No intervals are live-in to CopyMI - it is undef. + if (CP.isFlipped()) + DstInt = SrcInt; + SrcInt = 0; + + VNInfo *DeadVNI = DstInt->getVNInfoAt(Idx.getDefIndex()); + assert(DeadVNI && "No value defined in DstInt"); + DstInt->removeValNo(DeadVNI); + + // Find new undef uses. + for (MachineRegisterInfo::reg_nodbg_iterator + I = MRI->reg_nodbg_begin(DstInt->reg), E = MRI->reg_nodbg_end(); + I != E; ++I) { + MachineOperand &MO = I.getOperand(); + if (MO.isDef() || MO.isUndef()) + continue; + MachineInstr *MI = MO.getParent(); + SlotIndex Idx = LIS->getInstructionIndex(MI); + if (DstInt->liveAt(Idx)) + continue; + MO.setIsUndef(true); + DEBUG(dbgs() << "\tnew undef: " << Idx << '\t' << *MI); + } + return true; +} + /// UpdateRegDefsUses - Replace all defs and uses of SrcReg to DstReg and /// update the subregister number if it is not zero. If DstReg is a /// physical register and the existing subregister number of the def / use @@ -773,22 +921,20 @@ RegisterCoalescer::UpdateRegDefsUses(const CoalescerPair &CP) { unsigned SubIdx = CP.getSubIdx(); // Update LiveDebugVariables. - ldv_->renameRegister(SrcReg, DstReg, SubIdx); + LDV->renameRegister(SrcReg, DstReg, SubIdx); - for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(SrcReg); + for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(SrcReg); MachineInstr *UseMI = I.skipInstruction();) { // A PhysReg copy that won't be coalesced can perhaps be rematerialized // instead. if (DstIsPhys) { - if (UseMI->isCopy() && - !UseMI->getOperand(1).getSubReg() && - !UseMI->getOperand(0).getSubReg() && + if (UseMI->isFullCopy() && UseMI->getOperand(1).getReg() == SrcReg && UseMI->getOperand(0).getReg() != SrcReg && UseMI->getOperand(0).getReg() != DstReg && !JoinedCopies.count(UseMI) && - ReMaterializeTrivialDef(li_->getInterval(SrcReg), false, - UseMI->getOperand(0).getReg(), 0, UseMI)) + ReMaterializeTrivialDef(LIS->getInterval(SrcReg), false, + UseMI->getOperand(0).getReg(), UseMI)) continue; } @@ -803,10 +949,18 @@ RegisterCoalescer::UpdateRegDefsUses(const CoalescerPair &CP) { Kills |= MO.isKill(); Deads |= MO.isDead(); + // Make sure we don't create read-modify-write defs accidentally. We + // assume here that a SrcReg def cannot be joined into a live DstReg. If + // RegisterCoalescer starts tracking partially live registers, we will + // need to check the actual LiveInterval to determine if DstReg is live + // here. + if (SubIdx && !Reads) + MO.setIsUndef(); + if (DstIsPhys) - MO.substPhysReg(DstReg, *tri_); + MO.substPhysReg(DstReg, *TRI); else - MO.substVirtReg(DstReg, SubIdx, *tri_); + MO.substVirtReg(DstReg, SubIdx, *TRI); } // This instruction is a copy that will be removed. @@ -817,19 +971,19 @@ RegisterCoalescer::UpdateRegDefsUses(const CoalescerPair &CP) { // If UseMI was a simple SrcReg def, make sure we didn't turn it into a // read-modify-write of DstReg. if (Deads) - UseMI->addRegisterDead(DstReg, tri_); + UseMI->addRegisterDead(DstReg, TRI); else if (!Reads && Writes) - UseMI->addRegisterDefined(DstReg, tri_); + UseMI->addRegisterDefined(DstReg, TRI); // Kill flags apply to the whole physical register. if (DstIsPhys && Kills) - UseMI->addRegisterKilled(DstReg, tri_); + UseMI->addRegisterKilled(DstReg, TRI); } DEBUG({ dbgs() << "\t\tupdated: "; if (!UseMI->isDebugValue()) - dbgs() << li_->getInstructionIndex(UseMI) << "\t"; + dbgs() << LIS->getInstructionIndex(UseMI) << "\t"; dbgs() << *UseMI; }); } @@ -838,18 +992,18 @@ RegisterCoalescer::UpdateRegDefsUses(const CoalescerPair &CP) { /// removeIntervalIfEmpty - Check if the live interval of a physical register /// is empty, if so remove it and also remove the empty intervals of its /// sub-registers. Return true if live interval is removed. -static bool removeIntervalIfEmpty(LiveInterval &li, LiveIntervals *li_, - const TargetRegisterInfo *tri_) { +static bool removeIntervalIfEmpty(LiveInterval &li, LiveIntervals *LIS, + const TargetRegisterInfo *TRI) { if (li.empty()) { if (TargetRegisterInfo::isPhysicalRegister(li.reg)) - for (const unsigned* SR = tri_->getSubRegisters(li.reg); *SR; ++SR) { - if (!li_->hasInterval(*SR)) + for (const unsigned* SR = TRI->getSubRegisters(li.reg); *SR; ++SR) { + if (!LIS->hasInterval(*SR)) continue; - LiveInterval &sli = li_->getInterval(*SR); + LiveInterval &sli = LIS->getInterval(*SR); if (sli.empty()) - li_->removeInterval(*SR); + LIS->removeInterval(*SR); } - li_->removeInterval(li.reg); + LIS->removeInterval(li.reg); return true; } return false; @@ -859,29 +1013,29 @@ static bool removeIntervalIfEmpty(LiveInterval &li, LiveIntervals *li_, /// the val# it defines. If the live interval becomes empty, remove it as well. bool RegisterCoalescer::RemoveDeadDef(LiveInterval &li, MachineInstr *DefMI) { - SlotIndex DefIdx = li_->getInstructionIndex(DefMI).getDefIndex(); + SlotIndex DefIdx = LIS->getInstructionIndex(DefMI).getDefIndex(); LiveInterval::iterator MLR = li.FindLiveRangeContaining(DefIdx); if (DefIdx != MLR->valno->def) return false; li.removeValNo(MLR->valno); - return removeIntervalIfEmpty(li, li_, tri_); + return removeIntervalIfEmpty(li, LIS, TRI); } void RegisterCoalescer::RemoveCopyFlag(unsigned DstReg, const MachineInstr *CopyMI) { - SlotIndex DefIdx = li_->getInstructionIndex(CopyMI).getDefIndex(); - if (li_->hasInterval(DstReg)) { - LiveInterval &LI = li_->getInterval(DstReg); + SlotIndex DefIdx = LIS->getInstructionIndex(CopyMI).getDefIndex(); + if (LIS->hasInterval(DstReg)) { + LiveInterval &LI = LIS->getInterval(DstReg); if (const LiveRange *LR = LI.getLiveRangeContaining(DefIdx)) if (LR->valno->def == DefIdx) LR->valno->setCopy(0); } if (!TargetRegisterInfo::isPhysicalRegister(DstReg)) return; - for (const unsigned* AS = tri_->getAliasSet(DstReg); *AS; ++AS) { - if (!li_->hasInterval(*AS)) + for (const unsigned* AS = TRI->getAliasSet(DstReg); *AS; ++AS) { + if (!LIS->hasInterval(*AS)) continue; - LiveInterval &LI = li_->getInterval(*AS); + LiveInterval &LI = LIS->getInterval(*AS); if (const LiveRange *LR = LI.getLiveRangeContaining(DefIdx)) if (LR->valno->def == DefIdx) LR->valno->setCopy(0); @@ -894,8 +1048,8 @@ void RegisterCoalescer::RemoveCopyFlag(unsigned DstReg, /// are not spillable! If the destination interval uses are far away, think /// twice about coalescing them! bool RegisterCoalescer::shouldJoinPhys(CoalescerPair &CP) { - bool Allocatable = li_->isAllocatable(CP.getDstReg()); - LiveInterval &JoinVInt = li_->getInterval(CP.getSrcReg()); + bool Allocatable = LIS->isAllocatable(CP.getDstReg()); + LiveInterval &JoinVInt = LIS->getInterval(CP.getSrcReg()); /// Always join simple intervals that are defined by a single copy from a /// reserved register. This doesn't increase register pressure, so it is @@ -918,8 +1072,8 @@ bool RegisterCoalescer::shouldJoinPhys(CoalescerPair &CP) { // Don't join with physregs that have a ridiculous number of live // ranges. The data structure performance is really bad when that // happens. - if (li_->hasInterval(CP.getDstReg()) && - li_->getInterval(CP.getDstReg()).ranges.size() > 1000) { + if (LIS->hasInterval(CP.getDstReg()) && + LIS->getInterval(CP.getDstReg()).ranges.size() > 1000) { ++numAborts; DEBUG(dbgs() << "\tPhysical register live interval too complicated, abort!\n"); @@ -929,9 +1083,9 @@ bool RegisterCoalescer::shouldJoinPhys(CoalescerPair &CP) { // FIXME: Why are we skipping this test for partial copies? // CodeGen/X86/phys_subreg_coalesce-3.ll needs it. if (!CP.isPartial()) { - const TargetRegisterClass *RC = mri_->getRegClass(CP.getSrcReg()); + const TargetRegisterClass *RC = MRI->getRegClass(CP.getSrcReg()); unsigned Threshold = RegClassInfo.getNumAllocatableRegs(RC) * 2; - unsigned Length = li_->getApproximateInstructionCount(JoinVInt); + unsigned Length = LIS->getApproximateInstructionCount(JoinVInt); if (Length > Threshold) { ++numAborts; DEBUG(dbgs() << "\tMay tie down a physical register, abort!\n"); @@ -957,12 +1111,12 @@ RegisterCoalescer::isWinToJoinCrossClass(unsigned SrcReg, // Early exit if the function is fairly small, coalesce aggressively if // that's the case. For really special register classes with 3 or // fewer registers, be a bit more careful. - (li_->getFuncInstructionCount() / NewRCCount) < 8) + (LIS->getFuncInstructionCount() / NewRCCount) < 8) return true; - LiveInterval &SrcInt = li_->getInterval(SrcReg); - LiveInterval &DstInt = li_->getInterval(DstReg); - unsigned SrcSize = li_->getApproximateInstructionCount(SrcInt); - unsigned DstSize = li_->getApproximateInstructionCount(DstInt); + LiveInterval &SrcInt = LIS->getInterval(SrcReg); + LiveInterval &DstInt = LIS->getInterval(DstReg); + unsigned SrcSize = LIS->getApproximateInstructionCount(SrcInt); + unsigned DstSize = LIS->getApproximateInstructionCount(DstInt); // Coalesce aggressively if the intervals are small compared to the number of // registers in the new class. The number 4 is fairly arbitrary, chosen to be @@ -972,10 +1126,10 @@ RegisterCoalescer::isWinToJoinCrossClass(unsigned SrcReg, return true; // Estimate *register use density*. If it doubles or more, abort. - unsigned SrcUses = std::distance(mri_->use_nodbg_begin(SrcReg), - mri_->use_nodbg_end()); - unsigned DstUses = std::distance(mri_->use_nodbg_begin(DstReg), - mri_->use_nodbg_end()); + unsigned SrcUses = std::distance(MRI->use_nodbg_begin(SrcReg), + MRI->use_nodbg_end()); + unsigned DstUses = std::distance(MRI->use_nodbg_begin(DstReg), + MRI->use_nodbg_end()); unsigned NewUses = SrcUses + DstUses; unsigned NewSize = SrcSize + DstSize; if (SrcRC != NewRC && SrcSize > ThresSize) { @@ -1003,9 +1157,9 @@ bool RegisterCoalescer::JoinCopy(MachineInstr *CopyMI, bool &Again) { if (JoinedCopies.count(CopyMI) || ReMatCopies.count(CopyMI)) return false; // Already done. - DEBUG(dbgs() << li_->getInstructionIndex(CopyMI) << '\t' << *CopyMI); + DEBUG(dbgs() << LIS->getInstructionIndex(CopyMI) << '\t' << *CopyMI); - CoalescerPair CP(*tii_, *tri_); + CoalescerPair CP(*TII, *TRI); if (!CP.setRegisters(CopyMI)) { DEBUG(dbgs() << "\tNot coalescable.\n"); return false; @@ -1018,8 +1172,15 @@ bool RegisterCoalescer::JoinCopy(MachineInstr *CopyMI, bool &Again) { return false; // Not coalescable. } - DEBUG(dbgs() << "\tConsidering merging " << PrintReg(CP.getSrcReg(), tri_) - << " with " << PrintReg(CP.getDstReg(), tri_, CP.getSubIdx()) + // Eliminate undefs. + if (!CP.isPhys() && eliminateUndefCopy(CopyMI, CP)) { + markAsJoined(CopyMI); + DEBUG(dbgs() << "\tEliminated copy of value.\n"); + return false; // Not coalescable. + } + + DEBUG(dbgs() << "\tConsidering merging " << PrintReg(CP.getSrcReg(), TRI) + << " with " << PrintReg(CP.getDstReg(), TRI, CP.getSubIdx()) << "\n"); // Enforce policies. @@ -1028,8 +1189,8 @@ bool RegisterCoalescer::JoinCopy(MachineInstr *CopyMI, bool &Again) { // Before giving up coalescing, if definition of source is defined by // trivial computation, try rematerializing it. if (!CP.isFlipped() && - ReMaterializeTrivialDef(li_->getInterval(CP.getSrcReg()), true, - CP.getDstReg(), 0, CopyMI)) + ReMaterializeTrivialDef(LIS->getInterval(CP.getSrcReg()), true, + CP.getDstReg(), CopyMI)) return true; return false; } @@ -1042,8 +1203,8 @@ bool RegisterCoalescer::JoinCopy(MachineInstr *CopyMI, bool &Again) { return false; } if (!isWinToJoinCrossClass(CP.getSrcReg(), CP.getDstReg(), - mri_->getRegClass(CP.getSrcReg()), - mri_->getRegClass(CP.getDstReg()), + MRI->getRegClass(CP.getSrcReg()), + MRI->getRegClass(CP.getDstReg()), CP.getNewRC())) { DEBUG(dbgs() << "\tAvoid coalescing to constrained register class.\n"); Again = true; // May be possible to coalesce later. @@ -1052,8 +1213,8 @@ bool RegisterCoalescer::JoinCopy(MachineInstr *CopyMI, bool &Again) { } // When possible, let DstReg be the larger interval. - if (!CP.getSubIdx() && li_->getInterval(CP.getSrcReg()).ranges.size() > - li_->getInterval(CP.getDstReg()).ranges.size()) + if (!CP.getSubIdx() && LIS->getInterval(CP.getSrcReg()).ranges.size() > + LIS->getInterval(CP.getDstReg()).ranges.size()) CP.flip(); } @@ -1067,8 +1228,8 @@ bool RegisterCoalescer::JoinCopy(MachineInstr *CopyMI, bool &Again) { // If definition of source is defined by trivial computation, try // rematerializing it. if (!CP.isFlipped() && - ReMaterializeTrivialDef(li_->getInterval(CP.getSrcReg()), true, - CP.getDstReg(), 0, CopyMI)) + ReMaterializeTrivialDef(LIS->getInterval(CP.getSrcReg()), true, + CP.getDstReg(), CopyMI)) return true; // If we can eliminate the copy without merging the live ranges, do so now. @@ -1091,7 +1252,7 @@ bool RegisterCoalescer::JoinCopy(MachineInstr *CopyMI, bool &Again) { // other. Make sure the resulting register is set to the right register class. if (CP.isCrossClass()) { ++numCrossRCs; - mri_->setRegClass(CP.getDstReg(), CP.getNewRC()); + MRI->setRegClass(CP.getDstReg(), CP.getNewRC()); } // Remember to delete the copy instruction. @@ -1105,10 +1266,10 @@ bool RegisterCoalescer::JoinCopy(MachineInstr *CopyMI, bool &Again) { SmallVector BlockSeq; // JoinIntervals invalidates the VNInfos in SrcInt, but we only need the // ranges for this, and they are preserved. - LiveInterval &SrcInt = li_->getInterval(CP.getSrcReg()); + LiveInterval &SrcInt = LIS->getInterval(CP.getSrcReg()); for (LiveInterval::const_iterator I = SrcInt.begin(), E = SrcInt.end(); I != E; ++I ) { - li_->findLiveInMBBs(I->start, I->end, BlockSeq); + LIS->findLiveInMBBs(I->start, I->end, BlockSeq); for (unsigned idx = 0, size = BlockSeq.size(); idx != size; ++idx) { MachineBasicBlock &block = *BlockSeq[idx]; if (!block.isLiveIn(CP.getDstReg())) @@ -1120,15 +1281,15 @@ bool RegisterCoalescer::JoinCopy(MachineInstr *CopyMI, bool &Again) { // SrcReg is guarateed to be the register whose live interval that is // being merged. - li_->removeInterval(CP.getSrcReg()); + LIS->removeInterval(CP.getSrcReg()); // Update regalloc hint. - tri_->UpdateRegAllocHint(CP.getSrcReg(), CP.getDstReg(), *mf_); + TRI->UpdateRegAllocHint(CP.getSrcReg(), CP.getDstReg(), *MF); DEBUG({ - LiveInterval &DstInt = li_->getInterval(CP.getDstReg()); + LiveInterval &DstInt = LIS->getInterval(CP.getDstReg()); dbgs() << "\tJoined. Result = "; - DstInt.print(dbgs(), tri_); + DstInt.print(dbgs(), TRI); dbgs() << "\n"; }); @@ -1197,6 +1358,7 @@ static unsigned ComputeUltimateVN(VNInfo *VNI, // which allows us to coalesce A and B. // VNI is the definition of B. LR is the life range of A that includes // the slot just before B. If we return true, we add "B = X" to DupCopies. +// This implies that A dominates B. static bool RegistersDefinedFromSameValue(LiveIntervals &li, const TargetRegisterInfo &tri, CoalescerPair &CP, @@ -1248,7 +1410,9 @@ static bool RegistersDefinedFromSameValue(LiveIntervals &li, // If the copies use two different value numbers of X, we cannot merge // A and B. LiveInterval &SrcInt = li.getInterval(Src); - if (SrcInt.getVNInfoAt(Other->def) != SrcInt.getVNInfoAt(VNI->def)) + // getVNInfoBefore returns NULL for undef copies. In this case, the + // optimization is still safe. + if (SrcInt.getVNInfoBefore(Other->def) != SrcInt.getVNInfoBefore(VNI->def)) return false; DupCopies.push_back(MI); @@ -1259,18 +1423,18 @@ static bool RegistersDefinedFromSameValue(LiveIntervals &li, /// JoinIntervals - Attempt to join these two intervals. On failure, this /// returns false. bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) { - LiveInterval &RHS = li_->getInterval(CP.getSrcReg()); - DEBUG({ dbgs() << "\t\tRHS = "; RHS.print(dbgs(), tri_); dbgs() << "\n"; }); + LiveInterval &RHS = LIS->getInterval(CP.getSrcReg()); + DEBUG({ dbgs() << "\t\tRHS = "; RHS.print(dbgs(), TRI); dbgs() << "\n"; }); // If a live interval is a physical register, check for interference with any // aliases. The interference check implemented here is a bit more conservative // than the full interfeence check below. We allow overlapping live ranges // only when one is a copy of the other. if (CP.isPhys()) { - for (const unsigned *AS = tri_->getAliasSet(CP.getDstReg()); *AS; ++AS){ - if (!li_->hasInterval(*AS)) + for (const unsigned *AS = TRI->getAliasSet(CP.getDstReg()); *AS; ++AS){ + if (!LIS->hasInterval(*AS)) continue; - const LiveInterval &LHS = li_->getInterval(*AS); + const LiveInterval &LHS = LIS->getInterval(*AS); LiveInterval::const_iterator LI = LHS.begin(); for (LiveInterval::const_iterator RI = RHS.begin(), RE = RHS.end(); RI != RE; ++RI) { @@ -1278,10 +1442,10 @@ bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) { // Does LHS have an overlapping live range starting before RI? if ((LI != LHS.begin() && LI[-1].end > RI->start) && (RI->start != RI->valno->def || - !CP.isCoalescable(li_->getInstructionFromIndex(RI->start)))) { + !CP.isCoalescable(LIS->getInstructionFromIndex(RI->start)))) { DEBUG({ dbgs() << "\t\tInterference from alias: "; - LHS.print(dbgs(), tri_); + LHS.print(dbgs(), TRI); dbgs() << "\n\t\tOverlap at " << RI->start << " and no copy.\n"; }); return false; @@ -1290,10 +1454,10 @@ bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) { // Check that LHS ranges beginning in this range are copies. for (; LI != LHS.end() && LI->start < RI->end; ++LI) { if (LI->start != LI->valno->def || - !CP.isCoalescable(li_->getInstructionFromIndex(LI->start))) { + !CP.isCoalescable(LIS->getInstructionFromIndex(LI->start))) { DEBUG({ dbgs() << "\t\tInterference from alias: "; - LHS.print(dbgs(), tri_); + LHS.print(dbgs(), TRI); dbgs() << "\n\t\tDef at " << LI->start << " is not a copy.\n"; }); return false; @@ -1313,8 +1477,8 @@ bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) { SmallVector DupCopies; - LiveInterval &LHS = li_->getOrCreateInterval(CP.getDstReg()); - DEBUG({ dbgs() << "\t\tLHS = "; LHS.print(dbgs(), tri_); dbgs() << "\n"; }); + LiveInterval &LHS = LIS->getOrCreateInterval(CP.getDstReg()); + DEBUG({ dbgs() << "\t\tLHS = "; LHS.print(dbgs(), TRI); dbgs() << "\n"; }); // Loop over the value numbers of the LHS, seeing if any are defined from // the RHS. @@ -1337,7 +1501,7 @@ bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) { // from the RHS interval, we can use its value #. MachineInstr *MI = VNI->getCopy(); if (!CP.isCoalescable(MI) && - !RegistersDefinedFromSameValue(*li_, *tri_, CP, VNI, lr, DupCopies)) + !RegistersDefinedFromSameValue(*LIS, *TRI, CP, VNI, lr, DupCopies)) continue; LHSValsDefinedFromRHS[VNI] = lr->valno; @@ -1364,7 +1528,7 @@ bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) { // from the LHS interval, we can use its value #. MachineInstr *MI = VNI->getCopy(); if (!CP.isCoalescable(MI) && - !RegistersDefinedFromSameValue(*li_, *tri_, CP, VNI, lr, DupCopies)) + !RegistersDefinedFromSameValue(*LIS, *TRI, CP, VNI, lr, DupCopies)) continue; RHSValsDefinedFromLHS[VNI] = lr->valno; @@ -1486,7 +1650,7 @@ bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) { // and mark the X as coalesced to keep the illusion. unsigned Src = MI->getOperand(1).getReg(); SourceRegisters.push_back(Src); - MI->getOperand(0).substVirtReg(Src, 0, *tri_); + MI->getOperand(0).substVirtReg(Src, 0, *TRI); markAsJoined(MI); } @@ -1495,13 +1659,13 @@ bool RegisterCoalescer::JoinIntervals(CoalescerPair &CP) { // that B = X is gone. for (SmallVector::iterator I = SourceRegisters.begin(), E = SourceRegisters.end(); I != E; ++I) { - li_->shrinkToUses(&li_->getInterval(*I)); + LIS->shrinkToUses(&LIS->getInterval(*I)); } // If we get here, we know that we can coalesce the live ranges. Ask the // intervals to coalesce themselves now. LHS.join(RHS, &LHSValNoAssignments[0], &RHSValNoAssignments[0], NewVNInfo, - mri_); + MRI); return true; } @@ -1552,7 +1716,7 @@ void RegisterCoalescer::CopyCoalesceInMBB(MachineBasicBlock *MBB, bool SrcIsPhys = TargetRegisterInfo::isPhysicalRegister(SrcReg); bool DstIsPhys = TargetRegisterInfo::isPhysicalRegister(DstReg); - if (li_->hasInterval(SrcReg) && li_->getInterval(SrcReg).empty()) + if (LIS->hasInterval(SrcReg) && LIS->getInterval(SrcReg).empty()) ImpDefCopies.push_back(Inst); else if (SrcIsPhys || DstIsPhys) PhysCopies.push_back(Inst); @@ -1590,9 +1754,9 @@ void RegisterCoalescer::joinIntervals() { DEBUG(dbgs() << "********** JOINING INTERVALS ***********\n"); std::vector TryAgainList; - if (loopInfo->empty()) { + if (Loops->empty()) { // If there are no loops in the function, join intervals in function order. - for (MachineFunction::iterator I = mf_->begin(), E = mf_->end(); + for (MachineFunction::iterator I = MF->begin(), E = MF->end(); I != E; ++I) CopyCoalesceInMBB(I, TryAgainList); } else { @@ -1603,9 +1767,9 @@ void RegisterCoalescer::joinIntervals() { // Join intervals in the function prolog first. We want to join physical // registers with virtual registers before the intervals got too long. std::vector > MBBs; - for (MachineFunction::iterator I = mf_->begin(), E = mf_->end();I != E;++I){ + for (MachineFunction::iterator I = MF->begin(), E = MF->end();I != E;++I){ MachineBasicBlock *MBB = I; - MBBs.push_back(std::make_pair(loopInfo->getLoopDepth(MBB), I)); + MBBs.push_back(std::make_pair(Loops->getLoopDepth(MBB), I)); } // Sort by loop depth. @@ -1644,22 +1808,22 @@ void RegisterCoalescer::releaseMemory() { } bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { - mf_ = &fn; - mri_ = &fn.getRegInfo(); - tm_ = &fn.getTarget(); - tri_ = tm_->getRegisterInfo(); - tii_ = tm_->getInstrInfo(); - li_ = &getAnalysis(); - ldv_ = &getAnalysis(); + MF = &fn; + MRI = &fn.getRegInfo(); + TM = &fn.getTarget(); + TRI = TM->getRegisterInfo(); + TII = TM->getInstrInfo(); + LIS = &getAnalysis(); + LDV = &getAnalysis(); AA = &getAnalysis(); - loopInfo = &getAnalysis(); + Loops = &getAnalysis(); DEBUG(dbgs() << "********** SIMPLE REGISTER COALESCING **********\n" << "********** Function: " - << ((Value*)mf_->getFunction())->getName() << '\n'); + << ((Value*)MF->getFunction())->getName() << '\n'); if (VerifyCoalescing) - mf_->verify(this, "Before register coalescing"); + MF->verify(this, "Before register coalescing"); RegClassInfo.runOnMachineFunction(fn); @@ -1668,9 +1832,9 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { joinIntervals(); DEBUG({ dbgs() << "********** INTERVALS POST JOINING **********\n"; - for (LiveIntervals::iterator I = li_->begin(), E = li_->end(); + for (LiveIntervals::iterator I = LIS->begin(), E = LIS->end(); I != E; ++I){ - I->second->print(dbgs(), tri_); + I->second->print(dbgs(), TRI); dbgs() << "\n"; } }); @@ -1678,8 +1842,8 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { // Perform a final pass over the instructions and compute spill weights // and remove identity moves. - SmallVector DeadDefs; - for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end(); + SmallVector DeadDefs, InflateRegs; + for (MachineFunction::iterator mbbi = MF->begin(), mbbe = MF->end(); mbbi != mbbe; ++mbbi) { MachineBasicBlock* mbb = mbbi; for (MachineBasicBlock::iterator mii = mbb->begin(), mie = mbb->end(); @@ -1690,6 +1854,16 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { bool DoDelete = true; assert(MI->isCopyLike() && "Unrecognized copy instruction"); unsigned SrcReg = MI->getOperand(MI->isSubregToReg() ? 2 : 1).getReg(); + unsigned DstReg = MI->getOperand(0).getReg(); + + // Collect candidates for register class inflation. + if (TargetRegisterInfo::isVirtualRegister(SrcReg) && + RegClassInfo.isProperSubClass(MRI->getRegClass(SrcReg))) + InflateRegs.push_back(SrcReg); + if (TargetRegisterInfo::isVirtualRegister(DstReg) && + RegClassInfo.isProperSubClass(MRI->getRegClass(DstReg))) + InflateRegs.push_back(DstReg); + if (TargetRegisterInfo::isPhysicalRegister(SrcReg) && MI->getNumOperands() > 2) // Do not delete extract_subreg, insert_subreg of physical @@ -1701,8 +1875,8 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { if (MI->allDefsAreDead()) { if (TargetRegisterInfo::isVirtualRegister(SrcReg) && - li_->hasInterval(SrcReg)) - li_->shrinkToUses(&li_->getInterval(SrcReg)); + LIS->hasInterval(SrcReg)) + LIS->shrinkToUses(&LIS->getInterval(SrcReg)); DoDelete = true; } if (!DoDelete) { @@ -1711,10 +1885,10 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { MI->RemoveOperand(3); MI->RemoveOperand(1); } - MI->setDesc(tii_->get(TargetOpcode::KILL)); + MI->setDesc(TII->get(TargetOpcode::KILL)); mii = llvm::next(mii); } else { - li_->RemoveMachineInstrFromMaps(MI); + LIS->RemoveMachineInstrFromMaps(MI); mii = mbbi->erase(mii); ++numPeep; } @@ -1731,12 +1905,16 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { unsigned Reg = MO.getReg(); if (!Reg) continue; - if (TargetRegisterInfo::isVirtualRegister(Reg)) + if (TargetRegisterInfo::isVirtualRegister(Reg)) { DeadDefs.push_back(Reg); + // Remat may also enable register class inflation. + if (RegClassInfo.isProperSubClass(MRI->getRegClass(Reg))) + InflateRegs.push_back(Reg); + } if (MO.isDead()) continue; if (TargetRegisterInfo::isPhysicalRegister(Reg) || - !mri_->use_nodbg_empty(Reg)) { + !MRI->use_nodbg_empty(Reg)) { isDead = false; break; } @@ -1745,9 +1923,9 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { while (!DeadDefs.empty()) { unsigned DeadDef = DeadDefs.back(); DeadDefs.pop_back(); - RemoveDeadDef(li_->getInterval(DeadDef), MI); + RemoveDeadDef(LIS->getInterval(DeadDef), MI); } - li_->RemoveMachineInstrFromMaps(mii); + LIS->RemoveMachineInstrFromMaps(mii); mii = mbbi->erase(mii); continue; } else @@ -1757,14 +1935,14 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { ++mii; // Check for now unnecessary kill flags. - if (li_->isNotInMIMap(MI)) continue; - SlotIndex DefIdx = li_->getInstructionIndex(MI).getDefIndex(); + if (LIS->isNotInMIMap(MI)) continue; + SlotIndex DefIdx = LIS->getInstructionIndex(MI).getDefIndex(); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); if (!MO.isReg() || !MO.isKill()) continue; unsigned reg = MO.getReg(); - if (!reg || !li_->hasInterval(reg)) continue; - if (!li_->getInterval(reg).killedAt(DefIdx)) { + if (!reg || !LIS->hasInterval(reg)) continue; + if (!LIS->getInterval(reg).killedAt(DefIdx)) { MO.setIsKill(false); continue; } @@ -1772,26 +1950,40 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { // remain alive. if (!TargetRegisterInfo::isPhysicalRegister(reg)) continue; - for (const unsigned *SR = tri_->getSubRegisters(reg); + for (const unsigned *SR = TRI->getSubRegisters(reg); unsigned S = *SR; ++SR) - if (li_->hasInterval(S) && li_->getInterval(S).liveAt(DefIdx)) - MI->addRegisterDefined(S, tri_); + if (LIS->hasInterval(S) && LIS->getInterval(S).liveAt(DefIdx)) + MI->addRegisterDefined(S, TRI); } } } + // After deleting a lot of copies, register classes may be less constrained. + // Removing sub-register opreands may alow GR32_ABCD -> GR32 and DPR_VFP2 -> + // DPR inflation. + array_pod_sort(InflateRegs.begin(), InflateRegs.end()); + InflateRegs.erase(std::unique(InflateRegs.begin(), InflateRegs.end()), + InflateRegs.end()); + DEBUG(dbgs() << "Trying to inflate " << InflateRegs.size() << " regs.\n"); + for (unsigned i = 0, e = InflateRegs.size(); i != e; ++i) { + unsigned Reg = InflateRegs[i]; + if (MRI->reg_nodbg_empty(Reg)) + continue; + if (MRI->recomputeRegClass(Reg, *TM)) { + DEBUG(dbgs() << PrintReg(Reg) << " inflated to " + << MRI->getRegClass(Reg)->getName() << '\n'); + ++NumInflated; + } + } + DEBUG(dump()); - DEBUG(ldv_->dump()); + DEBUG(LDV->dump()); if (VerifyCoalescing) - mf_->verify(this, "After register coalescing"); + MF->verify(this, "After register coalescing"); return true; } /// print - Implement the dump method. void RegisterCoalescer::print(raw_ostream &O, const Module* m) const { - li_->print(O, m); -} - -RegisterCoalescer *llvm::createRegisterCoalescer() { - return new RegisterCoalescer(); + LIS->print(O, m); } diff --git a/lib/CodeGen/RegisterCoalescer.h b/lib/CodeGen/RegisterCoalescer.h index 4131d91c00e9..472c48377fef 100644 --- a/lib/CodeGen/RegisterCoalescer.h +++ b/lib/CodeGen/RegisterCoalescer.h @@ -12,198 +12,60 @@ // //===----------------------------------------------------------------------===// -#include "RegisterClassInfo.h" -#include "llvm/Support/IncludeFile.h" -#include "llvm/CodeGen/LiveInterval.h" -#include "llvm/ADT/SmallPtrSet.h" - #ifndef LLVM_CODEGEN_REGISTER_COALESCER_H #define LLVM_CODEGEN_REGISTER_COALESCER_H namespace llvm { - class MachineFunction; - class RegallocQuery; - class AnalysisUsage; class MachineInstr; class TargetRegisterInfo; class TargetRegisterClass; class TargetInstrInfo; - class LiveDebugVariables; - class VirtRegMap; - class MachineLoopInfo; - - class CoalescerPair; - - /// An abstract interface for register coalescers. Coalescers must - /// implement this interface to be part of the coalescer analysis - /// group. - class RegisterCoalescer : public MachineFunctionPass { - MachineFunction* mf_; - MachineRegisterInfo* mri_; - const TargetMachine* tm_; - const TargetRegisterInfo* tri_; - const TargetInstrInfo* tii_; - LiveIntervals *li_; - LiveDebugVariables *ldv_; - const MachineLoopInfo* loopInfo; - AliasAnalysis *AA; - RegisterClassInfo RegClassInfo; - - /// JoinedCopies - Keep track of copies eliminated due to coalescing. - /// - SmallPtrSet JoinedCopies; - - /// ReMatCopies - Keep track of copies eliminated due to remat. - /// - SmallPtrSet ReMatCopies; - - /// ReMatDefs - Keep track of definition instructions which have - /// been remat'ed. - SmallPtrSet ReMatDefs; - - /// joinIntervals - join compatible live intervals - void joinIntervals(); - - /// CopyCoalesceInMBB - Coalesce copies in the specified MBB, putting - /// copies that cannot yet be coalesced into the "TryAgain" list. - void CopyCoalesceInMBB(MachineBasicBlock *MBB, - std::vector &TryAgain); - - /// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg, - /// which are the src/dst of the copy instruction CopyMI. This returns true - /// if the copy was successfully coalesced away. If it is not currently - /// possible to coalesce this interval, but it may be possible if other - /// things get coalesced, then it returns true by reference in 'Again'. - bool JoinCopy(MachineInstr *TheCopy, bool &Again); - - /// JoinIntervals - Attempt to join these two intervals. On failure, this - /// returns false. The output "SrcInt" will not have been modified, so we can - /// use this information below to update aliases. - bool JoinIntervals(CoalescerPair &CP); - - /// AdjustCopiesBackFrom - We found a non-trivially-coalescable copy. If - /// the source value number is defined by a copy from the destination reg - /// see if we can merge these two destination reg valno# into a single - /// value number, eliminating a copy. - bool AdjustCopiesBackFrom(const CoalescerPair &CP, MachineInstr *CopyMI); - - /// HasOtherReachingDefs - Return true if there are definitions of IntB - /// other than BValNo val# that can reach uses of AValno val# of IntA. - bool HasOtherReachingDefs(LiveInterval &IntA, LiveInterval &IntB, - VNInfo *AValNo, VNInfo *BValNo); - - /// RemoveCopyByCommutingDef - We found a non-trivially-coalescable copy. - /// If the source value number is defined by a commutable instruction and - /// its other operand is coalesced to the copy dest register, see if we - /// can transform the copy into a noop by commuting the definition. - bool RemoveCopyByCommutingDef(const CoalescerPair &CP,MachineInstr *CopyMI); - - /// ReMaterializeTrivialDef - If the source of a copy is defined by a trivial - /// computation, replace the copy by rematerialize the definition. - /// If PreserveSrcInt is true, make sure SrcInt is valid after the call. - bool ReMaterializeTrivialDef(LiveInterval &SrcInt, bool PreserveSrcInt, - unsigned DstReg, unsigned DstSubIdx, - MachineInstr *CopyMI); - - /// shouldJoinPhys - Return true if a physreg copy should be joined. - bool shouldJoinPhys(CoalescerPair &CP); - - /// isWinToJoinCrossClass - Return true if it's profitable to coalesce - /// two virtual registers from different register classes. - bool isWinToJoinCrossClass(unsigned SrcReg, - unsigned DstReg, - const TargetRegisterClass *SrcRC, - const TargetRegisterClass *DstRC, - const TargetRegisterClass *NewRC); - - /// UpdateRegDefsUses - Replace all defs and uses of SrcReg to DstReg and - /// update the subregister number if it is not zero. If DstReg is a - /// physical register and the existing subregister number of the def / use - /// being updated is not zero, make sure to set it to the correct physical - /// subregister. - void UpdateRegDefsUses(const CoalescerPair &CP); - - /// RemoveDeadDef - If a def of a live interval is now determined dead, - /// remove the val# it defines. If the live interval becomes empty, remove - /// it as well. - bool RemoveDeadDef(LiveInterval &li, MachineInstr *DefMI); - - /// RemoveCopyFlag - If DstReg is no longer defined by CopyMI, clear the - /// VNInfo copy flag for DstReg and all aliases. - void RemoveCopyFlag(unsigned DstReg, const MachineInstr *CopyMI); - - /// markAsJoined - Remember that CopyMI has already been joined. - void markAsJoined(MachineInstr *CopyMI); - - public: - static char ID; // Class identification, replacement for typeinfo - RegisterCoalescer() : MachineFunctionPass(ID) { - initializeRegisterCoalescerPass(*PassRegistry::getPassRegistry()); - } - - /// Register allocators must call this from their own - /// getAnalysisUsage to cover the case where the coalescer is not - /// a Pass in the proper sense and isn't managed by PassManager. - /// PassManager needs to know which analyses to make available and - /// which to invalidate when running the register allocator or any - /// pass that might call coalescing. The long-term solution is to - /// allow hierarchies of PassManagers. - virtual void getAnalysisUsage(AnalysisUsage &AU) const; - - virtual void releaseMemory(); - - /// runOnMachineFunction - pass entry point - virtual bool runOnMachineFunction(MachineFunction&); - - /// print - Implement the dump method. - virtual void print(raw_ostream &O, const Module* = 0) const; - }; /// CoalescerPair - A helper class for register coalescers. When deciding if /// two registers can be coalesced, CoalescerPair can determine if a copy /// instruction would become an identity copy after coalescing. class CoalescerPair { - const TargetInstrInfo &tii_; - const TargetRegisterInfo &tri_; + const TargetInstrInfo &TII; + const TargetRegisterInfo &TRI; - /// dstReg_ - The register that will be left after coalescing. It can be a + /// DstReg - The register that will be left after coalescing. It can be a /// virtual or physical register. - unsigned dstReg_; + unsigned DstReg; - /// srcReg_ - the virtual register that will be coalesced into dstReg. - unsigned srcReg_; + /// SrcReg - the virtual register that will be coalesced into dstReg. + unsigned SrcReg; - /// subReg_ - The subregister index of srcReg in dstReg_. It is possible the - /// coalesce srcReg_ into a subreg of the larger dstReg_ when dstReg_ is a + /// subReg_ - The subregister index of srcReg in DstReg. It is possible the + /// coalesce SrcReg into a subreg of the larger DstReg when DstReg is a /// virtual register. - unsigned subIdx_; + unsigned SubIdx; - /// partial_ - True when the original copy was a partial subregister copy. - bool partial_; + /// Partial - True when the original copy was a partial subregister copy. + bool Partial; - /// crossClass_ - True when both regs are virtual, and newRC is constrained. - bool crossClass_; + /// CrossClass - True when both regs are virtual, and newRC is constrained. + bool CrossClass; - /// flipped_ - True when DstReg and SrcReg are reversed from the oriignal copy - /// instruction. - bool flipped_; + /// Flipped - True when DstReg and SrcReg are reversed from the oriignal + /// copy instruction. + bool Flipped; - /// newRC_ - The register class of the coalesced register, or NULL if dstReg_ + /// NewRC - The register class of the coalesced register, or NULL if DstReg /// is a physreg. - const TargetRegisterClass *newRC_; + const TargetRegisterClass *NewRC; public: CoalescerPair(const TargetInstrInfo &tii, const TargetRegisterInfo &tri) - : tii_(tii), tri_(tri), dstReg_(0), srcReg_(0), subIdx_(0), - partial_(false), crossClass_(false), flipped_(false), newRC_(0) {} + : TII(tii), TRI(tri), DstReg(0), SrcReg(0), SubIdx(0), + Partial(false), CrossClass(false), Flipped(false), NewRC(0) {} /// setRegisters - set registers to match the copy instruction MI. Return /// false if MI is not a coalescable copy instruction. bool setRegisters(const MachineInstr*); - /// flip - Swap srcReg_ and dstReg_. Return false if swapping is impossible - /// because dstReg_ is a physical register, or subIdx_ is set. + /// flip - Swap SrcReg and DstReg. Return false if swapping is impossible + /// because DstReg is a physical register, or SubIdx is set. bool flip(); /// isCoalescable - Return true if MI is a copy instruction that will become @@ -211,32 +73,33 @@ namespace llvm { bool isCoalescable(const MachineInstr*) const; /// isPhys - Return true if DstReg is a physical register. - bool isPhys() const { return !newRC_; } + bool isPhys() const { return !NewRC; } - /// isPartial - Return true if the original copy instruction did not copy the - /// full register, but was a subreg operation. - bool isPartial() const { return partial_; } + /// isPartial - Return true if the original copy instruction did not copy + /// the full register, but was a subreg operation. + bool isPartial() const { return Partial; } - /// isCrossClass - Return true if DstReg is virtual and NewRC is a smaller register class than DstReg's. - bool isCrossClass() const { return crossClass_; } + /// isCrossClass - Return true if DstReg is virtual and NewRC is a smaller + /// register class than DstReg's. + bool isCrossClass() const { return CrossClass; } /// isFlipped - Return true when getSrcReg is the register being defined by /// the original copy instruction. - bool isFlipped() const { return flipped_; } + bool isFlipped() const { return Flipped; } /// getDstReg - Return the register (virtual or physical) that will remain /// after coalescing. - unsigned getDstReg() const { return dstReg_; } + unsigned getDstReg() const { return DstReg; } /// getSrcReg - Return the virtual register that will be coalesced away. - unsigned getSrcReg() const { return srcReg_; } + unsigned getSrcReg() const { return SrcReg; } /// getSubIdx - Return the subregister index in DstReg that SrcReg will be /// coalesced into, or 0. - unsigned getSubIdx() const { return subIdx_; } + unsigned getSubIdx() const { return SubIdx; } /// getNewRC - Return the register class of the coalesced register. - const TargetRegisterClass *getNewRC() const { return newRC_; } + const TargetRegisterClass *getNewRC() const { return NewRC; } }; } // End llvm namespace diff --git a/lib/CodeGen/RegisterScavenging.cpp b/lib/CodeGen/RegisterScavenging.cpp index 9e9a145b0aa4..ca02aa1b8143 100644 --- a/lib/CodeGen/RegisterScavenging.cpp +++ b/lib/CodeGen/RegisterScavenging.cpp @@ -206,6 +206,7 @@ void RegScavenger::forward() { break; } assert(SubUsed && "Using an undefined register!"); + (void)SubUsed; } assert((!EarlyClobberRegs.test(Reg) || MI->isRegTiedToDefOperand(i)) && "Using an early clobbered register!"); diff --git a/lib/CodeGen/ScheduleDAG.cpp b/lib/CodeGen/ScheduleDAG.cpp index 21375b286c99..1e9b5c89f172 100644 --- a/lib/CodeGen/ScheduleDAG.cpp +++ b/lib/CodeGen/ScheduleDAG.cpp @@ -26,7 +26,7 @@ using namespace llvm; #ifndef NDEBUG -cl::opt StressSchedOpt( +static cl::opt StressSchedOpt( "stress-sched", cl::Hidden, cl::init(false), cl::desc("Stress test instruction scheduling")); #endif @@ -140,6 +140,7 @@ void SUnit::removePred(const SDep &D) { break; } assert(FoundSucc && "Mismatching preds / succs lists!"); + (void)FoundSucc; Preds.erase(I); // Update the bookkeeping. if (P.getKind() == SDep::Data) { diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp index 446adfc2b626..34b8ab0b47f2 100644 --- a/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -36,7 +36,7 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf, const MachineDominatorTree &mdt) : ScheduleDAG(mf), MLI(mli), MDT(mdt), MFI(mf.getFrameInfo()), InstrItins(mf.getTarget().getInstrItineraryData()), - Defs(TRI->getNumRegs()), Uses(TRI->getNumRegs()), + Defs(TRI->getNumRegs()), Uses(TRI->getNumRegs()), LoopRegs(MLI, MDT), FirstDbgValue(0) { DbgValues.clear(); } @@ -134,6 +134,7 @@ static const Value *getUnderlyingObjectForInstr(const MachineInstr *MI, } void ScheduleDAGInstrs::StartBlock(MachineBasicBlock *BB) { + LoopRegs.Deps.clear(); if (MachineLoop *ML = MLI.getLoopFor(BB)) if (BB == ML->getLoopLatch()) { MachineBasicBlock *Header = ML->getHeader(); diff --git a/lib/CodeGen/ScheduleDAGInstrs.h b/lib/CodeGen/ScheduleDAGInstrs.h index 8a4ea855235c..666bdf548c71 100644 --- a/lib/CodeGen/ScheduleDAGInstrs.h +++ b/lib/CodeGen/ScheduleDAGInstrs.h @@ -48,7 +48,8 @@ namespace llvm { /// VisitLoop - Clear out any previous state and analyze the given loop. /// void VisitLoop(const MachineLoop *Loop) { - Deps.clear(); + assert(Deps.empty() && "stale loop dependencies"); + MachineBasicBlock *Header = Loop->getHeader(); SmallSet LoopLiveIns; for (MachineBasicBlock::livein_iterator LI = Header->livein_begin(), @@ -109,7 +110,7 @@ namespace llvm { /// initialized and destructed for each block. std::vector > Defs; std::vector > Uses; - + /// PendingLoads - Remember where unknown loads are after the most recent /// unknown store, as we iterate. As with Defs and Uses, this is here /// to minimize construction/destruction. @@ -127,7 +128,7 @@ namespace llvm { protected: /// DbgValues - Remember instruction that preceeds DBG_VALUE. - typedef std::vector > + typedef std::vector > DbgValueVector; DbgValueVector DbgValues; MachineInstr *FirstDbgValue; diff --git a/lib/CodeGen/ScoreboardHazardRecognizer.cpp b/lib/CodeGen/ScoreboardHazardRecognizer.cpp index 0e005d35189d..b80c01ed58b9 100644 --- a/lib/CodeGen/ScoreboardHazardRecognizer.cpp +++ b/lib/CodeGen/ScoreboardHazardRecognizer.cpp @@ -213,7 +213,6 @@ void ScoreboardHazardRecognizer::EmitInstruction(SUnit *SU) { freeUnits = freeUnit & (freeUnit - 1); } while (freeUnits); - assert(freeUnit && "No function unit available!"); if (IS->getReservationKind() == InstrStage::Required) RequiredScoreboard[cycle + i] |= freeUnit; else diff --git a/lib/CodeGen/SelectionDAG/CMakeLists.txt b/lib/CodeGen/SelectionDAG/CMakeLists.txt index 15932c03a190..2282f0e6eb83 100644 --- a/lib/CodeGen/SelectionDAG/CMakeLists.txt +++ b/lib/CodeGen/SelectionDAG/CMakeLists.txt @@ -21,3 +21,13 @@ add_llvm_library(LLVMSelectionDAG TargetLowering.cpp TargetSelectionDAGInfo.cpp ) + +add_llvm_library_dependencies(LLVMSelectionDAG + LLVMAnalysis + LLVMCodeGen + LLVMCore + LLVMMC + LLVMSupport + LLVMTarget + LLVMTransformUtils + ) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 4f0d2caca22b..7b878688df63 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -216,6 +216,7 @@ namespace { SDValue visitEXTRACT_VECTOR_ELT(SDNode *N); SDValue visitBUILD_VECTOR(SDNode *N); SDValue visitCONCAT_VECTORS(SDNode *N); + SDValue visitEXTRACT_SUBVECTOR(SDNode *N); SDValue visitVECTOR_SHUFFLE(SDNode *N); SDValue visitMEMBARRIER(SDNode *N); @@ -1105,6 +1106,7 @@ SDValue DAGCombiner::visit(SDNode *N) { case ISD::EXTRACT_VECTOR_ELT: return visitEXTRACT_VECTOR_ELT(N); case ISD::BUILD_VECTOR: return visitBUILD_VECTOR(N); case ISD::CONCAT_VECTORS: return visitCONCAT_VECTORS(N); + case ISD::EXTRACT_SUBVECTOR: return visitEXTRACT_SUBVECTOR(N); case ISD::VECTOR_SHUFFLE: return visitVECTOR_SHUFFLE(N); case ISD::MEMBARRIER: return visitMEMBARRIER(N); } @@ -1526,12 +1528,6 @@ SDValue DAGCombiner::visitADDE(SDNode *N) { ConstantSDNode *N0C = dyn_cast(N0); ConstantSDNode *N1C = dyn_cast(N1); - // If both operands are null we know that carry out will always be false. - if (N0C && N0C->isNullValue() && N0 == N1) - DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), DAG.getNode(ISD::CARRY_FALSE, - N->getDebugLoc(), - MVT::Glue)); - // canonicalize constant to RHS if (N0C && !N1C) return DAG.getNode(ISD::ADDE, N->getDebugLoc(), N->getVTList(), @@ -3763,7 +3759,7 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) { if (VT.isInteger() && (VT0 == MVT::i1 || (VT0.isInteger() && - TLI.getBooleanContents() == TargetLowering::ZeroOrOneBooleanContent)) && + TLI.getBooleanContents(false) == TargetLowering::ZeroOrOneBooleanContent)) && N1C && N2C && N1C->isNullValue() && N2C->getAPIntValue() == 1) { SDValue XORNode; if (VT == VT0) @@ -4118,7 +4114,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { // we know that the element size of the sext'd result matches the // element size of the compare operands. if (VT.getSizeInBits() == N0VT.getSizeInBits()) - return DAG.getVSetCC(N->getDebugLoc(), VT, N0.getOperand(0), + return DAG.getSetCC(N->getDebugLoc(), VT, N0.getOperand(0), N0.getOperand(1), cast(N0.getOperand(2))->get()); // If the desired elements are smaller or larger than the source @@ -4132,7 +4128,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { EVT::getVectorVT(*DAG.getContext(), MatchingElementType, N0VT.getVectorNumElements()); SDValue VsetCC = - DAG.getVSetCC(N->getDebugLoc(), MatchingVectorType, N0.getOperand(0), + DAG.getSetCC(N->getDebugLoc(), MatchingVectorType, N0.getOperand(0), N0.getOperand(1), cast(N0.getOperand(2))->get()); return DAG.getSExtOrTrunc(VsetCC, N->getDebugLoc(), VT); @@ -4348,7 +4344,7 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { // we know that the element size of the sext'd result matches the // element size of the compare operands. return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, - DAG.getVSetCC(N->getDebugLoc(), VT, N0.getOperand(0), + DAG.getSetCC(N->getDebugLoc(), VT, N0.getOperand(0), N0.getOperand(1), cast(N0.getOperand(2))->get()), DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT, @@ -4364,7 +4360,7 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { EVT::getVectorVT(*DAG.getContext(), MatchingElementType, N0VT.getVectorNumElements()); SDValue VsetCC = - DAG.getVSetCC(N->getDebugLoc(), MatchingVectorType, N0.getOperand(0), + DAG.getSetCC(N->getDebugLoc(), MatchingVectorType, N0.getOperand(0), N0.getOperand(1), cast(N0.getOperand(2))->get()); return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, @@ -4532,7 +4528,7 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { // we know that the element size of the sext'd result matches the // element size of the compare operands. if (VT.getSizeInBits() == N0VT.getSizeInBits()) - return DAG.getVSetCC(N->getDebugLoc(), VT, N0.getOperand(0), + return DAG.getSetCC(N->getDebugLoc(), VT, N0.getOperand(0), N0.getOperand(1), cast(N0.getOperand(2))->get()); // If the desired elements are smaller or larger than the source @@ -4546,7 +4542,7 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { EVT::getVectorVT(*DAG.getContext(), MatchingElementType, N0VT.getVectorNumElements()); SDValue VsetCC = - DAG.getVSetCC(N->getDebugLoc(), MatchingVectorType, N0.getOperand(0), + DAG.getSetCC(N->getDebugLoc(), MatchingVectorType, N0.getOperand(0), N0.getOperand(1), cast(N0.getOperand(2))->get()); return DAG.getSExtOrTrunc(VsetCC, N->getDebugLoc(), VT); @@ -6479,7 +6475,7 @@ SDValue DAGCombiner::ReduceLoadOpStoreWidth(SDNode *N) { PtrOff = (BitWidth + 7 - NewBW) / 8 - PtrOff; unsigned NewAlign = MinAlign(LD->getAlignment(), PtrOff); - const Type *NewVTTy = NewVT.getTypeForEVT(*DAG.getContext()); + Type *NewVTTy = NewVT.getTypeForEVT(*DAG.getContext()); if (NewAlign < TLI.getTargetData()->getABITypeAlignment(NewVTTy)) return SDValue(); @@ -6542,7 +6538,7 @@ SDValue DAGCombiner::TransformFPLoadStorePair(SDNode *N) { unsigned LDAlign = LD->getAlignment(); unsigned STAlign = ST->getAlignment(); - const Type *IntVTTy = IntVT.getTypeForEVT(*DAG.getContext()); + Type *IntVTTy = IntVT.getTypeForEVT(*DAG.getContext()); unsigned ABIAlign = TLI.getTargetData()->getABITypeAlignment(IntVTTy); if (LDAlign < ABIAlign || STAlign < ABIAlign) return SDValue(); @@ -6776,6 +6772,7 @@ SDValue DAGCombiner::visitINSERT_VECTOR_ELT(SDNode *N) { SDValue InVec = N->getOperand(0); SDValue InVal = N->getOperand(1); SDValue EltNo = N->getOperand(2); + DebugLoc dl = N->getDebugLoc(); // If the inserted element is an UNDEF, just use the input vector. if (InVal.getOpcode() == ISD::UNDEF) @@ -6787,32 +6784,40 @@ SDValue DAGCombiner::visitINSERT_VECTOR_ELT(SDNode *N) { if (LegalOperations && !TLI.isOperationLegal(ISD::BUILD_VECTOR, VT)) return SDValue(); - // If the invec is a BUILD_VECTOR and if EltNo is a constant, build a new - // vector with the inserted element. - if (InVec.getOpcode() == ISD::BUILD_VECTOR && isa(EltNo)) { - unsigned Elt = cast(EltNo)->getZExtValue(); - SmallVector Ops(InVec.getNode()->op_begin(), - InVec.getNode()->op_end()); - if (Elt < Ops.size()) - Ops[Elt] = InVal; - return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), - VT, &Ops[0], Ops.size()); - } - // If the invec is an UNDEF and if EltNo is a constant, create a new - // BUILD_VECTOR with undef elements and the inserted element. - if (InVec.getOpcode() == ISD::UNDEF && - isa(EltNo)) { - EVT EltVT = VT.getVectorElementType(); - unsigned NElts = VT.getVectorNumElements(); - SmallVector Ops(NElts, DAG.getUNDEF(EltVT)); + // Check that we know which element is being inserted + if (!isa(EltNo)) + return SDValue(); + unsigned Elt = cast(EltNo)->getZExtValue(); - unsigned Elt = cast(EltNo)->getZExtValue(); - if (Elt < Ops.size()) - Ops[Elt] = InVal; - return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), - VT, &Ops[0], Ops.size()); + // Check that the operand is a BUILD_VECTOR (or UNDEF, which can essentially + // be converted to a BUILD_VECTOR). Fill in the Ops vector with the + // vector elements. + SmallVector Ops; + if (InVec.getOpcode() == ISD::BUILD_VECTOR) { + Ops.append(InVec.getNode()->op_begin(), + InVec.getNode()->op_end()); + } else if (InVec.getOpcode() == ISD::UNDEF) { + unsigned NElts = VT.getVectorNumElements(); + Ops.append(NElts, DAG.getUNDEF(InVal.getValueType())); + } else { + return SDValue(); } - return SDValue(); + + // Insert the element + if (Elt < Ops.size()) { + // All the operands of BUILD_VECTOR must have the same type; + // we enforce that here. + EVT OpVT = Ops[0].getValueType(); + if (InVal.getValueType() != OpVT) + InVal = OpVT.bitsGT(InVal.getValueType()) ? + DAG.getNode(ISD::ANY_EXTEND, dl, OpVT, InVal) : + DAG.getNode(ISD::TRUNCATE, dl, OpVT, InVal); + Ops[Elt] = InVal; + } + + // Return the new vector + return DAG.getNode(ISD::BUILD_VECTOR, dl, + VT, &Ops[0], Ops.size()); } SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) { @@ -6896,7 +6901,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) { // If Idx was -1 above, Elt is going to be -1, so just return undef. if (Elt == -1) - return DAG.getUNDEF(LN0->getBasePtr().getValueType()); + return DAG.getUNDEF(LVT); unsigned Align = LN0->getAlignment(); if (NewLoad) { @@ -7028,6 +7033,36 @@ SDValue DAGCombiner::visitCONCAT_VECTORS(SDNode *N) { return SDValue(); } +SDValue DAGCombiner::visitEXTRACT_SUBVECTOR(SDNode* N) { + EVT NVT = N->getValueType(0); + SDValue V = N->getOperand(0); + + if (V->getOpcode() == ISD::INSERT_SUBVECTOR) { + // Handle only simple case where vector being inserted and vector + // being extracted are of same type, and are half size of larger vectors. + EVT BigVT = V->getOperand(0).getValueType(); + EVT SmallVT = V->getOperand(1).getValueType(); + if (NVT != SmallVT || NVT.getSizeInBits()*2 != BigVT.getSizeInBits()) + return SDValue(); + + // Combine: + // (extract_subvec (insert_subvec V1, V2, InsIdx), ExtIdx) + // Into: + // indicies are equal => V1 + // otherwise => (extract_subvec V1, ExtIdx) + // + SDValue InsIdx = N->getOperand(1); + SDValue ExtIdx = V->getOperand(2); + + if (InsIdx == ExtIdx) + return V->getOperand(1); + return DAG.getNode(ISD::EXTRACT_SUBVECTOR, N->getDebugLoc(), NVT, + V->getOperand(0), N->getOperand(1)); + } + + return SDValue(); +} + SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { EVT VT = N->getValueType(0); unsigned NumElts = VT.getVectorNumElements(); @@ -7447,7 +7482,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, const_cast(FV->getConstantFPValue()), const_cast(TV->getConstantFPValue()) }; - const Type *FPTy = Elts[0]->getType(); + Type *FPTy = Elts[0]->getType(); const TargetData &TD = *TLI.getTargetData(); // Create a ConstantArray of the two constants. @@ -7465,10 +7500,13 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, SDValue Cond = DAG.getSetCC(DL, TLI.getSetCCResultType(N0.getValueType()), N0, N1, CC); + AddToWorkList(Cond.getNode()); SDValue CstOffset = DAG.getNode(ISD::SELECT, DL, Zero.getValueType(), Cond, One, Zero); + AddToWorkList(CstOffset.getNode()); CPIdx = DAG.getNode(ISD::ADD, DL, TLI.getPointerTy(), CPIdx, CstOffset); + AddToWorkList(CPIdx.getNode()); return DAG.getLoad(TV->getValueType(0), DL, DAG.getEntryNode(), CPIdx, MachinePointerInfo::getConstantPool(), false, false, Alignment); @@ -7553,7 +7591,8 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, // fold select C, 16, 0 -> shl C, 4 if (N2C && N3C && N3C->isNullValue() && N2C->getAPIntValue().isPowerOf2() && - TLI.getBooleanContents() == TargetLowering::ZeroOrOneBooleanContent) { + TLI.getBooleanContents(N0.getValueType().isVector()) == + TargetLowering::ZeroOrOneBooleanContent) { // If the caller doesn't want us to simplify this into a zext of a compare, // don't do it. diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index 54a7d43f46d6..e8f8c73d6883 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -66,17 +66,22 @@ using namespace llvm; void FastISel::startNewBlock() { LocalValueMap.clear(); - // Start out as null, meaining no local-value instructions have - // been emitted. - LastLocalValue = 0; + EmitStartPt = 0; - // Advance the last local value past any EH_LABEL instructions. + // Advance the emit start point past any EH_LABEL instructions. MachineBasicBlock::iterator I = FuncInfo.MBB->begin(), E = FuncInfo.MBB->end(); while (I != E && I->getOpcode() == TargetOpcode::EH_LABEL) { - LastLocalValue = I; + EmitStartPt = I; ++I; } + LastLocalValue = EmitStartPt; +} + +void FastISel::flushLocalValueMap() { + LocalValueMap.clear(); + LastLocalValue = EmitStartPt; + recomputeInsertPt(); } bool FastISel::hasTrivialKill(const Value *V) const { @@ -183,7 +188,7 @@ unsigned FastISel::materializeRegForValue(const Value *V, MVT VT) { (void) Flt.convertToInteger(x, IntBitWidth, /*isSigned=*/true, APFloat::rmTowardZero, &isExact); if (isExact) { - APInt IntVal(IntBitWidth, 2, x); + APInt IntVal(IntBitWidth, x); unsigned IntegerReg = getRegForValue(ConstantInt::get(V->getContext(), IntVal)); @@ -422,12 +427,12 @@ bool FastISel::SelectGetElementPtr(const User *I) { bool NIsKill = hasTrivialKill(I->getOperand(0)); - const Type *Ty = I->getOperand(0)->getType(); + Type *Ty = I->getOperand(0)->getType(); MVT VT = TLI.getPointerTy(); for (GetElementPtrInst::const_op_iterator OI = I->op_begin()+1, E = I->op_end(); OI != E; ++OI) { const Value *Idx = *OI; - if (const StructType *StTy = dyn_cast(Ty)) { + if (StructType *StTy = dyn_cast(Ty)) { unsigned Field = cast(Idx)->getZExtValue(); if (Field) { // N = N + Offset @@ -489,7 +494,7 @@ bool FastISel::SelectCall(const User *I) { const CallInst *Call = cast(I); // Handle simple inline asms. - if (const InlineAsm *IA = dyn_cast(Call->getArgOperand(0))) { + if (const InlineAsm *IA = dyn_cast(Call->getCalledValue())) { // Don't attempt to handle constraints. if (!IA->getConstraintString().empty()) return false; @@ -526,13 +531,10 @@ bool FastISel::SelectCall(const User *I) { unsigned Reg = 0; unsigned Offset = 0; if (const Argument *Arg = dyn_cast(Address)) { - if (Arg->hasByValAttr()) { - // Byval arguments' frame index is recorded during argument lowering. - // Use this info directly. - Offset = FuncInfo.getByValArgumentFrameIndex(Arg); - if (Offset) - Reg = TRI.getFrameRegister(*FuncInfo.MF); - } + // Some arguments' frame index is recorded during argument lowering. + Offset = FuncInfo.getArgumentFrameIndex(Arg); + if (Offset) + Reg = TRI.getFrameRegister(*FuncInfo.MF); } if (!Reg) Reg = getRegForValue(Address); @@ -645,6 +647,16 @@ bool FastISel::SelectCall(const User *I) { } } + // Usually, it does not make sense to initialize a value, + // make an unrelated function call and use the value, because + // it tends to be spilled on the stack. So, we move the pointer + // to the last local value to the beginning of the block, so that + // all the values which have already been materialized, + // appear after the call. It also makes sense to skip intrinsics + // since they tend to be inlined. + if (!isa(F)) + flushLocalValueMap(); + // An arbitrary call. Bail. return false; } @@ -839,7 +851,7 @@ FastISel::SelectExtractValue(const User *U) { return false; const Value *Op0 = EVI->getOperand(0); - const Type *AggTy = Op0->getType(); + Type *AggTy = Op0->getType(); // Get the base result register. unsigned ResultReg; @@ -1074,7 +1086,7 @@ unsigned FastISel::FastEmit_ri_(MVT VT, unsigned Opcode, if (MaterialReg == 0) { // This is a bit ugly/slow, but failing here means falling out of // fast-isel, which would be very slow. - const IntegerType *ITy = IntegerType::get(FuncInfo.Fn->getContext(), + IntegerType *ITy = IntegerType::get(FuncInfo.Fn->getContext(), VT.getSizeInBits()); MaterialReg = getRegForValue(ConstantInt::get(ITy, Imm)); } diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index d518b5d346a1..b052740a1abe 100644 --- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -78,7 +78,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf) { for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) if (const AllocaInst *AI = dyn_cast(I)) if (const ConstantInt *CUI = dyn_cast(AI->getArraySize())) { - const Type *Ty = AI->getAllocatedType(); + Type *Ty = AI->getAllocatedType(); uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty); unsigned Align = std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), @@ -216,7 +216,7 @@ unsigned FunctionLoweringInfo::CreateReg(EVT VT) { /// In the case that the given value has struct or array type, this function /// will assign registers for each member or element. /// -unsigned FunctionLoweringInfo::CreateRegs(const Type *Ty) { +unsigned FunctionLoweringInfo::CreateRegs(Type *Ty) { SmallVector ValueVTs; ComputeValueVTs(TLI, Ty, ValueVTs); @@ -260,7 +260,7 @@ FunctionLoweringInfo::GetLiveOutRegInfo(unsigned Reg, unsigned BitWidth) { /// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination /// register based on the LiveOutInfo of its operands. void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) { - const Type *Ty = PN->getType(); + Type *Ty = PN->getType(); if (!Ty->isIntegerTy() || Ty->isVectorTy()) return; @@ -351,20 +351,18 @@ void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) { } } -/// setByValArgumentFrameIndex - Record frame index for the byval +/// setArgumentFrameIndex - Record frame index for the byval /// argument. This overrides previous frame index entry for this argument, /// if any. -void FunctionLoweringInfo::setByValArgumentFrameIndex(const Argument *A, +void FunctionLoweringInfo::setArgumentFrameIndex(const Argument *A, int FI) { - assert (A->hasByValAttr() && "Argument does not have byval attribute!"); ByValArgFrameIndexMap[A] = FI; } -/// getByValArgumentFrameIndex - Get frame index for the byval argument. +/// getArgumentFrameIndex - Get frame index for the byval argument. /// If the argument does not have any assigned frame index then 0 is /// returned. -int FunctionLoweringInfo::getByValArgumentFrameIndex(const Argument *A) { - assert (A->hasByValAttr() && "Argument does not have byval attribute!"); +int FunctionLoweringInfo::getArgumentFrameIndex(const Argument *A) { DenseMap::iterator I = ByValArgFrameIndexMap.find(A); if (I != ByValArgFrameIndexMap.end()) @@ -454,3 +452,34 @@ void llvm::CopyCatchInfo(const BasicBlock *SuccBB, const BasicBlock *LPad, break; } } + +/// AddLandingPadInfo - Extract the exception handling information from the +/// landingpad instruction and add them to the specified machine module info. +void llvm::AddLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI, + MachineBasicBlock *MBB) { + MMI.addPersonality(MBB, + cast(I.getPersonalityFn()->stripPointerCasts())); + + if (I.isCleanup()) + MMI.addCleanup(MBB); + + // FIXME: New EH - Add the clauses in reverse order. This isn't 100% correct, + // but we need to do it this way because of how the DWARF EH emitter + // processes the clauses. + for (unsigned i = I.getNumClauses(); i != 0; --i) { + Value *Val = I.getClause(i - 1); + if (I.isCatch(i - 1)) { + MMI.addCatchTypeInfo(MBB, + dyn_cast(Val->stripPointerCasts())); + } else { + // Add filters in a list. + Constant *CVal = cast(Val); + SmallVector FilterList; + for (User::op_iterator + II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) + FilterList.push_back(cast((*II)->stripPointerCasts())); + + MMI.addFilterTypeInfo(MBB, FilterList); + } + } +} diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index f0f4743298e7..2ff66f8f8715 100644 --- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -30,6 +30,12 @@ #include "llvm/Support/MathExtras.h" using namespace llvm; +/// MinRCSize - Smallest register class we allow when constraining virtual +/// registers. If satisfying all register class constraints would require +/// using a smaller register class, emit a COPY to a new virtual register +/// instead. +const unsigned MinRCSize = 4; + /// CountResults - The results of target nodes have register or immediate /// operands first, then an optional chain, and optional glue operands (which do /// not go into the resulting MachineInstr). @@ -87,7 +93,7 @@ EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, bool IsCloned, UI != E; ++UI) { SDNode *User = *UI; bool Match = true; - if (User->getOpcode() == ISD::CopyToReg && + if (User->getOpcode() == ISD::CopyToReg && User->getOperand(2).getNode() == Node && User->getOperand(2).getResNo() == ResNo) { unsigned DestReg = cast(User->getOperand(1))->getReg(); @@ -113,7 +119,8 @@ EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, bool IsCloned, if (!UseRC) UseRC = RC; else if (RC) { - const TargetRegisterClass *ComRC = getCommonSubClass(UseRC, RC); + const TargetRegisterClass *ComRC = + TRI->getCommonSubClass(UseRC, RC); // If multiple uses expect disjoint register classes, we emit // copies in AddRegisterOperand. if (ComRC) @@ -139,7 +146,7 @@ EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, bool IsCloned, } else { DstRC = TLI->getRegClassFor(VT); } - + // If all uses are reading from the src physical register and copying the // register is either impossible or very expensive, then don't create a copy. if (MatchReg && SrcRC->getCopyCost() < 0) { @@ -167,7 +174,7 @@ unsigned InstrEmitter::getDstOfOnlyCopyToRegUse(SDNode *Node, return 0; SDNode *User = *Node->use_begin(); - if (User->getOpcode() == ISD::CopyToReg && + if (User->getOpcode() == ISD::CopyToReg && User->getOperand(2).getNode() == Node && User->getOperand(2).getResNo() == ResNo) { unsigned Reg = cast(User->getOperand(1))->getReg(); @@ -202,7 +209,7 @@ void InstrEmitter::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); UI != E; ++UI) { SDNode *User = *UI; - if (User->getOpcode() == ISD::CopyToReg && + if (User->getOpcode() == ISD::CopyToReg && User->getOperand(2).getNode() == Node && User->getOperand(2).getResNo() == i) { unsigned Reg = cast(User->getOperand(1))->getReg(); @@ -280,15 +287,16 @@ InstrEmitter::AddRegisterOperand(MachineInstr *MI, SDValue Op, MCID.OpInfo[IIOpNum].isOptionalDef(); // If the instruction requires a register in a different class, create - // a new virtual register and copy the value into it. + // a new virtual register and copy the value into it, but first attempt to + // shrink VReg's register class within reason. For example, if VReg == GR32 + // and II requires a GR32_NOSP, just constrain VReg to GR32_NOSP. if (II) { - const TargetRegisterClass *SrcRC = MRI->getRegClass(VReg); const TargetRegisterClass *DstRC = 0; if (IIOpNum < II->getNumOperands()) DstRC = TII->getRegClass(*II, IIOpNum, TRI); assert((DstRC || (MCID.isVariadic() && IIOpNum >= MCID.getNumOperands())) && "Don't have operand info for this instruction!"); - if (DstRC && !SrcRC->hasSuperClassEq(DstRC)) { + if (DstRC && !MRI->constrainRegClass(VReg, DstRC, MinRCSize)) { unsigned NewVReg = MRI->createVirtualRegister(DstRC); BuildMI(*MBB, InsertPos, Op.getNode()->getDebugLoc(), TII->get(TargetOpcode::COPY), NewVReg).addReg(VReg); @@ -326,7 +334,7 @@ InstrEmitter::AddRegisterOperand(MachineInstr *MI, SDValue Op, /// AddOperand - Add the specified operand to the specified machine instr. II /// specifies the instruction information for the node, and IIOpNum is the -/// operand number (in the II) that we are adding. IIOpNum and II are used for +/// operand number (in the II) that we are adding. IIOpNum and II are used for /// assertions only. void InstrEmitter::AddOperand(MachineInstr *MI, SDValue Op, unsigned IIOpNum, @@ -356,7 +364,7 @@ void InstrEmitter::AddOperand(MachineInstr *MI, SDValue Op, } else if (ConstantPoolSDNode *CP = dyn_cast(Op)) { int Offset = CP->getOffset(); unsigned Align = CP->getAlignment(); - const Type *Type = CP->getType(); + Type *Type = CP->getType(); // MachineConstantPool wants an explicit alignment. if (Align == 0) { Align = TM->getTargetData()->getPrefTypeAlignment(Type); @@ -365,7 +373,7 @@ void InstrEmitter::AddOperand(MachineInstr *MI, SDValue Op, Align = TM->getTargetData()->getTypeAllocSize(Type); } } - + unsigned Idx; MachineConstantPool *MCP = MF->getConstantPool(); if (CP->isMachineConstantPoolEntry()) @@ -389,35 +397,44 @@ void InstrEmitter::AddOperand(MachineInstr *MI, SDValue Op, } } -/// getSuperRegisterRegClass - Returns the register class of a superreg A whose -/// "SubIdx"'th sub-register class is the specified register class and whose -/// type matches the specified type. -static const TargetRegisterClass* -getSuperRegisterRegClass(const TargetRegisterClass *TRC, - unsigned SubIdx, EVT VT) { - // Pick the register class of the superegister for this type - for (TargetRegisterInfo::regclass_iterator I = TRC->superregclasses_begin(), - E = TRC->superregclasses_end(); I != E; ++I) - if ((*I)->hasType(VT) && (*I)->getSubRegisterRegClass(SubIdx) == TRC) - return *I; - assert(false && "Couldn't find the register class"); - return 0; +unsigned InstrEmitter::ConstrainForSubReg(unsigned VReg, unsigned SubIdx, + EVT VT, DebugLoc DL) { + const TargetRegisterClass *VRC = MRI->getRegClass(VReg); + const TargetRegisterClass *RC = TRI->getSubClassWithSubReg(VRC, SubIdx); + + // RC is a sub-class of VRC that supports SubIdx. Try to constrain VReg + // within reason. + if (RC && RC != VRC) + RC = MRI->constrainRegClass(VReg, RC, MinRCSize); + + // VReg has been adjusted. It can be used with SubIdx operands now. + if (RC) + return VReg; + + // VReg couldn't be reasonably constrained. Emit a COPY to a new virtual + // register instead. + RC = TRI->getSubClassWithSubReg(TLI->getRegClassFor(VT), SubIdx); + assert(RC && "No legal register class for VT supports that SubIdx"); + unsigned NewReg = MRI->createVirtualRegister(RC); + BuildMI(*MBB, InsertPos, DL, TII->get(TargetOpcode::COPY), NewReg) + .addReg(VReg); + return NewReg; } /// EmitSubregNode - Generate machine code for subreg nodes. /// -void InstrEmitter::EmitSubregNode(SDNode *Node, +void InstrEmitter::EmitSubregNode(SDNode *Node, DenseMap &VRBaseMap, bool IsClone, bool IsCloned) { unsigned VRBase = 0; unsigned Opc = Node->getMachineOpcode(); - + // If the node is only used by a CopyToReg and the dest reg is a vreg, use // the CopyToReg'd destination register instead of creating a new vreg. for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); UI != E; ++UI) { SDNode *User = *UI; - if (User->getOpcode() == ISD::CopyToReg && + if (User->getOpcode() == ISD::CopyToReg && User->getOperand(2).getNode() == Node) { unsigned DestReg = cast(User->getOperand(1))->getReg(); if (TargetRegisterInfo::isVirtualRegister(DestReg)) { @@ -426,12 +443,14 @@ void InstrEmitter::EmitSubregNode(SDNode *Node, } } } - - if (Opc == TargetOpcode::EXTRACT_SUBREG) { - // EXTRACT_SUBREG is lowered as %dst = COPY %src:sub - unsigned SubIdx = cast(Node->getOperand(1))->getZExtValue(); - // Figure out the register class to create for the destreg. + if (Opc == TargetOpcode::EXTRACT_SUBREG) { + // EXTRACT_SUBREG is lowered as %dst = COPY %src:sub. There are no + // constraints on the %dst register, COPY can target all legal register + // classes. + unsigned SubIdx = cast(Node->getOperand(1))->getZExtValue(); + const TargetRegisterClass *TRC = TLI->getRegClassFor(Node->getValueType(0)); + unsigned VReg = getVR(Node->getOperand(0), VRBaseMap); MachineInstr *DefMI = MRI->getVRegDef(VReg); unsigned SrcReg, DstReg, DefSubIdx; @@ -443,62 +462,57 @@ void InstrEmitter::EmitSubregNode(SDNode *Node, // r1026 = extract_subreg r1025, 4 // to a copy // r1026 = copy r1024 - const TargetRegisterClass *TRC = MRI->getRegClass(SrcReg); VRBase = MRI->createVirtualRegister(TRC); BuildMI(*MBB, InsertPos, Node->getDebugLoc(), TII->get(TargetOpcode::COPY), VRBase).addReg(SrcReg); } else { - const TargetRegisterClass *TRC = MRI->getRegClass(VReg); - const TargetRegisterClass *SRC = TRC->getSubRegisterRegClass(SubIdx); - assert(SRC && "Invalid subregister index in EXTRACT_SUBREG"); + // VReg may not support a SubIdx sub-register, and we may need to + // constrain its register class or issue a COPY to a compatible register + // class. + VReg = ConstrainForSubReg(VReg, SubIdx, + Node->getOperand(0).getValueType(), + Node->getDebugLoc()); - // Figure out the register class to create for the destreg. - // Note that if we're going to directly use an existing register, - // it must be precisely the required class, and not a subclass - // thereof. - if (VRBase == 0 || SRC != MRI->getRegClass(VRBase)) { - // Create the reg - assert(SRC && "Couldn't find source register class"); - VRBase = MRI->createVirtualRegister(SRC); - } + // Create the destreg if it is missing. + if (VRBase == 0) + VRBase = MRI->createVirtualRegister(TRC); // Create the extract_subreg machine instruction. - MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), - TII->get(TargetOpcode::COPY), VRBase); - - // Add source, and subreg index - AddOperand(MI, Node->getOperand(0), 0, 0, VRBaseMap, /*IsDebug=*/false, - IsClone, IsCloned); - assert(TargetRegisterInfo::isVirtualRegister(MI->getOperand(1).getReg())&& - "Cannot yet extract from physregs"); - MI->getOperand(1).setSubReg(SubIdx); - MBB->insert(InsertPos, MI); + BuildMI(*MBB, InsertPos, Node->getDebugLoc(), + TII->get(TargetOpcode::COPY), VRBase).addReg(VReg, 0, SubIdx); } } 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); - unsigned SubReg = getVR(N1, VRBaseMap); unsigned SubIdx = cast(N2)->getZExtValue(); - const TargetRegisterClass *TRC = MRI->getRegClass(SubReg); - const TargetRegisterClass *SRC = - getSuperRegisterRegClass(TRC, SubIdx, Node->getValueType(0)); - // Figure out the register class to create for the destreg. - // Note that if we're going to directly use an existing register, - // it must be precisely the required class, and not a subclass - // thereof. - if (VRBase == 0 || SRC != MRI->getRegClass(VRBase)) { - // Create the reg - assert(SRC && "Couldn't find source register class"); + // Figure out the register class to create for the destreg. It should be + // the largest legal register class supporting SubIdx sub-registers. + // RegisterCoalescer will constrain it further if it decides to eliminate + // the INSERT_SUBREG instruction. + // + // %dst = INSERT_SUBREG %src, %sub, SubIdx + // + // is lowered by TwoAddressInstructionPass to: + // + // %dst = COPY %src + // %dst:SubIdx = COPY %sub + // + // There is no constraint on the %src register class. + // + const TargetRegisterClass *SRC = TLI->getRegClassFor(Node->getValueType(0)); + SRC = TRI->getSubClassWithSubReg(SRC, SubIdx); + assert(SRC && "No register class supports VT and SubIdx for INSERT_SUBREG"); + + if (VRBase == 0 || !SRC->hasSubClassEq(MRI->getRegClass(VRBase))) VRBase = MRI->createVirtualRegister(SRC); - } // Create the insert_subreg or subreg_to_reg machine instruction. MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), TII->get(Opc)); MI->addOperand(MachineOperand::CreateReg(VRBase, true)); - + // If creating a subreg_to_reg, then the first input operand // is an implicit value immediate, otherwise it's a register if (Opc == TargetOpcode::SUBREG_TO_REG) { @@ -514,7 +528,7 @@ void InstrEmitter::EmitSubregNode(SDNode *Node, MBB->insert(InsertPos, MI); } else llvm_unreachable("Node is not insert_subreg, extract_subreg, or subreg_to_reg"); - + SDValue Op(Node, 0); bool isNew = VRBaseMap.insert(std::make_pair(Op, VRBase)).second; (void)isNew; // Silence compiler warning. @@ -643,9 +657,9 @@ void InstrEmitter:: EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, DenseMap &VRBaseMap) { unsigned Opc = Node->getMachineOpcode(); - + // Handle subreg insert/extract specially - if (Opc == TargetOpcode::EXTRACT_SUBREG || + if (Opc == TargetOpcode::EXTRACT_SUBREG || Opc == TargetOpcode::INSERT_SUBREG || Opc == TargetOpcode::SUBREG_TO_REG) { EmitSubregNode(Node, VRBaseMap, IsClone, IsCloned); @@ -667,7 +681,7 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, if (Opc == TargetOpcode::IMPLICIT_DEF) // We want a unique VR for each IMPLICIT_DEF use. return; - + const MCInstrDesc &II = TII->get(Opc); unsigned NumResults = CountResults(Node); unsigned NodeOperands = CountOperands(Node); @@ -712,12 +726,12 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, // Then mark unused registers as dead. MI->setPhysRegsDeadExcept(UsedRegs, *TRI); } - + // Add result register values for things that are defined by this // instruction. if (NumResults) CreateVirtualRegisters(Node, MI, II, IsClone, IsCloned, VRBaseMap); - + // Emit all of the actual operands of this instruction, adding them to the // instruction as appropriate. bool HasOptPRefs = II.getNumDefs() > NumResults; @@ -751,7 +765,7 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, MI->addRegisterDead(Reg, TRI); } } - + // If the instruction has implicit defs and the node doesn't, mark the // implicit def as dead. If the node has any glue outputs, we don't do this // because we don't know what implicit defs are being used by glued nodes. @@ -761,6 +775,12 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, i != e; ++i) MI->addRegisterDead(IDList[i-II.getNumDefs()], TRI); } + + // Run post-isel target hook to adjust this instruction if needed. +#ifdef NDEBUG + if (II.hasPostISelHook()) +#endif + TLI->AdjustInstrPostInstrSelection(MI, Node); } /// EmitSpecialNode - Generate machine code for a target-independent node and @@ -788,7 +808,7 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned, SrcReg = R->getReg(); else SrcReg = getVR(SrcVal, VRBaseMap); - + unsigned DestReg = cast(Node->getOperand(1))->getReg(); if (SrcReg == DestReg) // Coalesced away the copy? Ignore. break; @@ -808,12 +828,12 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned, TII->get(TargetOpcode::EH_LABEL)).addSym(S); break; } - + case ISD::INLINEASM: { unsigned NumOps = Node->getNumOperands(); if (Node->getOperand(NumOps-1).getValueType() == MVT::Glue) --NumOps; // Ignore the glue operand. - + // Create the inline asm machine instruction. MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), TII->get(TargetOpcode::INLINEASM)); @@ -822,7 +842,7 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned, SDValue AsmStrV = Node->getOperand(InlineAsm::Op_AsmString); const char *AsmStr = cast(AsmStrV)->getSymbol(); MI->addOperand(MachineOperand::CreateES(AsmStr)); - + // Add the HasSideEffect and isAlignStack bits. int64_t ExtraInfo = cast(Node->getOperand(InlineAsm::Op_ExtraInfo))-> @@ -834,10 +854,10 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned, unsigned Flags = cast(Node->getOperand(i))->getZExtValue(); unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); - + MI->addOperand(MachineOperand::CreateImm(Flags)); ++i; // Skip the ID value. - + switch (InlineAsm::getKind(Flags)) { default: llvm_unreachable("Bad flags!"); case InlineAsm::Kind_RegDef: @@ -873,13 +893,13 @@ EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned, break; } } - + // Get the mdnode from the asm if it exists and add it to the instruction. SDValue MDV = Node->getOperand(InlineAsm::Op_MDNode); const MDNode *MD = cast(MDV)->getMD(); if (MD) MI->addOperand(MachineOperand::CreateMetadata(MD)); - + MBB->insert(InsertPos, MI); break; } diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.h b/lib/CodeGen/SelectionDAG/InstrEmitter.h index 19fc0445b166..c081f38be024 100644 --- a/lib/CodeGen/SelectionDAG/InstrEmitter.h +++ b/lib/CodeGen/SelectionDAG/InstrEmitter.h @@ -77,6 +77,12 @@ class InstrEmitter { DenseMap &VRBaseMap, bool IsDebug, bool IsClone, bool IsCloned); + /// ConstrainForSubReg - Try to constrain VReg to a register class that + /// supports SubIdx sub-registers. Emit a copy if that isn't possible. + /// Return the virtual register to use. + unsigned ConstrainForSubReg(unsigned VReg, unsigned SubIdx, + EVT VT, DebugLoc DL); + /// EmitSubregNode - Generate machine code for subreg nodes. /// void EmitSubregNode(SDNode *Node, DenseMap &VRBaseMap, diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index d06e2bdce065..63255ae2ebd9 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -53,10 +53,15 @@ class SelectionDAGLegalize { // Libcall insertion helpers. - /// LastCALLSEQ - This keeps track of the CALLSEQ_END node that has been + /// LastCALLSEQ_END - This keeps track of the CALLSEQ_END node that has been /// legalized. We use this to ensure that calls are properly serialized /// against each other, including inserted libcalls. - SmallVector LastCALLSEQ; + SDValue LastCALLSEQ_END; + + /// IsLegalizingCall - This member is used *only* for purposes of providing + /// helpful assertions that a libcall isn't created while another call is + /// being legalized (which could lead to non-serialized call sequences). + bool IsLegalizingCall; /// LegalizedNodes - For nodes that are of legal width, and that have more /// than one use, this map indicates what regularized operand to use. This @@ -149,15 +154,6 @@ class SelectionDAGLegalize { void ExpandNode(SDNode *Node, SmallVectorImpl &Results); void PromoteNode(SDNode *Node, SmallVectorImpl &Results); - - SDValue getLastCALLSEQ() { return LastCALLSEQ.back(); } - void setLastCALLSEQ(const SDValue s) { LastCALLSEQ.back() = s; } - void pushLastCALLSEQ(SDValue s) { - LastCALLSEQ.push_back(s); - } - void popLastCALLSEQ() { - LastCALLSEQ.pop_back(); - } }; } @@ -199,7 +195,8 @@ SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag) } void SelectionDAGLegalize::LegalizeDAG() { - pushLastCALLSEQ(DAG.getEntryNode()); + LastCALLSEQ_END = DAG.getEntryNode(); + IsLegalizingCall = false; // The legalize process is inherently a bottom-up recursive process (users // legalize their uses before themselves). Given infinite stack space, we @@ -227,15 +224,14 @@ void SelectionDAGLegalize::LegalizeDAG() { /// FindCallEndFromCallStart - Given a chained node that is part of a call /// sequence, find the CALLSEQ_END node that terminates the call sequence. static SDNode *FindCallEndFromCallStart(SDNode *Node, int depth = 0) { - int next_depth = depth; + // Nested CALLSEQ_START/END constructs aren't yet legal, + // but we can DTRT and handle them correctly here. if (Node->getOpcode() == ISD::CALLSEQ_START) - next_depth = depth + 1; - if (Node->getOpcode() == ISD::CALLSEQ_END) { - assert(depth > 0 && "negative depth!"); - if (depth == 1) + depth++; + else if (Node->getOpcode() == ISD::CALLSEQ_END) { + depth--; + if (depth == 0) return Node; - else - next_depth = depth - 1; } if (Node->use_empty()) return 0; // No CallSeqEnd @@ -266,7 +262,7 @@ static SDNode *FindCallEndFromCallStart(SDNode *Node, int depth = 0) { SDNode *User = *UI; for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) if (User->getOperand(i) == TheChain) - if (SDNode *Result = FindCallEndFromCallStart(User, next_depth)) + if (SDNode *Result = FindCallEndFromCallStart(User, depth)) return Result; } return 0; @@ -287,7 +283,6 @@ static SDNode *FindCallStartFromCallEnd(SDNode *Node) { case ISD::CALLSEQ_START: if (!nested) return Node; - Node = Node->getOperand(0).getNode(); nested--; break; case ISD::CALLSEQ_END: @@ -295,7 +290,7 @@ static SDNode *FindCallStartFromCallEnd(SDNode *Node) { break; } } - return (Node->getOpcode() == ISD::CALLSEQ_START) ? Node : 0; + return 0; } /// LegalizeAllNodesNotLeadingTo - Recursively walk the uses of N, looking to @@ -365,7 +360,7 @@ static SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP, // smaller type. TLI.isLoadExtLegal(ISD::EXTLOAD, SVT) && TLI.ShouldShrinkFPConstant(OrigVT)) { - const Type *SType = SVT.getTypeForEVT(*DAG.getContext()); + Type *SType = SVT.getTypeForEVT(*DAG.getContext()); LLVMC = cast(ConstantExpr::getFPTrunc(LLVMC, SType)); VT = SVT; Extend = true; @@ -819,6 +814,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Action = TLI.getOperationAction(Node->getOpcode(), InnerType); break; } + case ISD::ATOMIC_STORE: { + Action = TLI.getOperationAction(Node->getOpcode(), + Node->getOperand(2).getValueType()); + break; + } case ISD::SELECT_CC: case ISD::SETCC: case ISD::BR_CC: { @@ -872,7 +872,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (Action == TargetLowering::Legal) Action = TargetLowering::Expand; break; - case ISD::TRAMPOLINE: + case ISD::INIT_TRAMPOLINE: + case ISD::ADJUST_TRAMPOLINE: case ISD::FRAMEADDR: case ISD::RETURNADDR: // These operations lie about being legal: when they claim to be legal, @@ -912,12 +913,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::BR_JT: case ISD::BR_CC: case ISD::BRCOND: - assert(LastCALLSEQ.size() == 1 && "branch inside CALLSEQ_BEGIN/END?"); - // Branches tweak the chain to include LastCALLSEQ + // Branches tweak the chain to include LastCALLSEQ_END Ops[0] = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Ops[0], - getLastCALLSEQ()); + LastCALLSEQ_END); Ops[0] = LegalizeOp(Ops[0]); - setLastCALLSEQ(DAG.getEntryNode()); + LastCALLSEQ_END = DAG.getEntryNode(); break; case ISD::SHL: case ISD::SRL: @@ -989,6 +989,31 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { #endif assert(0 && "Do not know how to legalize this operator!"); + case ISD::SRA: + case ISD::SRL: + case ISD::SHL: { + // Scalarize vector SRA/SRL/SHL. + EVT VT = Node->getValueType(0); + assert(VT.isVector() && "Unable to legalize non-vector shift"); + assert(TLI.isTypeLegal(VT.getScalarType())&& "Element type must be legal"); + unsigned NumElem = VT.getVectorNumElements(); + + SmallVector Scalars; + for (unsigned Idx = 0; Idx < NumElem; Idx++) { + SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, + VT.getScalarType(), + Node->getOperand(0), DAG.getIntPtrConstant(Idx)); + SDValue Sh = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, + VT.getScalarType(), + Node->getOperand(1), DAG.getIntPtrConstant(Idx)); + Scalars.push_back(DAG.getNode(Node->getOpcode(), dl, + VT.getScalarType(), Ex, Sh)); + } + Result = DAG.getNode(ISD::BUILD_VECTOR, dl, Node->getValueType(0), + &Scalars[0], Scalars.size()); + break; + } + case ISD::BUILD_VECTOR: switch (TLI.getOperationAction(ISD::BUILD_VECTOR, Node->getValueType(0))) { default: assert(0 && "This action is not supported yet!"); @@ -1006,7 +1031,6 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; case ISD::CALLSEQ_START: { SDNode *CallEnd = FindCallEndFromCallStart(Node); - assert(CallEnd && "didn't find CALLSEQ_END!"); // Recursively Legalize all of the inputs of the call end that do not lead // to this call start. This ensures that any libcalls that need be inserted @@ -1023,9 +1047,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Merge in the last call to ensure that this call starts after the last // call ended. - if (getLastCALLSEQ().getOpcode() != ISD::EntryToken) { + if (LastCALLSEQ_END.getOpcode() != ISD::EntryToken) { Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - Tmp1, getLastCALLSEQ()); + Tmp1, LastCALLSEQ_END); Tmp1 = LegalizeOp(Tmp1); } @@ -1046,29 +1070,25 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // sequence have been legalized, legalize the call itself. During this // process, no libcalls can/will be inserted, guaranteeing that no calls // can overlap. + assert(!IsLegalizingCall && "Inconsistent sequentialization of calls!"); // Note that we are selecting this call! - setLastCALLSEQ(SDValue(CallEnd, 0)); + LastCALLSEQ_END = SDValue(CallEnd, 0); + IsLegalizingCall = true; // Legalize the call, starting from the CALLSEQ_END. - LegalizeOp(getLastCALLSEQ()); + LegalizeOp(LastCALLSEQ_END); + assert(!IsLegalizingCall && "CALLSEQ_END should have cleared this!"); return Result; } case ISD::CALLSEQ_END: - { - SDNode *myCALLSEQ_BEGIN = FindCallStartFromCallEnd(Node); - - // If the CALLSEQ_START node hasn't been legalized first, legalize it. - // This will cause this node to be legalized as well as handling libcalls - // right. - if (getLastCALLSEQ().getNode() != Node) { - LegalizeOp(SDValue(myCALLSEQ_BEGIN, 0)); - DenseMap::iterator I = LegalizedNodes.find(Op); - assert(I != LegalizedNodes.end() && - "Legalizing the call start should have legalized this node!"); - return I->second; - } - - pushLastCALLSEQ(SDValue(myCALLSEQ_BEGIN, 0)); + // If the CALLSEQ_START node hasn't been legalized first, legalize it. This + // will cause this node to be legalized as well as handling libcalls right. + if (LastCALLSEQ_END.getNode() != Node) { + LegalizeOp(SDValue(FindCallStartFromCallEnd(Node), 0)); + DenseMap::iterator I = LegalizedNodes.find(Op); + assert(I != LegalizedNodes.end() && + "Legalizing the call start should have legalized this node!"); + return I->second; } // Otherwise, the call start has been legalized and everything is going @@ -1096,8 +1116,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Result.getResNo()); } } + assert(IsLegalizingCall && "Call sequence imbalance between start/end?"); // This finishes up call legalization. - popLastCALLSEQ(); + IsLegalizingCall = false; // If the CALLSEQ_END node has a flag, remember that we legalized it. AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0)); @@ -1124,7 +1145,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // If this is an unaligned load and the target doesn't support it, // expand it. if (!TLI.allowsUnalignedMemoryAccesses(LD->getMemoryVT())) { - const Type *Ty = LD->getMemoryVT().getTypeForEVT(*DAG.getContext()); + Type *Ty = LD->getMemoryVT().getTypeForEVT(*DAG.getContext()); unsigned ABIAlignment = TLI.getTargetData()->getABITypeAlignment(Ty); if (LD->getAlignment() < ABIAlignment){ Result = ExpandUnalignedLoad(cast(Result.getNode()), @@ -1311,7 +1332,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // If this is an unaligned load and the target doesn't support it, // expand it. if (!TLI.allowsUnalignedMemoryAccesses(LD->getMemoryVT())) { - const Type *Ty = + Type *Ty = LD->getMemoryVT().getTypeForEVT(*DAG.getContext()); unsigned ABIAlignment = TLI.getTargetData()->getABITypeAlignment(Ty); @@ -1491,7 +1512,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // If this is an unaligned store and the target doesn't support it, // expand it. if (!TLI.allowsUnalignedMemoryAccesses(ST->getMemoryVT())) { - const Type *Ty = ST->getMemoryVT().getTypeForEVT(*DAG.getContext()); + Type *Ty = ST->getMemoryVT().getTypeForEVT(*DAG.getContext()); unsigned ABIAlignment= TLI.getTargetData()->getABITypeAlignment(Ty); if (ST->getAlignment() < ABIAlignment) Result = ExpandUnalignedStore(cast(Result.getNode()), @@ -1596,7 +1617,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // If this is an unaligned store and the target doesn't support it, // expand it. if (!TLI.allowsUnalignedMemoryAccesses(ST->getMemoryVT())) { - const Type *Ty = ST->getMemoryVT().getTypeForEVT(*DAG.getContext()); + Type *Ty = ST->getMemoryVT().getTypeForEVT(*DAG.getContext()); unsigned ABIAlignment= TLI.getTargetData()->getABITypeAlignment(Ty); if (ST->getAlignment() < ABIAlignment) Result = ExpandUnalignedStore(cast(Result.getNode()), @@ -1611,82 +1632,101 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { EVT WideScalarVT = Tmp3.getValueType().getScalarType(); EVT NarrowScalarVT = StVT.getScalarType(); - // The Store type is illegal, must scalarize the vector store. - SmallVector Stores; - bool ScalarLegal = TLI.isTypeLegal(WideScalarVT); - if (!TLI.isTypeLegal(StVT) && StVT.isVector() && ScalarLegal) { + if (StVT.isVector()) { unsigned NumElem = StVT.getVectorNumElements(); + // The type of the data we want to save + EVT RegVT = Tmp3.getValueType(); + EVT RegSclVT = RegVT.getScalarType(); + // The type of data as saved in memory. + EVT MemSclVT = StVT.getScalarType(); - unsigned ScalarSize = StVT.getScalarType().getSizeInBits(); - // Round odd types to the next pow of two. - if (!isPowerOf2_32(ScalarSize)) - ScalarSize = NextPowerOf2(ScalarSize); - // Types smaller than 8 bits are promoted to 8 bits. - ScalarSize = std::max(ScalarSize, 8); - // Store stride - unsigned Stride = ScalarSize/8; - assert(isPowerOf2_32(Stride) && "Stride must be a power of two"); + bool RegScalarLegal = TLI.isTypeLegal(RegSclVT); + bool MemScalarLegal = TLI.isTypeLegal(MemSclVT); - for (unsigned Idx=0; Idx Stores; + for (unsigned Idx = 0; Idx < NumElem; Idx++) { + SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, + RegSclVT, Tmp3, DAG.getIntPtrConstant(Idx)); - Ex = DAG.getNode(ISD::TRUNCATE, dl, NVT, Ex); - Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, - DAG.getIntPtrConstant(Stride)); - SDValue Store = DAG.getStore(Tmp1, dl, Ex, Tmp2, - ST->getPointerInfo().getWithOffset(Idx*Stride), - isVolatile, isNonTemporal, Alignment); - Stores.push_back(Store); - } - Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - &Stores[0], Stores.size()); - break; - } + Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, + DAG.getIntPtrConstant(Stride)); - // The Store type is illegal, must scalarize the vector store. - // However, the scalar type is illegal. Must bitcast the result - // and store it in smaller parts. - if (!TLI.isTypeLegal(StVT) && StVT.isVector()) { - unsigned WideNumElem = StVT.getVectorNumElements(); - unsigned Stride = NarrowScalarVT.getSizeInBits()/8; + // This scalar TruncStore may be illegal, but we lehalize it + // later. + SDValue Store = DAG.getTruncStore(Tmp1, dl, Ex, Tmp2, + ST->getPointerInfo().getWithOffset(Idx*Stride), MemSclVT, + isVolatile, isNonTemporal, Alignment); - unsigned SizeRatio = - (WideScalarVT.getSizeInBits() / NarrowScalarVT.getSizeInBits()); - - EVT CastValueVT = EVT::getVectorVT(*DAG.getContext(), NarrowScalarVT, - SizeRatio*WideNumElem); - - // Cast the wide elem vector to wider vec with smaller elem type. - // Example <2 x i64> -> <4 x i32> - Tmp3 = DAG.getNode(ISD::BITCAST, dl, CastValueVT, Tmp3); - - for (unsigned Idx=0; IdxgetPointerInfo().getWithOffset(Idx*Stride), - isVolatile, isNonTemporal, Alignment); Stores.push_back(Store); } + + Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, + &Stores[0], Stores.size()); + break; } - Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, - &Stores[0], Stores.size()); - break; - } + + // The scalar register type is illegal. + // For example saving <2 x i64> -> <2 x i32> on a x86. + // In here we bitcast the value into a vector of smaller parts and + // save it using smaller scalars. + if (!RegScalarLegal && MemScalarLegal) { + // Store Stride in bytes + unsigned Stride = MemSclVT.getSizeInBits()/8; + + unsigned SizeRatio = + (RegSclVT.getSizeInBits() / MemSclVT.getSizeInBits()); + + EVT CastValueVT = EVT::getVectorVT(*DAG.getContext(), + MemSclVT, + SizeRatio * NumElem); + + // Cast the wide elem vector to wider vec with smaller elem type. + // Example <2 x i64> -> <4 x i32> + Tmp3 = DAG.getNode(ISD::BITCAST, dl, CastValueVT, Tmp3); + + SmallVector Stores; + for (unsigned Idx=0; Idx < NumElem * SizeRatio; Idx++) { + // Extract the Ith element. + SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, + NarrowScalarVT, Tmp3, DAG.getIntPtrConstant(Idx)); + // Bump pointer. + Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, + DAG.getIntPtrConstant(Stride)); + + // Store if, this element is: + // - First element on big endian, or + // - Last element on little endian + if (( TLI.isBigEndian() && (Idx % SizeRatio == 0)) || + ((!TLI.isBigEndian() && (Idx % SizeRatio == SizeRatio-1)))) { + SDValue Store = DAG.getStore(Tmp1, dl, Ex, Tmp2, + ST->getPointerInfo().getWithOffset(Idx*Stride), + isVolatile, isNonTemporal, Alignment); + Stores.push_back(Store); + } + } + Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, + &Stores[0], Stores.size()); + break; + } + + assert(false && "Unable to legalize the vector trunc store!"); + }// is vector // TRUNCSTORE:i16 i32 -> STORE i16 @@ -1999,7 +2039,7 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, unsigned SrcSize = SrcOp.getValueType().getSizeInBits(); unsigned SlotSize = SlotVT.getSizeInBits(); unsigned DestSize = DestVT.getSizeInBits(); - const Type *DestType = DestVT.getTypeForEVT(*DAG.getContext()); + Type *DestType = DestVT.getTypeForEVT(*DAG.getContext()); unsigned DestAlign = TLI.getTargetData()->getPrefTypeAlignment(DestType); // Emit a store to the stack slot. Use a truncstore if the input value is @@ -2106,7 +2146,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { } } else { assert(Node->getOperand(i).getOpcode() == ISD::UNDEF); - const Type *OpNTy = EltVT.getTypeForEVT(*DAG.getContext()); + Type *OpNTy = EltVT.getTypeForEVT(*DAG.getContext()); CV.push_back(UndefValue::get(OpNTy)); } } @@ -2150,6 +2190,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { // and leave the Hi part unset. SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned) { + assert(!IsLegalizingCall && "Cannot overlap legalization of calls!"); // The input chain to this libcall is the entry node of the function. // Legalizing the call will automatically add the previous call to the // dependence. @@ -2159,7 +2200,7 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, TargetLowering::ArgListEntry Entry; for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { EVT ArgVT = Node->getOperand(i).getValueType(); - const Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); + Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; Entry.isSExt = isSigned; Entry.isZExt = !isSigned; @@ -2169,7 +2210,7 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, TLI.getPointerTy()); // Splice the libcall in wherever FindInputOutputChains tells us to. - const Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); + Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); // isTailCall may be true since the callee does not reference caller stack // frame. Check if it's in the right position. @@ -2185,7 +2226,7 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, return DAG.getRoot(); // Legalize the call sequence, starting with the chain. This will advance - // the LastCALLSEQ to the legalized version of the CALLSEQ_END node that + // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that // was added by LowerCallTo (guaranteeing proper serialization of calls). LegalizeOp(CallInfo.second); return CallInfo.first; @@ -2210,7 +2251,7 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, EVT RetVT, SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), TLI.getPointerTy()); - const Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); + Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); std::pair CallInfo = TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, false, 0, TLI.getLibcallCallingConv(LC), false, @@ -2231,13 +2272,14 @@ std::pair SelectionDAGLegalize::ExpandChainLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned) { + assert(!IsLegalizingCall && "Cannot overlap legalization of calls!"); SDValue InChain = Node->getOperand(0); TargetLowering::ArgListTy Args; TargetLowering::ArgListEntry Entry; for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) { EVT ArgVT = Node->getOperand(i).getValueType(); - const Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); + Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; Entry.isSExt = isSigned; @@ -2248,7 +2290,7 @@ SelectionDAGLegalize::ExpandChainLibCall(RTLIB::Libcall LC, TLI.getPointerTy()); // Splice the libcall in wherever FindInputOutputChains tells us to. - const Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); + Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); std::pair CallInfo = TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 0, TLI.getLibcallCallingConv(LC), /*isTailCall=*/false, @@ -2256,7 +2298,7 @@ SelectionDAGLegalize::ExpandChainLibCall(RTLIB::Libcall LC, Callee, Args, DAG, Node->getDebugLoc()); // Legalize the call sequence, starting with the chain. This will advance - // the LastCALLSEQ to the legalized version of the CALLSEQ_END node that + // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that // was added by LowerCallTo (guaranteeing proper serialization of calls). LegalizeOp(CallInfo.second); return CallInfo; @@ -2360,13 +2402,13 @@ SelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node, SDValue InChain = DAG.getEntryNode(); EVT RetVT = Node->getValueType(0); - const Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); + Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); TargetLowering::ArgListTy Args; TargetLowering::ArgListEntry Entry; for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { EVT ArgVT = Node->getOperand(i).getValueType(); - const Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); + Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; Entry.isSExt = isSigned; Entry.isZExt = !isSigned; @@ -2397,7 +2439,7 @@ SelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node, LegalizeOp(CallInfo.second); // Remainder is loaded back from the stack frame. - SDValue Rem = DAG.getLoad(RetVT, dl, getLastCALLSEQ(), FIPtr, + SDValue Rem = DAG.getLoad(RetVT, dl, LastCALLSEQ_END, FIPtr, MachinePointerInfo(), false, false, 0); Results.push_back(CallInfo.first); Results.push_back(Rem); @@ -2955,8 +2997,10 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, Results.push_back(DAG.getConstant(0, MVT::i32)); Results.push_back(Node->getOperand(0)); break; + case ISD::ATOMIC_FENCE: case ISD::MEMBARRIER: { // If the target didn't lower this, lower it to '__sync_synchronize()' call + // FIXME: handle "fence singlethread" more efficiently. TargetLowering::ArgListTy Args; std::pair CallResult = TLI.LowerCallTo(Node->getOperand(0), Type::getVoidTy(*DAG.getContext()), @@ -2969,6 +3013,32 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, Results.push_back(CallResult.second); break; } + case ISD::ATOMIC_LOAD: { + // There is no libcall for atomic load; fake it with ATOMIC_CMP_SWAP. + SDValue Zero = DAG.getConstant(0, Node->getValueType(0)); + SDValue Swap = DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, dl, + cast(Node)->getMemoryVT(), + Node->getOperand(0), + Node->getOperand(1), Zero, Zero, + cast(Node)->getMemOperand(), + cast(Node)->getOrdering(), + cast(Node)->getSynchScope()); + Results.push_back(Swap.getValue(0)); + Results.push_back(Swap.getValue(1)); + break; + } + case ISD::ATOMIC_STORE: { + // There is no libcall for atomic store; fake it with ATOMIC_SWAP. + SDValue Swap = DAG.getAtomic(ISD::ATOMIC_SWAP, dl, + cast(Node)->getMemoryVT(), + Node->getOperand(0), + Node->getOperand(1), Node->getOperand(2), + cast(Node)->getMemOperand(), + cast(Node)->getOrdering(), + cast(Node)->getSynchScope()); + Results.push_back(Swap.getValue(1)); + break; + } // By default, atomic intrinsics are marked Legal and lowered. Targets // which don't support them directly, however, may want libcalls, in which // case they mark them Expand, and we get here. @@ -3727,8 +3797,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node, LegalizeSetCCCondCode(TLI.getSetCCResultType(Tmp2.getValueType()), Tmp2, Tmp3, Tmp4, dl); - assert(LastCALLSEQ.size() == 1 && "branch inside CALLSEQ_BEGIN/END?"); - setLastCALLSEQ(DAG.getEntryNode()); + LastCALLSEQ_END = DAG.getEntryNode(); assert(!Tmp3.getNode() && "Can't legalize BR_CC with legal condition!"); Tmp3 = DAG.getConstant(0, Tmp2.getValueType()); diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index e6835d87f82c..7c1cc69d6a2f 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -55,6 +55,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { #endif llvm_unreachable("Do not know how to soften the result of this operator!"); + case ISD::MERGE_VALUES:R = SoftenFloatRes_MERGE_VALUES(N, ResNo); break; case ISD::BITCAST: R = SoftenFloatRes_BITCAST(N); break; case ISD::BUILD_PAIR: R = SoftenFloatRes_BUILD_PAIR(N); break; case ISD::ConstantFP: @@ -107,6 +108,12 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_BITCAST(SDNode *N) { return BitConvertToInteger(N->getOperand(0)); } +SDValue DAGTypeLegalizer::SoftenFloatRes_MERGE_VALUES(SDNode *N, + unsigned ResNo) { + SDValue Op = DisintegrateMERGE_VALUES(N, ResNo); + return BitConvertToInteger(Op); +} + SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) { // Convert the inputs to integers, and build a new pair out of them. return DAG.getNode(ISD::BUILD_PAIR, N->getDebugLoc(), @@ -827,11 +834,11 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { #endif llvm_unreachable("Do not know how to expand the result of this operator!"); - case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; + case ISD::MERGE_VALUES: ExpandRes_MERGE_VALUES(N, ResNo, Lo, Hi); break; case ISD::BITCAST: ExpandRes_BITCAST(N, Lo, Hi); break; case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break; case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break; @@ -879,10 +886,10 @@ void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo, assert(NVT.getSizeInBits() == integerPartWidth && "Do not know how to expand this float constant!"); APInt C = cast(N)->getValueAPF().bitcastToAPInt(); - Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, - &C.getRawData()[1])), NVT); - Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, - &C.getRawData()[0])), NVT); + Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, C.getRawData()[1])), + NVT); + Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, C.getRawData()[0])), + NVT); } void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo, @@ -1201,7 +1208,7 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 }; static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 }; static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 }; - const uint64_t *Parts = 0; + ArrayRef Parts; switch (SrcVT.getSimpleVT().SimpleTy) { default: @@ -1218,7 +1225,7 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, } Lo = DAG.getNode(ISD::FADD, dl, VT, Hi, - DAG.getConstantFP(APFloat(APInt(128, 2, Parts)), + DAG.getConstantFP(APFloat(APInt(128, Parts)), MVT::ppcf128)); Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT), Lo, Hi, DAG.getCondCode(ISD::SETLT)); @@ -1291,8 +1298,7 @@ void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS, GetExpandedFloat(NewLHS, LHSLo, LHSHi); GetExpandedFloat(NewRHS, RHSLo, RHSHi); - EVT VT = NewLHS.getValueType(); - assert(VT == MVT::ppcf128 && "Unsupported setcc type!"); + assert(NewLHS.getValueType() == MVT::ppcf128 && "Unsupported setcc type!"); // FIXME: This generated code sucks. We want to generate // FCMPU crN, hi1, hi2 @@ -1373,7 +1379,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { assert(N->getOperand(0).getValueType() == MVT::ppcf128 && "Logic only correct for ppcf128!"); const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; - APFloat APF = APFloat(APInt(128, 2, TwoE31)); + APFloat APF = APFloat(APInt(128, TwoE31)); SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128); // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X // FIXME: generated code sucks. @@ -1445,6 +1451,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) { ST->getValue().getValueType()); assert(NVT.isByteSized() && "Expanded type not byte sized!"); assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?"); + (void)NVT; SDValue Lo, Hi; GetExpandedOp(ST->getValue(), Lo, Hi); diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index e7c77dd10cb6..a5c4c2ded4c5 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -48,6 +48,7 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { N->dump(&DAG); dbgs() << "\n"; #endif llvm_unreachable("Do not know how to promote this operator!"); + case ISD::MERGE_VALUES:Res = PromoteIntRes_MERGE_VALUES(N, ResNo); break; case ISD::AssertSext: Res = PromoteIntRes_AssertSext(N); break; case ISD::AssertZext: Res = PromoteIntRes_AssertZext(N); break; case ISD::BITCAST: Res = PromoteIntRes_BITCAST(N); break; @@ -63,6 +64,7 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { Res = PromoteIntRes_EXTRACT_VECTOR_ELT(N); break; case ISD::LOAD: Res = PromoteIntRes_LOAD(cast(N));break; case ISD::SELECT: Res = PromoteIntRes_SELECT(N); break; + case ISD::VSELECT: Res = PromoteIntRes_VSELECT(N); break; case ISD::SELECT_CC: Res = PromoteIntRes_SELECT_CC(N); break; case ISD::SETCC: Res = PromoteIntRes_SETCC(N); break; case ISD::SHL: Res = PromoteIntRes_SHL(N); break; @@ -84,6 +86,8 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { Res = PromoteIntRes_BUILD_VECTOR(N); break; case ISD::SCALAR_TO_VECTOR: Res = PromoteIntRes_SCALAR_TO_VECTOR(N); break; + case ISD::CONCAT_VECTORS: + Res = PromoteIntRes_CONCAT_VECTORS(N); break; case ISD::SIGN_EXTEND: case ISD::ZERO_EXTEND: @@ -114,6 +118,9 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { case ISD::SMULO: case ISD::UMULO: Res = PromoteIntRes_XMULO(N, ResNo); break; + case ISD::ATOMIC_LOAD: + Res = PromoteIntRes_Atomic0(cast(N)); break; + case ISD::ATOMIC_LOAD_ADD: case ISD::ATOMIC_LOAD_SUB: case ISD::ATOMIC_LOAD_AND: @@ -136,6 +143,12 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { SetPromotedInteger(SDValue(N, ResNo), Res); } +SDValue DAGTypeLegalizer::PromoteIntRes_MERGE_VALUES(SDNode *N, + unsigned ResNo) { + SDValue Op = DisintegrateMERGE_VALUES(N, ResNo); + return GetPromotedInteger(Op); +} + SDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) { // Sign-extend the new bits, and continue the assertion. SDValue Op = SExtPromotedInteger(N->getOperand(0)); @@ -150,12 +163,26 @@ SDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) { Op.getValueType(), Op, N->getOperand(1)); } +SDValue DAGTypeLegalizer::PromoteIntRes_Atomic0(AtomicSDNode *N) { + EVT ResVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); + SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), + N->getMemoryVT(), ResVT, + N->getChain(), N->getBasePtr(), + N->getMemOperand(), N->getOrdering(), + N->getSynchScope()); + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); + return Res; +} + SDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) { SDValue Op2 = GetPromotedInteger(N->getOperand(2)); SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), N->getMemoryVT(), N->getChain(), N->getBasePtr(), - Op2, N->getMemOperand()); + Op2, N->getMemOperand(), N->getOrdering(), + N->getSynchScope()); // Legalized the chain result - switch anything that used the old chain to // use the new one. ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); @@ -167,7 +194,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_Atomic2(AtomicSDNode *N) { SDValue Op3 = GetPromotedInteger(N->getOperand(3)); SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), N->getMemoryVT(), N->getChain(), N->getBasePtr(), - Op2, Op3, N->getMemOperand()); + Op2, Op3, N->getMemOperand(), N->getOrdering(), + N->getSynchScope()); // Legalized the chain result - switch anything that used the old chain to // use the new one. ReplaceValueWith(SDValue(N, 1), Res.getValue(1)); @@ -457,6 +485,14 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SELECT(SDNode *N) { LHS.getValueType(), N->getOperand(0),LHS,RHS); } +SDValue DAGTypeLegalizer::PromoteIntRes_VSELECT(SDNode *N) { + SDValue Mask = GetPromotedInteger(N->getOperand(0)); + SDValue LHS = GetPromotedInteger(N->getOperand(1)); + SDValue RHS = GetPromotedInteger(N->getOperand(2)); + return DAG.getNode(ISD::VSELECT, N->getDebugLoc(), + LHS.getValueType(), Mask, LHS, RHS); +} + SDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) { SDValue LHS = GetPromotedInteger(N->getOperand(2)); SDValue RHS = GetPromotedInteger(N->getOperand(3)); @@ -467,16 +503,24 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) { SDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) { EVT SVT = TLI.getSetCCResultType(N->getOperand(0).getValueType()); - assert(isTypeLegal(SVT) && "Illegal SetCC type!"); + + EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); + + // Only use the result of getSetCCResultType if it is legal, + // otherwise just use the promoted result type (NVT). + if (!TLI.isTypeLegal(SVT)) + SVT = NVT; + DebugLoc dl = N->getDebugLoc(); + assert(SVT.isVector() == N->getOperand(0).getValueType().isVector() && + "Vector compare must return a vector result!"); // Get the SETCC result using the canonical SETCC type. - SDValue SetCC = DAG.getNode(ISD::SETCC, dl, SVT, N->getOperand(0), + SDValue SetCC = DAG.getNode(N->getOpcode(), dl, SVT, N->getOperand(0), N->getOperand(1), N->getOperand(2)); - // Convert to the expected type. - EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); assert(NVT.bitsLE(SVT) && "Integer type overpromoted?"); + // Convert to the expected type. return DAG.getNode(ISD::TRUNCATE, dl, NVT, SetCC); } @@ -707,6 +751,9 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { llvm_unreachable("Do not know how to promote this operator's operand!"); case ISD::ANY_EXTEND: Res = PromoteIntOp_ANY_EXTEND(N); break; + case ISD::ATOMIC_STORE: + Res = PromoteIntOp_ATOMIC_STORE(cast(N)); + break; case ISD::BITCAST: Res = PromoteIntOp_BITCAST(N); break; case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break; case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break; @@ -721,6 +768,7 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { case ISD::MEMBARRIER: Res = PromoteIntOp_MEMBARRIER(N); break; case ISD::SCALAR_TO_VECTOR: Res = PromoteIntOp_SCALAR_TO_VECTOR(N); break; + case ISD::VSELECT: case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break; case ISD::SELECT_CC: Res = PromoteIntOp_SELECT_CC(N, OpNo); break; case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break; @@ -791,6 +839,13 @@ SDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) { return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op); } +SDValue DAGTypeLegalizer::PromoteIntOp_ATOMIC_STORE(AtomicSDNode *N) { + SDValue Op2 = GetPromotedInteger(N->getOperand(2)); + return DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), N->getMemoryVT(), + N->getChain(), N->getBasePtr(), Op2, N->getMemOperand(), + N->getOrdering(), N->getSynchScope()); +} + SDValue DAGTypeLegalizer::PromoteIntOp_BITCAST(SDNode *N) { // This should only occur in unusual situations like bitcasting to an // x86_fp80, so just turn it into a store+load @@ -913,14 +968,17 @@ SDValue DAGTypeLegalizer::PromoteIntOp_SCALAR_TO_VECTOR(SDNode *N) { } SDValue DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) { - assert(OpNo == 0 && "Only know how to promote condition"); + assert(OpNo == 0 && "Only know how to promote the condition!"); + SDValue Cond = N->getOperand(0); + EVT OpTy = N->getOperand(1).getValueType(); // Promote all the way up to the canonical SetCC type. - EVT SVT = TLI.getSetCCResultType(N->getOperand(1).getValueType()); - SDValue Cond = PromoteTargetBoolean(N->getOperand(0), SVT); + EVT SVT = TLI.getSetCCResultType(N->getOpcode() == ISD::SELECT ? + OpTy.getScalarType() : OpTy); + Cond = PromoteTargetBoolean(Cond, SVT); - return SDValue(DAG.UpdateNodeOperands(N, Cond, - N->getOperand(1), N->getOperand(2)), 0); + return SDValue(DAG.UpdateNodeOperands(N, Cond, N->getOperand(1), + N->getOperand(2)), 0); } SDValue DAGTypeLegalizer::PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo) { @@ -1024,7 +1082,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { #endif llvm_unreachable("Do not know how to expand the result of this operator!"); - case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; + case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break; case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; @@ -1055,6 +1113,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { case ISD::UDIV: ExpandIntRes_UDIV(N, Lo, Hi); break; case ISD::UREM: ExpandIntRes_UREM(N, Lo, Hi); break; case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break; + case ISD::ATOMIC_LOAD: ExpandIntRes_ATOMIC_LOAD(N, Lo, Hi); break; case ISD::ATOMIC_LOAD_ADD: case ISD::ATOMIC_LOAD_SUB: @@ -1546,6 +1605,12 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N, ReplaceValueWith(SDValue(N, 1), Hi.getValue(1)); } +void DAGTypeLegalizer::ExpandIntRes_MERGE_VALUES(SDNode *N, unsigned ResNo, + SDValue &Lo, SDValue &Hi) { + SDValue Res = DisintegrateMERGE_VALUES(N, ResNo); + SplitInteger(Res, Lo, Hi); +} + void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N, SDValue &Lo, SDValue &Hi) { EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); @@ -2176,9 +2241,9 @@ void DAGTypeLegalizer::ExpandIntRes_UADDSUBO(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N, SDValue &Lo, SDValue &Hi) { EVT VT = N->getValueType(0); - const Type *RetTy = VT.getTypeForEVT(*DAG.getContext()); + Type *RetTy = VT.getTypeForEVT(*DAG.getContext()); EVT PtrVT = TLI.getPointerTy(); - const Type *PtrTy = PtrVT.getTypeForEVT(*DAG.getContext()); + Type *PtrTy = PtrVT.getTypeForEVT(*DAG.getContext()); DebugLoc dl = N->getDebugLoc(); // A divide for UMULO should be faster than a function call. @@ -2222,7 +2287,7 @@ void DAGTypeLegalizer::ExpandIntRes_XMULO(SDNode *N, TargetLowering::ArgListEntry Entry; for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { EVT ArgVT = N->getOperand(i).getValueType(); - const Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); + Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); Entry.Node = N->getOperand(i); Entry.Ty = ArgTy; Entry.isSExt = true; @@ -2321,6 +2386,20 @@ void DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N, } } +void DAGTypeLegalizer::ExpandIntRes_ATOMIC_LOAD(SDNode *N, + SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); + EVT VT = cast(N)->getMemoryVT(); + SDValue Zero = DAG.getConstant(0, VT); + SDValue Swap = DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, dl, VT, + N->getOperand(0), + N->getOperand(1), Zero, Zero, + cast(N)->getMemOperand(), + cast(N)->getOrdering(), + cast(N)->getSynchScope()); + ReplaceValueWith(SDValue(N, 0), Swap.getValue(0)); + ReplaceValueWith(SDValue(N, 1), Swap.getValue(1)); +} //===----------------------------------------------------------------------===// // Integer Operand Expansion @@ -2365,6 +2444,8 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { case ISD::ROTR: Res = ExpandIntOp_Shift(N); break; case ISD::RETURNADDR: case ISD::FRAMEADDR: Res = ExpandIntOp_RETURNADDR(N); break; + + case ISD::ATOMIC_STORE: Res = ExpandIntOp_ATOMIC_STORE(N); break; } // If the result is null, the sub-method took care of registering results etc. @@ -2742,6 +2823,19 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { return MakeLibCall(LC, DstVT, &Op, 1, true, dl); } +SDValue DAGTypeLegalizer::ExpandIntOp_ATOMIC_STORE(SDNode *N) { + DebugLoc dl = N->getDebugLoc(); + SDValue Swap = DAG.getAtomic(ISD::ATOMIC_SWAP, dl, + cast(N)->getMemoryVT(), + N->getOperand(0), + N->getOperand(1), N->getOperand(2), + cast(N)->getMemOperand(), + cast(N)->getOrdering(), + cast(N)->getSynchScope()); + return Swap.getValue(1); +} + + SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N) { SDValue InOp0 = N->getOperand(0); EVT InVT = InOp0.getValueType(); @@ -2775,7 +2869,6 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N) { SDValue DAGTypeLegalizer::PromoteIntRes_VECTOR_SHUFFLE(SDNode *N) { - ShuffleVectorSDNode *SV = cast(N); EVT VT = N->getValueType(0); DebugLoc dl = N->getDebugLoc(); @@ -2830,6 +2923,46 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SCALAR_TO_VECTOR(SDNode *N) { return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NOutVT, Op); } +SDValue DAGTypeLegalizer::PromoteIntRes_CONCAT_VECTORS(SDNode *N) { + DebugLoc dl = N->getDebugLoc(); + + SDValue Op0 = N->getOperand(1); + SDValue Op1 = N->getOperand(1); + assert(Op0.getValueType() == Op1.getValueType() && + "Invalid input vector types"); + + EVT OutVT = N->getValueType(0); + EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT); + assert(NOutVT.isVector() && "This type must be promoted to a vector type"); + + EVT OutElemTy = NOutVT.getVectorElementType(); + + unsigned NumElem0 = Op0.getValueType().getVectorNumElements(); + unsigned NumElem1 = Op1.getValueType().getVectorNumElements(); + unsigned NumOutElem = NOutVT.getVectorNumElements(); + assert(NumElem0 + NumElem1 == NumOutElem && + "Invalid number of incoming elements"); + + // Take the elements from the first vector. + SmallVector Ops(NumOutElem); + for (unsigned i = 0; i < NumElem0; ++i) { + SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, + Op0.getValueType().getScalarType(), Op0, + DAG.getIntPtrConstant(i)); + Ops[i] = DAG.getNode(ISD::ANY_EXTEND, dl, OutElemTy, Ext); + } + + // Take the elements from the second vector + for (unsigned i = 0; i < NumElem1; ++i) { + SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, + Op1.getValueType().getScalarType(), Op1, + DAG.getIntPtrConstant(i)); + Ops[i + NumElem0] = DAG.getNode(ISD::ANY_EXTEND, dl, OutElemTy, Ext); + } + + return DAG.getNode(ISD::BUILD_VECTOR, dl, NOutVT, &Ops[0], Ops.size()); +} + SDValue DAGTypeLegalizer::PromoteIntRes_INSERT_VECTOR_ELT(SDNode *N) { EVT OutVT = N->getValueType(0); EVT NOutVT = TLI.getTypeToTransformTo(*DAG.getContext(), OutVT); @@ -2838,14 +2971,12 @@ SDValue DAGTypeLegalizer::PromoteIntRes_INSERT_VECTOR_ELT(SDNode *N) { EVT NOutVTElem = NOutVT.getVectorElementType(); DebugLoc dl = N->getDebugLoc(); - - SDValue ConvertedVector = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, - N->getOperand(0)); + SDValue V0 = GetPromotedInteger(N->getOperand(0)); SDValue ConvElem = DAG.getNode(ISD::ANY_EXTEND, dl, NOutVTElem, N->getOperand(1)); - return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl,NOutVT, - ConvertedVector, ConvElem, N->getOperand(2)); + return DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NOutVT, + V0, ConvElem, N->getOperand(2)); } SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) { @@ -2855,20 +2986,23 @@ SDValue DAGTypeLegalizer::PromoteIntOp_EXTRACT_VECTOR_ELT(SDNode *N) { SDValue Ext = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, V0->getValueType(0).getScalarType(), V0, V1); - return DAG.getNode(ISD::TRUNCATE, dl, N->getValueType(0), Ext); - + // EXTRACT_VECTOR_ELT can return types which are wider than the incoming + // element types. If this is the case then we need to expand the outgoing + // value and not truncate it. + return DAG.getAnyExtOrTrunc(Ext, dl, N->getValueType(0)); } SDValue DAGTypeLegalizer::PromoteIntOp_CONCAT_VECTORS(SDNode *N) { - DebugLoc dl = N->getDebugLoc(); + unsigned NumElems = N->getNumOperands(); EVT RetSclrTy = N->getValueType(0).getVectorElementType(); SmallVector NewOps; + NewOps.reserve(NumElems); // For each incoming vector - for (unsigned VecIdx = 0, E = N->getNumOperands(); VecIdx!= E; ++VecIdx) { + for (unsigned VecIdx = 0; VecIdx != NumElems; ++VecIdx) { SDValue Incoming = GetPromotedInteger(N->getOperand(VecIdx)); EVT SclrTy = Incoming->getValueType(0).getVectorElementType(); unsigned NumElem = Incoming->getValueType(0).getVectorNumElements(); diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index ba658b022053..a4bb577433cc 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -946,6 +946,13 @@ bool DAGTypeLegalizer::CustomWidenLowerNode(SDNode *N, EVT VT) { return true; } +SDValue DAGTypeLegalizer::DisintegrateMERGE_VALUES(SDNode *N, unsigned ResNo) { + for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) + if (i != ResNo) + ReplaceValueWith(SDValue(N, i), SDValue(N->getOperand(i))); + return SDValue(N, ResNo); +} + /// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a type /// which is split into two not necessarily identical pieces. void DAGTypeLegalizer::GetSplitDestVTs(EVT InVT, EVT &LoVT, EVT &HiVT) { @@ -1046,7 +1053,7 @@ SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, EVT RetVT, SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), TLI.getPointerTy()); - const Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); + Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); std::pair CallInfo = TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, false, 0, TLI.getLibcallCallingConv(LC), false, @@ -1067,7 +1074,7 @@ DAGTypeLegalizer::ExpandChainLibCall(RTLIB::Libcall LC, TargetLowering::ArgListEntry Entry; for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) { EVT ArgVT = Node->getOperand(i).getValueType(); - const Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); + Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; Entry.isSExt = isSigned; @@ -1078,7 +1085,7 @@ DAGTypeLegalizer::ExpandChainLibCall(RTLIB::Libcall LC, TLI.getPointerTy()); // Splice the libcall in wherever FindInputOutputChains tells us to. - const Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); + Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); std::pair CallInfo = TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 0, TLI.getLibcallCallingConv(LC), /*isTailCall=*/false, @@ -1093,24 +1100,8 @@ DAGTypeLegalizer::ExpandChainLibCall(RTLIB::Libcall LC, /// type i1, the bits of which conform to getBooleanContents. SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, EVT VT) { DebugLoc dl = Bool.getDebugLoc(); - ISD::NodeType ExtendCode; - switch (TLI.getBooleanContents()) { - default: - assert(false && "Unknown BooleanContent!"); - case TargetLowering::UndefinedBooleanContent: - // Extend to VT by adding rubbish bits. - ExtendCode = ISD::ANY_EXTEND; - break; - case TargetLowering::ZeroOrOneBooleanContent: - // Extend to VT by adding zero bits. - ExtendCode = ISD::ZERO_EXTEND; - break; - case TargetLowering::ZeroOrNegativeOneBooleanContent: { - // Extend to VT by copying the sign bit. - ExtendCode = ISD::SIGN_EXTEND; - break; - } - } + ISD::NodeType ExtendCode = + TargetLowering::getExtendForContent(TLI.getBooleanContents(VT.isVector())); return DAG.getNode(ExtendCode, dl, VT, Bool); } diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 952797dc75b8..abacdac686bc 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -148,15 +148,22 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { SDValue CreateStackStoreLoad(SDValue Op, EVT DestVT); bool CustomLowerNode(SDNode *N, EVT VT, bool LegalizeResult); bool CustomWidenLowerNode(SDNode *N, EVT VT); + + /// DisintegrateMERGE_VALUES - Replace each result of the given MERGE_VALUES + /// node with the corresponding input operand, except for the result 'ResNo', + /// which is returned. + SDValue DisintegrateMERGE_VALUES(SDNode *N, unsigned ResNo); + SDValue GetVectorElementPointer(SDValue VecPtr, EVT EltVT, SDValue Index); SDValue JoinIntegers(SDValue Lo, SDValue Hi); SDValue LibCallify(RTLIB::Libcall LC, SDNode *N, bool isSigned); SDValue MakeLibCall(RTLIB::Libcall LC, EVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned, DebugLoc dl); - std::pair ExpandChainLibCall(RTLIB::Libcall LC, - SDNode *Node, bool isSigned); - std::pair ExpandAtomic(SDNode *Node); + + std::pair ExpandChainLibCall(RTLIB::Libcall LC, + SDNode *Node, bool isSigned); + std::pair ExpandAtomic(SDNode *Node); SDValue PromoteTargetBoolean(SDValue Bool, EVT VT); void ReplaceValueWith(SDValue From, SDValue To); @@ -206,8 +213,10 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { // Integer Result Promotion. void PromoteIntegerResult(SDNode *N, unsigned ResNo); + SDValue PromoteIntRes_MERGE_VALUES(SDNode *N, unsigned ResNo); SDValue PromoteIntRes_AssertSext(SDNode *N); SDValue PromoteIntRes_AssertZext(SDNode *N); + SDValue PromoteIntRes_Atomic0(AtomicSDNode *N); SDValue PromoteIntRes_Atomic1(AtomicSDNode *N); SDValue PromoteIntRes_Atomic2(AtomicSDNode *N); SDValue PromoteIntRes_EXTRACT_SUBVECTOR(SDNode *N); @@ -215,6 +224,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { SDValue PromoteIntRes_BUILD_VECTOR(SDNode *N); SDValue PromoteIntRes_SCALAR_TO_VECTOR(SDNode *N); SDValue PromoteIntRes_INSERT_VECTOR_ELT(SDNode *N); + SDValue PromoteIntRes_CONCAT_VECTORS(SDNode *N); SDValue PromoteIntRes_BITCAST(SDNode *N); SDValue PromoteIntRes_BSWAP(SDNode *N); SDValue PromoteIntRes_BUILD_PAIR(SDNode *N); @@ -232,6 +242,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { SDValue PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo); SDValue PromoteIntRes_SDIV(SDNode *N); SDValue PromoteIntRes_SELECT(SDNode *N); + SDValue PromoteIntRes_VSELECT(SDNode *N); SDValue PromoteIntRes_SELECT_CC(SDNode *N); SDValue PromoteIntRes_SETCC(SDNode *N); SDValue PromoteIntRes_SHL(SDNode *N); @@ -249,6 +260,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { // Integer Operand Promotion. bool PromoteIntegerOperand(SDNode *N, unsigned OperandNo); SDValue PromoteIntOp_ANY_EXTEND(SDNode *N); + SDValue PromoteIntOp_ATOMIC_STORE(AtomicSDNode *N); SDValue PromoteIntOp_BITCAST(SDNode *N); SDValue PromoteIntOp_BUILD_PAIR(SDNode *N); SDValue PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo); @@ -264,6 +276,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { SDValue PromoteIntOp_SELECT(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_SETCC(SDNode *N, unsigned OpNo); + SDValue PromoteIntOp_VSETCC(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_Shift(SDNode *N); SDValue PromoteIntOp_SIGN_EXTEND(SDNode *N); SDValue PromoteIntOp_SINT_TO_FP(SDNode *N); @@ -289,6 +302,8 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { // Integer Result Expansion. void ExpandIntegerResult(SDNode *N, unsigned ResNo); + void ExpandIntRes_MERGE_VALUES (SDNode *N, unsigned ResNo, + SDValue &Lo, SDValue &Hi); void ExpandIntRes_ANY_EXTEND (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandIntRes_AssertSext (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandIntRes_AssertZext (SDNode *N, SDValue &Lo, SDValue &Hi); @@ -320,6 +335,8 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { void ExpandIntRes_UADDSUBO (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandIntRes_XMULO (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandIntRes_ATOMIC_LOAD (SDNode *N, SDValue &Lo, SDValue &Hi); + void ExpandShiftByConstant(SDNode *N, unsigned Amt, SDValue &Lo, SDValue &Hi); bool ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi); @@ -339,6 +356,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { SDValue ExpandIntOp_TRUNCATE(SDNode *N); SDValue ExpandIntOp_UINT_TO_FP(SDNode *N); SDValue ExpandIntOp_RETURNADDR(SDNode *N); + SDValue ExpandIntOp_ATOMIC_STORE(SDNode *N); void IntegerExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, DebugLoc dl); @@ -362,6 +380,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { // Result Float to Integer Conversion. void SoftenFloatResult(SDNode *N, unsigned OpNo); + SDValue SoftenFloatRes_MERGE_VALUES(SDNode *N, unsigned ResNo); SDValue SoftenFloatRes_BITCAST(SDNode *N); SDValue SoftenFloatRes_BUILD_PAIR(SDNode *N); SDValue SoftenFloatRes_ConstantFP(ConstantFPSDNode *N); @@ -488,6 +507,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { // Vector Result Scalarization: <1 x ty> -> ty. void ScalarizeVectorResult(SDNode *N, unsigned OpNo); + SDValue ScalarizeVecRes_MERGE_VALUES(SDNode *N, unsigned ResNo); SDValue ScalarizeVecRes_BinOp(SDNode *N); SDValue ScalarizeVecRes_UnaryOp(SDNode *N); SDValue ScalarizeVecRes_InregOp(SDNode *N); @@ -559,6 +579,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { SDValue SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N); SDValue SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo); SDValue SplitVecOp_CONCAT_VECTORS(SDNode *N); + SDValue SplitVecOp_VSETCC(SDNode *N); SDValue SplitVecOp_FP_ROUND(SDNode *N); //===--------------------------------------------------------------------===// @@ -581,6 +602,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { // Widen Vector Result Promotion. void WidenVectorResult(SDNode *N, unsigned ResNo); + SDValue WidenVecRes_MERGE_VALUES(SDNode* N, unsigned ResNo); SDValue WidenVecRes_BITCAST(SDNode* N); SDValue WidenVecRes_BUILD_VECTOR(SDNode* N); SDValue WidenVecRes_CONCAT_VECTORS(SDNode* N); @@ -677,7 +699,8 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { void GetPairElements(SDValue Pair, SDValue &Lo, SDValue &Hi); // Generic Result Splitting. - void SplitRes_MERGE_VALUES(SDNode *N, SDValue &Lo, SDValue &Hi); + void SplitRes_MERGE_VALUES(SDNode *N, unsigned ResNo, + SDValue &Lo, SDValue &Hi); void SplitRes_SELECT (SDNode *N, SDValue &Lo, SDValue &Hi); void SplitRes_SELECT_CC (SDNode *N, SDValue &Lo, SDValue &Hi); void SplitRes_UNDEF (SDNode *N, SDValue &Lo, SDValue &Hi); @@ -699,6 +722,8 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { } // Generic Result Expansion. + void ExpandRes_MERGE_VALUES (SDNode *N, unsigned ResNo, + SDValue &Lo, SDValue &Hi); void ExpandRes_BITCAST (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandRes_BUILD_PAIR (SDNode *N, SDValue &Lo, SDValue &Hi); void ExpandRes_EXTRACT_ELEMENT (SDNode *N, SDValue &Lo, SDValue &Hi); diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp index 85ea6b662044..8e7e4985e4d0 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp @@ -31,6 +31,11 @@ using namespace llvm; // These routines assume that the Lo/Hi part is stored first in memory on // little/big-endian machines, followed by the Hi/Lo part. This means that // they cannot be used as is on vectors, for which Lo is always stored first. +void DAGTypeLegalizer::ExpandRes_MERGE_VALUES(SDNode *N, unsigned ResNo, + SDValue &Lo, SDValue &Hi) { + SDValue Op = DisintegrateMERGE_VALUES(N, ResNo); + GetExpandedOp(Op, Lo, Hi); +} void DAGTypeLegalizer::ExpandRes_BITCAST(SDNode *N, SDValue &Lo, SDValue &Hi) { EVT OutVT = N->getValueType(0); @@ -426,37 +431,34 @@ SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) { // bytes; for integers and floats it is Lo first if and only if the machine is // little-endian). -void DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N, +void DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N, unsigned ResNo, SDValue &Lo, SDValue &Hi) { - // A MERGE_VALUES node can produce any number of values. We know that the - // first illegal one needs to be expanded into Lo/Hi. - unsigned i; - - // The string of legal results gets turned into input operands, which have - // the same type. - for (i = 0; isTypeLegal(N->getValueType(i)); ++i) - ReplaceValueWith(SDValue(N, i), SDValue(N->getOperand(i))); - - // The first illegal result must be the one that needs to be expanded. - GetSplitOp(N->getOperand(i), Lo, Hi); - - // Legalize the rest of the results into the input operands whether they are - // legal or not. - unsigned e = N->getNumValues(); - for (++i; i != e; ++i) - ReplaceValueWith(SDValue(N, i), SDValue(N->getOperand(i))); + SDValue Op = DisintegrateMERGE_VALUES(N, ResNo); + GetSplitOp(Op, Lo, Hi); } void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo, SDValue &Hi) { - SDValue LL, LH, RL, RH; + SDValue LL, LH, RL, RH, CL, CH; DebugLoc dl = N->getDebugLoc(); GetSplitOp(N->getOperand(1), LL, LH); GetSplitOp(N->getOperand(2), RL, RH); SDValue Cond = N->getOperand(0); - Lo = DAG.getNode(ISD::SELECT, dl, LL.getValueType(), Cond, LL, RL); - Hi = DAG.getNode(ISD::SELECT, dl, LH.getValueType(), Cond, LH, RH); + CL = CH = Cond; + if (Cond.getValueType().isVector()) { + assert(Cond.getValueType().getVectorElementType() == MVT::i1 && + "Condition legalized before result?"); + unsigned NumElements = Cond.getValueType().getVectorNumElements(); + EVT VCondTy = EVT::getVectorVT(*DAG.getContext(), MVT::i1, NumElements / 2); + CL = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VCondTy, Cond, + DAG.getIntPtrConstant(0)); + CH = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, VCondTy, Cond, + DAG.getIntPtrConstant(NumElements / 2)); + } + + Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), CL, LL, RL); + Hi = DAG.getNode(N->getOpcode(), dl, LH.getValueType(), CH, LH, RH); } void DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDValue &Lo, diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp index ffff10ce2948..f815b00db5d6 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -61,6 +61,9 @@ class VectorLegalizer { // Implements expansion for UINT_TO_FLOAT; falls back to UnrollVectorOp if // SINT_TO_FLOAT and SHR on vectors isn't legal. SDValue ExpandUINT_TO_FLOAT(SDValue Op); + // Implement vselect in terms of XOR, AND, OR when blend is not supported + // by the target. + SDValue ExpandVSELECT(SDValue Op); SDValue ExpandFNEG(SDValue Op); // Implements vector promotion; this is essentially just bitcasting the // operands to a different type and bitcasting the result back to the @@ -157,8 +160,9 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { case ISD::CTLZ: case ISD::CTPOP: case ISD::SELECT: + case ISD::VSELECT: case ISD::SELECT_CC: - case ISD::VSETCC: + case ISD::SETCC: case ISD::ZERO_EXTEND: case ISD::ANY_EXTEND: case ISD::TRUNCATE: @@ -210,11 +214,13 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) { // FALL THROUGH } case TargetLowering::Expand: - if (Node->getOpcode() == ISD::UINT_TO_FP) + if (Node->getOpcode() == ISD::VSELECT) + Result = ExpandVSELECT(Op); + else if (Node->getOpcode() == ISD::UINT_TO_FP) Result = ExpandUINT_TO_FLOAT(Op); else if (Node->getOpcode() == ISD::FNEG) Result = ExpandFNEG(Op); - else if (Node->getOpcode() == ISD::VSETCC) + else if (Node->getOpcode() == ISD::SETCC) Result = UnrollVSETCC(Op); else Result = DAG.UnrollVectorOp(Op.getNode()); @@ -256,9 +262,41 @@ SDValue VectorLegalizer::PromoteVectorOp(SDValue Op) { return DAG.getNode(ISD::BITCAST, dl, VT, Op); } +SDValue VectorLegalizer::ExpandVSELECT(SDValue Op) { + // Implement VSELECT in terms of XOR, AND, OR + // on platforms which do not support blend natively. + EVT VT = Op.getOperand(0).getValueType(); + DebugLoc DL = Op.getDebugLoc(); + + SDValue Mask = Op.getOperand(0); + SDValue Op1 = Op.getOperand(1); + SDValue Op2 = Op.getOperand(2); + + // If we can't even use the basic vector operations of + // AND,OR,XOR, we will have to scalarize the op. + if (!TLI.isOperationLegalOrCustom(ISD::AND, VT) || + !TLI.isOperationLegalOrCustom(ISD::XOR, VT) || + !TLI.isOperationLegalOrCustom(ISD::OR, VT)) + return DAG.UnrollVectorOp(Op.getNode()); + + assert(VT.getSizeInBits() == Op.getOperand(1).getValueType().getSizeInBits() + && "Invalid mask size"); + // Bitcast the operands to be the same type as the mask. + // This is needed when we select between FP types because + // the mask is a vector of integers. + Op1 = DAG.getNode(ISD::BITCAST, DL, VT, Op1); + Op2 = DAG.getNode(ISD::BITCAST, DL, VT, Op2); + + SDValue AllOnes = DAG.getConstant( + APInt::getAllOnesValue(VT.getScalarType().getSizeInBits()), VT); + SDValue NotMask = DAG.getNode(ISD::XOR, DL, VT, Mask, AllOnes); + + Op1 = DAG.getNode(ISD::AND, DL, VT, Op1, Mask); + Op2 = DAG.getNode(ISD::AND, DL, VT, Op2, NotMask); + return DAG.getNode(ISD::OR, DL, VT, Op1, Op2); +} + SDValue VectorLegalizer::ExpandUINT_TO_FLOAT(SDValue Op) { - - EVT VT = Op.getOperand(0).getValueType(); DebugLoc DL = Op.getDebugLoc(); diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index b5698f9c6738..107a42b2951c 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -44,8 +44,10 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) { N->dump(&DAG); dbgs() << "\n"; #endif - llvm_unreachable("Do not know how to scalarize the result of this operator!"); + report_fatal_error("Do not know how to scalarize the result of this " + "operator!\n"); + case ISD::MERGE_VALUES: R = ScalarizeVecRes_MERGE_VALUES(N, ResNo);break; case ISD::BITCAST: R = ScalarizeVecRes_BITCAST(N); break; case ISD::BUILD_VECTOR: R = N->getOperand(0); break; case ISD::CONVERT_RNDSAT: R = ScalarizeVecRes_CONVERT_RNDSAT(N); break; @@ -62,8 +64,6 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) { case ISD::SETCC: R = ScalarizeVecRes_SETCC(N); break; case ISD::UNDEF: R = ScalarizeVecRes_UNDEF(N); break; case ISD::VECTOR_SHUFFLE: R = ScalarizeVecRes_VECTOR_SHUFFLE(N); break; - case ISD::VSETCC: R = ScalarizeVecRes_VSETCC(N); break; - case ISD::ANY_EXTEND: case ISD::CTLZ: case ISD::CTPOP: @@ -129,6 +129,12 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) { LHS.getValueType(), LHS, RHS); } +SDValue DAGTypeLegalizer::ScalarizeVecRes_MERGE_VALUES(SDNode *N, + unsigned ResNo) { + SDValue Op = DisintegrateMERGE_VALUES(N, ResNo); + return GetScalarizedVector(Op); +} + SDValue DAGTypeLegalizer::ScalarizeVecRes_BITCAST(SDNode *N) { EVT NewVT = N->getValueType(0).getVectorElementType(); return DAG.getNode(ISD::BITCAST, N->getDebugLoc(), @@ -237,6 +243,12 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT_CC(SDNode *N) { } SDValue DAGTypeLegalizer::ScalarizeVecRes_SETCC(SDNode *N) { + assert(N->getValueType(0).isVector() == + N->getOperand(0).getValueType().isVector() && + "Scalar/Vector type mismatch"); + + if (N->getValueType(0).isVector()) return ScalarizeVecRes_VSETCC(N); + SDValue LHS = GetScalarizedVector(N->getOperand(0)); SDValue RHS = GetScalarizedVector(N->getOperand(1)); DebugLoc DL = N->getDebugLoc(); @@ -259,35 +271,23 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) { } SDValue DAGTypeLegalizer::ScalarizeVecRes_VSETCC(SDNode *N) { + assert(N->getValueType(0).isVector() && + N->getOperand(0).getValueType().isVector() && + "Operand types must be vectors"); + SDValue LHS = GetScalarizedVector(N->getOperand(0)); SDValue RHS = GetScalarizedVector(N->getOperand(1)); EVT NVT = N->getValueType(0).getVectorElementType(); - EVT SVT = TLI.getSetCCResultType(LHS.getValueType()); DebugLoc DL = N->getDebugLoc(); // Turn it into a scalar SETCC. - SDValue Res = DAG.getNode(ISD::SETCC, DL, SVT, LHS, RHS, N->getOperand(2)); - - // VSETCC always returns a sign-extended value, while SETCC may not. The - // SETCC result type may not match the vector element type. Correct these. - if (NVT.bitsLE(SVT)) { - // The SETCC result type is bigger than the vector element type. - // Ensure the SETCC result is sign-extended. - if (TLI.getBooleanContents() != - TargetLowering::ZeroOrNegativeOneBooleanContent) - Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, SVT, Res, - DAG.getValueType(MVT::i1)); - // Truncate to the final type. - return DAG.getNode(ISD::TRUNCATE, DL, NVT, Res); - } - - // The SETCC result type is smaller than the vector element type. - // If the SetCC result is not sign-extended, chop it down to MVT::i1. - if (TLI.getBooleanContents() != - TargetLowering::ZeroOrNegativeOneBooleanContent) - Res = DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, Res); - // Sign extend to the final type. - return DAG.getNode(ISD::SIGN_EXTEND, DL, NVT, Res); + SDValue Res = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS, + N->getOperand(2)); + // Vectors may have a different boolean contents to scalars. Promote the + // value appropriately. + ISD::NodeType ExtendCode = + TargetLowering::getExtendForContent(TLI.getBooleanContents(true)); + return DAG.getNode(ExtendCode, DL, NVT, Res); } @@ -415,7 +415,8 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { #endif llvm_unreachable("Do not know how to split the result of this operator!"); - case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; + case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, ResNo, Lo, Hi); break; + case ISD::VSELECT: case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; @@ -432,7 +433,6 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) { SplitVecRes_LOAD(cast(N), Lo, Hi); break; case ISD::SETCC: - case ISD::VSETCC: SplitVecRes_SETCC(N, Lo, Hi); break; case ISD::VECTOR_SHUFFLE: @@ -524,12 +524,11 @@ void DAGTypeLegalizer::SplitVecRes_BITCAST(SDNode *N, SDValue &Lo, // Handle some special cases efficiently. switch (getTypeAction(InVT)) { - default: - assert(false && "Unknown type action!"); case TargetLowering::TypeLegal: case TargetLowering::TypePromoteInteger: case TargetLowering::TypeSoftenFloat: case TargetLowering::TypeScalarizeVector: + case TargetLowering::TypeWidenVector: break; case TargetLowering::TypeExpandInteger: case TargetLowering::TypeExpandFloat: @@ -670,7 +669,7 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, // Store the new element. This may be larger than the vector element type, // so use a truncating store. SDValue EltPtr = GetVectorElementPointer(StackPtr, EltVT, Idx); - const Type *VecType = VecVT.getTypeForEVT(*DAG.getContext()); + Type *VecType = VecVT.getTypeForEVT(*DAG.getContext()); unsigned Alignment = TLI.getTargetData()->getPrefTypeAlignment(VecType); Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, MachinePointerInfo(), EltVT, @@ -740,6 +739,10 @@ void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, } void DAGTypeLegalizer::SplitVecRes_SETCC(SDNode *N, SDValue &Lo, SDValue &Hi) { + assert(N->getValueType(0).isVector() && + N->getOperand(0).getValueType().isVector() && + "Operand types must be vectors"); + EVT LoVT, HiVT; DebugLoc DL = N->getDebugLoc(); GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); @@ -965,7 +968,7 @@ bool DAGTypeLegalizer::SplitVectorOperand(SDNode *N, unsigned OpNo) { dbgs() << "\n"; #endif llvm_unreachable("Do not know how to split this operator's operand!"); - + case ISD::SETCC: Res = SplitVecOp_VSETCC(N); break; case ISD::BITCAST: Res = SplitVecOp_BITCAST(N); break; case ISD::EXTRACT_SUBVECTOR: Res = SplitVecOp_EXTRACT_SUBVECTOR(N); break; case ISD::EXTRACT_VECTOR_ELT:Res = SplitVecOp_EXTRACT_VECTOR_ELT(N); break; @@ -1163,6 +1166,26 @@ SDValue DAGTypeLegalizer::SplitVecOp_CONCAT_VECTORS(SDNode *N) { &Elts[0], Elts.size()); } +SDValue DAGTypeLegalizer::SplitVecOp_VSETCC(SDNode *N) { + assert(N->getValueType(0).isVector() && + N->getOperand(0).getValueType().isVector() && + "Operand types must be vectors"); + // The result has a legal vector type, but the input needs splitting. + SDValue Lo0, Hi0, Lo1, Hi1, LoRes, HiRes; + DebugLoc DL = N->getDebugLoc(); + GetSplitVector(N->getOperand(0), Lo0, Hi0); + GetSplitVector(N->getOperand(1), Lo1, Hi1); + unsigned PartElements = Lo0.getValueType().getVectorNumElements(); + EVT PartResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, PartElements); + EVT WideResVT = EVT::getVectorVT(*DAG.getContext(), MVT::i1, 2*PartElements); + + LoRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Lo0, Lo1, N->getOperand(2)); + HiRes = DAG.getNode(ISD::SETCC, DL, PartResVT, Hi0, Hi1, N->getOperand(2)); + SDValue Con = DAG.getNode(ISD::CONCAT_VECTORS, DL, WideResVT, LoRes, HiRes); + return PromoteTargetBoolean(Con, N->getValueType(0)); +} + + SDValue DAGTypeLegalizer::SplitVecOp_FP_ROUND(SDNode *N) { // The result has a legal vector type, but the input needs splitting. EVT ResVT = N->getValueType(0); @@ -1205,6 +1228,7 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) { #endif llvm_unreachable("Do not know how to widen the result of this operator!"); + case ISD::MERGE_VALUES: Res = WidenVecRes_MERGE_VALUES(N, ResNo); break; case ISD::BITCAST: Res = WidenVecRes_BITCAST(N); break; case ISD::BUILD_VECTOR: Res = WidenVecRes_BUILD_VECTOR(N); break; case ISD::CONCAT_VECTORS: Res = WidenVecRes_CONCAT_VECTORS(N); break; @@ -1222,10 +1246,6 @@ void DAGTypeLegalizer::WidenVectorResult(SDNode *N, unsigned ResNo) { case ISD::VECTOR_SHUFFLE: Res = WidenVecRes_VECTOR_SHUFFLE(cast(N)); break; - case ISD::VSETCC: - Res = WidenVecRes_VSETCC(N); - break; - case ISD::ADD: case ISD::AND: case ISD::BSWAP: @@ -1557,6 +1577,11 @@ SDValue DAGTypeLegalizer::WidenVecRes_InregOp(SDNode *N) { WidenVT, WidenLHS, DAG.getValueType(ExtVT)); } +SDValue DAGTypeLegalizer::WidenVecRes_MERGE_VALUES(SDNode *N, unsigned ResNo) { + SDValue WidenVec = DisintegrateMERGE_VALUES(N, ResNo); + return GetWidenedVector(WidenVec); +} + SDValue DAGTypeLegalizer::WidenVecRes_BITCAST(SDNode *N) { SDValue InOp = N->getOperand(0); EVT InVT = InOp.getValueType(); @@ -1661,6 +1686,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); DebugLoc dl = N->getDebugLoc(); unsigned WidenNumElts = WidenVT.getVectorNumElements(); + unsigned NumInElts = InVT.getVectorNumElements(); unsigned NumOperands = N->getNumOperands(); bool InputWidened = false; // Indicates we need to widen the input. @@ -1686,17 +1712,17 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { if (N->getOperand(i).getOpcode() != ISD::UNDEF) break; - if (i > NumOperands) + if (i == NumOperands) // Everything but the first operand is an UNDEF so just return the // widened first operand. return GetWidenedVector(N->getOperand(0)); if (NumOperands == 2) { // Replace concat of two operands with a shuffle. - SmallVector MaskOps(WidenNumElts); - for (unsigned i=0; i < WidenNumElts/2; ++i) { + SmallVector MaskOps(WidenNumElts, -1); + for (unsigned i = 0; i < NumInElts; ++i) { MaskOps[i] = i; - MaskOps[i+WidenNumElts/2] = i+WidenNumElts; + MaskOps[i + NumInElts] = i + WidenNumElts; } return DAG.getVectorShuffle(WidenVT, dl, GetWidenedVector(N->getOperand(0)), @@ -1708,7 +1734,6 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { // Fall back to use extracts and build vector. EVT EltVT = WidenVT.getVectorElementType(); - unsigned NumInElts = InVT.getVectorNumElements(); SmallVector Ops(WidenNumElts); unsigned Idx = 0; for (unsigned i=0; i < NumOperands; ++i) { @@ -1916,6 +1941,11 @@ SDValue DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode *N) { } SDValue DAGTypeLegalizer::WidenVecRes_SETCC(SDNode *N) { + assert(N->getValueType(0).isVector() == + N->getOperand(0).getValueType().isVector() && + "Scalar/Vector type mismatch"); + if (N->getValueType(0).isVector()) return WidenVecRes_VSETCC(N); + EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); SDValue InOp1 = GetWidenedVector(N->getOperand(0)); SDValue InOp2 = GetWidenedVector(N->getOperand(1)); @@ -1954,6 +1984,9 @@ SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(ShuffleVectorSDNode *N) { } SDValue DAGTypeLegalizer::WidenVecRes_VSETCC(SDNode *N) { + assert(N->getValueType(0).isVector() && + N->getOperand(0).getValueType().isVector() && + "Operands must be vectors"); EVT WidenVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); unsigned WidenNumElts = WidenVT.getVectorNumElements(); @@ -1970,7 +2003,8 @@ SDValue DAGTypeLegalizer::WidenVecRes_VSETCC(SDNode *N) { assert(InOp1.getValueType() == WidenInVT && InOp2.getValueType() == WidenInVT && "Input not widened to expected type!"); - return DAG.getNode(ISD::VSETCC, N->getDebugLoc(), + (void)WidenInVT; + return DAG.getNode(ISD::SETCC, N->getDebugLoc(), WidenVT, InOp1, InOp2, N->getOperand(2)); } diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index 12b183804c28..e757defd3895 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -2621,6 +2621,39 @@ bool RegReductionPQBase::canClobber(const SUnit *SU, const SUnit *Op) { return false; } +/// canClobberReachingPhysRegUse - True if SU would clobber one of it's +/// successor's explicit physregs whose definition can reach DepSU. +/// i.e. DepSU should not be scheduled above SU. +static bool canClobberReachingPhysRegUse(const SUnit *DepSU, const SUnit *SU, + ScheduleDAGRRList *scheduleDAG, + const TargetInstrInfo *TII, + const TargetRegisterInfo *TRI) { + const unsigned *ImpDefs + = TII->get(SU->getNode()->getMachineOpcode()).getImplicitDefs(); + if(!ImpDefs) + return false; + + for (SUnit::const_succ_iterator SI = SU->Succs.begin(), SE = SU->Succs.end(); + SI != SE; ++SI) { + SUnit *SuccSU = SI->getSUnit(); + for (SUnit::const_pred_iterator PI = SuccSU->Preds.begin(), + PE = SuccSU->Preds.end(); PI != PE; ++PI) { + if (!PI->isAssignedRegDep()) + continue; + + for (const unsigned *ImpDef = ImpDefs; *ImpDef; ++ImpDef) { + // Return true if SU clobbers this physical register use and the + // definition of the register reaches from DepSU. IsReachable queries a + // topological forward sort of the DAG (following the successors). + if (TRI->regsOverlap(*ImpDef, PI->getReg()) && + scheduleDAG->IsReachable(DepSU, PI->getSUnit())) + return true; + } + } + } + return false; +} + /// canClobberPhysRegDefs - True if SU would clobber one of SuccSU's /// physical register defs. static bool canClobberPhysRegDefs(const SUnit *SuccSU, const SUnit *SU, @@ -2837,7 +2870,8 @@ void RegReductionPQBase::AddPseudoTwoAddrDeps() { SuccOpc == TargetOpcode::INSERT_SUBREG || SuccOpc == TargetOpcode::SUBREG_TO_REG) continue; - if ((!canClobber(SuccSU, DUSU) || + if (!canClobberReachingPhysRegUse(SuccSU, SU, scheduleDAG, TII, TRI) && + (!canClobber(SuccSU, DUSU) || (isLiveOut && !hasOnlyLiveOutUses(SuccSU)) || (!SU->isCommutable && SuccSU->isCommutable)) && !scheduleDAG->IsReachable(SuccSU, SU)) { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 35ea0bb940b5..20bea8e4c9e9 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -403,7 +403,7 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) { ID.AddInteger(CP->getAlignment()); ID.AddInteger(CP->getOffset()); if (CP->isMachineConstantPoolEntry()) - CP->getMachineCPVal()->AddSelectionDAGCSEId(ID); + CP->getMachineCPVal()->addSelectionDAGCSEId(ID); else ID.AddPointer(CP->getConstVal()); ID.AddInteger(CP->getTargetFlags()); @@ -432,7 +432,9 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) { case ISD::ATOMIC_LOAD_MIN: case ISD::ATOMIC_LOAD_MAX: case ISD::ATOMIC_LOAD_UMIN: - case ISD::ATOMIC_LOAD_UMAX: { + case ISD::ATOMIC_LOAD_UMAX: + case ISD::ATOMIC_LOAD: + case ISD::ATOMIC_STORE: { const AtomicSDNode *AT = cast(N); ID.AddInteger(AT->getMemoryVT().getRawBits()); ID.AddInteger(AT->getRawSubclassData()); @@ -769,11 +771,14 @@ static void VerifyNodeCommon(SDNode *N) { assert(N->getNumOperands() == N->getValueType(0).getVectorNumElements() && "Wrong number of operands!"); EVT EltVT = N->getValueType(0).getVectorElementType(); - for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) + for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) { assert((I->getValueType() == EltVT || (EltVT.isInteger() && I->getValueType().isInteger() && EltVT.bitsLE(I->getValueType()))) && "Wrong operand type!"); + assert(I->getValueType() == N->getOperand(0).getValueType() && + "Operands must all have the same type"); + } break; } } @@ -821,7 +826,7 @@ static void VerifyMachineNode(SDNode *N) { /// given type. /// unsigned SelectionDAG::getEVTAlignment(EVT VT) const { - const Type *Ty = VT == MVT::iPTR ? + Type *Ty = VT == MVT::iPTR ? PointerType::get(Type::getInt8Ty(*getContext()), 0) : VT.getTypeForEVT(*getContext()); @@ -876,6 +881,12 @@ void SelectionDAG::clear() { DbgInfo->clear(); } +SDValue SelectionDAG::getAnyExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT) { + return VT.bitsGT(Op.getValueType()) ? + getNode(ISD::ANY_EXTEND, DL, VT, Op) : + getNode(ISD::TRUNCATE, DL, VT, Op); +} + SDValue SelectionDAG::getSExtOrTrunc(SDValue Op, DebugLoc DL, EVT VT) { return VT.bitsGT(Op.getValueType()) ? getNode(ISD::SIGN_EXTEND, DL, VT, Op) : @@ -925,13 +936,25 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) { assert(VT.isInteger() && "Cannot create FP integer constant!"); EVT EltVT = VT.getScalarType(); - assert(Val.getBitWidth() == EltVT.getSizeInBits() && - "APInt size does not match type size!"); + const ConstantInt *Elt = &Val; + // In some cases the vector type is legal but the element type is illegal and + // needs to be promoted, for example v8i8 on ARM. In this case, promote the + // inserted value (the type does not need to match the vector element type). + // Any extra bits introduced will be truncated away. + if (VT.isVector() && TLI.getTypeAction(*getContext(), EltVT) == + TargetLowering::TypePromoteInteger) { + EltVT = TLI.getTypeToTransformTo(*getContext(), EltVT); + APInt NewVal = Elt->getValue().zext(EltVT.getSizeInBits()); + Elt = ConstantInt::get(*getContext(), NewVal); + } + + assert(Elt->getBitWidth() == EltVT.getSizeInBits() && + "APInt size does not match type size!"); unsigned Opc = isT ? ISD::TargetConstant : ISD::Constant; FoldingSetNodeID ID; AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0); - ID.AddPointer(&Val); + ID.AddPointer(Elt); void *IP = 0; SDNode *N = NULL; if ((N = CSEMap.FindNodeOrInsertPos(ID, IP))) @@ -939,7 +962,7 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) { return SDValue(N, 0); if (!N) { - N = new (NodeAllocator) ConstantSDNode(isT, &Val, EltVT); + N = new (NodeAllocator) ConstantSDNode(isT, Elt, EltVT); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); } @@ -1131,7 +1154,7 @@ SDValue SelectionDAG::getConstantPool(MachineConstantPoolValue *C, EVT VT, AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0); ID.AddInteger(Alignment); ID.AddInteger(Offset); - C->AddSelectionDAGCSEId(ID); + C->addSelectionDAGCSEId(ID); ID.AddInteger(TargetFlags); void *IP = 0; if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) @@ -1432,7 +1455,7 @@ SDValue SelectionDAG::getShiftAmountOperand(EVT LHSTy, SDValue Op) { SDValue SelectionDAG::CreateStackTemporary(EVT VT, unsigned minAlign) { MachineFrameInfo *FrameInfo = getMachineFunction().getFrameInfo(); unsigned ByteSize = VT.getStoreSize(); - const Type *Ty = VT.getTypeForEVT(*getContext()); + Type *Ty = VT.getTypeForEVT(*getContext()); unsigned StackAlign = std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), minAlign); @@ -1445,8 +1468,8 @@ SDValue SelectionDAG::CreateStackTemporary(EVT VT, unsigned minAlign) { SDValue SelectionDAG::CreateStackTemporary(EVT VT1, EVT VT2) { unsigned Bytes = std::max(VT1.getStoreSizeInBits(), VT2.getStoreSizeInBits())/8; - const Type *Ty1 = VT1.getTypeForEVT(*getContext()); - const Type *Ty2 = VT2.getTypeForEVT(*getContext()); + Type *Ty1 = VT1.getTypeForEVT(*getContext()); + Type *Ty2 = VT2.getTypeForEVT(*getContext()); const TargetData *TD = TLI.getTargetData(); unsigned Align = std::max(TD->getPrefTypeAlignment(Ty1), TD->getPrefTypeAlignment(Ty2)); @@ -1718,8 +1741,8 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, const APInt &Mask, // The boolean result conforms to getBooleanContents. Fall through. case ISD::SETCC: // If we know the result of a setcc has the top bits zero, use this info. - if (TLI.getBooleanContents() == TargetLowering::ZeroOrOneBooleanContent && - BitWidth > 1) + if (TLI.getBooleanContents(Op.getValueType().isVector()) == + TargetLowering::ZeroOrOneBooleanContent && BitWidth > 1) KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1); return; case ISD::SHL: @@ -2153,7 +2176,7 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{ // The boolean result conforms to getBooleanContents. Fall through. case ISD::SETCC: // If setcc returns 0/-1, all bits are sign bits. - if (TLI.getBooleanContents() == + if (TLI.getBooleanContents(Op.getValueType().isVector()) == TargetLowering::ZeroOrNegativeOneBooleanContent) return VTBits; break; @@ -2437,7 +2460,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, APFloat::rmTowardZero, &ignored); if (s==APFloat::opInvalidOp) // inexact is OK, in fact usual break; - APInt api(VT.getSizeInBits(), 2, x); + APInt api(VT.getSizeInBits(), x); return getConstant(api, VT); } case ISD::BITCAST: @@ -2777,6 +2800,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT, EVT.getVectorNumElements() == VT.getVectorNumElements()) && "Vector element counts must match in FP_ROUND_INREG"); assert(EVT.bitsLE(VT) && "Not rounding down!"); + (void)EVT; if (cast(N2)->getVT() == VT) return N1; // Not actually rounding. break; } @@ -2884,6 +2908,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT, assert(N2C && (unsigned)N2C->getZExtValue() < 2 && "Bad EXTRACT_ELEMENT!"); assert(!N1.getValueType().isVector() && !VT.isVector() && (N1.getValueType().isInteger() == VT.isInteger()) && + N1.getValueType() != VT && "Wrong types for EXTRACT_ELEMENT!"); // EXTRACT_ELEMENT of BUILD_PAIR is often formed while legalize is expanding @@ -3425,7 +3450,7 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl, return SDValue(); if (DstAlignCanChange) { - const Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext()); + Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext()); unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(Ty); if (NewAlign > Align) { // Give the stack frame object a larger alignment if needed. @@ -3514,7 +3539,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl, return SDValue(); if (DstAlignCanChange) { - const Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext()); + Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext()); unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(Ty); if (NewAlign > Align) { // Give the stack frame object a larger alignment if needed. @@ -3589,7 +3614,7 @@ static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl, return SDValue(); if (DstAlignCanChange) { - const Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext()); + Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext()); unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(Ty); if (NewAlign > Align) { // Give the stack frame object a larger alignment if needed. @@ -3782,7 +3807,7 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst, return Result; // Emit a library call. - const Type *IntPtrTy = TLI.getTargetData()->getIntPtrType(*getContext()); + Type *IntPtrTy = TLI.getTargetData()->getIntPtrType(*getContext()); TargetLowering::ArgListTy Args; TargetLowering::ArgListEntry Entry; Entry.Node = Dst; Entry.Ty = IntPtrTy; @@ -3815,7 +3840,9 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst, SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Cmp, SDValue Swp, MachinePointerInfo PtrInfo, - unsigned Alignment) { + unsigned Alignment, + AtomicOrdering Ordering, + SynchronizationScope SynchScope) { if (Alignment == 0) // Ensure that codegen never sees alignment 0 Alignment = getEVTAlignment(MemVT); @@ -3823,18 +3850,23 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, unsigned Flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore; // For now, atomics are considered to be volatile always. + // FIXME: Volatile isn't really correct; we should keep track of atomic + // orderings in the memoperand. Flags |= MachineMemOperand::MOVolatile; MachineMemOperand *MMO = MF.getMachineMemOperand(PtrInfo, Flags, MemVT.getStoreSize(), Alignment); - return getAtomic(Opcode, dl, MemVT, Chain, Ptr, Cmp, Swp, MMO); + return getAtomic(Opcode, dl, MemVT, Chain, Ptr, Cmp, Swp, MMO, + Ordering, SynchScope); } SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Cmp, - SDValue Swp, MachineMemOperand *MMO) { + SDValue Swp, MachineMemOperand *MMO, + AtomicOrdering Ordering, + SynchronizationScope SynchScope) { assert(Opcode == ISD::ATOMIC_CMP_SWAP && "Invalid Atomic Op"); assert(Cmp.getValueType() == Swp.getValueType() && "Invalid Atomic Op Types"); @@ -3851,7 +3883,8 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, return SDValue(E, 0); } SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl, VTs, MemVT, Chain, - Ptr, Cmp, Swp, MMO); + Ptr, Cmp, Swp, MMO, Ordering, + SynchScope); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); return SDValue(N, 0); @@ -3861,27 +3894,39 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, const Value* PtrVal, - unsigned Alignment) { + unsigned Alignment, + AtomicOrdering Ordering, + SynchronizationScope SynchScope) { if (Alignment == 0) // Ensure that codegen never sees alignment 0 Alignment = getEVTAlignment(MemVT); MachineFunction &MF = getMachineFunction(); - unsigned Flags = MachineMemOperand::MOLoad | MachineMemOperand::MOStore; + // A monotonic store does not load; a release store "loads" in the sense + // that other stores cannot be sunk past it. + // (An atomicrmw obviously both loads and stores.) + unsigned Flags = MachineMemOperand::MOStore; + if (Opcode != ISD::ATOMIC_STORE || Ordering > Monotonic) + Flags |= MachineMemOperand::MOLoad; // For now, atomics are considered to be volatile always. + // FIXME: Volatile isn't really correct; we should keep track of atomic + // orderings in the memoperand. Flags |= MachineMemOperand::MOVolatile; MachineMemOperand *MMO = MF.getMachineMemOperand(MachinePointerInfo(PtrVal), Flags, MemVT.getStoreSize(), Alignment); - return getAtomic(Opcode, dl, MemVT, Chain, Ptr, Val, MMO); + return getAtomic(Opcode, dl, MemVT, Chain, Ptr, Val, MMO, + Ordering, SynchScope); } SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, - MachineMemOperand *MMO) { + MachineMemOperand *MMO, + AtomicOrdering Ordering, + SynchronizationScope SynchScope) { assert((Opcode == ISD::ATOMIC_LOAD_ADD || Opcode == ISD::ATOMIC_LOAD_SUB || Opcode == ISD::ATOMIC_LOAD_AND || @@ -3892,12 +3937,14 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, Opcode == ISD::ATOMIC_LOAD_MAX || Opcode == ISD::ATOMIC_LOAD_UMIN || Opcode == ISD::ATOMIC_LOAD_UMAX || - Opcode == ISD::ATOMIC_SWAP) && + Opcode == ISD::ATOMIC_SWAP || + Opcode == ISD::ATOMIC_STORE) && "Invalid Atomic Op"); EVT VT = Val.getValueType(); - SDVTList VTs = getVTList(VT, MVT::Other); + SDVTList VTs = Opcode == ISD::ATOMIC_STORE ? getVTList(MVT::Other) : + getVTList(VT, MVT::Other); FoldingSetNodeID ID; ID.AddInteger(MemVT.getRawBits()); SDValue Ops[] = {Chain, Ptr, Val}; @@ -3908,7 +3955,63 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, return SDValue(E, 0); } SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl, VTs, MemVT, Chain, - Ptr, Val, MMO); + Ptr, Val, MMO, + Ordering, SynchScope); + CSEMap.InsertNode(N, IP); + AllNodes.push_back(N); + return SDValue(N, 0); +} + +SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, + EVT VT, SDValue Chain, + SDValue Ptr, + const Value* PtrVal, + unsigned Alignment, + AtomicOrdering Ordering, + SynchronizationScope SynchScope) { + if (Alignment == 0) // Ensure that codegen never sees alignment 0 + Alignment = getEVTAlignment(MemVT); + + MachineFunction &MF = getMachineFunction(); + // A monotonic load does not store; an acquire load "stores" in the sense + // that other loads cannot be hoisted past it. + unsigned Flags = MachineMemOperand::MOLoad; + if (Ordering > Monotonic) + Flags |= MachineMemOperand::MOStore; + + // For now, atomics are considered to be volatile always. + // FIXME: Volatile isn't really correct; we should keep track of atomic + // orderings in the memoperand. + Flags |= MachineMemOperand::MOVolatile; + + MachineMemOperand *MMO = + MF.getMachineMemOperand(MachinePointerInfo(PtrVal), Flags, + MemVT.getStoreSize(), Alignment); + + return getAtomic(Opcode, dl, MemVT, VT, Chain, Ptr, MMO, + Ordering, SynchScope); +} + +SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, EVT MemVT, + EVT VT, SDValue Chain, + SDValue Ptr, + MachineMemOperand *MMO, + AtomicOrdering Ordering, + SynchronizationScope SynchScope) { + assert(Opcode == ISD::ATOMIC_LOAD && "Invalid Atomic Op"); + + SDVTList VTs = getVTList(VT, MVT::Other); + FoldingSetNodeID ID; + ID.AddInteger(MemVT.getRawBits()); + SDValue Ops[] = {Chain, Ptr}; + AddNodeIDNode(ID, Opcode, VTs, Ops, 2); + void* IP = 0; + if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) { + cast(E)->refineAlignment(MMO); + return SDValue(E, 0); + } + SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl, VTs, MemVT, Chain, + Ptr, MMO, Ordering, SynchScope); CSEMap.InsertNode(N, IP); AllNodes.push_back(N); return SDValue(N, 0); @@ -5769,6 +5872,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { #endif case ISD::PREFETCH: return "Prefetch"; case ISD::MEMBARRIER: return "MemBarrier"; + case ISD::ATOMIC_FENCE: return "AtomicFence"; case ISD::ATOMIC_CMP_SWAP: return "AtomicCmpSwap"; case ISD::ATOMIC_SWAP: return "AtomicSwap"; case ISD::ATOMIC_LOAD_ADD: return "AtomicLoadAdd"; @@ -5781,6 +5885,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::ATOMIC_LOAD_MAX: return "AtomicLoadMax"; case ISD::ATOMIC_LOAD_UMIN: return "AtomicLoadUMin"; case ISD::ATOMIC_LOAD_UMAX: return "AtomicLoadUMax"; + case ISD::ATOMIC_LOAD: return "AtomicLoad"; + case ISD::ATOMIC_STORE: return "AtomicStore"; case ISD::PCMARKER: return "PCMarker"; case ISD::READCYCLECOUNTER: return "ReadCycleCounter"; case ISD::SRCVALUE: return "SrcValue"; @@ -5896,8 +6002,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::FPOWI: return "fpowi"; case ISD::SETCC: return "setcc"; - case ISD::VSETCC: return "vsetcc"; case ISD::SELECT: return "select"; + case ISD::VSELECT: return "vselect"; case ISD::SELECT_CC: return "select_cc"; case ISD::INSERT_VECTOR_ELT: return "insert_vector_elt"; case ISD::EXTRACT_VECTOR_ELT: return "extract_vector_elt"; @@ -5985,7 +6091,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const { case ISD::CTLZ: return "ctlz"; // Trampolines - case ISD::TRAMPOLINE: return "trampoline"; + case ISD::INIT_TRAMPOLINE: return "init_trampoline"; + case ISD::ADJUST_TRAMPOLINE: return "adjust_trampoline"; case ISD::CONDCODE: switch (cast(this)->get()) { @@ -6245,8 +6352,7 @@ void SDNode::print(raw_ostream &OS, const SelectionDAG *G) const { static void printrWithDepthHelper(raw_ostream &OS, const SDNode *N, const SelectionDAG *G, unsigned depth, - unsigned indent) -{ + unsigned indent) { if (depth == 0) return; @@ -6340,6 +6446,10 @@ SDValue SelectionDAG::UnrollVectorOp(SDNode *N, unsigned ResNE) { Scalars.push_back(getNode(N->getOpcode(), dl, EltVT, &Operands[0], Operands.size())); break; + case ISD::VSELECT: + Scalars.push_back(getNode(ISD::SELECT, dl, EltVT, + &Operands[0], Operands.size())); + break; case ISD::SHL: case ISD::SRA: case ISD::SRL: @@ -6427,6 +6537,8 @@ unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const { Align = TD->getPreferredAlignment(GVar); } } + if (!Align) + Align = TLI.getTargetData()->getABITypeAlignment(GV->getType()); } return MinAlign(Align, GVOffset); } @@ -6528,7 +6640,7 @@ unsigned GlobalAddressSDNode::getAddressSpace() const { } -const Type *ConstantPoolSDNode::getType() const { +Type *ConstantPoolSDNode::getType() const { if (isMachineConstantPoolEntry()) return Val.MachineCPVal->getType(); return Val.ConstVal->getType(); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 81b03ee76a5c..7ed46a6952d1 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -578,7 +578,7 @@ namespace { : ValueVTs(1, valuevt), RegVTs(1, regvt), Regs(regs) {} RegsForValue(LLVMContext &Context, const TargetLowering &tli, - unsigned Reg, const Type *Ty) { + unsigned Reg, Type *Ty) { ComputeValueVTs(tli, Ty, ValueVTs); for (unsigned Value = 0, e = ValueVTs.size(); Value != e; ++Value) { @@ -788,6 +788,18 @@ void RegsForValue::AddInlineAsmOperands(unsigned Code, bool HasMatching, unsigned Flag = InlineAsm::getFlagWord(Code, Regs.size()); if (HasMatching) Flag = InlineAsm::getFlagWordForMatchingOp(Flag, MatchingIdx); + else if (!Regs.empty() && + TargetRegisterInfo::isVirtualRegister(Regs.front())) { + // Put the register class of the virtual registers in the flag word. That + // way, later passes can recompute register class constraints for inline + // assembly as well as normal instructions. + // Don't do this for tied operands that can use the regclass information + // from the def. + const MachineRegisterInfo &MRI = DAG.getMachineFunction().getRegInfo(); + const TargetRegisterClass *RC = MRI.getRegClass(Regs.front()); + Flag = InlineAsm::getFlagWordForRegClass(Flag, RC->getID()); + } + SDValue Res = DAG.getTargetConstant(Flag, MVT::i32); Ops.push_back(Res); @@ -805,6 +817,7 @@ void SelectionDAGBuilder::init(GCFunctionInfo *gfi, AliasAnalysis &aa) { AA = &aa; GFI = gfi; TD = DAG.getTarget().getTargetData(); + LPadToCallSiteMap.clear(); } /// clear - Clear out the current SelectionDAG and the associated @@ -956,7 +969,7 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V, } } -// getValue - Return an SDValue for the given Value. +/// getValue - Return an SDValue for the given Value. SDValue SelectionDAGBuilder::getValue(const Value *V) { // If we already have an SDValue for this value, use it. It's important // to do this first, so that we don't create a CopyFromReg if we already @@ -971,7 +984,7 @@ SDValue SelectionDAGBuilder::getValue(const Value *V) { unsigned InReg = It->second; RegsForValue RFV(*DAG.getContext(), TLI, InReg, V->getType()); SDValue Chain = DAG.getEntryNode(); - N = RFV.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain,NULL); + N = RFV.getCopyFromRegs(DAG, FuncInfo, getCurDebugLoc(), Chain, NULL); resolveDanglingDebugInfo(V, N); return N; } @@ -1069,7 +1082,7 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) { if (const BlockAddress *BA = dyn_cast(C)) return DAG.getBlockAddress(BA, VT); - const VectorType *VecTy = cast(V->getType()); + VectorType *VecTy = cast(V->getType()); unsigned NumElements = VecTy->getNumElements(); // Now that we know the number and type of the elements, get that number of @@ -1277,15 +1290,17 @@ uint32_t SelectionDAGBuilder::getEdgeWeight(MachineBasicBlock *Src, BranchProbabilityInfo *BPI = FuncInfo.BPI; if (!BPI) return 0; - BasicBlock *SrcBB = const_cast(Src->getBasicBlock()); - BasicBlock *DstBB = const_cast(Dst->getBasicBlock()); + const BasicBlock *SrcBB = Src->getBasicBlock(); + const BasicBlock *DstBB = Dst->getBasicBlock(); return BPI->getEdgeWeight(SrcBB, DstBB); } -void SelectionDAGBuilder::addSuccessorWithWeight(MachineBasicBlock *Src, - MachineBasicBlock *Dst) { - uint32_t weight = getEdgeWeight(Src, Dst); - Src->addSuccessor(Dst, weight); +void SelectionDAGBuilder:: +addSuccessorWithWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst, + uint32_t Weight /* = 0 */) { + if (!Weight) + Weight = getEdgeWeight(Src, Dst); + Src->addSuccessor(Dst, Weight); } @@ -1558,8 +1573,8 @@ void SelectionDAGBuilder::visitSwitchCase(CaseBlock &CB, } // Update successor info - addSuccessorWithWeight(SwitchBB, CB.TrueBB); - addSuccessorWithWeight(SwitchBB, CB.FalseBB); + addSuccessorWithWeight(SwitchBB, CB.TrueBB, CB.TrueWeight); + addSuccessorWithWeight(SwitchBB, CB.FalseBB, CB.FalseWeight); // 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. @@ -1677,7 +1692,7 @@ void SelectionDAGBuilder::visitBitTestHeader(BitTestBlock &B, UsePtrType = true; else { for (unsigned i = 0, e = B.Cases.size(); i != e; ++i) - if ((uint64_t)((int64_t)B.Cases[i].Mask >> VT.getSizeInBits()) + 1 >= 2) { + if (!isUIntN(VT.getSizeInBits(), B.Cases[i].Mask)) { // Switch table case range are encoded into series of masks. // Just use pointer type, it's guaranteed to fit. UsePtrType = true; @@ -1808,6 +1823,49 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) { void SelectionDAGBuilder::visitUnwind(const UnwindInst &I) { } +void SelectionDAGBuilder::visitResume(const ResumeInst &RI) { + llvm_unreachable("SelectionDAGBuilder shouldn't visit resume instructions!"); +} + +void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) { + assert(FuncInfo.MBB->isLandingPad() && + "Call to landingpad not in landing pad!"); + + MachineBasicBlock *MBB = FuncInfo.MBB; + MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI(); + AddLandingPadInfo(LP, MMI, MBB); + + SmallVector ValueVTs; + ComputeValueVTs(TLI, LP.getType(), ValueVTs); + + // Insert the EXCEPTIONADDR instruction. + assert(FuncInfo.MBB->isLandingPad() && + "Call to eh.exception not in landing pad!"); + SDVTList VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other); + SDValue Ops[2]; + Ops[0] = DAG.getRoot(); + SDValue Op1 = DAG.getNode(ISD::EXCEPTIONADDR, getCurDebugLoc(), VTs, Ops, 1); + SDValue Chain = Op1.getValue(1); + + // Insert the EHSELECTION instruction. + VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other); + Ops[0] = Op1; + Ops[1] = Chain; + SDValue Op2 = DAG.getNode(ISD::EHSELECTION, getCurDebugLoc(), VTs, Ops, 2); + Chain = Op2.getValue(1); + Op2 = DAG.getSExtOrTrunc(Op2, getCurDebugLoc(), MVT::i32); + + Ops[0] = Op1; + Ops[1] = Op2; + SDValue Res = DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), + DAG.getVTList(&ValueVTs[0], ValueVTs.size()), + &Ops[0], 2); + + std::pair RetPair = std::make_pair(Res, Chain); + setValue(&LP, RetPair.first); + DAG.setRoot(RetPair.second); +} + /// handleSmallSwitchCaseRange - Emit a series of specific tests (suitable for /// small case ranges). bool SelectionDAGBuilder::handleSmallSwitchRange(CaseRec& CR, @@ -1866,8 +1924,8 @@ bool SelectionDAGBuilder::handleSmallSwitchRange(CaseRec& CR, ISD::SETEQ); // Update successor info. - SwitchBB->addSuccessor(Small.BB); - SwitchBB->addSuccessor(Default); + addSuccessorWithWeight(SwitchBB, Small.BB); + addSuccessorWithWeight(SwitchBB, Default); // Insert the true branch. SDValue BrCond = DAG.getNode(ISD::BRCOND, DL, MVT::Other, @@ -1923,7 +1981,11 @@ bool SelectionDAGBuilder::handleSmallSwitchRange(CaseRec& CR, CC = ISD::SETLE; LHS = I->Low; MHS = SV; RHS = I->High; } - CaseBlock CB(CC, LHS, RHS, MHS, I->BB, FallThrough, CurBlock); + + uint32_t ExtraWeight = I->ExtraWeight; + CaseBlock CB(CC, LHS, RHS, MHS, /* truebb */ I->BB, /* falsebb */ FallThrough, + /* me */ CurBlock, + /* trueweight */ ExtraWeight / 2, /* falseweight */ ExtraWeight / 2); // If emitting the first comparison, just call visitSwitchCase to emit the // code into the current block. Otherwise, push the CaseBlock onto the @@ -1953,10 +2015,10 @@ static APInt ComputeRange(const APInt &First, const APInt &Last) { } /// handleJTSwitchCase - Emit jumptable for current switch case range -bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR, - CaseRecVector& WorkList, - const Value* SV, - MachineBasicBlock* Default, +bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec &CR, + CaseRecVector &WorkList, + const Value *SV, + MachineBasicBlock *Default, MachineBasicBlock *SwitchBB) { Case& FrontCase = *CR.Range.first; Case& BackCase = *(CR.Range.second-1); @@ -1965,8 +2027,7 @@ bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR, const APInt &Last = cast(BackCase.High)->getValue(); APInt TSize(First.getBitWidth(), 0); - for (CaseItr I = CR.Range.first, E = CR.Range.second; - I!=E; ++I) + for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++I) TSize += I->size(); if (!areJTsAllowed(TLI) || TSize.ult(4)) @@ -2044,7 +2105,6 @@ bool SelectionDAGBuilder::handleJTSwitchCase(CaseRec& CR, visitJumpTableHeader(JT, JTH, SwitchBB); JTCases.push_back(JumpTableBlock(JTH, JT)); - return true; } @@ -2318,12 +2378,17 @@ size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases, const SwitchInst& SI) { size_t numCmps = 0; + BranchProbabilityInfo *BPI = FuncInfo.BPI; // Start with "simple" cases for (size_t i = 1; i < SI.getNumSuccessors(); ++i) { - MachineBasicBlock *SMBB = FuncInfo.MBBMap[SI.getSuccessor(i)]; + BasicBlock *SuccBB = SI.getSuccessor(i); + MachineBasicBlock *SMBB = FuncInfo.MBBMap[SuccBB]; + + uint32_t ExtraWeight = BPI ? BPI->getEdgeWeight(SI.getParent(), SuccBB) : 0; + Cases.push_back(Case(SI.getSuccessorValue(i), SI.getSuccessorValue(i), - SMBB)); + SMBB, ExtraWeight)); } std::sort(Cases.begin(), Cases.end(), CaseCmp()); @@ -2343,6 +2408,16 @@ size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases, if ((nextValue - currentValue == 1) && (currentBB == nextBB)) { I->High = J->High; J = Cases.erase(J); + + if (BranchProbabilityInfo *BPI = FuncInfo.BPI) { + uint32_t CurWeight = currentBB->getBasicBlock() ? + BPI->getEdgeWeight(SI.getParent(), currentBB->getBasicBlock()) : 16; + uint32_t NextWeight = nextBB->getBasicBlock() ? + BPI->getEdgeWeight(SI.getParent(), nextBB->getBasicBlock()) : 16; + + BPI->setEdgeWeight(SI.getParent(), currentBB->getBasicBlock(), + CurWeight + NextWeight); + } } else { I = J++; } @@ -2379,7 +2454,7 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) { // If there is only the default destination, branch to it if it is not the // next basic block. Otherwise, just fall through. - if (SI.getNumOperands() == 2) { + if (SI.getNumCases() == 1) { // Update machine-CFG edges. // If this is not a fall-through branch, emit the branch. @@ -2399,12 +2474,12 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) { size_t numCmps = Clusterify(Cases, SI); DEBUG(dbgs() << "Clusterify finished. Total clusters: " << Cases.size() << ". Total compares: " << numCmps << '\n'); - numCmps = 0; + (void)numCmps; // Get the Value to be switched on and default basic blocks, which will be // inserted into CaseBlock records, representing basic blocks in the binary // search tree. - const Value *SV = SI.getOperand(0); + const Value *SV = SI.getCondition(); // Push the initial CaseRec onto the worklist CaseRecVector WorkList; @@ -2458,7 +2533,7 @@ void SelectionDAGBuilder::visitIndirectBr(const IndirectBrInst &I) { void SelectionDAGBuilder::visitFSub(const User &I) { // -0.0 - X --> fneg - const Type *Ty = I.getType(); + Type *Ty = I.getType(); if (isa(I.getOperand(0)) && I.getOperand(0) == ConstantFP::getZeroValueForNegation(Ty)) { SDValue Op2 = getValue(I.getOperand(1)); @@ -2562,10 +2637,12 @@ void SelectionDAGBuilder::visitSelect(const User &I) { SDValue Cond = getValue(I.getOperand(0)); SDValue TrueVal = getValue(I.getOperand(1)); SDValue FalseVal = getValue(I.getOperand(2)); + ISD::NodeType OpCode = Cond.getValueType().isVector() ? + ISD::VSELECT : ISD::SELECT; for (unsigned i = 0; i != NumValues; ++i) - Values[i] = DAG.getNode(ISD::SELECT, getCurDebugLoc(), - TrueVal.getNode()->getValueType(TrueVal.getResNo()+i), + Values[i] = DAG.getNode(OpCode, getCurDebugLoc(), + TrueVal.getNode()->getValueType(TrueVal.getResNo()+i), Cond, SDValue(TrueVal.getNode(), TrueVal.getResNo() + i), @@ -2778,7 +2855,8 @@ void SelectionDAGBuilder::visitShuffleVector(const User &I) { // Analyze the access pattern of the vector to see if we can extract // two subvectors and do the shuffle. The analysis is done by calculating // the range of elements the mask access on both vectors. - int MinRange[2] = { SrcNumElts+1, SrcNumElts+1}; + int MinRange[2] = { static_cast(SrcNumElts+1), + static_cast(SrcNumElts+1)}; int MaxRange[2] = {-1, -1}; for (unsigned i = 0; i != MaskNumElts; ++i) { @@ -2886,8 +2964,8 @@ void SelectionDAGBuilder::visitShuffleVector(const User &I) { void SelectionDAGBuilder::visitInsertValue(const InsertValueInst &I) { const Value *Op0 = I.getOperand(0); const Value *Op1 = I.getOperand(1); - const Type *AggTy = I.getType(); - const Type *ValTy = Op1->getType(); + Type *AggTy = I.getType(); + Type *ValTy = Op1->getType(); bool IntoUndef = isa(Op0); bool FromUndef = isa(Op1); @@ -2927,8 +3005,8 @@ void SelectionDAGBuilder::visitInsertValue(const InsertValueInst &I) { void SelectionDAGBuilder::visitExtractValue(const ExtractValueInst &I) { const Value *Op0 = I.getOperand(0); - const Type *AggTy = Op0->getType(); - const Type *ValTy = I.getType(); + Type *AggTy = Op0->getType(); + Type *ValTy = I.getType(); bool OutOfUndef = isa(Op0); unsigned LinearIndex = ComputeLinearIndex(AggTy, I.getIndices()); @@ -2961,12 +3039,12 @@ void SelectionDAGBuilder::visitExtractValue(const ExtractValueInst &I) { void SelectionDAGBuilder::visitGetElementPtr(const User &I) { SDValue N = getValue(I.getOperand(0)); - const Type *Ty = I.getOperand(0)->getType(); + Type *Ty = I.getOperand(0)->getType(); for (GetElementPtrInst::const_op_iterator OI = I.op_begin()+1, E = I.op_end(); OI != E; ++OI) { const Value *Idx = *OI; - if (const StructType *StTy = dyn_cast(Ty)) { + if (StructType *StTy = dyn_cast(Ty)) { unsigned Field = cast(Idx)->getZExtValue(); if (Field) { // N = N + Offset @@ -3037,7 +3115,7 @@ void SelectionDAGBuilder::visitAlloca(const AllocaInst &I) { if (FuncInfo.StaticAllocaMap.count(&I)) return; // getValue will auto-populate this. - const Type *Ty = I.getAllocatedType(); + Type *Ty = I.getAllocatedType(); uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty); unsigned Align = std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), @@ -3084,10 +3162,13 @@ void SelectionDAGBuilder::visitAlloca(const AllocaInst &I) { } void SelectionDAGBuilder::visitLoad(const LoadInst &I) { + if (I.isAtomic()) + return visitAtomicLoad(I); + const Value *SV = I.getOperand(0); SDValue Ptr = getValue(SV); - const Type *Ty = I.getType(); + Type *Ty = I.getType(); bool isVolatile = I.isVolatile(); bool isNonTemporal = I.getMetadata("nontemporal") != 0; @@ -3161,6 +3242,9 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) { } void SelectionDAGBuilder::visitStore(const StoreInst &I) { + if (I.isAtomic()) + return visitAtomicStore(I); + const Value *SrcV = I.getOperand(0); const Value *PtrV = I.getOperand(1); @@ -3211,6 +3295,179 @@ void SelectionDAGBuilder::visitStore(const StoreInst &I) { DAG.setRoot(StoreNode); } +static SDValue InsertFenceForAtomic(SDValue Chain, AtomicOrdering Order, + SynchronizationScope Scope, + bool Before, DebugLoc dl, + SelectionDAG &DAG, + const TargetLowering &TLI) { + // Fence, if necessary + if (Before) { + if (Order == AcquireRelease || Order == SequentiallyConsistent) + Order = Release; + else if (Order == Acquire || Order == Monotonic) + return Chain; + } else { + if (Order == AcquireRelease) + Order = Acquire; + else if (Order == Release || Order == Monotonic) + return Chain; + } + SDValue Ops[3]; + Ops[0] = Chain; + Ops[1] = DAG.getConstant(Order, TLI.getPointerTy()); + Ops[2] = DAG.getConstant(Scope, TLI.getPointerTy()); + return DAG.getNode(ISD::ATOMIC_FENCE, dl, MVT::Other, Ops, 3); +} + +void SelectionDAGBuilder::visitAtomicCmpXchg(const AtomicCmpXchgInst &I) { + DebugLoc dl = getCurDebugLoc(); + AtomicOrdering Order = I.getOrdering(); + SynchronizationScope Scope = I.getSynchScope(); + + SDValue InChain = getRoot(); + + if (TLI.getInsertFencesForAtomic()) + InChain = InsertFenceForAtomic(InChain, Order, Scope, true, dl, + DAG, TLI); + + SDValue L = + DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, dl, + getValue(I.getCompareOperand()).getValueType().getSimpleVT(), + InChain, + getValue(I.getPointerOperand()), + getValue(I.getCompareOperand()), + getValue(I.getNewValOperand()), + MachinePointerInfo(I.getPointerOperand()), 0 /* Alignment */, + TLI.getInsertFencesForAtomic() ? Monotonic : Order, + Scope); + + SDValue OutChain = L.getValue(1); + + if (TLI.getInsertFencesForAtomic()) + OutChain = InsertFenceForAtomic(OutChain, Order, Scope, false, dl, + DAG, TLI); + + setValue(&I, L); + DAG.setRoot(OutChain); +} + +void SelectionDAGBuilder::visitAtomicRMW(const AtomicRMWInst &I) { + DebugLoc dl = getCurDebugLoc(); + ISD::NodeType NT; + switch (I.getOperation()) { + default: llvm_unreachable("Unknown atomicrmw operation"); return; + case AtomicRMWInst::Xchg: NT = ISD::ATOMIC_SWAP; break; + case AtomicRMWInst::Add: NT = ISD::ATOMIC_LOAD_ADD; break; + case AtomicRMWInst::Sub: NT = ISD::ATOMIC_LOAD_SUB; break; + case AtomicRMWInst::And: NT = ISD::ATOMIC_LOAD_AND; break; + case AtomicRMWInst::Nand: NT = ISD::ATOMIC_LOAD_NAND; break; + case AtomicRMWInst::Or: NT = ISD::ATOMIC_LOAD_OR; break; + case AtomicRMWInst::Xor: NT = ISD::ATOMIC_LOAD_XOR; break; + case AtomicRMWInst::Max: NT = ISD::ATOMIC_LOAD_MAX; break; + case AtomicRMWInst::Min: NT = ISD::ATOMIC_LOAD_MIN; break; + case AtomicRMWInst::UMax: NT = ISD::ATOMIC_LOAD_UMAX; break; + case AtomicRMWInst::UMin: NT = ISD::ATOMIC_LOAD_UMIN; break; + } + AtomicOrdering Order = I.getOrdering(); + SynchronizationScope Scope = I.getSynchScope(); + + SDValue InChain = getRoot(); + + if (TLI.getInsertFencesForAtomic()) + InChain = InsertFenceForAtomic(InChain, Order, Scope, true, dl, + DAG, TLI); + + SDValue L = + DAG.getAtomic(NT, dl, + getValue(I.getValOperand()).getValueType().getSimpleVT(), + InChain, + getValue(I.getPointerOperand()), + getValue(I.getValOperand()), + I.getPointerOperand(), 0 /* Alignment */, + TLI.getInsertFencesForAtomic() ? Monotonic : Order, + Scope); + + SDValue OutChain = L.getValue(1); + + if (TLI.getInsertFencesForAtomic()) + OutChain = InsertFenceForAtomic(OutChain, Order, Scope, false, dl, + DAG, TLI); + + setValue(&I, L); + DAG.setRoot(OutChain); +} + +void SelectionDAGBuilder::visitFence(const FenceInst &I) { + DebugLoc dl = getCurDebugLoc(); + SDValue Ops[3]; + Ops[0] = getRoot(); + Ops[1] = DAG.getConstant(I.getOrdering(), TLI.getPointerTy()); + Ops[2] = DAG.getConstant(I.getSynchScope(), TLI.getPointerTy()); + DAG.setRoot(DAG.getNode(ISD::ATOMIC_FENCE, dl, MVT::Other, Ops, 3)); +} + +void SelectionDAGBuilder::visitAtomicLoad(const LoadInst &I) { + DebugLoc dl = getCurDebugLoc(); + AtomicOrdering Order = I.getOrdering(); + SynchronizationScope Scope = I.getSynchScope(); + + SDValue InChain = getRoot(); + + EVT VT = EVT::getEVT(I.getType()); + + if (I.getAlignment() * 8 < VT.getSizeInBits()) + report_fatal_error("Cannot generate unaligned atomic load"); + + SDValue L = + DAG.getAtomic(ISD::ATOMIC_LOAD, dl, VT, VT, InChain, + getValue(I.getPointerOperand()), + I.getPointerOperand(), I.getAlignment(), + TLI.getInsertFencesForAtomic() ? Monotonic : Order, + Scope); + + SDValue OutChain = L.getValue(1); + + if (TLI.getInsertFencesForAtomic()) + OutChain = InsertFenceForAtomic(OutChain, Order, Scope, false, dl, + DAG, TLI); + + setValue(&I, L); + DAG.setRoot(OutChain); +} + +void SelectionDAGBuilder::visitAtomicStore(const StoreInst &I) { + DebugLoc dl = getCurDebugLoc(); + + AtomicOrdering Order = I.getOrdering(); + SynchronizationScope Scope = I.getSynchScope(); + + SDValue InChain = getRoot(); + + EVT VT = EVT::getEVT(I.getValueOperand()->getType()); + + if (I.getAlignment() * 8 < VT.getSizeInBits()) + report_fatal_error("Cannot generate unaligned atomic store"); + + if (TLI.getInsertFencesForAtomic()) + InChain = InsertFenceForAtomic(InChain, Order, Scope, true, dl, + DAG, TLI); + + SDValue OutChain = + DAG.getAtomic(ISD::ATOMIC_STORE, dl, VT, + InChain, + getValue(I.getPointerOperand()), + getValue(I.getValueOperand()), + I.getPointerOperand(), I.getAlignment(), + TLI.getInsertFencesForAtomic() ? Monotonic : Order, + Scope); + + if (TLI.getInsertFencesForAtomic()) + OutChain = InsertFenceForAtomic(OutChain, Order, Scope, false, dl, + DAG, TLI); + + DAG.setRoot(OutChain); +} + /// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC /// node. void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I, @@ -3290,7 +3547,7 @@ void SelectionDAGBuilder::visitTargetIntrinsic(const CallInst &I, } if (!I.getType()->isVoidTy()) { - if (const VectorType *PTy = dyn_cast(I.getType())) { + if (VectorType *PTy = dyn_cast(I.getType())) { EVT VT = TLI.getValueType(PTy); Result = DAG.getNode(ISD::BITCAST, getCurDebugLoc(), VT, Result); } @@ -3337,25 +3594,6 @@ getF32Constant(SelectionDAG &DAG, unsigned Flt) { return DAG.getConstantFP(APFloat(APInt(32, Flt)), MVT::f32); } -/// Inlined utility function to implement binary input atomic intrinsics for -/// visitIntrinsicCall: I is a call instruction -/// Op is the associated NodeType for I -const char * -SelectionDAGBuilder::implVisitBinaryAtomic(const CallInst& I, - ISD::NodeType Op) { - SDValue Root = getRoot(); - SDValue L = - DAG.getAtomic(Op, getCurDebugLoc(), - getValue(I.getArgOperand(1)).getValueType().getSimpleVT(), - Root, - getValue(I.getArgOperand(0)), - getValue(I.getArgOperand(1)), - I.getArgOperand(0)); - setValue(&I, L); - DAG.setRoot(L.getValue(1)); - return 0; -} - // implVisitAluOverflow - Lower arithmetic overflow instrinsics. const char * SelectionDAGBuilder::implVisitAluOverflow(const CallInst &I, ISD::NodeType Op) { @@ -4154,17 +4392,12 @@ SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable, return false; unsigned Reg = 0; - if (Arg->hasByValAttr()) { - // Byval arguments' frame index is recorded during argument lowering. - // Use this info directly. - Reg = TRI->getFrameRegister(MF); - Offset = FuncInfo.getByValArgumentFrameIndex(Arg); - // If byval argument ofset is not recorded then ignore this. - if (!Offset) - Reg = 0; - } + // Some arguments' frame index is recorded during argument lowering. + Offset = FuncInfo.getArgumentFrameIndex(Arg); + if (Offset) + Reg = TRI->getFrameRegister(MF); - if (N.getNode()) { + if (!Reg && N.getNode()) { if (N.getOpcode() == ISD::CopyFromReg) Reg = cast(N.getOperand(1))->getReg(); else @@ -4295,7 +4528,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { const DbgDeclareInst &DI = cast(I); MDNode *Variable = DI.getVariable(); const Value *Address = DI.getAddress(); - if (!Address || !DIVariable(DI.getVariable()).Verify()) + if (!Address || !DIVariable(Variable).Verify()) return 0; // Build an entry in DbgOrdering. Debug info input nodes get an SDNodeOrder @@ -4385,7 +4618,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { // debug info exists. ++SDNodeOrder; SDDbgValue *SDV; - if (isa(V) || isa(V)) { + if (isa(V) || isa(V) || isa(V)) { SDV = DAG.getDbgValue(Variable, V, Offset, dl, SDNodeOrder); DAG.AddDbgValue(SDV, 0, false); } else { @@ -4514,9 +4747,24 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { MMI.setCurrentCallSite(CI->getZExtValue()); return 0; } + case Intrinsic::eh_sjlj_functioncontext: { + // Get and store the index of the function context. + MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + AllocaInst *FnCtx = + cast(I.getArgOperand(0)->stripPointerCasts()); + int FI = FuncInfo.StaticAllocaMap[FnCtx]; + MFI->setFunctionContextIndex(FI); + return 0; + } case Intrinsic::eh_sjlj_setjmp: { - setValue(&I, DAG.getNode(ISD::EH_SJLJ_SETJMP, dl, MVT::i32, getRoot(), - getValue(I.getArgOperand(0)))); + SDValue Ops[2]; + Ops[0] = getRoot(); + Ops[1] = getValue(I.getArgOperand(0)); + SDValue Op = DAG.getNode(ISD::EH_SJLJ_SETJMP, dl, + DAG.getVTList(MVT::i32, MVT::Other), + Ops, 2); + setValue(&I, Op.getValue(0)); + DAG.setRoot(Op.getValue(1)); return 0; } case Intrinsic::eh_sjlj_longjmp: { @@ -4778,12 +5026,15 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { Ops[4] = DAG.getSrcValue(I.getArgOperand(0)); Ops[5] = DAG.getSrcValue(F); - Res = DAG.getNode(ISD::TRAMPOLINE, dl, - DAG.getVTList(TLI.getPointerTy(), MVT::Other), - Ops, 6); + Res = DAG.getNode(ISD::INIT_TRAMPOLINE, dl, MVT::Other, Ops, 6); - setValue(&I, Res); - DAG.setRoot(Res.getValue(1)); + DAG.setRoot(Res); + return 0; + } + case Intrinsic::adjust_trampoline: { + setValue(&I, DAG.getNode(ISD::ADJUST_TRAMPOLINE, dl, + TLI.getPointerTy(), + getValue(I.getArgOperand(0)))); return 0; } case Intrinsic::gcroot: @@ -4857,51 +5108,6 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { rw==1)); /* write */ return 0; } - case Intrinsic::memory_barrier: { - SDValue Ops[6]; - Ops[0] = getRoot(); - for (int x = 1; x < 6; ++x) - Ops[x] = getValue(I.getArgOperand(x - 1)); - - DAG.setRoot(DAG.getNode(ISD::MEMBARRIER, dl, MVT::Other, &Ops[0], 6)); - return 0; - } - case Intrinsic::atomic_cmp_swap: { - SDValue Root = getRoot(); - SDValue L = - DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, getCurDebugLoc(), - getValue(I.getArgOperand(1)).getValueType().getSimpleVT(), - Root, - getValue(I.getArgOperand(0)), - getValue(I.getArgOperand(1)), - getValue(I.getArgOperand(2)), - MachinePointerInfo(I.getArgOperand(0))); - setValue(&I, L); - DAG.setRoot(L.getValue(1)); - return 0; - } - case Intrinsic::atomic_load_add: - return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_ADD); - case Intrinsic::atomic_load_sub: - return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_SUB); - case Intrinsic::atomic_load_or: - return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_OR); - case Intrinsic::atomic_load_xor: - return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_XOR); - case Intrinsic::atomic_load_and: - return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_AND); - case Intrinsic::atomic_load_nand: - return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_NAND); - case Intrinsic::atomic_load_max: - return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MAX); - case Intrinsic::atomic_load_min: - return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_MIN); - case Intrinsic::atomic_load_umin: - return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMIN); - case Intrinsic::atomic_load_umax: - return implVisitBinaryAtomic(I, ISD::ATOMIC_LOAD_UMAX); - case Intrinsic::atomic_swap: - return implVisitBinaryAtomic(I, ISD::ATOMIC_SWAP); case Intrinsic::invariant_start: case Intrinsic::lifetime_start: @@ -4918,9 +5124,9 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) { void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee, bool isTailCall, MachineBasicBlock *LandingPad) { - const PointerType *PT = cast(CS.getCalledValue()->getType()); - const FunctionType *FTy = cast(PT->getElementType()); - const Type *RetTy = FTy->getReturnType(); + PointerType *PT = cast(CS.getCalledValue()->getType()); + FunctionType *FTy = cast(PT->getElementType()); + Type *RetTy = FTy->getReturnType(); MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI(); MCSymbol *BeginLabel = 0; @@ -4949,7 +5155,7 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee, FTy->getReturnType()); MachineFunction &MF = DAG.getMachineFunction(); DemoteStackIdx = MF.getFrameInfo()->CreateStackObject(TySize, Align, false); - const Type *StackSlotPtrType = PointerType::getUnqual(FTy->getReturnType()); + Type *StackSlotPtrType = PointerType::getUnqual(FTy->getReturnType()); DemoteStackSlot = DAG.getFrameIndex(DemoteStackIdx, TLI.getPointerTy()); Entry.Node = DemoteStackSlot; @@ -4997,6 +5203,8 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee, unsigned CallSiteIndex = MMI.getCurrentCallSite(); if (CallSiteIndex) { MMI.setCallSiteBeginLabel(BeginLabel, CallSiteIndex); + LPadToCallSiteMap[LandingPad].push_back(CallSiteIndex); + // Now that the call site is handled, stop tracking it. MMI.setCurrentCallSite(0); } @@ -5037,7 +5245,7 @@ void SelectionDAGBuilder::LowerCallTo(ImmutableCallSite CS, SDValue Callee, // The instruction result is the result of loading from the // hidden sret parameter. SmallVector PVTs; - const Type *PtrRetTy = PointerType::getUnqual(FTy->getReturnType()); + Type *PtrRetTy = PointerType::getUnqual(FTy->getReturnType()); ComputeValueVTs(TLI, PtrRetTy, PVTs); assert(PVTs.size() == 1 && "Pointers should fit in one register"); @@ -5130,7 +5338,7 @@ static bool IsOnlyUsedInZeroEqualityComparison(const Value *V) { } static SDValue getMemCmpLoad(const Value *PtrVal, MVT LoadVT, - const Type *LoadTy, + Type *LoadTy, SelectionDAGBuilder &Builder) { // Check to see if this load can be trivially constant folded, e.g. if the @@ -5193,7 +5401,7 @@ bool SelectionDAGBuilder::visitMemCmpCall(const CallInst &I) { if (Size && IsOnlyUsedInZeroEqualityComparison(&I)) { bool ActuallyDoIt = true; MVT LoadVT; - const Type *LoadTy; + Type *LoadTy; switch (Size->getZExtValue()) { default: LoadVT = MVT::Other; @@ -5261,14 +5469,14 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) { // See if any floating point values are being passed to this function. This is // used to emit an undefined reference to fltused on Windows. - const FunctionType *FT = + FunctionType *FT = cast(I.getCalledValue()->getType()->getContainedType(0)); MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI(); if (FT->isVarArg() && !MMI.callsExternalVAFunctionWithFloatingPointArguments()) { for (unsigned i = 0, e = I.getNumArgOperands(); i != e; ++i) { - const Type* T = I.getArgOperand(i)->getType(); - for (po_iterator i = po_begin(T), e = po_end(T); + Type* T = I.getArgOperand(i)->getType(); + for (po_iterator i = po_begin(T), e = po_end(T); i != e; ++i) { if (!i->isFloatingPointTy()) continue; MMI.setCallsExternalVAFunctionWithFloatingPointArguments(true); @@ -5412,20 +5620,20 @@ class SDISelAsmOperandInfo : public TargetLowering::AsmOperandInfo { if (isa(CallOperandVal)) return TLI.getPointerTy(); - const llvm::Type *OpTy = CallOperandVal->getType(); + llvm::Type *OpTy = CallOperandVal->getType(); // FIXME: code duplicated from TargetLowering::ParseConstraints(). // If this is an indirect operand, the operand is a pointer to the // accessed type. if (isIndirect) { - const llvm::PointerType *PtrTy = dyn_cast(OpTy); + llvm::PointerType *PtrTy = dyn_cast(OpTy); if (!PtrTy) report_fatal_error("Indirect operand for inline asm not a pointer!"); OpTy = PtrTy->getElementType(); } // Look for vector wrapped in a struct. e.g. { <16 x i8> }. - if (const StructType *STy = dyn_cast(OpTy)) + if (StructType *STy = dyn_cast(OpTy)) if (STy->getNumElements() == 1) OpTy = STy->getElementType(0); @@ -5637,9 +5845,8 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { // The return value of the call is this value. As such, there is no // corresponding argument. - assert(!CS.getType()->isVoidTy() && - "Bad inline asm!"); - if (const StructType *STy = dyn_cast(CS.getType())) { + assert(!CS.getType()->isVoidTy() && "Bad inline asm!"); + if (StructType *STy = dyn_cast(CS.getType())) { OpVT = TLI.getValueType(STy->getElementType(ResNo)); } else { assert(ResNo == 0 && "Asm only has one result!"); @@ -5707,9 +5914,11 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { if (OpInfo.ConstraintVT != Input.ConstraintVT) { std::pair MatchRC = - TLI.getRegForInlineAsmConstraint(OpInfo.ConstraintCode, OpInfo.ConstraintVT); + TLI.getRegForInlineAsmConstraint(OpInfo.ConstraintCode, + OpInfo.ConstraintVT); std::pair InputRC = - TLI.getRegForInlineAsmConstraint(Input.ConstraintCode, Input.ConstraintVT); + TLI.getRegForInlineAsmConstraint(Input.ConstraintCode, + Input.ConstraintVT); if ((OpInfo.ConstraintVT.isInteger() != Input.ConstraintVT.isInteger()) || (MatchRC.second != InputRC.second)) { @@ -5750,7 +5959,7 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) { } else { // Otherwise, create a stack slot and emit a store to it before the // asm. - const Type *Ty = OpVal->getType(); + Type *Ty = OpVal->getType(); uint64_t TySize = TLI.getTargetData()->getTypeAllocSize(Ty); unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty); MachineFunction &MF = DAG.getMachineFunction(); @@ -6111,7 +6320,7 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) { /// FIXME: When all targets are /// migrated to using LowerCall, this hook should be integrated into SDISel. std::pair -TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, +TargetLowering::LowerCallTo(SDValue Chain, Type *RetTy, bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg, unsigned NumFixedArgs, CallingConv::ID CallConv, bool isTailCall, @@ -6128,7 +6337,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, for (unsigned Value = 0, NumValues = ValueVTs.size(); Value != NumValues; ++Value) { EVT VT = ValueVTs[Value]; - const Type *ArgTy = VT.getTypeForEVT(RetTy->getContext()); + Type *ArgTy = VT.getTypeForEVT(RetTy->getContext()); SDValue Op = SDValue(Args[i].Node.getNode(), Args[i].Node.getResNo() + Value); ISD::ArgFlagsTy Flags; @@ -6145,8 +6354,8 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, Flags.setSRet(); if (Args[i].isByVal) { Flags.setByVal(); - const PointerType *Ty = cast(Args[i].Ty); - const Type *ElementTy = Ty->getElementType(); + PointerType *Ty = cast(Args[i].Ty); + Type *ElementTy = Ty->getElementType(); Flags.setByValSize(getTargetData()->getTypeAllocSize(ElementTy)); // For ByVal, alignment should come from FE. BE will guess if this // info is not there but there are cases it cannot get right. @@ -6356,7 +6565,7 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) { for (unsigned Value = 0, NumValues = ValueVTs.size(); Value != NumValues; ++Value) { EVT VT = ValueVTs[Value]; - const Type *ArgTy = VT.getTypeForEVT(*DAG.getContext()); + Type *ArgTy = VT.getTypeForEVT(*DAG.getContext()); ISD::ArgFlagsTy Flags; unsigned OriginalAlignment = TD->getABITypeAlignment(ArgTy); @@ -6371,8 +6580,8 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) { Flags.setSRet(); if (F.paramHasAttr(Idx, Attribute::ByVal)) { Flags.setByVal(); - const PointerType *Ty = cast(I->getType()); - const Type *ElementTy = Ty->getElementType(); + PointerType *Ty = cast(I->getType()); + Type *ElementTy = Ty->getElementType(); Flags.setByValSize(TD->getTypeAllocSize(ElementTy)); // For ByVal, alignment should be passed from FE. BE will guess if // this info is not there but there are cases it cannot get right. @@ -6487,15 +6696,22 @@ void SelectionDAGISel::LowerArguments(const BasicBlock *LLVMBB) { if (ArgValues.empty()) continue; - // Note down frame index for byval arguments. - if (I->hasByValAttr()) - if (FrameIndexSDNode *FI = - dyn_cast(ArgValues[0].getNode())) - FuncInfo->setByValArgumentFrameIndex(I, FI->getIndex()); + // Note down frame index. + if (FrameIndexSDNode *FI = + dyn_cast(ArgValues[0].getNode())) + FuncInfo->setArgumentFrameIndex(I, FI->getIndex()); SDValue Res = DAG.getMergeValues(&ArgValues[0], NumValues, SDB->getCurDebugLoc()); + SDB->setValue(I, Res); + if (!EnableFastISel && Res.getOpcode() == ISD::BUILD_PAIR) { + if (LoadSDNode *LNode = + dyn_cast(Res.getOperand(0).getNode())) + if (FrameIndexSDNode *FI = + dyn_cast(LNode->getBasePtr().getNode())) + FuncInfo->setArgumentFrameIndex(I, FI->getIndex()); + } // If this argument is live outside of the entry block, insert a copy from // wherever we got it to the vreg that other BB's will reference it as. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index a0884ebf5d56..0a21ca3472ca 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -132,10 +132,13 @@ class SelectionDAGBuilder { Constant* Low; Constant* High; MachineBasicBlock* BB; + uint32_t ExtraWeight; + + Case() : Low(0), High(0), BB(0), ExtraWeight(0) { } + Case(Constant* low, Constant* high, MachineBasicBlock* bb, + uint32_t extraweight) : Low(low), High(high), BB(bb), + ExtraWeight(extraweight) { } - Case() : Low(0), High(0), BB(0) { } - Case(Constant* low, Constant* high, MachineBasicBlock* bb) : - Low(low), High(high), BB(bb) { } APInt size() const { const APInt &rHigh = cast(High)->getValue(); const APInt &rLow = cast(Low)->getValue(); @@ -203,20 +206,30 @@ class SelectionDAGBuilder { CaseBlock(ISD::CondCode cc, const Value *cmplhs, const Value *cmprhs, const Value *cmpmiddle, MachineBasicBlock *truebb, MachineBasicBlock *falsebb, - MachineBasicBlock *me) + MachineBasicBlock *me, + uint32_t trueweight = 0, uint32_t falseweight = 0) : CC(cc), CmpLHS(cmplhs), CmpMHS(cmpmiddle), CmpRHS(cmprhs), - TrueBB(truebb), FalseBB(falsebb), ThisBB(me) {} + TrueBB(truebb), FalseBB(falsebb), ThisBB(me), + TrueWeight(trueweight), FalseWeight(falseweight) { } + // CC - the condition code to use for the case block's setcc node ISD::CondCode CC; + // CmpLHS/CmpRHS/CmpMHS - The LHS/MHS/RHS of the comparison to emit. // Emit by default LHS op RHS. MHS is used for range comparisons: // If MHS is not null: (LHS <= MHS) and (MHS <= RHS). const Value *CmpLHS, *CmpMHS, *CmpRHS; + // TrueBB/FalseBB - the block to branch to if the setcc is true/false. MachineBasicBlock *TrueBB, *FalseBB; + // ThisBB - the block into which to emit the code for the setcc and branches MachineBasicBlock *ThisBB; + + // TrueWeight/FalseWeight - branch weights. + uint32_t TrueWeight, FalseWeight; }; + struct JumpTable { JumpTable(unsigned R, unsigned J, MachineBasicBlock *M, MachineBasicBlock *D): Reg(R), JTI(J), MBB(M), Default(D) {} @@ -307,6 +320,9 @@ class SelectionDAGBuilder { /// GFI - Garbage collection metadata for the function. GCFunctionInfo *GFI; + /// LPadToCallSiteMap - Map a landing pad to the call site indexes. + DenseMap > LPadToCallSiteMap; + /// HasTailCall - This is set to true if a call in the current /// block has been translated as a tail call. In this case, /// no subsequent DAG nodes should be created. @@ -436,7 +452,8 @@ class SelectionDAGBuilder { MachineBasicBlock *SwitchBB); uint32_t getEdgeWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst); - void addSuccessorWithWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst); + void addSuccessorWithWeight(MachineBasicBlock *Src, MachineBasicBlock *Dst, + uint32_t Weight = 0); public: void visitSwitchCase(CaseBlock &CB, MachineBasicBlock *SwitchBB); @@ -453,6 +470,7 @@ class SelectionDAGBuilder { private: // These all get lowered before this pass. void visitInvoke(const InvokeInst &I); + void visitResume(const ResumeInst &I); void visitUnwind(const UnwindInst &I); void visitBinary(const User &I, unsigned OpCode); @@ -497,6 +515,7 @@ class SelectionDAGBuilder { void visitExtractValue(const ExtractValueInst &I); void visitInsertValue(const InsertValueInst &I); + void visitLandingPad(const LandingPadInst &I); void visitGetElementPtr(const User &I); void visitSelect(const User &I); @@ -504,10 +523,15 @@ class SelectionDAGBuilder { void visitAlloca(const AllocaInst &I); void visitLoad(const LoadInst &I); void visitStore(const StoreInst &I); + void visitAtomicCmpXchg(const AtomicCmpXchgInst &I); + void visitAtomicRMW(const AtomicRMWInst &I); + void visitFence(const FenceInst &I); void visitPHI(const PHINode &I); void visitCall(const CallInst &I); bool visitMemCmpCall(const CallInst &I); - + void visitAtomicLoad(const LoadInst &I); + void visitAtomicStore(const StoreInst &I); + void visitInlineAsm(ImmutableCallSite CS); const char *visitIntrinsicCall(const CallInst &I, unsigned Intrinsic); void visitTargetIntrinsic(const CallInst &I, unsigned Intrinsic); @@ -531,7 +555,6 @@ class SelectionDAGBuilder { llvm_unreachable("UserOp2 should not exist at instruction selection time!"); } - const char *implVisitBinaryAtomic(const CallInst& I, ISD::NodeType Op); const char *implVisitAluOverflow(const CallInst &I, ISD::NodeType Op); void HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 87bb296b8c79..68b9146adfe1 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -177,6 +177,13 @@ TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, return 0; } +void TargetLowering::AdjustInstrPostInstrSelection(MachineInstr *MI, + SDNode *Node) const { + assert(!MI->getDesc().hasPostISelHook() && + "If a target marks an instruction with 'hasPostISelHook', " + "it must implement TargetLowering::AdjustInstrPostInstrSelection!"); +} + //===----------------------------------------------------------------------===// // SelectionDAGISel code //===----------------------------------------------------------------------===// @@ -463,6 +470,7 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { GroupName = "Instruction Selection and Scheduling"; std::string BlockName; int BlockNumber = -1; + (void)BlockNumber; #ifdef NDEBUG if (ViewDAGCombine1 || ViewLegalizeTypesDAGs || ViewLegalizeDAGs || ViewDAGCombine2 || ViewDAGCombineLT || ViewISelDAGs || ViewSchedDAGs || @@ -677,21 +685,26 @@ void SelectionDAGISel::DoInstructionSelection() { /// PrepareEHLandingPad - Emit an EH_LABEL, set up live-in registers, and /// do other setup for EH landing-pad blocks. void SelectionDAGISel::PrepareEHLandingPad() { + MachineBasicBlock *MBB = FuncInfo->MBB; + // Add a label to mark the beginning of the landing pad. Deletion of the // landing pad can thus be detected via the MachineModuleInfo. - MCSymbol *Label = MF->getMMI().addLandingPad(FuncInfo->MBB); + MCSymbol *Label = MF->getMMI().addLandingPad(MBB); + // Assign the call site to the landing pad's begin label. + MF->getMMI().setCallSiteLandingPad(Label, SDB->LPadToCallSiteMap[MBB]); + const MCInstrDesc &II = TM.getInstrInfo()->get(TargetOpcode::EH_LABEL); - BuildMI(*FuncInfo->MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II) + BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II) .addSym(Label); // Mark exception register as live in. unsigned Reg = TLI.getExceptionAddressRegister(); - if (Reg) FuncInfo->MBB->addLiveIn(Reg); + if (Reg) MBB->addLiveIn(Reg); // Mark exception selector register as live in. Reg = TLI.getExceptionSelectorRegister(); - if (Reg) FuncInfo->MBB->addLiveIn(Reg); + if (Reg) MBB->addLiveIn(Reg); // FIXME: Hack around an exception handling flaw (PR1508): the personality // function and list of typeids logically belong to the invoke (or, if you @@ -704,7 +717,7 @@ void SelectionDAGISel::PrepareEHLandingPad() { // in exceptions not being caught because no typeids are associated with // the invoke. This may not be the only way things can go wrong, but it // is the only way we try to work around for the moment. - const BasicBlock *LLVMBB = FuncInfo->MBB->getBasicBlock(); + const BasicBlock *LLVMBB = MBB->getBasicBlock(); const BranchInst *Br = dyn_cast(LLVMBB->getTerminator()); if (Br && Br->isUnconditional()) { // Critical edge? @@ -719,8 +732,6 @@ void SelectionDAGISel::PrepareEHLandingPad() { } } - - /// TryToFoldFastISelLoad - We're checking to see if we can fold the specified /// load into the specified FoldInst. Note that we could have a sequence where /// multiple LLVM IR instructions are folded into the same machineinstr. For @@ -741,7 +752,7 @@ bool SelectionDAGISel::TryToFoldFastISelLoad(const LoadInst *LI, // isn't one of the folded instructions, then we can't succeed here. Handle // this by scanning the single-use users of the load until we get to FoldInst. unsigned MaxUsers = 6; // Don't scan down huge single-use chains of instrs. - + const Instruction *TheUser = LI->use_back(); while (TheUser != FoldInst && // Scan up until we find FoldInst. // Stay in the right block. @@ -750,10 +761,15 @@ bool SelectionDAGISel::TryToFoldFastISelLoad(const LoadInst *LI, // If there are multiple or no uses of this instruction, then bail out. if (!TheUser->hasOneUse()) return false; - + TheUser = TheUser->use_back(); } - + + // If we didn't find the fold instruction, then we failed to collapse the + // sequence. + if (TheUser != FoldInst) + return false; + // Don't try to fold volatile loads. Target has to deal with alignment // constraints. if (LI->isVolatile()) return false; @@ -802,6 +818,7 @@ static bool isFoldedOrDeadInstruction(const Instruction *I, return !I->mayWriteToMemory() && // Side-effecting instructions aren't folded. !isa(I) && // Terminators aren't folded. !isa(I) && // Debug instructions aren't folded. + !isa(I) && // Landingpad instructions aren't folded. !FuncInfo->isExportedInst(I); // Exported instrs must be computed. } diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 2626ac3bbb2a..907d8d9da1af 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -317,7 +317,7 @@ static void InitLibcallNames(const char **Names) { Names[RTLIB::SYNC_FETCH_AND_OR_8] = "__sync_fetch_and_or_8"; Names[RTLIB::SYNC_FETCH_AND_XOR_1] = "__sync_fetch_and_xor_1"; Names[RTLIB::SYNC_FETCH_AND_XOR_2] = "__sync_fetch_and_xor_2"; - Names[RTLIB::SYNC_FETCH_AND_XOR_4] = "__sync_fetch_and-xor_4"; + Names[RTLIB::SYNC_FETCH_AND_XOR_4] = "__sync_fetch_and_xor_4"; Names[RTLIB::SYNC_FETCH_AND_XOR_8] = "__sync_fetch_and_xor_8"; Names[RTLIB::SYNC_FETCH_AND_NAND_1] = "__sync_fetch_and_nand_1"; Names[RTLIB::SYNC_FETCH_AND_NAND_2] = "__sync_fetch_and_nand_2"; @@ -609,6 +609,7 @@ TargetLowering::TargetLowering(const TargetMachine &tm, ExceptionPointerRegister = 0; ExceptionSelectorRegister = 0; BooleanContents = UndefinedBooleanContent; + BooleanVectorContents = UndefinedBooleanContent; SchedPreferenceInfo = Sched::Latency; JumpBufSize = 0; JumpBufAlignment = 0; @@ -617,6 +618,7 @@ TargetLowering::TargetLowering(const TargetMachine &tm, PrefLoopAlignment = 0; MinStackArgumentAlignment = 1; ShouldFoldAtomicFences = false; + InsertFencesForAtomic = false; InitLibcallNames(LibcallRoutineNames); InitCmpLibcallCCs(CmpLibcallCCs); @@ -914,7 +916,8 @@ const char *TargetLowering::getTargetNodeName(unsigned Opcode) const { } -MVT::SimpleValueType TargetLowering::getSetCCResultType(EVT VT) const { +EVT TargetLowering::getSetCCResultType(EVT VT) const { + assert(!VT.isVector() && "No default SetCC type for vectors!"); return PointerTy.SimpleTy; } @@ -996,7 +999,7 @@ unsigned TargetLowering::getVectorTypeBreakdown(LLVMContext &Context, EVT VT, /// type of the given function. This does not require a DAG or a return value, /// and is suitable for use before any DAGs for the function are constructed. /// TODO: Move this out of TargetLowering.cpp. -void llvm::GetReturnInfo(const Type* ReturnType, Attributes attr, +void llvm::GetReturnInfo(Type* ReturnType, Attributes attr, SmallVectorImpl &Outs, const TargetLowering &TLI, SmallVectorImpl *Offsets) { @@ -1054,7 +1057,7 @@ void llvm::GetReturnInfo(const Type* ReturnType, Attributes attr, /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate /// function arguments in the caller parameter area. This is the actual /// alignment, not its logarithm. -unsigned TargetLowering::getByValTypeAlignment(const Type *Ty) const { +unsigned TargetLowering::getByValTypeAlignment(Type *Ty) const { return TD->getCallFrameTypeAlignment(Ty); } @@ -1764,17 +1767,16 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, break; } case ISD::AssertZext: { - // Demand all the bits of the input that are demanded in the output. - // The low bits are obvious; the high bits are demanded because we're - // asserting that they're zero here. - if (SimplifyDemandedBits(Op.getOperand(0), NewMask, + // AssertZext demands all of the high bits, plus any of the low bits + // demanded by its users. + EVT VT = cast(Op.getOperand(1))->getVT(); + APInt InMask = APInt::getLowBitsSet(BitWidth, + VT.getSizeInBits()); + if (SimplifyDemandedBits(Op.getOperand(0), ~InMask | NewMask, KnownZero, KnownOne, TLO, Depth+1)) return true; assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); - EVT VT = cast(Op.getOperand(1))->getVT(); - APInt InMask = APInt::getLowBitsSet(BitWidth, - VT.getSizeInBits()); KnownZero |= ~InMask & NewMask; break; } @@ -2191,7 +2193,7 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1, } } else if (N1C->getAPIntValue() == 1 && (VT == MVT::i1 || - getBooleanContents() == ZeroOrOneBooleanContent)) { + getBooleanContents(false) == ZeroOrOneBooleanContent)) { SDValue Op0 = N0; if (Op0.getOpcode() == ISD::TRUNCATE) Op0 = Op0.getOperand(0); @@ -2758,16 +2760,8 @@ getRegForInlineAsmConstraint(const std::string &Constraint, // 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(); - I != E; ++I) { - if (isTypeLegal(*I)) { - isLegal = true; - break; - } - } - - if (!isLegal) continue; + if (!isLegalRC(RC)) + continue; for (TargetRegisterClass::iterator I = RC->begin(), E = RC->end(); I != E; ++I) { @@ -2840,7 +2834,7 @@ TargetLowering::AsmOperandInfoVector TargetLowering::ParseConstraints( // corresponding argument. assert(!CS.getType()->isVoidTy() && "Bad inline asm!"); - if (const StructType *STy = dyn_cast(CS.getType())) { + if (StructType *STy = dyn_cast(CS.getType())) { OpInfo.ConstraintVT = getValueType(STy->getElementType(ResNo)); } else { assert(ResNo == 0 && "Asm only has one result!"); @@ -2857,16 +2851,16 @@ TargetLowering::AsmOperandInfoVector TargetLowering::ParseConstraints( } if (OpInfo.CallOperandVal) { - const llvm::Type *OpTy = OpInfo.CallOperandVal->getType(); + llvm::Type *OpTy = OpInfo.CallOperandVal->getType(); if (OpInfo.isIndirect) { - const llvm::PointerType *PtrTy = dyn_cast(OpTy); + llvm::PointerType *PtrTy = dyn_cast(OpTy); if (!PtrTy) report_fatal_error("Indirect operand for inline asm not a pointer!"); OpTy = PtrTy->getElementType(); } // Look for vector wrapped in a struct. e.g. { <16 x i8> }. - if (const StructType *STy = dyn_cast(OpTy)) + if (StructType *STy = dyn_cast(OpTy)) if (STy->getNumElements() == 1) OpTy = STy->getElementType(0); @@ -3187,7 +3181,7 @@ void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo, /// isLegalAddressingMode - Return true if the addressing mode represented /// by AM is legal for this target, for a load/store of the specified type. bool TargetLowering::isLegalAddressingMode(const AddrMode &AM, - const Type *Ty) const { + Type *Ty) const { // The default implementation of this implements a conservative RISCy, r+r and // r+i addr mode. diff --git a/lib/CodeGen/ShadowStackGC.cpp b/lib/CodeGen/ShadowStackGC.cpp index 5a253a4d97e4..2609256c8ffa 100644 --- a/lib/CodeGen/ShadowStackGC.cpp +++ b/lib/CodeGen/ShadowStackGC.cpp @@ -61,7 +61,7 @@ namespace { private: bool IsNullValue(Value *V); Constant *GetFrameMap(Function &F); - const Type* GetConcreteStackEntryType(Function &F); + Type* GetConcreteStackEntryType(Function &F); void CollectRoots(Function &F); static GetElementPtrInst *CreateGEP(LLVMContext &Context, IRBuilder<> &B, Value *BasePtr, @@ -109,13 +109,15 @@ namespace { State = 1; case 1: - // Find all 'return' and 'unwind' instructions. + // Find all 'return', 'resume', and 'unwind' instructions. while (StateBB != StateE) { BasicBlock *CurBB = StateBB++; - // Branches and invokes do not escape, only unwind and return do. + // Branches and invokes do not escape, only unwind, resume, and return + // do. TerminatorInst *TI = CurBB->getTerminator(); - if (!isa(TI) && !isa(TI)) + if (!isa(TI) && !isa(TI) && + !isa(TI)) continue; Builder.SetInsertPoint(TI->getParent(), TI); @@ -139,9 +141,19 @@ namespace { return 0; // Create a cleanup block. - BasicBlock *CleanupBB = BasicBlock::Create(F.getContext(), - CleanupBBName, &F); - UnwindInst *UI = new UnwindInst(F.getContext(), CleanupBB); + LLVMContext &C = F.getContext(); + BasicBlock *CleanupBB = BasicBlock::Create(C, CleanupBBName, &F); + Type *ExnTy = StructType::get(Type::getInt8PtrTy(C), + Type::getInt32Ty(C), NULL); + Constant *PersFn = + F.getParent()-> + getOrInsertFunction("__gcc_personality_v0", + FunctionType::get(Type::getInt32Ty(C), true)); + LandingPadInst *LPad = LandingPadInst::Create(ExnTy, PersFn, 1, + "cleanup.lpad", + CleanupBB); + LPad->setCleanup(true); + ResumeInst *RI = ResumeInst::Create(LPad, CleanupBB); // Transform the 'call' instructions into 'invoke's branching to the // cleanup block. Go in reverse order to make prettier BB names. @@ -172,7 +184,7 @@ namespace { delete CI; } - Builder.SetInsertPoint(UI->getParent(), UI); + Builder.SetInsertPoint(RI->getParent(), RI); return &Builder; } } @@ -190,7 +202,7 @@ ShadowStackGC::ShadowStackGC() : Head(0), StackEntryTy(0) { Constant *ShadowStackGC::GetFrameMap(Function &F) { // doInitialization creates the abstract type of this value. - const Type *VoidPtr = Type::getInt8PtrTy(F.getContext()); + Type *VoidPtr = Type::getInt8PtrTy(F.getContext()); // Truncate the ShadowStackDescriptor if some metadata is null. unsigned NumMeta = 0; @@ -203,7 +215,7 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) { } Metadata.resize(NumMeta); - const Type *Int32Ty = Type::getInt32Ty(F.getContext()); + Type *Int32Ty = Type::getInt32Ty(F.getContext()); Constant *BaseElts[] = { ConstantInt::get(Int32Ty, Roots.size(), false), @@ -216,7 +228,7 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) { }; Type *EltTys[] = { DescriptorElts[0]->getType(),DescriptorElts[1]->getType()}; - StructType *STy = StructType::createNamed("gc_map."+utostr(NumMeta), EltTys); + StructType *STy = StructType::create(EltTys, "gc_map."+utostr(NumMeta)); Constant *FrameMap = ConstantStruct::get(STy, DescriptorElts); @@ -241,17 +253,17 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) { ConstantInt::get(Type::getInt32Ty(F.getContext()), 0), ConstantInt::get(Type::getInt32Ty(F.getContext()), 0) }; - return ConstantExpr::getGetElementPtr(GV, GEPIndices, 2); + return ConstantExpr::getGetElementPtr(GV, GEPIndices); } -const Type* ShadowStackGC::GetConcreteStackEntryType(Function &F) { +Type* ShadowStackGC::GetConcreteStackEntryType(Function &F) { // doInitialization creates the generic version of this type. std::vector EltTys; EltTys.push_back(StackEntryTy); for (size_t I = 0; I != Roots.size(); I++) EltTys.push_back(Roots[I].second->getAllocatedType()); - return StructType::createNamed("gc_stackentry."+F.getName().str(), EltTys); + return StructType::create(EltTys, "gc_stackentry."+F.getName().str()); } /// doInitialization - If this module uses the GC intrinsics, find them now. If @@ -267,7 +279,7 @@ bool ShadowStackGC::initializeCustomLowering(Module &M) { EltTys.push_back(Type::getInt32Ty(M.getContext())); // Specifies length of variable length array. EltTys.push_back(Type::getInt32Ty(M.getContext())); - FrameMapTy = StructType::createNamed("gc_map", EltTys); + FrameMapTy = StructType::create(EltTys, "gc_map"); PointerType *FrameMapPtrTy = PointerType::getUnqual(FrameMapTy); // struct StackEntry { @@ -276,13 +288,13 @@ bool ShadowStackGC::initializeCustomLowering(Module &M) { // void *Roots[]; // Stack roots (in-place array, so we pretend). // }; - StackEntryTy = StructType::createNamed(M.getContext(), "gc_stackentry"); + StackEntryTy = StructType::create(M.getContext(), "gc_stackentry"); EltTys.clear(); EltTys.push_back(PointerType::getUnqual(StackEntryTy)); EltTys.push_back(FrameMapPtrTy); StackEntryTy->setBody(EltTys); - const PointerType *StackEntryPtrTy = PointerType::getUnqual(StackEntryTy); + PointerType *StackEntryPtrTy = PointerType::getUnqual(StackEntryTy); // Get the root chain if it already exists. Head = M.getGlobalVariable("llvm_gc_root_chain"); @@ -340,7 +352,7 @@ ShadowStackGC::CreateGEP(LLVMContext &Context, IRBuilder<> &B, Value *BasePtr, Value *Indices[] = { ConstantInt::get(Type::getInt32Ty(Context), 0), ConstantInt::get(Type::getInt32Ty(Context), Idx), ConstantInt::get(Type::getInt32Ty(Context), Idx2) }; - Value* Val = B.CreateGEP(BasePtr, Indices, Indices + 3, Name); + Value* Val = B.CreateGEP(BasePtr, Indices, Name); assert(isa(Val) && "Unexpected folded constant"); @@ -352,7 +364,7 @@ ShadowStackGC::CreateGEP(LLVMContext &Context, IRBuilder<> &B, Value *BasePtr, int Idx, const char *Name) { Value *Indices[] = { ConstantInt::get(Type::getInt32Ty(Context), 0), ConstantInt::get(Type::getInt32Ty(Context), Idx) }; - Value *Val = B.CreateGEP(BasePtr, Indices, Indices + 2, Name); + Value *Val = B.CreateGEP(BasePtr, Indices, Name); assert(isa(Val) && "Unexpected folded constant"); @@ -373,7 +385,7 @@ bool ShadowStackGC::performCustomLowering(Function &F) { // Build the constant map and figure the type of the shadow stack entry. Value *FrameMap = GetFrameMap(F); - const Type *ConcreteStackEntryTy = GetConcreteStackEntryType(F); + Type *ConcreteStackEntryTy = GetConcreteStackEntryType(F); // Build the shadow stack entry at the very start of the function. BasicBlock::iterator IP = F.getEntryBlock().begin(); diff --git a/lib/CodeGen/SjLjEHPrepare.cpp b/lib/CodeGen/SjLjEHPrepare.cpp index 65a33da93afe..ded2459d4278 100644 --- a/lib/CodeGen/SjLjEHPrepare.cpp +++ b/lib/CodeGen/SjLjEHPrepare.cpp @@ -21,26 +21,31 @@ #include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/Pass.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/Support/Debug.h" +#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/IRBuilder.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" #include using namespace llvm; +static cl::opt DisableOldSjLjEH("disable-old-sjlj-eh", cl::Hidden, + cl::desc("Disable the old SjLj EH preparation pass")); + STATISTIC(NumInvokes, "Number of invokes replaced"); STATISTIC(NumUnwinds, "Number of unwinds replaced"); STATISTIC(NumSpilled, "Number of registers live across unwind edges"); namespace { class SjLjEHPass : public FunctionPass { - const TargetLowering *TLI; - - const Type *FunctionContextTy; + Type *FunctionContextTy; Constant *RegisterFn; Constant *UnregisterFn; Constant *BuiltinSetjmpFn; @@ -53,8 +58,9 @@ namespace { Constant *ExceptionFn; Constant *CallSiteFn; Constant *DispatchSetupFn; - + Constant *FuncCtxFn; Value *CallSite; + DenseMap LPadSuccMap; public: static char ID; // Pass identification, replacement for typeid explicit SjLjEHPass(const TargetLowering *tli = NULL) @@ -62,16 +68,22 @@ namespace { bool doInitialization(Module &M); bool runOnFunction(Function &F); - virtual void getAnalysisUsage(AnalysisUsage &AU) const { } + virtual void getAnalysisUsage(AnalysisUsage &AU) const {} const char *getPassName() const { return "SJLJ Exception Handling preparation"; } private: + bool setupEntryBlockAndCallSites(Function &F); + Value *setupFunctionContext(Function &F, ArrayRef LPads); + void lowerIncomingArguments(Function &F); + void lowerAcrossUnwindEdges(Function &F, ArrayRef Invokes); + void insertCallSiteStore(Instruction *I, int Number, Value *CallSite); void markInvokeCallSite(InvokeInst *II, int InvokeNo, Value *CallSite, SwitchInst *CatchSwitch); void splitLiveRangesAcrossInvokes(SmallVector &Invokes); + void splitLandingPad(InvokeInst *II); bool insertSjLjEHSupport(Function &F); }; } // end anonymous namespace @@ -116,6 +128,7 @@ bool SjLjEHPass::doInitialization(Module &M) { CallSiteFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_callsite); DispatchSetupFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_dispatch_setup); + FuncCtxFn = Intrinsic::getDeclaration(&M, Intrinsic::eh_sjlj_functioncontext); PersonalityFn = 0; return true; @@ -131,6 +144,42 @@ void SjLjEHPass::insertCallSiteStore(Instruction *I, int Number, new StoreInst(CallSiteNoC, CallSite, true, I); // volatile } +/// splitLandingPad - Split a landing pad. This takes considerable care because +/// of PHIs and other nasties. The problem is that the jump table needs to jump +/// to the landing pad block. However, the landing pad block can be jumped to +/// only by an invoke instruction. So we clone the landingpad instruction into +/// its own basic block, have the invoke jump to there. The landingpad +/// instruction's basic block's successor is now the target for the jump table. +/// +/// But because of PHI nodes, we need to create another basic block for the jump +/// table to jump to. This is definitely a hack, because the values for the PHI +/// nodes may not be defined on the edge from the jump table. But that's okay, +/// because the jump table is simply a construct to mimic what is happening in +/// the CFG. So the values are mysteriously there, even though there is no value +/// for the PHI from the jump table's edge (hence calling this a hack). +void SjLjEHPass::splitLandingPad(InvokeInst *II) { + SmallVector NewBBs; + SplitLandingPadPredecessors(II->getUnwindDest(), II->getParent(), + ".1", ".2", this, NewBBs); + + // Create an empty block so that the jump table has something to jump to + // which doesn't have any PHI nodes. + BasicBlock *LPad = NewBBs[0]; + BasicBlock *Succ = *succ_begin(LPad); + BasicBlock *JumpTo = BasicBlock::Create(II->getContext(), "jt.land", + LPad->getParent(), Succ); + LPad->getTerminator()->eraseFromParent(); + BranchInst::Create(JumpTo, LPad); + BranchInst::Create(Succ, JumpTo); + LPadSuccMap[II] = JumpTo; + + for (BasicBlock::iterator I = Succ->begin(); isa(I); ++I) { + PHINode *PN = cast(I); + Value *Val = PN->removeIncomingValue(LPad, false); + PN->addIncoming(Val, JumpTo); + } +} + /// markInvokeCallSite - Insert code to mark the call_site for this invoke void SjLjEHPass::markInvokeCallSite(InvokeInst *II, int InvokeNo, Value *CallSite, @@ -140,11 +189,15 @@ void SjLjEHPass::markInvokeCallSite(InvokeInst *II, int InvokeNo, // The runtime comes back to the dispatcher with the call_site - 1 in // the context. Odd, but there it is. ConstantInt *SwitchValC = ConstantInt::get(Type::getInt32Ty(II->getContext()), - InvokeNo - 1); + InvokeNo - 1); // If the unwind edge has phi nodes, split the edge. if (isa(II->getUnwindDest()->begin())) { - SplitCriticalEdge(II, 1, this); + // FIXME: New EH - This if-condition will be always true in the new scheme. + if (II->getUnwindDest()->isLandingPad()) + splitLandingPad(II); + else + SplitCriticalEdge(II, 1, this); // If there are any phi nodes left, they must have a single predecessor. while (PHINode *PN = dyn_cast(II->getUnwindDest()->begin())) { @@ -161,7 +214,12 @@ void SjLjEHPass::markInvokeCallSite(InvokeInst *II, int InvokeNo, CallInst::Create(CallSiteFn, CallSiteNoC, "", II); // Add a switch case to our unwind block. - CatchSwitch->addCase(SwitchValC, II->getUnwindDest()); + if (BasicBlock *SuccBB = LPadSuccMap[II]) { + CatchSwitch->addCase(SwitchValC, SuccBB); + } else { + CatchSwitch->addCase(SwitchValC, II->getUnwindDest()); + } + // 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. } @@ -187,10 +245,16 @@ splitLiveRangesAcrossInvokes(SmallVector &Invokes) { for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { InvokeInst *II = Invokes[i]; SplitCriticalEdge(II, 0, this); - SplitCriticalEdge(II, 1, this); + + // FIXME: New EH - This if-condition will be always true in the new scheme. + if (II->getUnwindDest()->isLandingPad()) + splitLandingPad(II); + else + SplitCriticalEdge(II, 1, this); + assert(!isa(II->getNormalDest()) && !isa(II->getUnwindDest()) && - "critical edge splitting left single entry phi nodes?"); + "Critical edge splitting left single entry phi nodes?"); } Function *F = Invokes.back()->getParent()->getParent(); @@ -204,7 +268,7 @@ splitLiveRangesAcrossInvokes(SmallVector &Invokes) { ++AfterAllocaInsertPt; for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; ++AI) { - const Type *Ty = AI->getType(); + Type *Ty = AI->getType(); // Aggregate types can't be cast, but are legal argument types, so we have // to handle them differently. We use an extract/insert pair as a // lightweight method to achieve the same goal. @@ -283,9 +347,8 @@ splitLiveRangesAcrossInvokes(SmallVector &Invokes) { bool NeedsSpill = false; for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); - if (UnwindBlock != BB && LiveBBs.count(UnwindBlock)) { + if (UnwindBlock != BB && LiveBBs.count(UnwindBlock)) NeedsSpill = true; - } } // If we decided we need a spill, do it. @@ -299,6 +362,44 @@ splitLiveRangesAcrossInvokes(SmallVector &Invokes) { } } +/// CreateLandingPadLoad - Load the exception handling values and insert them +/// into a structure. +static Instruction *CreateLandingPadLoad(Function &F, Value *ExnAddr, + Value *SelAddr, + BasicBlock::iterator InsertPt) { + Value *Exn = new LoadInst(ExnAddr, "exn", false, + InsertPt); + Type *Ty = Type::getInt8PtrTy(F.getContext()); + Exn = CastInst::Create(Instruction::IntToPtr, Exn, Ty, "", InsertPt); + Value *Sel = new LoadInst(SelAddr, "sel", false, InsertPt); + + Ty = StructType::get(Exn->getType(), Sel->getType(), NULL); + InsertValueInst *LPadVal = InsertValueInst::Create(llvm::UndefValue::get(Ty), + Exn, 0, + "lpad.val", InsertPt); + return InsertValueInst::Create(LPadVal, Sel, 1, "lpad.val", InsertPt); +} + +/// ReplaceLandingPadVal - Replace the landingpad instruction's value with a +/// load from the stored values (via CreateLandingPadLoad). This looks through +/// PHI nodes, and removes them if they are dead. +static void ReplaceLandingPadVal(Function &F, Instruction *Inst, Value *ExnAddr, + Value *SelAddr) { + if (Inst->use_empty()) return; + + while (!Inst->use_empty()) { + Instruction *I = cast(Inst->use_back()); + + if (PHINode *PN = dyn_cast(I)) { + ReplaceLandingPadVal(F, PN, ExnAddr, SelAddr); + if (PN->use_empty()) PN->eraseFromParent(); + continue; + } + + I->replaceUsesOfWith(Inst, CreateLandingPadLoad(F, ExnAddr, SelAddr, I)); + } +} + bool SjLjEHPass::insertSjLjEHSupport(Function &F) { SmallVector Returns; SmallVector Unwinds; @@ -337,10 +438,23 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { SmallVector EH_Exceptions; SmallVector JmpbufUpdatePoints; - // Note: Skip the entry block since there's nothing there that interests - // us. eh.selector and eh.exception shouldn't ever be there, and we - // want to disregard any allocas that are there. - for (Function::iterator BB = F.begin(), E = F.end(); ++BB != E;) { + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { + // Note: Skip the entry block since there's nothing there that interests + // us. eh.selector and eh.exception shouldn't ever be there, and we + // want to disregard any allocas that are there. + // + // FIXME: This is awkward. The new EH scheme won't need to skip the entry + // block. + if (BB == F.begin()) { + if (InvokeInst *II = dyn_cast(F.begin()->getTerminator())) { + // FIXME: This will be always non-NULL in the new EH. + if (LandingPadInst *LPI = II->getUnwindDest()->getLandingPadInst()) + if (!PersonalityFn) PersonalityFn = LPI->getPersonalityFn(); + } + + continue; + } + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { if (CallInst *CI = dyn_cast(I)) { if (CI->getCalledFunction() == SelectorFn) { @@ -353,6 +467,10 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { } } else if (AllocaInst *AI = dyn_cast(I)) { JmpbufUpdatePoints.push_back(AI); + } else if (InvokeInst *II = dyn_cast(I)) { + // FIXME: This will be always non-NULL in the new EH. + if (LandingPadInst *LPI = II->getUnwindDest()->getLandingPadInst()) + if (!PersonalityFn) PersonalityFn = LPI->getPersonalityFn(); } } } @@ -371,6 +489,16 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { // invoke's. splitLiveRangesAcrossInvokes(Invokes); + + SmallVector LandingPads; + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { + if (InvokeInst *II = dyn_cast(BB->getTerminator())) + // FIXME: This will be always non-NULL in the new EH. + if (LandingPadInst *LPI = II->getUnwindDest()->getLandingPadInst()) + LandingPads.push_back(LPI); + } + + BasicBlock *EntryBB = F.begin(); // Create an alloca for the incoming jump buffer ptr and the new jump buffer // that needs to be restored on all exits from the function. This is an @@ -381,27 +509,25 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { "fcn_context", F.begin()->begin()); Value *Idxs[2]; - const Type *Int32Ty = Type::getInt32Ty(F.getContext()); + Type *Int32Ty = Type::getInt32Ty(F.getContext()); Value *Zero = ConstantInt::get(Int32Ty, 0); // We need to also keep around a reference to the call_site field Idxs[0] = Zero; Idxs[1] = ConstantInt::get(Int32Ty, 1); - CallSite = GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, - "call_site", + CallSite = GetElementPtrInst::Create(FunctionContext, Idxs, "call_site", EntryBB->getTerminator()); // The exception selector comes back in context->data[1] Idxs[1] = ConstantInt::get(Int32Ty, 2); - Value *FCData = GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, - "fc_data", + Value *FCData = GetElementPtrInst::Create(FunctionContext, Idxs, "fc_data", EntryBB->getTerminator()); Idxs[1] = ConstantInt::get(Int32Ty, 1); - Value *SelectorAddr = GetElementPtrInst::Create(FCData, Idxs, Idxs+2, + Value *SelectorAddr = GetElementPtrInst::Create(FCData, Idxs, "exc_selector_gep", EntryBB->getTerminator()); // The exception value comes back in context->data[0] Idxs[1] = Zero; - Value *ExceptionAddr = GetElementPtrInst::Create(FCData, Idxs, Idxs+2, + Value *ExceptionAddr = GetElementPtrInst::Create(FCData, Idxs, "exception_gep", EntryBB->getTerminator()); @@ -423,13 +549,16 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { // instruction hasn't already been removed. if (!I->getParent()) continue; Value *Val = new LoadInst(ExceptionAddr, "exception", true, I); - const Type *Ty = Type::getInt8PtrTy(F.getContext()); + Type *Ty = Type::getInt8PtrTy(F.getContext()); Val = CastInst::Create(Instruction::IntToPtr, Val, Ty, "", I); I->replaceAllUsesWith(Val); I->eraseFromParent(); } + for (unsigned i = 0, e = LandingPads.size(); i != e; ++i) + ReplaceLandingPadVal(F, LandingPads[i], ExceptionAddr, SelectorAddr); + // The entry block changes to have the eh.sjlj.setjmp, with a conditional // branch to a dispatch block for non-zero returns. If we return normally, // we're not handling an exception and just register the function context and @@ -466,8 +595,7 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { Idxs[0] = Zero; Idxs[1] = ConstantInt::get(Int32Ty, 4); Value *LSDAFieldPtr = - GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, - "lsda_gep", + GetElementPtrInst::Create(FunctionContext, Idxs, "lsda_gep", EntryBB->getTerminator()); Value *LSDA = CallInst::Create(LSDAAddrFn, "lsda_addr", EntryBB->getTerminator()); @@ -475,8 +603,7 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { Idxs[1] = ConstantInt::get(Int32Ty, 3); Value *PersonalityFieldPtr = - GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, - "lsda_gep", + GetElementPtrInst::Create(FunctionContext, Idxs, "lsda_gep", EntryBB->getTerminator()); new StoreInst(PersonalityFn, PersonalityFieldPtr, true, EntryBB->getTerminator()); @@ -484,12 +611,11 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { // Save the frame pointer. Idxs[1] = ConstantInt::get(Int32Ty, 5); Value *JBufPtr - = GetElementPtrInst::Create(FunctionContext, Idxs, Idxs+2, - "jbuf_gep", + = GetElementPtrInst::Create(FunctionContext, Idxs, "jbuf_gep", EntryBB->getTerminator()); Idxs[1] = ConstantInt::get(Int32Ty, 0); Value *FramePtr = - GetElementPtrInst::Create(JBufPtr, Idxs, Idxs+2, "jbuf_fp_gep", + GetElementPtrInst::Create(JBufPtr, Idxs, "jbuf_fp_gep", EntryBB->getTerminator()); Value *Val = CallInst::Create(FrameAddrFn, @@ -501,7 +627,7 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { // Save the stack pointer. Idxs[1] = ConstantInt::get(Int32Ty, 2); Value *StackPtr = - GetElementPtrInst::Create(JBufPtr, Idxs, Idxs+2, "jbuf_sp_gep", + GetElementPtrInst::Create(JBufPtr, Idxs, "jbuf_sp_gep", EntryBB->getTerminator()); Val = CallInst::Create(StackAddrFn, "sp", EntryBB->getTerminator()); @@ -513,7 +639,7 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { Type::getInt8PtrTy(F.getContext()), "", EntryBB->getTerminator()); Value *DispatchVal = CallInst::Create(BuiltinSetjmpFn, SetjmpArg, - "dispatch", + "", EntryBB->getTerminator()); // Add a call to dispatch_setup after the setjmp call. This is expanded to any @@ -554,6 +680,8 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { if (Callee != SelectorFn && Callee != ExceptionFn && !CI->doesNotThrow()) insertCallSiteStore(CI, -1, CallSite); + } else if (ResumeInst *RI = dyn_cast(I)) { + insertCallSiteStore(RI, -1, CallSite); } } @@ -582,7 +710,317 @@ bool SjLjEHPass::insertSjLjEHSupport(Function &F) { return true; } +/// setupFunctionContext - Allocate the function context on the stack and fill +/// it with all of the data that we know at this point. +Value *SjLjEHPass:: +setupFunctionContext(Function &F, ArrayRef LPads) { + BasicBlock *EntryBB = F.begin(); + + // Create an alloca for the incoming jump buffer ptr and the new jump buffer + // that needs to be restored on all exits from the function. This is an alloca + // because the value needs to be added to the global context list. + unsigned Align = + TLI->getTargetData()->getPrefTypeAlignment(FunctionContextTy); + AllocaInst *FuncCtx = + new AllocaInst(FunctionContextTy, 0, Align, "fn_context", EntryBB->begin()); + + // Fill in the function context structure. + Value *Idxs[2]; + Type *Int32Ty = Type::getInt32Ty(F.getContext()); + Value *Zero = ConstantInt::get(Int32Ty, 0); + Value *One = ConstantInt::get(Int32Ty, 1); + + // Keep around a reference to the call_site field. + Idxs[0] = Zero; + Idxs[1] = One; + CallSite = GetElementPtrInst::Create(FuncCtx, Idxs, "call_site", + EntryBB->getTerminator()); + + // Reference the __data field. + Idxs[1] = ConstantInt::get(Int32Ty, 2); + Value *FCData = GetElementPtrInst::Create(FuncCtx, Idxs, "__data", + EntryBB->getTerminator()); + + // The exception value comes back in context->__data[0]. + Idxs[1] = Zero; + Value *ExceptionAddr = GetElementPtrInst::Create(FCData, Idxs, + "exception_gep", + EntryBB->getTerminator()); + + // The exception selector comes back in context->__data[1]. + Idxs[1] = One; + Value *SelectorAddr = GetElementPtrInst::Create(FCData, Idxs, + "exn_selector_gep", + EntryBB->getTerminator()); + + for (unsigned I = 0, E = LPads.size(); I != E; ++I) { + LandingPadInst *LPI = LPads[I]; + IRBuilder<> Builder(LPI->getParent()->getFirstInsertionPt()); + + Value *ExnVal = Builder.CreateLoad(ExceptionAddr, true, "exn_val"); + ExnVal = Builder.CreateIntToPtr(ExnVal, Type::getInt8PtrTy(F.getContext())); + Value *SelVal = Builder.CreateLoad(SelectorAddr, true, "exn_selector_val"); + + Type *LPadType = LPI->getType(); + Value *LPadVal = UndefValue::get(LPadType); + LPadVal = Builder.CreateInsertValue(LPadVal, ExnVal, 0, "lpad.val"); + LPadVal = Builder.CreateInsertValue(LPadVal, SelVal, 1, "lpad.val"); + + LPI->replaceAllUsesWith(LPadVal); + } + + // Personality function + Idxs[1] = ConstantInt::get(Int32Ty, 3); + if (!PersonalityFn) + PersonalityFn = LPads[0]->getPersonalityFn(); + Value *PersonalityFieldPtr = + GetElementPtrInst::Create(FuncCtx, Idxs, "pers_fn_gep", + EntryBB->getTerminator()); + new StoreInst(PersonalityFn, PersonalityFieldPtr, true, + EntryBB->getTerminator()); + + // LSDA address + Idxs[1] = ConstantInt::get(Int32Ty, 4); + Value *LSDAFieldPtr = GetElementPtrInst::Create(FuncCtx, Idxs, "lsda_gep", + EntryBB->getTerminator()); + Value *LSDA = CallInst::Create(LSDAAddrFn, "lsda_addr", + EntryBB->getTerminator()); + new StoreInst(LSDA, LSDAFieldPtr, true, EntryBB->getTerminator()); + + return FuncCtx; +} + +/// lowerIncomingArguments - To avoid having to handle incoming arguments +/// specially, we lower each arg to a copy instruction in the entry block. This +/// ensures that the argument value itself cannot be live out of the entry +/// block. +void SjLjEHPass::lowerIncomingArguments(Function &F) { + BasicBlock::iterator AfterAllocaInsPt = F.begin()->begin(); + while (isa(AfterAllocaInsPt) && + isa(cast(AfterAllocaInsPt)->getArraySize())) + ++AfterAllocaInsPt; + + for (Function::arg_iterator + AI = F.arg_begin(), AE = F.arg_end(); AI != AE; ++AI) { + Type *Ty = AI->getType(); + + // Aggregate types can't be cast, but are legal argument types, so we have + // to handle them differently. We use an extract/insert pair as a + // lightweight method to achieve the same goal. + if (isa(Ty) || isa(Ty) || isa(Ty)) { + Instruction *EI = ExtractValueInst::Create(AI, 0, "", AfterAllocaInsPt); + Instruction *NI = InsertValueInst::Create(AI, EI, 0); + NI->insertAfter(EI); + AI->replaceAllUsesWith(NI); + + // Set the operand of the instructions back to the AllocaInst. + EI->setOperand(0, AI); + NI->setOperand(0, AI); + } else { + // This is always a no-op cast because we're casting AI to AI->getType() + // so src and destination types are identical. BitCast is the only + // possibility. + CastInst *NC = + new BitCastInst(AI, AI->getType(), AI->getName() + ".tmp", + AfterAllocaInsPt); + AI->replaceAllUsesWith(NC); + + // Set the operand of the cast instruction back to the AllocaInst. + // Normally it's forbidden to replace a CastInst's operand because it + // could cause the opcode to reflect an illegal conversion. However, we're + // replacing it here with the same value it was constructed with. We do + // this because the above replaceAllUsesWith() clobbered the operand, but + // we want this one to remain. + NC->setOperand(0, AI); + } + } +} + +/// lowerAcrossUnwindEdges - Find all variables which are alive across an unwind +/// edge and spill them. +void SjLjEHPass::lowerAcrossUnwindEdges(Function &F, + ArrayRef Invokes) { + // Finally, scan the code looking for instructions with bad live ranges. + for (Function::iterator + BB = F.begin(), BBE = F.end(); BB != BBE; ++BB) { + for (BasicBlock::iterator + II = BB->begin(), IIE = BB->end(); II != IIE; ++II) { + // Ignore obvious cases we don't have to handle. In particular, most + // instructions either have no uses or only have a single use inside the + // current block. Ignore them quickly. + Instruction *Inst = II; + if (Inst->use_empty()) continue; + if (Inst->hasOneUse() && + cast(Inst->use_back())->getParent() == BB && + !isa(Inst->use_back())) continue; + + // If this is an alloca in the entry block, it's not a real register + // value. + if (AllocaInst *AI = dyn_cast(Inst)) + if (isa(AI->getArraySize()) && BB == F.begin()) + continue; + + // Avoid iterator invalidation by copying users to a temporary vector. + SmallVector Users; + for (Value::use_iterator + UI = Inst->use_begin(), E = Inst->use_end(); UI != E; ++UI) { + Instruction *User = cast(*UI); + if (User->getParent() != BB || isa(User)) + Users.push_back(User); + } + + // Find all of the blocks that this value is live in. + std::set LiveBBs; + LiveBBs.insert(Inst->getParent()); + while (!Users.empty()) { + Instruction *U = Users.back(); + Users.pop_back(); + + if (!isa(U)) { + MarkBlocksLiveIn(U->getParent(), LiveBBs); + } else { + // Uses for a PHI node occur in their predecessor block. + PHINode *PN = cast(U); + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) + if (PN->getIncomingValue(i) == Inst) + MarkBlocksLiveIn(PN->getIncomingBlock(i), LiveBBs); + } + } + + // Now that we know all of the blocks that this thing is live in, see if + // it includes any of the unwind locations. + bool NeedsSpill = false; + for (unsigned i = 0, e = Invokes.size(); i != e; ++i) { + BasicBlock *UnwindBlock = Invokes[i]->getUnwindDest(); + if (UnwindBlock != BB && LiveBBs.count(UnwindBlock)) { + NeedsSpill = true; + } + } + + // If we decided we need a spill, do it. + // FIXME: Spilling this way is overkill, as it forces all uses of + // the value to be reloaded from the stack slot, even those that aren't + // in the unwind blocks. We should be more selective. + if (NeedsSpill) { + ++NumSpilled; + DemoteRegToStack(*Inst, true); + } + } + } +} + +/// setupEntryBlockAndCallSites - Setup the entry block by creating and filling +/// the function context and marking the call sites with the appropriate +/// values. These values are used by the DWARF EH emitter. +bool SjLjEHPass::setupEntryBlockAndCallSites(Function &F) { + SmallVector Returns; + SmallVector Invokes; + SmallVector LPads; + + // Look through the terminators of the basic blocks to find invokes. + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + if (InvokeInst *II = dyn_cast(BB->getTerminator())) { + Invokes.push_back(II); + LPads.push_back(II->getUnwindDest()->getLandingPadInst()); + } else if (ReturnInst *RI = dyn_cast(BB->getTerminator())) { + Returns.push_back(RI); + } + + if (Invokes.empty()) return false; + + lowerIncomingArguments(F); + lowerAcrossUnwindEdges(F, Invokes); + + Value *FuncCtx = setupFunctionContext(F, LPads); + BasicBlock *EntryBB = F.begin(); + Type *Int32Ty = Type::getInt32Ty(F.getContext()); + + Value *Idxs[2] = { + ConstantInt::get(Int32Ty, 0), 0 + }; + + // Get a reference to the jump buffer. + Idxs[1] = ConstantInt::get(Int32Ty, 5); + Value *JBufPtr = GetElementPtrInst::Create(FuncCtx, Idxs, "jbuf_gep", + EntryBB->getTerminator()); + + // Save the frame pointer. + Idxs[1] = ConstantInt::get(Int32Ty, 0); + Value *FramePtr = GetElementPtrInst::Create(JBufPtr, Idxs, "jbuf_fp_gep", + EntryBB->getTerminator()); + + Value *Val = CallInst::Create(FrameAddrFn, + ConstantInt::get(Int32Ty, 0), + "fp", + EntryBB->getTerminator()); + new StoreInst(Val, FramePtr, true, EntryBB->getTerminator()); + + // Save the stack pointer. + Idxs[1] = ConstantInt::get(Int32Ty, 2); + Value *StackPtr = GetElementPtrInst::Create(JBufPtr, Idxs, "jbuf_sp_gep", + EntryBB->getTerminator()); + + Val = CallInst::Create(StackAddrFn, "sp", EntryBB->getTerminator()); + new StoreInst(Val, StackPtr, true, EntryBB->getTerminator()); + + // Call the setjmp instrinsic. It fills in the rest of the jmpbuf. + Value *SetjmpArg = CastInst::Create(Instruction::BitCast, JBufPtr, + Type::getInt8PtrTy(F.getContext()), "", + EntryBB->getTerminator()); + CallInst::Create(BuiltinSetjmpFn, SetjmpArg, "", EntryBB->getTerminator()); + + // Store a pointer to the function context so that the back-end will know + // where to look for it. + Value *FuncCtxArg = CastInst::Create(Instruction::BitCast, FuncCtx, + Type::getInt8PtrTy(F.getContext()), "", + EntryBB->getTerminator()); + CallInst::Create(FuncCtxFn, FuncCtxArg, "", EntryBB->getTerminator()); + + // At this point, we are all set up, update the invoke instructions to mark + // their call_site values. + for (unsigned I = 0, E = Invokes.size(); I != E; ++I) { + insertCallSiteStore(Invokes[I], I + 1, CallSite); + + ConstantInt *CallSiteNum = + ConstantInt::get(Type::getInt32Ty(F.getContext()), I + 1); + + // Record the call site value for the back end so it stays associated with + // the invoke. + CallInst::Create(CallSiteFn, CallSiteNum, "", Invokes[I]); + } + + // Mark call instructions that aren't nounwind as no-action (call_site == + // -1). Skip the entry block, as prior to then, no function context has been + // created for this function and any unexpected exceptions thrown will go + // directly to the caller's context, which is what we want anyway, so no need + // to do anything here. + for (Function::iterator BB = F.begin(), E = F.end(); ++BB != E;) + for (BasicBlock::iterator I = BB->begin(), end = BB->end(); I != end; ++I) + if (CallInst *CI = dyn_cast(I)) { + if (!CI->doesNotThrow()) + insertCallSiteStore(CI, -1, CallSite); + } else if (ResumeInst *RI = dyn_cast(I)) { + insertCallSiteStore(RI, -1, CallSite); + } + + // Register the function context and make sure it's known to not throw + CallInst *Register = CallInst::Create(RegisterFn, FuncCtx, "", + EntryBB->getTerminator()); + Register->setDoesNotThrow(); + + // Finally, for any returns from this function, if this function contains an + // invoke, add a call to unregister the function context. + for (unsigned I = 0, E = Returns.size(); I != E; ++I) + CallInst::Create(UnregisterFn, FuncCtx, "", Returns[I]); + + return true; +} + bool SjLjEHPass::runOnFunction(Function &F) { - bool Res = insertSjLjEHSupport(F); + bool Res = false; + if (!DisableOldSjLjEH) + Res = insertSjLjEHSupport(F); + else + Res = setupEntryBlockAndCallSites(F); return Res; } diff --git a/lib/CodeGen/SpillPlacement.cpp b/lib/CodeGen/SpillPlacement.cpp index 694961863261..6f33f5465ca2 100644 --- a/lib/CodeGen/SpillPlacement.cpp +++ b/lib/CodeGen/SpillPlacement.cpp @@ -220,6 +220,7 @@ void SpillPlacement::addConstraints(ArrayRef LiveBlocks) { 0, // DontCare, 1, // PrefReg, -1, // PrefSpill + 0, // PrefBoth -HUGE_VALF // MustSpill }; @@ -239,6 +240,22 @@ void SpillPlacement::addConstraints(ArrayRef LiveBlocks) { } } +/// addPrefSpill - Same as addConstraints(PrefSpill) +void SpillPlacement::addPrefSpill(ArrayRef Blocks, bool Strong) { + for (ArrayRef::iterator I = Blocks.begin(), E = Blocks.end(); + I != E; ++I) { + float Freq = getBlockFrequency(*I); + if (Strong) + Freq += Freq; + unsigned ib = bundles->getBundle(*I, 0); + unsigned ob = bundles->getBundle(*I, 1); + activate(ib); + activate(ob); + nodes[ib].addBias(-Freq, 1); + nodes[ob].addBias(-Freq, 0); + } +} + void SpillPlacement::addLinks(ArrayRef Links) { for (ArrayRef::iterator I = Links.begin(), E = Links.end(); I != E; ++I) { diff --git a/lib/CodeGen/SpillPlacement.h b/lib/CodeGen/SpillPlacement.h index 6952ad800965..fc412f817cdb 100644 --- a/lib/CodeGen/SpillPlacement.h +++ b/lib/CodeGen/SpillPlacement.h @@ -71,6 +71,7 @@ class SpillPlacement : public MachineFunctionPass { DontCare, ///< Block doesn't care / variable not live. PrefReg, ///< Block entry/exit prefers a register. PrefSpill, ///< Block entry/exit prefers a stack slot. + PrefBoth, ///< Block entry prefers both register and stack. MustSpill ///< A register is impossible, variable must be spilled. }; @@ -79,6 +80,11 @@ class SpillPlacement : public MachineFunctionPass { unsigned Number; ///< Basic block number (from MBB::getNumber()). BorderConstraint Entry : 8; ///< Constraint on block entry. BorderConstraint Exit : 8; ///< Constraint on block exit. + + /// True when this block changes the value of the live range. This means + /// the block has a non-PHI def. When this is false, a live-in value on + /// the stack can be live-out on the stack without inserting a spill. + bool ChangesValue; }; /// prepare - Reset state and prepare for a new spill placement computation. @@ -96,6 +102,14 @@ class SpillPlacement : public MachineFunctionPass { /// live out. void addConstraints(ArrayRef LiveBlocks); + /// addPrefSpill - Add PrefSpill constraints to all blocks listed. This is + /// equivalent to calling addConstraint with identical BlockConstraints with + /// Entry = Exit = PrefSpill, and ChangesValue = false. + /// + /// @param Blocks Array of block numbers that prefer to spill in and out. + /// @param Strong When true, double the negative bias for these blocks. + void addPrefSpill(ArrayRef Blocks, bool Strong); + /// addLinks - Add transparent blocks with the given numbers. void addLinks(ArrayRef Links); diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp index 761cab7ce850..63627800af69 100644 --- a/lib/CodeGen/SplitKit.cpp +++ b/lib/CodeGen/SplitKit.cpp @@ -20,6 +20,7 @@ #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -178,45 +179,55 @@ bool SplitAnalysis::calcLiveBlockInfo() { return false; } else { // This block has uses. Find the first and last uses in the block. - BI.FirstUse = *UseI; - assert(BI.FirstUse >= Start); + BI.FirstInstr = *UseI; + assert(BI.FirstInstr >= Start); do ++UseI; while (UseI != UseE && *UseI < Stop); - BI.LastUse = UseI[-1]; - assert(BI.LastUse < Stop); + BI.LastInstr = UseI[-1]; + assert(BI.LastInstr < Stop); // LVI is the first live segment overlapping MBB. BI.LiveIn = LVI->start <= Start; + // When not live in, the first use should be a def. + if (!BI.LiveIn) { + assert(LVI->start == LVI->valno->def && "Dangling LiveRange start"); + assert(LVI->start == BI.FirstInstr && "First instr should be a def"); + BI.FirstDef = BI.FirstInstr; + } + // Look for gaps in the live range. BI.LiveOut = true; while (LVI->end < Stop) { SlotIndex LastStop = LVI->end; if (++LVI == LVE || LVI->start >= Stop) { BI.LiveOut = false; - BI.LastUse = LastStop; + BI.LastInstr = LastStop; break; } + if (LastStop < LVI->start) { // There is a gap in the live range. Create duplicate entries for the // live-in snippet and the live-out snippet. ++NumGapBlocks; // Push the Live-in part. - BI.LiveThrough = false; BI.LiveOut = false; UseBlocks.push_back(BI); - UseBlocks.back().LastUse = LastStop; + UseBlocks.back().LastInstr = LastStop; // Set up BI for the live-out part. BI.LiveIn = false; BI.LiveOut = true; - BI.FirstUse = LVI->start; + BI.FirstInstr = BI.FirstDef = LVI->start; } + + // A LiveRange that starts in the middle of the block must be a def. + assert(LVI->start == LVI->valno->def && "Dangling LiveRange start"); + if (!BI.FirstDef) + BI.FirstDef = LVI->start; } - // Don't set LiveThrough when the block has a gap. - BI.LiveThrough = BI.LiveIn && BI.LiveOut; UseBlocks.push_back(BI); // LVI is now at LVE or LVI->end >= Stop. @@ -299,17 +310,21 @@ SplitEditor::SplitEditor(SplitAnalysis &sa, TRI(*vrm.getMachineFunction().getTarget().getRegisterInfo()), Edit(0), OpenIdx(0), + SpillMode(SM_Partition), RegAssign(Allocator) {} -void SplitEditor::reset(LiveRangeEdit &lre) { - Edit = &lre; +void SplitEditor::reset(LiveRangeEdit &LRE, ComplementSpillMode SM) { + Edit = &LRE; + SpillMode = SM; OpenIdx = 0; RegAssign.clear(); Values.clear(); - // We don't need to clear LiveOutCache, only LiveOutSeen entries are read. - LiveOutSeen.clear(); + // Reset the LiveRangeCalc instances needed for this spill mode. + LRCalc[0].reset(&VRM.getMachineFunction()); + if (SpillMode) + LRCalc[1].reset(&VRM.getMachineFunction()); // We don't need an AliasAnalysis since we will only be performing // cheap-as-a-copy remats anyway. @@ -340,7 +355,8 @@ VNInfo *SplitEditor::defValue(unsigned RegIdx, // Use insert for lookup, so we can add missing values with a second lookup. std::pair InsP = - Values.insert(std::make_pair(std::make_pair(RegIdx, ParentVNI->id), VNI)); + Values.insert(std::make_pair(std::make_pair(RegIdx, ParentVNI->id), + ValueForcePair(VNI, false))); // This was the first time (RegIdx, ParentVNI) was mapped. // Keep it as a simple def without any liveness. @@ -348,11 +364,11 @@ VNInfo *SplitEditor::defValue(unsigned RegIdx, return VNI; // If the previous value was a simple mapping, add liveness for it now. - if (VNInfo *OldVNI = InsP.first->second) { + if (VNInfo *OldVNI = InsP.first->second.getPointer()) { SlotIndex Def = OldVNI->def; LI->addRange(LiveRange(Def, Def.getNextSlot(), OldVNI)); - // No longer a simple mapping. - InsP.first->second = 0; + // No longer a simple mapping. Switch to a complex, non-forced mapping. + InsP.first->second = ValueForcePair(); } // This is a complex mapping, add liveness for VNI @@ -362,230 +378,24 @@ VNInfo *SplitEditor::defValue(unsigned RegIdx, return VNI; } -void SplitEditor::markComplexMapped(unsigned RegIdx, const VNInfo *ParentVNI) { +void SplitEditor::forceRecompute(unsigned RegIdx, const VNInfo *ParentVNI) { assert(ParentVNI && "Mapping NULL value"); - VNInfo *&VNI = Values[std::make_pair(RegIdx, ParentVNI->id)]; + ValueForcePair &VFP = Values[std::make_pair(RegIdx, ParentVNI->id)]; + VNInfo *VNI = VFP.getPointer(); - // ParentVNI was either unmapped or already complex mapped. Either way. - if (!VNI) + // ParentVNI was either unmapped or already complex mapped. Either way, just + // set the force bit. + if (!VNI) { + VFP.setInt(true); return; + } // This was previously a single mapping. Make sure the old def is represented // by a trivial live range. SlotIndex Def = VNI->def; Edit->get(RegIdx)->addRange(LiveRange(Def, Def.getNextSlot(), VNI)); - VNI = 0; -} - -// extendRange - Extend the live range to reach Idx. -// Potentially create phi-def values. -void SplitEditor::extendRange(unsigned RegIdx, SlotIndex Idx) { - assert(Idx.isValid() && "Invalid SlotIndex"); - MachineBasicBlock *IdxMBB = LIS.getMBBFromIndex(Idx); - assert(IdxMBB && "No MBB at Idx"); - LiveInterval *LI = Edit->get(RegIdx); - - // Is there a def in the same MBB we can extend? - if (LI->extendInBlock(LIS.getMBBStartIdx(IdxMBB), Idx)) - return; - - // Now for the fun part. We know that ParentVNI potentially has multiple defs, - // and we may need to create even more phi-defs to preserve VNInfo SSA form. - // Perform a search for all predecessor blocks where we know the dominating - // VNInfo. - VNInfo *VNI = findReachingDefs(LI, IdxMBB, Idx.getNextSlot()); - - // When there were multiple different values, we may need new PHIs. - if (!VNI) - return updateSSA(); - - // Poor man's SSA update for the single-value case. - LiveOutPair LOP(VNI, MDT[LIS.getMBBFromIndex(VNI->def)]); - for (SmallVectorImpl::iterator I = LiveInBlocks.begin(), - E = LiveInBlocks.end(); I != E; ++I) { - MachineBasicBlock *MBB = I->DomNode->getBlock(); - SlotIndex Start = LIS.getMBBStartIdx(MBB); - if (I->Kill.isValid()) - LI->addRange(LiveRange(Start, I->Kill, VNI)); - else { - LiveOutCache[MBB] = LOP; - LI->addRange(LiveRange(Start, LIS.getMBBEndIdx(MBB), VNI)); - } - } -} - -/// findReachingDefs - Search the CFG for known live-out values. -/// Add required live-in blocks to LiveInBlocks. -VNInfo *SplitEditor::findReachingDefs(LiveInterval *LI, - MachineBasicBlock *KillMBB, - SlotIndex Kill) { - // Initialize the live-out cache the first time it is needed. - if (LiveOutSeen.empty()) { - unsigned N = VRM.getMachineFunction().getNumBlockIDs(); - LiveOutSeen.resize(N); - LiveOutCache.resize(N); - } - - // Blocks where LI should be live-in. - SmallVector WorkList(1, KillMBB); - - // Remember if we have seen more than one value. - bool UniqueVNI = true; - VNInfo *TheVNI = 0; - - // Using LiveOutCache as a visited set, perform a BFS for all reaching defs. - for (unsigned i = 0; i != WorkList.size(); ++i) { - MachineBasicBlock *MBB = WorkList[i]; - assert(!MBB->pred_empty() && "Value live-in to entry block?"); - for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), - PE = MBB->pred_end(); PI != PE; ++PI) { - MachineBasicBlock *Pred = *PI; - LiveOutPair &LOP = LiveOutCache[Pred]; - - // Is this a known live-out block? - if (LiveOutSeen.test(Pred->getNumber())) { - if (VNInfo *VNI = LOP.first) { - if (TheVNI && TheVNI != VNI) - UniqueVNI = false; - TheVNI = VNI; - } - continue; - } - - // First time. LOP is garbage and must be cleared below. - LiveOutSeen.set(Pred->getNumber()); - - // Does Pred provide a live-out value? - SlotIndex Start, Last; - tie(Start, Last) = LIS.getSlotIndexes()->getMBBRange(Pred); - Last = Last.getPrevSlot(); - VNInfo *VNI = LI->extendInBlock(Start, Last); - LOP.first = VNI; - if (VNI) { - LOP.second = MDT[LIS.getMBBFromIndex(VNI->def)]; - if (TheVNI && TheVNI != VNI) - UniqueVNI = false; - TheVNI = VNI; - continue; - } - LOP.second = 0; - - // No, we need a live-in value for Pred as well - if (Pred != KillMBB) - WorkList.push_back(Pred); - else - // Loopback to KillMBB, so value is really live through. - Kill = SlotIndex(); - } - } - - // Transfer WorkList to LiveInBlocks in reverse order. - // This ordering works best with updateSSA(). - LiveInBlocks.clear(); - LiveInBlocks.reserve(WorkList.size()); - while(!WorkList.empty()) - LiveInBlocks.push_back(MDT[WorkList.pop_back_val()]); - - // The kill block may not be live-through. - assert(LiveInBlocks.back().DomNode->getBlock() == KillMBB); - LiveInBlocks.back().Kill = Kill; - - return UniqueVNI ? TheVNI : 0; -} - -void SplitEditor::updateSSA() { - // This is essentially the same iterative algorithm that SSAUpdater uses, - // except we already have a dominator tree, so we don't have to recompute it. - unsigned Changes; - do { - Changes = 0; - // Propagate live-out values down the dominator tree, inserting phi-defs - // when necessary. - for (SmallVectorImpl::iterator I = LiveInBlocks.begin(), - E = LiveInBlocks.end(); I != E; ++I) { - MachineDomTreeNode *Node = I->DomNode; - // Skip block if the live-in value has already been determined. - if (!Node) - continue; - MachineBasicBlock *MBB = Node->getBlock(); - MachineDomTreeNode *IDom = Node->getIDom(); - LiveOutPair IDomValue; - - // We need a live-in value to a block with no immediate dominator? - // This is probably an unreachable block that has survived somehow. - bool needPHI = !IDom || !LiveOutSeen.test(IDom->getBlock()->getNumber()); - - // IDom dominates all of our predecessors, but it may not be their - // immediate dominator. Check if any of them have live-out values that are - // properly dominated by IDom. If so, we need a phi-def here. - if (!needPHI) { - IDomValue = LiveOutCache[IDom->getBlock()]; - for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), - PE = MBB->pred_end(); PI != PE; ++PI) { - LiveOutPair Value = LiveOutCache[*PI]; - if (!Value.first || Value.first == IDomValue.first) - continue; - // This predecessor is carrying something other than IDomValue. - // It could be because IDomValue hasn't propagated yet, or it could be - // because MBB is in the dominance frontier of that value. - if (MDT.dominates(IDom, Value.second)) { - needPHI = true; - break; - } - } - } - - // The value may be live-through even if Kill is set, as can happen when - // we are called from extendRange. In that case LiveOutSeen is true, and - // LiveOutCache indicates a foreign or missing value. - LiveOutPair &LOP = LiveOutCache[MBB]; - - // Create a phi-def if required. - if (needPHI) { - ++Changes; - SlotIndex Start = LIS.getMBBStartIdx(MBB); - unsigned RegIdx = RegAssign.lookup(Start); - LiveInterval *LI = Edit->get(RegIdx); - VNInfo *VNI = LI->getNextValue(Start, 0, LIS.getVNInfoAllocator()); - VNI->setIsPHIDef(true); - I->Value = VNI; - // This block is done, we know the final value. - I->DomNode = 0; - if (I->Kill.isValid()) - LI->addRange(LiveRange(Start, I->Kill, VNI)); - else { - LI->addRange(LiveRange(Start, LIS.getMBBEndIdx(MBB), VNI)); - LOP = LiveOutPair(VNI, Node); - } - } else if (IDomValue.first) { - // No phi-def here. Remember incoming value. - I->Value = IDomValue.first; - if (I->Kill.isValid()) - continue; - // Propagate IDomValue if needed: - // MBB is live-out and doesn't define its own value. - if (LOP.second != Node && LOP.first != IDomValue.first) { - ++Changes; - LOP = IDomValue; - } - } - } - } while (Changes); - - // The values in LiveInBlocks are now accurate. No more phi-defs are needed - // for these blocks, so we can color the live ranges. - for (SmallVectorImpl::iterator I = LiveInBlocks.begin(), - E = LiveInBlocks.end(); I != E; ++I) { - if (!I->DomNode) - continue; - assert(I->Value && "No live-in value found"); - MachineBasicBlock *MBB = I->DomNode->getBlock(); - SlotIndex Start = LIS.getMBBStartIdx(MBB); - unsigned RegIdx = RegAssign.lookup(Start); - LiveInterval *LI = Edit->get(RegIdx); - LI->addRange(LiveRange(Start, I->Kill.isValid() ? - I->Kill : LIS.getMBBEndIdx(MBB), I->Value)); - } + // Mark as complex mapped, forced. + VFP = ValueForcePair(0, true); } VNInfo *SplitEditor::defFromParent(unsigned RegIdx, @@ -710,17 +520,28 @@ SlotIndex SplitEditor::leaveIntvAfter(SlotIndex Idx) { DEBUG(dbgs() << " leaveIntvAfter " << Idx); // The interval must be live beyond the instruction at Idx. - Idx = Idx.getBoundaryIndex(); - VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Idx); + SlotIndex Boundary = Idx.getBoundaryIndex(); + VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Boundary); if (!ParentVNI) { DEBUG(dbgs() << ": not live\n"); - return Idx.getNextSlot(); + return Boundary.getNextSlot(); } DEBUG(dbgs() << ": valno " << ParentVNI->id << '\n'); - - MachineInstr *MI = LIS.getInstructionFromIndex(Idx); + MachineInstr *MI = LIS.getInstructionFromIndex(Boundary); assert(MI && "No instruction at index"); - VNInfo *VNI = defFromParent(0, ParentVNI, Idx, *MI->getParent(), + + // In spill mode, make live ranges as short as possible by inserting the copy + // before MI. This is only possible if that instruction doesn't redefine the + // value. The inserted COPY is not a kill, and we don't need to recompute + // the source live range. The spiller also won't try to hoist this copy. + if (SpillMode && !SlotIndex::isSameInstr(ParentVNI->def, Idx) && + MI->readsVirtualRegister(Edit->getReg())) { + forceRecompute(0, ParentVNI); + defFromParent(0, ParentVNI, Idx, *MI->getParent(), MI); + return Idx; + } + + VNInfo *VNI = defFromParent(0, ParentVNI, Boundary, *MI->getParent(), llvm::next(MachineBasicBlock::iterator(MI))); return VNI->def; } @@ -730,7 +551,7 @@ SlotIndex SplitEditor::leaveIntvBefore(SlotIndex Idx) { DEBUG(dbgs() << " leaveIntvBefore " << Idx); // The interval must be live into the instruction at Idx. - Idx = Idx.getBoundaryIndex(); + Idx = Idx.getBaseIndex(); VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(Idx); if (!ParentVNI) { DEBUG(dbgs() << ": not live\n"); @@ -770,19 +591,219 @@ void SplitEditor::overlapIntv(SlotIndex Start, SlotIndex End) { assert(LIS.getMBBFromIndex(Start) == LIS.getMBBFromIndex(End) && "Range cannot span basic blocks"); - // The complement interval will be extended as needed by extendRange(). + // The complement interval will be extended as needed by LRCalc.extend(). if (ParentVNI) - markComplexMapped(0, ParentVNI); + forceRecompute(0, ParentVNI); DEBUG(dbgs() << " overlapIntv [" << Start << ';' << End << "):"); RegAssign.insert(Start, End, OpenIdx); DEBUG(dump()); } +//===----------------------------------------------------------------------===// +// Spill modes +//===----------------------------------------------------------------------===// + +void SplitEditor::removeBackCopies(SmallVectorImpl &Copies) { + LiveInterval *LI = Edit->get(0); + DEBUG(dbgs() << "Removing " << Copies.size() << " back-copies.\n"); + RegAssignMap::iterator AssignI; + AssignI.setMap(RegAssign); + + for (unsigned i = 0, e = Copies.size(); i != e; ++i) { + VNInfo *VNI = Copies[i]; + SlotIndex Def = VNI->def; + MachineInstr *MI = LIS.getInstructionFromIndex(Def); + assert(MI && "No instruction for back-copy"); + + MachineBasicBlock *MBB = MI->getParent(); + MachineBasicBlock::iterator MBBI(MI); + bool AtBegin; + do AtBegin = MBBI == MBB->begin(); + while (!AtBegin && (--MBBI)->isDebugValue()); + + DEBUG(dbgs() << "Removing " << Def << '\t' << *MI); + LI->removeValNo(VNI); + LIS.RemoveMachineInstrFromMaps(MI); + MI->eraseFromParent(); + + // Adjust RegAssign if a register assignment is killed at VNI->def. We + // want to avoid calculating the live range of the source register if + // possible. + AssignI.find(VNI->def.getPrevSlot()); + if (!AssignI.valid() || AssignI.start() >= Def) + continue; + // If MI doesn't kill the assigned register, just leave it. + if (AssignI.stop() != Def) + continue; + unsigned RegIdx = AssignI.value(); + if (AtBegin || !MBBI->readsVirtualRegister(Edit->getReg())) { + DEBUG(dbgs() << " cannot find simple kill of RegIdx " << RegIdx << '\n'); + forceRecompute(RegIdx, Edit->getParent().getVNInfoAt(Def)); + } else { + SlotIndex Kill = LIS.getInstructionIndex(MBBI).getDefIndex(); + DEBUG(dbgs() << " move kill to " << Kill << '\t' << *MBBI); + AssignI.setStop(Kill); + } + } +} + +MachineBasicBlock* +SplitEditor::findShallowDominator(MachineBasicBlock *MBB, + MachineBasicBlock *DefMBB) { + if (MBB == DefMBB) + return MBB; + assert(MDT.dominates(DefMBB, MBB) && "MBB must be dominated by the def."); + + const MachineLoopInfo &Loops = SA.Loops; + const MachineLoop *DefLoop = Loops.getLoopFor(DefMBB); + MachineDomTreeNode *DefDomNode = MDT[DefMBB]; + + // Best candidate so far. + MachineBasicBlock *BestMBB = MBB; + unsigned BestDepth = UINT_MAX; + + for (;;) { + const MachineLoop *Loop = Loops.getLoopFor(MBB); + + // MBB isn't in a loop, it doesn't get any better. All dominators have a + // higher frequency by definition. + if (!Loop) { + DEBUG(dbgs() << "Def in BB#" << DefMBB->getNumber() << " dominates BB#" + << MBB->getNumber() << " at depth 0\n"); + return MBB; + } + + // We'll never be able to exit the DefLoop. + if (Loop == DefLoop) { + DEBUG(dbgs() << "Def in BB#" << DefMBB->getNumber() << " dominates BB#" + << MBB->getNumber() << " in the same loop\n"); + return MBB; + } + + // Least busy dominator seen so far. + unsigned Depth = Loop->getLoopDepth(); + if (Depth < BestDepth) { + BestMBB = MBB; + BestDepth = Depth; + DEBUG(dbgs() << "Def in BB#" << DefMBB->getNumber() << " dominates BB#" + << MBB->getNumber() << " at depth " << Depth << '\n'); + } + + // Leave loop by going to the immediate dominator of the loop header. + // This is a bigger stride than simply walking up the dominator tree. + MachineDomTreeNode *IDom = MDT[Loop->getHeader()]->getIDom(); + + // Too far up the dominator tree? + if (!IDom || !MDT.dominates(DefDomNode, IDom)) + return BestMBB; + + MBB = IDom->getBlock(); + } +} + +void SplitEditor::hoistCopiesForSize() { + // Get the complement interval, always RegIdx 0. + LiveInterval *LI = Edit->get(0); + LiveInterval *Parent = &Edit->getParent(); + + // Track the nearest common dominator for all back-copies for each ParentVNI, + // indexed by ParentVNI->id. + typedef std::pair DomPair; + SmallVector NearestDom(Parent->getNumValNums()); + + // Find the nearest common dominator for parent values with multiple + // back-copies. If a single back-copy dominates, put it in DomPair.second. + for (LiveInterval::vni_iterator VI = LI->vni_begin(), VE = LI->vni_end(); + VI != VE; ++VI) { + VNInfo *VNI = *VI; + VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(VNI->def); + assert(ParentVNI && "Parent not live at complement def"); + + // Don't hoist remats. The complement is probably going to disappear + // completely anyway. + if (Edit->didRematerialize(ParentVNI)) + continue; + + MachineBasicBlock *ValMBB = LIS.getMBBFromIndex(VNI->def); + DomPair &Dom = NearestDom[ParentVNI->id]; + + // Keep directly defined parent values. This is either a PHI or an + // instruction in the complement range. All other copies of ParentVNI + // should be eliminated. + if (VNI->def == ParentVNI->def) { + DEBUG(dbgs() << "Direct complement def at " << VNI->def << '\n'); + Dom = DomPair(ValMBB, VNI->def); + continue; + } + // Skip the singly mapped values. There is nothing to gain from hoisting a + // single back-copy. + if (Values.lookup(std::make_pair(0, ParentVNI->id)).getPointer()) { + DEBUG(dbgs() << "Single complement def at " << VNI->def << '\n'); + continue; + } + + if (!Dom.first) { + // First time we see ParentVNI. VNI dominates itself. + Dom = DomPair(ValMBB, VNI->def); + } else if (Dom.first == ValMBB) { + // Two defs in the same block. Pick the earlier def. + if (!Dom.second.isValid() || VNI->def < Dom.second) + Dom.second = VNI->def; + } else { + // Different basic blocks. Check if one dominates. + MachineBasicBlock *Near = + MDT.findNearestCommonDominator(Dom.first, ValMBB); + if (Near == ValMBB) + // Def ValMBB dominates. + Dom = DomPair(ValMBB, VNI->def); + else if (Near != Dom.first) + // None dominate. Hoist to common dominator, need new def. + Dom = DomPair(Near, SlotIndex()); + } + + DEBUG(dbgs() << "Multi-mapped complement " << VNI->id << '@' << VNI->def + << " for parent " << ParentVNI->id << '@' << ParentVNI->def + << " hoist to BB#" << Dom.first->getNumber() << ' ' + << Dom.second << '\n'); + } + + // Insert the hoisted copies. + for (unsigned i = 0, e = Parent->getNumValNums(); i != e; ++i) { + DomPair &Dom = NearestDom[i]; + if (!Dom.first || Dom.second.isValid()) + continue; + // This value needs a hoisted copy inserted at the end of Dom.first. + VNInfo *ParentVNI = Parent->getValNumInfo(i); + MachineBasicBlock *DefMBB = LIS.getMBBFromIndex(ParentVNI->def); + // Get a less loopy dominator than Dom.first. + Dom.first = findShallowDominator(Dom.first, DefMBB); + SlotIndex Last = LIS.getMBBEndIdx(Dom.first).getPrevSlot(); + Dom.second = + defFromParent(0, ParentVNI, Last, *Dom.first, + LIS.getLastSplitPoint(Edit->getParent(), Dom.first))->def; + } + + // Remove redundant back-copies that are now known to be dominated by another + // def with the same value. + SmallVector BackCopies; + for (LiveInterval::vni_iterator VI = LI->vni_begin(), VE = LI->vni_end(); + VI != VE; ++VI) { + VNInfo *VNI = *VI; + VNInfo *ParentVNI = Edit->getParent().getVNInfoAt(VNI->def); + const DomPair &Dom = NearestDom[ParentVNI->id]; + if (!Dom.first || Dom.second == VNI->def) + continue; + BackCopies.push_back(VNI); + forceRecompute(0, ParentVNI); + } + removeBackCopies(BackCopies); +} + + /// transferValues - Transfer all possible values to the new live ranges. -/// Values that were rematerialized are left alone, they need extendRange(). +/// Values that were rematerialized are left alone, they need LRCalc.extend(). bool SplitEditor::transferValues() { bool Skipped = false; - LiveInBlocks.clear(); RegAssignMap::const_iterator AssignI = RegAssign.begin(); for (LiveInterval::const_iterator ParentI = Edit->getParent().begin(), ParentE = Edit->getParent().end(); ParentI != ParentE; ++ParentI) { @@ -812,28 +833,23 @@ bool SplitEditor::transferValues() { LiveInterval *LI = Edit->get(RegIdx); // Check for a simply defined value that can be blitted directly. - if (VNInfo *VNI = Values.lookup(std::make_pair(RegIdx, ParentVNI->id))) { + ValueForcePair VFP = Values.lookup(std::make_pair(RegIdx, ParentVNI->id)); + if (VNInfo *VNI = VFP.getPointer()) { DEBUG(dbgs() << ':' << VNI->id); LI->addRange(LiveRange(Start, End, VNI)); Start = End; continue; } - // Skip rematerialized values, we need to use extendRange() and - // extendPHIKillRanges() to completely recompute the live ranges. - if (Edit->didRematerialize(ParentVNI)) { - DEBUG(dbgs() << "(remat)"); + // Skip values with forced recomputation. + if (VFP.getInt()) { + DEBUG(dbgs() << "(recalc)"); Skipped = true; Start = End; continue; } - // Initialize the live-out cache the first time it is needed. - if (LiveOutSeen.empty()) { - unsigned N = VRM.getMachineFunction().getNumBlockIDs(); - LiveOutSeen.resize(N); - LiveOutCache.resize(N); - } + LiveRangeCalc &LRC = getLRCalc(RegIdx); // This value has multiple defs in RegIdx, but it wasn't rematerialized, // so the live range is accurate. Add live-in blocks in [Start;End) to the @@ -844,15 +860,13 @@ bool SplitEditor::transferValues() { // The first block may be live-in, or it may have its own def. if (Start != BlockStart) { - VNInfo *VNI = LI->extendInBlock(BlockStart, - std::min(BlockEnd, End).getPrevSlot()); + VNInfo *VNI = LI->extendInBlock(BlockStart, std::min(BlockEnd, End)); assert(VNI && "Missing def for complex mapped value"); DEBUG(dbgs() << ':' << VNI->id << "*BB#" << MBB->getNumber()); // MBB has its own def. Is it also live-out? - if (BlockEnd <= End) { - LiveOutSeen.set(MBB->getNumber()); - LiveOutCache[MBB] = LiveOutPair(VNI, MDT[MBB]); - } + if (BlockEnd <= End) + LRC.setLiveOutValue(MBB, VNI); + // Skip to the next block for live-in. ++MBB; BlockStart = BlockEnd; @@ -866,25 +880,19 @@ bool SplitEditor::transferValues() { if (BlockStart == ParentVNI->def) { // This block has the def of a parent PHI, so it isn't live-in. assert(ParentVNI->isPHIDef() && "Non-phi defined at block start?"); - VNInfo *VNI = LI->extendInBlock(BlockStart, - std::min(BlockEnd, End).getPrevSlot()); + VNInfo *VNI = LI->extendInBlock(BlockStart, std::min(BlockEnd, End)); assert(VNI && "Missing def for complex mapped parent PHI"); - if (End >= BlockEnd) { - // Live-out as well. - LiveOutSeen.set(MBB->getNumber()); - LiveOutCache[MBB] = LiveOutPair(VNI, MDT[MBB]); - } + if (End >= BlockEnd) + LRC.setLiveOutValue(MBB, VNI); // Live-out as well. } else { - // This block needs a live-in value. - LiveInBlocks.push_back(MDT[MBB]); - // The last block covered may not be live-out. + // This block needs a live-in value. The last block covered may not + // be live-out. if (End < BlockEnd) - LiveInBlocks.back().Kill = End; + LRC.addLiveInBlock(LI, MDT[MBB], End); else { - // Live-out, but we need updateSSA to tell us the value. - LiveOutSeen.set(MBB->getNumber()); - LiveOutCache[MBB] = LiveOutPair((VNInfo*)0, - (MachineDomTreeNode*)0); + // Live-through, and we don't know the value. + LRC.addLiveInBlock(LI, MDT[MBB]); + LRC.setLiveOutValue(MBB, 0); } } BlockStart = BlockEnd; @@ -895,8 +903,11 @@ bool SplitEditor::transferValues() { DEBUG(dbgs() << '\n'); } - if (!LiveInBlocks.empty()) - updateSSA(); + LRCalc[0].calculateValues(LIS.getSlotIndexes(), &MDT, + &LIS.getVNInfoAllocator()); + if (SpillMode) + LRCalc[1].calculateValues(LIS.getSlotIndexes(), &MDT, + &LIS.getVNInfoAllocator()); return Skipped; } @@ -909,16 +920,20 @@ void SplitEditor::extendPHIKillRanges() { if (PHIVNI->isUnused() || !PHIVNI->isPHIDef()) continue; unsigned RegIdx = RegAssign.lookup(PHIVNI->def); + LiveInterval *LI = Edit->get(RegIdx); + LiveRangeCalc &LRC = getLRCalc(RegIdx); MachineBasicBlock *MBB = LIS.getMBBFromIndex(PHIVNI->def); for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), PE = MBB->pred_end(); PI != PE; ++PI) { - SlotIndex End = LIS.getMBBEndIdx(*PI).getPrevSlot(); + SlotIndex End = LIS.getMBBEndIdx(*PI); + SlotIndex LastUse = End.getPrevSlot(); // The predecessor may not have a live-out value. That is OK, like an // undef PHI operand. - if (Edit->getParent().liveAt(End)) { - assert(RegAssign.lookup(End) == RegIdx && + if (Edit->getParent().liveAt(LastUse)) { + assert(RegAssign.lookup(LastUse) == RegIdx && "Different register assignment in phi predecessor"); - extendRange(RegIdx, End); + LRC.extend(LI, End, + LIS.getSlotIndexes(), &MDT, &LIS.getVNInfoAllocator()); } } } @@ -938,25 +953,22 @@ void SplitEditor::rewriteAssigned(bool ExtendRanges) { continue; } - // operands don't really read the register, so just assign them to - // the complement. - if (MO.isUse() && MO.isUndef()) { - MO.setReg(Edit->get(0)->reg); - continue; - } - + // operands don't really read the register, so it doesn't matter + // which register we choose. When the use operand is tied to a def, we must + // use the same register as the def, so just do that always. SlotIndex Idx = LIS.getInstructionIndex(MI); - if (MO.isDef()) + if (MO.isDef() || MO.isUndef()) Idx = MO.isEarlyClobber() ? Idx.getUseIndex() : Idx.getDefIndex(); // Rewrite to the mapped register at Idx. unsigned RegIdx = RegAssign.lookup(Idx); - MO.setReg(Edit->get(RegIdx)->reg); + LiveInterval *LI = Edit->get(RegIdx); + MO.setReg(LI->reg); DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t' << Idx << ':' << RegIdx << '\t' << *MI); // Extend liveness to Idx if the instruction reads reg. - if (!ExtendRanges) + if (!ExtendRanges || MO.isUndef()) continue; // Skip instructions that don't read Reg. @@ -971,7 +983,8 @@ void SplitEditor::rewriteAssigned(bool ExtendRanges) { } else Idx = Idx.getUseIndex(); - extendRange(RegIdx, Idx); + getLRCalc(RegIdx).extend(LI, Idx.getNextSlot(), LIS.getSlotIndexes(), + &MDT, &LIS.getVNInfoAllocator()); } } @@ -1019,11 +1032,24 @@ void SplitEditor::finish(SmallVectorImpl *LRMap) { VNI->setIsPHIDef(ParentVNI->isPHIDef()); VNI->setCopy(ParentVNI->getCopy()); - // Mark rematted values as complex everywhere to force liveness computation. + // Force rematted values to be recomputed everywhere. // The new live ranges may be truncated. if (Edit->didRematerialize(ParentVNI)) for (unsigned i = 0, e = Edit->size(); i != e; ++i) - markComplexMapped(i, ParentVNI); + forceRecompute(i, ParentVNI); + } + + // Hoist back-copies to the complement interval when in spill mode. + switch (SpillMode) { + case SM_Partition: + // Leave all back-copies as is. + break; + case SM_Size: + hoistCopiesForSize(); + break; + case SM_Speed: + llvm_unreachable("Spill mode 'speed' not implemented yet"); + break; } // Transfer the simply mapped values, check if any are skipped. @@ -1081,50 +1107,39 @@ void SplitEditor::finish(SmallVectorImpl *LRMap) { // Single Block Splitting //===----------------------------------------------------------------------===// -/// getMultiUseBlocks - if CurLI has more than one use in a basic block, it -/// may be an advantage to split CurLI for the duration of the block. -bool SplitAnalysis::getMultiUseBlocks(BlockPtrSet &Blocks) { - // If CurLI is local to one block, there is no point to splitting it. - if (UseBlocks.size() <= 1) +bool SplitAnalysis::shouldSplitSingleBlock(const BlockInfo &BI, + bool SingleInstrs) const { + // Always split for multiple instructions. + if (!BI.isOneInstr()) + return true; + // Don't split for single instructions unless explicitly requested. + if (!SingleInstrs) return false; - // Add blocks with multiple uses. - for (unsigned i = 0, e = UseBlocks.size(); i != e; ++i) { - const BlockInfo &BI = UseBlocks[i]; - if (BI.FirstUse == BI.LastUse) - continue; - Blocks.insert(BI.MBB); - } - return !Blocks.empty(); + // Splitting a live-through range always makes progress. + if (BI.LiveIn && BI.LiveOut) + return true; + // No point in isolating a copy. It has no register class constraints. + if (LIS.getInstructionFromIndex(BI.FirstInstr)->isCopyLike()) + return false; + // Finally, don't isolate an end point that was created by earlier splits. + return isOriginalEndpoint(BI.FirstInstr); } void SplitEditor::splitSingleBlock(const SplitAnalysis::BlockInfo &BI) { openIntv(); SlotIndex LastSplitPoint = SA.getLastSplitPoint(BI.MBB->getNumber()); - SlotIndex SegStart = enterIntvBefore(std::min(BI.FirstUse, + SlotIndex SegStart = enterIntvBefore(std::min(BI.FirstInstr, LastSplitPoint)); - if (!BI.LiveOut || BI.LastUse < LastSplitPoint) { - useIntv(SegStart, leaveIntvAfter(BI.LastUse)); + if (!BI.LiveOut || BI.LastInstr < LastSplitPoint) { + useIntv(SegStart, leaveIntvAfter(BI.LastInstr)); } else { // The last use is after the last valid split point. SlotIndex SegStop = leaveIntvBefore(LastSplitPoint); useIntv(SegStart, SegStop); - overlapIntv(SegStop, BI.LastUse); + overlapIntv(SegStop, BI.LastInstr); } } -/// splitSingleBlocks - Split CurLI into a separate live interval inside each -/// basic block in Blocks. -void SplitEditor::splitSingleBlocks(const SplitAnalysis::BlockPtrSet &Blocks) { - DEBUG(dbgs() << " splitSingleBlocks for " << Blocks.size() << " blocks.\n"); - ArrayRef UseBlocks = SA.getUseBlocks(); - for (unsigned i = 0; i != UseBlocks.size(); ++i) { - const SplitAnalysis::BlockInfo &BI = UseBlocks[i]; - if (Blocks.count(BI.MBB)) - splitSingleBlock(BI); - } - finish(); -} - //===----------------------------------------------------------------------===// // Global Live Range Splitting Support @@ -1149,6 +1164,12 @@ void SplitEditor::splitLiveThroughBlock(unsigned MBBNum, assert((IntvIn || IntvOut) && "Use splitSingleBlock for isolated blocks"); + assert((!LeaveBefore || LeaveBefore < Stop) && "Interference after block"); + assert((!IntvIn || !LeaveBefore || LeaveBefore > Start) && "Impossible intf"); + assert((!EnterAfter || EnterAfter >= Start) && "Interference before block"); + + MachineBasicBlock *MBB = VRM.getMachineFunction().getBlockNumbered(MBBNum); + if (!IntvOut) { DEBUG(dbgs() << ", spill on entry.\n"); // @@ -1157,7 +1178,6 @@ void SplitEditor::splitLiveThroughBlock(unsigned MBBNum, // -____________ Spill on entry. // selectIntv(IntvIn); - MachineBasicBlock *MBB = VRM.getMachineFunction().getBlockNumbered(MBBNum); SlotIndex Idx = leaveIntvAtTop(*MBB); assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference"); (void)Idx; @@ -1172,7 +1192,6 @@ void SplitEditor::splitLiveThroughBlock(unsigned MBBNum, // ___________-- Reload on exit. // selectIntv(IntvOut); - MachineBasicBlock *MBB = VRM.getMachineFunction().getBlockNumbered(MBBNum); SlotIndex Idx = enterIntvAtEnd(*MBB); assert((!EnterAfter || Idx >= EnterAfter) && "Interference"); (void)Idx; @@ -1192,6 +1211,7 @@ void SplitEditor::splitLiveThroughBlock(unsigned MBBNum, // We cannot legally insert splits after LSP. SlotIndex LSP = SA.getLastSplitPoint(MBBNum); + assert((!IntvOut || !EnterAfter || EnterAfter < LSP) && "Impossible intf"); if (IntvIn != IntvOut && (!LeaveBefore || !EnterAfter || LeaveBefore.getBaseIndex() > EnterAfter.getBoundaryIndex())) { @@ -1201,10 +1221,14 @@ void SplitEditor::splitLiveThroughBlock(unsigned MBBNum, // |-----------| Live through. // ------======= Switch intervals between interference. // - SlotIndex Cut = (LeaveBefore && LeaveBefore < LSP) ? LeaveBefore : LSP; selectIntv(IntvOut); - SlotIndex Idx = enterIntvBefore(Cut); - useIntv(Idx, Stop); + SlotIndex Idx; + if (LeaveBefore && LeaveBefore < LSP) { + Idx = enterIntvBefore(LeaveBefore); + useIntv(Idx, Stop); + } else { + Idx = enterIntvAtEnd(*MBB); + } selectIntv(IntvIn); useIntv(Start, Idx); assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference"); @@ -1238,7 +1262,7 @@ void SplitEditor::splitRegInBlock(const SplitAnalysis::BlockInfo &BI, tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(BI.MBB); DEBUG(dbgs() << "BB#" << BI.MBB->getNumber() << " [" << Start << ';' << Stop - << "), uses " << BI.FirstUse << '-' << BI.LastUse + << "), uses " << BI.FirstInstr << '-' << BI.LastInstr << ", reg-in " << IntvIn << ", leave before " << LeaveBefore << (BI.LiveOut ? ", stack-out" : ", killed in block")); @@ -1246,7 +1270,7 @@ void SplitEditor::splitRegInBlock(const SplitAnalysis::BlockInfo &BI, assert(BI.LiveIn && "Must be live-in"); assert((!LeaveBefore || LeaveBefore > Start) && "Bad interference"); - if (!BI.LiveOut && (!LeaveBefore || LeaveBefore >= BI.LastUse)) { + if (!BI.LiveOut && (!LeaveBefore || LeaveBefore >= BI.LastInstr)) { DEBUG(dbgs() << " before interference.\n"); // // <<< Interference after kill. @@ -1254,13 +1278,13 @@ void SplitEditor::splitRegInBlock(const SplitAnalysis::BlockInfo &BI, // ========= Use IntvIn everywhere. // selectIntv(IntvIn); - useIntv(Start, BI.LastUse); + useIntv(Start, BI.LastInstr); return; } SlotIndex LSP = SA.getLastSplitPoint(BI.MBB->getNumber()); - if (!LeaveBefore || LeaveBefore > BI.LastUse.getBoundaryIndex()) { + if (!LeaveBefore || LeaveBefore > BI.LastInstr.getBoundaryIndex()) { // // <<< Possible interference after last use. // |---o---o---| Live-out on stack. @@ -1271,17 +1295,17 @@ void SplitEditor::splitRegInBlock(const SplitAnalysis::BlockInfo &BI, // ============ Copy to stack after LSP, overlap IntvIn. // \_____ Stack interval is live-out. // - if (BI.LastUse < LSP) { + if (BI.LastInstr < LSP) { DEBUG(dbgs() << ", spill after last use before interference.\n"); selectIntv(IntvIn); - SlotIndex Idx = leaveIntvAfter(BI.LastUse); + SlotIndex Idx = leaveIntvAfter(BI.LastInstr); useIntv(Start, Idx); assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference"); } else { DEBUG(dbgs() << ", spill before last split point.\n"); selectIntv(IntvIn); SlotIndex Idx = leaveIntvBefore(LSP); - overlapIntv(Idx, BI.LastUse); + overlapIntv(Idx, BI.LastInstr); useIntv(Start, Idx); assert((!LeaveBefore || Idx <= LeaveBefore) && "Interference"); } @@ -1295,13 +1319,13 @@ void SplitEditor::splitRegInBlock(const SplitAnalysis::BlockInfo &BI, (void)LocalIntv; DEBUG(dbgs() << ", creating local interval " << LocalIntv << ".\n"); - if (!BI.LiveOut || BI.LastUse < LSP) { + if (!BI.LiveOut || BI.LastInstr < LSP) { // // <<<<<<< Interference overlapping uses. // |---o---o---| Live-out on stack. // =====----____ Leave IntvIn before interference, then spill. // - SlotIndex To = leaveIntvAfter(BI.LastUse); + SlotIndex To = leaveIntvAfter(BI.LastInstr); SlotIndex From = enterIntvBefore(LeaveBefore); useIntv(From, To); selectIntv(IntvIn); @@ -1316,7 +1340,7 @@ void SplitEditor::splitRegInBlock(const SplitAnalysis::BlockInfo &BI, // \_____ Stack interval is live-out. // SlotIndex To = leaveIntvBefore(LSP); - overlapIntv(To, BI.LastUse); + overlapIntv(To, BI.LastInstr); SlotIndex From = enterIntvBefore(std::min(To, LeaveBefore)); useIntv(From, To); selectIntv(IntvIn); @@ -1330,7 +1354,7 @@ void SplitEditor::splitRegOutBlock(const SplitAnalysis::BlockInfo &BI, tie(Start, Stop) = LIS.getSlotIndexes()->getMBBRange(BI.MBB); DEBUG(dbgs() << "BB#" << BI.MBB->getNumber() << " [" << Start << ';' << Stop - << "), uses " << BI.FirstUse << '-' << BI.LastUse + << "), uses " << BI.FirstInstr << '-' << BI.LastInstr << ", reg-out " << IntvOut << ", enter after " << EnterAfter << (BI.LiveIn ? ", stack-in" : ", defined in block")); @@ -1340,7 +1364,7 @@ void SplitEditor::splitRegOutBlock(const SplitAnalysis::BlockInfo &BI, assert(BI.LiveOut && "Must be live-out"); assert((!EnterAfter || EnterAfter < LSP) && "Bad interference"); - if (!BI.LiveIn && (!EnterAfter || EnterAfter <= BI.FirstUse)) { + if (!BI.LiveIn && (!EnterAfter || EnterAfter <= BI.FirstInstr)) { DEBUG(dbgs() << " after interference.\n"); // // >>>> Interference before def. @@ -1348,11 +1372,11 @@ void SplitEditor::splitRegOutBlock(const SplitAnalysis::BlockInfo &BI, // ========= Use IntvOut everywhere. // selectIntv(IntvOut); - useIntv(BI.FirstUse, Stop); + useIntv(BI.FirstInstr, Stop); return; } - if (!EnterAfter || EnterAfter < BI.FirstUse.getBaseIndex()) { + if (!EnterAfter || EnterAfter < BI.FirstInstr.getBaseIndex()) { DEBUG(dbgs() << ", reload after interference.\n"); // // >>>> Interference before def. @@ -1360,7 +1384,7 @@ void SplitEditor::splitRegOutBlock(const SplitAnalysis::BlockInfo &BI, // ____========= Enter IntvOut before first use. // selectIntv(IntvOut); - SlotIndex Idx = enterIntvBefore(std::min(LSP, BI.FirstUse)); + SlotIndex Idx = enterIntvBefore(std::min(LSP, BI.FirstInstr)); useIntv(Idx, Stop); assert((!EnterAfter || Idx >= EnterAfter) && "Interference"); return; @@ -1381,6 +1405,6 @@ void SplitEditor::splitRegOutBlock(const SplitAnalysis::BlockInfo &BI, assert((!EnterAfter || Idx >= EnterAfter) && "Interference"); openIntv(); - SlotIndex From = enterIntvBefore(std::min(Idx, BI.FirstUse)); + SlotIndex From = enterIntvBefore(std::min(Idx, BI.FirstInstr)); useIntv(From, Idx); } diff --git a/lib/CodeGen/SplitKit.h b/lib/CodeGen/SplitKit.h index 7948b725f856..d8fc2122a3c7 100644 --- a/lib/CodeGen/SplitKit.h +++ b/lib/CodeGen/SplitKit.h @@ -15,13 +15,11 @@ #ifndef LLVM_CODEGEN_SPLITKIT_H #define LLVM_CODEGEN_SPLITKIT_H +#include "LiveRangeCalc.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/CodeGen/SlotIndexes.h" namespace llvm { @@ -38,12 +36,6 @@ class VirtRegMap; class VNInfo; class raw_ostream; -/// At some point we should just include MachineDominators.h: -class MachineDominatorTree; -template class DomTreeNodeBase; -typedef DomTreeNodeBase MachineDomTreeNode; - - /// SplitAnalysis - Analyze a LiveInterval, looking for live range splitting /// opportunities. class SplitAnalysis { @@ -76,16 +68,16 @@ class SplitAnalysis { /// struct BlockInfo { MachineBasicBlock *MBB; - SlotIndex FirstUse; ///< First instr using current reg. - SlotIndex LastUse; ///< Last instr using current reg. - bool LiveThrough; ///< Live in whole block (Templ 5. above). + SlotIndex FirstInstr; ///< First instr accessing current reg. + SlotIndex LastInstr; ///< Last instr accessing current reg. + SlotIndex FirstDef; ///< First non-phi valno->def, or SlotIndex(). bool LiveIn; ///< Current reg is live in. bool LiveOut; ///< Current reg is live out. /// isOneInstr - Returns true when this BlockInfo describes a single /// instruction. bool isOneInstr() const { - return SlotIndex::isSameInstr(FirstUse, LastUse); + return SlotIndex::isSameInstr(FirstInstr, LastInstr); } }; @@ -185,10 +177,15 @@ class SplitAnalysis { typedef SmallPtrSet BlockPtrSet; - /// getMultiUseBlocks - Add basic blocks to Blocks that may benefit from - /// having CurLI split to a new live interval. Return true if Blocks can be - /// passed to SplitEditor::splitSingleBlocks. - bool getMultiUseBlocks(BlockPtrSet &Blocks); + /// shouldSplitSingleBlock - Returns true if it would help to create a local + /// live range for the instructions in BI. There is normally no benefit to + /// creating a live range for a single instruction, but it does enable + /// register class inflation if the instruction has a restricted register + /// class. + /// + /// @param BI The block to be isolated. + /// @param SingleInstrs True when single instructions should be isolated. + bool shouldSplitSingleBlock(const BlockInfo &BI, bool SingleInstrs) const; }; @@ -212,6 +209,36 @@ class SplitEditor { const TargetInstrInfo &TII; const TargetRegisterInfo &TRI; +public: + + /// ComplementSpillMode - Select how the complement live range should be + /// created. SplitEditor automatically creates interval 0 to contain + /// anything that isn't added to another interval. This complement interval + /// can get quite complicated, and it can sometimes be an advantage to allow + /// it to overlap the other intervals. If it is going to spill anyway, no + /// registers are wasted by keeping a value in two places at the same time. + enum ComplementSpillMode { + /// SM_Partition(Default) - Try to create the complement interval so it + /// doesn't overlap any other intervals, and the original interval is + /// partitioned. This may require a large number of back copies and extra + /// PHI-defs. Only segments marked with overlapIntv will be overlapping. + SM_Partition, + + /// SM_Size - Overlap intervals to minimize the number of inserted COPY + /// instructions. Copies to the complement interval are hoisted to their + /// common dominator, so only one COPY is required per value in the + /// complement interval. This also means that no extra PHI-defs need to be + /// inserted in the complement interval. + SM_Size, + + /// SM_Speed - Overlap intervals to minimize the expected execution + /// frequency of the inserted copies. This is very similar to SM_Size, but + /// the complement interval may get some extra PHI-defs. + SM_Speed + }; + +private: + /// Edit - The current parent register and new intervals created. LiveRangeEdit *Edit; @@ -220,6 +247,9 @@ class SplitEditor { /// openIntv will be 1. unsigned OpenIdx; + /// The current spill mode, selected by reset(). + ComplementSpillMode SpillMode; + typedef IntervalMap RegAssignMap; /// Allocator for the interval map. This will eventually be shared with @@ -231,65 +261,34 @@ class SplitEditor { /// Idx. RegAssignMap RegAssign; - typedef DenseMap, VNInfo*> ValueMap; + typedef PointerIntPair ValueForcePair; + typedef DenseMap, ValueForcePair> ValueMap; /// Values - keep track of the mapping from parent values to values in the new /// intervals. Given a pair (RegIdx, ParentVNI->id), Values contains: /// /// 1. No entry - the value is not mapped to Edit.get(RegIdx). - /// 2. Null - the value is mapped to multiple values in Edit.get(RegIdx). - /// Each value is represented by a minimal live range at its def. - /// 3. A non-null VNInfo - the value is mapped to a single new value. + /// 2. (Null, false) - the value is mapped to multiple values in + /// Edit.get(RegIdx). Each value is represented by a minimal live range at + /// its def. The full live range can be inferred exactly from the range + /// of RegIdx in RegAssign. + /// 3. (Null, true). As above, but the ranges in RegAssign are too large, and + /// the live range must be recomputed using LiveRangeCalc::extend(). + /// 4. (VNI, false) The value is mapped to a single new value. /// The new value has no live ranges anywhere. ValueMap Values; - typedef std::pair LiveOutPair; - typedef IndexedMap LiveOutMap; + /// LRCalc - Cache for computing live ranges and SSA update. Each instance + /// can only handle non-overlapping live ranges, so use a separate + /// LiveRangeCalc instance for the complement interval when in spill mode. + LiveRangeCalc LRCalc[2]; - // LiveOutCache - Map each basic block where a new register is live out to the - // live-out value and its defining block. - // One of these conditions shall be true: - // - // 1. !LiveOutCache.count(MBB) - // 2. LiveOutCache[MBB].second.getNode() == MBB - // 3. forall P in preds(MBB): LiveOutCache[P] == LiveOutCache[MBB] - // - // This is only a cache, the values can be computed as: - // - // VNI = Edit.get(RegIdx)->getVNInfoAt(LIS.getMBBEndIdx(MBB)) - // Node = mbt_[LIS.getMBBFromIndex(VNI->def)] - // - // The cache is also used as a visited set by extendRange(). It can be shared - // by all the new registers because at most one is live out of each block. - LiveOutMap LiveOutCache; - - // LiveOutSeen - Indexed by MBB->getNumber(), a bit is set for each valid - // entry in LiveOutCache. - BitVector LiveOutSeen; - - /// LiveInBlock - Info for updateSSA() about a block where a register is - /// live-in. - /// The updateSSA caller provides DomNode and Kill inside MBB, updateSSA() - /// adds the computed live-in value. - struct LiveInBlock { - // Dominator tree node for the block. - // Cleared by updateSSA when the final value has been determined. - MachineDomTreeNode *DomNode; - - // Live-in value filled in by updateSSA once it is known. - VNInfo *Value; - - // Position in block where the live-in range ends, or SlotIndex() if the - // range passes through the block. - SlotIndex Kill; - - LiveInBlock(MachineDomTreeNode *node) : DomNode(node), Value(0) {} - }; - - /// LiveInBlocks - List of live-in blocks used by findReachingDefs() and - /// updateSSA(). This list is usually empty, it exists here to avoid frequent - /// reallocations. - SmallVector LiveInBlocks; + /// getLRCalc - Return the LRCalc to use for RegIdx. In spill mode, the + /// complement interval can overlap the other intervals, so it gets its own + /// LRCalc instance. When not in spill mode, all intervals can share one. + LiveRangeCalc &getLRCalc(unsigned RegIdx) { + return LRCalc[SpillMode != SM_Partition && RegIdx != 0]; + } /// defValue - define a value in RegIdx from ParentVNI at Idx. /// Idx does not have to be ParentVNI->def, but it must be contained within @@ -298,9 +297,11 @@ class SplitEditor { /// Return the new LI value. VNInfo *defValue(unsigned RegIdx, const VNInfo *ParentVNI, SlotIndex Idx); - /// markComplexMapped - Mark ParentVNI as complex mapped in RegIdx regardless - /// of the number of defs. - void markComplexMapped(unsigned RegIdx, const VNInfo *ParentVNI); + /// forceRecompute - Force the live range of ParentVNI in RegIdx to be + /// recomputed by LiveRangeCalc::extend regardless of the number of defs. + /// This is used for values whose live range doesn't match RegAssign exactly. + /// They could have rematerialized, or back-copies may have been moved. + void forceRecompute(unsigned RegIdx, const VNInfo *ParentVNI); /// defFromParent - Define Reg from ParentVNI at UseIdx using either /// rematerialization or a COPY from parent. Return the new value. @@ -310,22 +311,18 @@ class SplitEditor { MachineBasicBlock &MBB, MachineBasicBlock::iterator I); - /// extendRange - Extend the live range of Edit.get(RegIdx) so it reaches Idx. - /// Insert PHIDefs as needed to preserve SSA form. - void extendRange(unsigned RegIdx, SlotIndex Idx); + /// removeBackCopies - Remove the copy instructions that defines the values + /// in the vector in the complement interval. + void removeBackCopies(SmallVectorImpl &Copies); - /// findReachingDefs - Starting from MBB, add blocks to LiveInBlocks until all - /// reaching defs for LI are found. - /// @param LI Live interval whose value is needed. - /// @param MBB Block where LI should be live-in. - /// @param Kill Kill point in MBB. - /// @return Unique value seen, or NULL. - VNInfo *findReachingDefs(LiveInterval *LI, MachineBasicBlock *MBB, - SlotIndex Kill); + /// getShallowDominator - Returns the least busy dominator of MBB that is + /// also dominated by DefMBB. Busy is measured by loop depth. + MachineBasicBlock *findShallowDominator(MachineBasicBlock *MBB, + MachineBasicBlock *DefMBB); - /// updateSSA - Compute and insert PHIDefs such that all blocks in - // LiveInBlocks get a known live-in value. Add live ranges to the blocks. - void updateSSA(); + /// hoistCopiesForSize - Hoist back-copies to the complement interval in a + /// way that minimizes code size. This implements the SM_Size spill mode. + void hoistCopiesForSize(); /// transferValues - Transfer values to the new ranges. /// Return true if any ranges were skipped. @@ -348,7 +345,7 @@ class SplitEditor { MachineDominatorTree&); /// reset - Prepare for a new split. - void reset(LiveRangeEdit&); + void reset(LiveRangeEdit&, ComplementSpillMode = SM_Partition); /// Create a new virtual register and live interval. /// Return the interval index, starting from 1. Interval index 0 is the @@ -423,10 +420,6 @@ class SplitEditor { /// split, and doesn't call finish(). void splitSingleBlock(const SplitAnalysis::BlockInfo &BI); - /// splitSingleBlocks - Split CurLI into a separate live interval inside each - /// basic block in Blocks. - void splitSingleBlocks(const SplitAnalysis::BlockPtrSet &Blocks); - /// splitLiveThroughBlock - Split CurLI in the given block such that it /// enters the block in IntvIn and leaves it in IntvOut. There may be uses in /// the block, but they will be ignored when placing split points. diff --git a/lib/CodeGen/Splitter.cpp b/lib/CodeGen/Splitter.cpp index ec75df4b7d1f..77973b72bbc8 100644 --- a/lib/CodeGen/Splitter.cpp +++ b/lib/CodeGen/Splitter.cpp @@ -11,7 +11,6 @@ #include "Splitter.h" -#include "RegisterCoalescer.h" #include "llvm/Module.h" #include "llvm/CodeGen/CalcSpillWeights.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" @@ -20,6 +19,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/SlotIndexes.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -262,7 +262,7 @@ namespace llvm { au.addPreserved(); au.addRequired(); au.addPreserved(); - au.addPreserved(); + au.addPreservedID(RegisterCoalescerPassID); au.addPreserved(); au.addPreserved(); au.addRequired(); diff --git a/lib/CodeGen/StackProtector.cpp b/lib/CodeGen/StackProtector.cpp index d3cbd15b64e8..1f0e5a2711ae 100644 --- a/lib/CodeGen/StackProtector.cpp +++ b/lib/CodeGen/StackProtector.cpp @@ -123,7 +123,7 @@ bool StackProtector::RequiresStackProtector() const { // protectors. return true; - if (const ArrayType *AT = dyn_cast(AI->getAllocatedType())) { + if (ArrayType *AT = dyn_cast(AI->getAllocatedType())) { // We apparently only care about character arrays. if (!AT->getElementType()->isIntegerTy(8)) continue; @@ -165,7 +165,7 @@ bool StackProtector::InsertStackProtectors() { // StackGuard = load __stack_chk_guard // call void @llvm.stackprotect.create(StackGuard, StackGuardSlot) // - const PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext()); + PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext()); unsigned AddressSpace, Offset; if (TLI->getStackCookieLocation(AddressSpace, Offset)) { Constant *OffsetVal = diff --git a/lib/CodeGen/StrongPHIElimination.cpp b/lib/CodeGen/StrongPHIElimination.cpp index 227eb47e6827..260cc0ee50a5 100644 --- a/lib/CodeGen/StrongPHIElimination.cpp +++ b/lib/CodeGen/StrongPHIElimination.cpp @@ -47,6 +47,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" using namespace llvm; @@ -673,7 +674,7 @@ void StrongPHIElimination::InsertCopiesForPHI(MachineInstr *PHI, if (PHIColor && SrcColor == PHIColor) { LiveInterval &SrcInterval = LI->getInterval(SrcReg); SlotIndex PredIndex = LI->getMBBEndIdx(PredBB); - VNInfo *SrcVNI = SrcInterval.getVNInfoAt(PredIndex.getPrevIndex()); + VNInfo *SrcVNI = SrcInterval.getVNInfoBefore(PredIndex); assert(SrcVNI); SrcVNI->setHasPHIKill(true); continue; diff --git a/lib/CodeGen/TailDuplication.cpp b/lib/CodeGen/TailDuplication.cpp index 6b801cbf6e1e..3a6211a0f3e6 100644 --- a/lib/CodeGen/TailDuplication.cpp +++ b/lib/CodeGen/TailDuplication.cpp @@ -25,6 +25,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/Statistic.h" diff --git a/lib/CodeGen/TargetInstrInfoImpl.cpp b/lib/CodeGen/TargetInstrInfoImpl.cpp index 86e71d8ccbb6..f32678f12b0a 100644 --- a/lib/CodeGen/TargetInstrInfoImpl.cpp +++ b/lib/CodeGen/TargetInstrInfoImpl.cpp @@ -74,23 +74,25 @@ MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI, assert(MI->getOperand(Idx1).isReg() && MI->getOperand(Idx2).isReg() && "This only knows how to commute register operands so far"); + unsigned Reg0 = HasDef ? MI->getOperand(0).getReg() : 0; unsigned Reg1 = MI->getOperand(Idx1).getReg(); unsigned Reg2 = MI->getOperand(Idx2).getReg(); bool Reg1IsKill = MI->getOperand(Idx1).isKill(); bool Reg2IsKill = MI->getOperand(Idx2).isKill(); - bool ChangeReg0 = false; - if (HasDef && MI->getOperand(0).getReg() == Reg1) { - // Must be two address instruction! - assert(MI->getDesc().getOperandConstraint(0, MCOI::TIED_TO) && - "Expecting a two-address instruction!"); + // If destination is tied to either of the commuted source register, then + // it must be updated. + if (HasDef && Reg0 == Reg1 && + MI->getDesc().getOperandConstraint(Idx1, MCOI::TIED_TO) == 0) { Reg2IsKill = false; - ChangeReg0 = true; + Reg0 = Reg2; + } else if (HasDef && Reg0 == Reg2 && + MI->getDesc().getOperandConstraint(Idx2, MCOI::TIED_TO) == 0) { + Reg1IsKill = false; + Reg0 = Reg1; } if (NewMI) { // Create a new instruction. - unsigned Reg0 = HasDef - ? (ChangeReg0 ? Reg2 : MI->getOperand(0).getReg()) : 0; bool Reg0IsDead = HasDef ? MI->getOperand(0).isDead() : false; MachineFunction &MF = *MI->getParent()->getParent(); if (HasDef) @@ -104,8 +106,8 @@ MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI, .addReg(Reg1, getKillRegState(Reg2IsKill)); } - if (ChangeReg0) - MI->getOperand(0).setReg(Reg2); + if (HasDef) + MI->getOperand(0).setReg(Reg0); MI->getOperand(Idx2).setReg(Reg1); MI->getOperand(Idx1).setReg(Reg2); MI->getOperand(Idx2).setIsKill(Reg1IsKill); @@ -160,6 +162,42 @@ bool TargetInstrInfoImpl::PredicateInstruction(MachineInstr *MI, return MadeChange; } +bool TargetInstrInfoImpl::hasLoadFromStackSlot(const MachineInstr *MI, + const MachineMemOperand *&MMO, + int &FrameIndex) const { + for (MachineInstr::mmo_iterator o = MI->memoperands_begin(), + oe = MI->memoperands_end(); + o != oe; + ++o) { + if ((*o)->isLoad() && (*o)->getValue()) + if (const FixedStackPseudoSourceValue *Value = + dyn_cast((*o)->getValue())) { + FrameIndex = Value->getFrameIndex(); + MMO = *o; + return true; + } + } + return false; +} + +bool TargetInstrInfoImpl::hasStoreToStackSlot(const MachineInstr *MI, + const MachineMemOperand *&MMO, + int &FrameIndex) const { + for (MachineInstr::mmo_iterator o = MI->memoperands_begin(), + oe = MI->memoperands_end(); + o != oe; + ++o) { + if ((*o)->isStore() && (*o)->getValue()) + if (const FixedStackPseudoSourceValue *Value = + dyn_cast((*o)->getValue())) { + FrameIndex = Value->getFrameIndex(); + MMO = *o; + return true; + } + } + return false; +} + void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, @@ -324,6 +362,19 @@ isReallyTriviallyReMaterializableGeneric(const MachineInstr *MI, const TargetInstrInfo &TII = *TM.getInstrInfo(); const TargetRegisterInfo &TRI = *TM.getRegisterInfo(); + // Remat clients assume operand 0 is the defined register. + if (!MI->getNumOperands() || !MI->getOperand(0).isReg()) + return false; + unsigned DefReg = MI->getOperand(0).getReg(); + + // A sub-register definition can only be rematerialized if the instruction + // doesn't read the other parts of the register. Otherwise it is really a + // read-modify-write operation on the full virtual register which cannot be + // moved safely. + if (TargetRegisterInfo::isVirtualRegister(DefReg) && + MI->getOperand(0).getSubReg() && MI->readsVirtualRegister(DefReg)) + return false; + // A load from a fixed stack slot can be rematerialized. This may be // redundant with subsequent checks, but it's target-independent, // simple, and a common case. @@ -383,8 +434,9 @@ isReallyTriviallyReMaterializableGeneric(const MachineInstr *MI, continue; } - // Only allow one virtual-register def, and that in the first operand. - if (MO.isDef() != (i == 0)) + // Only allow one virtual-register def. There may be multiple defs of the + // same virtual register, though. + if (MO.isDef() && Reg != DefReg) return false; // Don't allow any virtual-register uses. Rematting an instruction with diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index a3c562013b59..fb87154232a0 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -43,153 +43,6 @@ using namespace dwarf; // ELF //===----------------------------------------------------------------------===// -TargetLoweringObjectFileELF::TargetLoweringObjectFileELF() - : TargetLoweringObjectFile(), - TLSDataSection(0), - TLSBSSSection(0), - DataRelSection(0), - DataRelLocalSection(0), - DataRelROSection(0), - DataRelROLocalSection(0), - MergeableConst4Section(0), - MergeableConst8Section(0), - MergeableConst16Section(0) { -} - -void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, - const TargetMachine &TM) { - TargetLoweringObjectFile::Initialize(Ctx, TM); - - BSSSection = - getContext().getELFSection(".bss", ELF::SHT_NOBITS, - ELF::SHF_WRITE |ELF::SHF_ALLOC, - SectionKind::getBSS()); - - TextSection = - getContext().getELFSection(".text", ELF::SHT_PROGBITS, - ELF::SHF_EXECINSTR | - ELF::SHF_ALLOC, - SectionKind::getText()); - - DataSection = - getContext().getELFSection(".data", ELF::SHT_PROGBITS, - ELF::SHF_WRITE |ELF::SHF_ALLOC, - SectionKind::getDataRel()); - - ReadOnlySection = - getContext().getELFSection(".rodata", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC, - SectionKind::getReadOnly()); - - TLSDataSection = - getContext().getELFSection(".tdata", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_TLS | - ELF::SHF_WRITE, - SectionKind::getThreadData()); - - TLSBSSSection = - getContext().getELFSection(".tbss", ELF::SHT_NOBITS, - ELF::SHF_ALLOC | ELF::SHF_TLS | - ELF::SHF_WRITE, - SectionKind::getThreadBSS()); - - DataRelSection = - getContext().getELFSection(".data.rel", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getDataRel()); - - DataRelLocalSection = - getContext().getELFSection(".data.rel.local", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getDataRelLocal()); - - DataRelROSection = - getContext().getELFSection(".data.rel.ro", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getReadOnlyWithRel()); - - DataRelROLocalSection = - getContext().getELFSection(".data.rel.ro.local", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getReadOnlyWithRelLocal()); - - MergeableConst4Section = - getContext().getELFSection(".rodata.cst4", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_MERGE, - SectionKind::getMergeableConst4()); - - MergeableConst8Section = - getContext().getELFSection(".rodata.cst8", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_MERGE, - SectionKind::getMergeableConst8()); - - MergeableConst16Section = - getContext().getELFSection(".rodata.cst16", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_MERGE, - SectionKind::getMergeableConst16()); - - StaticCtorSection = - getContext().getELFSection(".ctors", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::SHF_WRITE, - SectionKind::getDataRel()); - - StaticDtorSection = - getContext().getELFSection(".dtors", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC |ELF::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 = - getContext().getELFSection(".gcc_except_table", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC, - SectionKind::getReadOnly()); - // Debug Info Sections. - DwarfAbbrevSection = - getContext().getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfInfoSection = - getContext().getELFSection(".debug_info", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfLineSection = - getContext().getELFSection(".debug_line", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfFrameSection = - getContext().getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfPubNamesSection = - getContext().getELFSection(".debug_pubnames", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfPubTypesSection = - getContext().getELFSection(".debug_pubtypes", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfStrSection = - getContext().getELFSection(".debug_str", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfLocSection = - getContext().getELFSection(".debug_loc", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfARangesSection = - getContext().getELFSection(".debug_aranges", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfRangesSection = - getContext().getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); - DwarfMacroInfoSection = - getContext().getELFSection(".debug_macinfo", ELF::SHT_PROGBITS, 0, - SectionKind::getMetadata()); -} - -const MCSection *TargetLoweringObjectFileELF::getEHFrameSection() const { - return getContext().getELFSection(".eh_frame", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC, - SectionKind::getDataRel()); -} - MCSymbol * TargetLoweringObjectFileELF::getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, @@ -493,221 +346,6 @@ getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, // MachO //===----------------------------------------------------------------------===// -TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() - : TargetLoweringObjectFile(), - TLSDataSection(0), - TLSBSSSection(0), - TLSTLVSection(0), - TLSThreadInitSection(0), - CStringSection(0), - UStringSection(0), - TextCoalSection(0), - ConstTextCoalSection(0), - ConstDataSection(0), - DataCoalSection(0), - DataCommonSection(0), - DataBSSSection(0), - FourByteConstantSection(0), - EightByteConstantSection(0), - SixteenByteConstantSection(0), - LazySymbolPointerSection(0), - NonLazySymbolPointerSection(0) { -} - -void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, - const TargetMachine &TM) { - IsFunctionEHFrameSymbolPrivate = false; - SupportsWeakOmittedEHFrame = false; - - // .comm doesn't support alignment before Leopard. - Triple T(((LLVMTargetMachine&)TM).getTargetTriple()); - if (T.isMacOSX() && T.isMacOSXVersionLT(10, 5)) - CommDirectiveSupportsAlignment = false; - - TargetLoweringObjectFile::Initialize(Ctx, TM); - - TextSection // .text - = getContext().getMachOSection("__TEXT", "__text", - MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, - SectionKind::getText()); - DataSection // .data - = getContext().getMachOSection("__DATA", "__data", 0, - SectionKind::getDataRel()); - - TLSDataSection // .tdata - = getContext().getMachOSection("__DATA", "__thread_data", - MCSectionMachO::S_THREAD_LOCAL_REGULAR, - SectionKind::getDataRel()); - TLSBSSSection // .tbss - = getContext().getMachOSection("__DATA", "__thread_bss", - MCSectionMachO::S_THREAD_LOCAL_ZEROFILL, - SectionKind::getThreadBSS()); - - // TODO: Verify datarel below. - TLSTLVSection // .tlv - = getContext().getMachOSection("__DATA", "__thread_vars", - MCSectionMachO::S_THREAD_LOCAL_VARIABLES, - SectionKind::getDataRel()); - - TLSThreadInitSection - = getContext().getMachOSection("__DATA", "__thread_init", - MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS, - SectionKind::getDataRel()); - - CStringSection // .cstring - = getContext().getMachOSection("__TEXT", "__cstring", - MCSectionMachO::S_CSTRING_LITERALS, - SectionKind::getMergeable1ByteCString()); - UStringSection - = getContext().getMachOSection("__TEXT","__ustring", 0, - SectionKind::getMergeable2ByteCString()); - FourByteConstantSection // .literal4 - = getContext().getMachOSection("__TEXT", "__literal4", - MCSectionMachO::S_4BYTE_LITERALS, - SectionKind::getMergeableConst4()); - EightByteConstantSection // .literal8 - = getContext().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 - getContext().getMachOSection("__TEXT", "__literal16", - MCSectionMachO::S_16BYTE_LITERALS, - SectionKind::getMergeableConst16()); - - ReadOnlySection // .const - = getContext().getMachOSection("__TEXT", "__const", 0, - SectionKind::getReadOnly()); - - TextCoalSection - = getContext().getMachOSection("__TEXT", "__textcoal_nt", - MCSectionMachO::S_COALESCED | - MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, - SectionKind::getText()); - ConstTextCoalSection - = getContext().getMachOSection("__TEXT", "__const_coal", - MCSectionMachO::S_COALESCED, - SectionKind::getReadOnly()); - ConstDataSection // .const_data - = getContext().getMachOSection("__DATA", "__const", 0, - SectionKind::getReadOnlyWithRel()); - DataCoalSection - = getContext().getMachOSection("__DATA","__datacoal_nt", - MCSectionMachO::S_COALESCED, - SectionKind::getDataRel()); - DataCommonSection - = getContext().getMachOSection("__DATA","__common", - MCSectionMachO::S_ZEROFILL, - SectionKind::getBSS()); - DataBSSSection - = getContext().getMachOSection("__DATA","__bss", MCSectionMachO::S_ZEROFILL, - SectionKind::getBSS()); - - - LazySymbolPointerSection - = getContext().getMachOSection("__DATA", "__la_symbol_ptr", - MCSectionMachO::S_LAZY_SYMBOL_POINTERS, - SectionKind::getMetadata()); - NonLazySymbolPointerSection - = getContext().getMachOSection("__DATA", "__nl_symbol_ptr", - MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, - SectionKind::getMetadata()); - - if (TM.getRelocationModel() == Reloc::Static) { - StaticCtorSection - = getContext().getMachOSection("__TEXT", "__constructor", 0, - SectionKind::getDataRel()); - StaticDtorSection - = getContext().getMachOSection("__TEXT", "__destructor", 0, - SectionKind::getDataRel()); - } else { - StaticCtorSection - = getContext().getMachOSection("__DATA", "__mod_init_func", - MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, - SectionKind::getDataRel()); - StaticDtorSection - = getContext().getMachOSection("__DATA", "__mod_term_func", - MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, - SectionKind::getDataRel()); - } - - // Exception Handling. - LSDASection = getContext().getMachOSection("__TEXT", "__gcc_except_tab", 0, - SectionKind::getReadOnlyWithRel()); - - if (T.isMacOSX() && !T.isMacOSXVersionLT(10, 6)) - CompactUnwindSection = - getContext().getMachOSection("__LD", "__compact_unwind", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getReadOnly()); - - // Debug Information. - DwarfAbbrevSection = - getContext().getMachOSection("__DWARF", "__debug_abbrev", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - DwarfInfoSection = - getContext().getMachOSection("__DWARF", "__debug_info", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - DwarfLineSection = - getContext().getMachOSection("__DWARF", "__debug_line", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - DwarfFrameSection = - getContext().getMachOSection("__DWARF", "__debug_frame", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - DwarfPubNamesSection = - getContext().getMachOSection("__DWARF", "__debug_pubnames", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - DwarfPubTypesSection = - getContext().getMachOSection("__DWARF", "__debug_pubtypes", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - DwarfStrSection = - getContext().getMachOSection("__DWARF", "__debug_str", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - DwarfLocSection = - getContext().getMachOSection("__DWARF", "__debug_loc", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - DwarfARangesSection = - getContext().getMachOSection("__DWARF", "__debug_aranges", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - DwarfRangesSection = - getContext().getMachOSection("__DWARF", "__debug_ranges", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - DwarfMacroInfoSection = - getContext().getMachOSection("__DWARF", "__debug_macinfo", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - DwarfDebugInlineSection = - getContext().getMachOSection("__DWARF", "__debug_inlined", - MCSectionMachO::S_ATTR_DEBUG, - SectionKind::getMetadata()); - - TLSExtraDataSection = TLSTLVSection; -} - -const MCSection *TargetLoweringObjectFileMachO::getEHFrameSection() const { - return getContext().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()); -} - const MCSection *TargetLoweringObjectFileMachO:: getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const { @@ -905,183 +543,10 @@ getCFIPersonalitySymbol(const GlobalValue *GV, Mangler *Mang, return SSym; } -unsigned TargetLoweringObjectFileMachO::getPersonalityEncoding() const { - return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4; -} - -unsigned TargetLoweringObjectFileMachO::getLSDAEncoding() const { - return DW_EH_PE_pcrel; -} - -unsigned TargetLoweringObjectFileMachO::getFDEEncoding(bool CFI) const { - return DW_EH_PE_pcrel; -} - -unsigned TargetLoweringObjectFileMachO::getTTypeEncoding() const { - return DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4; -} - //===----------------------------------------------------------------------===// // COFF //===----------------------------------------------------------------------===// -TargetLoweringObjectFileCOFF::TargetLoweringObjectFileCOFF() - : TargetLoweringObjectFile(), - DrectveSection(0), - PDataSection(0), - XDataSection(0) { -} - -void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx, - const TargetMachine &TM) { - TargetLoweringObjectFile::Initialize(Ctx, TM); - TextSection = - getContext().getCOFFSection(".text", - COFF::IMAGE_SCN_CNT_CODE | - COFF::IMAGE_SCN_MEM_EXECUTE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getText()); - DataSection = - getContext().getCOFFSection(".data", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getDataRel()); - ReadOnlySection = - getContext().getCOFFSection(".rdata", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getReadOnly()); - StaticCtorSection = - getContext().getCOFFSection(".ctors", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getDataRel()); - StaticDtorSection = - getContext().getCOFFSection(".dtors", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - 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 = - getContext().getCOFFSection(".gcc_except_table", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getReadOnly()); - // Debug info. - DwarfAbbrevSection = - getContext().getCOFFSection(".debug_abbrev", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfInfoSection = - getContext().getCOFFSection(".debug_info", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfLineSection = - getContext().getCOFFSection(".debug_line", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfFrameSection = - getContext().getCOFFSection(".debug_frame", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfPubNamesSection = - getContext().getCOFFSection(".debug_pubnames", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfPubTypesSection = - getContext().getCOFFSection(".debug_pubtypes", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfStrSection = - getContext().getCOFFSection(".debug_str", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfLocSection = - getContext().getCOFFSection(".debug_loc", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfARangesSection = - getContext().getCOFFSection(".debug_aranges", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfRangesSection = - getContext().getCOFFSection(".debug_ranges", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - DwarfMacroInfoSection = - getContext().getCOFFSection(".debug_macinfo", - COFF::IMAGE_SCN_MEM_DISCARDABLE | - COFF::IMAGE_SCN_MEM_READ, - SectionKind::getMetadata()); - - DrectveSection = - getContext().getCOFFSection(".drectve", - COFF::IMAGE_SCN_LNK_INFO, - SectionKind::getMetadata()); - - PDataSection = - getContext().getCOFFSection(".pdata", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getDataRel()); - - XDataSection = - getContext().getCOFFSection(".xdata", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getDataRel()); -} - -const MCSection *TargetLoweringObjectFileCOFF::getEHFrameSection() const { - return getContext().getCOFFSection(".eh_frame", - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getDataRel()); -} - -const MCSection *TargetLoweringObjectFileCOFF::getWin64EHFuncTableSection( - StringRef suffix) const { - if (suffix == "") - return PDataSection; - return getContext().getCOFFSection((".pdata"+suffix).str(), - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getDataRel()); -} - -const MCSection *TargetLoweringObjectFileCOFF::getWin64EHTableSection( - StringRef suffix) const { - if (suffix == "") - return XDataSection; - return getContext().getCOFFSection((".xdata"+suffix).str(), - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE, - SectionKind::getDataRel()); -} - - static unsigned getCOFFSectionFlags(SectionKind K) { unsigned Flags = 0; diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 6d6244e4f879..d87937822280 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -177,6 +177,10 @@ char &llvm::TwoAddressInstructionPassID = TwoAddressInstructionPass::ID; bool TwoAddressInstructionPass::Sink3AddrInstruction(MachineBasicBlock *MBB, MachineInstr *MI, unsigned SavedReg, MachineBasicBlock::iterator OldPos) { + // FIXME: Shouldn't we be trying to do this before we three-addressify the + // instruction? After this transformation is done, we no longer need + // the instruction to be in three-address form. + // Check if it's safe to move this instruction. bool SeenStore = true; // Be conservative. if (!MI->isSafeToMove(TII, AA, SeenStore)) @@ -217,7 +221,11 @@ bool TwoAddressInstructionPass::Sink3AddrInstruction(MachineBasicBlock *MBB, break; } - if (!KillMI || KillMI->getParent() != MBB || KillMI == MI) + // If we find the instruction that kills SavedReg, and it is in an + // appropriate location, we can try to sink the current instruction + // past it. + if (!KillMI || KillMI->getParent() != MBB || KillMI == MI || + KillMI->getDesc().isTerminator()) return false; // If any of the definitions are used by another instruction between the @@ -1041,6 +1049,9 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { DEBUG(dbgs() << "********** Function: " << MF.getFunction()->getName() << '\n'); + // This pass takes the function out of SSA form. + MRI->leaveSSA(); + // ReMatRegs - Keep track of the registers whose def's are remat'ed. BitVector ReMatRegs(MRI->getNumVirtRegs()); diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index 7557979ec9bb..8a1cdc01c494 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -41,8 +41,8 @@ #include using namespace llvm; -STATISTIC(NumSpills , "Number of register spills"); -STATISTIC(NumIdCopies, "Number of identity moves eliminated after rewriting"); +STATISTIC(NumSpillSlots, "Number of spill slots allocated"); +STATISTIC(NumIdCopies, "Number of identity moves eliminated after rewriting"); //===----------------------------------------------------------------------===// // VirtRegMap implementation @@ -111,6 +111,7 @@ unsigned VirtRegMap::createSpillSlot(const TargetRegisterClass *RC) { unsigned Idx = SS-LowSpillSlot; while (Idx >= SpillSlotToUsesMap.size()) SpillSlotToUsesMap.resize(SpillSlotToUsesMap.size()*2); + ++NumSpillSlots; return SS; } @@ -130,7 +131,6 @@ int VirtRegMap::assignVirt2StackSlot(unsigned virtReg) { assert(Virt2StackSlotMap[virtReg] == NO_STACK_SLOT && "attempt to assign stack slot to already spilled register"); const TargetRegisterClass* RC = MF->getRegInfo().getRegClass(virtReg); - ++NumSpills; return Virt2StackSlotMap[virtReg] = createSpillSlot(RC); } @@ -285,14 +285,24 @@ void VirtRegMap::rewrite(SlotIndexes *Indexes) { // Preserve semantics of sub-register operands. if (MO.getSubReg()) { // A virtual register kill refers to the whole register, so we may - // have to add operands for the super-register. - if (MO.isUse()) { - if (MO.isKill() && !MO.isUndef()) - SuperKills.push_back(PhysReg); - } else if (MO.isDead()) - SuperDeads.push_back(PhysReg); - else - SuperDefs.push_back(PhysReg); + // have to add operands for the super-register. A + // partial redef always kills and redefines the super-register. + if (MO.readsReg() && (MO.isDef() || MO.isKill())) + SuperKills.push_back(PhysReg); + + if (MO.isDef()) { + // The flag only makes sense for sub-register defs, and + // we are substituting a full physreg. An operand + // from the SuperKills list will represent the partial read of the + // super-register. + MO.setIsUndef(false); + + // Also add implicit defs for the super-register. + if (MO.isDead()) + SuperDeads.push_back(PhysReg); + else + SuperDefs.push_back(PhysReg); + } // PhysReg operands cannot have subregister indexes. PhysReg = TRI->getSubReg(PhysReg, MO.getSubReg()); diff --git a/lib/CompilerDriver/Action.cpp b/lib/CompilerDriver/Action.cpp deleted file mode 100644 index a8d625c7ac04..000000000000 --- a/lib/CompilerDriver/Action.cpp +++ /dev/null @@ -1,134 +0,0 @@ -//===--- Action.cpp - The LLVM Compiler Driver ------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Action class - implementation and auxiliary functions. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CompilerDriver/Action.h" -#include "llvm/CompilerDriver/BuiltinOptions.h" -#include "llvm/CompilerDriver/Error.h" -#include "llvm/CompilerDriver/Main.h" - -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/SystemUtils.h" -#include "llvm/Support/Program.h" -#include "llvm/Support/TimeValue.h" - -#include -#include - -using namespace llvm; -using namespace llvmc; - -namespace llvmc { - -extern const char* ProgramName; - -} - -namespace { - - void PrintString (const std::string& str) { - errs() << str << ' '; - } - - void PrintCommand (const std::string& Cmd, const StrVector& Args) { - errs() << Cmd << ' '; - std::for_each(Args.begin(), Args.end(), &PrintString); - errs() << '\n'; - } - - bool IsSegmentationFault (int returnCode) { -#ifdef LLVM_ON_WIN32 - return (returnCode >= 0xc0000000UL) -#else - return (returnCode < 0); -#endif - } - - int ExecuteProgram (const std::string& name, const StrVector& args) { - sys::Path prog(name); - - if (sys::path::is_relative(prog.str())) { - prog = PrependMainExecutablePath(name, ProgramName, - (void *)(intptr_t)&Main); - - if (!prog.canExecute()) { - prog = sys::Program::FindProgramByName(name); - if (prog.isEmpty()) { - PrintError("Can't find program '" + name + "'"); - return -1; - } - } - } - if (!prog.canExecute()) { - PrintError("Program '" + name + "' is not executable."); - return -1; - } - - // Build the command line vector and the redirects array. - const sys::Path* redirects[3] = {0,0,0}; - sys::Path stdout_redirect; - - std::vector argv; - argv.reserve((args.size()+2)); - argv.push_back(name.c_str()); - - for (StrVector::const_iterator B = args.begin(), E = args.end(); - B!=E; ++B) { - if (*B == ">") { - ++B; - stdout_redirect.set(*B); - redirects[1] = &stdout_redirect; - } - else { - argv.push_back((*B).c_str()); - } - } - argv.push_back(0); // null terminate list. - - // Invoke the program. - int ret = sys::Program::ExecuteAndWait(prog, &argv[0], 0, &redirects[0]); - - if (IsSegmentationFault(ret)) { - errs() << "Segmentation fault: "; - PrintCommand(name, args); - } - - return ret; - } -} - -namespace llvmc { - void AppendToGlobalTimeLog (const std::string& cmd, double time); -} - -int llvmc::Action::Execute () const { - if (DryRun || VerboseMode) - PrintCommand(Command_, Args_); - - if (!DryRun) { - if (Time) { - sys::TimeValue now = sys::TimeValue::now(); - int ret = ExecuteProgram(Command_, Args_); - sys::TimeValue now2 = sys::TimeValue::now(); - now2 -= now; - double elapsed = now2.seconds() + now2.microseconds() / 1000000.0; - AppendToGlobalTimeLog(Command_, elapsed); - - return ret; - } - else { - return ExecuteProgram(Command_, Args_); - } - } - - return 0; -} diff --git a/lib/CompilerDriver/BuiltinOptions.cpp b/lib/CompilerDriver/BuiltinOptions.cpp deleted file mode 100644 index 38442038d738..000000000000 --- a/lib/CompilerDriver/BuiltinOptions.cpp +++ /dev/null @@ -1,61 +0,0 @@ -//===--- BuiltinOptions.cpp - The LLVM Compiler Driver ----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Definitions of all global command-line option variables. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CompilerDriver/BuiltinOptions.h" - -#ifdef ENABLE_LLVMC_DYNAMIC_PLUGINS -#include "llvm/Support/PluginLoader.h" -#endif - -namespace cl = llvm::cl; - -namespace llvmc { - -cl::list InputFilenames(cl::Positional, cl::desc(""), - cl::ZeroOrMore); -cl::opt OutputFilename("o", cl::desc("Output file name"), - cl::value_desc("file"), cl::Prefix); -cl::opt TempDirname("temp-dir", cl::desc("Temp dir name"), - cl::value_desc(""), cl::Prefix); -cl::list Languages("x", - cl::desc("Specify the language of the following input files"), - cl::ZeroOrMore); - -cl::opt DryRun("dry-run", - cl::desc("Only pretend to run commands")); -cl::opt Time("time", cl::desc("Time individual commands")); -cl::opt VerboseMode("v", - cl::desc("Enable verbose mode")); - -cl::opt CheckGraph("check-graph", - cl::desc("Check the compilation graph for errors"), - cl::Hidden); -cl::opt WriteGraph("write-graph", - cl::desc("Write compilation-graph.dot file"), - cl::Hidden); -cl::opt ViewGraph("view-graph", - cl::desc("Show compilation graph in GhostView"), - cl::Hidden); - -cl::opt SaveTemps -("save-temps", cl::desc("Keep temporary files"), - cl::init(SaveTempsEnum::Unset), - cl::values(clEnumValN(SaveTempsEnum::Obj, "obj", - "Save files in the directory specified with -o"), - clEnumValN(SaveTempsEnum::Cwd, "cwd", - "Use current working directory"), - clEnumValN(SaveTempsEnum::Obj, "", "Same as 'cwd'"), - clEnumValEnd), - cl::ValueOptional); - -} // End namespace llvmc. diff --git a/lib/CompilerDriver/CMakeLists.txt b/lib/CompilerDriver/CMakeLists.txt deleted file mode 100644 index a12b3378aaf2..000000000000 --- a/lib/CompilerDriver/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -set(LLVM_LINK_COMPONENTS support) - -# We don't want this library to appear in `llvm-config --libs` output, -# so its name doesn't start with "LLVM". - -add_llvm_library(CompilerDriver - Action.cpp - BuiltinOptions.cpp - CompilationGraph.cpp - Main.cpp - Tool.cpp - ) diff --git a/lib/CompilerDriver/CompilationGraph.cpp b/lib/CompilerDriver/CompilationGraph.cpp deleted file mode 100644 index 33c6566499b8..000000000000 --- a/lib/CompilerDriver/CompilationGraph.cpp +++ /dev/null @@ -1,655 +0,0 @@ -//===--- CompilationGraph.cpp - The LLVM Compiler Driver --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Compilation graph - implementation. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CompilerDriver/BuiltinOptions.h" -#include "llvm/CompilerDriver/CompilationGraph.h" -#include "llvm/CompilerDriver/Error.h" - -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/DOTGraphTraits.h" -#include "llvm/Support/GraphWriter.h" -#include "llvm/Support/raw_ostream.h" - -#include -#include -#include -#include -#include - -using namespace llvm; -using namespace llvmc; - -namespace llvmc { - - const std::string* LanguageMap::GetLanguage(const sys::Path& File) const { - // Remove the '.'. - StringRef suf = sys::path::extension(File.str()).substr(1); - LanguageMap::const_iterator Lang = - this->find(suf.empty() ? "*empty*" : suf); - if (Lang == this->end()) { - PrintError("File '" + File.str() + "' has unknown suffix '" - + suf.str() + '\''); - return 0; - } - return &Lang->second; - } -} - -namespace { - - /// ChooseEdge - Return the edge with the maximum weight. Returns 0 on error. - template - const Edge* ChooseEdge(const C& EdgesContainer, - const InputLanguagesSet& InLangs, - const std::string& NodeName = "root") { - const Edge* MaxEdge = 0; - int MaxWeight = 0; - bool SingleMax = true; - - // TODO: fix calculation of SingleMax. - for (typename C::const_iterator B = EdgesContainer.begin(), - E = EdgesContainer.end(); B != E; ++B) { - const Edge* e = B->getPtr(); - int EW = e->Weight(InLangs); - if (EW < 0) { - // (error) invocation in TableGen -> we don't need to print an error - // message. - return 0; - } - if (EW > MaxWeight) { - MaxEdge = e; - MaxWeight = EW; - SingleMax = true; - } else if (EW == MaxWeight) { - SingleMax = false; - } - } - - if (!SingleMax) { - PrintError("Node " + NodeName + ": multiple maximal outward edges found!" - " Most probably a specification error."); - return 0; - } - if (!MaxEdge) { - PrintError("Node " + NodeName + ": no maximal outward edge found!" - " Most probably a specification error."); - return 0; - } - return MaxEdge; - } - -} - -void Node::AddEdge(Edge* Edg) { - // If there already was an edge between two nodes, modify it instead - // of adding a new edge. - const std::string& ToolName = Edg->ToolName(); - for (container_type::iterator B = OutEdges.begin(), E = OutEdges.end(); - B != E; ++B) { - if ((*B)->ToolName() == ToolName) { - llvm::IntrusiveRefCntPtr(Edg).swap(*B); - return; - } - } - OutEdges.push_back(llvm::IntrusiveRefCntPtr(Edg)); -} - -CompilationGraph::CompilationGraph() { - NodesMap["root"] = Node(this); -} - -Node* CompilationGraph::getNode(const std::string& ToolName) { - nodes_map_type::iterator I = NodesMap.find(ToolName); - if (I == NodesMap.end()) { - PrintError("Node " + ToolName + " is not in the graph"); - return 0; - } - return &I->second; -} - -const Node* CompilationGraph::getNode(const std::string& ToolName) const { - nodes_map_type::const_iterator I = NodesMap.find(ToolName); - if (I == NodesMap.end()) { - PrintError("Node " + ToolName + " is not in the graph!"); - return 0; - } - return &I->second; -} - -// Find the tools list corresponding to the given language name. -const CompilationGraph::tools_vector_type* -CompilationGraph::getToolsVector(const std::string& LangName) const -{ - tools_map_type::const_iterator I = ToolsMap.find(LangName); - if (I == ToolsMap.end()) { - PrintError("No tool corresponding to the language " + LangName + " found"); - return 0; - } - return &I->second; -} - -void CompilationGraph::insertNode(Tool* V) { - if (NodesMap.count(V->Name()) == 0) - NodesMap[V->Name()] = Node(this, V); -} - -int CompilationGraph::insertEdge(const std::string& A, Edge* Edg) { - Node* B = getNode(Edg->ToolName()); - if (B == 0) - return 1; - - if (A == "root") { - const char** InLangs = B->ToolPtr->InputLanguages(); - for (;*InLangs; ++InLangs) - ToolsMap[*InLangs].push_back(IntrusiveRefCntPtr(Edg)); - NodesMap["root"].AddEdge(Edg); - } - else { - Node* N = getNode(A); - if (N == 0) - return 1; - - N->AddEdge(Edg); - } - // Increase the inward edge counter. - B->IncrInEdges(); - - return 0; -} - -// Pass input file through the chain until we bump into a Join node or -// a node that says that it is the last. -int CompilationGraph::PassThroughGraph (const sys::Path& InFile, - const Node* StartNode, - const InputLanguagesSet& InLangs, - const sys::Path& TempDir, - const LanguageMap& LangMap) const { - sys::Path In = InFile; - const Node* CurNode = StartNode; - - while(true) { - Tool* CurTool = CurNode->ToolPtr.getPtr(); - - if (CurTool->IsJoin()) { - JoinTool& JT = static_cast(*CurTool); - JT.AddToJoinList(In); - break; - } - - Action CurAction; - if (int ret = CurTool->GenerateAction(CurAction, In, CurNode->HasChildren(), - TempDir, InLangs, LangMap)) { - return ret; - } - - if (int ret = CurAction.Execute()) - return ret; - - if (CurAction.StopCompilation()) - return 0; - - const Edge* Edg = ChooseEdge(CurNode->OutEdges, InLangs, CurNode->Name()); - if (Edg == 0) - return 1; - - CurNode = getNode(Edg->ToolName()); - if (CurNode == 0) - return 1; - - In = CurAction.OutFile(); - } - - return 0; -} - -// Find the head of the toolchain corresponding to the given file. -// Also, insert an input language into InLangs. -const Node* CompilationGraph:: -FindToolChain(const sys::Path& In, const std::string* ForceLanguage, - InputLanguagesSet& InLangs, const LanguageMap& LangMap) const { - - // Determine the input language. - const std::string* InLang = (ForceLanguage ? ForceLanguage - : LangMap.GetLanguage(In)); - if (InLang == 0) - return 0; - const std::string& InLanguage = *InLang; - - // Add the current input language to the input language set. - InLangs.insert(InLanguage); - - // Find the toolchain for the input language. - const tools_vector_type* pTV = getToolsVector(InLanguage); - if (pTV == 0) - return 0; - - const tools_vector_type& TV = *pTV; - if (TV.empty()) { - PrintError("No toolchain corresponding to language " - + InLanguage + " found"); - return 0; - } - - const Edge* Edg = ChooseEdge(TV, InLangs); - if (Edg == 0) - return 0; - - return getNode(Edg->ToolName()); -} - -// Helper function used by Build(). -// Traverses initial portions of the toolchains (up to the first Join node). -// This function is also responsible for handling the -x option. -int CompilationGraph::BuildInitial (InputLanguagesSet& InLangs, - const sys::Path& TempDir, - const LanguageMap& LangMap) { - // This is related to -x option handling. - cl::list::const_iterator xIter = Languages.begin(), - xBegin = xIter, xEnd = Languages.end(); - bool xEmpty = true; - const std::string* xLanguage = 0; - unsigned xPos = 0, xPosNext = 0, filePos = 0; - - if (xIter != xEnd) { - xEmpty = false; - xPos = Languages.getPosition(xIter - xBegin); - cl::list::const_iterator xNext = llvm::next(xIter); - xPosNext = (xNext == xEnd) ? std::numeric_limits::max() - : Languages.getPosition(xNext - xBegin); - xLanguage = (*xIter == "none") ? 0 : &(*xIter); - } - - // For each input file: - for (cl::list::const_iterator B = InputFilenames.begin(), - CB = B, E = InputFilenames.end(); B != E; ++B) { - sys::Path In = sys::Path(*B); - - // Code for handling the -x option. - // Output: std::string* xLanguage (can be NULL). - if (!xEmpty) { - filePos = InputFilenames.getPosition(B - CB); - - if (xPos < filePos) { - if (filePos < xPosNext) { - xLanguage = (*xIter == "none") ? 0 : &(*xIter); - } - else { // filePos >= xPosNext - // Skip xIters while filePos > xPosNext - while (filePos > xPosNext) { - ++xIter; - xPos = xPosNext; - - cl::list::const_iterator xNext = llvm::next(xIter); - if (xNext == xEnd) - xPosNext = std::numeric_limits::max(); - else - xPosNext = Languages.getPosition(xNext - xBegin); - xLanguage = (*xIter == "none") ? 0 : &(*xIter); - } - } - } - } - - // Find the toolchain corresponding to this file. - const Node* N = FindToolChain(In, xLanguage, InLangs, LangMap); - if (N == 0) - return 1; - // Pass file through the chain starting at head. - if (int ret = PassThroughGraph(In, N, InLangs, TempDir, LangMap)) - return ret; - } - - return 0; -} - -// Sort the nodes in topological order. -int CompilationGraph::TopologicalSort(std::vector& Out) { - std::queue Q; - - Node* Root = getNode("root"); - if (Root == 0) - return 1; - - Q.push(Root); - - while (!Q.empty()) { - const Node* A = Q.front(); - Q.pop(); - Out.push_back(A); - for (Node::const_iterator EB = A->EdgesBegin(), EE = A->EdgesEnd(); - EB != EE; ++EB) { - Node* B = getNode((*EB)->ToolName()); - if (B == 0) - return 1; - - B->DecrInEdges(); - if (B->HasNoInEdges()) - Q.push(B); - } - } - - return 0; -} - -namespace { - bool NotJoinNode(const Node* N) { - return N->ToolPtr ? !N->ToolPtr->IsJoin() : true; - } -} - -// Call TopologicalSort and filter the resulting list to include -// only Join nodes. -int CompilationGraph:: -TopologicalSortFilterJoinNodes(std::vector& Out) { - std::vector TopSorted; - if (int ret = TopologicalSort(TopSorted)) - return ret; - std::remove_copy_if(TopSorted.begin(), TopSorted.end(), - std::back_inserter(Out), NotJoinNode); - - return 0; -} - -int CompilationGraph::Build (const sys::Path& TempDir, - const LanguageMap& LangMap) { - InputLanguagesSet InLangs; - bool WasSomeActionGenerated = !InputFilenames.empty(); - - // Traverse initial parts of the toolchains and fill in InLangs. - if (int ret = BuildInitial(InLangs, TempDir, LangMap)) - return ret; - - std::vector JTV; - if (int ret = TopologicalSortFilterJoinNodes(JTV)) - return ret; - - // For all join nodes in topological order: - for (std::vector::iterator B = JTV.begin(), E = JTV.end(); - B != E; ++B) { - - const Node* CurNode = *B; - JoinTool* JT = &static_cast(*CurNode->ToolPtr.getPtr()); - - // Are there any files in the join list? - if (JT->JoinListEmpty() && !(JT->WorksOnEmpty() && InputFilenames.empty())) - continue; - - WasSomeActionGenerated = true; - Action CurAction; - if (int ret = JT->GenerateAction(CurAction, CurNode->HasChildren(), - TempDir, InLangs, LangMap)) { - return ret; - } - - if (int ret = CurAction.Execute()) - return ret; - - if (CurAction.StopCompilation()) - return 0; - - const Edge* Edg = ChooseEdge(CurNode->OutEdges, InLangs, CurNode->Name()); - if (Edg == 0) - return 1; - - const Node* NextNode = getNode(Edg->ToolName()); - if (NextNode == 0) - return 1; - - if (int ret = PassThroughGraph(sys::Path(CurAction.OutFile()), NextNode, - InLangs, TempDir, LangMap)) { - return ret; - } - } - - if (!WasSomeActionGenerated) { - PrintError("no input files"); - return 1; - } - - return 0; -} - -int CompilationGraph::CheckLanguageNames() const { - int ret = 0; - - // Check that names for output and input languages on all edges do match. - for (const_nodes_iterator B = this->NodesMap.begin(), - E = this->NodesMap.end(); B != E; ++B) { - - const Node & N1 = B->second; - if (N1.ToolPtr) { - for (Node::const_iterator EB = N1.EdgesBegin(), EE = N1.EdgesEnd(); - EB != EE; ++EB) { - const Node* N2 = this->getNode((*EB)->ToolName()); - if (N2 == 0) - return 1; - - if (!N2->ToolPtr) { - ++ret; - errs() << "Error: there is an edge from '" << N1.ToolPtr->Name() - << "' back to the root!\n\n"; - continue; - } - - const char** OutLangs = N1.ToolPtr->OutputLanguages(); - const char** InLangs = N2->ToolPtr->InputLanguages(); - bool eq = false; - const char* OutLang = 0; - for (;*OutLangs; ++OutLangs) { - OutLang = *OutLangs; - for (;*InLangs; ++InLangs) { - if (std::strcmp(OutLang, *InLangs) == 0) { - eq = true; - break; - } - } - } - - if (!eq) { - ++ret; - errs() << "Error: Output->input language mismatch in the edge '" - << N1.ToolPtr->Name() << "' -> '" << N2->ToolPtr->Name() - << "'!\n" - << "Expected one of { "; - - InLangs = N2->ToolPtr->InputLanguages(); - for (;*InLangs; ++InLangs) { - errs() << '\'' << *InLangs << (*(InLangs+1) ? "', " : "'"); - } - - errs() << " }, but got '" << OutLang << "'!\n\n"; - } - - } - } - } - - return ret; -} - -int CompilationGraph::CheckMultipleDefaultEdges() const { - int ret = 0; - InputLanguagesSet Dummy; - - // For all nodes, just iterate over the outgoing edges and check if there is - // more than one edge with maximum weight. - for (const_nodes_iterator B = this->NodesMap.begin(), - E = this->NodesMap.end(); B != E; ++B) { - const Node& N = B->second; - int MaxWeight = -1024; - - // Ignore the root node. - if (!N.ToolPtr) - continue; - - for (Node::const_iterator EB = N.EdgesBegin(), EE = N.EdgesEnd(); - EB != EE; ++EB) { - int EdgeWeight = (*EB)->Weight(Dummy); - if (EdgeWeight > MaxWeight) { - MaxWeight = EdgeWeight; - } - else if (EdgeWeight == MaxWeight) { - ++ret; - errs() << "Error: there are multiple maximal edges stemming from the '" - << N.ToolPtr->Name() << "' node!\n\n"; - break; - } - } - } - - return ret; -} - -int CompilationGraph::CheckCycles() { - unsigned deleted = 0; - std::queue Q; - - Node* Root = getNode("root"); - if (Root == 0) - return 1; - - Q.push(Root); - - // Try to delete all nodes that have no ingoing edges, starting from the - // root. If there are any nodes left after this operation, then we have a - // cycle. This relies on '--check-graph' not performing the topological sort. - while (!Q.empty()) { - Node* A = Q.front(); - Q.pop(); - ++deleted; - - for (Node::iterator EB = A->EdgesBegin(), EE = A->EdgesEnd(); - EB != EE; ++EB) { - Node* B = getNode((*EB)->ToolName()); - if (B == 0) - return 1; - - B->DecrInEdges(); - if (B->HasNoInEdges()) - Q.push(B); - } - } - - if (deleted != NodesMap.size()) { - errs() << "Error: there are cycles in the compilation graph!\n" - << "Try inspecting the diagram produced by " - << "'llvmc --view-graph'.\n\n"; - return 1; - } - - return 0; -} - -int CompilationGraph::Check () { - // We try to catch as many errors as we can in one go. - int errs = 0; - int ret = 0; - - // Check that output/input language names match. - ret = this->CheckLanguageNames(); - if (ret < 0) - return 1; - errs += ret; - - // Check for multiple default edges. - ret = this->CheckMultipleDefaultEdges(); - if (ret < 0) - return 1; - errs += ret; - - // Check for cycles. - ret = this->CheckCycles(); - if (ret < 0) - return 1; - errs += ret; - - return errs; -} - -// Code related to graph visualization. - -namespace { - -std::string SquashStrArray (const char** StrArr) { - std::string ret; - - for (; *StrArr; ++StrArr) { - if (*(StrArr + 1)) { - ret += *StrArr; - ret += ", "; - } - else { - ret += *StrArr; - } - } - - return ret; -} - -} // End anonymous namespace. - -namespace llvm { - template <> - struct DOTGraphTraits - : public DefaultDOTGraphTraits - { - DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} - - template - static std::string getNodeLabel(const Node* N, const GraphType&) - { - if (N->ToolPtr) - if (N->ToolPtr->IsJoin()) - return N->Name() + "\n (join" + - (N->HasChildren() ? ")" - : std::string(": ") + - SquashStrArray(N->ToolPtr->OutputLanguages()) + ')'); - else - return N->Name(); - else - return "root"; - } - - template - static std::string getEdgeSourceLabel(const Node* N, EdgeIter I) { - if (N->ToolPtr) { - return SquashStrArray(N->ToolPtr->OutputLanguages()); - } - else { - return SquashStrArray(I->ToolPtr->InputLanguages()); - } - } - }; - -} // End namespace llvm - -int CompilationGraph::writeGraph(const std::string& OutputFilename) { - std::string ErrorInfo; - raw_fd_ostream O(OutputFilename.c_str(), ErrorInfo); - - if (ErrorInfo.empty()) { - errs() << "Writing '"<< OutputFilename << "' file..."; - llvm::WriteGraph(O, this); - errs() << "done.\n"; - } - else { - PrintError("Error opening file '" + OutputFilename + "' for writing!"); - return 1; - } - - return 0; -} - -void CompilationGraph::viewGraph() { - llvm::ViewGraph(this, "compilation-graph"); -} diff --git a/lib/CompilerDriver/Main.cpp b/lib/CompilerDriver/Main.cpp deleted file mode 100644 index 7120027f7ce0..000000000000 --- a/lib/CompilerDriver/Main.cpp +++ /dev/null @@ -1,146 +0,0 @@ -//===--- Main.cpp - The LLVM Compiler Driver --------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// llvmc::Main function - driver entry point. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CompilerDriver/AutoGenerated.h" -#include "llvm/CompilerDriver/BuiltinOptions.h" -#include "llvm/CompilerDriver/CompilationGraph.h" -#include "llvm/CompilerDriver/Error.h" - -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Path.h" - -#include -#include - -namespace cl = llvm::cl; -namespace sys = llvm::sys; -using namespace llvmc; - -namespace { - - std::stringstream* GlobalTimeLog; - - /// GetTempDir - Get the temporary directory location. Returns non-zero value - /// on error. - int GetTempDir(sys::Path& tempDir) { - // The --temp-dir option. - if (!TempDirname.empty()) { - tempDir = TempDirname; - } - // GCC 4.5-style -save-temps handling. - else if (SaveTemps == SaveTempsEnum::Unset) { - tempDir = sys::Path::GetTemporaryDirectory(); - return 0; - } - else if (SaveTemps == SaveTempsEnum::Obj && !OutputFilename.empty()) { - tempDir = sys::path::parent_path(OutputFilename); - } - else { - // SaveTemps == Cwd --> use current dir (leave tempDir empty). - return 0; - } - - bool Exists; - if (llvm::sys::fs::exists(tempDir.str(), Exists) || !Exists) { - std::string ErrMsg; - if (tempDir.createDirectoryOnDisk(true, &ErrMsg)) { - PrintError(ErrMsg); - return 1; - } - } - - return 0; - } - - /// BuildTargets - A small wrapper for CompilationGraph::Build. Returns - /// non-zero value in case of error. - int BuildTargets(CompilationGraph& graph, const LanguageMap& langMap) { - int ret; - sys::Path tempDir; - bool toDelete = (SaveTemps == SaveTempsEnum::Unset); - - if (int ret = GetTempDir(tempDir)) - return ret; - - ret = graph.Build(tempDir, langMap); - - if (toDelete) - tempDir.eraseFromDisk(true); - - return ret; - } -} - -namespace llvmc { - -// Used to implement -time option. External linkage is intentional. -void AppendToGlobalTimeLog(const std::string& cmd, double time) { - *GlobalTimeLog << "# " << cmd << ' ' << time << '\n'; -} - -// Sometimes user code wants to access the argv[0] value. -const char* ProgramName; - -int Main(int argc, char** argv) { - int ret = 0; - LanguageMap langMap; - CompilationGraph graph; - - ProgramName = argv[0]; - - cl::ParseCommandLineOptions - (argc, argv, - /* Overview = */ "LLVM Compiler Driver (Work In Progress)", - /* ReadResponseFiles = */ false); - - if (int ret = autogenerated::RunInitialization(langMap, graph)) - return ret; - - if (CheckGraph) { - ret = graph.Check(); - if (!ret) - llvm::errs() << "check-graph: no errors found.\n"; - - return ret; - } - - if (ViewGraph) { - graph.viewGraph(); - if (!WriteGraph) - return 0; - } - - if (WriteGraph) { - const std::string& Out = (OutputFilename.empty() - ? std::string("compilation-graph.dot") - : OutputFilename); - return graph.writeGraph(Out); - } - - if (Time) { - GlobalTimeLog = new std::stringstream; - GlobalTimeLog->precision(2); - } - - ret = BuildTargets(graph, langMap); - - if (Time) { - llvm::errs() << GlobalTimeLog->str(); - delete GlobalTimeLog; - } - - return ret; -} - -} // end namespace llvmc diff --git a/lib/CompilerDriver/Makefile b/lib/CompilerDriver/Makefile deleted file mode 100644 index 10cfa4f02923..000000000000 --- a/lib/CompilerDriver/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -##===- lib/CompilerDriver/Makefile -------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open -# Source License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. - -# We don't want this library to appear in `llvm-config --libs` output, so its -# name doesn't start with "LLVM" and NO_LLVM_CONFIG is set. - -LIBRARYNAME = CompilerDriver -LINK_COMPONENTS = support -NO_LLVM_CONFIG = 1 - - -include $(LEVEL)/Makefile.common diff --git a/lib/CompilerDriver/Tool.cpp b/lib/CompilerDriver/Tool.cpp deleted file mode 100644 index 876759aa72b0..000000000000 --- a/lib/CompilerDriver/Tool.cpp +++ /dev/null @@ -1,95 +0,0 @@ -//===--- Tool.cpp - The LLVM Compiler Driver --------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Tool base class - implementation details. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CompilerDriver/BuiltinOptions.h" -#include "llvm/CompilerDriver/Tool.h" - -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/Path.h" - -#include - -using namespace llvm; -using namespace llvmc; - -namespace { - sys::Path MakeTempFile(const sys::Path& TempDir, const std::string& BaseName, - const std::string& Suffix) { - sys::Path Out; - - // Make sure we don't end up with path names like '/file.o' if the - // TempDir is empty. - if (TempDir.empty()) { - Out.set(BaseName); - } - else { - Out = TempDir; - Out.appendComponent(BaseName); - } - Out.appendSuffix(Suffix); - // NOTE: makeUnique always *creates* a unique temporary file, - // which is good, since there will be no races. However, some - // tools do not like it when the output file already exists, so - // they need to be placated with -f or something like that. - Out.makeUnique(true, NULL); - return Out; - } -} - -sys::Path Tool::OutFilename(const sys::Path& In, - const sys::Path& TempDir, - bool StopCompilation, - const char* OutputSuffix) const { - sys::Path Out; - - if (StopCompilation) { - if (!OutputFilename.empty()) { - Out.set(OutputFilename); - } - else if (IsJoin()) { - Out.set("a"); - Out.appendSuffix(OutputSuffix); - } - else { - Out.set(sys::path::stem(In.str())); - Out.appendSuffix(OutputSuffix); - } - } - else { - if (IsJoin()) - Out = MakeTempFile(TempDir, "tmp", OutputSuffix); - else - Out = MakeTempFile(TempDir, sys::path::stem(In.str()), OutputSuffix); - } - return Out; -} - -namespace { - template - bool CompareFirst (std::pair p1, std::pair p2) { - return std::less()(p1.first, p2.first); - } -} - -StrVector Tool::SortArgs(ArgsVector& Args) const { - StrVector Out; - - // HACK: this won't be needed when we'll migrate away from CommandLine. - std::stable_sort(Args.begin(), Args.end(), - &CompareFirst); - for (ArgsVector::iterator B = Args.begin(), E = Args.end(); B != E; ++B) { - Out.push_back(B->second); - } - - return Out; -} diff --git a/lib/DebugInfo/CMakeLists.txt b/lib/DebugInfo/CMakeLists.txt new file mode 100644 index 000000000000..fdffcb6a77c6 --- /dev/null +++ b/lib/DebugInfo/CMakeLists.txt @@ -0,0 +1,16 @@ +add_llvm_library(LLVMDebugInfo + DIContext.cpp + DWARFAbbreviationDeclaration.cpp + DWARFCompileUnit.cpp + DWARFContext.cpp + DWARFDebugAbbrev.cpp + DWARFDebugArangeSet.cpp + DWARFDebugAranges.cpp + DWARFDebugInfoEntry.cpp + DWARFDebugLine.cpp + DWARFFormValue.cpp + ) + +add_llvm_library_dependencies(LLVMDebugInfo + LLVMSupport + ) diff --git a/lib/DebugInfo/DIContext.cpp b/lib/DebugInfo/DIContext.cpp new file mode 100644 index 000000000000..e2fd55fd6ef8 --- /dev/null +++ b/lib/DebugInfo/DIContext.cpp @@ -0,0 +1,24 @@ +//===-- DIContext.cpp -----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/DIContext.h" +#include "DWARFContext.h" +using namespace llvm; + +DIContext::~DIContext() {} + +DIContext *DIContext::getDWARFContext(bool isLittleEndian, + StringRef infoSection, + StringRef abbrevSection, + StringRef aRangeSection, + StringRef lineSection, + StringRef stringSection) { + return new DWARFContextInMemory(isLittleEndian, infoSection, abbrevSection, + aRangeSection, lineSection, stringSection); +} diff --git a/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp b/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp new file mode 100644 index 000000000000..0df692c3a3b7 --- /dev/null +++ b/lib/DebugInfo/DWARFAbbreviationDeclaration.cpp @@ -0,0 +1,83 @@ +//===-- DWARFAbbreviationDeclaration.cpp ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFAbbreviationDeclaration.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; +using namespace dwarf; + +bool +DWARFAbbreviationDeclaration::extract(DataExtractor data, uint32_t* offset_ptr){ + return extract(data, offset_ptr, data.getULEB128(offset_ptr)); +} + +bool +DWARFAbbreviationDeclaration::extract(DataExtractor data, uint32_t* offset_ptr, + uint32_t code) { + Code = code; + Attributes.clear(); + if (Code) { + Tag = data.getULEB128(offset_ptr); + HasChildren = data.getU8(offset_ptr); + + while (data.isValidOffset(*offset_ptr)) { + uint16_t attr = data.getULEB128(offset_ptr); + uint16_t form = data.getULEB128(offset_ptr); + + if (attr && form) + Attributes.push_back(DWARFAttribute(attr, form)); + else + break; + } + + return Tag != 0; + } else { + Tag = 0; + HasChildren = false; + } + + return false; +} + +void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const { + const char *tagString = TagString(getTag()); + OS << '[' << getCode() << "] "; + if (tagString) + OS << tagString; + else + OS << format("DW_TAG_Unknown_%x", getTag()); + OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n'; + for (unsigned i = 0, e = Attributes.size(); i != e; ++i) { + OS << '\t'; + const char *attrString = AttributeString(Attributes[i].getAttribute()); + if (attrString) + OS << attrString; + else + OS << format("DW_AT_Unknown_%x", Attributes[i].getAttribute()); + OS << '\t'; + const char *formString = FormEncodingString(Attributes[i].getForm()); + if (formString) + OS << formString; + else + OS << format("DW_FORM_Unknown_%x", Attributes[i].getForm()); + OS << '\n'; + } + OS << '\n'; +} + +uint32_t +DWARFAbbreviationDeclaration::findAttributeIndex(uint16_t attr) const { + for (uint32_t i = 0, e = Attributes.size(); i != e; ++i) { + if (Attributes[i].getAttribute() == attr) + return i; + } + return -1U; +} diff --git a/lib/DebugInfo/DWARFAbbreviationDeclaration.h b/lib/DebugInfo/DWARFAbbreviationDeclaration.h new file mode 100644 index 000000000000..2463a3cc0494 --- /dev/null +++ b/lib/DebugInfo/DWARFAbbreviationDeclaration.h @@ -0,0 +1,54 @@ +//===-- DWARFAbbreviationDeclaration.h --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H +#define LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H + +#include "DWARFAttribute.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DataExtractor.h" + +namespace llvm { + +class raw_ostream; + +class DWARFAbbreviationDeclaration { + uint32_t Code; + uint32_t Tag; + bool HasChildren; + SmallVector Attributes; +public: + enum { InvalidCode = 0 }; + DWARFAbbreviationDeclaration() + : Code(InvalidCode), Tag(0), HasChildren(0) {} + + uint32_t getCode() const { return Code; } + uint32_t getTag() const { return Tag; } + bool hasChildren() const { return HasChildren; } + uint32_t getNumAttributes() const { return Attributes.size(); } + uint16_t getAttrByIndex(uint32_t idx) const { + return Attributes.size() > idx ? Attributes[idx].getAttribute() : 0; + } + uint16_t getFormByIndex(uint32_t idx) const { + return Attributes.size() > idx ? Attributes[idx].getForm() : 0; + } + + uint32_t findAttributeIndex(uint16_t attr) const; + bool extract(DataExtractor data, uint32_t* offset_ptr); + bool extract(DataExtractor data, uint32_t* offset_ptr, uint32_t code); + bool isValid() const { return Code != 0 && Tag != 0; } + void dump(raw_ostream &OS) const; + const SmallVectorImpl &getAttributes() const { + return Attributes; + } +}; + +} + +#endif diff --git a/lib/DebugInfo/DWARFAttribute.h b/lib/DebugInfo/DWARFAttribute.h new file mode 100644 index 000000000000..6f49b637c6a6 --- /dev/null +++ b/lib/DebugInfo/DWARFAttribute.h @@ -0,0 +1,30 @@ +//===-- DWARFAttribute.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARFATTRIBUTE_H +#define LLVM_DEBUGINFO_DWARFATTRIBUTE_H + +#include "llvm/Support/DataTypes.h" + +namespace llvm { + +class DWARFAttribute { + uint16_t Attribute; + uint16_t Form; + public: + DWARFAttribute(uint16_t attr, uint16_t form) + : Attribute(attr), Form(form) {} + + uint16_t getAttribute() const { return Attribute; } + uint16_t getForm() const { return Form; } +}; + +} + +#endif diff --git a/lib/DebugInfo/DWARFCompileUnit.cpp b/lib/DebugInfo/DWARFCompileUnit.cpp new file mode 100644 index 000000000000..24bf97ff608a --- /dev/null +++ b/lib/DebugInfo/DWARFCompileUnit.cpp @@ -0,0 +1,238 @@ +//===-- DWARFCompileUnit.cpp ----------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFCompileUnit.h" +#include "DWARFContext.h" +#include "DWARFFormValue.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; +using namespace dwarf; + +DataExtractor DWARFCompileUnit::getDebugInfoExtractor() const { + return DataExtractor(Context.getInfoSection(), + Context.isLittleEndian(), getAddressByteSize()); +} + +bool DWARFCompileUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) { + clear(); + + Offset = *offset_ptr; + + if (debug_info.isValidOffset(*offset_ptr)) { + uint64_t abbrOffset; + const DWARFDebugAbbrev *abbr = Context.getDebugAbbrev(); + Length = debug_info.getU32(offset_ptr); + Version = debug_info.getU16(offset_ptr); + abbrOffset = debug_info.getU32(offset_ptr); + AddrSize = debug_info.getU8(offset_ptr); + + bool lengthOK = debug_info.isValidOffset(getNextCompileUnitOffset()-1); + bool versionOK = DWARFContext::isSupportedVersion(Version); + bool abbrOffsetOK = Context.getAbbrevSection().size() > abbrOffset; + bool addrSizeOK = AddrSize == 4 || AddrSize == 8; + + if (lengthOK && versionOK && addrSizeOK && abbrOffsetOK && abbr != NULL) { + Abbrevs = abbr->getAbbreviationDeclarationSet(abbrOffset); + return true; + } + + // reset the offset to where we tried to parse from if anything went wrong + *offset_ptr = Offset; + } + + return false; +} + +uint32_t +DWARFCompileUnit::extract(uint32_t offset, DataExtractor debug_info_data, + const DWARFAbbreviationDeclarationSet *abbrevs) { + clear(); + + Offset = offset; + + if (debug_info_data.isValidOffset(offset)) { + Length = debug_info_data.getU32(&offset); + Version = debug_info_data.getU16(&offset); + bool abbrevsOK = debug_info_data.getU32(&offset) == abbrevs->getOffset(); + Abbrevs = abbrevs; + AddrSize = debug_info_data.getU8 (&offset); + + bool versionOK = DWARFContext::isSupportedVersion(Version); + bool addrSizeOK = AddrSize == 4 || AddrSize == 8; + + if (versionOK && addrSizeOK && abbrevsOK && + debug_info_data.isValidOffset(offset)) + return offset; + } + return 0; +} + +void DWARFCompileUnit::clear() { + Offset = 0; + Length = 0; + Version = 0; + Abbrevs = 0; + AddrSize = 0; + BaseAddr = 0; + DieArray.clear(); +} + +void DWARFCompileUnit::dump(raw_ostream &OS) { + OS << format("0x%08x", Offset) << ": Compile Unit:" + << " length = " << format("0x%08x", Length) + << " version = " << format("0x%04x", Version) + << " abbr_offset = " << format("0x%04x", Abbrevs->getOffset()) + << " addr_size = " << format("0x%02x", AddrSize) + << " (next CU at " << format("0x%08x", getNextCompileUnitOffset()) + << ")\n"; + + getCompileUnitDIE(false)->dump(OS, this, -1U); +} + +void DWARFCompileUnit::setDIERelations() { + if (DieArray.empty()) + return; + DWARFDebugInfoEntryMinimal *die_array_begin = &DieArray.front(); + DWARFDebugInfoEntryMinimal *die_array_end = &DieArray.back(); + DWARFDebugInfoEntryMinimal *curr_die; + // We purposely are skipping the last element in the array in the loop below + // so that we can always have a valid next item + for (curr_die = die_array_begin; curr_die < die_array_end; ++curr_die) { + // Since our loop doesn't include the last element, we can always + // safely access the next die in the array. + DWARFDebugInfoEntryMinimal *next_die = curr_die + 1; + + const DWARFAbbreviationDeclaration *curr_die_abbrev = + curr_die->getAbbreviationDeclarationPtr(); + + if (curr_die_abbrev) { + // Normal DIE + if (curr_die_abbrev->hasChildren()) + next_die->setParent(curr_die); + else + curr_die->setSibling(next_die); + } else { + // NULL DIE that terminates a sibling chain + DWARFDebugInfoEntryMinimal *parent = curr_die->getParent(); + if (parent) + parent->setSibling(next_die); + } + } + + // Since we skipped the last element, we need to fix it up! + if (die_array_begin < die_array_end) + curr_die->setParent(die_array_begin); +} + +size_t DWARFCompileUnit::extractDIEsIfNeeded(bool cu_die_only) { + const size_t initial_die_array_size = DieArray.size(); + if ((cu_die_only && initial_die_array_size > 0) || + initial_die_array_size > 1) + return 0; // Already parsed + + // Set the offset to that of the first DIE and calculate the start of the + // next compilation unit header. + uint32_t offset = getFirstDIEOffset(); + uint32_t next_cu_offset = getNextCompileUnitOffset(); + + DWARFDebugInfoEntryMinimal die; + // Keep a flat array of the DIE for binary lookup by DIE offset + uint32_t depth = 0; + // We are in our compile unit, parse starting at the offset + // we were told to parse + + const uint8_t *fixed_form_sizes = + DWARFFormValue::getFixedFormSizesForAddressSize(getAddressByteSize()); + + while (offset < next_cu_offset && + die.extractFast(this, fixed_form_sizes, &offset)) { + + if (depth == 0) { + uint64_t base_addr = + die.getAttributeValueAsUnsigned(this, DW_AT_low_pc, -1U); + if (base_addr == -1U) + base_addr = die.getAttributeValueAsUnsigned(this, DW_AT_entry_pc, 0); + setBaseAddress(base_addr); + } + + if (cu_die_only) { + addDIE(die); + return 1; + } + else if (depth == 0 && initial_die_array_size == 1) { + // Don't append the CU die as we already did that + } else { + addDIE (die); + } + + const DWARFAbbreviationDeclaration *abbrDecl = + die.getAbbreviationDeclarationPtr(); + if (abbrDecl) { + // Normal DIE + if (abbrDecl->hasChildren()) + ++depth; + } else { + // NULL DIE. + if (depth > 0) + --depth; + if (depth == 0) + break; // We are done with this compile unit! + } + + } + + // Give a little bit of info if we encounter corrupt DWARF (our offset + // should always terminate at or before the start of the next compilation + // unit header). + if (offset > next_cu_offset) { + fprintf (stderr, "warning: DWARF compile unit extends beyond its bounds cu 0x%8.8x at 0x%8.8x'\n", getOffset(), offset); + } + + setDIERelations(); + return DieArray.size(); +} + +void DWARFCompileUnit::clearDIEs(bool keep_compile_unit_die) { + if (DieArray.size() > 1) { + // std::vectors never get any smaller when resized to a smaller size, + // or when clear() or erase() are called, the size will report that it + // is smaller, but the memory allocated remains intact (call capacity() + // to see this). So we need to create a temporary vector and swap the + // contents which will cause just the internal pointers to be swapped + // so that when "tmp_array" goes out of scope, it will destroy the + // contents. + + // Save at least the compile unit DIE + std::vector tmpArray; + DieArray.swap(tmpArray); + if (keep_compile_unit_die) + DieArray.push_back(tmpArray.front()); + } +} + +void +DWARFCompileUnit::buildAddressRangeTable(DWARFDebugAranges *debug_aranges, + bool clear_dies_if_already_not_parsed){ + // This function is usually called if there in no .debug_aranges section + // in order to produce a compile unit level set of address ranges that + // is accurate. If the DIEs weren't parsed, then we don't want all dies for + // all compile units to stay loaded when they weren't needed. So we can end + // up parsing the DWARF and then throwing them all away to keep memory usage + // down. + const bool clear_dies = extractDIEsIfNeeded(false) > 1; + + DieArray[0].buildAddressRangeTable(this, debug_aranges); + + // Keep memory down by clearing DIEs if this generate function + // caused them to be parsed. + if (clear_dies) + clearDIEs(true); +} diff --git a/lib/DebugInfo/DWARFCompileUnit.h b/lib/DebugInfo/DWARFCompileUnit.h new file mode 100644 index 000000000000..d9167292a9df --- /dev/null +++ b/lib/DebugInfo/DWARFCompileUnit.h @@ -0,0 +1,111 @@ +//===-- DWARFCompileUnit.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H +#define LLVM_DEBUGINFO_DWARFCOMPILEUNIT_H + +#include "DWARFDebugAbbrev.h" +#include "DWARFDebugInfoEntry.h" +#include + +namespace llvm { + +class DWARFContext; +class raw_ostream; + +class DWARFCompileUnit { + DWARFContext &Context; + + uint32_t Offset; + uint32_t Length; + uint16_t Version; + const DWARFAbbreviationDeclarationSet *Abbrevs; + uint8_t AddrSize; + uint64_t BaseAddr; + // The compile unit debug information entry item. + std::vector DieArray; +public: + DWARFCompileUnit(DWARFContext &context) : Context(context) { + clear(); + } + + DWARFContext &getContext() const { return Context; } + DataExtractor getDebugInfoExtractor() const; + + bool extract(DataExtractor debug_info, uint32_t* offset_ptr); + uint32_t extract(uint32_t offset, DataExtractor debug_info_data, + const DWARFAbbreviationDeclarationSet *abbrevs); + + /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it + /// hasn't already been done. + size_t extractDIEsIfNeeded(bool cu_die_only); + void clear(); + void dump(raw_ostream &OS); + uint32_t getOffset() const { return Offset; } + /// Size in bytes of the compile unit header. + uint32_t getSize() const { return 11; } + bool containsDIEOffset(uint32_t die_offset) const { + return die_offset >= getFirstDIEOffset() && + die_offset < getNextCompileUnitOffset(); + } + uint32_t getFirstDIEOffset() const { return Offset + getSize(); } + uint32_t getNextCompileUnitOffset() const { return Offset + Length + 4; } + /// Size in bytes of the .debug_info data associated with this compile unit. + size_t getDebugInfoSize() const { return Length + 4 - getSize(); } + uint32_t getLength() const { return Length; } + uint16_t getVersion() const { return Version; } + const DWARFAbbreviationDeclarationSet *getAbbreviations() const { + return Abbrevs; + } + uint8_t getAddressByteSize() const { return AddrSize; } + uint64_t getBaseAddress() const { return BaseAddr; } + + void setBaseAddress(uint64_t base_addr) { + BaseAddr = base_addr; + } + + const DWARFDebugInfoEntryMinimal * + getCompileUnitDIE(bool extract_cu_die_only = true) { + extractDIEsIfNeeded(extract_cu_die_only); + if (DieArray.empty()) + return NULL; + return &DieArray[0]; + } + + /// setDIERelations - We read in all of the DIE entries into our flat list + /// of DIE entries and now we need to go back through all of them and set the + /// parent, sibling and child pointers for quick DIE navigation. + void setDIERelations(); + + void addDIE(DWARFDebugInfoEntryMinimal &die) { + // The average bytes per DIE entry has been seen to be + // around 14-20 so lets pre-reserve the needed memory for + // our DIE entries accordingly. Search forward for "Compute + // average bytes per DIE" to see #if'ed out code that does + // that determination. + + // Only reserve the memory if we are adding children of + // the main compile unit DIE. The compile unit DIE is always + // the first entry, so if our size is 1, then we are adding + // the first compile unit child DIE and should reserve + // the memory. + if (DieArray.empty()) + DieArray.reserve(getDebugInfoSize() / 14); + DieArray.push_back(die); + } + + void clearDIEs(bool keep_compile_unit_die); + + void buildAddressRangeTable(DWARFDebugAranges *debug_aranges, + bool clear_dies_if_already_not_parsed); +}; + +} + +#endif diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp new file mode 100644 index 000000000000..e1ac398b1011 --- /dev/null +++ b/lib/DebugInfo/DWARFContext.cpp @@ -0,0 +1,167 @@ +//===-- DWARFContext.cpp --------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFContext.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +#include +using namespace llvm; +using namespace dwarf; + +void DWARFContext::dump(raw_ostream &OS) { + OS << ".debug_abbrev contents:\n"; + getDebugAbbrev()->dump(OS); + + OS << "\n.debug_info contents:\n"; + for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) + getCompileUnitAtIndex(i)->dump(OS); + + OS << "\n.debug_aranges contents:\n"; + DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0); + uint32_t offset = 0; + DWARFDebugArangeSet set; + while (set.extract(arangesData, &offset)) + set.dump(OS); + + OS << "\n.debug_lines contents:\n"; + for (unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) { + DWARFCompileUnit *cu = getCompileUnitAtIndex(i); + unsigned stmtOffset = + cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list, + -1U); + if (stmtOffset != -1U) { + DataExtractor lineData(getLineSection(), isLittleEndian(), + cu->getAddressByteSize()); + DWARFDebugLine::DumpingState state(OS); + DWARFDebugLine::parseStatementTable(lineData, &stmtOffset, state); + } + } + + OS << "\n.debug_str contents:\n"; + DataExtractor strData(getStringSection(), isLittleEndian(), 0); + offset = 0; + uint32_t lastOffset = 0; + while (const char *s = strData.getCStr(&offset)) { + OS << format("0x%8.8x: \"%s\"\n", lastOffset, s); + lastOffset = offset; + } +} + +const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() { + if (Abbrev) + return Abbrev.get(); + + DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0); + + Abbrev.reset(new DWARFDebugAbbrev()); + Abbrev->parse(abbrData); + return Abbrev.get(); +} + +const DWARFDebugAranges *DWARFContext::getDebugAranges() { + if (Aranges) + return Aranges.get(); + + DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0); + + Aranges.reset(new DWARFDebugAranges()); + Aranges->extract(arangesData); + if (Aranges->isEmpty()) // No aranges in file, generate them from the DIEs. + Aranges->generate(this); + return Aranges.get(); +} + +const DWARFDebugLine::LineTable * +DWARFContext::getLineTableForCompileUnit(DWARFCompileUnit *cu) { + if (!Line) + Line.reset(new DWARFDebugLine()); + + unsigned stmtOffset = + cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_stmt_list, + -1U); + if (stmtOffset == -1U) + return 0; // No line table for this compile unit. + + // See if the line table is cached. + if (const DWARFDebugLine::LineTable *lt = Line->getLineTable(stmtOffset)) + return lt; + + // We have to parse it first. + DataExtractor lineData(getLineSection(), isLittleEndian(), + cu->getAddressByteSize()); + return Line->getOrParseLineTable(lineData, stmtOffset); +} + +void DWARFContext::parseCompileUnits() { + uint32_t offset = 0; + const DataExtractor &debug_info_data = DataExtractor(getInfoSection(), + isLittleEndian(), 0); + while (debug_info_data.isValidOffset(offset)) { + CUs.push_back(DWARFCompileUnit(*this)); + if (!CUs.back().extract(debug_info_data, &offset)) { + CUs.pop_back(); + break; + } + + offset = CUs.back().getNextCompileUnitOffset(); + } +} + +namespace { + struct OffsetComparator { + bool operator()(const DWARFCompileUnit &LHS, + const DWARFCompileUnit &RHS) const { + return LHS.getOffset() < RHS.getOffset(); + } + bool operator()(const DWARFCompileUnit &LHS, uint32_t RHS) const { + return LHS.getOffset() < RHS; + } + bool operator()(uint32_t LHS, const DWARFCompileUnit &RHS) const { + return LHS < RHS.getOffset(); + } + }; +} + +DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t offset) { + if (CUs.empty()) + parseCompileUnits(); + + DWARFCompileUnit *i = std::lower_bound(CUs.begin(), CUs.end(), offset, + OffsetComparator()); + if (i != CUs.end()) + return &*i; + return 0; +} + +DILineInfo DWARFContext::getLineInfoForAddress(uint64_t address) { + // First, get the offset of the compile unit. + uint32_t cuOffset = getDebugAranges()->findAddress(address); + // Retrieve the compile unit. + DWARFCompileUnit *cu = getCompileUnitForOffset(cuOffset); + if (!cu) + return DILineInfo("", 0, 0); + // Get the line table for this compile unit. + const DWARFDebugLine::LineTable *lineTable = getLineTableForCompileUnit(cu); + if (!lineTable) + return DILineInfo("", 0, 0); + // Get the index of the row we're looking for in the line table. + uint64_t hiPC = + cu->getCompileUnitDIE()->getAttributeValueAsUnsigned(cu, DW_AT_high_pc, + -1ULL); + uint32_t rowIndex = lineTable->lookupAddress(address, hiPC); + if (rowIndex == -1U) + return DILineInfo("", 0, 0); + + // From here, contruct the DILineInfo. + const DWARFDebugLine::Row &row = lineTable->Rows[rowIndex]; + const std::string &fileName = lineTable->Prologue.FileNames[row.File-1].Name; + + return DILineInfo(fileName.c_str(), row.Line, row.Column); +} diff --git a/lib/DebugInfo/DWARFContext.h b/lib/DebugInfo/DWARFContext.h new file mode 100644 index 000000000000..746a4639f277 --- /dev/null +++ b/lib/DebugInfo/DWARFContext.h @@ -0,0 +1,118 @@ +//===-- DWARFContext.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===/ + +#ifndef LLVM_DEBUGINFO_DWARFCONTEXT_H +#define LLVM_DEBUGINFO_DWARFCONTEXT_H + +#include "DWARFCompileUnit.h" +#include "DWARFDebugAranges.h" +#include "DWARFDebugLine.h" +#include "llvm/DebugInfo/DIContext.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallVector.h" + +namespace llvm { + +/// DWARFContext +/// This data structure is the top level entity that deals with dwarf debug +/// information parsing. The actual data is supplied through pure virtual +/// methods that a concrete implementation provides. +class DWARFContext : public DIContext { + bool IsLittleEndian; + + SmallVector CUs; + OwningPtr Abbrev; + OwningPtr Aranges; + OwningPtr Line; + + DWARFContext(DWARFContext &); // = delete + DWARFContext &operator=(DWARFContext &); // = delete + + /// Read compile units from the debug_info section and store them in CUs. + void parseCompileUnits(); +protected: + DWARFContext(bool isLittleEndian) : IsLittleEndian(isLittleEndian) {} +public: + virtual void dump(raw_ostream &OS); + /// Get the number of compile units in this context. + unsigned getNumCompileUnits() { + if (CUs.empty()) + parseCompileUnits(); + return CUs.size(); + } + /// Get the compile unit at the specified index for this compile unit. + DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) { + if (CUs.empty()) + parseCompileUnits(); + return &CUs[index]; + } + + /// Return the compile unit that includes an offset (relative to .debug_info). + DWARFCompileUnit *getCompileUnitForOffset(uint32_t offset); + + /// Get a pointer to the parsed DebugAbbrev object. + const DWARFDebugAbbrev *getDebugAbbrev(); + + /// Get a pointer to the parsed DebugAranges object. + const DWARFDebugAranges *getDebugAranges(); + + /// Get a pointer to a parsed line table corresponding to a compile unit. + const DWARFDebugLine::LineTable * + getLineTableForCompileUnit(DWARFCompileUnit *cu); + + virtual DILineInfo getLineInfoForAddress(uint64_t address); + + bool isLittleEndian() const { return IsLittleEndian; } + + virtual StringRef getInfoSection() = 0; + virtual StringRef getAbbrevSection() = 0; + virtual StringRef getARangeSection() = 0; + virtual StringRef getLineSection() = 0; + virtual StringRef getStringSection() = 0; + + static bool isSupportedVersion(unsigned version) { + return version == 2 || version == 3; + } +}; + + +/// DWARFContextInMemory is the simplest possible implementation of a +/// DWARFContext. It assumes all content is available in memory and stores +/// pointers to it. +class DWARFContextInMemory : public DWARFContext { + StringRef InfoSection; + StringRef AbbrevSection; + StringRef ARangeSection; + StringRef LineSection; + StringRef StringSection; +public: + DWARFContextInMemory(bool isLittleEndian, + StringRef infoSection, + StringRef abbrevSection, + StringRef aRangeSection, + StringRef lineSection, + StringRef stringSection) + : DWARFContext(isLittleEndian), + InfoSection(infoSection), + AbbrevSection(abbrevSection), + ARangeSection(aRangeSection), + LineSection(lineSection), + StringSection(stringSection) + {} + + virtual StringRef getInfoSection() { return InfoSection; } + virtual StringRef getAbbrevSection() { return AbbrevSection; } + virtual StringRef getARangeSection() { return ARangeSection; } + virtual StringRef getLineSection() { return LineSection; } + virtual StringRef getStringSection() { return StringSection; } +}; + +} + +#endif diff --git a/lib/DebugInfo/DWARFDebugAbbrev.cpp b/lib/DebugInfo/DWARFDebugAbbrev.cpp new file mode 100644 index 000000000000..a11ae3f2908e --- /dev/null +++ b/lib/DebugInfo/DWARFDebugAbbrev.cpp @@ -0,0 +1,106 @@ +//===-- DWARFDebugAbbrev.cpp ----------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFDebugAbbrev.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +bool DWARFAbbreviationDeclarationSet::extract(DataExtractor data, + uint32_t* offset_ptr) { + const uint32_t beginOffset = *offset_ptr; + Offset = beginOffset; + clear(); + DWARFAbbreviationDeclaration abbrevDeclaration; + uint32_t prevAbbrAode = 0; + while (abbrevDeclaration.extract(data, offset_ptr)) { + Decls.push_back(abbrevDeclaration); + if (IdxOffset == 0) { + IdxOffset = abbrevDeclaration.getCode(); + } else { + if (prevAbbrAode + 1 != abbrevDeclaration.getCode()) + IdxOffset = UINT32_MAX;// Out of order indexes, we can't do O(1) lookups + } + prevAbbrAode = abbrevDeclaration.getCode(); + } + return beginOffset != *offset_ptr; +} + +void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const { + for (unsigned i = 0, e = Decls.size(); i != e; ++i) + Decls[i].dump(OS); +} + +const DWARFAbbreviationDeclaration* +DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(uint32_t abbrCode) + const { + if (IdxOffset == UINT32_MAX) { + DWARFAbbreviationDeclarationCollConstIter pos; + DWARFAbbreviationDeclarationCollConstIter end = Decls.end(); + for (pos = Decls.begin(); pos != end; ++pos) { + if (pos->getCode() == abbrCode) + return &(*pos); + } + } else { + uint32_t idx = abbrCode - IdxOffset; + if (idx < Decls.size()) + return &Decls[idx]; + } + return NULL; +} + +DWARFDebugAbbrev::DWARFDebugAbbrev() : + AbbrevCollMap(), + PrevAbbrOffsetPos(AbbrevCollMap.end()) {} + + +void DWARFDebugAbbrev::parse(DataExtractor data) { + uint32_t offset = 0; + + while (data.isValidOffset(offset)) { + uint32_t initial_cu_offset = offset; + DWARFAbbreviationDeclarationSet abbrevDeclSet; + + if (abbrevDeclSet.extract(data, &offset)) + AbbrevCollMap[initial_cu_offset] = abbrevDeclSet; + else + break; + } + PrevAbbrOffsetPos = AbbrevCollMap.end(); +} + +void DWARFDebugAbbrev::dump(raw_ostream &OS) const { + if (AbbrevCollMap.empty()) { + OS << "< EMPTY >\n"; + return; + } + + DWARFAbbreviationDeclarationCollMapConstIter pos; + for (pos = AbbrevCollMap.begin(); pos != AbbrevCollMap.end(); ++pos) { + OS << format("Abbrev table for offset: 0x%8.8x\n", pos->first); + pos->second.dump(OS); + } +} + +const DWARFAbbreviationDeclarationSet* +DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t cu_abbr_offset) const { + DWARFAbbreviationDeclarationCollMapConstIter end = AbbrevCollMap.end(); + DWARFAbbreviationDeclarationCollMapConstIter pos; + if (PrevAbbrOffsetPos != end && + PrevAbbrOffsetPos->first == cu_abbr_offset) { + return &(PrevAbbrOffsetPos->second); + } else { + pos = AbbrevCollMap.find(cu_abbr_offset); + PrevAbbrOffsetPos = pos; + } + + if (pos != AbbrevCollMap.end()) + return &(pos->second); + return NULL; +} diff --git a/lib/DebugInfo/DWARFDebugAbbrev.h b/lib/DebugInfo/DWARFDebugAbbrev.h new file mode 100644 index 000000000000..03189b132127 --- /dev/null +++ b/lib/DebugInfo/DWARFDebugAbbrev.h @@ -0,0 +1,73 @@ +//===-- DWARFDebugAbbrev.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARFDEBUGABBREV_H +#define LLVM_DEBUGINFO_DWARFDEBUGABBREV_H + +#include "DWARFAbbreviationDeclaration.h" +#include +#include +#include + +namespace llvm { + +typedef std::vector + DWARFAbbreviationDeclarationColl; +typedef DWARFAbbreviationDeclarationColl::iterator + DWARFAbbreviationDeclarationCollIter; +typedef DWARFAbbreviationDeclarationColl::const_iterator + DWARFAbbreviationDeclarationCollConstIter; + +class DWARFAbbreviationDeclarationSet { + uint64_t Offset; + uint32_t IdxOffset; + std::vector Decls; + public: + DWARFAbbreviationDeclarationSet() + : Offset(0), IdxOffset(0) {} + + DWARFAbbreviationDeclarationSet(uint64_t offset, uint32_t idxOffset) + : Offset(offset), IdxOffset(idxOffset) {} + + void clear() { + IdxOffset = 0; + Decls.clear(); + } + uint64_t getOffset() const { return Offset; } + void dump(raw_ostream &OS) const; + bool extract(DataExtractor data, uint32_t* offset_ptr); + + const DWARFAbbreviationDeclaration * + getAbbreviationDeclaration(uint32_t abbrCode) const; +}; + +class DWARFDebugAbbrev { +public: + typedef std::map + DWARFAbbreviationDeclarationCollMap; + typedef DWARFAbbreviationDeclarationCollMap::iterator + DWARFAbbreviationDeclarationCollMapIter; + typedef DWARFAbbreviationDeclarationCollMap::const_iterator + DWARFAbbreviationDeclarationCollMapConstIter; + +private: + DWARFAbbreviationDeclarationCollMap AbbrevCollMap; + mutable DWARFAbbreviationDeclarationCollMapConstIter PrevAbbrOffsetPos; + +public: + DWARFDebugAbbrev(); + const DWARFAbbreviationDeclarationSet * + getAbbreviationDeclarationSet(uint64_t cu_abbr_offset) const; + void dump(raw_ostream &OS) const; + void parse(DataExtractor data); +}; + +} + +#endif diff --git a/lib/DebugInfo/DWARFDebugArangeSet.cpp b/lib/DebugInfo/DWARFDebugArangeSet.cpp new file mode 100644 index 000000000000..b0c0354383b9 --- /dev/null +++ b/lib/DebugInfo/DWARFDebugArangeSet.cpp @@ -0,0 +1,150 @@ +//===-- DWARFDebugArangeSet.cpp -------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFDebugArangeSet.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +using namespace llvm; + +void DWARFDebugArangeSet::clear() { + Offset = -1U; + std::memset(&Header, 0, sizeof(Header)); + ArangeDescriptors.clear(); +} + +void DWARFDebugArangeSet::compact() { + if (ArangeDescriptors.empty()) + return; + + // Iterate through all arange descriptors and combine any ranges that + // overlap or have matching boundaries. The ArangeDescriptors are assumed + // to be in ascending order. + uint32_t i = 0; + while (i + 1 < ArangeDescriptors.size()) { + if (ArangeDescriptors[i].getEndAddress() >= ArangeDescriptors[i+1].Address){ + // The current range ends at or exceeds the start of the next address + // range. Compute the max end address between the two and use that to + // make the new length. + const uint64_t max_end_addr = + std::max(ArangeDescriptors[i].getEndAddress(), + ArangeDescriptors[i+1].getEndAddress()); + ArangeDescriptors[i].Length = max_end_addr - ArangeDescriptors[i].Address; + // Now remove the next entry as it was just combined with the previous one + ArangeDescriptors.erase(ArangeDescriptors.begin()+i+1); + } else { + // Discontiguous address range, just proceed to the next one. + ++i; + } + } +} + +bool +DWARFDebugArangeSet::extract(DataExtractor data, uint32_t *offset_ptr) { + if (data.isValidOffset(*offset_ptr)) { + ArangeDescriptors.clear(); + Offset = *offset_ptr; + + // 7.20 Address Range Table + // + // Each set of entries in the table of address ranges contained in + // the .debug_aranges section begins with a header consisting of: a + // 4-byte length containing the length of the set of entries for this + // compilation unit, not including the length field itself; a 2-byte + // version identifier containing the value 2 for DWARF Version 2; a + // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer + // containing the size in bytes of an address (or the offset portion of + // an address for segmented addressing) on the target system; and a + // 1-byte unsigned integer containing the size in bytes of a segment + // descriptor on the target system. This header is followed by a series + // of tuples. Each tuple consists of an address and a length, each in + // the size appropriate for an address on the target architecture. + Header.Length = data.getU32(offset_ptr); + Header.Version = data.getU16(offset_ptr); + Header.CuOffset = data.getU32(offset_ptr); + Header.AddrSize = data.getU8(offset_ptr); + Header.SegSize = data.getU8(offset_ptr); + + // Perform basic validation of the header fields. + if (!data.isValidOffsetForDataOfSize(Offset, Header.Length) || + (Header.AddrSize != 4 && Header.AddrSize != 8)) { + clear(); + return false; + } + + // The first tuple following the header in each set begins at an offset + // that is a multiple of the size of a single tuple (that is, twice the + // size of an address). The header is padded, if necessary, to the + // appropriate boundary. + const uint32_t header_size = *offset_ptr - Offset; + const uint32_t tuple_size = Header.AddrSize * 2; + uint32_t first_tuple_offset = 0; + while (first_tuple_offset < header_size) + first_tuple_offset += tuple_size; + + *offset_ptr = Offset + first_tuple_offset; + + Descriptor arangeDescriptor; + + assert(sizeof(arangeDescriptor.Address) == sizeof(arangeDescriptor.Length)); + assert(sizeof(arangeDescriptor.Address) >= Header.AddrSize); + + while (data.isValidOffset(*offset_ptr)) { + arangeDescriptor.Address = data.getUnsigned(offset_ptr, Header.AddrSize); + arangeDescriptor.Length = data.getUnsigned(offset_ptr, Header.AddrSize); + + // Each set of tuples is terminated by a 0 for the address and 0 + // for the length. + if (arangeDescriptor.Address || arangeDescriptor.Length) + ArangeDescriptors.push_back(arangeDescriptor); + else + break; // We are done if we get a zero address and length + } + + return !ArangeDescriptors.empty(); + } + return false; +} + +void DWARFDebugArangeSet::dump(raw_ostream &OS) const { + OS << format("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, ", + Header.Length, Header.Version) + << format("cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n", + Header.CuOffset, Header.AddrSize, Header.SegSize); + + const uint32_t hex_width = Header.AddrSize * 2; + for (DescriptorConstIter pos = ArangeDescriptors.begin(), + end = ArangeDescriptors.end(); pos != end; ++pos) + OS << format("[0x%*.*llx -", hex_width, hex_width, pos->Address) + << format(" 0x%*.*llx)\n", hex_width, hex_width, pos->getEndAddress()); +} + + +namespace { + class DescriptorContainsAddress { + const uint64_t Address; + public: + DescriptorContainsAddress(uint64_t address) : Address(address) {} + bool operator()(const DWARFDebugArangeSet::Descriptor &desc) const { + return Address >= desc.Address && Address < (desc.Address + desc.Length); + } + }; +} + +uint32_t DWARFDebugArangeSet::findAddress(uint64_t address) const { + DescriptorConstIter end = ArangeDescriptors.end(); + DescriptorConstIter pos = + std::find_if(ArangeDescriptors.begin(), end, // Range + DescriptorContainsAddress(address)); // Predicate + if (pos != end) + return Header.CuOffset; + + return -1U; +} diff --git a/lib/DebugInfo/DWARFDebugArangeSet.h b/lib/DebugInfo/DWARFDebugArangeSet.h new file mode 100644 index 000000000000..9a2a6d0f0037 --- /dev/null +++ b/lib/DebugInfo/DWARFDebugArangeSet.h @@ -0,0 +1,75 @@ +//===-- DWARFDebugArangeSet.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H +#define LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H + +#include "llvm/Support/DataExtractor.h" +#include + +namespace llvm { + +class raw_ostream; + +class DWARFDebugArangeSet { +public: + struct Header { + // The total length of the entries for that set, not including the length + // field itself. + uint32_t Length; + // The offset from the beginning of the .debug_info section of the + // compilation unit entry referenced by the table. + uint32_t CuOffset; + // The DWARF version number. + uint16_t Version; + // The size in bytes of an address on the target architecture. For segmented + // addressing, this is the size of the offset portion of the address. + uint8_t AddrSize; + // The size in bytes of a segment descriptor on the target architecture. + // If the target system uses a flat address space, this value is 0. + uint8_t SegSize; + }; + + struct Descriptor { + uint64_t Address; + uint64_t Length; + uint64_t getEndAddress() const { return Address + Length; } + }; + +private: + typedef std::vector DescriptorColl; + typedef DescriptorColl::iterator DescriptorIter; + typedef DescriptorColl::const_iterator DescriptorConstIter; + + uint32_t Offset; + Header Header; + DescriptorColl ArangeDescriptors; + +public: + DWARFDebugArangeSet() { clear(); } + void clear(); + void compact(); + bool extract(DataExtractor data, uint32_t *offset_ptr); + void dump(raw_ostream &OS) const; + + uint32_t getCompileUnitDIEOffset() const { return Header.CuOffset; } + uint32_t getOffsetOfNextEntry() const { return Offset + Header.Length + 4; } + uint32_t findAddress(uint64_t address) const; + uint32_t getNumDescriptors() const { return ArangeDescriptors.size(); } + const struct Header &getHeader() const { return Header; } + const Descriptor *getDescriptor(uint32_t i) const { + if (i < ArangeDescriptors.size()) + return &ArangeDescriptors[i]; + return NULL; + } +}; + +} + +#endif diff --git a/lib/DebugInfo/DWARFDebugAranges.cpp b/lib/DebugInfo/DWARFDebugAranges.cpp new file mode 100644 index 000000000000..576d37d7813a --- /dev/null +++ b/lib/DebugInfo/DWARFDebugAranges.cpp @@ -0,0 +1,223 @@ +//===-- DWARFDebugAranges.cpp -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFDebugAranges.h" +#include "DWARFCompileUnit.h" +#include "DWARFContext.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +using namespace llvm; + +// Compare function DWARFDebugAranges::Range structures +static bool RangeLessThan(const DWARFDebugAranges::Range &range1, + const DWARFDebugAranges::Range &range2) { + return range1.LoPC < range2.LoPC; +} + +namespace { + class CountArangeDescriptors { + public: + CountArangeDescriptors(uint32_t &count_ref) : Count(count_ref) {} + void operator()(const DWARFDebugArangeSet &set) { + Count += set.getNumDescriptors(); + } + uint32_t &Count; + }; + + class AddArangeDescriptors { + public: + AddArangeDescriptors(DWARFDebugAranges::RangeColl &ranges) + : RangeCollection(ranges) {} + void operator()(const DWARFDebugArangeSet& set) { + const DWARFDebugArangeSet::Descriptor* arange_desc_ptr; + DWARFDebugAranges::Range range; + range.Offset = set.getCompileUnitDIEOffset(); + + for (uint32_t i=0; (arange_desc_ptr = set.getDescriptor(i)) != NULL; ++i){ + range.LoPC = arange_desc_ptr->Address; + range.Length = arange_desc_ptr->Length; + + // Insert each item in increasing address order so binary searching + // can later be done! + DWARFDebugAranges::RangeColl::iterator insert_pos = + std::lower_bound(RangeCollection.begin(), RangeCollection.end(), + range, RangeLessThan); + RangeCollection.insert(insert_pos, range); + } + } + DWARFDebugAranges::RangeColl& RangeCollection; + }; +} + +bool DWARFDebugAranges::extract(DataExtractor debug_aranges_data) { + if (debug_aranges_data.isValidOffset(0)) { + uint32_t offset = 0; + + typedef std::vector SetCollection; + typedef SetCollection::const_iterator SetCollectionIter; + SetCollection sets; + + DWARFDebugArangeSet set; + Range range; + while (set.extract(debug_aranges_data, &offset)) + sets.push_back(set); + + uint32_t count = 0; + + std::for_each(sets.begin(), sets.end(), CountArangeDescriptors(count)); + + if (count > 0) { + Aranges.reserve(count); + AddArangeDescriptors range_adder(Aranges); + std::for_each(sets.begin(), sets.end(), range_adder); + } + } + return false; +} + +bool DWARFDebugAranges::generate(DWARFContext *ctx) { + clear(); + if (ctx) { + const uint32_t num_compile_units = ctx->getNumCompileUnits(); + for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { + DWARFCompileUnit *cu = ctx->getCompileUnitAtIndex(cu_idx); + if (cu) + cu->buildAddressRangeTable(this, true); + } + } + return !isEmpty(); +} + +void DWARFDebugAranges::dump(raw_ostream &OS) const { + const uint32_t num_ranges = getNumRanges(); + for (uint32_t i = 0; i < num_ranges; ++i) { + const Range &range = Aranges[i]; + OS << format("0x%8.8x: [0x%8.8llx - 0x%8.8llx)\n", range.Offset, + (uint64_t)range.LoPC, (uint64_t)range.HiPC()); + } +} + +void DWARFDebugAranges::Range::dump(raw_ostream &OS) const { + OS << format("{0x%8.8x}: [0x%8.8llx - 0x%8.8llx)\n", Offset, LoPC, HiPC()); +} + +void DWARFDebugAranges::appendRange(uint32_t offset, uint64_t low_pc, + uint64_t high_pc) { + if (!Aranges.empty()) { + if (Aranges.back().Offset == offset && Aranges.back().HiPC() == low_pc) { + Aranges.back().setHiPC(high_pc); + return; + } + } + Aranges.push_back(Range(low_pc, high_pc, offset)); +} + +void DWARFDebugAranges::sort(bool minimize, uint32_t n) { + const size_t orig_arange_size = Aranges.size(); + // Size of one? If so, no sorting is needed + if (orig_arange_size <= 1) + return; + // Sort our address range entries + std::stable_sort(Aranges.begin(), Aranges.end(), RangeLessThan); + + if (!minimize) + return; + + // Most address ranges are contiguous from function to function + // so our new ranges will likely be smaller. We calculate the size + // of the new ranges since although std::vector objects can be resized, + // the will never reduce their allocated block size and free any excesss + // memory, so we might as well start a brand new collection so it is as + // small as possible. + + // First calculate the size of the new minimal arange vector + // so we don't have to do a bunch of re-allocations as we + // copy the new minimal stuff over to the new collection. + size_t minimal_size = 1; + for (size_t i = 1; i < orig_arange_size; ++i) { + if (!Range::SortedOverlapCheck(Aranges[i-1], Aranges[i], n)) + ++minimal_size; + } + + // If the sizes are the same, then no consecutive aranges can be + // combined, we are done. + if (minimal_size == orig_arange_size) + return; + + // Else, make a new RangeColl that _only_ contains what we need. + RangeColl minimal_aranges; + minimal_aranges.resize(minimal_size); + uint32_t j = 0; + minimal_aranges[j] = Aranges[0]; + for (size_t i = 1; i < orig_arange_size; ++i) { + if(Range::SortedOverlapCheck (minimal_aranges[j], Aranges[i], n)) { + minimal_aranges[j].setHiPC (Aranges[i].HiPC()); + } else { + // Only increment j if we aren't merging + minimal_aranges[++j] = Aranges[i]; + } + } + assert (j+1 == minimal_size); + + // Now swap our new minimal aranges into place. The local + // minimal_aranges will then contian the old big collection + // which will get freed. + minimal_aranges.swap(Aranges); +} + +uint32_t DWARFDebugAranges::findAddress(uint64_t address) const { + if (!Aranges.empty()) { + Range range(address); + RangeCollIterator begin = Aranges.begin(); + RangeCollIterator end = Aranges.end(); + RangeCollIterator pos = lower_bound(begin, end, range, RangeLessThan); + + if (pos != end && pos->LoPC <= address && address < pos->HiPC()) { + return pos->Offset; + } else if (pos != begin) { + --pos; + if (pos->LoPC <= address && address < pos->HiPC()) + return (*pos).Offset; + } + } + return -1U; +} + +bool +DWARFDebugAranges::allRangesAreContiguous(uint64_t &LoPC, uint64_t &HiPC) const{ + if (Aranges.empty()) + return false; + + uint64_t next_addr = 0; + RangeCollIterator begin = Aranges.begin(); + for (RangeCollIterator pos = begin, end = Aranges.end(); pos != end; + ++pos) { + if (pos != begin && pos->LoPC != next_addr) + return false; + next_addr = pos->HiPC(); + } + // We checked for empty at the start of function so front() will be valid. + LoPC = Aranges.front().LoPC; + // We checked for empty at the start of function so back() will be valid. + HiPC = Aranges.back().HiPC(); + return true; +} + +bool DWARFDebugAranges::getMaxRange(uint64_t &LoPC, uint64_t &HiPC) const { + if (Aranges.empty()) + return false; + // We checked for empty at the start of function so front() will be valid. + LoPC = Aranges.front().LoPC; + // We checked for empty at the start of function so back() will be valid. + HiPC = Aranges.back().HiPC(); + return true; +} + diff --git a/lib/DebugInfo/DWARFDebugAranges.h b/lib/DebugInfo/DWARFDebugAranges.h new file mode 100644 index 000000000000..12afb60beb40 --- /dev/null +++ b/lib/DebugInfo/DWARFDebugAranges.h @@ -0,0 +1,98 @@ +//===-- DWARFDebugAranges.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARFDEBUGARANGES_H +#define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H + +#include "DWARFDebugArangeSet.h" +#include + +namespace llvm { + +class DWARFContext; + +class DWARFDebugAranges { +public: + struct Range { + explicit Range(uint64_t lo = -1ULL, uint64_t hi = -1ULL, + uint32_t off = -1U) + : LoPC(lo), Length(hi-lo), Offset(off) {} + + void clear() { + LoPC = -1ULL; + Length = 0; + Offset = -1U; + } + + void setHiPC(uint64_t HiPC) { + if (HiPC == -1ULL || HiPC <= LoPC) + Length = 0; + else + Length = HiPC - LoPC; + } + uint64_t HiPC() const { + if (Length) + return LoPC + Length; + return -1ULL; + } + bool isValidRange() const { return Length > 0; } + + static bool SortedOverlapCheck(const Range &curr_range, + const Range &next_range, uint32_t n) { + if (curr_range.Offset != next_range.Offset) + return false; + return curr_range.HiPC() + n >= next_range.LoPC; + } + + bool contains(const Range &range) const { + return LoPC <= range.LoPC && range.HiPC() <= HiPC(); + } + + void dump(raw_ostream &OS) const; + uint64_t LoPC; // Start of address range + uint32_t Length; // End of address range (not including this address) + uint32_t Offset; // Offset of the compile unit or die + }; + + void clear() { Aranges.clear(); } + bool allRangesAreContiguous(uint64_t& LoPC, uint64_t& HiPC) const; + bool getMaxRange(uint64_t& LoPC, uint64_t& HiPC) const; + bool extract(DataExtractor debug_aranges_data); + bool generate(DWARFContext *ctx); + + // Use append range multiple times and then call sort + void appendRange(uint32_t cu_offset, uint64_t low_pc, uint64_t high_pc); + void sort(bool minimize, uint32_t n); + + const Range *rangeAtIndex(uint32_t idx) const { + if (idx < Aranges.size()) + return &Aranges[idx]; + return NULL; + } + void dump(raw_ostream &OS) const; + uint32_t findAddress(uint64_t address) const; + bool isEmpty() const { return Aranges.empty(); } + uint32_t getNumRanges() const { return Aranges.size(); } + + uint32_t offsetAtIndex(uint32_t idx) const { + if (idx < Aranges.size()) + return Aranges[idx].Offset; + return -1U; + } + + typedef std::vector RangeColl; + typedef RangeColl::const_iterator RangeCollIterator; + +private: + RangeColl Aranges; +}; + +} + +#endif diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp new file mode 100644 index 000000000000..1b089adbe13b --- /dev/null +++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp @@ -0,0 +1,444 @@ +//===-- DWARFDebugInfoEntry.cpp --------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFDebugInfoEntry.h" +#include "DWARFCompileUnit.h" +#include "DWARFContext.h" +#include "DWARFDebugAbbrev.h" +#include "DWARFFormValue.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; +using namespace dwarf; + +void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, + const DWARFCompileUnit *cu, + unsigned recurseDepth, + unsigned indent) const { + DataExtractor debug_info_data = cu->getDebugInfoExtractor(); + uint32_t offset = Offset; + + if (debug_info_data.isValidOffset(offset)) { + uint64_t abbrCode = debug_info_data.getULEB128(&offset); + + OS << format("\n0x%8.8x: ", Offset); + if (abbrCode) { + if (AbbrevDecl) { + const char *tagString = TagString(getTag()); + if (tagString) + OS.indent(indent) << tagString; + else + OS.indent(indent) << format("DW_TAG_Unknown_%x", getTag()); + OS << format(" [%u] %c\n", abbrCode, + AbbrevDecl->hasChildren() ? '*' : ' '); + + // Dump all data in the .debug_info for the attributes + const uint32_t numAttributes = AbbrevDecl->getNumAttributes(); + for (uint32_t i = 0; i != numAttributes; ++i) { + uint16_t attr = AbbrevDecl->getAttrByIndex(i); + uint16_t form = AbbrevDecl->getFormByIndex(i); + dumpAttribute(OS, cu, &offset, attr, form, indent); + } + + const DWARFDebugInfoEntryMinimal *child = getFirstChild(); + if (recurseDepth > 0 && child) { + while (child) { + child->dump(OS, cu, recurseDepth-1, indent+2); + child = child->getSibling(); + } + } + } else { + OS << "Abbreviation code not found in 'debug_abbrev' class for code: " + << abbrCode << '\n'; + } + } else { + OS.indent(indent) << "NULL\n"; + } + } +} + +void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS, + const DWARFCompileUnit *cu, + uint32_t* offset_ptr, + uint16_t attr, + uint16_t form, + unsigned indent) const { + OS << format("0x%8.8x: ", *offset_ptr); + OS.indent(indent+2); + const char *attrString = AttributeString(attr); + if (attrString) + OS << attrString; + else + OS << format("DW_AT_Unknown_%x", attr); + const char *formString = FormEncodingString(form); + if (formString) + OS << " [" << formString << ']'; + else + OS << format(" [DW_FORM_Unknown_%x]", form); + + DWARFFormValue formValue(form); + + if (!formValue.extractValue(cu->getDebugInfoExtractor(), offset_ptr, cu)) + return; + + OS << "\t("; + formValue.dump(OS, cu); + OS << ")\n"; +} + +bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFCompileUnit *cu, + const uint8_t *fixed_form_sizes, + uint32_t *offset_ptr) { + Offset = *offset_ptr; + + DataExtractor debug_info_data = cu->getDebugInfoExtractor(); + uint64_t abbrCode = debug_info_data.getULEB128(offset_ptr); + + assert (fixed_form_sizes); // For best performance this should be specified! + + if (abbrCode) { + uint32_t offset = *offset_ptr; + + AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode); + + // Skip all data in the .debug_info for the attributes + const uint32_t numAttributes = AbbrevDecl->getNumAttributes(); + uint32_t i; + uint16_t form; + for (i=0; igetFormByIndex(i); + + const uint8_t fixed_skip_size = fixed_form_sizes[form]; + if (fixed_skip_size) + offset += fixed_skip_size; + else { + bool form_is_indirect = false; + do { + form_is_indirect = false; + uint32_t form_size = 0; + switch (form) { + // Blocks if inlined data that have a length field and the data bytes + // inlined in the .debug_info. + case DW_FORM_block: + form_size = debug_info_data.getULEB128(&offset); + break; + case DW_FORM_block1: + form_size = debug_info_data.getU8(&offset); + break; + case DW_FORM_block2: + form_size = debug_info_data.getU16(&offset); + break; + case DW_FORM_block4: + form_size = debug_info_data.getU32(&offset); + break; + + // Inlined NULL terminated C-strings + case DW_FORM_string: + debug_info_data.getCStr(&offset); + break; + + // Compile unit address sized values + case DW_FORM_addr: + case DW_FORM_ref_addr: + form_size = cu->getAddressByteSize(); + break; + + // 1 byte values + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + form_size = 1; + break; + + // 2 byte values + case DW_FORM_data2: + case DW_FORM_ref2: + form_size = 2; + break; + + // 4 byte values + case DW_FORM_strp: + case DW_FORM_data4: + case DW_FORM_ref4: + form_size = 4; + break; + + // 8 byte values + case DW_FORM_data8: + case DW_FORM_ref8: + form_size = 8; + break; + + // signed or unsigned LEB 128 values + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_ref_udata: + debug_info_data.getULEB128(&offset); + break; + + case DW_FORM_indirect: + form_is_indirect = true; + form = debug_info_data.getULEB128(&offset); + break; + + default: + *offset_ptr = Offset; + return false; + } + offset += form_size; + + } while (form_is_indirect); + } + } + *offset_ptr = offset; + return true; + } else { + AbbrevDecl = NULL; + return true; // NULL debug tag entry + } + + return false; +} + +bool +DWARFDebugInfoEntryMinimal::extract(const DWARFCompileUnit *cu, + uint32_t *offset_ptr) { + DataExtractor debug_info_data = cu->getDebugInfoExtractor(); + const uint32_t cu_end_offset = cu->getNextCompileUnitOffset(); + const uint8_t cu_addr_size = cu->getAddressByteSize(); + uint32_t offset = *offset_ptr; + if ((offset < cu_end_offset) && debug_info_data.isValidOffset(offset)) { + Offset = offset; + + uint64_t abbrCode = debug_info_data.getULEB128(&offset); + + if (abbrCode) { + AbbrevDecl = cu->getAbbreviations()->getAbbreviationDeclaration(abbrCode); + + if (AbbrevDecl) { + uint16_t tag = AbbrevDecl->getTag(); + + bool isCompileUnitTag = tag == DW_TAG_compile_unit; + if(cu && isCompileUnitTag) + const_cast(cu)->setBaseAddress(0); + + // Skip all data in the .debug_info for the attributes + const uint32_t numAttributes = AbbrevDecl->getNumAttributes(); + for (uint32_t i = 0; i != numAttributes; ++i) { + uint16_t attr = AbbrevDecl->getAttrByIndex(i); + uint16_t form = AbbrevDecl->getFormByIndex(i); + + if (isCompileUnitTag && + ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) { + DWARFFormValue form_value(form); + if (form_value.extractValue(debug_info_data, &offset, cu)) { + if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) + const_cast(cu) + ->setBaseAddress(form_value.getUnsigned()); + } + } else { + bool form_is_indirect = false; + do { + form_is_indirect = false; + register uint32_t form_size = 0; + switch (form) { + // Blocks if inlined data that have a length field and the data + // bytes // inlined in the .debug_info + case DW_FORM_block: + form_size = debug_info_data.getULEB128(&offset); + break; + case DW_FORM_block1: + form_size = debug_info_data.getU8(&offset); + break; + case DW_FORM_block2: + form_size = debug_info_data.getU16(&offset); + break; + case DW_FORM_block4: + form_size = debug_info_data.getU32(&offset); + break; + + // Inlined NULL terminated C-strings + case DW_FORM_string: + debug_info_data.getCStr(&offset); + break; + + // Compile unit address sized values + case DW_FORM_addr: + case DW_FORM_ref_addr: + form_size = cu_addr_size; + break; + + // 1 byte values + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + form_size = 1; + break; + + // 2 byte values + case DW_FORM_data2: + case DW_FORM_ref2: + form_size = 2; + break; + + // 4 byte values + case DW_FORM_strp: + form_size = 4; + break; + + case DW_FORM_data4: + case DW_FORM_ref4: + form_size = 4; + break; + + // 8 byte values + case DW_FORM_data8: + case DW_FORM_ref8: + form_size = 8; + break; + + // signed or unsigned LEB 128 values + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_ref_udata: + debug_info_data.getULEB128(&offset); + break; + + case DW_FORM_indirect: + form = debug_info_data.getULEB128(&offset); + form_is_indirect = true; + break; + + default: + *offset_ptr = offset; + return false; + } + + offset += form_size; + } while (form_is_indirect); + } + } + *offset_ptr = offset; + return true; + } + } else { + AbbrevDecl = NULL; + *offset_ptr = offset; + return true; // NULL debug tag entry + } + } + + return false; +} + +uint32_t +DWARFDebugInfoEntryMinimal::getAttributeValue(const DWARFCompileUnit *cu, + const uint16_t attr, + DWARFFormValue &form_value, + uint32_t *end_attr_offset_ptr) + const { + if (AbbrevDecl) { + uint32_t attr_idx = AbbrevDecl->findAttributeIndex(attr); + + if (attr_idx != -1U) { + uint32_t offset = getOffset(); + + DataExtractor debug_info_data = cu->getDebugInfoExtractor(); + + // Skip the abbreviation code so we are at the data for the attributes + debug_info_data.getULEB128(&offset); + + uint32_t idx = 0; + while (idx < attr_idx) + DWARFFormValue::skipValue(AbbrevDecl->getFormByIndex(idx++), + debug_info_data, &offset, cu); + + const uint32_t attr_offset = offset; + form_value = DWARFFormValue(AbbrevDecl->getFormByIndex(idx)); + if (form_value.extractValue(debug_info_data, &offset, cu)) { + if (end_attr_offset_ptr) + *end_attr_offset_ptr = offset; + return attr_offset; + } + } + } + + return 0; +} + +const char* +DWARFDebugInfoEntryMinimal::getAttributeValueAsString( + const DWARFCompileUnit* cu, + const uint16_t attr, + const char* fail_value) const { + DWARFFormValue form_value; + if (getAttributeValue(cu, attr, form_value)) { + DataExtractor stringExtractor(cu->getContext().getStringSection(), + false, 0); + return form_value.getAsCString(&stringExtractor); + } + return fail_value; +} + +uint64_t +DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsigned( + const DWARFCompileUnit* cu, + const uint16_t attr, + uint64_t fail_value) const { + DWARFFormValue form_value; + if (getAttributeValue(cu, attr, form_value)) + return form_value.getUnsigned(); + return fail_value; +} + +int64_t +DWARFDebugInfoEntryMinimal::getAttributeValueAsSigned( + const DWARFCompileUnit* cu, + const uint16_t attr, + int64_t fail_value) const { + DWARFFormValue form_value; + if (getAttributeValue(cu, attr, form_value)) + return form_value.getSigned(); + return fail_value; +} + +uint64_t +DWARFDebugInfoEntryMinimal::getAttributeValueAsReference( + const DWARFCompileUnit* cu, + const uint16_t attr, + uint64_t fail_value) const { + DWARFFormValue form_value; + if (getAttributeValue(cu, attr, form_value)) + return form_value.getReference(cu); + return fail_value; +} + +void +DWARFDebugInfoEntryMinimal::buildAddressRangeTable(const DWARFCompileUnit *cu, + DWARFDebugAranges *debug_aranges) + const { + if (AbbrevDecl) { + uint16_t tag = AbbrevDecl->getTag(); + if (tag == DW_TAG_subprogram) { + uint64_t hi_pc = -1ULL; + uint64_t lo_pc = getAttributeValueAsUnsigned(cu, DW_AT_low_pc, -1ULL); + if (lo_pc != -1ULL) + hi_pc = getAttributeValueAsUnsigned(cu, DW_AT_high_pc, -1ULL); + if (hi_pc != -1ULL) + debug_aranges->appendRange(cu->getOffset(), lo_pc, hi_pc); + } + + const DWARFDebugInfoEntryMinimal *child = getFirstChild(); + while (child) { + child->buildAddressRangeTable(cu, debug_aranges); + child = child->getSibling(); + } + } +} diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.h b/lib/DebugInfo/DWARFDebugInfoEntry.h new file mode 100644 index 000000000000..aff2e8556729 --- /dev/null +++ b/lib/DebugInfo/DWARFDebugInfoEntry.h @@ -0,0 +1,135 @@ +//===-- DWARFDebugInfoEntry.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H +#define LLVM_DEBUGINFO_DWARFDEBUGINFOENTRY_H + +#include "DWARFAbbreviationDeclaration.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { + +class DWARFDebugAranges; +class DWARFCompileUnit; +class DWARFContext; +class DWARFFormValue; + +/// DWARFDebugInfoEntryMinimal - A DIE with only the minimum required data. +class DWARFDebugInfoEntryMinimal { + /// Offset within the .debug_info of the start of this entry. + uint64_t Offset; + + /// How many to subtract from "this" to get the parent. + /// If zero this die has no parent. + uint32_t ParentIdx; + + /// How many to add to "this" to get the sibling. + uint32_t SiblingIdx; + + const DWARFAbbreviationDeclaration *AbbrevDecl; +public: + DWARFDebugInfoEntryMinimal() + : Offset(0), ParentIdx(0), SiblingIdx(0), AbbrevDecl(0) {} + + void dump(raw_ostream &OS, const DWARFCompileUnit *cu, + unsigned recurseDepth, unsigned indent = 0) const; + void dumpAttribute(raw_ostream &OS, const DWARFCompileUnit *cu, + uint32_t *offset_ptr, uint16_t attr, uint16_t form, + unsigned indent = 0) const; + + bool extractFast(const DWARFCompileUnit *cu, const uint8_t *fixed_form_sizes, + uint32_t *offset_ptr); + + /// Extract a debug info entry for a given compile unit from the + /// .debug_info and .debug_abbrev data starting at the given offset. + bool extract(const DWARFCompileUnit *cu, uint32_t *offset_ptr); + + uint32_t getTag() const { return AbbrevDecl ? AbbrevDecl->getTag() : 0; } + bool isNULL() const { return AbbrevDecl == 0; } + uint64_t getOffset() const { return Offset; } + uint32_t getNumAttributes() const { + return !isNULL() ? AbbrevDecl->getNumAttributes() : 0; + } + bool hasChildren() const { return !isNULL() && AbbrevDecl->hasChildren(); } + + // We know we are kept in a vector of contiguous entries, so we know + // our parent will be some index behind "this". + DWARFDebugInfoEntryMinimal *getParent() { + return ParentIdx > 0 ? this - ParentIdx : 0; + } + const DWARFDebugInfoEntryMinimal *getParent() const { + return ParentIdx > 0 ? this - ParentIdx : 0; + } + // We know we are kept in a vector of contiguous entries, so we know + // our sibling will be some index after "this". + DWARFDebugInfoEntryMinimal *getSibling() { + return SiblingIdx > 0 ? this + SiblingIdx : 0; + } + const DWARFDebugInfoEntryMinimal *getSibling() const { + return SiblingIdx > 0 ? this + SiblingIdx : 0; + } + // We know we are kept in a vector of contiguous entries, so we know + // we don't need to store our child pointer, if we have a child it will + // be the next entry in the list... + DWARFDebugInfoEntryMinimal *getFirstChild() { + return hasChildren() ? this + 1 : 0; + } + const DWARFDebugInfoEntryMinimal *getFirstChild() const { + return hasChildren() ? this + 1 : 0; + } + + void setParent(DWARFDebugInfoEntryMinimal *parent) { + if (parent) { + // We know we are kept in a vector of contiguous entries, so we know + // our parent will be some index behind "this". + ParentIdx = this - parent; + } else + ParentIdx = 0; + } + void setSibling(DWARFDebugInfoEntryMinimal *sibling) { + if (sibling) { + // We know we are kept in a vector of contiguous entries, so we know + // our sibling will be some index after "this". + SiblingIdx = sibling - this; + sibling->setParent(getParent()); + } else + SiblingIdx = 0; + } + + const DWARFAbbreviationDeclaration *getAbbreviationDeclarationPtr() const { + return AbbrevDecl; + } + + uint32_t getAttributeValue(const DWARFCompileUnit *cu, + const uint16_t attr, DWARFFormValue &formValue, + uint32_t *end_attr_offset_ptr = 0) const; + + const char* getAttributeValueAsString(const DWARFCompileUnit* cu, + const uint16_t attr, + const char *fail_value) const; + + uint64_t getAttributeValueAsUnsigned(const DWARFCompileUnit *cu, + const uint16_t attr, + uint64_t fail_value) const; + + uint64_t getAttributeValueAsReference(const DWARFCompileUnit *cu, + const uint16_t attr, + uint64_t fail_value) const; + + int64_t getAttributeValueAsSigned(const DWARFCompileUnit* cu, + const uint16_t attr, + int64_t fail_value) const; + + void buildAddressRangeTable(const DWARFCompileUnit *cu, + DWARFDebugAranges *debug_aranges) const; +}; + +} + +#endif diff --git a/lib/DebugInfo/DWARFDebugLine.cpp b/lib/DebugInfo/DWARFDebugLine.cpp new file mode 100644 index 000000000000..fe1ef78b026e --- /dev/null +++ b/lib/DebugInfo/DWARFDebugLine.cpp @@ -0,0 +1,475 @@ +//===-- DWARFDebugLine.cpp ------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFDebugLine.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +#include +using namespace llvm; +using namespace dwarf; + +void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const { + OS << "Line table prologue:\n" + << format(" total_length: 0x%8.8x\n", TotalLength) + << format(" version: %u\n", Version) + << format("prologue_length: 0x%8.8x\n", PrologueLength) + << format("min_inst_length: %u\n", MinInstLength) + << format("default_is_stmt: %u\n", DefaultIsStmt) + << format(" line_base: %i\n", LineBase) + << format(" line_range: %u\n", LineRange) + << format(" opcode_base: %u\n", OpcodeBase); + + for (uint32_t i = 0; i < StandardOpcodeLengths.size(); ++i) + OS << format("standard_opcode_lengths[%s] = %u\n", LNStandardString(i+1), + StandardOpcodeLengths[i]); + + if (!IncludeDirectories.empty()) + for (uint32_t i = 0; i < IncludeDirectories.size(); ++i) + OS << format("include_directories[%3u] = '", i+1) + << IncludeDirectories[i] << "'\n"; + + if (!FileNames.empty()) { + OS << " Dir Mod Time File Len File Name\n" + << " ---- ---------- ---------- -----------" + "----------------\n"; + for (uint32_t i = 0; i < FileNames.size(); ++i) { + const FileNameEntry& fileEntry = FileNames[i]; + OS << format("file_names[%3u] %4u ", i+1, fileEntry.DirIdx) + << format("0x%8.8x 0x%8.8x ", fileEntry.ModTime, fileEntry.Length) + << fileEntry.Name << '\n'; + } + } +} + +void DWARFDebugLine::Row::postAppend() { + BasicBlock = false; + PrologueEnd = false; + EpilogueBegin = false; +} + +void DWARFDebugLine::Row::reset(bool default_is_stmt) { + Address = 0; + Line = 1; + Column = 0; + File = 1; + Isa = 0; + IsStmt = default_is_stmt; + BasicBlock = false; + EndSequence = false; + PrologueEnd = false; + EpilogueBegin = false; +} + +void DWARFDebugLine::Row::dump(raw_ostream &OS) const { + OS << format("0x%16.16llx %6u %6u", Address, Line, Column) + << format(" %6u %3u ", File, Isa) + << (IsStmt ? " is_stmt" : "") + << (BasicBlock ? " basic_block" : "") + << (PrologueEnd ? " prologue_end" : "") + << (EpilogueBegin ? " epilogue_begin" : "") + << (EndSequence ? " end_sequence" : "") + << '\n'; +} + +void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const { + Prologue.dump(OS); + OS << '\n'; + + if (!Rows.empty()) { + OS << "Address Line Column File ISA Flags\n" + << "------------------ ------ ------ ------ --- -------------\n"; + for (std::vector::const_iterator pos = Rows.begin(), + end = Rows.end(); pos != end; ++pos) + pos->dump(OS); + } +} + +DWARFDebugLine::State::~State() {} + +void DWARFDebugLine::State::appendRowToMatrix(uint32_t offset) { + ++row; // Increase the row number. + LineTable::appendRow(*this); + Row::postAppend(); +} + +DWARFDebugLine::DumpingState::~DumpingState() {} + +void DWARFDebugLine::DumpingState::finalize(uint32_t offset) { + LineTable::dump(OS); +} + +const DWARFDebugLine::LineTable * +DWARFDebugLine::getLineTable(uint32_t offset) const { + LineTableConstIter pos = LineTableMap.find(offset); + if (pos != LineTableMap.end()) + return &pos->second; + return 0; +} + +const DWARFDebugLine::LineTable * +DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data, + uint32_t offset) { + std::pair pos = + LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable())); + if (pos.second) { + // Parse and cache the line table for at this offset. + State state; + if (!parseStatementTable(debug_line_data, &offset, state)) + return 0; + pos.first->second = state; + } + return &pos.first->second; +} + +bool +DWARFDebugLine::parsePrologue(DataExtractor debug_line_data, + uint32_t *offset_ptr, Prologue *prologue) { + const uint32_t prologue_offset = *offset_ptr; + + prologue->clear(); + prologue->TotalLength = debug_line_data.getU32(offset_ptr); + prologue->Version = debug_line_data.getU16(offset_ptr); + if (prologue->Version != 2) + return false; + + prologue->PrologueLength = debug_line_data.getU32(offset_ptr); + const uint32_t end_prologue_offset = prologue->PrologueLength + *offset_ptr; + prologue->MinInstLength = debug_line_data.getU8(offset_ptr); + prologue->DefaultIsStmt = debug_line_data.getU8(offset_ptr); + prologue->LineBase = debug_line_data.getU8(offset_ptr); + prologue->LineRange = debug_line_data.getU8(offset_ptr); + prologue->OpcodeBase = debug_line_data.getU8(offset_ptr); + + prologue->StandardOpcodeLengths.reserve(prologue->OpcodeBase-1); + for (uint32_t i = 1; i < prologue->OpcodeBase; ++i) { + uint8_t op_len = debug_line_data.getU8(offset_ptr); + prologue->StandardOpcodeLengths.push_back(op_len); + } + + while (*offset_ptr < end_prologue_offset) { + const char *s = debug_line_data.getCStr(offset_ptr); + if (s && s[0]) + prologue->IncludeDirectories.push_back(s); + else + break; + } + + while (*offset_ptr < end_prologue_offset) { + const char *name = debug_line_data.getCStr(offset_ptr); + if (name && name[0]) { + FileNameEntry fileEntry; + fileEntry.Name = name; + fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr); + fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr); + fileEntry.Length = debug_line_data.getULEB128(offset_ptr); + prologue->FileNames.push_back(fileEntry); + } else { + break; + } + } + + if (*offset_ptr != end_prologue_offset) { + fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should" + " have ended at 0x%8.8x but it ended ad 0x%8.8x\n", + prologue_offset, end_prologue_offset, *offset_ptr); + } + return end_prologue_offset; +} + +bool +DWARFDebugLine::parseStatementTable(DataExtractor debug_line_data, + uint32_t *offset_ptr, State &state) { + const uint32_t debug_line_offset = *offset_ptr; + + Prologue *prologue = &state.Prologue; + + if (!parsePrologue(debug_line_data, offset_ptr, prologue)) { + // Restore our offset and return false to indicate failure! + *offset_ptr = debug_line_offset; + return false; + } + + const uint32_t end_offset = debug_line_offset + prologue->TotalLength + + sizeof(prologue->TotalLength); + + state.reset(); + + while (*offset_ptr < end_offset) { + uint8_t opcode = debug_line_data.getU8(offset_ptr); + + if (opcode == 0) { + // Extended Opcodes always start with a zero opcode followed by + // a uleb128 length so you can skip ones you don't know about + uint32_t ext_offset = *offset_ptr; + uint64_t len = debug_line_data.getULEB128(offset_ptr); + uint32_t arg_size = len - (*offset_ptr - ext_offset); + + uint8_t sub_opcode = debug_line_data.getU8(offset_ptr); + switch (sub_opcode) { + case DW_LNE_end_sequence: + // Set the end_sequence register of the state machine to true and + // append a row to the matrix using the current values of the + // state-machine registers. Then reset the registers to the initial + // values specified above. Every statement program sequence must end + // with a DW_LNE_end_sequence instruction which creates a row whose + // address is that of the byte after the last target machine instruction + // of the sequence. + state.EndSequence = true; + state.appendRowToMatrix(*offset_ptr); + state.reset(); + break; + + case DW_LNE_set_address: + // Takes a single relocatable address as an operand. The size of the + // operand is the size appropriate to hold an address on the target + // machine. Set the address register to the value given by the + // relocatable address. All of the other statement program opcodes + // that affect the address register add a delta to it. This instruction + // stores a relocatable value into it instead. + state.Address = debug_line_data.getAddress(offset_ptr); + break; + + case DW_LNE_define_file: + // Takes 4 arguments. The first is a null terminated string containing + // a source file name. The second is an unsigned LEB128 number + // representing the directory index of the directory in which the file + // was found. The third is an unsigned LEB128 number representing the + // time of last modification of the file. The fourth is an unsigned + // LEB128 number representing the length in bytes of the file. The time + // and length fields may contain LEB128(0) if the information is not + // available. + // + // The directory index represents an entry in the include_directories + // section of the statement program prologue. The index is LEB128(0) + // if the file was found in the current directory of the compilation, + // LEB128(1) if it was found in the first directory in the + // include_directories section, and so on. The directory index is + // ignored for file names that represent full path names. + // + // The files are numbered, starting at 1, in the order in which they + // appear; the names in the prologue come before names defined by + // the DW_LNE_define_file instruction. These numbers are used in the + // the file register of the state machine. + { + FileNameEntry fileEntry; + fileEntry.Name = debug_line_data.getCStr(offset_ptr); + fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr); + fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr); + fileEntry.Length = debug_line_data.getULEB128(offset_ptr); + prologue->FileNames.push_back(fileEntry); + } + break; + + default: + // Length doesn't include the zero opcode byte or the length itself, but + // it does include the sub_opcode, so we have to adjust for that below + (*offset_ptr) += arg_size; + break; + } + } else if (opcode < prologue->OpcodeBase) { + switch (opcode) { + // Standard Opcodes + case DW_LNS_copy: + // Takes no arguments. Append a row to the matrix using the + // current values of the state-machine registers. Then set + // the basic_block register to false. + state.appendRowToMatrix(*offset_ptr); + break; + + case DW_LNS_advance_pc: + // Takes a single unsigned LEB128 operand, multiplies it by the + // min_inst_length field of the prologue, and adds the + // result to the address register of the state machine. + state.Address += debug_line_data.getULEB128(offset_ptr) * + prologue->MinInstLength; + break; + + case DW_LNS_advance_line: + // Takes a single signed LEB128 operand and adds that value to + // the line register of the state machine. + state.Line += debug_line_data.getSLEB128(offset_ptr); + break; + + case DW_LNS_set_file: + // Takes a single unsigned LEB128 operand and stores it in the file + // register of the state machine. + state.File = debug_line_data.getULEB128(offset_ptr); + break; + + case DW_LNS_set_column: + // Takes a single unsigned LEB128 operand and stores it in the + // column register of the state machine. + state.Column = debug_line_data.getULEB128(offset_ptr); + break; + + case DW_LNS_negate_stmt: + // Takes no arguments. Set the is_stmt register of the state + // machine to the logical negation of its current value. + state.IsStmt = !state.IsStmt; + break; + + case DW_LNS_set_basic_block: + // Takes no arguments. Set the basic_block register of the + // state machine to true + state.BasicBlock = true; + break; + + case DW_LNS_const_add_pc: + // Takes no arguments. Add to the address register of the state + // machine the address increment value corresponding to special + // opcode 255. The motivation for DW_LNS_const_add_pc is this: + // when the statement program needs to advance the address by a + // small amount, it can use a single special opcode, which occupies + // a single byte. When it needs to advance the address by up to + // twice the range of the last special opcode, it can use + // DW_LNS_const_add_pc followed by a special opcode, for a total + // of two bytes. Only if it needs to advance the address by more + // than twice that range will it need to use both DW_LNS_advance_pc + // and a special opcode, requiring three or more bytes. + { + uint8_t adjust_opcode = 255 - prologue->OpcodeBase; + uint64_t addr_offset = (adjust_opcode / prologue->LineRange) * + prologue->MinInstLength; + state.Address += addr_offset; + } + break; + + case DW_LNS_fixed_advance_pc: + // Takes a single uhalf operand. Add to the address register of + // the state machine the value of the (unencoded) operand. This + // is the only extended opcode that takes an argument that is not + // a variable length number. The motivation for DW_LNS_fixed_advance_pc + // is this: existing assemblers cannot emit DW_LNS_advance_pc or + // special opcodes because they cannot encode LEB128 numbers or + // judge when the computation of a special opcode overflows and + // requires the use of DW_LNS_advance_pc. Such assemblers, however, + // can use DW_LNS_fixed_advance_pc instead, sacrificing compression. + state.Address += debug_line_data.getU16(offset_ptr); + break; + + case DW_LNS_set_prologue_end: + // Takes no arguments. Set the prologue_end register of the + // state machine to true + state.PrologueEnd = true; + break; + + case DW_LNS_set_epilogue_begin: + // Takes no arguments. Set the basic_block register of the + // state machine to true + state.EpilogueBegin = true; + break; + + case DW_LNS_set_isa: + // Takes a single unsigned LEB128 operand and stores it in the + // column register of the state machine. + state.Isa = debug_line_data.getULEB128(offset_ptr); + break; + + default: + // Handle any unknown standard opcodes here. We know the lengths + // of such opcodes because they are specified in the prologue + // as a multiple of LEB128 operands for each opcode. + { + assert(opcode - 1U < prologue->StandardOpcodeLengths.size()); + uint8_t opcode_length = prologue->StandardOpcodeLengths[opcode - 1]; + for (uint8_t i=0; iOpcodeBase; + uint64_t addr_offset = (adjust_opcode / prologue->LineRange) * + prologue->MinInstLength; + int32_t line_offset = prologue->LineBase + + (adjust_opcode % prologue->LineRange); + state.Line += line_offset; + state.Address += addr_offset; + state.appendRowToMatrix(*offset_ptr); + } + } + + state.finalize(*offset_ptr); + + return end_offset; +} + +static bool findMatchingAddress(const DWARFDebugLine::Row& row1, + const DWARFDebugLine::Row& row2) { + return row1.Address < row2.Address; +} + +uint32_t +DWARFDebugLine::LineTable::lookupAddress(uint64_t address, + uint64_t cu_high_pc) const { + uint32_t index = UINT32_MAX; + if (!Rows.empty()) { + // Use the lower_bound algorithm to perform a binary search since we know + // that our line table data is ordered by address. + DWARFDebugLine::Row row; + row.Address = address; + typedef std::vector::const_iterator iterator; + iterator begin_pos = Rows.begin(); + iterator end_pos = Rows.end(); + iterator pos = std::lower_bound(begin_pos, end_pos, row, + findMatchingAddress); + if (pos == end_pos) { + if (address < cu_high_pc) + return Rows.size()-1; + } else { + // Rely on fact that we are using a std::vector and we can do + // pointer arithmetic to find the row index (which will be one less + // that what we found since it will find the first position after + // the current address) since std::vector iterators are just + // pointers to the container type. + index = pos - begin_pos; + if (pos->Address > address) { + if (index > 0) + --index; + else + index = UINT32_MAX; + } + } + } + return index; // Failed to find address. +} diff --git a/lib/DebugInfo/DWARFDebugLine.h b/lib/DebugInfo/DWARFDebugLine.h new file mode 100644 index 000000000000..bc6a70b11120 --- /dev/null +++ b/lib/DebugInfo/DWARFDebugLine.h @@ -0,0 +1,190 @@ +//===-- DWARFDebugLine.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARFDEBUGLINE_H +#define LLVM_DEBUGINFO_DWARFDEBUGLINE_H + +#include "llvm/Support/DataExtractor.h" +#include +#include +#include + +namespace llvm { + +class raw_ostream; + +class DWARFDebugLine { +public: + struct FileNameEntry { + FileNameEntry() : DirIdx(0), ModTime(0), Length(0) {} + + std::string Name; + uint64_t DirIdx; + uint64_t ModTime; + uint64_t Length; + }; + + struct Prologue { + Prologue() + : TotalLength(0), Version(0), PrologueLength(0), MinInstLength(0), + DefaultIsStmt(0), LineBase(0), LineRange(0), OpcodeBase(0) {} + + // The size in bytes of the statement information for this compilation unit + // (not including the total_length field itself). + uint32_t TotalLength; + // Version identifier for the statement information format. + uint16_t Version; + // The number of bytes following the prologue_length field to the beginning + // of the first byte of the statement program itself. + uint32_t PrologueLength; + // The size in bytes of the smallest target machine instruction. Statement + // program opcodes that alter the address register first multiply their + // operands by this value. + uint8_t MinInstLength; + // The initial value of theis_stmtregister. + uint8_t DefaultIsStmt; + // This parameter affects the meaning of the special opcodes. See below. + int8_t LineBase; + // This parameter affects the meaning of the special opcodes. See below. + uint8_t LineRange; + // The number assigned to the first special opcode. + uint8_t OpcodeBase; + std::vector StandardOpcodeLengths; + std::vector IncludeDirectories; + std::vector FileNames; + + // Length of the prologue in bytes. + uint32_t getLength() const { + return PrologueLength + sizeof(TotalLength) + sizeof(Version) + + sizeof(PrologueLength); + } + // Length of the line table data in bytes (not including the prologue). + uint32_t getStatementTableLength() const { + return TotalLength + sizeof(TotalLength) - getLength(); + } + int32_t getMaxLineIncrementForSpecialOpcode() const { + return LineBase + (int8_t)LineRange - 1; + } + void dump(raw_ostream &OS) const; + void clear() { + TotalLength = Version = PrologueLength = 0; + MinInstLength = LineBase = LineRange = OpcodeBase = 0; + StandardOpcodeLengths.clear(); + IncludeDirectories.clear(); + FileNames.clear(); + } + }; + + // Standard .debug_line state machine structure. + struct Row { + Row(bool default_is_stmt = false) { reset(default_is_stmt); } + /// Called after a row is appended to the matrix. + void postAppend(); + void reset(bool default_is_stmt); + void dump(raw_ostream &OS) const; + + // The program-counter value corresponding to a machine instruction + // generated by the compiler. + uint64_t Address; + // An unsigned integer indicating a source line number. Lines are numbered + // beginning at 1. The compiler may emit the value 0 in cases where an + // instruction cannot be attributed to any source line. + uint32_t Line; + // An unsigned integer indicating a column number within a source line. + // Columns are numbered beginning at 1. The value 0 is reserved to indicate + // that a statement begins at the 'left edge' of the line. + uint16_t Column; + // An unsigned integer indicating the identity of the source file + // corresponding to a machine instruction. + uint16_t File; + // An unsigned integer whose value encodes the applicable instruction set + // architecture for the current instruction. + uint8_t Isa; + // A boolean indicating that the current instruction is the beginning of a + // statement. + uint8_t IsStmt:1, + // A boolean indicating that the current instruction is the + // beginning of a basic block. + BasicBlock:1, + // A boolean indicating that the current address is that of the + // first byte after the end of a sequence of target machine + // instructions. + EndSequence:1, + // A boolean indicating that the current address is one (of possibly + // many) where execution should be suspended for an entry breakpoint + // of a function. + PrologueEnd:1, + // A boolean indicating that the current address is one (of possibly + // many) where execution should be suspended for an exit breakpoint + // of a function. + EpilogueBegin:1; + }; + + struct LineTable { + void appendRow(const DWARFDebugLine::Row &state) { Rows.push_back(state); } + void clear() { + Prologue.clear(); + Rows.clear(); + } + + uint32_t lookupAddress(uint64_t address, uint64_t cu_high_pc) const; + void dump(raw_ostream &OS) const; + + struct Prologue Prologue; + std::vector Rows; + }; + + struct State : public Row, public LineTable { + // Special row codes. + enum { + StartParsingLineTable = 0, + DoneParsingLineTable = -1 + }; + + State() : row(StartParsingLineTable) {} + virtual ~State(); + + virtual void appendRowToMatrix(uint32_t offset); + virtual void finalize(uint32_t offset) { row = DoneParsingLineTable; } + virtual void reset() { Row::reset(Prologue.DefaultIsStmt); } + + // The row number that starts at zero for the prologue, and increases for + // each row added to the matrix. + unsigned row; + }; + + struct DumpingState : public State { + DumpingState(raw_ostream &OS) : OS(OS) {} + virtual ~DumpingState(); + virtual void finalize(uint32_t offset); + private: + raw_ostream &OS; + }; + + static bool parsePrologue(DataExtractor debug_line_data, uint32_t *offset_ptr, + Prologue *prologue); + /// Parse a single line table (prologue and all rows). + static bool parseStatementTable(DataExtractor debug_line_data, + uint32_t *offset_ptr, State &state); + + const LineTable *getLineTable(uint32_t offset) const; + const LineTable *getOrParseLineTable(DataExtractor debug_line_data, + uint32_t offset); + +private: + typedef std::map LineTableMapTy; + typedef LineTableMapTy::iterator LineTableIter; + typedef LineTableMapTy::const_iterator LineTableConstIter; + + LineTableMapTy LineTableMap; +}; + +} + +#endif diff --git a/lib/DebugInfo/DWARFFormValue.cpp b/lib/DebugInfo/DWARFFormValue.cpp new file mode 100644 index 000000000000..705efe5549b6 --- /dev/null +++ b/lib/DebugInfo/DWARFFormValue.cpp @@ -0,0 +1,427 @@ +//===-- DWARFFormValue.cpp ------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFFormValue.h" +#include "DWARFCompileUnit.h" +#include "DWARFContext.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +#include +using namespace llvm; +using namespace dwarf; + +static const uint8_t form_sizes_addr4[] = { + 0, // 0x00 unused + 4, // 0x01 DW_FORM_addr + 0, // 0x02 unused + 0, // 0x03 DW_FORM_block2 + 0, // 0x04 DW_FORM_block4 + 2, // 0x05 DW_FORM_data2 + 4, // 0x06 DW_FORM_data4 + 8, // 0x07 DW_FORM_data8 + 0, // 0x08 DW_FORM_string + 0, // 0x09 DW_FORM_block + 0, // 0x0a DW_FORM_block1 + 1, // 0x0b DW_FORM_data1 + 1, // 0x0c DW_FORM_flag + 0, // 0x0d DW_FORM_sdata + 4, // 0x0e DW_FORM_strp + 0, // 0x0f DW_FORM_udata + 4, // 0x10 DW_FORM_ref_addr + 1, // 0x11 DW_FORM_ref1 + 2, // 0x12 DW_FORM_ref2 + 4, // 0x13 DW_FORM_ref4 + 8, // 0x14 DW_FORM_ref8 + 0, // 0x15 DW_FORM_ref_udata + 0, // 0x16 DW_FORM_indirect +}; + +static const uint8_t form_sizes_addr8[] = { + 0, // 0x00 unused + 8, // 0x01 DW_FORM_addr + 0, // 0x02 unused + 0, // 0x03 DW_FORM_block2 + 0, // 0x04 DW_FORM_block4 + 2, // 0x05 DW_FORM_data2 + 4, // 0x06 DW_FORM_data4 + 8, // 0x07 DW_FORM_data8 + 0, // 0x08 DW_FORM_string + 0, // 0x09 DW_FORM_block + 0, // 0x0a DW_FORM_block1 + 1, // 0x0b DW_FORM_data1 + 1, // 0x0c DW_FORM_flag + 0, // 0x0d DW_FORM_sdata + 4, // 0x0e DW_FORM_strp + 0, // 0x0f DW_FORM_udata + 8, // 0x10 DW_FORM_ref_addr + 1, // 0x11 DW_FORM_ref1 + 2, // 0x12 DW_FORM_ref2 + 4, // 0x13 DW_FORM_ref4 + 8, // 0x14 DW_FORM_ref8 + 0, // 0x15 DW_FORM_ref_udata + 0, // 0x16 DW_FORM_indirect +}; + +const uint8_t * +DWARFFormValue::getFixedFormSizesForAddressSize(uint8_t addr_size) { + switch (addr_size) { + case 4: return form_sizes_addr4; + case 8: return form_sizes_addr8; + } + return NULL; +} + +bool +DWARFFormValue::extractValue(DataExtractor data, uint32_t *offset_ptr, + const DWARFCompileUnit *cu) { + bool indirect = false; + bool is_block = false; + Value.data = NULL; + // Read the value for the form into value and follow and DW_FORM_indirect + // instances we run into + do { + indirect = false; + switch (Form) { + case DW_FORM_addr: + case DW_FORM_ref_addr: + Value.uval = data.getUnsigned(offset_ptr, cu->getAddressByteSize()); + break; + case DW_FORM_block: + Value.uval = data.getULEB128(offset_ptr); + is_block = true; + break; + case DW_FORM_block1: + Value.uval = data.getU8(offset_ptr); + is_block = true; + break; + case DW_FORM_block2: + Value.uval = data.getU16(offset_ptr); + is_block = true; + break; + case DW_FORM_block4: + Value.uval = data.getU32(offset_ptr); + is_block = true; + break; + case DW_FORM_data1: + case DW_FORM_ref1: + case DW_FORM_flag: + Value.uval = data.getU8(offset_ptr); + break; + case DW_FORM_data2: + case DW_FORM_ref2: + Value.uval = data.getU16(offset_ptr); + break; + case DW_FORM_data4: + case DW_FORM_ref4: + Value.uval = data.getU32(offset_ptr); + break; + case DW_FORM_data8: + case DW_FORM_ref8: + Value.uval = data.getU64(offset_ptr); + break; + case DW_FORM_sdata: + Value.sval = data.getSLEB128(offset_ptr); + break; + case DW_FORM_strp: + Value.uval = data.getU32(offset_ptr); + break; + case DW_FORM_udata: + case DW_FORM_ref_udata: + Value.uval = data.getULEB128(offset_ptr); + break; + case DW_FORM_string: + Value.cstr = data.getCStr(offset_ptr); + // Set the string value to also be the data for inlined cstr form + // values only so we can tell the differnence between DW_FORM_string + // and DW_FORM_strp form values + Value.data = (uint8_t*)Value.cstr; + break; + case DW_FORM_indirect: + Form = data.getULEB128(offset_ptr); + indirect = true; + break; + default: + return false; + } + } while (indirect); + + if (is_block) { + StringRef str = data.getData().substr(*offset_ptr, Value.uval); + Value.data = NULL; + if (!str.empty()) { + Value.data = reinterpret_cast(str.data()); + *offset_ptr += Value.uval; + } + } + + return true; +} + +bool +DWARFFormValue::skipValue(DataExtractor debug_info_data, uint32_t* offset_ptr, + const DWARFCompileUnit *cu) const { + return DWARFFormValue::skipValue(Form, debug_info_data, offset_ptr, cu); +} + +bool +DWARFFormValue::skipValue(uint16_t form, DataExtractor debug_info_data, + uint32_t *offset_ptr, const DWARFCompileUnit *cu) { + bool indirect = false; + do { + indirect = false; + switch (form) { + // Blocks if inlined data that have a length field and the data bytes + // inlined in the .debug_info + case DW_FORM_block: { + uint64_t size = debug_info_data.getULEB128(offset_ptr); + *offset_ptr += size; + return true; + } + case DW_FORM_block1: { + uint8_t size = debug_info_data.getU8(offset_ptr); + *offset_ptr += size; + return true; + } + case DW_FORM_block2: { + uint16_t size = debug_info_data.getU16(offset_ptr); + *offset_ptr += size; + return true; + } + case DW_FORM_block4: { + uint32_t size = debug_info_data.getU32(offset_ptr); + *offset_ptr += size; + return true; + } + + // Inlined NULL terminated C-strings + case DW_FORM_string: + debug_info_data.getCStr(offset_ptr); + return true; + + // Compile unit address sized values + case DW_FORM_addr: + case DW_FORM_ref_addr: + *offset_ptr += cu->getAddressByteSize(); + return true; + + // 1 byte values + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + *offset_ptr += 1; + return true; + + // 2 byte values + case DW_FORM_data2: + case DW_FORM_ref2: + *offset_ptr += 2; + return true; + + // 4 byte values + case DW_FORM_strp: + case DW_FORM_data4: + case DW_FORM_ref4: + *offset_ptr += 4; + return true; + + // 8 byte values + case DW_FORM_data8: + case DW_FORM_ref8: + *offset_ptr += 8; + return true; + + // signed or unsigned LEB 128 values + // case DW_FORM_APPLE_db_str: + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_ref_udata: + debug_info_data.getULEB128(offset_ptr); + return true; + + case DW_FORM_indirect: + indirect = true; + form = debug_info_data.getULEB128(offset_ptr); + break; + default: + return false; + } + } while (indirect); + return true; +} + +void +DWARFFormValue::dump(raw_ostream &OS, const DWARFCompileUnit *cu) const { + DataExtractor debug_str_data(cu->getContext().getStringSection(), true, 0); + uint64_t uvalue = getUnsigned(); + bool cu_relative_offset = false; + + switch (Form) { + case DW_FORM_addr: OS << format("0x%016x", uvalue); break; + case DW_FORM_flag: + case DW_FORM_data1: OS << format("0x%02x", uvalue); break; + case DW_FORM_data2: OS << format("0x%04x", uvalue); break; + case DW_FORM_data4: OS << format("0x%08x", uvalue); break; + case DW_FORM_data8: OS << format("0x%016x", uvalue); break; + case DW_FORM_string: + OS << '"'; + OS.write_escaped(getAsCString(NULL)); + OS << '"'; + break; + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + if (uvalue > 0) { + switch (Form) { + case DW_FORM_block: OS << format("<0x%llx> ", uvalue); break; + case DW_FORM_block1: OS << format("<0x%2.2x> ", (uint8_t)uvalue); break; + case DW_FORM_block2: OS << format("<0x%4.4x> ", (uint16_t)uvalue); break; + case DW_FORM_block4: OS << format("<0x%8.8x> ", (uint32_t)uvalue); break; + default: break; + } + + const uint8_t* data_ptr = Value.data; + if (data_ptr) { + // uvalue contains size of block + const uint8_t* end_data_ptr = data_ptr + uvalue; + while (data_ptr < end_data_ptr) { + OS << format("%2.2x ", *data_ptr); + ++data_ptr; + } + } + else + OS << "NULL"; + } + break; + + case DW_FORM_sdata: OS << getSigned(); break; + case DW_FORM_udata: OS << getUnsigned(); break; + case DW_FORM_strp: { + OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)uvalue); + const char* dbg_str = getAsCString(&debug_str_data); + if (dbg_str) { + OS << '"'; + OS.write_escaped(dbg_str); + OS << '"'; + } + break; + } + case DW_FORM_ref_addr: + OS << format("0x%016x", uvalue); + break; + case DW_FORM_ref1: + cu_relative_offset = true; + OS << format("cu + 0x%2.2x", (uint8_t)uvalue); + break; + case DW_FORM_ref2: + cu_relative_offset = true; + OS << format("cu + 0x%4.4x", (uint16_t)uvalue); + break; + case DW_FORM_ref4: + cu_relative_offset = true; + OS << format("cu + 0x%4.4x", (uint32_t)uvalue); + break; + case DW_FORM_ref8: + cu_relative_offset = true; + OS << format("cu + 0x%8.8llx", uvalue); + break; + case DW_FORM_ref_udata: + cu_relative_offset = true; + OS << format("cu + 0x%llx", uvalue); + break; + + // All DW_FORM_indirect attributes should be resolved prior to calling + // this function + case DW_FORM_indirect: + OS << "DW_FORM_indirect"; + break; + default: + OS << format("DW_FORM(0x%4.4x)", Form); + break; + } + + if (cu_relative_offset) + OS << format(" => {0x%8.8x}", (uvalue + (cu ? cu->getOffset() : 0))); +} + +const char* +DWARFFormValue::getAsCString(const DataExtractor *debug_str_data_ptr) const { + if (isInlinedCStr()) { + return Value.cstr; + } else if (debug_str_data_ptr) { + uint32_t offset = Value.uval; + return debug_str_data_ptr->getCStr(&offset); + } + return NULL; +} + +uint64_t DWARFFormValue::getReference(const DWARFCompileUnit *cu) const { + uint64_t die_offset = Value.uval; + switch (Form) { + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + die_offset += (cu ? cu->getOffset() : 0); + break; + default: + break; + } + + return die_offset; +} + +bool +DWARFFormValue::resolveCompileUnitReferences(const DWARFCompileUnit *cu) { + switch (Form) { + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + Value.uval += cu->getOffset(); + Form = DW_FORM_ref_addr; + return true; + default: + break; + } + return false; +} + +const uint8_t *DWARFFormValue::BlockData() const { + if (!isInlinedCStr()) + return Value.data; + return NULL; +} + +bool DWARFFormValue::isBlockForm(uint16_t form) { + switch (form) { + case DW_FORM_block: + case DW_FORM_block1: + case DW_FORM_block2: + case DW_FORM_block4: + return true; + } + return false; +} + +bool DWARFFormValue::isDataForm(uint16_t form) { + switch (form) { + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_data1: + case DW_FORM_data2: + case DW_FORM_data4: + case DW_FORM_data8: + return true; + } + return false; +} diff --git a/lib/DebugInfo/DWARFFormValue.h b/lib/DebugInfo/DWARFFormValue.h new file mode 100644 index 000000000000..22ac0116646e --- /dev/null +++ b/lib/DebugInfo/DWARFFormValue.h @@ -0,0 +1,78 @@ +//===-- DWARFFormValue.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARFFORMVALUE_H +#define LLVM_DEBUGINFO_DWARFFORMVALUE_H + +#include "llvm/Support/DataExtractor.h" + +namespace llvm { + +class DWARFCompileUnit; +class raw_ostream; + +class DWARFFormValue { +public: + struct ValueType { + ValueType() : data(NULL) { + uval = 0; + } + + union { + uint64_t uval; + int64_t sval; + const char* cstr; + }; + const uint8_t* data; + }; + + enum { + eValueTypeInvalid = 0, + eValueTypeUnsigned, + eValueTypeSigned, + eValueTypeCStr, + eValueTypeBlock + }; + +private: + uint16_t Form; // Form for this value. + ValueType Value; // Contains all data for the form. + +public: + DWARFFormValue(uint16_t form = 0) : Form(form) {} + uint16_t getForm() const { return Form; } + const ValueType& value() const { return Value; } + void dump(raw_ostream &OS, const DWARFCompileUnit* cu) const; + bool extractValue(DataExtractor data, uint32_t *offset_ptr, + const DWARFCompileUnit *cu); + bool isInlinedCStr() const { + return Value.data != NULL && Value.data == (uint8_t*)Value.cstr; + } + const uint8_t *BlockData() const; + uint64_t getReference(const DWARFCompileUnit* cu) const; + + /// Resolve any compile unit specific references so that we don't need + /// the compile unit at a later time in order to work with the form + /// value. + bool resolveCompileUnitReferences(const DWARFCompileUnit* cu); + uint64_t getUnsigned() const { return Value.uval; } + int64_t getSigned() const { return Value.sval; } + const char *getAsCString(const DataExtractor *debug_str_data_ptr) const; + bool skipValue(DataExtractor debug_info_data, uint32_t *offset_ptr, + const DWARFCompileUnit *cu) const; + static bool skipValue(uint16_t form, DataExtractor debug_info_data, + uint32_t *offset_ptr, const DWARFCompileUnit *cu); + static bool isBlockForm(uint16_t form); + static bool isDataForm(uint16_t form); + static const uint8_t *getFixedFormSizesForAddressSize(uint8_t addr_size); +}; + +} + +#endif diff --git a/tools/llvmc/examples/Makefile b/lib/DebugInfo/Makefile similarity index 70% rename from tools/llvmc/examples/Makefile rename to lib/DebugInfo/Makefile index 8468e9310442..1292b5728359 100644 --- a/tools/llvmc/examples/Makefile +++ b/lib/DebugInfo/Makefile @@ -1,4 +1,4 @@ -##===- tools/llvmc/examples/Makefile -----------------------*- Makefile -*-===## +##===- lib/DebugInfo/Makefile ------------------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # @@ -7,8 +7,8 @@ # ##===----------------------------------------------------------------------===## -LEVEL=../../.. - -PARALLEL_DIRS := Hello Simple mcc16 Skeleton +LEVEL = ../.. +LIBRARYNAME = LLVMDebugInfo +BUILD_ARCHIVE := 1 include $(LEVEL)/Makefile.common diff --git a/lib/ExecutionEngine/CMakeLists.txt b/lib/ExecutionEngine/CMakeLists.txt index 58caae830f49..fb14d41e91d2 100644 --- a/lib/ExecutionEngine/CMakeLists.txt +++ b/lib/ExecutionEngine/CMakeLists.txt @@ -4,6 +4,13 @@ add_llvm_library(LLVMExecutionEngine TargetSelect.cpp ) +add_llvm_library_dependencies(LLVMExecutionEngine + LLVMCore + LLVMMC + LLVMSupport + LLVMTarget + ) + add_subdirectory(Interpreter) add_subdirectory(JIT) add_subdirectory(MCJIT) diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 7652090af8f5..525877b68900 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -93,7 +93,7 @@ class GVMemoryBlock : public CallbackVH { /// \brief Returns the address the GlobalVariable should be written into. The /// GVMemoryBlock object prefixes that. static char *Create(const GlobalVariable *GV, const TargetData& TD) { - const Type *ElTy = GV->getType()->getElementType(); + Type *ElTy = GV->getType()->getElementType(); size_t GVSize = (size_t)TD.getTypeAllocSize(ElTy); void *RawMemory = ::operator new( TargetData::RoundUpAlignment(sizeof(GVMemoryBlock), @@ -272,7 +272,7 @@ void *ArgvArray::reset(LLVMContext &C, ExecutionEngine *EE, Array = new char[(InputArgv.size()+1)*PtrSize]; DEBUG(dbgs() << "JIT: ARGV = " << (void*)Array << "\n"); - const Type *SBytePtr = Type::getInt8PtrTy(C); + Type *SBytePtr = Type::getInt8PtrTy(C); for (unsigned i = 0; i != InputArgv.size(); ++i) { unsigned Size = InputArgv[i].size()+1; @@ -361,8 +361,8 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn, // Check main() type unsigned NumArgs = Fn->getFunctionType()->getNumParams(); - const FunctionType *FTy = Fn->getFunctionType(); - const Type* PPInt8Ty = Type::getInt8PtrTy(Fn->getContext())->getPointerTo(); + FunctionType *FTy = Fn->getFunctionType(); + Type* PPInt8Ty = Type::getInt8PtrTy(Fn->getContext())->getPointerTo(); // Check the argument types. if (NumArgs > 3) @@ -422,6 +422,7 @@ ExecutionEngine *ExecutionEngine::createJIT(Module *M, JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool GVsWithCode, + Reloc::Model RM, CodeModel::Model CMM) { if (ExecutionEngine::JITCtor == 0) { if (ErrorStr) @@ -436,9 +437,8 @@ ExecutionEngine *ExecutionEngine::createJIT(Module *M, SmallVector MAttrs; TargetMachine *TM = - EngineBuilder::selectTarget(M, MArch, MCPU, MAttrs, ErrorStr); + EngineBuilder::selectTarget(M, MArch, MCPU, MAttrs, RM, CMM, ErrorStr); if (!TM || (ErrorStr && ErrorStr->length() > 0)) return 0; - TM->setCodeModel(CMM); return ExecutionEngine::JITCtor(M, ErrorStr, JMM, OptLevel, GVsWithCode, TM); } @@ -465,10 +465,9 @@ ExecutionEngine *EngineBuilder::create() { // Unless the interpreter was explicitly selected or the JIT is not linked, // try making a JIT. if (WhichEngine & EngineKind::JIT) { - if (TargetMachine *TM = - EngineBuilder::selectTarget(M, MArch, MCPU, MAttrs, ErrorStr)) { - TM->setCodeModel(CMModel); - + if (TargetMachine *TM = EngineBuilder::selectTarget(M, MArch, MCPU, MAttrs, + RelocModel, CMModel, + ErrorStr)) { if (UseMCJIT && ExecutionEngine::MCJITCtor) { ExecutionEngine *EE = ExecutionEngine::MCJITCtor(M, ErrorStr, JMM, OptLevel, @@ -548,8 +547,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { // Compute the index GenericValue Result = getConstantValue(Op0); SmallVector Indices(CE->op_begin()+1, CE->op_end()); - uint64_t Offset = - TD->getIndexedOffset(Op0->getType(), &Indices[0], Indices.size()); + uint64_t Offset = TD->getIndexedOffset(Op0->getType(), Indices); char* tmp = (char*) Result.PointerVal; Result = PTOGV(tmp + Offset); @@ -651,7 +649,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) { } case Instruction::BitCast: { GenericValue GV = getConstantValue(Op0); - const Type* DestTy = CE->getType(); + Type* DestTy = CE->getType(); switch (Op0->getType()->getTypeID()) { default: llvm_unreachable("Invalid bitcast operand"); case Type::IntegerTyID: @@ -847,7 +845,7 @@ static void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, } void ExecutionEngine::StoreValueToMemory(const GenericValue &Val, - GenericValue *Ptr, const Type *Ty) { + GenericValue *Ptr, Type *Ty) { const unsigned StoreBytes = getTargetData()->getTypeStoreSize(Ty); switch (Ty->getTypeID()) { @@ -909,7 +907,7 @@ static void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes) { /// void ExecutionEngine::LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr, - const Type *Ty) { + Type *Ty) { const unsigned LoadBytes = getTargetData()->getTypeStoreSize(Ty); switch (Ty->getTypeID()) { @@ -932,7 +930,7 @@ void ExecutionEngine::LoadValueFromMemory(GenericValue &Result, // FIXME: Will not trap if loading a signaling NaN. uint64_t y[2]; memcpy(y, Ptr, 10); - Result.IntVal = APInt(80, 2, y); + Result.IntVal = APInt(80, y); break; } default: @@ -986,7 +984,7 @@ void ExecutionEngine::emitGlobals() { // Loop over all of the global variables in the program, allocating the memory // to hold them. If there is more than one module, do a prepass over globals // to figure out how the different modules should link together. - std::map, + std::map, const GlobalValue*> LinkedGlobalsMap; if (Modules.size() != 1) { @@ -1101,7 +1099,7 @@ void ExecutionEngine::EmitGlobalVariable(const GlobalVariable *GV) { if (!GV->isThreadLocal()) InitializeMemory(GV->getInitializer(), GA); - const Type *ElTy = GV->getType()->getElementType(); + Type *ElTy = GV->getType()->getElementType(); size_t GVSize = (size_t)getTargetData()->getTypeAllocSize(ElTy); NumInitBytes += (unsigned)GVSize; ++NumGlobals; diff --git a/lib/ExecutionEngine/Interpreter/CMakeLists.txt b/lib/ExecutionEngine/Interpreter/CMakeLists.txt index d331f830b62e..4fb58c2e3783 100644 --- a/lib/ExecutionEngine/Interpreter/CMakeLists.txt +++ b/lib/ExecutionEngine/Interpreter/CMakeLists.txt @@ -12,6 +12,14 @@ add_llvm_library(LLVMInterpreter Interpreter.cpp ) +add_llvm_library_dependencies(LLVMInterpreter + LLVMCodeGen + LLVMCore + LLVMExecutionEngine + LLVMSupport + LLVMTarget + ) + if( LLVM_ENABLE_FFI ) target_link_libraries( LLVMInterpreter ${FFI_LIBRARY_PATH} ) endif() diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 498063bf6555..27917da07a2c 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -51,7 +51,7 @@ static void SetValue(Value *V, GenericValue Val, ExecutionContext &SF) { break static void executeFAddInst(GenericValue &Dest, GenericValue Src1, - GenericValue Src2, const Type *Ty) { + GenericValue Src2, Type *Ty) { switch (Ty->getTypeID()) { IMPLEMENT_BINARY_OPERATOR(+, Float); IMPLEMENT_BINARY_OPERATOR(+, Double); @@ -62,7 +62,7 @@ static void executeFAddInst(GenericValue &Dest, GenericValue Src1, } static void executeFSubInst(GenericValue &Dest, GenericValue Src1, - GenericValue Src2, const Type *Ty) { + GenericValue Src2, Type *Ty) { switch (Ty->getTypeID()) { IMPLEMENT_BINARY_OPERATOR(-, Float); IMPLEMENT_BINARY_OPERATOR(-, Double); @@ -73,7 +73,7 @@ static void executeFSubInst(GenericValue &Dest, GenericValue Src1, } static void executeFMulInst(GenericValue &Dest, GenericValue Src1, - GenericValue Src2, const Type *Ty) { + GenericValue Src2, Type *Ty) { switch (Ty->getTypeID()) { IMPLEMENT_BINARY_OPERATOR(*, Float); IMPLEMENT_BINARY_OPERATOR(*, Double); @@ -84,7 +84,7 @@ static void executeFMulInst(GenericValue &Dest, GenericValue Src1, } static void executeFDivInst(GenericValue &Dest, GenericValue Src1, - GenericValue Src2, const Type *Ty) { + GenericValue Src2, Type *Ty) { switch (Ty->getTypeID()) { IMPLEMENT_BINARY_OPERATOR(/, Float); IMPLEMENT_BINARY_OPERATOR(/, Double); @@ -95,7 +95,7 @@ static void executeFDivInst(GenericValue &Dest, GenericValue Src1, } static void executeFRemInst(GenericValue &Dest, GenericValue Src1, - GenericValue Src2, const Type *Ty) { + GenericValue Src2, Type *Ty) { switch (Ty->getTypeID()) { case Type::FloatTyID: Dest.FloatVal = fmod(Src1.FloatVal, Src2.FloatVal); @@ -125,7 +125,7 @@ static void executeFRemInst(GenericValue &Dest, GenericValue Src1, break; static GenericValue executeICMP_EQ(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_ICMP(eq,Ty); @@ -138,7 +138,7 @@ static GenericValue executeICMP_EQ(GenericValue Src1, GenericValue Src2, } static GenericValue executeICMP_NE(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_ICMP(ne,Ty); @@ -151,7 +151,7 @@ static GenericValue executeICMP_NE(GenericValue Src1, GenericValue Src2, } static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_ICMP(ult,Ty); @@ -164,7 +164,7 @@ static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue Src2, } static GenericValue executeICMP_SLT(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_ICMP(slt,Ty); @@ -177,7 +177,7 @@ static GenericValue executeICMP_SLT(GenericValue Src1, GenericValue Src2, } static GenericValue executeICMP_UGT(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_ICMP(ugt,Ty); @@ -190,7 +190,7 @@ static GenericValue executeICMP_UGT(GenericValue Src1, GenericValue Src2, } static GenericValue executeICMP_SGT(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_ICMP(sgt,Ty); @@ -203,7 +203,7 @@ static GenericValue executeICMP_SGT(GenericValue Src1, GenericValue Src2, } static GenericValue executeICMP_ULE(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_ICMP(ule,Ty); @@ -216,7 +216,7 @@ static GenericValue executeICMP_ULE(GenericValue Src1, GenericValue Src2, } static GenericValue executeICMP_SLE(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_ICMP(sle,Ty); @@ -229,7 +229,7 @@ static GenericValue executeICMP_SLE(GenericValue Src1, GenericValue Src2, } static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_ICMP(uge,Ty); @@ -242,7 +242,7 @@ static GenericValue executeICMP_UGE(GenericValue Src1, GenericValue Src2, } static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_INTEGER_ICMP(sge,Ty); @@ -256,7 +256,7 @@ static GenericValue executeICMP_SGE(GenericValue Src1, GenericValue Src2, void Interpreter::visitICmpInst(ICmpInst &I) { ExecutionContext &SF = ECStack.back(); - const Type *Ty = I.getOperand(0)->getType(); + Type *Ty = I.getOperand(0)->getType(); GenericValue Src1 = getOperandValue(I.getOperand(0), SF); GenericValue Src2 = getOperandValue(I.getOperand(1), SF); GenericValue R; // Result @@ -286,7 +286,7 @@ void Interpreter::visitICmpInst(ICmpInst &I) { break static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_FCMP(==, Float); @@ -299,7 +299,7 @@ static GenericValue executeFCMP_OEQ(GenericValue Src1, GenericValue Src2, } static GenericValue executeFCMP_ONE(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_FCMP(!=, Float); @@ -313,7 +313,7 @@ static GenericValue executeFCMP_ONE(GenericValue Src1, GenericValue Src2, } static GenericValue executeFCMP_OLE(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_FCMP(<=, Float); @@ -326,7 +326,7 @@ static GenericValue executeFCMP_OLE(GenericValue Src1, GenericValue Src2, } static GenericValue executeFCMP_OGE(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_FCMP(>=, Float); @@ -339,7 +339,7 @@ static GenericValue executeFCMP_OGE(GenericValue Src1, GenericValue Src2, } static GenericValue executeFCMP_OLT(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_FCMP(<, Float); @@ -352,7 +352,7 @@ static GenericValue executeFCMP_OLT(GenericValue Src1, GenericValue Src2, } static GenericValue executeFCMP_OGT(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; switch (Ty->getTypeID()) { IMPLEMENT_FCMP(>, Float); @@ -377,49 +377,49 @@ static GenericValue executeFCMP_OGT(GenericValue Src1, GenericValue Src2, static GenericValue executeFCMP_UEQ(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; IMPLEMENT_UNORDERED(Ty, Src1, Src2) return executeFCMP_OEQ(Src1, Src2, Ty); } static GenericValue executeFCMP_UNE(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; IMPLEMENT_UNORDERED(Ty, Src1, Src2) return executeFCMP_ONE(Src1, Src2, Ty); } static GenericValue executeFCMP_ULE(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; IMPLEMENT_UNORDERED(Ty, Src1, Src2) return executeFCMP_OLE(Src1, Src2, Ty); } static GenericValue executeFCMP_UGE(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; IMPLEMENT_UNORDERED(Ty, Src1, Src2) return executeFCMP_OGE(Src1, Src2, Ty); } static GenericValue executeFCMP_ULT(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; IMPLEMENT_UNORDERED(Ty, Src1, Src2) return executeFCMP_OLT(Src1, Src2, Ty); } static GenericValue executeFCMP_UGT(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; IMPLEMENT_UNORDERED(Ty, Src1, Src2) return executeFCMP_OGT(Src1, Src2, Ty); } static GenericValue executeFCMP_ORD(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; if (Ty->isFloatTy()) Dest.IntVal = APInt(1,(Src1.FloatVal == Src1.FloatVal && @@ -431,7 +431,7 @@ static GenericValue executeFCMP_ORD(GenericValue Src1, GenericValue Src2, } static GenericValue executeFCMP_UNO(GenericValue Src1, GenericValue Src2, - const Type *Ty) { + Type *Ty) { GenericValue Dest; if (Ty->isFloatTy()) Dest.IntVal = APInt(1,(Src1.FloatVal != Src1.FloatVal || @@ -444,7 +444,7 @@ static GenericValue executeFCMP_UNO(GenericValue Src1, GenericValue Src2, void Interpreter::visitFCmpInst(FCmpInst &I) { ExecutionContext &SF = ECStack.back(); - const Type *Ty = I.getOperand(0)->getType(); + Type *Ty = I.getOperand(0)->getType(); GenericValue Src1 = getOperandValue(I.getOperand(0), SF); GenericValue Src2 = getOperandValue(I.getOperand(1), SF); GenericValue R; // Result @@ -475,7 +475,7 @@ void Interpreter::visitFCmpInst(FCmpInst &I) { } static GenericValue executeCmpInst(unsigned predicate, GenericValue Src1, - GenericValue Src2, const Type *Ty) { + GenericValue Src2, Type *Ty) { GenericValue Result; switch (predicate) { case ICmpInst::ICMP_EQ: return executeICMP_EQ(Src1, Src2, Ty); @@ -520,7 +520,7 @@ static GenericValue executeCmpInst(unsigned predicate, GenericValue Src1, void Interpreter::visitBinaryOperator(BinaryOperator &I) { ExecutionContext &SF = ECStack.back(); - const Type *Ty = I.getOperand(0)->getType(); + Type *Ty = I.getOperand(0)->getType(); GenericValue Src1 = getOperandValue(I.getOperand(0), SF); GenericValue Src2 = getOperandValue(I.getOperand(1), SF); GenericValue R; // Result @@ -585,7 +585,7 @@ void Interpreter::exitCalled(GenericValue GV) { /// care of switching to the normal destination BB, if we are returning /// from an invoke. /// -void Interpreter::popStackAndReturnValueToCaller(const Type *RetTy, +void Interpreter::popStackAndReturnValueToCaller(Type *RetTy, GenericValue Result) { // Pop the current stack frame. ECStack.pop_back(); @@ -613,7 +613,7 @@ void Interpreter::popStackAndReturnValueToCaller(const Type *RetTy, void Interpreter::visitReturnInst(ReturnInst &I) { ExecutionContext &SF = ECStack.back(); - const Type *RetTy = Type::getVoidTy(I.getContext()); + Type *RetTy = Type::getVoidTy(I.getContext()); GenericValue Result; // Save away the return value... (if we are not 'ret void') @@ -662,18 +662,21 @@ void Interpreter::visitBranchInst(BranchInst &I) { void Interpreter::visitSwitchInst(SwitchInst &I) { ExecutionContext &SF = ECStack.back(); - GenericValue CondVal = getOperandValue(I.getOperand(0), SF); - const Type *ElTy = I.getOperand(0)->getType(); + Value* Cond = I.getCondition(); + Type *ElTy = Cond->getType(); + GenericValue CondVal = getOperandValue(Cond, SF); // Check to see if any of the cases match... BasicBlock *Dest = 0; - for (unsigned i = 2, e = I.getNumOperands(); i != e; i += 2) - if (executeICMP_EQ(CondVal, getOperandValue(I.getOperand(i), SF), ElTy) - .IntVal != 0) { - Dest = cast(I.getOperand(i+1)); + unsigned NumCases = I.getNumCases(); + // Skip the first item since that's the default case. + for (unsigned i = 1; i < NumCases; ++i) { + GenericValue CaseVal = getOperandValue(I.getCaseValue(i), SF); + if (executeICMP_EQ(CondVal, CaseVal, ElTy).IntVal != 0) { + Dest = cast(I.getSuccessor(i)); break; } - + } if (!Dest) Dest = I.getDefaultDest(); // No cases matched: use default SwitchToNewBasicBlock(Dest, SF); } @@ -730,7 +733,7 @@ void Interpreter::SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF){ void Interpreter::visitAllocaInst(AllocaInst &I) { ExecutionContext &SF = ECStack.back(); - const Type *Ty = I.getType()->getElementType(); // Type to be allocated + Type *Ty = I.getType()->getElementType(); // Type to be allocated // Get the number of elements being allocated by the array... unsigned NumElements = @@ -767,7 +770,7 @@ GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I, uint64_t Total = 0; for (; I != E; ++I) { - if (const StructType *STy = dyn_cast(*I)) { + if (StructType *STy = dyn_cast(*I)) { const StructLayout *SLO = TD.getStructLayout(STy); const ConstantInt *CPU = cast(I.getOperand()); @@ -775,7 +778,7 @@ GenericValue Interpreter::executeGEPOperation(Value *Ptr, gep_type_iterator I, Total += SLO->getElementOffset(Index); } else { - const SequentialType *ST = cast(*I); + SequentialType *ST = cast(*I); // Get the index number for the array... which must be long type... GenericValue IdxGV = getOperandValue(I.getOperand(), SF); @@ -929,34 +932,34 @@ void Interpreter::visitAShr(BinaryOperator &I) { SetValue(&I, Dest, SF); } -GenericValue Interpreter::executeTruncInst(Value *SrcVal, const Type *DstTy, +GenericValue Interpreter::executeTruncInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF) { GenericValue Dest, Src = getOperandValue(SrcVal, SF); - const IntegerType *DITy = cast(DstTy); + IntegerType *DITy = cast(DstTy); unsigned DBitWidth = DITy->getBitWidth(); Dest.IntVal = Src.IntVal.trunc(DBitWidth); return Dest; } -GenericValue Interpreter::executeSExtInst(Value *SrcVal, const Type *DstTy, +GenericValue Interpreter::executeSExtInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF) { GenericValue Dest, Src = getOperandValue(SrcVal, SF); - const IntegerType *DITy = cast(DstTy); + IntegerType *DITy = cast(DstTy); unsigned DBitWidth = DITy->getBitWidth(); Dest.IntVal = Src.IntVal.sext(DBitWidth); return Dest; } -GenericValue Interpreter::executeZExtInst(Value *SrcVal, const Type *DstTy, +GenericValue Interpreter::executeZExtInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF) { GenericValue Dest, Src = getOperandValue(SrcVal, SF); - const IntegerType *DITy = cast(DstTy); + IntegerType *DITy = cast(DstTy); unsigned DBitWidth = DITy->getBitWidth(); Dest.IntVal = Src.IntVal.zext(DBitWidth); return Dest; } -GenericValue Interpreter::executeFPTruncInst(Value *SrcVal, const Type *DstTy, +GenericValue Interpreter::executeFPTruncInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF) { GenericValue Dest, Src = getOperandValue(SrcVal, SF); assert(SrcVal->getType()->isDoubleTy() && DstTy->isFloatTy() && @@ -965,7 +968,7 @@ GenericValue Interpreter::executeFPTruncInst(Value *SrcVal, const Type *DstTy, return Dest; } -GenericValue Interpreter::executeFPExtInst(Value *SrcVal, const Type *DstTy, +GenericValue Interpreter::executeFPExtInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF) { GenericValue Dest, Src = getOperandValue(SrcVal, SF); assert(SrcVal->getType()->isFloatTy() && DstTy->isDoubleTy() && @@ -974,9 +977,9 @@ GenericValue Interpreter::executeFPExtInst(Value *SrcVal, const Type *DstTy, return Dest; } -GenericValue Interpreter::executeFPToUIInst(Value *SrcVal, const Type *DstTy, +GenericValue Interpreter::executeFPToUIInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF) { - const Type *SrcTy = SrcVal->getType(); + Type *SrcTy = SrcVal->getType(); uint32_t DBitWidth = cast(DstTy)->getBitWidth(); GenericValue Dest, Src = getOperandValue(SrcVal, SF); assert(SrcTy->isFloatingPointTy() && "Invalid FPToUI instruction"); @@ -988,9 +991,9 @@ GenericValue Interpreter::executeFPToUIInst(Value *SrcVal, const Type *DstTy, return Dest; } -GenericValue Interpreter::executeFPToSIInst(Value *SrcVal, const Type *DstTy, +GenericValue Interpreter::executeFPToSIInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF) { - const Type *SrcTy = SrcVal->getType(); + Type *SrcTy = SrcVal->getType(); uint32_t DBitWidth = cast(DstTy)->getBitWidth(); GenericValue Dest, Src = getOperandValue(SrcVal, SF); assert(SrcTy->isFloatingPointTy() && "Invalid FPToSI instruction"); @@ -1002,7 +1005,7 @@ GenericValue Interpreter::executeFPToSIInst(Value *SrcVal, const Type *DstTy, return Dest; } -GenericValue Interpreter::executeUIToFPInst(Value *SrcVal, const Type *DstTy, +GenericValue Interpreter::executeUIToFPInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF) { GenericValue Dest, Src = getOperandValue(SrcVal, SF); assert(DstTy->isFloatingPointTy() && "Invalid UIToFP instruction"); @@ -1014,7 +1017,7 @@ GenericValue Interpreter::executeUIToFPInst(Value *SrcVal, const Type *DstTy, return Dest; } -GenericValue Interpreter::executeSIToFPInst(Value *SrcVal, const Type *DstTy, +GenericValue Interpreter::executeSIToFPInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF) { GenericValue Dest, Src = getOperandValue(SrcVal, SF); assert(DstTy->isFloatingPointTy() && "Invalid SIToFP instruction"); @@ -1027,7 +1030,7 @@ GenericValue Interpreter::executeSIToFPInst(Value *SrcVal, const Type *DstTy, } -GenericValue Interpreter::executePtrToIntInst(Value *SrcVal, const Type *DstTy, +GenericValue Interpreter::executePtrToIntInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF) { uint32_t DBitWidth = cast(DstTy)->getBitWidth(); GenericValue Dest, Src = getOperandValue(SrcVal, SF); @@ -1037,7 +1040,7 @@ GenericValue Interpreter::executePtrToIntInst(Value *SrcVal, const Type *DstTy, return Dest; } -GenericValue Interpreter::executeIntToPtrInst(Value *SrcVal, const Type *DstTy, +GenericValue Interpreter::executeIntToPtrInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF) { GenericValue Dest, Src = getOperandValue(SrcVal, SF); assert(DstTy->isPointerTy() && "Invalid PtrToInt instruction"); @@ -1050,10 +1053,10 @@ GenericValue Interpreter::executeIntToPtrInst(Value *SrcVal, const Type *DstTy, return Dest; } -GenericValue Interpreter::executeBitCastInst(Value *SrcVal, const Type *DstTy, +GenericValue Interpreter::executeBitCastInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF) { - const Type *SrcTy = SrcVal->getType(); + Type *SrcTy = SrcVal->getType(); GenericValue Dest, Src = getOperandValue(SrcVal, SF); if (DstTy->isPointerTy()) { assert(SrcTy->isPointerTy() && "Invalid BitCast"); @@ -1155,7 +1158,7 @@ void Interpreter::visitVAArgInst(VAArgInst &I) { GenericValue Dest; GenericValue Src = ECStack[VAList.UIntPairVal.first] .VarArgs[VAList.UIntPairVal.second]; - const Type *Ty = I.getType(); + Type *Ty = I.getType(); switch (Ty->getTypeID()) { case Type::IntegerTyID: Dest.IntVal = Src.IntVal; IMPLEMENT_VAARG(Pointer); @@ -1222,7 +1225,7 @@ GenericValue Interpreter::getConstantExprValue (ConstantExpr *CE, GenericValue Op0 = getOperandValue(CE->getOperand(0), SF); GenericValue Op1 = getOperandValue(CE->getOperand(1), SF); GenericValue Dest; - const Type * Ty = CE->getOperand(0)->getType(); + Type * Ty = CE->getOperand(0)->getType(); switch (CE->getOpcode()) { case Instruction::Add: Dest.IntVal = Op0.IntVal + Op1.IntVal; break; case Instruction::Sub: Dest.IntVal = Op0.IntVal - Op1.IntVal; break; diff --git a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp index f7e2a4df951e..055875c9456a 100644 --- a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp +++ b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp @@ -48,7 +48,7 @@ using namespace llvm; static ManagedStatic FunctionsLock; -typedef GenericValue (*ExFunc)(const FunctionType *, +typedef GenericValue (*ExFunc)(FunctionType *, const std::vector &); static ManagedStatic > ExportedFunctions; static std::map FuncNames; @@ -60,7 +60,7 @@ static ManagedStatic > RawFunctions; static Interpreter *TheInterpreter; -static char getTypeID(const Type *Ty) { +static char getTypeID(Type *Ty) { switch (Ty->getTypeID()) { case Type::VoidTyID: return 'V'; case Type::IntegerTyID: @@ -91,7 +91,7 @@ static ExFunc lookupFunction(const Function *F) { // Function not found, look it up... start by figuring out what the // composite function name should be. std::string ExtName = "lle_"; - const FunctionType *FT = F->getFunctionType(); + FunctionType *FT = F->getFunctionType(); for (unsigned i = 0, e = FT->getNumContainedTypes(); i != e; ++i) ExtName += getTypeID(FT->getContainedType(i)); ExtName + "_" + F->getNameStr(); @@ -109,7 +109,7 @@ static ExFunc lookupFunction(const Function *F) { } #ifdef USE_LIBFFI -static ffi_type *ffiTypeFor(const Type *Ty) { +static ffi_type *ffiTypeFor(Type *Ty) { switch (Ty->getTypeID()) { case Type::VoidTyID: return &ffi_type_void; case Type::IntegerTyID: @@ -129,7 +129,7 @@ static ffi_type *ffiTypeFor(const Type *Ty) { return NULL; } -static void *ffiValueFor(const Type *Ty, const GenericValue &AV, +static void *ffiValueFor(Type *Ty, const GenericValue &AV, void *ArgDataPtr) { switch (Ty->getTypeID()) { case Type::IntegerTyID: @@ -181,7 +181,7 @@ static bool ffiInvoke(RawFunc Fn, Function *F, const std::vector &ArgVals, const TargetData *TD, GenericValue &Result) { ffi_cif cif; - const FunctionType *FTy = F->getFunctionType(); + FunctionType *FTy = F->getFunctionType(); const unsigned NumArgs = F->arg_size(); // TODO: We don't have type information about the remaining arguments, because @@ -197,7 +197,7 @@ static bool ffiInvoke(RawFunc Fn, Function *F, for (Function::const_arg_iterator A = F->arg_begin(), E = F->arg_end(); A != E; ++A) { const unsigned ArgNo = A->getArgNo(); - const Type *ArgTy = FTy->getParamType(ArgNo); + Type *ArgTy = FTy->getParamType(ArgNo); args[ArgNo] = ffiTypeFor(ArgTy); ArgBytes += TD->getTypeStoreSize(ArgTy); } @@ -209,12 +209,12 @@ static bool ffiInvoke(RawFunc Fn, Function *F, for (Function::const_arg_iterator A = F->arg_begin(), E = F->arg_end(); A != E; ++A) { const unsigned ArgNo = A->getArgNo(); - const Type *ArgTy = FTy->getParamType(ArgNo); + Type *ArgTy = FTy->getParamType(ArgNo); values[ArgNo] = ffiValueFor(ArgTy, ArgVals[ArgNo], ArgDataPtr); ArgDataPtr += TD->getTypeStoreSize(ArgTy); } - const Type *RetTy = FTy->getReturnType(); + Type *RetTy = FTy->getReturnType(); ffi_type *rtype = ffiTypeFor(RetTy); if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NumArgs, rtype, &args[0]) == FFI_OK) { @@ -304,7 +304,7 @@ GenericValue Interpreter::callExternalFunction(Function *F, extern "C" { // Don't add C++ manglings to llvm mangling :) // void atexit(Function*) -GenericValue lle_X_atexit(const FunctionType *FT, +GenericValue lle_X_atexit(FunctionType *FT, const std::vector &Args) { assert(Args.size() == 1); TheInterpreter->addAtExitHandler((Function*)GVTOP(Args[0])); @@ -314,14 +314,14 @@ GenericValue lle_X_atexit(const FunctionType *FT, } // void exit(int) -GenericValue lle_X_exit(const FunctionType *FT, +GenericValue lle_X_exit(FunctionType *FT, const std::vector &Args) { TheInterpreter->exitCalled(Args[0]); return GenericValue(); } // void abort(void) -GenericValue lle_X_abort(const FunctionType *FT, +GenericValue lle_X_abort(FunctionType *FT, const std::vector &Args) { //FIXME: should we report or raise here? //report_fatal_error("Interpreted program raised SIGABRT"); @@ -331,7 +331,7 @@ GenericValue lle_X_abort(const FunctionType *FT, // int sprintf(char *, const char *, ...) - a very rough implementation to make // output useful. -GenericValue lle_X_sprintf(const FunctionType *FT, +GenericValue lle_X_sprintf(FunctionType *FT, const std::vector &Args) { char *OutputBuffer = (char *)GVTOP(Args[0]); const char *FmtStr = (const char *)GVTOP(Args[1]); @@ -413,7 +413,7 @@ GenericValue lle_X_sprintf(const FunctionType *FT, // int printf(const char *, ...) - a very rough implementation to make output // useful. -GenericValue lle_X_printf(const FunctionType *FT, +GenericValue lle_X_printf(FunctionType *FT, const std::vector &Args) { char Buffer[10000]; std::vector NewArgs; @@ -425,7 +425,7 @@ GenericValue lle_X_printf(const FunctionType *FT, } // int sscanf(const char *format, ...); -GenericValue lle_X_sscanf(const FunctionType *FT, +GenericValue lle_X_sscanf(FunctionType *FT, const std::vector &args) { assert(args.size() < 10 && "Only handle up to 10 args to sscanf right now!"); @@ -440,7 +440,7 @@ GenericValue lle_X_sscanf(const FunctionType *FT, } // int scanf(const char *format, ...); -GenericValue lle_X_scanf(const FunctionType *FT, +GenericValue lle_X_scanf(FunctionType *FT, const std::vector &args) { assert(args.size() < 10 && "Only handle up to 10 args to scanf right now!"); @@ -456,7 +456,7 @@ GenericValue lle_X_scanf(const FunctionType *FT, // int fprintf(FILE *, const char *, ...) - a very rough implementation to make // output useful. -GenericValue lle_X_fprintf(const FunctionType *FT, +GenericValue lle_X_fprintf(FunctionType *FT, const std::vector &Args) { assert(Args.size() >= 2); char Buffer[10000]; diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h index bfebe3debfcd..ee2b4596f38f 100644 --- a/lib/ExecutionEngine/Interpreter/Interpreter.h +++ b/lib/ExecutionEngine/Interpreter/Interpreter.h @@ -174,7 +174,7 @@ class Interpreter : public ExecutionEngine, public InstVisitor { void visitVAArgInst(VAArgInst &I); void visitInstruction(Instruction &I) { - errs() << I; + errs() << I << "\n"; llvm_unreachable("Instruction not interpretable yet!"); } @@ -207,33 +207,33 @@ class Interpreter : public ExecutionEngine, public InstVisitor { void initializeExternalFunctions(); GenericValue getConstantExprValue(ConstantExpr *CE, ExecutionContext &SF); GenericValue getOperandValue(Value *V, ExecutionContext &SF); - GenericValue executeTruncInst(Value *SrcVal, const Type *DstTy, + GenericValue executeTruncInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF); - GenericValue executeSExtInst(Value *SrcVal, const Type *DstTy, + GenericValue executeSExtInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF); - GenericValue executeZExtInst(Value *SrcVal, const Type *DstTy, + GenericValue executeZExtInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF); - GenericValue executeFPTruncInst(Value *SrcVal, const Type *DstTy, + GenericValue executeFPTruncInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF); - GenericValue executeFPExtInst(Value *SrcVal, const Type *DstTy, + GenericValue executeFPExtInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF); - GenericValue executeFPToUIInst(Value *SrcVal, const Type *DstTy, + GenericValue executeFPToUIInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF); - GenericValue executeFPToSIInst(Value *SrcVal, const Type *DstTy, + GenericValue executeFPToSIInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF); - GenericValue executeUIToFPInst(Value *SrcVal, const Type *DstTy, + GenericValue executeUIToFPInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF); - GenericValue executeSIToFPInst(Value *SrcVal, const Type *DstTy, + GenericValue executeSIToFPInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF); - GenericValue executePtrToIntInst(Value *SrcVal, const Type *DstTy, + GenericValue executePtrToIntInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF); - GenericValue executeIntToPtrInst(Value *SrcVal, const Type *DstTy, + GenericValue executeIntToPtrInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF); - GenericValue executeBitCastInst(Value *SrcVal, const Type *DstTy, + GenericValue executeBitCastInst(Value *SrcVal, Type *DstTy, ExecutionContext &SF); GenericValue executeCastOperation(Instruction::CastOps opcode, Value *SrcVal, - const Type *Ty, ExecutionContext &SF); - void popStackAndReturnValueToCaller(const Type *RetTy, GenericValue Result); + Type *Ty, ExecutionContext &SF); + void popStackAndReturnValueToCaller(Type *RetTy, GenericValue Result); }; diff --git a/lib/ExecutionEngine/JIT/CMakeLists.txt b/lib/ExecutionEngine/JIT/CMakeLists.txt index cefb0aedde0b..598e50e79460 100644 --- a/lib/ExecutionEngine/JIT/CMakeLists.txt +++ b/lib/ExecutionEngine/JIT/CMakeLists.txt @@ -10,3 +10,11 @@ add_llvm_library(LLVMJIT JITMemoryManager.cpp OProfileJITEventListener.cpp ) + +add_llvm_library_dependencies(LLVMJIT + LLVMCore + LLVMExecutionEngine + LLVMRuntimeDyld + LLVMSupport + LLVMTarget + ) diff --git a/lib/ExecutionEngine/JIT/Intercept.cpp b/lib/ExecutionEngine/JIT/Intercept.cpp index fa8bee460427..2251a8e6b077 100644 --- a/lib/ExecutionEngine/JIT/Intercept.cpp +++ b/lib/ExecutionEngine/JIT/Intercept.cpp @@ -52,6 +52,7 @@ static void runAtExitHandlers() { #include #endif #include +#include /* stat functions are redirecting to __xstat with a version number. On x86-64 * linking with libc_nonshared.a and -Wl,--export-dynamic doesn't make 'stat' * available as an exported symbol, so we have to add it explicitly. diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp index 445d2d0670c8..d773009065b5 100644 --- a/lib/ExecutionEngine/JIT/JIT.cpp +++ b/lib/ExecutionEngine/JIT/JIT.cpp @@ -390,8 +390,8 @@ GenericValue JIT::runFunction(Function *F, void *FPtr = getPointerToFunction(F); assert(FPtr && "Pointer to fn's code was null after getPointerToFunction"); - const FunctionType *FTy = F->getFunctionType(); - const Type *RetTy = FTy->getReturnType(); + FunctionType *FTy = F->getFunctionType(); + Type *RetTy = FTy->getReturnType(); assert((FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && @@ -500,7 +500,7 @@ GenericValue JIT::runFunction(Function *F, SmallVector Args; for (unsigned i = 0, e = ArgValues.size(); i != e; ++i) { Constant *C = 0; - const Type *ArgTy = FTy->getParamType(i); + Type *ArgTy = FTy->getParamType(i); const GenericValue &AV = ArgValues[i]; switch (ArgTy->getTypeID()) { default: llvm_unreachable("Unknown argument type for function call!"); @@ -788,7 +788,7 @@ char* JIT::getMemoryForGV(const GlobalVariable* GV) { // be allocated into the same buffer, but in general globals are allocated // through the memory manager which puts them near the code but not in the // same buffer. - const Type *GlobalType = GV->getType()->getElementType(); + Type *GlobalType = GV->getType()->getElementType(); size_t S = getTargetData()->getTypeAllocSize(GlobalType); size_t A = getTargetData()->getPreferredAlignment(GV); if (GV->isThreadLocal()) { diff --git a/lib/ExecutionEngine/JIT/JIT.h b/lib/ExecutionEngine/JIT/JIT.h index b879fc36e59b..92dcb0e99586 100644 --- a/lib/ExecutionEngine/JIT/JIT.h +++ b/lib/ExecutionEngine/JIT/JIT.h @@ -100,9 +100,10 @@ class JIT : public ExecutionEngine { CodeGenOpt::Level OptLevel = CodeGenOpt::Default, bool GVsWithCode = true, - CodeModel::Model CMM = CodeModel::Default) { + Reloc::Model RM = Reloc::Default, + CodeModel::Model CMM = CodeModel::JITDefault) { return ExecutionEngine::createJIT(M, Err, JMM, OptLevel, GVsWithCode, - CMM); + RM, CMM); } virtual void addModule(Module *M); diff --git a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp index ddb0d5478596..8f84ac7b4126 100644 --- a/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITDwarfEmitter.cpp @@ -18,12 +18,12 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/CodeGen/JITCodeEmitter.h" #include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineLocation.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/ExecutionEngine/JITMemoryManager.h" -#include "llvm/Support/ErrorHandling.h" +#include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetFrameLowering.h" @@ -45,7 +45,7 @@ unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F, TD = TM.getTargetData(); stackGrowthDirection = TM.getFrameLowering()->getStackGrowthDirection(); RI = TM.getRegisterInfo(); - TFI = TM.getFrameLowering(); + MAI = TM.getMCAsmInfo(); JCE = &jce; unsigned char* ExceptionTable = EmitExceptionTable(&F, StartFunction, @@ -523,9 +523,7 @@ JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const { JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); } - std::vector Moves; - TFI->getInitialFrameState(Moves); - EmitFrameMoves(0, Moves); + EmitFrameMoves(0, MAI->getInitialFrameState()); JCE->emitAlignmentWithFill(PointerSize, dwarf::DW_CFA_nop); diff --git a/lib/ExecutionEngine/JIT/JITDwarfEmitter.h b/lib/ExecutionEngine/JIT/JITDwarfEmitter.h index e1d00454d8d2..8dc99abc4224 100644 --- a/lib/ExecutionEngine/JIT/JITDwarfEmitter.h +++ b/lib/ExecutionEngine/JIT/JITDwarfEmitter.h @@ -22,8 +22,8 @@ class JITCodeEmitter; class MachineFunction; class MachineModuleInfo; class MachineMove; +class MCAsmInfo; class TargetData; -class TargetFrameLowering; class TargetMachine; class TargetRegisterInfo; @@ -31,7 +31,7 @@ class JITDwarfEmitter { const TargetData* TD; JITCodeEmitter* JCE; const TargetRegisterInfo* RI; - const TargetFrameLowering *TFI; + const MCAsmInfo *MAI; MachineModuleInfo* MMI; JIT& Jit; bool stackGrowthDirection; diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index d046b8aea641..24020ee6d689 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -668,6 +668,7 @@ void *JITResolver::JITCompilerFn(void *Stub) { DEBUG(dbgs() << "JIT: Lazily resolving function '" << F->getName() << "' In stub ptr = " << Stub << " actual ptr = " << ActualPtr << "\n"); + (void)ActualPtr; Result = JR->TheJIT->getPointerToFunction(F); } @@ -770,7 +771,7 @@ static unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP, MachineConstantPoolEntry CPE = Constants[i]; unsigned AlignMask = CPE.getAlignment() - 1; Size = (Size + AlignMask) & ~AlignMask; - const Type *Ty = CPE.getType(); + Type *Ty = CPE.getType(); Size += TD->getTypeAllocSize(Ty); } return Size; @@ -1098,7 +1099,7 @@ void JITEmitter::emitConstantPool(MachineConstantPool *MCP) { DEBUG(dbgs() << "JIT: CP" << i << " at [0x"; dbgs().write_hex(CAddr) << "]\n"); - const Type *Ty = CPE.Val.ConstVal->getType(); + Type *Ty = CPE.Val.ConstVal->getType(); Offset += TheJIT->getTargetData()->getTypeAllocSize(Ty); } } diff --git a/lib/ExecutionEngine/MCJIT/CMakeLists.txt b/lib/ExecutionEngine/MCJIT/CMakeLists.txt index 38fdffa0e991..aae8a1b2c521 100644 --- a/lib/ExecutionEngine/MCJIT/CMakeLists.txt +++ b/lib/ExecutionEngine/MCJIT/CMakeLists.txt @@ -2,3 +2,11 @@ add_llvm_library(LLVMMCJIT MCJIT.cpp Intercept.cpp ) + +add_llvm_library_dependencies(LLVMMCJIT + LLVMCore + LLVMExecutionEngine + LLVMRuntimeDyld + LLVMSupport + LLVMTarget + ) diff --git a/lib/ExecutionEngine/MCJIT/Intercept.cpp b/lib/ExecutionEngine/MCJIT/Intercept.cpp index e431c848d630..f83f4282e016 100644 --- a/lib/ExecutionEngine/MCJIT/Intercept.cpp +++ b/lib/ExecutionEngine/MCJIT/Intercept.cpp @@ -52,6 +52,7 @@ static void runAtExitHandlers() { #include #endif #include +#include /* stat functions are redirecting to __xstat with a version number. On x86-64 * linking with libc_nonshared.a and -Wl,--export-dynamic doesn't make 'stat' * available as an exported symbol, so we have to add it explicitly. diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 4475f4d5c0d8..7c8a740dc862 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -59,6 +59,7 @@ MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji, bool AllocateGVsWithCode) : ExecutionEngine(m), TM(tm), MemMgr(MM), M(m), OS(Buffer), Dyld(MM) { + setTargetData(TM->getTargetData()); PM.add(new TargetData(*TM->getTargetData())); // Turn the machine code intermediate representation into bytes in memory @@ -124,8 +125,8 @@ GenericValue MCJIT::runFunction(Function *F, void *FPtr = getPointerToFunction(F); assert(FPtr && "Pointer to fn's code was null after getPointerToFunction"); - const FunctionType *FTy = F->getFunctionType(); - const Type *RetTy = FTy->getReturnType(); + FunctionType *FTy = F->getFunctionType(); + Type *RetTy = FTy->getReturnType(); assert((FTy->getNumParams() == ArgValues.size() || (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && @@ -216,6 +217,6 @@ GenericValue MCJIT::runFunction(Function *F, } } - assert("Full-featured argument passing not supported yet!"); + assert(0 && "Full-featured argument passing not supported yet!"); return GenericValue(); } diff --git a/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt b/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt index 59bdfee3db43..c236d1d9d115 100644 --- a/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt +++ b/lib/ExecutionEngine/RuntimeDyld/CMakeLists.txt @@ -2,3 +2,8 @@ add_llvm_library(LLVMRuntimeDyld RuntimeDyld.cpp RuntimeDyldMachO.cpp ) + +add_llvm_library_dependencies(LLVMRuntimeDyld + LLVMObject + LLVMSupport + ) diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index bcdfb04801a5..7190a3c36fe9 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -143,7 +143,7 @@ class RuntimeDyldMachO : public RuntimeDyldImpl { bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const { return isKnownFormat(InputBuffer); - }; + } }; } // end namespace llvm diff --git a/lib/ExecutionEngine/TargetSelect.cpp b/lib/ExecutionEngine/TargetSelect.cpp index f51aff3603b8..004b8656bf22 100644 --- a/lib/ExecutionEngine/TargetSelect.cpp +++ b/lib/ExecutionEngine/TargetSelect.cpp @@ -17,11 +17,11 @@ #include "llvm/Module.h" #include "llvm/ADT/Triple.h" #include "llvm/MC/SubtargetFeature.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Host.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegistry.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; /// selectTarget - Pick a target either via -march or by guessing the native @@ -30,6 +30,8 @@ TargetMachine *EngineBuilder::selectTarget(Module *Mod, StringRef MArch, StringRef MCPU, const SmallVectorImpl& MAttrs, + Reloc::Model RM, + CodeModel::Model CM, std::string *ErrorStr) { Triple TheTriple(Mod->getTargetTriple()); if (TheTriple.getTriple().empty()) @@ -83,8 +85,9 @@ TargetMachine *EngineBuilder::selectTarget(Module *Mod, } // Allocate a target... - TargetMachine *Target = - TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr); + TargetMachine *Target = TheTarget->createTargetMachine(TheTriple.getTriple(), + MCPU, FeaturesStr, + RM, CM); assert(Target && "Could not allocate target machine!"); return Target; } diff --git a/lib/Linker/CMakeLists.txt b/lib/Linker/CMakeLists.txt index 0b6d2f4218e3..4d8824bfcb3f 100644 --- a/lib/Linker/CMakeLists.txt +++ b/lib/Linker/CMakeLists.txt @@ -4,3 +4,11 @@ add_llvm_library(LLVMLinker LinkModules.cpp Linker.cpp ) + +add_llvm_library_dependencies(LLVMLinker + LLVMArchive + LLVMBitReader + LLVMCore + LLVMSupport + LLVMTransformUtils + ) diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 55aa9bf18887..03a962e3be5d 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -14,9 +14,12 @@ #include "llvm/Linker.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" #include "llvm/Module.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Path.h" +#include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/ValueMapper.h" using namespace llvm; @@ -139,7 +142,7 @@ bool TypeMapTy::areTypesIsomorphic(Type *DstTy, Type *SrcTy) { return false; } else if (StructType *DSTy = dyn_cast(DstTy)) { StructType *SSTy = cast(SrcTy); - if (DSTy->isAnonymous() != SSTy->isAnonymous() || + if (DSTy->isLiteral() != SSTy->isLiteral() || DSTy->isPacked() != SSTy->isPacked()) return false; } else if (ArrayType *DATy = dyn_cast(DstTy)) { @@ -223,7 +226,7 @@ Type *TypeMapTy::getImpl(Type *Ty) { // If this is not a named struct type, then just map all of the elements and // then rebuild the type from inside out. - if (!isa(Ty) || cast(Ty)->isAnonymous()) { + if (!isa(Ty) || cast(Ty)->isLiteral()) { // If there are no element types to map, then the type is itself. This is // true for the anonymous {} struct, things like 'float', integers, etc. if (Ty->getNumContainedTypes() == 0) @@ -261,7 +264,7 @@ Type *TypeMapTy::getImpl(Type *Ty) { cast(Ty)->getAddressSpace()); case Type::FunctionTyID: return *Entry = FunctionType::get(ElementTypes[0], - ArrayRef(ElementTypes).slice(1), + makeArrayRef(ElementTypes).slice(1), cast(Ty)->isVarArg()); case Type::StructTyID: // Note that this is only reached for anonymous structs. @@ -302,7 +305,7 @@ Type *TypeMapTy::getImpl(Type *Ty) { // Otherwise we create a new type and resolve its body later. This will be // resolved by the top level of get(). DefinitionsToResolve.push_back(STy); - return *Entry = StructType::createNamed(STy->getContext(), ""); + return *Entry = StructType::create(STy->getContext()); } @@ -333,10 +336,16 @@ namespace { std::vector AppendingVars; + unsigned Mode; // Mode to treat source module. + + // Set of items not to link in from source. + SmallPtrSet DoNotLinkFromSource; + public: std::string ErrorMsg; - ModuleLinker(Module *dstM, Module *srcM) : DstM(dstM), SrcM(srcM) { } + ModuleLinker(Module *dstM, Module *srcM, unsigned mode) + : DstM(dstM), SrcM(srcM), Mode(mode) { } bool run(); @@ -596,9 +605,9 @@ bool ModuleLinker::linkAppendingVarProto(GlobalVariable *DstGV, DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType())); DstGV->eraseFromParent(); - // Zap the initializer in the source variable so we don't try to link it. - SrcGV->setInitializer(0); - SrcGV->setLinkage(GlobalValue::ExternalLinkage); + // Track the source variable so we don't try to link it. + DoNotLinkFromSource.insert(SrcGV); + return false; } @@ -633,11 +642,10 @@ bool ModuleLinker::linkGlobalProto(GlobalVariable *SGV) { // Make sure to remember this mapping. ValueMap[SGV] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGV->getType())); - // Destroy the source global's initializer (and convert it to a prototype) - // so that we don't attempt to copy it over when processing global - // initializers. - SGV->setInitializer(0); - SGV->setLinkage(GlobalValue::ExternalLinkage); + // Track the source global so that we don't attempt to copy it over when + // processing global initializers. + DoNotLinkFromSource.insert(SGV); + return false; } } @@ -682,8 +690,10 @@ bool ModuleLinker::linkFunctionProto(Function *SF) { // Make sure to remember this mapping. ValueMap[SF] = ConstantExpr::getBitCast(DGV, TypeMap.get(SF->getType())); - // Remove the body from the source module so we don't attempt to remap it. - SF->deleteBody(); + // Track the function from the source module so we don't attempt to remap + // it. + DoNotLinkFromSource.insert(SF); + return false; } } @@ -722,8 +732,9 @@ bool ModuleLinker::linkAliasProto(GlobalAlias *SGA) { // Make sure to remember this mapping. ValueMap[SGA] = ConstantExpr::getBitCast(DGV,TypeMap.get(SGA->getType())); - // Remove the body from the source module so we don't attempt to remap it. - SGA->setAliasee(0); + // Track the alias from the source module so we don't attempt to remap it. + DoNotLinkFromSource.insert(SGA); + return false; } } @@ -779,7 +790,9 @@ void ModuleLinker::linkGlobalInits() { // Loop over all of the globals in the src module, mapping them over as we go for (Module::const_global_iterator I = SrcM->global_begin(), E = SrcM->global_end(); I != E; ++I) { - if (!I->hasInitializer()) continue; // Only process initialized GV's. + + // Only process initialized GV's or ones not already in dest. + if (!I->hasInitializer() || DoNotLinkFromSource.count(I)) continue; // Grab destination global variable. GlobalVariable *DGV = cast(ValueMap[I]); @@ -805,31 +818,42 @@ void ModuleLinker::linkFunctionBody(Function *Dst, Function *Src) { ValueMap[I] = DI; } - // Splice the body of the source function into the dest function. - Dst->getBasicBlockList().splice(Dst->end(), Src->getBasicBlockList()); - - // At this point, all of the instructions and values of the function are now - // copied over. The only problem is that they are still referencing values in - // the Source function as operands. Loop through all of the operands of the - // functions and patch them up to point to the local versions. - for (Function::iterator BB = Dst->begin(), BE = Dst->end(); BB != BE; ++BB) - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) - RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries, &TypeMap); - + if (Mode == Linker::DestroySource) { + // Splice the body of the source function into the dest function. + Dst->getBasicBlockList().splice(Dst->end(), Src->getBasicBlockList()); + + // At this point, all of the instructions and values of the function are now + // copied over. The only problem is that they are still referencing values in + // the Source function as operands. Loop through all of the operands of the + // functions and patch them up to point to the local versions. + for (Function::iterator BB = Dst->begin(), BE = Dst->end(); BB != BE; ++BB) + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + RemapInstruction(I, ValueMap, RF_IgnoreMissingEntries, &TypeMap); + + } else { + // Clone the body of the function into the dest function. + SmallVector Returns; // Ignore returns. + CloneFunctionInto(Dst, Src, ValueMap, false, Returns); + } + // There is no need to map the arguments anymore. for (Function::arg_iterator I = Src->arg_begin(), E = Src->arg_end(); I != E; ++I) ValueMap.erase(I); + } void ModuleLinker::linkAliasBodies() { for (Module::alias_iterator I = SrcM->alias_begin(), E = SrcM->alias_end(); - I != E; ++I) + I != E; ++I) { + if (DoNotLinkFromSource.count(I)) + continue; if (Constant *Aliasee = I->getAliasee()) { GlobalAlias *DA = cast(ValueMap[I]); DA->setAliasee(MapValue(Aliasee, ValueMap, RF_None, &TypeMap)); } + } } /// linkNamedMDNodes - Insert all of the named mdnodes in Src into the Dest @@ -891,16 +915,10 @@ bool ModuleLinker::run() { StringRef ModuleId = SrcM->getModuleIdentifier(); if (!ModuleId.empty()) DstM->removeLibrary(sys::path::stem(ModuleId)); - // Loop over all of the linked values to compute type mappings. computeTypeMapping(); - // Remap all of the named mdnoes in Src into the DstM module. We do this - // after linking GlobalValues so that MDNodes that reference GlobalValues - // are properly remapped. - linkNamedMDNodes(); - // Insert all of the globals in src into the DstM module... without linking // initializers (which could refer to functions not yet mapped over). for (Module::global_iterator I = SrcM->global_begin(), @@ -933,7 +951,17 @@ bool ModuleLinker::run() { // Link in the function bodies that are defined in the source module into // DstM. for (Module::iterator SF = SrcM->begin(), E = SrcM->end(); SF != E; ++SF) { - if (SF->isDeclaration()) continue; // No body if function is external. + + // Skip if not linking from source. + if (DoNotLinkFromSource.count(SF)) continue; + + // Skip if no body (function is external) or materialize. + if (SF->isDeclaration()) { + if (!SF->isMaterializable()) + continue; + if (SF->Materialize(&ErrorMsg)) + return true; + } linkFunctionBody(cast(ValueMap[SF]), SF); } @@ -941,6 +969,11 @@ bool ModuleLinker::run() { // Resolve all uses of aliases with aliasees. linkAliasBodies(); + // Remap all of the named mdnoes in Src into the DstM module. We do this + // after linking GlobalValues so that MDNodes that reference GlobalValues + // are properly remapped. + linkNamedMDNodes(); + // Now that all of the types from the source are used, resolve any structs // copied over to the dest that didn't exist there. TypeMap.linkDefinedTypeBodies(); @@ -957,8 +990,9 @@ bool ModuleLinker::run() { // error occurs, true is returned and ErrorMsg (if not null) is set to indicate // the problem. Upon failure, the Dest module could be in a modified state, and // shouldn't be relied on to be consistent. -bool Linker::LinkModules(Module *Dest, Module *Src, std::string *ErrorMsg) { - ModuleLinker TheLinker(Dest, Src); +bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Mode, + std::string *ErrorMsg) { + ModuleLinker TheLinker(Dest, Src, Mode); if (TheLinker.run()) { if (ErrorMsg) *ErrorMsg = TheLinker.ErrorMsg; return true; diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp index fba91da5ddd1..59fbceb6a308 100644 --- a/lib/Linker/Linker.cpp +++ b/lib/Linker/Linker.cpp @@ -141,6 +141,14 @@ static inline sys::Path IsLibrary(StringRef Name, if (FullPath.isBitcodeFile()) // .so file containing bitcode? return FullPath; + // Try libX form, to make it possible to add dependency on the + // specific version of .so, like liblzma.so.1.0.0 + FullPath.eraseSuffix(); + if (FullPath.isDynamicLibrary()) // Native shared library? + return FullPath; + if (FullPath.isBitcodeFile()) // .so file containing bitcode? + return FullPath; + // Not found .. fall through // Indicate that the library was not found in the directory. diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt index 22afa7e91cbe..a4ac1bf60529 100644 --- a/lib/MC/CMakeLists.txt +++ b/lib/MC/CMakeLists.txt @@ -1,25 +1,31 @@ add_llvm_library(LLVMMC ELFObjectWriter.cpp + MCAsmBackend.cpp MCAsmInfo.cpp MCAsmInfoCOFF.cpp MCAsmInfoDarwin.cpp MCAsmStreamer.cpp MCAssembler.cpp + MCAtom.cpp MCCodeEmitter.cpp + MCCodeGenInfo.cpp MCContext.cpp MCDisassembler.cpp + MCDwarf.cpp MCELF.cpp MCELFObjectTargetWriter.cpp MCELFStreamer.cpp MCExpr.cpp MCInst.cpp MCInstPrinter.cpp + MCInstrAnalysis.cpp MCLabel.cpp - MCDwarf.cpp MCLoggingStreamer.cpp MCMachOStreamer.cpp MCMachObjectTargetWriter.cpp + MCModule.cpp MCNullStreamer.cpp + MCObjectFileInfo.cpp MCObjectStreamer.cpp MCObjectWriter.cpp MCPureStreamer.cpp @@ -30,13 +36,18 @@ add_llvm_library(LLVMMC MCStreamer.cpp MCSubtargetInfo.cpp MCSymbol.cpp + MCTargetAsmLexer.cpp MCValue.cpp MCWin64EH.cpp MachObjectWriter.cpp - WinCOFFStreamer.cpp - WinCOFFObjectWriter.cpp SubtargetFeature.cpp - TargetAsmBackend.cpp + WinCOFFObjectWriter.cpp + WinCOFFStreamer.cpp + ) + +add_llvm_library_dependencies(LLVMMC + LLVMObject + LLVMSupport ) add_subdirectory(MCParser) diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 59e1b8eb8105..3d16de5604f6 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" @@ -23,13 +24,13 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ELF.h" -#include "llvm/Target/TargetAsmBackend.h" -#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/CommandLine.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringSwitch.h" -#include "../Target/X86/X86FixupKinds.h" -#include "../Target/ARM/ARMFixupKinds.h" +#include "../Target/X86/MCTargetDesc/X86FixupKinds.h" +#include "../Target/ARM/MCTargetDesc/ARMFixupKinds.h" +#include "../Target/PowerPC/MCTargetDesc/PPCFixupKinds.h" #include using namespace llvm; @@ -124,12 +125,12 @@ void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize, // e_shnum = # of section header ents if (NumberOfSections >= ELF::SHN_LORESERVE) - Write16(0); + Write16(ELF::SHN_UNDEF); else Write16(NumberOfSections); // e_shstrndx = Section # of '.shstrtab' - if (NumberOfSections >= ELF::SHN_LORESERVE) + if (ShstrtabIndex >= ELF::SHN_LORESERVE) Write16(ELF::SHN_XINDEX); else Write16(ShstrtabIndex); @@ -301,7 +302,8 @@ void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, if (Section.getType() == ELF::SHT_RELA || Section.getType() == ELF::SHT_REL || Section.getType() == ELF::SHT_STRTAB || - Section.getType() == ELF::SHT_SYMTAB) + Section.getType() == ELF::SHT_SYMTAB || + Section.getType() == ELF::SHT_SYMTAB_SHNDX) continue; WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0, ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), false); @@ -447,8 +449,16 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); + adjustFixupOffset(Fixup, RelocOffset); + if (!hasRelocationAddend()) Addend = 0; + + if (is64Bit()) + assert(isInt<64>(Addend)); + else + assert(isInt<32>(Addend)); + ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend); Relocations[Fragment->getParent()].push_back(ERE); } @@ -656,6 +666,9 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, ExternalSymbolData[i].SymbolData->setIndex(Index++); for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) UndefinedSymbolData[i].SymbolData->setIndex(Index++); + + if (NumRegularSections > ELF::SHN_LORESERVE) + NeedsSymtabShndx = true; } void ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, @@ -992,11 +1005,10 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, // Nothing to do. break; - case ELF::SHT_GROUP: { + case ELF::SHT_GROUP: sh_link = SymbolTableIndex; sh_info = GroupSymbolIndex; break; - } default: assert(0 && "FIXME: sh_type value not supported!"); @@ -1224,7 +1236,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, FileOff = OS.tell(); - // ... and then the remainting sections ... + // ... and then the remaining sections ... for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) WriteDataSectionData(Asm, Layout, *Sections[i]); } @@ -1252,6 +1264,11 @@ MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break; case ELF::EM_MBLAZE: return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break; + case ELF::EM_PPC: + case ELF::EM_PPC64: + return new PPCELFObjectWriter(MOTW, OS, IsLittleEndian); break; + case ELF::EM_MIPS: + return new MipsELFObjectWriter(MOTW, OS, IsLittleEndian); break; default: llvm_unreachable("Unsupported architecture"); break; } } @@ -1503,6 +1520,76 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, return Type; } +//===- PPCELFObjectWriter -------------------------------------------===// + +PPCELFObjectWriter::PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW, + raw_ostream &_OS, + bool IsLittleEndian) + : ELFObjectWriter(MOTW, _OS, IsLittleEndian) { +} + +PPCELFObjectWriter::~PPCELFObjectWriter() { +} + +unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel, + bool IsRelocWithSymbol, + int64_t Addend) { + // determine the type of the relocation + unsigned Type; + if (IsPCRel) { + switch ((unsigned)Fixup.getKind()) { + default: + llvm_unreachable("Unimplemented"); + case PPC::fixup_ppc_br24: + Type = ELF::R_PPC_REL24; + break; + case FK_PCRel_4: + Type = ELF::R_PPC_REL32; + break; + } + } else { + switch ((unsigned)Fixup.getKind()) { + default: llvm_unreachable("invalid fixup kind!"); + case PPC::fixup_ppc_br24: + Type = ELF::R_PPC_ADDR24; + break; + case PPC::fixup_ppc_brcond14: + Type = ELF::R_PPC_ADDR14_BRTAKEN; // XXX: or BRNTAKEN?_ + break; + case PPC::fixup_ppc_ha16: + Type = ELF::R_PPC_ADDR16_HA; + break; + case PPC::fixup_ppc_lo16: + Type = ELF::R_PPC_ADDR16_LO; + break; + case PPC::fixup_ppc_lo14: + Type = ELF::R_PPC_ADDR14; + break; + case FK_Data_4: + Type = ELF::R_PPC_ADDR32; + break; + case FK_Data_2: + Type = ELF::R_PPC_ADDR16; + break; + } + } + return Type; +} + +void +PPCELFObjectWriter::adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) { + switch ((unsigned)Fixup.getKind()) { + case PPC::fixup_ppc_ha16: + case PPC::fixup_ppc_lo16: + RelocOffset += 2; + break; + default: + break; + } +} + //===- MBlazeELFObjectWriter -------------------------------------------===// MBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW, @@ -1624,7 +1711,6 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, default: llvm_unreachable("invalid fixup kind!"); case FK_Data_8: Type = ELF::R_X86_64_64; break; case X86::reloc_signed_4byte: - assert(isInt<32>(Target.getConstant())); switch (Modifier) { default: llvm_unreachable("Unimplemented"); @@ -1728,3 +1814,19 @@ unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, return Type; } + +MipsELFObjectWriter::MipsELFObjectWriter(MCELFObjectTargetWriter *MOTW, + raw_ostream &_OS, + bool IsLittleEndian) + : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {} + +MipsELFObjectWriter::~MipsELFObjectWriter() {} + +unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, + const MCFixup &Fixup, + bool IsPCRel, + bool IsRelocWithSymbol, + int64_t Addend) { + // tbd + return 1; +} diff --git a/lib/MC/ELFObjectWriter.h b/lib/MC/ELFObjectWriter.h index 7593099fb447..862b085c76bf 100644 --- a/lib/MC/ELFObjectWriter.h +++ b/lib/MC/ELFObjectWriter.h @@ -347,6 +347,7 @@ class ELFObjectWriter : public MCObjectWriter { virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel, bool IsRelocWithSymbol, int64_t Addend) = 0; + virtual void adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) { } }; //===- X86ELFObjectWriter -------------------------------------------===// @@ -395,6 +396,22 @@ class ELFObjectWriter : public MCObjectWriter { }; + //===- PPCELFObjectWriter -------------------------------------------===// + + class PPCELFObjectWriter : public ELFObjectWriter { + public: + PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW, + raw_ostream &_OS, + bool IsLittleEndian); + + virtual ~PPCELFObjectWriter(); + protected: + virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, + bool IsPCRel, bool IsRelocWithSymbol, + int64_t Addend); + virtual void adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset); + }; + //===- MBlazeELFObjectWriter -------------------------------------------===// class MBlazeELFObjectWriter : public ELFObjectWriter { @@ -409,6 +426,21 @@ class ELFObjectWriter : public MCObjectWriter { bool IsPCRel, bool IsRelocWithSymbol, int64_t Addend); }; + + //===- MipsELFObjectWriter -------------------------------------------===// + + class MipsELFObjectWriter : public ELFObjectWriter { + public: + MipsELFObjectWriter(MCELFObjectTargetWriter *MOTW, + raw_ostream &_OS, + bool IsLittleEndian); + + virtual ~MipsELFObjectWriter(); + protected: + virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, + bool IsPCRel, bool IsRelocWithSymbol, + int64_t Addend); + }; } #endif diff --git a/lib/MC/TargetAsmBackend.cpp b/lib/MC/MCAsmBackend.cpp similarity index 78% rename from lib/MC/TargetAsmBackend.cpp rename to lib/MC/MCAsmBackend.cpp index 192755742535..2c150f456cf6 100644 --- a/lib/MC/TargetAsmBackend.cpp +++ b/lib/MC/MCAsmBackend.cpp @@ -1,4 +1,4 @@ -//===-- TargetAsmBackend.cpp - Target Assembly Backend ---------------------==// +//===-- MCAsmBackend.cpp - Target MC Assembly Backend ----------------------==// // // The LLVM Compiler Infrastructure // @@ -7,19 +7,19 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Target/TargetAsmBackend.h" +#include "llvm/MC/MCAsmBackend.h" using namespace llvm; -TargetAsmBackend::TargetAsmBackend() +MCAsmBackend::MCAsmBackend() : HasReliableSymbolDifference(false) { } -TargetAsmBackend::~TargetAsmBackend() { +MCAsmBackend::~MCAsmBackend() { } const MCFixupKindInfo & -TargetAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { +MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { static const MCFixupKindInfo Builtins[] = { { "FK_Data_1", 0, 8, 0 }, { "FK_Data_2", 0, 16, 0 }, diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index 502b60b0edf4..95861bc61c27 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -29,6 +29,7 @@ MCAsmInfo::MCAsmInfo() { HasSubsectionsViaSymbols = false; HasMachoZeroFillDirective = false; HasMachoTBSSDirective = false; + StructorOutputOrder = Structors::ReversePriorityOrder; HasStaticCtorDtorReferenceInStaticMode = false; LinkerRequiresNonEmptyDwarfLines = false; MaxInstLength = 4; @@ -42,6 +43,9 @@ MCAsmInfo::MCAsmInfo() { LinkerPrivateGlobalPrefix = ""; InlineAsmStart = "APP"; InlineAsmEnd = "NO_APP"; + Code16Directive = ".code16"; + Code32Directive = ".code32"; + Code64Directive = ".code64"; AssemblerDialect = 0; AllowQuotesInName = false; AllowNameToStartWithDigit = false; @@ -53,6 +57,12 @@ MCAsmInfo::MCAsmInfo() { Data16bitsDirective = "\t.short\t"; Data32bitsDirective = "\t.long\t"; Data64bitsDirective = "\t.quad\t"; + DataBegin = "$d."; + CodeBegin = "$a."; + JT8Begin = "$d."; + JT16Begin = "$d."; + JT32Begin = "$d."; + SupportsDataRegions = false; SunStyleELFSectionSwitchSyntax = false; UsesELFSectionDirectiveForBSS = false; AlignDirective = "\t.align\t"; @@ -62,7 +72,7 @@ MCAsmInfo::MCAsmInfo() { GlobalDirective = "\t.globl\t"; HasSetDirective = true; HasAggressiveSymbolFolding = true; - HasLCOMMDirective = false; + LCOMMDirectiveType = LCOMM::None; COMMDirectiveAlignmentIsInBytes = true; HasDotTypeDotSizeDirective = true; HasSingleParameterDotFile = true; diff --git a/lib/MC/MCAsmInfoCOFF.cpp b/lib/MC/MCAsmInfoCOFF.cpp index 7fc7d7abb232..434d9103a71a 100644 --- a/lib/MC/MCAsmInfoCOFF.cpp +++ b/lib/MC/MCAsmInfoCOFF.cpp @@ -19,7 +19,7 @@ using namespace llvm; MCAsmInfoCOFF::MCAsmInfoCOFF() { GlobalPrefix = "_"; COMMDirectiveAlignmentIsInBytes = false; - HasLCOMMDirective = true; + LCOMMDirectiveType = LCOMM::ByteAlignment; HasDotTypeDotSizeDirective = false; HasSingleParameterDotFile = false; PrivateGlobalPrefix = "L"; // Prefix for private global symbols @@ -27,11 +27,14 @@ MCAsmInfoCOFF::MCAsmInfoCOFF() { LinkOnceDirective = "\t.linkonce discard\n"; // Doesn't support visibility: - HiddenVisibilityAttr = ProtectedVisibilityAttr = MCSA_Invalid; + HiddenVisibilityAttr = HiddenDeclarationVisibilityAttr = MCSA_Invalid; + ProtectedVisibilityAttr = MCSA_Invalid; // Set up DWARF directives HasLEB128 = true; // Target asm supports leb128 directives (little-endian) SupportsDebugInformation = true; DwarfSectionOffsetDirective = "\t.secrel32\t"; HasMicrosoftFastStdCallMangling = true; + + SupportsDataRegions = false; } diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp index 5851cb0391d8..b20e338f7904 100644 --- a/lib/MC/MCAsmInfoDarwin.cpp +++ b/lib/MC/MCAsmInfoDarwin.cpp @@ -39,8 +39,16 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() { ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. HasMachoZeroFillDirective = true; // Uses .zerofill HasMachoTBSSDirective = true; // Uses .tbss + StructorOutputOrder = Structors::PriorityOrder; HasStaticCtorDtorReferenceInStaticMode = true; + CodeBegin = "L$start$code$"; + DataBegin = "L$start$data$"; + JT8Begin = "L$start$jt8$"; + JT16Begin = "L$start$jt16$"; + JT32Begin = "L$start$jt32$"; + SupportsDataRegions = true; + // FIXME: Darwin 10 and newer don't need this. LinkerRequiresNonEmptyDwarfLines = true; diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index d5d08e8f69fb..3fcbb05907bc 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -15,8 +15,12 @@ #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" @@ -25,9 +29,6 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" -#include "llvm/Target/TargetAsmBackend.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetLoweringObjectFile.h" #include using namespace llvm; @@ -40,7 +41,7 @@ class MCAsmStreamer : public MCStreamer { private: OwningPtr InstPrinter; OwningPtr Emitter; - OwningPtr AsmBackend; + OwningPtr AsmBackend; SmallString<128> CommentToEmit; raw_svector_ostream CommentStream; @@ -63,7 +64,7 @@ class MCAsmStreamer : public MCStreamer { MCAsmStreamer(MCContext &Context, formatted_raw_ostream &os, bool isVerboseAsm, bool useLoc, bool useCFI, MCInstPrinter *printer, MCCodeEmitter *emitter, - TargetAsmBackend *asmbackend, + MCAsmBackend *asmbackend, bool showInst) : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()), InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend), @@ -157,7 +158,9 @@ class MCAsmStreamer : public MCStreamer { /// /// @param Symbol - The common symbol to emit. /// @param Size - The size of the common symbol. - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size); + /// @param Size - The alignment of the common symbol in bytes. + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0, unsigned ByteAlignment = 0); @@ -334,8 +337,9 @@ void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { default: assert(0 && "Invalid flag!"); case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break; case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break; - case MCAF_Code16: OS << "\t.code\t16"; break; - case MCAF_Code32: OS << "\t.code\t32"; break; + case MCAF_Code16: OS << '\t'<< MAI.getCode16Directive(); break; + case MCAF_Code32: OS << '\t'<< MAI.getCode32Directive(); break; + case MCAF_Code64: OS << '\t'<< MAI.getCode64Directive(); break; } EmitEOL(); } @@ -482,9 +486,16 @@ void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, /// /// @param Symbol - The common symbol to emit. /// @param Size - The size of the common symbol. -void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { - assert(MAI.hasLCOMMDirective() && "Doesn't have .lcomm, can't emit it!"); +void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlign) { + assert(MAI.getLCOMMDirectiveType() != LCOMM::None && + "Doesn't have .lcomm, can't emit it!"); OS << "\t.lcomm\t" << *Symbol << ',' << Size; + if (ByteAlign > 1) { + assert(MAI.getLCOMMDirectiveType() == LCOMM::ByteAlignment && + "Alignment not supported on .lcomm!"); + OS << ',' << ByteAlign; + } EmitEOL(); } @@ -827,8 +838,8 @@ void MCAsmStreamer::EmitCFIEndProc() { void MCAsmStreamer::EmitRegisterName(int64_t Register) { if (InstPrinter && !MAI.useDwarfRegNumForCFI()) { - const TargetAsmInfo &TAI = getContext().getTargetAsmInfo(); - unsigned LLVMRegister = TAI.getLLVMRegNum(Register, true); + const MCRegisterInfo &MRI = getContext().getRegisterInfo(); + unsigned LLVMRegister = MRI.getLLVMRegNum(Register, true); InstPrinter->printRegName(OS, LLVMRegister); } else { OS << Register; @@ -994,6 +1005,19 @@ void MCAsmStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, EmitEOL(); } +static const MCSection *getWin64EHTableSection(StringRef suffix, + MCContext &context) { + // FIXME: This doesn't belong in MCObjectFileInfo. However, + /// this duplicate code in MCWin64EH.cpp. + if (suffix == "") + return context.getObjectFileInfo()->getXDataSection(); + return context.getCOFFSection((".xdata"+suffix).str(), + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); +} + void MCAsmStreamer::EmitWin64EHHandlerData() { MCStreamer::EmitWin64EHHandlerData(); @@ -1003,8 +1027,7 @@ void MCAsmStreamer::EmitWin64EHHandlerData() { // data block is visible. MCWin64EHUnwindInfo *CurFrame = getCurrentW64UnwindInfo(); StringRef suffix=MCWin64EHUnwindEmitter::GetSectionSuffix(CurFrame->Function); - const MCSection *xdataSect = - getContext().getTargetAsmInfo().getWin64EHTableSection(suffix); + const MCSection *xdataSect = getWin64EHTableSection(suffix, getContext()); if (xdataSect) SwitchSectionNoChange(xdataSect); @@ -1221,7 +1244,7 @@ void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { // If we have an AsmPrinter, use that to print, otherwise print the MCInst. if (InstPrinter) - InstPrinter->printInst(&Inst, OS); + InstPrinter->printInst(&Inst, OS, ""); else Inst.print(OS, &MAI); EmitEOL(); @@ -1249,8 +1272,8 @@ MCStreamer *llvm::createAsmStreamer(MCContext &Context, formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, bool useCFI, MCInstPrinter *IP, - MCCodeEmitter *CE, TargetAsmBackend *TAB, + MCCodeEmitter *CE, MCAsmBackend *MAB, bool ShowInst) { return new MCAsmStreamer(Context, OS, isVerboseAsm, useLoc, useCFI, - IP, CE, TAB, ShowInst); + IP, CE, MAB, ShowInst); } diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 527a63caaee5..06c8aec91917 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCValue.h" #include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" @@ -25,8 +26,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetAsmBackend.h" +#include "llvm/Support/TargetRegistry.h" using namespace llvm; @@ -194,7 +194,7 @@ MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, /* *** */ -MCAssembler::MCAssembler(MCContext &Context_, TargetAsmBackend &Backend_, +MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_, MCCodeEmitter &Emitter_, MCObjectWriter &Writer_, raw_ostream &OS_) : Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_), diff --git a/lib/MC/MCAtom.cpp b/lib/MC/MCAtom.cpp new file mode 100644 index 000000000000..d71444324f3d --- /dev/null +++ b/lib/MC/MCAtom.cpp @@ -0,0 +1,97 @@ +//===- lib/MC/MCAtom.cpp - MCAtom implementation --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCAtom.h" +#include "llvm/MC/MCModule.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +void MCAtom::addInst(const MCInst &I, uint64_t Address, unsigned Size) { + assert(Type == TextAtom && "Trying to add MCInst to a non-text atom!"); + + assert(Address < End+Size && + "Instruction not contiguous with end of atom!"); + if (Address > End) + Parent->remap(this, Begin, End+Size); + + Text.push_back(std::make_pair(Address, I)); +} + +void MCAtom::addData(const MCData &D) { + assert(Type == DataAtom && "Trying to add MCData to a non-data atom!"); + Parent->remap(this, Begin, End+1); + + Data.push_back(D); +} + +MCAtom *MCAtom::split(uint64_t SplitPt) { + assert((SplitPt > Begin && SplitPt <= End) && + "Splitting at point not contained in atom!"); + + // Compute the new begin/end points. + uint64_t LeftBegin = Begin; + uint64_t LeftEnd = SplitPt - 1; + uint64_t RightBegin = SplitPt; + uint64_t RightEnd = End; + + // Remap this atom to become the lower of the two new ones. + Parent->remap(this, LeftBegin, LeftEnd); + + // Create a new atom for the higher atom. + MCAtom *RightAtom = Parent->createAtom(Type, RightBegin, RightEnd); + + // Split the contents of the original atom between it and the new one. The + // precise method depends on whether this is a data or a text atom. + if (isDataAtom()) { + std::vector::iterator I = Data.begin() + (RightBegin - LeftBegin); + + assert(I != Data.end() && "Split point not found in range!"); + + std::copy(I, Data.end(), RightAtom->Data.end()); + Data.erase(I, Data.end()); + } else if (isTextAtom()) { + std::vector >::iterator I = Text.begin(); + + while (I != Text.end() && I->first < SplitPt) ++I; + + assert(I != Text.end() && "Split point not found in disassembly!"); + assert(I->first == SplitPt && + "Split point does not fall on instruction boundary!"); + + std::copy(I, Text.end(), RightAtom->Text.end()); + Text.erase(I, Text.end()); + } else + llvm_unreachable("Unknown atom type!"); + + return RightAtom; +} + +void MCAtom::truncate(uint64_t TruncPt) { + assert((TruncPt >= Begin && TruncPt < End) && + "Truncation point not contained in atom!"); + + Parent->remap(this, Begin, TruncPt); + + if (isDataAtom()) { + Data.resize(TruncPt - Begin + 1); + } else if (isTextAtom()) { + std::vector >::iterator I = Text.begin(); + + while (I != Text.end() && I->first <= TruncPt) ++I; + + assert(I != Text.end() && "Truncation point not found in disassembly!"); + assert(I->first == TruncPt+1 && + "Truncation point does not fall on instruction boundary"); + + Text.erase(I, Text.end()); + } else + llvm_unreachable("Unknown atom type!"); +} + diff --git a/lib/MC/MCCodeGenInfo.cpp b/lib/MC/MCCodeGenInfo.cpp new file mode 100644 index 000000000000..236e7de68a8a --- /dev/null +++ b/lib/MC/MCCodeGenInfo.cpp @@ -0,0 +1,21 @@ +//===-- MCCodeGenInfo.cpp - Target CodeGen 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 tracks information about the target which can affect codegen, +// asm parsing, and asm printing. For example, relocation model. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCCodeGenInfo.h" +using namespace llvm; + +void MCCodeGenInfo::InitMCCodeGenInfo(Reloc::Model RM, CodeModel::Model CM) { + RelocationModel = RM; + CMModel = CM; +} diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index 8faa72ecb4e8..82690ee3b3e9 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -9,13 +9,14 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCLabel.h" #include "llvm/MC/MCDwarf.h" -#include "llvm/Target/TargetAsmInfo.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ELF.h" @@ -26,8 +27,9 @@ typedef StringMap ELFUniqueMapTy; typedef StringMap COFFUniqueMapTy; -MCContext::MCContext(const MCAsmInfo &mai, const TargetAsmInfo *tai) : - MAI(mai), TAI(tai), +MCContext::MCContext(const MCAsmInfo &mai, const MCRegisterInfo &mri, + const MCObjectFileInfo *mofi) : + MAI(mai), MRI(mri), MOFI(mofi), Allocator(), Symbols(Allocator), UsedNames(Allocator), NextUniqueID(0), CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0), @@ -54,8 +56,6 @@ MCContext::~MCContext() { // If the stream for the .secure_log_unique directive was created free it. delete (raw_ostream*)SecureLog; - - delete TAI; } //===----------------------------------------------------------------------===// @@ -279,7 +279,8 @@ unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) { } else { StringRef Directory = Slash.first; Name = Slash.second; - for (DirIndex = 0; DirIndex < MCDwarfDirs.size(); DirIndex++) { + DirIndex = 0; + for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) { if (Directory == MCDwarfDirs[DirIndex]) break; } diff --git a/lib/MC/MCDisassembler/CMakeLists.txt b/lib/MC/MCDisassembler/CMakeLists.txt index 0ce359d4b533..4debb288e5ab 100644 --- a/lib/MC/MCDisassembler/CMakeLists.txt +++ b/lib/MC/MCDisassembler/CMakeLists.txt @@ -1,4 +1,3 @@ - add_llvm_library(LLVMMCDisassembler Disassembler.cpp EDDisassembler.cpp @@ -6,3 +5,26 @@ add_llvm_library(LLVMMCDisassembler EDOperand.cpp EDToken.cpp ) + +add_llvm_library_dependencies(LLVMMCDisassembler + LLVMMC + LLVMMCParser + LLVMSupport + LLVMTarget + ) + +foreach(t ${LLVM_TARGETS_TO_BUILD}) + set(td ${LLVM_MAIN_SRC_DIR}/lib/Target/${t}) + if(EXISTS ${td}/TargetInfo/CMakeLists.txt) + add_llvm_library_dependencies(LLVMMCDisassembler "LLVM${t}Info") + endif() + if(EXISTS ${td}/MCTargetDesc/CMakeLists.txt) + add_llvm_library_dependencies(LLVMMCDisassembler "LLVM${t}Desc") + endif() + if(EXISTS ${td}/AsmParser/CMakeLists.txt) + add_llvm_library_dependencies(LLVMMCDisassembler "LLVM${t}AsmParser") + endif() + if(EXISTS ${td}/Disassembler/CMakeLists.txt) + add_llvm_library_dependencies(LLVMMCDisassembler "LLVM${t}Disassembler") + endif() +endforeach(t) diff --git a/lib/MC/MCDisassembler/Disassembler.cpp b/lib/MC/MCDisassembler/Disassembler.cpp index 5480b4b12b2c..16e66dc98e74 100644 --- a/lib/MC/MCDisassembler/Disassembler.cpp +++ b/lib/MC/MCDisassembler/Disassembler.cpp @@ -1,4 +1,4 @@ -//===-- lib/MC/Disassembler.cpp - Disassembler Public C Interface -*- C -*-===// +//===-- lib/MC/Disassembler.cpp - Disassembler Public C Interface ---------===// // // The LLVM Compiler Infrastructure // @@ -11,15 +11,14 @@ #include "llvm-c/Disassembler.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" -#include "llvm/MC/MCContext.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetAsmInfo.h" // FIXME. -#include "llvm/Target/TargetMachine.h" // FIXME. -#include "llvm/Target/TargetSelect.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/MemoryObject.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" namespace llvm { class Target; @@ -38,10 +37,7 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, LLVMSymbolLookupCallback SymbolLookUp) { // Initialize targets and assembly printers/parsers. llvm::InitializeAllTargetInfos(); - // FIXME: We shouldn't need to initialize the Target(Machine)s. - llvm::InitializeAllTargets(); - llvm::InitializeAllMCAsmInfos(); - llvm::InitializeAllAsmPrinters(); + llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); @@ -54,41 +50,38 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(TripleName); assert(MAI && "Unable to create target asm info!"); + const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(TripleName); + assert(MRI && "Unable to create target register info!"); + // Package up features to be passed to target/subtarget std::string FeaturesStr; std::string CPU; - // FIXME: We shouldn't need to do this (and link in codegen). - // When we split this out, we should do it in a way that makes - // it straightforward to switch subtargets on the fly. - TargetMachine *TM = TheTarget->createTargetMachine(TripleName, CPU, - FeaturesStr); - assert(TM && "Unable to create target machine!"); - - // Get the target assembler info needed to setup the context. - const TargetAsmInfo *tai = new TargetAsmInfo(*TM); - assert(tai && "Unable to create target assembler!"); + const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(TripleName, CPU, + FeaturesStr); + assert(STI && "Unable to create subtarget info!"); // Set up the MCContext for creating symbols and MCExpr's. - MCContext *Ctx = new MCContext(*MAI, tai); + MCContext *Ctx = new MCContext(*MAI, *MRI, 0); assert(Ctx && "Unable to create MCContext!"); // Set up disassembler. - MCDisassembler *DisAsm = TheTarget->createMCDisassembler(); + MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI); assert(DisAsm && "Unable to create disassembler!"); - DisAsm->setupForSymbolicDisassembly(GetOpInfo, DisInfo, Ctx); + DisAsm->setupForSymbolicDisassembly(GetOpInfo, SymbolLookUp, DisInfo, Ctx); // Set up the instruction printer. int AsmPrinterVariant = MAI->getAssemblerDialect(); MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant, - *MAI); + *MAI, *STI); assert(IP && "Unable to create instruction printer!"); LLVMDisasmContext *DC = new LLVMDisasmContext(TripleName, DisInfo, TagType, GetOpInfo, SymbolLookUp, - TheTarget, MAI, TM, tai, Ctx, - DisAsm, IP); + TheTarget, MAI, MRI, + Ctx, DisAsm, IP); assert(DC && "Allocation failure!"); + return DC; } @@ -147,18 +140,35 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes, MCInst Inst; const MCDisassembler *DisAsm = DC->getDisAsm(); MCInstPrinter *IP = DC->getIP(); - if (!DisAsm->getInstruction(Inst, Size, MemoryObject, PC, /*REMOVE*/ nulls())) + MCDisassembler::DecodeStatus S; + S = DisAsm->getInstruction(Inst, Size, MemoryObject, PC, + /*REMOVE*/ nulls(), DC->CommentStream); + switch (S) { + case MCDisassembler::Fail: + case MCDisassembler::SoftFail: + // FIXME: Do something different for soft failure modes? return 0; - SmallVector InsnStr; - raw_svector_ostream OS(InsnStr); - IP->printInst(&Inst, OS); - OS.flush(); + case MCDisassembler::Success: { + DC->CommentStream.flush(); + StringRef Comments = DC->CommentsToEmit.str(); - assert(OutStringSize != 0 && "Output buffer cannot be zero size"); - size_t OutputSize = std::min(OutStringSize-1, InsnStr.size()); - std::memcpy(OutString, InsnStr.data(), OutputSize); - OutString[OutputSize] = '\0'; // Terminate string. + SmallVector InsnStr; + raw_svector_ostream OS(InsnStr); + IP->printInst(&Inst, OS, Comments); + OS.flush(); - return Size; + // Tell the comment stream that the vector changed underneath it. + DC->CommentsToEmit.clear(); + DC->CommentStream.resync(); + + assert(OutStringSize != 0 && "Output buffer cannot be zero size"); + size_t OutputSize = std::min(OutStringSize-1, InsnStr.size()); + std::memcpy(OutString, InsnStr.data(), OutputSize); + OutString[OutputSize] = '\0'; // Terminate string. + + return Size; + } + } + return 0; } diff --git a/lib/MC/MCDisassembler/Disassembler.h b/lib/MC/MCDisassembler/Disassembler.h index f0ec42a017a4..238ff7d50025 100644 --- a/lib/MC/MCDisassembler/Disassembler.h +++ b/lib/MC/MCDisassembler/Disassembler.h @@ -20,15 +20,16 @@ #include "llvm-c/Disassembler.h" #include #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/raw_ostream.h" namespace llvm { -class TargetAsmInfo; class MCContext; class MCAsmInfo; class MCDisassembler; class MCInstPrinter; +class MCRegisterInfo; class Target; -class TargetMachine; // // This is the disassembler context returned by LLVMCreateDisasm(). @@ -58,12 +59,8 @@ class LLVMDisasmContext { const Target *TheTarget; // The assembly information for the target architecture. llvm::OwningPtr MAI; - // The target machine instance. - llvm::OwningPtr TM; - // The disassembler for the target architecture. - // FIXME: using llvm::OwningPtr causes a malloc - // error when this LLVMDisasmContext is deleted. - const TargetAsmInfo *Tai; + // The register information for the target architecture. + llvm::OwningPtr MRI; // The assembly context for creating symbols and MCExprs. llvm::OwningPtr Ctx; // The disassembler for the target architecture. @@ -72,22 +69,28 @@ class LLVMDisasmContext { llvm::OwningPtr IP; public: + // Comment stream and backing vector. + SmallString<128> CommentsToEmit; + raw_svector_ostream CommentStream; + LLVMDisasmContext(std::string tripleName, void *disInfo, int tagType, LLVMOpInfoCallback getOpInfo, LLVMSymbolLookupCallback symbolLookUp, const Target *theTarget, const MCAsmInfo *mAI, - llvm::TargetMachine *tM, const TargetAsmInfo *tai, + const MCRegisterInfo *mRI, llvm::MCContext *ctx, const MCDisassembler *disAsm, MCInstPrinter *iP) : TripleName(tripleName), DisInfo(disInfo), TagType(tagType), GetOpInfo(getOpInfo), - SymbolLookUp(symbolLookUp), TheTarget(theTarget), Tai(tai) { - TM.reset(tM); + SymbolLookUp(symbolLookUp), TheTarget(theTarget), + CommentStream(CommentsToEmit) { MAI.reset(mAI); + MRI.reset(mRI); Ctx.reset(ctx); DisAsm.reset(disAsm); IP.reset(iP); } const MCDisassembler *getDisAsm() const { return DisAsm.get(); } + const MCAsmInfo *getAsmInfo() const { return MAI.get(); } MCInstPrinter *getIP() { return IP.get(); } }; diff --git a/lib/MC/MCDisassembler/EDDisassembler.cpp b/lib/MC/MCDisassembler/EDDisassembler.cpp index bdd99afe1ae4..83362a21f77b 100644 --- a/lib/MC/MCDisassembler/EDDisassembler.cpp +++ b/lib/MC/MCDisassembler/EDDisassembler.cpp @@ -22,20 +22,19 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCParser/AsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h" +#include "llvm/MC/MCTargetAsmLexer.h" +#include "llvm/MC/MCTargetAsmParser.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 "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" using namespace llvm; bool EDDisassembler::sInitialized = false; @@ -106,9 +105,7 @@ void EDDisassembler::initialize() { sInitialized = true; InitializeAllTargetInfos(); - InitializeAllTargets(); - InitializeAllMCAsmInfos(); - InitializeAllAsmPrinters(); + InitializeAllTargetMCs(); InitializeAllAsmParsers(); InitializeAllDisassemblers(); } @@ -169,24 +166,24 @@ EDDisassembler::EDDisassembler(CPUKey &key) : if (!Tgt) return; - std::string CPU; - std::string featureString; - TargetMachine.reset(Tgt->createTargetMachine(tripleString, CPU, - featureString)); + MRI.reset(Tgt->createMCRegInfo(tripleString)); - const TargetRegisterInfo *registerInfo = TargetMachine->getRegisterInfo(); - - if (!registerInfo) + if (!MRI) return; - - initMaps(*registerInfo); + + initMaps(*MRI); AsmInfo.reset(Tgt->createMCAsmInfo(tripleString)); if (!AsmInfo) return; - Disassembler.reset(Tgt->createMCDisassembler()); + STI.reset(Tgt->createMCSubtargetInfo(tripleString, "", "")); + + if (!STI) + return; + + Disassembler.reset(Tgt->createMCDisassembler(*STI)); if (!Disassembler) return; @@ -195,16 +192,16 @@ EDDisassembler::EDDisassembler(CPUKey &key) : InstString.reset(new std::string); InstStream.reset(new raw_string_ostream(*InstString)); - InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo)); + InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo, *STI)); if (!InstPrinter) return; GenericAsmLexer.reset(new AsmLexer(*AsmInfo)); - SpecificAsmLexer.reset(Tgt->createAsmLexer(*AsmInfo)); + SpecificAsmLexer.reset(Tgt->createMCAsmLexer(*MRI, *AsmInfo)); SpecificAsmLexer->InstallLexer(*GenericAsmLexer); - initMaps(*TargetMachine->getRegisterInfo()); + initMaps(*MRI); Valid = true; } @@ -247,14 +244,17 @@ EDInst *EDDisassembler::createInst(EDByteReaderCallback byteReader, MCInst* inst = new MCInst; uint64_t byteSize; - if (!Disassembler->getInstruction(*inst, - byteSize, - memoryObject, - address, - ErrorStream)) { + MCDisassembler::DecodeStatus S; + S = Disassembler->getInstruction(*inst, byteSize, memoryObject, address, + ErrorStream, nulls()); + switch (S) { + case MCDisassembler::Fail: + case MCDisassembler::SoftFail: + // FIXME: Do something different on soft failure mode? delete inst; return NULL; - } else { + + case MCDisassembler::Success: { const llvm::EDInstInfo *thisInstInfo = NULL; if (InstInfos) { @@ -264,9 +264,11 @@ EDInst *EDDisassembler::createInst(EDByteReaderCallback byteReader, EDInst* sdInst = new EDInst(inst, byteSize, *this, thisInstInfo); return sdInst; } + } + return NULL; } -void EDDisassembler::initMaps(const TargetRegisterInfo ®isterInfo) { +void EDDisassembler::initMaps(const MCRegisterInfo ®isterInfo) { unsigned numRegisters = registerInfo.getNumRegs(); unsigned registerIndex; @@ -325,7 +327,7 @@ bool EDDisassembler::registerIsProgramCounter(unsigned registerID) { int EDDisassembler::printInst(std::string &str, MCInst &inst) { PrinterMutex.acquire(); - InstPrinter->printInst(&inst, *InstStream); + InstPrinter->printInst(&inst, *InstStream, ""); InstStream->flush(); str = *InstString; InstString->clear(); @@ -368,16 +370,16 @@ int EDDisassembler::parseInst(SmallVectorImpl &operands, SourceMgr sourceMgr; sourceMgr.setDiagHandler(diag_handler, static_cast(this)); sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over - MCContext context(*AsmInfo, NULL); + MCContext context(*AsmInfo, *MRI, NULL); OwningPtr streamer(createNullStreamer(context)); - OwningPtr genericParser(createMCAsmParser(*Tgt, sourceMgr, + OwningPtr genericParser(createMCAsmParser(sourceMgr, context, *streamer, *AsmInfo)); StringRef triple = tripleFromArch(Key.Arch); OwningPtr STI(Tgt->createMCSubtargetInfo(triple, "", "")); - OwningPtr TargetParser(Tgt->createAsmParser(*STI, - *genericParser)); + OwningPtr + TargetParser(Tgt->createMCAsmParser(*STI, *genericParser)); AsmToken OpcodeToken = genericParser->Lex(); AsmToken NextToken = genericParser->Lex(); // consume next token, because specificParser expects us to diff --git a/lib/MC/MCDisassembler/EDDisassembler.h b/lib/MC/MCDisassembler/EDDisassembler.h index 11d69c151cf9..38c22038c510 100644 --- a/lib/MC/MCDisassembler/EDDisassembler.h +++ b/lib/MC/MCDisassembler/EDDisassembler.h @@ -29,24 +29,23 @@ namespace llvm { class AsmLexer; +class AsmParser; class AsmToken; class MCContext; class MCAsmInfo; class MCAsmLexer; -class AsmParser; -class TargetAsmLexer; -class TargetAsmParser; class MCDisassembler; class MCInstPrinter; class MCInst; class MCParsedAsmOperand; +class MCRegisterInfo; class MCStreamer; class MCSubtargetInfo; +class MCTargetAsmLexer; +class MCTargetAsmParser; template class SmallVectorImpl; class SourceMgr; class Target; -class TargetMachine; -class TargetRegisterInfo; struct EDInstInfo; struct EDInst; @@ -136,10 +135,12 @@ struct EDDisassembler { CPUKey Key; /// The LLVM target corresponding to the disassembler const llvm::Target *Tgt; - /// The target machine instance. - llvm::OwningPtr TargetMachine; /// The assembly information for the target architecture llvm::OwningPtr AsmInfo; + /// The subtarget information for the target architecture + llvm::OwningPtr STI; + // The register information for the target architecture. + llvm::OwningPtr MRI; /// The disassembler for the target architecture llvm::OwningPtr Disassembler; /// The output string for the instruction printer; must be guarded with @@ -160,7 +161,7 @@ struct EDDisassembler { /// The target-specific lexer for use in tokenizing strings, in /// target-independent and target-specific portions llvm::OwningPtr GenericAsmLexer; - llvm::OwningPtr SpecificAsmLexer; + llvm::OwningPtr SpecificAsmLexer; /// The guard for the above llvm::sys::Mutex ParserMutex; /// The LLVM number used for the target disassembly syntax variant @@ -216,7 +217,7 @@ struct EDDisassembler { /// info /// /// @arg registerInfo - the register information to use as a source - void initMaps(const llvm::TargetRegisterInfo ®isterInfo); + void initMaps(const llvm::MCRegisterInfo ®isterInfo); /// nameWithRegisterID - Returns the name (owned by the EDDisassembler) of a /// register for a given register ID, or NULL on failure /// diff --git a/lib/MC/MCDisassembler/EDInst.h b/lib/MC/MCDisassembler/EDInst.h index ceb9505028de..6b78dc826c92 100644 --- a/lib/MC/MCDisassembler/EDInst.h +++ b/lib/MC/MCDisassembler/EDInst.h @@ -73,7 +73,7 @@ struct EDInst { std::string String; /// The order in which operands from the InstInfo's operand information appear /// in String - const char* OperandOrder; + const signed char* OperandOrder; /// The result of the parseOperands() function CachedResult ParseResult; diff --git a/lib/MC/MCDisassembler/EDToken.cpp b/lib/MC/MCDisassembler/EDToken.cpp index de770b41ef35..5f6c9df4812a 100644 --- a/lib/MC/MCDisassembler/EDToken.cpp +++ b/lib/MC/MCDisassembler/EDToken.cpp @@ -87,14 +87,18 @@ int EDToken::registerID(unsigned ®isterID) const { int EDToken::tokenize(std::vector &tokens, std::string &str, - const char *operandOrder, + const signed char *operandOrder, EDDisassembler &disassembler) { SmallVector parsedOperands; SmallVector asmTokens; if (disassembler.parseInst(parsedOperands, asmTokens, str)) + { + for (unsigned i = 0, e = parsedOperands.size(); i != e; ++i) + delete parsedOperands[i]; return -1; - + } + SmallVectorImpl::iterator operandIterator; unsigned int operandIndex; SmallVectorImpl::iterator tokenIterator; diff --git a/lib/MC/MCDisassembler/EDToken.h b/lib/MC/MCDisassembler/EDToken.h index ba467078686a..384079b72eec 100644 --- a/lib/MC/MCDisassembler/EDToken.h +++ b/lib/MC/MCDisassembler/EDToken.h @@ -125,7 +125,7 @@ struct EDToken { // assembly syntax static int tokenize(std::vector &tokens, std::string &str, - const char *operandOrder, + const signed char *operandOrder, EDDisassembler &disassembler); /// getString - Directs a character pointer to the string, returning 0 on diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index ad86db13d510..4658a3093fab 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -7,17 +7,18 @@ // //===----------------------------------------------------------------------===// -#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCObjectWriter.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetAsmInfo.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" @@ -196,7 +197,7 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS, MCOS->EmitLabel(SectionEnd); // Switch back the the dwarf line section. - MCOS->SwitchSection(context.getTargetAsmInfo().getDwarfLineSection()); + MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection()); const MCAsmInfo &asmInfo = MCOS->getContext().getAsmInfo(); MCOS->EmitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd, @@ -209,7 +210,7 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS, void MCDwarfFileTable::Emit(MCStreamer *MCOS) { MCContext &context = MCOS->getContext(); // Switch to the section where the table will be emitted into. - MCOS->SwitchSection(context.getTargetAsmInfo().getDwarfLineSection()); + MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection()); // Create a symbol at the beginning of this section. MCSymbol *LineStartSym = context.CreateTempSymbol(); @@ -485,11 +486,11 @@ static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, } static const MachineLocation TranslateMachineLocation( - const TargetAsmInfo &TAI, + const MCRegisterInfo &MRI, const MachineLocation &Loc) { unsigned Reg = Loc.getReg() == MachineLocation::VirtualFP ? MachineLocation::VirtualFP : - unsigned(TAI.getDwarfRegNum(Loc.getReg(), true)); + unsigned(MRI.getDwarfRegNum(Loc.getReg(), true)); const MachineLocation &NewLoc = Loc.isReg() ? MachineLocation(Reg) : MachineLocation(Reg, Loc.getOffset()); return NewLoc; @@ -503,10 +504,11 @@ namespace { bool IsEH; const MCSymbol *SectionStart; public: - FrameEmitterImpl(bool usingCFI, bool isEH, const MCSymbol *sectionStart) : - CFAOffset(0), CIENum(0), UsingCFI(usingCFI), IsEH(isEH), - SectionStart(sectionStart) { - } + FrameEmitterImpl(bool usingCFI, bool isEH) + : CFAOffset(0), CIENum(0), UsingCFI(usingCFI), IsEH(isEH), + SectionStart(0) {} + + void setSectionStart(const MCSymbol *Label) { SectionStart = Label; } /// EmitCompactUnwind - Emit the unwind information in a compact way. If /// we're successful, return 'true'. Otherwise, return 'false' and it will @@ -687,11 +689,8 @@ void FrameEmitterImpl::EmitCFIInstructions(MCStreamer &streamer, /// normal CIE and FDE. bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, const MCDwarfFrameInfo &Frame) { -#if 1 - return false; -#else MCContext &Context = Streamer.getContext(); - const TargetAsmInfo &TAI = Context.getTargetAsmInfo(); + const MCObjectFileInfo *MOFI = Context.getObjectFileInfo(); bool VerboseAsm = Streamer.isVerboseAsm(); // range-start range-length compact-unwind-enc personality-func lsda @@ -716,19 +715,17 @@ bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, // .quad __gxx_personality // .quad except_tab1 - uint32_t Encoding = - TAI.getCompactUnwindEncoding(Frame.Instructions, - getDataAlignmentFactor(Streamer), IsEH); + uint32_t Encoding = Frame.CompactUnwindEncoding; if (!Encoding) return false; // The encoding needs to know we have an LSDA. if (Frame.Lsda) Encoding |= 0x40000000; - Streamer.SwitchSection(TAI.getCompactUnwindSection()); + Streamer.SwitchSection(MOFI->getCompactUnwindSection()); // Range Start - unsigned FDEEncoding = TAI.getFDEEncoding(UsingCFI); + unsigned FDEEncoding = MOFI->getFDEEncoding(UsingCFI); unsigned Size = getSizeForEncoding(Streamer, FDEEncoding); if (VerboseAsm) Streamer.AddComment("Range Start"); Streamer.EmitSymbolValue(Frame.Function, Size); @@ -745,6 +742,7 @@ bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, Twine(llvm::utohexstr(Encoding))); Streamer.EmitIntValue(Encoding, Size); + // Personality Function Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_absptr); if (VerboseAsm) Streamer.AddComment("Personality Function"); @@ -762,7 +760,6 @@ bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, Streamer.EmitIntValue(0, Size); // No LSDA return true; -#endif } const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, @@ -771,11 +768,12 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, const MCSymbol *lsda, unsigned lsdaEncoding) { MCContext &context = streamer.getContext(); - const TargetAsmInfo &TAI = context.getTargetAsmInfo(); + const MCRegisterInfo &MRI = context.getRegisterInfo(); + const MCObjectFileInfo *MOFI = context.getObjectFileInfo(); bool verboseAsm = streamer.isVerboseAsm(); MCSymbol *sectionStart; - if (TAI.isFunctionEHFrameSymbolPrivate() || !IsEH) + if (MOFI->isFunctionEHFrameSymbolPrivate() || !IsEH) sectionStart = context.CreateTempSymbol(); else sectionStart = context.GetOrCreateSymbol(Twine("EH_frame") + Twine(CIENum)); @@ -824,7 +822,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, // Return Address Register if (verboseAsm) streamer.AddComment("CIE Return Address Column"); - streamer.EmitULEB128IntValue(TAI.getDwarfRARegNum(true)); + streamer.EmitULEB128IntValue(MRI.getDwarfRegNum(MRI.getRARegister(), true)); // Augmentation Data Length (optional) @@ -858,21 +856,22 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, EmitEncodingByte(streamer, lsdaEncoding, "LSDA Encoding"); // Encoding of the FDE pointers - EmitEncodingByte(streamer, TAI.getFDEEncoding(UsingCFI), + EmitEncodingByte(streamer, MOFI->getFDEEncoding(UsingCFI), "FDE Encoding"); } // Initial Instructions - const std::vector &Moves = TAI.getInitialFrameState(); + const MCAsmInfo &MAI = context.getAsmInfo(); + const std::vector &Moves = MAI.getInitialFrameState(); std::vector Instructions; for (int i = 0, n = Moves.size(); i != n; ++i) { MCSymbol *Label = Moves[i].getLabel(); const MachineLocation &Dst = - TranslateMachineLocation(TAI, Moves[i].getDestination()); + TranslateMachineLocation(MRI, Moves[i].getDestination()); const MachineLocation &Src = - TranslateMachineLocation(TAI, Moves[i].getSource()); + TranslateMachineLocation(MRI, Moves[i].getSource()); MCCFIInstruction Inst(Label, Dst, Src); Instructions.push_back(Inst); } @@ -893,10 +892,10 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, MCContext &context = streamer.getContext(); MCSymbol *fdeStart = context.CreateTempSymbol(); MCSymbol *fdeEnd = context.CreateTempSymbol(); - const TargetAsmInfo &TAI = context.getTargetAsmInfo(); + const MCObjectFileInfo *MOFI = context.getObjectFileInfo(); bool verboseAsm = streamer.isVerboseAsm(); - if (!TAI.isFunctionEHFrameSymbolPrivate() && IsEH) { + if (IsEH && frame.Function && !MOFI->isFunctionEHFrameSymbolPrivate()) { MCSymbol *EHSym = context.GetOrCreateSymbol(frame.Function->getName() + Twine(".eh")); streamer.EmitEHSymAttributes(frame.Function, EHSym); @@ -925,7 +924,7 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, streamer.EmitSymbolValue(&cieStart, 4); } - unsigned fdeEncoding = TAI.getFDEEncoding(UsingCFI); + unsigned fdeEncoding = MOFI->getFDEEncoding(UsingCFI); unsigned size = getSizeForEncoding(streamer, fdeEncoding); // PC Begin @@ -1011,26 +1010,34 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, bool UsingCFI, bool IsEH) { MCContext &Context = Streamer.getContext(); - const TargetAsmInfo &TAI = Context.getTargetAsmInfo(); - const MCSection &Section = IsEH ? *TAI.getEHFrameSection() : - *TAI.getDwarfFrameSection(); + MCObjectFileInfo *MOFI = + const_cast(Context.getObjectFileInfo()); + FrameEmitterImpl Emitter(UsingCFI, IsEH); + ArrayRef FrameArray = Streamer.getFrameInfos(); + + // Emit the compact unwind info if available. + // FIXME: This emits both the compact unwind and the old CIE/FDE + // information. Only one of those is needed. + if (IsEH && MOFI->getCompactUnwindSection()) + for (unsigned i = 0, n = Streamer.getNumFrameInfos(); i < n; ++i) { + const MCDwarfFrameInfo &Frame = Streamer.getFrameInfo(i); + if (!Frame.CompactUnwindEncoding) + Emitter.EmitCompactUnwind(Streamer, Frame); + } + + const MCSection &Section = IsEH ? *MOFI->getEHFrameSection() : + *MOFI->getDwarfFrameSection(); Streamer.SwitchSection(&Section); MCSymbol *SectionStart = Context.CreateTempSymbol(); Streamer.EmitLabel(SectionStart); + Emitter.setSectionStart(SectionStart); MCSymbol *FDEEnd = NULL; DenseMap CIEStarts; - FrameEmitterImpl Emitter(UsingCFI, IsEH, SectionStart); const MCSymbol *DummyDebugKey = NULL; - for (unsigned i = 0, n = Streamer.getNumFrameInfos(); i < n; ++i) { - const MCDwarfFrameInfo &Frame = Streamer.getFrameInfo(i); - if (IsEH && TAI.getCompactUnwindSection() && - Emitter.EmitCompactUnwind(Streamer, Frame)) { - FDEEnd = NULL; - continue; - } - + for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) { + const MCDwarfFrameInfo &Frame = FrameArray[i]; CIEKey Key(Frame.Personality, Frame.PersonalityEncoding, Frame.LsdaEncoding); const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey; diff --git a/lib/MC/MCELF.cpp b/lib/MC/MCELF.cpp index 2c3f8e8f7866..dad2e7ba9878 100644 --- a/lib/MC/MCELF.cpp +++ b/lib/MC/MCELF.cpp @@ -16,7 +16,6 @@ #include "llvm/MC/MCELFSymbolFlags.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/Support/ELF.h" -#include "llvm/Target/TargetAsmBackend.h" namespace llvm { diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 49340edbed5e..9ada08ea9530 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -21,11 +21,11 @@ #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCValue.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetAsmBackend.h" using namespace llvm; @@ -53,8 +53,9 @@ void MCELFStreamer::EmitLabel(MCSymbol *Symbol) { void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { switch (Flag) { case MCAF_SyntaxUnified: return; // no-op here. - case MCAF_Code16: return; // no-op here. - case MCAF_Code32: return; // no-op here. + case MCAF_Code16: return; // Change parsing mode; no-op here. + case MCAF_Code32: return; // Change parsing mode; no-op here. + case MCAF_Code64: return; // Change parsing mode; no-op here. case MCAF_SubsectionsViaSymbols: getAssembler().setSubsectionsViaSymbols(true); return; @@ -219,14 +220,14 @@ void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, SD.setSize(MCConstantExpr::Create(Size, getContext())); } -void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { +void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { // FIXME: Should this be caught and done earlier? MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); MCELF::SetBinding(SD, ELF::STB_LOCAL); SD.setExternal(false); BindingExplicitlySet.insert(Symbol); - // FIXME: ByteAlignment is not needed here, but is required. - EmitCommonSymbol(Symbol, Size, 1); + EmitCommonSymbol(Symbol, Size, ByteAlignment); } void MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { @@ -374,10 +375,10 @@ void MCELFStreamer::Finish() { this->MCObjectStreamer::Finish(); } -MCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB, +MCStreamer *llvm::createELFStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll, bool NoExecStack) { - MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE); + MCELFStreamer *S = new MCELFStreamer(Context, MAB, OS, CE); if (RelaxAll) S->getAssembler().setRelaxAll(true); if (NoExecStack) diff --git a/lib/MC/MCELFStreamer.h b/lib/MC/MCELFStreamer.h index 855e7e9ca60f..10bf77580998 100644 --- a/lib/MC/MCELFStreamer.h +++ b/lib/MC/MCELFStreamer.h @@ -25,11 +25,11 @@ namespace llvm { class MCELFStreamer : public MCObjectStreamer { public: - MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB, + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter) : MCObjectStreamer(Context, TAB, OS, Emitter) {} - MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB, + MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, MCAssembler *Assembler) : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {} @@ -74,7 +74,8 @@ class MCELFStreamer : public MCObjectStreamer { SD.setSize(Value); } - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size); + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0, unsigned ByteAlignment = 0) { diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index fcf1aabb5a86..da297fb1d95a 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -18,7 +18,6 @@ #include "llvm/MC/MCValue.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetAsmBackend.h" using namespace llvm; namespace { diff --git a/lib/MC/MCInstPrinter.cpp b/lib/MC/MCInstPrinter.cpp index 81a939ffaaef..2317a2891f8b 100644 --- a/lib/MC/MCInstPrinter.cpp +++ b/lib/MC/MCInstPrinter.cpp @@ -8,7 +8,9 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; MCInstPrinter::~MCInstPrinter() { @@ -23,3 +25,12 @@ StringRef MCInstPrinter::getOpcodeName(unsigned Opcode) const { void MCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { assert(0 && "Target should implement this"); } + +void MCInstPrinter::printAnnotation(raw_ostream &OS, StringRef Annot) { + if (!Annot.empty()) { + if (CommentStream) + (*CommentStream) << Annot; + else + OS << " " << MAI.getCommentString() << " " << Annot; + } +} diff --git a/lib/MC/MCInstrAnalysis.cpp b/lib/MC/MCInstrAnalysis.cpp new file mode 100644 index 000000000000..7736702f35a4 --- /dev/null +++ b/lib/MC/MCInstrAnalysis.cpp @@ -0,0 +1,21 @@ +//===-- MCInstrAnalysis.cpp - InstrDesc target hooks ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCInstrAnalysis.h" +using namespace llvm; + +uint64_t MCInstrAnalysis::evaluateBranch(const MCInst &Inst, uint64_t Addr, + uint64_t Size) const { + if (Inst.getNumOperands() == 0 || + Info->get(Inst.getOpcode()).OpInfo[0].OperandType != MCOI::OPERAND_PCREL) + return -1ULL; + + int64_t Imm = Inst.getOperand(0).getImm(); + return Addr+Size+Imm; +} diff --git a/lib/MC/MCLoggingStreamer.cpp b/lib/MC/MCLoggingStreamer.cpp index 309752ec5f02..3fe8ac72c8ec 100644 --- a/lib/MC/MCLoggingStreamer.cpp +++ b/lib/MC/MCLoggingStreamer.cpp @@ -133,9 +133,10 @@ class MCLoggingStreamer : public MCStreamer { return Child->EmitCommonSymbol(Symbol, Size, ByteAlignment); } - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { LogCall("EmitLocalCommonSymbol"); - return Child->EmitLocalCommonSymbol(Symbol, Size); + return Child->EmitLocalCommonSymbol(Symbol, Size, ByteAlignment); } virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 1b21249ca321..aa35815dd19c 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -20,10 +20,10 @@ #include "llvm/MC/MCMachOSymbolFlags.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetAsmBackend.h" using namespace llvm; @@ -34,9 +34,9 @@ class MCMachOStreamer : public MCObjectStreamer { virtual void EmitInstToData(const MCInst &Inst); public: - MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB, + MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *Emitter) - : MCObjectStreamer(Context, TAB, OS, Emitter) {} + : MCObjectStreamer(Context, MAB, OS, Emitter) {} /// @name MCStreamer Interface /// @{ @@ -67,7 +67,8 @@ class MCMachOStreamer : public MCObjectStreamer { virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { assert(0 && "macho doesn't support this directive"); } - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { assert(0 && "macho doesn't support this directive"); } virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, @@ -143,8 +144,9 @@ void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { // Do any generic stuff we need to do. switch (Flag) { case MCAF_SyntaxUnified: return; // no-op here. - case MCAF_Code16: return; // no-op here. - case MCAF_Code32: return; // no-op here. + case MCAF_Code16: return; // Change parsing mode; no-op here. + case MCAF_Code32: return; // Change parsing mode; no-op here. + case MCAF_Code64: return; // Change parsing mode; no-op here. case MCAF_SubsectionsViaSymbols: getAssembler().setSubsectionsViaSymbols(true); return; @@ -207,8 +209,8 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_ELF_TypeCommon: case MCSA_ELF_TypeNoType: case MCSA_ELF_TypeGnuUniqueObject: - case MCSA_IndirectSymbol: case MCSA_Hidden: + case MCSA_IndirectSymbol: case MCSA_Internal: case MCSA_Protected: case MCSA_Weak: @@ -410,10 +412,10 @@ void MCMachOStreamer::Finish() { this->MCObjectStreamer::Finish(); } -MCStreamer *llvm::createMachOStreamer(MCContext &Context, TargetAsmBackend &TAB, +MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *CE, bool RelaxAll) { - MCMachOStreamer *S = new MCMachOStreamer(Context, TAB, OS, CE); + MCMachOStreamer *S = new MCMachOStreamer(Context, MAB, OS, CE); if (RelaxAll) S->getAssembler().setRelaxAll(true); return S; diff --git a/lib/MC/MCModule.cpp b/lib/MC/MCModule.cpp new file mode 100644 index 000000000000..b1d09d945a39 --- /dev/null +++ b/lib/MC/MCModule.cpp @@ -0,0 +1,45 @@ +//===- lib/MC/MCModule.cpp - MCModule implementation --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCAtom.h" +#include "llvm/MC/MCModule.h" + +using namespace llvm; + +MCAtom *MCModule::createAtom(MCAtom::AtomType Type, + uint64_t Begin, uint64_t End) { + assert(Begin < End && "Creating MCAtom with endpoints reversed?"); + + // Check for atoms already covering this range. + IntervalMap::iterator I = OffsetMap.find(Begin); + assert((!I.valid() || I.start() < End) && "Offset range already occupied!"); + + // Create the new atom and add it to our maps. + MCAtom *NewAtom = new MCAtom(Type, this, Begin, End); + AtomAllocationTracker.insert(NewAtom); + OffsetMap.insert(Begin, End, NewAtom); + return NewAtom; +} + +// remap - Update the interval mapping for an atom. +void MCModule::remap(MCAtom *Atom, uint64_t NewBegin, uint64_t NewEnd) { + // Find and erase the old mapping. + IntervalMap::iterator I = OffsetMap.find(Atom->Begin); + assert(I.valid() && "Atom offset not found in module!"); + assert(*I == Atom && "Previous atom mapping was invalid!"); + I.erase(); + + // Insert the new mapping. + OffsetMap.insert(NewBegin, NewEnd, Atom); + + // Update the atom internal bounds. + Atom->Begin = NewBegin; + Atom->End = NewEnd; +} + diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index 9577af010205..a6c0adb6793f 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -59,8 +59,8 @@ namespace { 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) {} - + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) {} virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0, unsigned ByteAlignment = 0) {} virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp new file mode 100644 index 000000000000..df8b99d2be6c --- /dev/null +++ b/lib/MC/MCObjectFileInfo.cpp @@ -0,0 +1,554 @@ +//===-- MObjectFileInfo.cpp - Object File Information ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCSection.h" +#include "llvm/MC/MCSectionCOFF.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCSectionMachO.h" +#include "llvm/ADT/Triple.h" +using namespace llvm; + +void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) { + // MachO + IsFunctionEHFrameSymbolPrivate = false; + SupportsWeakOmittedEHFrame = false; + + PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel + | dwarf::DW_EH_PE_sdata4; + LSDAEncoding = FDEEncoding = FDECFIEncoding = dwarf::DW_EH_PE_pcrel; + TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | + dwarf::DW_EH_PE_sdata4; + + // .comm doesn't support alignment before Leopard. + if (T.isMacOSX() && T.isMacOSXVersionLT(10, 5)) + CommDirectiveSupportsAlignment = false; + + TextSection // .text + = Ctx->getMachOSection("__TEXT", "__text", + MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, + SectionKind::getText()); + DataSection // .data + = Ctx->getMachOSection("__DATA", "__data", 0, + SectionKind::getDataRel()); + + TLSDataSection // .tdata + = Ctx->getMachOSection("__DATA", "__thread_data", + MCSectionMachO::S_THREAD_LOCAL_REGULAR, + SectionKind::getDataRel()); + TLSBSSSection // .tbss + = Ctx->getMachOSection("__DATA", "__thread_bss", + MCSectionMachO::S_THREAD_LOCAL_ZEROFILL, + SectionKind::getThreadBSS()); + + // TODO: Verify datarel below. + TLSTLVSection // .tlv + = Ctx->getMachOSection("__DATA", "__thread_vars", + MCSectionMachO::S_THREAD_LOCAL_VARIABLES, + SectionKind::getDataRel()); + + TLSThreadInitSection + = Ctx->getMachOSection("__DATA", "__thread_init", + MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS, + SectionKind::getDataRel()); + + CStringSection // .cstring + = Ctx->getMachOSection("__TEXT", "__cstring", + MCSectionMachO::S_CSTRING_LITERALS, + SectionKind::getMergeable1ByteCString()); + UStringSection + = Ctx->getMachOSection("__TEXT","__ustring", 0, + SectionKind::getMergeable2ByteCString()); + FourByteConstantSection // .literal4 + = Ctx->getMachOSection("__TEXT", "__literal4", + MCSectionMachO::S_4BYTE_LITERALS, + SectionKind::getMergeableConst4()); + EightByteConstantSection // .literal8 + = Ctx->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 (RelocM != Reloc::Static && + T.getArch() != Triple::x86_64 && T.getArch() != Triple::ppc64) + SixteenByteConstantSection = // .literal16 + Ctx->getMachOSection("__TEXT", "__literal16", + MCSectionMachO::S_16BYTE_LITERALS, + SectionKind::getMergeableConst16()); + + ReadOnlySection // .const + = Ctx->getMachOSection("__TEXT", "__const", 0, + SectionKind::getReadOnly()); + + TextCoalSection + = Ctx->getMachOSection("__TEXT", "__textcoal_nt", + MCSectionMachO::S_COALESCED | + MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, + SectionKind::getText()); + ConstTextCoalSection + = Ctx->getMachOSection("__TEXT", "__const_coal", + MCSectionMachO::S_COALESCED, + SectionKind::getReadOnly()); + ConstDataSection // .const_data + = Ctx->getMachOSection("__DATA", "__const", 0, + SectionKind::getReadOnlyWithRel()); + DataCoalSection + = Ctx->getMachOSection("__DATA","__datacoal_nt", + MCSectionMachO::S_COALESCED, + SectionKind::getDataRel()); + DataCommonSection + = Ctx->getMachOSection("__DATA","__common", + MCSectionMachO::S_ZEROFILL, + SectionKind::getBSS()); + DataBSSSection + = Ctx->getMachOSection("__DATA","__bss", MCSectionMachO::S_ZEROFILL, + SectionKind::getBSS()); + + + LazySymbolPointerSection + = Ctx->getMachOSection("__DATA", "__la_symbol_ptr", + MCSectionMachO::S_LAZY_SYMBOL_POINTERS, + SectionKind::getMetadata()); + NonLazySymbolPointerSection + = Ctx->getMachOSection("__DATA", "__nl_symbol_ptr", + MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, + SectionKind::getMetadata()); + + if (RelocM == Reloc::Static) { + StaticCtorSection + = Ctx->getMachOSection("__TEXT", "__constructor", 0, + SectionKind::getDataRel()); + StaticDtorSection + = Ctx->getMachOSection("__TEXT", "__destructor", 0, + SectionKind::getDataRel()); + } else { + StaticCtorSection + = Ctx->getMachOSection("__DATA", "__mod_init_func", + MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, + SectionKind::getDataRel()); + StaticDtorSection + = Ctx->getMachOSection("__DATA", "__mod_term_func", + MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, + SectionKind::getDataRel()); + } + + // Exception Handling. + LSDASection = Ctx->getMachOSection("__TEXT", "__gcc_except_tab", 0, + SectionKind::getReadOnlyWithRel()); + + if (T.isMacOSX() && !T.isMacOSXVersionLT(10, 6)) + CompactUnwindSection = + Ctx->getMachOSection("__LD", "__compact_unwind", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getReadOnly()); + + // Debug Information. + DwarfAbbrevSection = + Ctx->getMachOSection("__DWARF", "__debug_abbrev", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfInfoSection = + Ctx->getMachOSection("__DWARF", "__debug_info", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfLineSection = + Ctx->getMachOSection("__DWARF", "__debug_line", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfFrameSection = + Ctx->getMachOSection("__DWARF", "__debug_frame", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfPubNamesSection = + Ctx->getMachOSection("__DWARF", "__debug_pubnames", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfPubTypesSection = + Ctx->getMachOSection("__DWARF", "__debug_pubtypes", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfStrSection = + Ctx->getMachOSection("__DWARF", "__debug_str", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfLocSection = + Ctx->getMachOSection("__DWARF", "__debug_loc", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfARangesSection = + Ctx->getMachOSection("__DWARF", "__debug_aranges", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfRangesSection = + Ctx->getMachOSection("__DWARF", "__debug_ranges", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfMacroInfoSection = + Ctx->getMachOSection("__DWARF", "__debug_macinfo", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + DwarfDebugInlineSection = + Ctx->getMachOSection("__DWARF", "__debug_inlined", + MCSectionMachO::S_ATTR_DEBUG, + SectionKind::getMetadata()); + + TLSExtraDataSection = TLSTLVSection; +} + +void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) { + if (T.getArch() == Triple::x86) { + PersonalityEncoding = (RelocM == Reloc::PIC_) + ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 + : dwarf::DW_EH_PE_absptr; + LSDAEncoding = (RelocM == Reloc::PIC_) + ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 + : dwarf::DW_EH_PE_absptr; + FDEEncoding = FDECFIEncoding = (RelocM == Reloc::PIC_) + ? dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 + : dwarf::DW_EH_PE_absptr; + TTypeEncoding = (RelocM == Reloc::PIC_) + ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 + : dwarf::DW_EH_PE_absptr; + } else if (T.getArch() == Triple::x86_64) { + FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + + if (RelocM == Reloc::PIC_) { + PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | + ((CMModel == CodeModel::Small || CMModel == CodeModel::Medium) + ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); + LSDAEncoding = dwarf::DW_EH_PE_pcrel | + (CMModel == CodeModel::Small + ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); + FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; + TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | + ((CMModel == CodeModel::Small || CMModel == CodeModel::Medium) + ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8); + } else { + PersonalityEncoding = + (CMModel == CodeModel::Small || CMModel == CodeModel::Medium) + ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; + LSDAEncoding = (CMModel == CodeModel::Small) + ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; + FDEEncoding = dwarf::DW_EH_PE_udata4; + TTypeEncoding = (CMModel == CodeModel::Small) + ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr; + } + } + + // ELF + BSSSection = + Ctx->getELFSection(".bss", ELF::SHT_NOBITS, + ELF::SHF_WRITE |ELF::SHF_ALLOC, + SectionKind::getBSS()); + + TextSection = + Ctx->getELFSection(".text", ELF::SHT_PROGBITS, + ELF::SHF_EXECINSTR | + ELF::SHF_ALLOC, + SectionKind::getText()); + + DataSection = + Ctx->getELFSection(".data", ELF::SHT_PROGBITS, + ELF::SHF_WRITE |ELF::SHF_ALLOC, + SectionKind::getDataRel()); + + ReadOnlySection = + Ctx->getELFSection(".rodata", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC, + SectionKind::getReadOnly()); + + TLSDataSection = + Ctx->getELFSection(".tdata", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_TLS | + ELF::SHF_WRITE, + SectionKind::getThreadData()); + + TLSBSSSection = + Ctx->getELFSection(".tbss", ELF::SHT_NOBITS, + ELF::SHF_ALLOC | ELF::SHF_TLS | + ELF::SHF_WRITE, + SectionKind::getThreadBSS()); + + DataRelSection = + Ctx->getELFSection(".data.rel", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC |ELF::SHF_WRITE, + SectionKind::getDataRel()); + + DataRelLocalSection = + Ctx->getELFSection(".data.rel.local", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC |ELF::SHF_WRITE, + SectionKind::getDataRelLocal()); + + DataRelROSection = + Ctx->getELFSection(".data.rel.ro", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC |ELF::SHF_WRITE, + SectionKind::getReadOnlyWithRel()); + + DataRelROLocalSection = + Ctx->getELFSection(".data.rel.ro.local", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC |ELF::SHF_WRITE, + SectionKind::getReadOnlyWithRelLocal()); + + MergeableConst4Section = + Ctx->getELFSection(".rodata.cst4", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC |ELF::SHF_MERGE, + SectionKind::getMergeableConst4()); + + MergeableConst8Section = + Ctx->getELFSection(".rodata.cst8", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC |ELF::SHF_MERGE, + SectionKind::getMergeableConst8()); + + MergeableConst16Section = + Ctx->getELFSection(".rodata.cst16", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC |ELF::SHF_MERGE, + SectionKind::getMergeableConst16()); + + StaticCtorSection = + Ctx->getELFSection(".ctors", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC |ELF::SHF_WRITE, + SectionKind::getDataRel()); + + StaticDtorSection = + Ctx->getELFSection(".dtors", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC |ELF::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 = + Ctx->getELFSection(".gcc_except_table", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC, + SectionKind::getReadOnly()); + + // Debug Info Sections. + DwarfAbbrevSection = + Ctx->getELFSection(".debug_abbrev", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfInfoSection = + Ctx->getELFSection(".debug_info", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfLineSection = + Ctx->getELFSection(".debug_line", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfFrameSection = + Ctx->getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfPubNamesSection = + Ctx->getELFSection(".debug_pubnames", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfPubTypesSection = + Ctx->getELFSection(".debug_pubtypes", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfStrSection = + Ctx->getELFSection(".debug_str", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfLocSection = + Ctx->getELFSection(".debug_loc", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfARangesSection = + Ctx->getELFSection(".debug_aranges", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfRangesSection = + Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); + DwarfMacroInfoSection = + Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS, 0, + SectionKind::getMetadata()); +} + + +void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) { + // COFF + TextSection = + Ctx->getCOFFSection(".text", + COFF::IMAGE_SCN_CNT_CODE | + COFF::IMAGE_SCN_MEM_EXECUTE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getText()); + DataSection = + Ctx->getCOFFSection(".data", + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); + ReadOnlySection = + Ctx->getCOFFSection(".rdata", + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getReadOnly()); + StaticCtorSection = + Ctx->getCOFFSection(".ctors", + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); + StaticDtorSection = + Ctx->getCOFFSection(".dtors", + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + 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 = + Ctx->getCOFFSection(".gcc_except_table", + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getReadOnly()); + + // Debug info. + DwarfAbbrevSection = + Ctx->getCOFFSection(".debug_abbrev", + COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfInfoSection = + Ctx->getCOFFSection(".debug_info", + COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfLineSection = + Ctx->getCOFFSection(".debug_line", + COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfFrameSection = + Ctx->getCOFFSection(".debug_frame", + COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfPubNamesSection = + Ctx->getCOFFSection(".debug_pubnames", + COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfPubTypesSection = + Ctx->getCOFFSection(".debug_pubtypes", + COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfStrSection = + Ctx->getCOFFSection(".debug_str", + COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfLocSection = + Ctx->getCOFFSection(".debug_loc", + COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfARangesSection = + Ctx->getCOFFSection(".debug_aranges", + COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfRangesSection = + Ctx->getCOFFSection(".debug_ranges", + COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + DwarfMacroInfoSection = + Ctx->getCOFFSection(".debug_macinfo", + COFF::IMAGE_SCN_MEM_DISCARDABLE | + COFF::IMAGE_SCN_MEM_READ, + SectionKind::getMetadata()); + + DrectveSection = + Ctx->getCOFFSection(".drectve", + COFF::IMAGE_SCN_LNK_INFO, + SectionKind::getMetadata()); + + PDataSection = + Ctx->getCOFFSection(".pdata", + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); + + XDataSection = + Ctx->getCOFFSection(".xdata", + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); +} + +void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm, + CodeModel::Model cm, + MCContext &ctx) { + RelocM = relocm; + CMModel = cm; + Ctx = &ctx; + + // Common. + CommDirectiveSupportsAlignment = true; + SupportsWeakOmittedEHFrame = true; + IsFunctionEHFrameSymbolPrivate = true; + + PersonalityEncoding = LSDAEncoding = FDEEncoding = FDECFIEncoding = + TTypeEncoding = dwarf::DW_EH_PE_absptr; + + EHFrameSection = 0; // Created on demand. + CompactUnwindSection = 0; // Used only by selected targets. + + Triple T(TT); + Triple::ArchType Arch = T.getArch(); + // FIXME: Checking for Arch here to filter out bogus triples such as + // cellspu-apple-darwin. Perhaps we should fix in Triple? + if ((Arch == Triple::x86 || Arch == Triple::x86_64 || + Arch == Triple::arm || Arch == Triple::thumb || + Arch == Triple::ppc || Arch == Triple::ppc64 || + Arch == Triple::UnknownArch) && + (T.isOSDarwin() || T.getEnvironment() == Triple::MachO)) { + Env = IsMachO; + InitMachOMCObjectFileInfo(T); + } else if ((Arch == Triple::x86 || Arch == Triple::x86_64) && + (T.getOS() == Triple::MinGW32 || T.getOS() == Triple::Cygwin || + T.getOS() == Triple::Win32)) { + Env = IsCOFF; + InitCOFFMCObjectFileInfo(T); + } else { + Env = IsELF; + InitELFMCObjectFileInfo(T); + } +} + +void MCObjectFileInfo::InitEHFrameSection() { + if (Env == IsMachO) + EHFrameSection = + Ctx->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()); + else if (Env == IsELF) + EHFrameSection = + Ctx->getELFSection(".eh_frame", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC, + SectionKind::getDataRel()); + else + EHFrameSection = + Ctx->getCOFFSection(".eh_frame", + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); +} diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index 8635aac00302..a04ae0812a3e 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -17,10 +17,10 @@ #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/Target/TargetAsmBackend.h" +#include "llvm/MC/MCAsmBackend.h" using namespace llvm; -MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, +MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter_) : MCStreamer(Context), Assembler(new MCAssembler(Context, TAB, @@ -30,7 +30,7 @@ MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, { } -MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB, +MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter_, MCAssembler *_Assembler) : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0) diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp index 0c1f8f0df774..c76052d66e00 100644 --- a/lib/MC/MCParser/AsmLexer.cpp +++ b/lib/MC/MCParser/AsmLexer.cpp @@ -24,6 +24,7 @@ using namespace llvm; AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI) { CurBuf = NULL; CurPtr = NULL; + isAtStartOfLine = true; } AsmLexer::~AsmLexer() { @@ -146,7 +147,7 @@ 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) + while (CurChar != '\n' && CurChar != '\r' && CurChar != EOF) CurChar = getNextChar(); if (CurChar == EOF) @@ -334,6 +335,17 @@ StringRef AsmLexer::LexUntilEndOfStatement() { return StringRef(TokStart, CurPtr-TokStart); } +StringRef AsmLexer::LexUntilEndOfLine() { + TokStart = CurPtr; + + while (*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(); @@ -349,14 +361,29 @@ AsmToken AsmLexer::LexToken() { // This always consumes at least one character. int CurChar = getNextChar(); - if (isAtStartOfComment(CurChar)) + if (isAtStartOfComment(CurChar)) { + // If this comment starts with a '#', then return the Hash token and let + // the assembler parser see if it can be parsed as a cpp line filename + // comment. We do this only if we are at the start of a line. + if (CurChar == '#' && isAtStartOfLine) + return AsmToken(AsmToken::Hash, StringRef(TokStart, 1)); + isAtStartOfLine = true; return LexLineComment(); + } if (isAtStatementSeparator(TokStart)) { CurPtr += strlen(MAI.getSeparatorString()) - 1; return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, strlen(MAI.getSeparatorString()))); } + // If we're missing a newline at EOF, make sure we still get an + // EndOfStatement token before the Eof token. + if (CurChar == EOF && !isAtStartOfLine) { + isAtStartOfLine = true; + return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1)); + } + + isAtStartOfLine = false; switch (CurChar) { default: // Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]* @@ -373,6 +400,7 @@ AsmToken AsmLexer::LexToken() { return LexToken(); case '\n': // FALL THROUGH. case '\r': + isAtStartOfLine = true; return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1)); case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1)); case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1)); diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 0c181f39611e..16487579abfc 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -18,22 +18,22 @@ #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCParser/AsmCond.h" #include "llvm/MC/MCParser/AsmLexer.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCDwarf.h" +#include "llvm/MC/MCTargetAsmParser.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetAsmParser.h" #include #include using namespace llvm; @@ -87,6 +87,8 @@ class AsmParser : public MCAsmParser { MCStreamer &Out; const MCAsmInfo &MAI; SourceMgr &SrcMgr; + SourceMgr::DiagHandlerTy SavedDiagHandler; + void *SavedDiagContext; MCAsmParserExtension *GenericParser; MCAsmParserExtension *PlatformParser; @@ -115,8 +117,13 @@ class AsmParser : public MCAsmParser { /// Flag tracking whether any errors have been encountered. unsigned HadError : 1; + /// The values from the last parsed cpp hash file line comment if any. + StringRef CppHashFilename; + int64_t CppHashLineNumber; + SMLoc CppHashLoc; + public: - AsmParser(const Target &T, SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, + AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, const MCAsmInfo &MAI); ~AsmParser(); @@ -153,6 +160,8 @@ class AsmParser : public MCAsmParser { void CheckForValidSection(); bool ParseStatement(); + void EatToEndOfLine(); + bool ParseCppHashLineFilenameComment(const SMLoc &L); bool HandleMacroEntry(StringRef Name, SMLoc NameLoc, const Macro *M); bool expandMacro(SmallString<256> &Buf, StringRef Body, @@ -166,6 +175,7 @@ class AsmParser : public MCAsmParser { bool ShowLine = true) const { SrcMgr.PrintMessage(Loc, Msg, Type, ShowLine); } + static void DiagHandler(const SMDiagnostic &Diag, void *Context); /// EnterIncludeFile - Enter the specified file. This returns true on failure. bool EnterIncludeFile(const std::string &Filename); @@ -338,11 +348,16 @@ extern MCAsmParserExtension *createCOFFAsmParser(); enum { DEFAULT_ADDRSPACE = 0 }; -AsmParser::AsmParser(const Target &T, SourceMgr &_SM, MCContext &_Ctx, +AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, const MCAsmInfo &_MAI) : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), GenericParser(new GenericAsmParser), PlatformParser(0), - CurBuffer(0), MacrosEnabled(true) { + CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0) { + // Save the old handler. + SavedDiagHandler = SrcMgr.getDiagHandler(); + SavedDiagContext = SrcMgr.getDiagContext(); + // Set our own handler which calls the saved handler. + SrcMgr.setDiagHandler(DiagHandler, this); Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); // Initialize the generic parser. @@ -740,9 +755,12 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E, /// ParseExpression - Parse an expression and return it. /// -/// expr ::= expr +,- expr -> lowest. -/// expr ::= expr |,^,&,! expr -> middle. -/// expr ::= expr *,/,%,<<,>> expr -> highest. +/// expr ::= expr &&,|| expr -> lowest. +/// expr ::= expr |,^,&,! expr +/// expr ::= expr ==,!=,<>,<,<=,>,>= expr +/// expr ::= expr <<,>> expr +/// expr ::= expr +,- expr +/// expr ::= expr *,/,% expr -> highest. /// expr ::= primaryexpr /// bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) { @@ -809,7 +827,7 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, default: return 0; // not a binop. - // Lowest Precedence: &&, ||, @ + // Lowest Precedence: &&, || case AsmToken::AmpAmp: Kind = MCBinaryExpr::LAnd; return 1; @@ -852,30 +870,32 @@ static unsigned getBinOpPrecedence(AsmToken::TokenKind K, Kind = MCBinaryExpr::GTE; return 3; + // Intermediate Precedence: <<, >> + case AsmToken::LessLess: + Kind = MCBinaryExpr::Shl; + return 4; + case AsmToken::GreaterGreater: + Kind = MCBinaryExpr::Shr; + return 4; + // High Intermediate Precedence: +, - case AsmToken::Plus: Kind = MCBinaryExpr::Add; - return 4; + return 5; case AsmToken::Minus: Kind = MCBinaryExpr::Sub; - return 4; + return 5; - // Highest Precedence: *, /, %, <<, >> + // Highest Precedence: *, /, % case AsmToken::Star: Kind = MCBinaryExpr::Mul; - return 5; + return 6; case AsmToken::Slash: Kind = MCBinaryExpr::Div; - return 5; + return 6; case AsmToken::Percent: Kind = MCBinaryExpr::Mod; - return 5; - case AsmToken::LessLess: - Kind = MCBinaryExpr::Shl; - return 5; - case AsmToken::GreaterGreater: - Kind = MCBinaryExpr::Shr; - return 5; + return 6; } } @@ -932,10 +952,8 @@ bool AsmParser::ParseStatement() { StringRef IDVal; int64_t LocalLabelVal = -1; // A full line comment is a '#' as the first token. - if (Lexer.is(AsmToken::Hash)) { - EatToEndOfStatement(); - return false; - } + if (Lexer.is(AsmToken::Hash)) + return ParseCppHashLineFilenameComment(IDLoc); // Allow an integer followed by a ':' as a directional local label. if (Lexer.is(AsmToken::Integer)) { @@ -1117,15 +1135,8 @@ bool AsmParser::ParseStatement() { if (IDVal == ".globl" || IDVal == ".global") return ParseDirectiveSymbolAttribute(MCSA_Global); - // ELF only? Should it be here? - if (IDVal == ".local") - return ParseDirectiveSymbolAttribute(MCSA_Local); - if (IDVal == ".hidden") - return ParseDirectiveSymbolAttribute(MCSA_Hidden); if (IDVal == ".indirect_symbol") return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol); - if (IDVal == ".internal") - return ParseDirectiveSymbolAttribute(MCSA_Internal); if (IDVal == ".lazy_reference") return ParseDirectiveSymbolAttribute(MCSA_LazyReference); if (IDVal == ".no_dead_strip") @@ -1134,12 +1145,8 @@ bool AsmParser::ParseStatement() { return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver); if (IDVal == ".private_extern") return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern); - if (IDVal == ".protected") - return ParseDirectiveSymbolAttribute(MCSA_Protected); if (IDVal == ".reference") return ParseDirectiveSymbolAttribute(MCSA_Reference); - if (IDVal == ".weak") - return ParseDirectiveSymbolAttribute(MCSA_Weak); if (IDVal == ".weak_definition") return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition); if (IDVal == ".weak_reference") @@ -1157,7 +1164,7 @@ bool AsmParser::ParseStatement() { if (IDVal == ".include") return ParseDirectiveInclude(); - if (IDVal == ".code16" || IDVal == ".code32" || IDVal == ".code64") + if (IDVal == ".code16") return TokError(Twine(IDVal) + " not supported yet"); // Look up the handler in the handler table. @@ -1215,6 +1222,108 @@ bool AsmParser::ParseStatement() { return false; } +/// EatToEndOfLine uses the Lexer to eat the characters to the end of the line +/// since they may not be able to be tokenized to get to the end of line token. +void AsmParser::EatToEndOfLine() { + if (!Lexer.is(AsmToken::EndOfStatement)) + Lexer.LexUntilEndOfLine(); + // Eat EOL. + Lex(); +} + +/// ParseCppHashLineFilenameComment as this: +/// ::= # number "filename" +/// or just as a full line comment if it doesn't have a number and a string. +bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) { + Lex(); // Eat the hash token. + + if (getLexer().isNot(AsmToken::Integer)) { + // Consume the line since in cases it is not a well-formed line directive, + // as if were simply a full line comment. + EatToEndOfLine(); + return false; + } + + int64_t LineNumber = getTok().getIntVal(); + Lex(); + + if (getLexer().isNot(AsmToken::String)) { + EatToEndOfLine(); + return false; + } + + StringRef Filename = getTok().getString(); + // Get rid of the enclosing quotes. + Filename = Filename.substr(1, Filename.size()-2); + + // Save the SMLoc, Filename and LineNumber for later use by diagnostics. + CppHashLoc = L; + CppHashFilename = Filename; + CppHashLineNumber = LineNumber; + + // Ignore any trailing characters, they're just comment. + EatToEndOfLine(); + return false; +} + +/// DiagHandler - will use the the last parsed cpp hash line filename comment +/// for the Filename and LineNo if any in the diagnostic. +void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { + const AsmParser *Parser = static_cast(Context); + raw_ostream &OS = errs(); + + const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr(); + const SMLoc &DiagLoc = Diag.getLoc(); + int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); + int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc); + + // Like SourceMgr::PrintMessage() we need to print the include stack if any + // before printing the message. + int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); + if (!Parser->SavedDiagHandler && DiagCurBuffer > 0) { + SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer); + DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS); + } + + // If we have not parsed a cpp hash line filename comment or the source + // manager changed or buffer changed (like in a nested include) then just + // print the normal diagnostic using its Filename and LineNo. + if (!Parser->CppHashLineNumber || + &DiagSrcMgr != &Parser->SrcMgr || + DiagBuf != CppHashBuf) { + if (Parser->SavedDiagHandler) + Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext); + else + Diag.Print(0, OS); + return; + } + + // Use the CppHashFilename and calculate a line number based on the + // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for + // the diagnostic. + const std::string Filename = Parser->CppHashFilename; + + int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf); + int CppHashLocLineNo = + Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf); + int LineNo = Parser->CppHashLineNumber - 1 + + (DiagLocLineNo - CppHashLocLineNo); + + SMDiagnostic NewDiag(*Diag.getSourceMgr(), + Diag.getLoc(), + Filename, + LineNo, + Diag.getColumnNo(), + Diag.getMessage(), + Diag.getLineContents(), + Diag.getShowLine()); + + if (Parser->SavedDiagHandler) + Parser->SavedDiagHandler(NewDiag, Parser->SavedDiagContext); + else + NewDiag.Print(0, OS); +} + bool AsmParser::expandMacro(SmallString<256> &Buf, StringRef Body, const std::vector &Parameters, const std::vector > &A, @@ -1923,12 +2032,17 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) { if (getLexer().isNot(AsmToken::EndOfStatement)) { for (;;) { StringRef Name; + SMLoc Loc = getTok().getLoc(); if (ParseIdentifier(Name)) - return TokError("expected identifier in directive"); + return Error(Loc, "expected identifier in directive"); MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + // Assembler local symbols don't make any sense here. Complain loudly. + if (Sym->isTemporary()) + return Error(Loc, "non-local symbol required in directive"); + getStreamer().EmitSymbolAttribute(Sym, Attr); if (getLexer().is(AsmToken::EndOfStatement)) @@ -2416,7 +2530,7 @@ bool GenericAsmParser::ParseRegisterOrRegisterNumber(int64_t &Register, if (getParser().getTargetParser().ParseRegister(RegNo, DirectiveLoc, DirectiveLoc)) return true; - Register = getContext().getTargetAsmInfo().getDwarfRegNum(RegNo, true); + Register = getContext().getRegisterInfo().getDwarfRegNum(RegNo, true); } else return getParser().ParseAbsoluteExpression(Register); @@ -2724,8 +2838,8 @@ bool GenericAsmParser::ParseDirectiveLEB128(StringRef DirName, SMLoc) { /// \brief Create an MCAsmParser instance. -MCAsmParser *llvm::createMCAsmParser(const Target &T, SourceMgr &SM, +MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C, MCStreamer &Out, const MCAsmInfo &MAI) { - return new AsmParser(T, SM, C, Out, MAI); + return new AsmParser(SM, C, Out, MAI); } diff --git a/lib/MC/MCParser/CMakeLists.txt b/lib/MC/MCParser/CMakeLists.txt index eaea9f6cd3c5..299d28168948 100644 --- a/lib/MC/MCParser/CMakeLists.txt +++ b/lib/MC/MCParser/CMakeLists.txt @@ -7,5 +7,10 @@ add_llvm_library(LLVMMCParser MCAsmLexer.cpp MCAsmParser.cpp MCAsmParserExtension.cpp - TargetAsmParser.cpp + MCTargetAsmParser.cpp + ) + +add_llvm_library_dependencies(LLVMMCParser + LLVMMC + LLVMSupport ) diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp index 66ad384c7db2..185b5168bd6c 100644 --- a/lib/MC/MCParser/COFFAsmParser.cpp +++ b/lib/MC/MCParser/COFFAsmParser.cpp @@ -8,15 +8,16 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCParser/MCAsmParserExtension.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCParser/MCAsmLexer.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCExpr.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetAsmParser.h" +#include "llvm/MC/MCTargetAsmParser.h" #include "llvm/Support/COFF.h" using namespace llvm; @@ -72,6 +73,7 @@ class COFFAsmParser : public MCAsmParserExtension { ".seh_pushframe"); AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>( ".seh_endprologue"); + AddDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); } bool ParseSectionDirectiveText(StringRef, SMLoc) { @@ -118,12 +120,44 @@ class COFFAsmParser : public MCAsmParserExtension { bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except); bool ParseSEHRegisterNumber(unsigned &RegNo); + bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc); public: COFFAsmParser() {} }; } // end annonomous namespace. +/// ParseDirectiveSymbolAttribute +/// ::= { ".weak", ... } [ identifier ( , identifier )* ] +bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { + MCSymbolAttr Attr = StringSwitch(Directive) + .Case(".weak", MCSA_Weak) + .Default(MCSA_Invalid); + assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); + if (getLexer().isNot(AsmToken::EndOfStatement)) { + for (;;) { + StringRef Name; + + if (getParser().ParseIdentifier(Name)) + return TokError("expected identifier in directive"); + + MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + + getStreamer().EmitSymbolAttribute(Sym, Attr); + + if (getLexer().is(AsmToken::EndOfStatement)) + break; + + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in directive"); + Lex(); + } + } + + Lex(); + return false; +} + bool COFFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Characteristics, SectionKind Kind) { @@ -401,12 +435,16 @@ bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) { bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) { SMLoc startLoc = getLexer().getLoc(); if (getLexer().is(AsmToken::Percent)) { - const TargetAsmInfo &TAI = getContext().getTargetAsmInfo(); + const MCRegisterInfo &MRI = getContext().getRegisterInfo(); SMLoc endLoc; unsigned LLVMRegNo; if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc)) return true; +#if 0 + // FIXME: TargetAsmInfo::getCalleeSavedRegs() commits a serious layering + // violation so this validation code is disabled. + // Check that this is a non-volatile register. const unsigned *NVRegs = TAI.getCalleeSavedRegs(); unsigned i; @@ -415,8 +453,9 @@ bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) { break; if (NVRegs[i] == 0) return Error(startLoc, "expected non-volatile register"); +#endif - int SEHRegNo = TAI.getSEHRegNum(LLVMRegNo); + int SEHRegNo = MRI.getSEHRegNum(LLVMRegNo); if (SEHRegNo < 0) return Error(startLoc,"register can't be represented in SEH unwind info"); RegNo = SEHRegNo; diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index dcf689a6f0e7..d89112645cd8 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -47,12 +47,17 @@ class ELFAsmParser : public MCAsmParserExtension { AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata"); AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata"); AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss"); - AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel"); - AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro"); - AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveDataRelRoLocal>(".data.rel.ro.local"); - AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame"); + AddDirectiveHandler< + &ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel"); + AddDirectiveHandler< + &ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro"); + AddDirectiveHandler< + &ELFAsmParser::ParseSectionDirectiveDataRelRoLocal>(".data.rel.ro.local"); + AddDirectiveHandler< + &ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section"); - AddDirectiveHandler<&ELFAsmParser::ParseDirectivePushSection>(".pushsection"); + AddDirectiveHandler< + &ELFAsmParser::ParseDirectivePushSection>(".pushsection"); AddDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size"); AddDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous"); @@ -60,6 +65,14 @@ class ELFAsmParser : public MCAsmParserExtension { AddDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref"); + AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); + AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local"); + AddDirectiveHandler< + &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected"); + AddDirectiveHandler< + &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal"); + AddDirectiveHandler< + &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden"); } // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is @@ -129,6 +142,7 @@ class ELFAsmParser : public MCAsmParserExtension { bool ParseDirectiveIdent(StringRef, SMLoc); bool ParseDirectiveSymver(StringRef, SMLoc); bool ParseDirectiveWeakref(StringRef, SMLoc); + bool ParseDirectiveSymbolAttribute(StringRef, SMLoc); private: bool ParseSectionName(StringRef &SectionName); @@ -136,6 +150,41 @@ class ELFAsmParser : public MCAsmParserExtension { } +/// ParseDirectiveSymbolAttribute +/// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ] +bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { + MCSymbolAttr Attr = StringSwitch(Directive) + .Case(".weak", MCSA_Weak) + .Case(".local", MCSA_Local) + .Case(".hidden", MCSA_Hidden) + .Case(".internal", MCSA_Internal) + .Case(".protected", MCSA_Protected) + .Default(MCSA_Invalid); + assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); + if (getLexer().isNot(AsmToken::EndOfStatement)) { + for (;;) { + StringRef Name; + + if (getParser().ParseIdentifier(Name)) + return TokError("expected identifier in directive"); + + MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + + getStreamer().EmitSymbolAttribute(Sym, Attr); + + if (getLexer().is(AsmToken::EndOfStatement)) + break; + + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in directive"); + Lex(); + } + } + + Lex(); + return false; +} + bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags, SectionKind Kind) { if (getLexer().isNot(AsmToken::EndOfStatement)) diff --git a/lib/MC/MCParser/MCAsmParser.cpp b/lib/MC/MCParser/MCAsmParser.cpp index 4030e41036aa..5239ec753e77 100644 --- a/lib/MC/MCParser/MCAsmParser.cpp +++ b/lib/MC/MCParser/MCAsmParser.cpp @@ -8,13 +8,13 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCParser/MCAsmParser.h" -#include "llvm/ADT/Twine.h" #include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h" +#include "llvm/MC/MCTargetAsmParser.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Debug.h" -#include "llvm/Target/TargetAsmParser.h" +#include "llvm/ADT/Twine.h" using namespace llvm; MCAsmParser::MCAsmParser() : TargetParser(0), ShowParsedOperands(0) { @@ -23,7 +23,7 @@ MCAsmParser::MCAsmParser() : TargetParser(0), ShowParsedOperands(0) { MCAsmParser::~MCAsmParser() { } -void MCAsmParser::setTargetParser(TargetAsmParser &P) { +void MCAsmParser::setTargetParser(MCTargetAsmParser &P) { assert(!TargetParser && "Target parser is already initialized!"); TargetParser = &P; TargetParser->Initialize(*this); diff --git a/lib/MC/MCParser/TargetAsmParser.cpp b/lib/MC/MCParser/MCTargetAsmParser.cpp similarity index 64% rename from lib/MC/MCParser/TargetAsmParser.cpp rename to lib/MC/MCParser/MCTargetAsmParser.cpp index 512f6b044911..6fb1ba4216f8 100644 --- a/lib/MC/MCParser/TargetAsmParser.cpp +++ b/lib/MC/MCParser/MCTargetAsmParser.cpp @@ -1,4 +1,4 @@ -//===-- TargetAsmParser.cpp - Target Assembly Parser -----------------------==// +//===-- MCTargetAsmParser.cpp - Target Assembly Parser ---------------------==// // // The LLVM Compiler Infrastructure // @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Target/TargetAsmParser.h" +#include "llvm/MC/MCTargetAsmParser.h" using namespace llvm; -TargetAsmParser::TargetAsmParser() +MCTargetAsmParser::MCTargetAsmParser() : AvailableFeatures(0) { } -TargetAsmParser::~TargetAsmParser() { +MCTargetAsmParser::~MCTargetAsmParser() { } diff --git a/lib/MC/MCPureStreamer.cpp b/lib/MC/MCPureStreamer.cpp index 6098e6b8f38b..086c9229bcdc 100644 --- a/lib/MC/MCPureStreamer.cpp +++ b/lib/MC/MCPureStreamer.cpp @@ -28,7 +28,7 @@ class MCPureStreamer : public MCObjectStreamer { virtual void EmitInstToData(const MCInst &Inst); public: - MCPureStreamer(MCContext &Context, TargetAsmBackend &TAB, + MCPureStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter) : MCObjectStreamer(Context, TAB, OS, Emitter) {} @@ -86,7 +86,8 @@ class MCPureStreamer : public MCObjectStreamer { virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { report_fatal_error("unsupported directive in pure streamer"); } - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { report_fatal_error("unsupported directive in pure streamer"); } virtual void EmitFileDirective(StringRef Filename) { @@ -228,7 +229,7 @@ void MCPureStreamer::Finish() { this->MCObjectStreamer::Finish(); } -MCStreamer *llvm::createPureStreamer(MCContext &Context, TargetAsmBackend &TAB, +MCStreamer *llvm::createPureStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *CE) { - return new MCPureStreamer(Context, TAB, OS, CE); + return new MCPureStreamer(Context, MAB, OS, CE); } diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 6e96b78e315b..3afa22b0d0be 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -16,13 +16,17 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include using namespace llvm; MCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false), - CurrentW64UnwindInfo(0) { + CurrentW64UnwindInfo(0), + LastSymbol(0), + UniqueCodeBeginSuffix(0), + UniqueDataBeginSuffix(0) { const MCSection *section = NULL; SectionStack.push_back(std::make_pair(section, section)); } @@ -171,10 +175,94 @@ void MCStreamer::EmitLabel(MCSymbol *Symbol) { assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); assert(getCurrentSection() && "Cannot emit before setting section!"); Symbol->setSection(*getCurrentSection()); + LastSymbol = Symbol; +} - StringRef Prefix = getContext().getAsmInfo().getPrivateGlobalPrefix(); - if (!Symbol->getName().startswith(Prefix)) - LastNonPrivate = Symbol; +void MCStreamer::EmitDataRegion() { + if (RegionIndicator == Data) return; + + MCContext &Context = getContext(); + const MCAsmInfo &MAI = Context.getAsmInfo(); + if (!MAI.getSupportsDataRegions()) return; + + // Generate a unique symbol name. + MCSymbol *NewSym = Context.GetOrCreateSymbol( + Twine(MAI.getDataBeginLabelName()) + + utostr(UniqueDataBeginSuffix++)); + EmitLabel(NewSym); + + RegionIndicator = Data; +} + +void MCStreamer::EmitCodeRegion() { + if (RegionIndicator == Code) return; + + MCContext &Context = getContext(); + const MCAsmInfo &MAI = Context.getAsmInfo(); + if (!MAI.getSupportsDataRegions()) return; + + // Generate a unique symbol name. + MCSymbol *NewSym = Context.GetOrCreateSymbol( + Twine(MAI.getCodeBeginLabelName()) + + utostr(UniqueCodeBeginSuffix++)); + EmitLabel(NewSym); + + RegionIndicator = Code; +} + +void MCStreamer::EmitJumpTable8Region() { + if (RegionIndicator == JumpTable8) return; + + MCContext &Context = getContext(); + const MCAsmInfo &MAI = Context.getAsmInfo(); + if (!MAI.getSupportsDataRegions()) return; + + // Generate a unique symbol name. + MCSymbol *NewSym = Context.GetOrCreateSymbol( + Twine(MAI.getJumpTable8BeginLabelName()) + + utostr(UniqueDataBeginSuffix++)); + EmitLabel(NewSym); + + RegionIndicator = JumpTable8; +} + +void MCStreamer::EmitJumpTable16Region() { + if (RegionIndicator == JumpTable16) return; + + MCContext &Context = getContext(); + const MCAsmInfo &MAI = Context.getAsmInfo(); + if (!MAI.getSupportsDataRegions()) return; + + // Generate a unique symbol name. + MCSymbol *NewSym = Context.GetOrCreateSymbol( + Twine(MAI.getJumpTable16BeginLabelName()) + + utostr(UniqueDataBeginSuffix++)); + EmitLabel(NewSym); + + RegionIndicator = JumpTable16; +} + + +void MCStreamer::EmitJumpTable32Region() { + if (RegionIndicator == JumpTable32) return; + + MCContext &Context = getContext(); + const MCAsmInfo &MAI = Context.getAsmInfo(); + if (!MAI.getSupportsDataRegions()) return; + + // Generate a unique symbol name. + MCSymbol *NewSym = Context.GetOrCreateSymbol( + Twine(MAI.getJumpTable32BeginLabelName()) + + utostr(UniqueDataBeginSuffix++)); + EmitLabel(NewSym); + + RegionIndicator = JumpTable32; +} + +void MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) { + EnsureValidFrame(); + MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); + CurFrame->CompactUnwindEncoding = CompactUnwindEncoding; } void MCStreamer::EmitCFISections(bool EH, bool Debug) { @@ -187,11 +275,22 @@ void MCStreamer::EmitCFIStartProc() { MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); if (CurFrame && !CurFrame->End) report_fatal_error("Starting a frame before finishing the previous one!"); + MCDwarfFrameInfo Frame; - Frame.Begin = getContext().CreateTempSymbol(); - Frame.Function = LastNonPrivate; - EmitLabel(Frame.Begin); + Frame.Function = LastSymbol; + + // If the function is externally visible, we need to create a local + // symbol to avoid relocations. + StringRef Prefix = getContext().getAsmInfo().getPrivateGlobalPrefix(); + if (LastSymbol && LastSymbol->getName().startswith(Prefix)) { + Frame.Begin = LastSymbol; + } else { + Frame.Begin = getContext().CreateTempSymbol(); + EmitLabel(Frame.Begin); + } + FrameInfos.push_back(Frame); + RegionIndicator = Code; } void MCStreamer::EmitCFIEndProc() { diff --git a/lib/Target/TargetAsmLexer.cpp b/lib/MC/MCTargetAsmLexer.cpp similarity index 56% rename from lib/Target/TargetAsmLexer.cpp rename to lib/MC/MCTargetAsmLexer.cpp index d4893ff2521e..c01c914cecd2 100644 --- a/lib/Target/TargetAsmLexer.cpp +++ b/lib/MC/MCTargetAsmLexer.cpp @@ -1,4 +1,4 @@ -//===-- llvm/Target/TargetAsmLexer.cpp - Target Assembly Lexer ------------===// +//===-- llvm/MC/MCTargetAsmLexer.cpp - Target Assembly Lexer --------------===// // // The LLVM Compiler Infrastructure // @@ -7,8 +7,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Target/TargetAsmLexer.h" +#include "llvm/MC/MCTargetAsmLexer.h" using namespace llvm; -TargetAsmLexer::TargetAsmLexer(const Target &T) : TheTarget(T), Lexer(NULL) {} -TargetAsmLexer::~TargetAsmLexer() {} +MCTargetAsmLexer::MCTargetAsmLexer(const Target &T) + : TheTarget(T), Lexer(NULL) { +} +MCTargetAsmLexer::~MCTargetAsmLexer() {} diff --git a/lib/MC/MCWin64EH.cpp b/lib/MC/MCWin64EH.cpp index e698384a49f1..79e66fcdf2c0 100644 --- a/lib/MC/MCWin64EH.cpp +++ b/lib/MC/MCWin64EH.cpp @@ -10,10 +10,11 @@ #include "llvm/MC/MCWin64EH.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCExpr.h" -#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/ADT/Twine.h" namespace llvm { @@ -220,14 +221,36 @@ StringRef MCWin64EHUnwindEmitter::GetSectionSuffix(const MCSymbol *func) { return ""; } +static const MCSection *getWin64EHTableSection(StringRef suffix, + MCContext &context) { + if (suffix == "") + return context.getObjectFileInfo()->getXDataSection(); + + return context.getCOFFSection((".xdata"+suffix).str(), + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); +} + +static const MCSection *getWin64EHFuncTableSection(StringRef suffix, + MCContext &context) { + if (suffix == "") + return context.getObjectFileInfo()->getPDataSection(); + return context.getCOFFSection((".pdata"+suffix).str(), + COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | + COFF::IMAGE_SCN_MEM_READ | + COFF::IMAGE_SCN_MEM_WRITE, + SectionKind::getDataRel()); +} + void MCWin64EHUnwindEmitter::EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) { // Switch sections (the static function above is meant to be called from // here and from Emit(). MCContext &context = streamer.getContext(); - const TargetAsmInfo &TAI = context.getTargetAsmInfo(); const MCSection *xdataSect = - TAI.getWin64EHTableSection(GetSectionSuffix(info->Function)); + getWin64EHTableSection(GetSectionSuffix(info->Function), context); streamer.SwitchSection(xdataSect); llvm::EmitUnwindInfo(streamer, info); @@ -236,11 +259,10 @@ void MCWin64EHUnwindEmitter::EmitUnwindInfo(MCStreamer &streamer, void MCWin64EHUnwindEmitter::Emit(MCStreamer &streamer) { MCContext &context = streamer.getContext(); // Emit the unwind info structs first. - const TargetAsmInfo &TAI = context.getTargetAsmInfo(); for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i) { MCWin64EHUnwindInfo &info = streamer.getW64UnwindInfo(i); const MCSection *xdataSect = - TAI.getWin64EHTableSection(GetSectionSuffix(info.Function)); + getWin64EHTableSection(GetSectionSuffix(info.Function), context); streamer.SwitchSection(xdataSect); llvm::EmitUnwindInfo(streamer, &info); } @@ -248,7 +270,7 @@ void MCWin64EHUnwindEmitter::Emit(MCStreamer &streamer) { for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i) { MCWin64EHUnwindInfo &info = streamer.getW64UnwindInfo(i); const MCSection *pdataSect = - TAI.getWin64EHFuncTableSection(GetSectionSuffix(info.Function)); + getWin64EHFuncTableSection(GetSectionSuffix(info.Function), context); streamer.SwitchSection(pdataSect); EmitRuntimeFunction(streamer, &info); } diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp index 69efe231ad6e..a9219ad29c65 100644 --- a/lib/MC/MachObjectWriter.cpp +++ b/lib/MC/MachObjectWriter.cpp @@ -12,6 +12,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCObjectWriter.h" @@ -21,7 +22,6 @@ #include "llvm/MC/MCValue.h" #include "llvm/Object/MachOFormat.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Target/TargetAsmBackend.h" #include using namespace llvm; @@ -291,7 +291,7 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD, const MCSymbol &Symbol = Data.getSymbol(); uint8_t Type = 0; uint16_t Flags = Data.getFlags(); - uint32_t Address = 0; + uint64_t Address = 0; // Set the N_TYPE bits. See . // @@ -590,14 +590,28 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, return false; return true; } + // For Darwin x86_64, there is one special case when the reference IsPCRel. + // If the fragment with the reference does not have a base symbol but meets + // the simple way of dealing with this, in that it is a temporary symbol in + // the same atom then it is assumed to be fully resolved. This is needed so + // a relocation entry is not created and so the static linker does not + // mess up the reference later. + else if(!FB.getAtom() && + SA.isTemporary() && SA.isInSection() && &SecA == &SecB){ + return true; + } } else { if (!TargetObjectWriter->useAggressiveSymbolFolding()) return false; } - const MCFragment &FA = *Asm.getSymbolData(SA).getFragment(); + const MCFragment *FA = Asm.getSymbolData(SA).getFragment(); - A_Base = FA.getAtom(); + // Bail if the symbol has no fragment. + if (!FA) + return false; + + A_Base = FA->getAtom(); if (!A_Base) return false; @@ -613,7 +627,8 @@ IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, return false; } -void MachObjectWriter::WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) { +void MachObjectWriter::WriteObject(MCAssembler &Asm, + const MCAsmLayout &Layout) { unsigned NumSections = Asm.size(); // The section data starts after the header, the segment load command (and diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp index 101237aabb02..b15e225fc2a3 100644 --- a/lib/MC/WinCOFFObjectWriter.cpp +++ b/lib/MC/WinCOFFObjectWriter.cpp @@ -33,7 +33,7 @@ #include "llvm/Support/TimeValue.h" -#include "../Target/X86/X86FixupKinds.h" +#include "../Target/X86/MCTargetDesc/X86FixupKinds.h" #include diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp index 6c36c1231c83..7409daf39085 100644 --- a/lib/MC/WinCOFFStreamer.cpp +++ b/lib/MC/WinCOFFStreamer.cpp @@ -24,13 +24,13 @@ #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCWin64EH.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetAsmBackend.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -40,7 +40,7 @@ class WinCOFFStreamer : public MCObjectStreamer { MCSymbol const *CurSymbol; WinCOFFStreamer(MCContext &Context, - TargetAsmBackend &TAB, + MCAsmBackend &MAB, MCCodeEmitter &CE, raw_ostream &OS); @@ -63,7 +63,8 @@ class WinCOFFStreamer : public MCObjectStreamer { 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); + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment); virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, unsigned Size,unsigned ByteAlignment); virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, @@ -123,10 +124,10 @@ class WinCOFFStreamer : public MCObjectStreamer { } // end anonymous namespace. WinCOFFStreamer::WinCOFFStreamer(MCContext &Context, - TargetAsmBackend &TAB, + MCAsmBackend &MAB, MCCodeEmitter &CE, raw_ostream &OS) - : MCObjectStreamer(Context, TAB, OS, &CE) + : MCObjectStreamer(Context, MAB, OS, &CE) , CurSymbol(NULL) { } @@ -304,11 +305,12 @@ void WinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, AddCommonSymbol(Symbol, Size, ByteAlignment, true); } -void WinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) { +void WinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) { assert((Symbol->isInSection() ? Symbol->getSection().getVariant() == MCSection::SV_COFF : true) && "Got non COFF section in the COFF backend!"); - AddCommonSymbol(Symbol, Size, 1, false); + AddCommonSymbol(Symbol, Size, ByteAlignment, false); } void WinCOFFStreamer::EmitZerofill(const MCSection *Section, MCSymbol *Symbol, @@ -395,11 +397,11 @@ void WinCOFFStreamer::Finish() { namespace llvm { MCStreamer *createWinCOFFStreamer(MCContext &Context, - TargetAsmBackend &TAB, + MCAsmBackend &MAB, MCCodeEmitter &CE, raw_ostream &OS, bool RelaxAll) { - WinCOFFStreamer *S = new WinCOFFStreamer(Context, TAB, CE, OS); + WinCOFFStreamer *S = new WinCOFFStreamer(Context, MAB, CE, OS); S->getAssembler().setRelaxAll(RelaxAll); return S; } diff --git a/lib/Makefile b/lib/Makefile index ed27854f22c7..fd575cd19570 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -11,7 +11,7 @@ LEVEL = .. include $(LEVEL)/Makefile.config PARALLEL_DIRS := VMCore AsmParser Bitcode Archive Analysis Transforms CodeGen \ - Target ExecutionEngine Linker MC CompilerDriver Object + Target ExecutionEngine Linker MC Object DebugInfo include $(LEVEL)/Makefile.common diff --git a/lib/Object/Archive.cpp b/lib/Object/Archive.cpp new file mode 100644 index 000000000000..e2eaff53c1f1 --- /dev/null +++ b/lib/Object/Archive.cpp @@ -0,0 +1,172 @@ +//===- Archive.cpp - ar File Format implementation --------------*- 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 ArchiveObjectFile class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/Archive.h" +#include "llvm/ADT/APInt.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace llvm; +using namespace object; + +namespace { +const StringRef Magic = "!\n"; + +struct ArchiveMemberHeader { + char Name[16]; + char LastModified[12]; + char UID[6]; + char GID[6]; + char AccessMode[8]; + char Size[10]; //< Size of data, not including header or padding. + char Terminator[2]; + + ///! Get the name without looking up long names. + StringRef getName() const { + char EndCond = Name[0] == '/' ? ' ' : '/'; + StringRef::size_type end = StringRef(Name, sizeof(Name)).find(EndCond); + if (end == StringRef::npos) + end = sizeof(Name); + assert(end <= sizeof(Name) && end > 0); + // Don't include the EndCond if there is one. + return StringRef(Name, end); + } + + uint64_t getSize() const { + APInt ret; + StringRef(Size, sizeof(Size)).getAsInteger(10, ret); + return ret.getZExtValue(); + } +}; + +const ArchiveMemberHeader *ToHeader(const char *base) { + return reinterpret_cast(base); +} +} + +Archive::Child Archive::Child::getNext() const { + size_t SpaceToSkip = sizeof(ArchiveMemberHeader) + + ToHeader(Data.data())->getSize(); + // If it's odd, add 1 to make it even. + if (SpaceToSkip & 1) + ++SpaceToSkip; + + const char *NextLoc = Data.data() + SpaceToSkip; + + // Check to see if this is past the end of the archive. + if (NextLoc >= Parent->Data->getBufferEnd()) + return Child(Parent, StringRef(0, 0)); + + size_t NextSize = sizeof(ArchiveMemberHeader) + + ToHeader(NextLoc)->getSize(); + + return Child(Parent, StringRef(NextLoc, NextSize)); +} + +error_code Archive::Child::getName(StringRef &Result) const { + StringRef name = ToHeader(Data.data())->getName(); + // Check if it's a special name. + if (name[0] == '/') { + if (name.size() == 1) { // Linker member. + Result = name; + return object_error::success; + } + if (name.size() == 2 && name[1] == '/') { // String table. + Result = name; + return object_error::success; + } + // It's a long name. + // Get the offset. + APInt offset; + name.substr(1).getAsInteger(10, offset); + const char *addr = Parent->StringTable->Data.begin() + + sizeof(ArchiveMemberHeader) + + offset.getZExtValue(); + // Verify it. + if (Parent->StringTable == Parent->end_children() + || addr < (Parent->StringTable->Data.begin() + + sizeof(ArchiveMemberHeader)) + || addr > (Parent->StringTable->Data.begin() + + sizeof(ArchiveMemberHeader) + + Parent->StringTable->getSize())) + return object_error::parse_failed; + Result = addr; + return object_error::success; + } + // It's a simple name. + if (name[name.size() - 1] == '/') + Result = name.substr(0, name.size() - 1); + else + Result = name; + return object_error::success; +} + +uint64_t Archive::Child::getSize() const { + return ToHeader(Data.data())->getSize(); +} + +MemoryBuffer *Archive::Child::getBuffer() const { + StringRef name; + if (getName(name)) return NULL; + return MemoryBuffer::getMemBuffer(Data.substr(sizeof(ArchiveMemberHeader), + getSize()), + name, + false); +} + +error_code Archive::Child::getAsBinary(OwningPtr &Result) const { + OwningPtr ret; + if (error_code ec = + createBinary(getBuffer(), ret)) + return ec; + Result.swap(ret); + return object_error::success; +} + +Archive::Archive(MemoryBuffer *source, error_code &ec) + : Binary(Binary::isArchive, source) + , StringTable(Child(this, StringRef(0, 0))) { + // Check for sufficient magic. + if (!source || source->getBufferSize() + < (8 + sizeof(ArchiveMemberHeader) + 2) // Smallest archive. + || StringRef(source->getBufferStart(), 8) != Magic) { + ec = object_error::invalid_file_type; + return; + } + + // Get the string table. It's the 3rd member. + child_iterator StrTable = begin_children(); + child_iterator e = end_children(); + for (int i = 0; StrTable != e && i < 2; ++StrTable, ++i) {} + + // Check to see if there were 3 members, or the 3rd member wasn't named "//". + StringRef name; + if (StrTable != e && !StrTable->getName(name) && name == "//") + StringTable = StrTable; + + ec = object_error::success; +} + +Archive::child_iterator Archive::begin_children() const { + const char *Loc = Data->getBufferStart() + Magic.size(); + size_t Size = sizeof(ArchiveMemberHeader) + + ToHeader(Loc)->getSize(); + return Child(this, StringRef(Loc, Size)); +} + +Archive::child_iterator Archive::end_children() const { + return Child(this, StringRef(0, 0)); +} + +namespace llvm { + +} // end namespace llvm diff --git a/lib/Object/Binary.cpp b/lib/Object/Binary.cpp index 4b31c7557dd3..4e528d8ea565 100644 --- a/lib/Object/Binary.cpp +++ b/lib/Object/Binary.cpp @@ -17,8 +17,9 @@ #include "llvm/Support/Path.h" // Include headers for createBinary. -#include "llvm/Object/ObjectFile.h" +#include "llvm/Object/Archive.h" #include "llvm/Object/COFF.h" +#include "llvm/Object/ObjectFile.h" using namespace llvm; using namespace object; @@ -50,6 +51,12 @@ error_code object::createBinary(MemoryBuffer *Source, static_cast(Source->getBufferSize())); error_code ec; switch (type) { + case sys::Archive_FileType: { + OwningPtr ret(new Archive(scopedSource.take(), ec)); + if (ec) return ec; + Result.swap(ret); + return object_error::success; + } case sys::ELF_Relocatable_FileType: case sys::ELF_Executable_FileType: case sys::ELF_SharedObject_FileType: @@ -90,7 +97,7 @@ error_code object::createBinary(MemoryBuffer *Source, error_code object::createBinary(StringRef Path, OwningPtr &Result) { OwningPtr File; - if (error_code ec = MemoryBuffer::getFile(Path, File)) + if (error_code ec = MemoryBuffer::getFileOrSTDIN(Path, File)) return ec; return createBinary(File.take(), Result); } diff --git a/lib/Object/CMakeLists.txt b/lib/Object/CMakeLists.txt index 68e5e94924d0..86eb51a01646 100644 --- a/lib/Object/CMakeLists.txt +++ b/lib/Object/CMakeLists.txt @@ -1,4 +1,5 @@ add_llvm_library(LLVMObject + Archive.cpp Binary.cpp COFFObjectFile.cpp ELFObjectFile.cpp @@ -8,3 +9,8 @@ add_llvm_library(LLVMObject Object.cpp ObjectFile.cpp ) + +add_llvm_library_dependencies(LLVMObject + LLVMCore + LLVMSupport + ) diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 07de6bc99973..750c34d12a18 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Object/COFF.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" @@ -114,7 +115,7 @@ error_code COFFObjectFile::getSymbolNext(DataRefImpl Symb, return object_error::success; } -error_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb, +error_code COFFObjectFile::getSymbolOffset(DataRefImpl Symb, uint64_t &Result) const { const coff_symbol *symb = toSymb(Symb); const coff_section *Section = NULL; @@ -132,6 +133,55 @@ error_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb, return object_error::success; } +error_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb, + uint64_t &Result) const { + const coff_symbol *symb = toSymb(Symb); + const coff_section *Section = NULL; + if (error_code ec = getSection(symb->SectionNumber, Section)) + return ec; + char Type; + if (error_code ec = getSymbolNMTypeChar(Symb, Type)) + return ec; + if (Type == 'U' || Type == 'w') + Result = UnknownAddressOrSize; + else if (Section) + Result = reinterpret_cast(base() + + Section->PointerToRawData + + symb->Value); + else + Result = reinterpret_cast(base() + symb->Value); + return object_error::success; +} + +error_code COFFObjectFile::getSymbolType(DataRefImpl Symb, + SymbolRef::SymbolType &Result) const { + const coff_symbol *symb = toSymb(Symb); + Result = SymbolRef::ST_Other; + if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && + symb->SectionNumber == COFF::IMAGE_SYM_UNDEFINED) { + Result = SymbolRef::ST_External; + } else { + if (symb->Type.ComplexType == COFF::IMAGE_SYM_DTYPE_FUNCTION) { + Result = SymbolRef::ST_Function; + } else { + char Type; + if (error_code ec = getSymbolNMTypeChar(Symb, Type)) + return ec; + if (Type == 'r' || Type == 'R') { + Result = SymbolRef::ST_Data; + } + } + } + return object_error::success; +} + +error_code COFFObjectFile::isSymbolGlobal(DataRefImpl Symb, + bool &Result) const { + const coff_symbol *symb = toSymb(Symb); + Result = (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL); + return object_error::success; +} + error_code COFFObjectFile::getSymbolSize(DataRefImpl Symb, uint64_t &Result) const { // FIXME: Return the correct size. This requires looking at all the symbols @@ -286,6 +336,15 @@ error_code COFFObjectFile::getSectionContents(DataRefImpl Sec, return object_error::success; } +error_code COFFObjectFile::getSectionAlignment(DataRefImpl Sec, + uint64_t &Res) const { + const coff_section *sec = toSec(Sec); + if (!sec) + return object_error::parse_failed; + Res = uint64_t(1) << (((sec->Characteristics & 0x00F00000) >> 20) - 1); + return object_error::success; +} + error_code COFFObjectFile::isSectionText(DataRefImpl Sec, bool &Result) const { const coff_section *sec = toSec(Sec); @@ -293,14 +352,61 @@ error_code COFFObjectFile::isSectionText(DataRefImpl Sec, return object_error::success; } +error_code COFFObjectFile::isSectionData(DataRefImpl Sec, + bool &Result) const { + const coff_section *sec = toSec(Sec); + Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; + return object_error::success; +} + +error_code COFFObjectFile::isSectionBSS(DataRefImpl Sec, + bool &Result) const { + const coff_section *sec = toSec(Sec); + Result = sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; + return object_error::success; +} + error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const { - // FIXME: Unimplemented. - Result = false; + const coff_section *sec = toSec(Sec); + const coff_symbol *symb = toSymb(Symb); + const coff_section *symb_sec; + if (error_code ec = getSection(symb->SectionNumber, symb_sec)) return ec; + if (symb_sec == sec) + Result = true; + else + Result = false; return object_error::success; } +relocation_iterator COFFObjectFile::getSectionRelBegin(DataRefImpl Sec) const { + const coff_section *sec = toSec(Sec); + DataRefImpl ret; + std::memset(&ret, 0, sizeof(ret)); + if (sec->NumberOfRelocations == 0) + ret.p = 0; + else + ret.p = reinterpret_cast(base() + sec->PointerToRelocations); + + return relocation_iterator(RelocationRef(ret, this)); +} + +relocation_iterator COFFObjectFile::getSectionRelEnd(DataRefImpl Sec) const { + const coff_section *sec = toSec(Sec); + DataRefImpl ret; + std::memset(&ret, 0, sizeof(ret)); + if (sec->NumberOfRelocations == 0) + ret.p = 0; + else + ret.p = reinterpret_cast( + reinterpret_cast( + base() + sec->PointerToRelocations) + + sec->NumberOfRelocations); + + return relocation_iterator(RelocationRef(ret, this)); +} + COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) : ObjectFile(Binary::isCOFF, Object, ec) { // Check that we at least have enough room for a header. @@ -327,7 +433,7 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) Header = reinterpret_cast(base() + HeaderStart); if (!checkAddr(Data, ec, uintptr_t(Header), sizeof(coff_file_header))) return; - + SectionTable = reinterpret_cast( base() + HeaderStart @@ -360,18 +466,18 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) ec = object_error::parse_failed; return; } - + ec = object_error::success; } -ObjectFile::symbol_iterator COFFObjectFile::begin_symbols() const { +symbol_iterator COFFObjectFile::begin_symbols() const { DataRefImpl ret; std::memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast(SymbolTable); return symbol_iterator(SymbolRef(ret, this)); } -ObjectFile::symbol_iterator COFFObjectFile::end_symbols() const { +symbol_iterator COFFObjectFile::end_symbols() const { // The symbol table ends where the string table begins. DataRefImpl ret; std::memset(&ret, 0, sizeof(DataRefImpl)); @@ -379,14 +485,14 @@ ObjectFile::symbol_iterator COFFObjectFile::end_symbols() const { return symbol_iterator(SymbolRef(ret, this)); } -ObjectFile::section_iterator COFFObjectFile::begin_sections() const { +section_iterator COFFObjectFile::begin_sections() const { DataRefImpl ret; std::memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast(SectionTable); return section_iterator(SectionRef(ret, this)); } -ObjectFile::section_iterator COFFObjectFile::end_sections() const { +section_iterator COFFObjectFile::end_sections() const { DataRefImpl ret; std::memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast(SectionTable + Header->NumberOfSections); @@ -445,6 +551,121 @@ error_code COFFObjectFile::getString(uint32_t offset, return object_error::success; } +error_code COFFObjectFile::getSymbol(uint32_t index, + const coff_symbol *&Result) const { + if (index > 0 && index < Header->NumberOfSymbols) + Result = SymbolTable + index; + else + return object_error::parse_failed; + return object_error::success; +} + +const coff_relocation *COFFObjectFile::toRel(DataRefImpl Rel) const { + return reinterpret_cast(Rel.p); +} +error_code COFFObjectFile::getRelocationNext(DataRefImpl Rel, + RelocationRef &Res) const { + Rel.p = reinterpret_cast( + reinterpret_cast(Rel.p) + 1); + Res = RelocationRef(Rel, this); + return object_error::success; +} +error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel, + uint64_t &Res) const { + Res = toRel(Rel)->VirtualAddress; + return object_error::success; +} +error_code COFFObjectFile::getRelocationSymbol(DataRefImpl Rel, + SymbolRef &Res) const { + const coff_relocation* R = toRel(Rel); + DataRefImpl Symb; + Symb.p = reinterpret_cast(SymbolTable + R->SymbolTableIndex); + Res = SymbolRef(Symb, this); + return object_error::success; +} +error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, + uint32_t &Res) const { + const coff_relocation* R = toRel(Rel); + Res = R->Type; + return object_error::success; +} + +#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(enum) \ + case COFF::enum: res = #enum; break; + +error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl &Result) const { + const coff_relocation *reloc = toRel(Rel); + StringRef res; + switch (Header->Machine) { + case COFF::IMAGE_FILE_MACHINE_AMD64: + switch (reloc->Type) { + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ABSOLUTE); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR64); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_ADDR32NB); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_1); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_2); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_3); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_4); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_REL32_5); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECTION); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SECREL7); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_TOKEN); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SREL32); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_PAIR); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_AMD64_SSPAN32); + default: + res = "Unknown"; + } + break; + case COFF::IMAGE_FILE_MACHINE_I386: + switch (reloc->Type) { + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR16); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL16); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_DIR32NB); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SEG12); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECTION); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_TOKEN); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_SECREL7); + LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_REL32); + default: + res = "Unknown"; + } + break; + default: + res = "Unknown"; + } + Result.append(res.begin(), res.end()); + return object_error::success; +} + +#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME + +error_code COFFObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, + int64_t &Res) const { + Res = 0; + return object_error::success; +} +error_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel, + SmallVectorImpl &Result) const { + const coff_relocation *reloc = toRel(Rel); + const coff_symbol *symb = 0; + if (error_code ec = getSymbol(reloc->SymbolTableIndex, symb)) return ec; + DataRefImpl sym; + ::memset(&sym, 0, sizeof(sym)); + sym.p = reinterpret_cast(symb); + StringRef symname; + if (error_code ec = getSymbolName(sym, symname)) return ec; + Result.append(symname.begin(), symname.end()); + return object_error::success; +} + namespace llvm { ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) { diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index e2ff4dfc0384..257d08cadff3 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -14,11 +14,14 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" +#include #include #include @@ -175,6 +178,81 @@ struct Elf_Sym_Impl : Elf_Sym_Base { }; } +namespace { +template +struct Elf_Rel_Base; + +template +struct Elf_Rel_Base { + LLVM_ELF_IMPORT_TYPES(target_endianness, false) + Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) + Elf_Word r_info; // Symbol table index and type of relocation to apply +}; + +template +struct Elf_Rel_Base { + LLVM_ELF_IMPORT_TYPES(target_endianness, true) + Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) + Elf_Xword r_info; // Symbol table index and type of relocation to apply +}; + +template +struct Elf_Rel_Base { + LLVM_ELF_IMPORT_TYPES(target_endianness, false) + Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) + Elf_Word r_info; // Symbol table index and type of relocation to apply + Elf_Sword r_addend; // Compute value for relocatable field by adding this +}; + +template +struct Elf_Rel_Base { + LLVM_ELF_IMPORT_TYPES(target_endianness, true) + Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) + Elf_Xword r_info; // Symbol table index and type of relocation to apply + Elf_Sxword r_addend; // Compute value for relocatable field by adding this. +}; + +template +struct Elf_Rel_Impl; + +template +struct Elf_Rel_Impl + : Elf_Rel_Base { + using Elf_Rel_Base::r_info; + LLVM_ELF_IMPORT_TYPES(target_endianness, true) + + // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, + // and ELF64_R_INFO macros defined in the ELF specification: + uint64_t getSymbol() const { return (r_info >> 32); } + unsigned char getType() const { + return (unsigned char) (r_info & 0xffffffffL); + } + void setSymbol(uint64_t s) { setSymbolAndType(s, getType()); } + void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } + void setSymbolAndType(uint64_t s, unsigned char t) { + r_info = (s << 32) + (t&0xffffffffL); + } +}; + +template +struct Elf_Rel_Impl + : Elf_Rel_Base { + using Elf_Rel_Base::r_info; + LLVM_ELF_IMPORT_TYPES(target_endianness, false) + + // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, + // and ELF32_R_INFO macros defined in the ELF specification: + uint32_t getSymbol() const { return (r_info >> 8); } + unsigned char getType() const { return (unsigned char) (r_info & 0x0ff); } + void setSymbol(uint32_t s) { setSymbolAndType(s, getType()); } + void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); } + void setSymbolAndType(uint32_t s, unsigned char t) { + r_info = (s << 8) + t; + } +}; + +} + namespace { template class ELFObjectFile : public ObjectFile { @@ -182,6 +260,8 @@ class ELFObjectFile : public ObjectFile { typedef Elf_Shdr_Impl Elf_Shdr; typedef Elf_Sym_Impl Elf_Sym; + typedef Elf_Rel_Impl Elf_Rel; + typedef Elf_Rel_Impl Elf_Rela; struct Elf_Ehdr { unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes @@ -206,37 +286,81 @@ class ELFObjectFile : public ObjectFile { unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; } }; - typedef SmallVector SymbolTableSections_t; + typedef SmallVector Sections_t; + typedef DenseMap IndexMap_t; + typedef DenseMap > RelocMap_t; const Elf_Ehdr *Header; const Elf_Shdr *SectionHeaderTable; const Elf_Shdr *dot_shstrtab_sec; // Section header string table. const Elf_Shdr *dot_strtab_sec; // Symbol header string table. - SymbolTableSections_t SymbolTableSections; + Sections_t SymbolTableSections; + IndexMap_t SymbolTableSectionsIndexMap; + DenseMap ExtendedSymbolTable; + + /// @brief Map sections to an array of relocation sections that reference + /// them sorted by section index. + RelocMap_t SectionRelocMap; + + /// @brief Get the relocation section that contains \a Rel. + const Elf_Shdr *getRelSection(DataRefImpl Rel) const { + return getSection(Rel.w.b); + } void validateSymbol(DataRefImpl Symb) const; + bool isRelocationHasAddend(DataRefImpl Rel) const; + template + const T *getEntry(uint16_t Section, uint32_t Entry) const; + template + const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const; const Elf_Sym *getSymbol(DataRefImpl Symb) const; const Elf_Shdr *getSection(DataRefImpl index) const; - const Elf_Shdr *getSection(uint16_t index) const; - const char *getString(uint16_t section, uint32_t offset) const; + const Elf_Shdr *getSection(uint32_t index) const; + const Elf_Rel *getRel(DataRefImpl Rel) const; + const Elf_Rela *getRela(DataRefImpl Rela) const; + const char *getString(uint32_t section, uint32_t offset) const; const char *getString(const Elf_Shdr *section, uint32_t offset) const; + error_code getSymbolName(const Elf_Sym *Symb, StringRef &Res) const; protected: virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; + virtual error_code getSymbolOffset(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const; + virtual error_code isSymbolGlobal(DataRefImpl Symb, bool &Res) const; + virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::SymbolType &Res) const; virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; + virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const; virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const; + virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; + virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const; + + virtual error_code getRelocationNext(DataRefImpl Rel, + RelocationRef &Res) const; + virtual error_code getRelocationAddress(DataRefImpl Rel, + uint64_t &Res) const; + virtual error_code getRelocationSymbol(DataRefImpl Rel, + SymbolRef &Res) const; + virtual error_code getRelocationType(DataRefImpl Rel, + uint32_t &Res) const; + virtual error_code getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl &Result) const; + virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, + int64_t &Res) const; + virtual error_code getRelocationValueString(DataRefImpl Rel, + SmallVectorImpl &Result) const; public: ELFObjectFile(MemoryBuffer *Object, error_code &ec); @@ -248,6 +372,11 @@ class ELFObjectFile : public ObjectFile { virtual uint8_t getBytesInAddress() const; virtual StringRef getFileFormatName() const; virtual unsigned getArch() const; + + uint64_t getNumSections() const; + uint64_t getStringTableIndex() const; + ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const; + const Elf_Shdr *getSection(const Elf_Sym *symb) const; }; } // end namespace @@ -299,29 +428,37 @@ error_code ELFObjectFile ::getSymbolName(DataRefImpl Symb, StringRef &Result) const { validateSymbol(Symb); - const Elf_Sym *symb = getSymbol(Symb); - if (symb->st_name == 0) { - const Elf_Shdr *section = getSection(symb->st_shndx); - if (!section) - Result = ""; - else - Result = getString(dot_shstrtab_sec, section->sh_name); - return object_error::success; - } + const Elf_Sym *symb = getSymbol(Symb); + return getSymbolName(symb, Result); +} - // Use the default symbol table name section. - Result = getString(dot_strtab_sec, symb->st_name); - return object_error::success; +template +ELF::Elf64_Word ELFObjectFile + ::getSymbolTableIndex(const Elf_Sym *symb) const { + if (symb->st_shndx == ELF::SHN_XINDEX) + return ExtendedSymbolTable.lookup(symb); + return symb->st_shndx; +} + +template +const typename ELFObjectFile::Elf_Shdr * +ELFObjectFile + ::getSection(const Elf_Sym *symb) const { + if (symb->st_shndx == ELF::SHN_XINDEX) + return getSection(ExtendedSymbolTable.lookup(symb)); + if (symb->st_shndx >= ELF::SHN_LORESERVE) + return 0; + return getSection(symb->st_shndx); } template error_code ELFObjectFile - ::getSymbolAddress(DataRefImpl Symb, - uint64_t &Result) const { + ::getSymbolOffset(DataRefImpl Symb, + uint64_t &Result) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); const Elf_Shdr *Section; - switch (symb->st_shndx) { + switch (getSymbolTableIndex(symb)) { case ELF::SHN_COMMON: // Undefined symbols have no address yet. case ELF::SHN_UNDEF: @@ -330,7 +467,7 @@ error_code ELFObjectFile case ELF::SHN_ABS: Result = symb->st_value; return object_error::success; - default: Section = getSection(symb->st_shndx); + default: Section = getSection(symb); } switch (symb->getType()) { @@ -348,6 +485,43 @@ error_code ELFObjectFile } } +template +error_code ELFObjectFile + ::getSymbolAddress(DataRefImpl Symb, + uint64_t &Result) const { + validateSymbol(Symb); + const Elf_Sym *symb = getSymbol(Symb); + const Elf_Shdr *Section; + switch (getSymbolTableIndex(symb)) { + case ELF::SHN_COMMON: // Fall through. + // Undefined symbols have no address yet. + case ELF::SHN_UNDEF: + Result = UnknownAddressOrSize; + return object_error::success; + case ELF::SHN_ABS: + Result = reinterpret_cast(base()+symb->st_value); + return object_error::success; + default: Section = getSection(symb); + } + const uint8_t* addr = base(); + if (Section) + addr += Section->sh_offset; + switch (symb->getType()) { + case ELF::STT_SECTION: + Result = reinterpret_cast(addr); + return object_error::success; + case ELF::STT_FUNC: // Fall through. + case ELF::STT_OBJECT: // Fall through. + case ELF::STT_NOTYPE: + addr += symb->st_value; + Result = reinterpret_cast(addr); + return object_error::success; + default: + Result = UnknownAddressOrSize; + return object_error::success; + } +} + template error_code ELFObjectFile ::getSymbolSize(DataRefImpl Symb, @@ -366,7 +540,7 @@ error_code ELFObjectFile char &Result) const { validateSymbol(Symb); const Elf_Sym *symb = getSymbol(Symb); - const Elf_Shdr *Section = getSection(symb->st_shndx); + const Elf_Shdr *Section = getSection(symb); char ret = '?'; @@ -389,7 +563,7 @@ error_code ELFObjectFile } } - switch (symb->st_shndx) { + switch (getSymbolTableIndex(symb)) { case ELF::SHN_UNDEF: if (ret == '?') ret = 'U'; @@ -401,7 +575,7 @@ error_code ELFObjectFile switch (symb->getBinding()) { case ELF::STB_GLOBAL: ret = ::toupper(ret); break; case ELF::STB_WEAK: - if (symb->st_shndx == ELF::SHN_UNDEF) + if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF) ret = 'w'; else if (symb->getType() == ELF::STT_OBJECT) @@ -416,7 +590,8 @@ error_code ELFObjectFile return ec; Result = StringSwitch(name) .StartsWith(".debug", 'N') - .StartsWith(".note", 'n'); + .StartsWith(".note", 'n') + .Default('?'); return object_error::success; } @@ -424,6 +599,43 @@ error_code ELFObjectFile return object_error::success; } +template +error_code ELFObjectFile + ::getSymbolType(DataRefImpl Symb, + SymbolRef::SymbolType &Result) const { + validateSymbol(Symb); + const Elf_Sym *symb = getSymbol(Symb); + + if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF) { + Result = SymbolRef::ST_External; + return object_error::success; + } + + switch (symb->getType()) { + case ELF::STT_FUNC: + Result = SymbolRef::ST_Function; + break; + case ELF::STT_OBJECT: + Result = SymbolRef::ST_Data; + break; + default: + Result = SymbolRef::ST_Other; + break; + } + return object_error::success; +} + +template +error_code ELFObjectFile + ::isSymbolGlobal(DataRefImpl Symb, + bool &Result) const { + validateSymbol(Symb); + const Elf_Sym *symb = getSymbol(Symb); + + Result = symb->getBinding() == ELF::STB_GLOBAL; + return object_error::success; +} + template error_code ELFObjectFile ::isSymbolInternal(DataRefImpl Symb, @@ -485,6 +697,15 @@ error_code ELFObjectFile return object_error::success; } +template +error_code ELFObjectFile + ::getSectionAlignment(DataRefImpl Sec, + uint64_t &Result) const { + const Elf_Shdr *sec = reinterpret_cast(Sec.p); + Result = sec->sh_addralign; + return object_error::success; +} + template error_code ELFObjectFile ::isSectionText(DataRefImpl Sec, @@ -497,6 +718,32 @@ error_code ELFObjectFile return object_error::success; } +template +error_code ELFObjectFile + ::isSectionData(DataRefImpl Sec, + bool &Result) const { + const Elf_Shdr *sec = reinterpret_cast(Sec.p); + if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) + && sec->sh_type == ELF::SHT_PROGBITS) + Result = true; + else + Result = false; + return object_error::success; +} + +template +error_code ELFObjectFile + ::isSectionBSS(DataRefImpl Sec, + bool &Result) const { + const Elf_Shdr *sec = reinterpret_cast(Sec.p); + if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE) + && sec->sh_type == ELF::SHT_NOBITS) + Result = true; + else + Result = false; + return object_error::success; +} + template error_code ELFObjectFile ::sectionContainsSymbol(DataRefImpl Sec, @@ -507,6 +754,330 @@ error_code ELFObjectFile return object_error::success; } +template +relocation_iterator ELFObjectFile + ::getSectionRelBegin(DataRefImpl Sec) const { + DataRefImpl RelData; + memset(&RelData, 0, sizeof(RelData)); + const Elf_Shdr *sec = reinterpret_cast(Sec.p); + typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); + if (sec != 0 && ittr != SectionRelocMap.end()) { + RelData.w.a = getSection(ittr->second[0])->sh_info; + RelData.w.b = ittr->second[0]; + RelData.w.c = 0; + } + return relocation_iterator(RelocationRef(RelData, this)); +} + +template +relocation_iterator ELFObjectFile + ::getSectionRelEnd(DataRefImpl Sec) const { + DataRefImpl RelData; + memset(&RelData, 0, sizeof(RelData)); + const Elf_Shdr *sec = reinterpret_cast(Sec.p); + typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec); + if (sec != 0 && ittr != SectionRelocMap.end()) { + // Get the index of the last relocation section for this section. + std::size_t relocsecindex = ittr->second[ittr->second.size() - 1]; + const Elf_Shdr *relocsec = getSection(relocsecindex); + RelData.w.a = relocsec->sh_info; + RelData.w.b = relocsecindex; + RelData.w.c = relocsec->sh_size / relocsec->sh_entsize; + } + return relocation_iterator(RelocationRef(RelData, this)); +} + +// Relocations +template +error_code ELFObjectFile + ::getRelocationNext(DataRefImpl Rel, + RelocationRef &Result) const { + ++Rel.w.c; + const Elf_Shdr *relocsec = getSection(Rel.w.b); + if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) { + // We have reached the end of the relocations for this section. See if there + // is another relocation section. + typename RelocMap_t::mapped_type relocseclist = + SectionRelocMap.lookup(getSection(Rel.w.a)); + + // Do a binary search for the current reloc section index (which must be + // present). Then get the next one. + typename RelocMap_t::mapped_type::const_iterator loc = + std::lower_bound(relocseclist.begin(), relocseclist.end(), Rel.w.b); + ++loc; + + // If there is no next one, don't do anything. The ++Rel.w.c above sets Rel + // to the end iterator. + if (loc != relocseclist.end()) { + Rel.w.b = *loc; + Rel.w.a = 0; + } + } + Result = RelocationRef(Rel, this); + return object_error::success; +} + +template +error_code ELFObjectFile + ::getRelocationSymbol(DataRefImpl Rel, + SymbolRef &Result) const { + uint32_t symbolIdx; + const Elf_Shdr *sec = getSection(Rel.w.b); + switch (sec->sh_type) { + default : + report_fatal_error("Invalid section type in Rel!"); + case ELF::SHT_REL : { + symbolIdx = getRel(Rel)->getSymbol(); + break; + } + case ELF::SHT_RELA : { + symbolIdx = getRela(Rel)->getSymbol(); + break; + } + } + DataRefImpl SymbolData; + IndexMap_t::const_iterator it = SymbolTableSectionsIndexMap.find(sec->sh_link); + if (it == SymbolTableSectionsIndexMap.end()) + report_fatal_error("Relocation symbol table not found!"); + SymbolData.d.a = symbolIdx; + SymbolData.d.b = it->second; + Result = SymbolRef(SymbolData, this); + return object_error::success; +} + +template +error_code ELFObjectFile + ::getRelocationAddress(DataRefImpl Rel, + uint64_t &Result) const { + uint64_t offset; + const Elf_Shdr *sec = getSection(Rel.w.b); + switch (sec->sh_type) { + default : + report_fatal_error("Invalid section type in Rel!"); + case ELF::SHT_REL : { + offset = getRel(Rel)->r_offset; + break; + } + case ELF::SHT_RELA : { + offset = getRela(Rel)->r_offset; + break; + } + } + + Result = offset; + return object_error::success; +} + +template +error_code ELFObjectFile + ::getRelocationType(DataRefImpl Rel, + uint32_t &Result) const { + const Elf_Shdr *sec = getSection(Rel.w.b); + switch (sec->sh_type) { + default : + report_fatal_error("Invalid section type in Rel!"); + case ELF::SHT_REL : { + Result = getRel(Rel)->getType(); + break; + } + case ELF::SHT_RELA : { + Result = getRela(Rel)->getType(); + break; + } + } + return object_error::success; +} + +#define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \ + case ELF::enum: res = #enum; break; + +template +error_code ELFObjectFile + ::getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl &Result) const { + const Elf_Shdr *sec = getSection(Rel.w.b); + uint8_t type; + StringRef res; + switch (sec->sh_type) { + default : + return object_error::parse_failed; + case ELF::SHT_REL : { + type = getRel(Rel)->getType(); + break; + } + case ELF::SHT_RELA : { + type = getRela(Rel)->getType(); + break; + } + } + switch (Header->e_machine) { + case ELF::EM_X86_64: + switch (type) { + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_NONE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOT32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PLT32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_COPY); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GLOB_DAT); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_JUMP_SLOT); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_RELATIVE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPCREL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_32S); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_8); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC8); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPMOD64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSGD); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSLD); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_DTPOFF32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTTPOFF); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TPOFF32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_PC64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTOFF64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_SIZE64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_GOTPC32_TLSDESC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC_CALL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_X86_64_TLSDESC); + default: + res = "Unknown"; + } + break; + case ELF::EM_386: + switch (type) { + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_NONE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOT32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PLT32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_COPY); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GLOB_DAT); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_JUMP_SLOT); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_RELATIVE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTOFF); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_GOTPC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_32PLT); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTIE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_8); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_PC8); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_PUSH); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_CALL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GD_POP); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_PUSH); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_CALL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDM_POP); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LDO_32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_IE_32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_LE_32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPMOD32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DTPOFF32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_TPOFF32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_GOTDESC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC_CALL); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_TLS_DESC); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_386_IRELATIVE); + default: + res = "Unknown"; + } + break; + default: + res = "Unknown"; + } + Result.append(res.begin(), res.end()); + return object_error::success; +} + +#undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME + +template +error_code ELFObjectFile + ::getRelocationAdditionalInfo(DataRefImpl Rel, + int64_t &Result) const { + const Elf_Shdr *sec = getSection(Rel.w.b); + switch (sec->sh_type) { + default : + report_fatal_error("Invalid section type in Rel!"); + case ELF::SHT_REL : { + Result = 0; + return object_error::success; + } + case ELF::SHT_RELA : { + Result = getRela(Rel)->r_addend; + return object_error::success; + } + } +} + +template +error_code ELFObjectFile + ::getRelocationValueString(DataRefImpl Rel, + SmallVectorImpl &Result) const { + const Elf_Shdr *sec = getSection(Rel.w.b); + uint8_t type; + StringRef res; + int64_t addend = 0; + uint16_t symbol_index = 0; + switch (sec->sh_type) { + default : + return object_error::parse_failed; + case ELF::SHT_REL : { + type = getRel(Rel)->getType(); + symbol_index = getRel(Rel)->getSymbol(); + // TODO: Read implicit addend from section data. + break; + } + case ELF::SHT_RELA : { + type = getRela(Rel)->getType(); + symbol_index = getRela(Rel)->getSymbol(); + addend = getRela(Rel)->r_addend; + break; + } + } + const Elf_Sym *symb = getEntry(sec->sh_link, symbol_index); + StringRef symname; + if (error_code ec = getSymbolName(symb, symname)) + return ec; + switch (Header->e_machine) { + case ELF::EM_X86_64: + switch (type) { + case ELF::R_X86_64_32S: + res = symname; + break; + case ELF::R_X86_64_PC32: { + std::string fmtbuf; + raw_string_ostream fmt(fmtbuf); + fmt << symname << (addend < 0 ? "" : "+") << addend << "-P"; + fmt.flush(); + Result.append(fmtbuf.begin(), fmtbuf.end()); + } + break; + default: + res = "Unknown"; + } + break; + default: + res = "Unknown"; + } + if (Result.empty()) + Result.append(res.begin(), res.end()); + return object_error::success; +} + template ELFObjectFile::ELFObjectFile(MemoryBuffer *Object , error_code &ec) @@ -521,25 +1092,41 @@ ELFObjectFile::ELFObjectFile(MemoryBuffer *Object SectionHeaderTable = reinterpret_cast(base() + Header->e_shoff); - uint32_t SectionTableSize = Header->e_shnum * Header->e_shentsize; + uint64_t SectionTableSize = getNumSections() * Header->e_shentsize; if (!( (const uint8_t *)SectionHeaderTable + SectionTableSize <= base() + Data->getBufferSize())) // FIXME: Proper error handling. report_fatal_error("Section table goes past end of file!"); - // To find the symbol tables we walk the section table to find SHT_STMTAB. - for (const char *i = reinterpret_cast(SectionHeaderTable), - *e = i + Header->e_shnum * Header->e_shentsize; - i != e; i += Header->e_shentsize) { - const Elf_Shdr *sh = reinterpret_cast(i); + // To find the symbol tables we walk the section table to find SHT_SYMTAB. + const Elf_Shdr* SymbolTableSectionHeaderIndex = 0; + const Elf_Shdr* sh = reinterpret_cast(SectionHeaderTable); + for (uint64_t i = 0, e = getNumSections(); i != e; ++i) { + if (sh->sh_type == ELF::SHT_SYMTAB_SHNDX) { + if (SymbolTableSectionHeaderIndex) + // FIXME: Proper error handling. + report_fatal_error("More than one .symtab_shndx!"); + SymbolTableSectionHeaderIndex = sh; + } if (sh->sh_type == ELF::SHT_SYMTAB) { + SymbolTableSectionsIndexMap[i] = SymbolTableSections.size(); SymbolTableSections.push_back(sh); } + if (sh->sh_type == ELF::SHT_REL || sh->sh_type == ELF::SHT_RELA) { + SectionRelocMap[getSection(sh->sh_info)].push_back(i); + } + ++sh; + } + + // Sort section relocation lists by index. + for (typename RelocMap_t::iterator i = SectionRelocMap.begin(), + e = SectionRelocMap.end(); i != e; ++i) { + std::sort(i->second.begin(), i->second.end()); } // Get string table sections. - dot_shstrtab_sec = getSection(Header->e_shstrndx); + dot_shstrtab_sec = getSection(getStringTableIndex()); if (dot_shstrtab_sec) { // Verify that the last byte in the string table in a null. if (((const char*)base() + dot_shstrtab_sec->sh_offset) @@ -550,7 +1137,7 @@ ELFObjectFile::ELFObjectFile(MemoryBuffer *Object // Merge this into the above loop. for (const char *i = reinterpret_cast(SectionHeaderTable), - *e = i + Header->e_shnum * Header->e_shentsize; + *e = i + getNumSections() * Header->e_shentsize; i != e; i += Header->e_shentsize) { const Elf_Shdr *sh = reinterpret_cast(i); if (sh->sh_type == ELF::SHT_STRTAB) { @@ -567,11 +1154,26 @@ ELFObjectFile::ELFObjectFile(MemoryBuffer *Object } } } + + // Build symbol name side-mapping if there is one. + if (SymbolTableSectionHeaderIndex) { + const Elf_Word *ShndxTable = reinterpret_cast(base() + + SymbolTableSectionHeaderIndex->sh_offset); + error_code ec; + for (symbol_iterator si = begin_symbols(), + se = end_symbols(); si != se; si.increment(ec)) { + if (ec) + report_fatal_error("Fewer extended symbol table entries than symbols!"); + if (*ShndxTable != ELF::SHN_UNDEF) + ExtendedSymbolTable[getSymbol(si->getRawDataRefImpl())] = *ShndxTable; + ++ShndxTable; + } + } } template -ObjectFile::symbol_iterator ELFObjectFile - ::begin_symbols() const { +symbol_iterator ELFObjectFile + ::begin_symbols() const { DataRefImpl SymbolData; memset(&SymbolData, 0, sizeof(SymbolData)); if (SymbolTableSections.size() == 0) { @@ -585,8 +1187,8 @@ ObjectFile::symbol_iterator ELFObjectFile } template -ObjectFile::symbol_iterator ELFObjectFile - ::end_symbols() const { +symbol_iterator ELFObjectFile + ::end_symbols() const { DataRefImpl SymbolData; memset(&SymbolData, 0, sizeof(SymbolData)); SymbolData.d.a = std::numeric_limits::max(); @@ -595,8 +1197,8 @@ ObjectFile::symbol_iterator ELFObjectFile } template -ObjectFile::section_iterator ELFObjectFile - ::begin_sections() const { +section_iterator ELFObjectFile + ::begin_sections() const { DataRefImpl ret; memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast(base() + Header->e_shoff); @@ -604,13 +1206,13 @@ ObjectFile::section_iterator ELFObjectFile } template -ObjectFile::section_iterator ELFObjectFile - ::end_sections() const { +section_iterator ELFObjectFile + ::end_sections() const { DataRefImpl ret; memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast(base() + Header->e_shoff - + (Header->e_shentsize * Header->e_shnum)); + + (Header->e_shentsize*getNumSections())); return section_iterator(SectionRef(ret, this)); } @@ -629,6 +1231,8 @@ StringRef ELFObjectFile return "ELF32-i386"; case ELF::EM_X86_64: return "ELF32-x86-64"; + case ELF::EM_ARM: + return "ELF32-arm"; default: return "ELF32-unknown"; } @@ -654,26 +1258,75 @@ unsigned ELFObjectFile::getArch() const { return Triple::x86; case ELF::EM_X86_64: return Triple::x86_64; + case ELF::EM_ARM: + return Triple::arm; default: return Triple::UnknownArch; } } +template +uint64_t ELFObjectFile::getNumSections() const { + if (Header->e_shnum == ELF::SHN_UNDEF) + return SectionHeaderTable->sh_size; + return Header->e_shnum; +} + +template +uint64_t +ELFObjectFile::getStringTableIndex() const { + if (Header->e_shnum == ELF::SHN_UNDEF) { + if (Header->e_shstrndx == ELF::SHN_HIRESERVE) + return SectionHeaderTable->sh_link; + if (Header->e_shstrndx >= getNumSections()) + return 0; + } + return Header->e_shstrndx; +} + + +template +template +inline const T * +ELFObjectFile::getEntry(uint16_t Section, + uint32_t Entry) const { + return getEntry(getSection(Section), Entry); +} + +template +template +inline const T * +ELFObjectFile::getEntry(const Elf_Shdr * Section, + uint32_t Entry) const { + return reinterpret_cast( + base() + + Section->sh_offset + + (Entry * Section->sh_entsize)); +} + template const typename ELFObjectFile::Elf_Sym * ELFObjectFile::getSymbol(DataRefImpl Symb) const { - const Elf_Shdr *sec = SymbolTableSections[Symb.d.b]; - return reinterpret_cast( - base() - + sec->sh_offset - + (Symb.d.a * sec->sh_entsize)); + return getEntry(SymbolTableSections[Symb.d.b], Symb.d.a); +} + +template +const typename ELFObjectFile::Elf_Rel * +ELFObjectFile::getRel(DataRefImpl Rel) const { + return getEntry(Rel.w.b, Rel.w.c); +} + +template +const typename ELFObjectFile::Elf_Rela * +ELFObjectFile::getRela(DataRefImpl Rela) const { + return getEntry(Rela.w.b, Rela.w.c); } template const typename ELFObjectFile::Elf_Shdr * ELFObjectFile::getSection(DataRefImpl Symb) const { const Elf_Shdr *sec = getSection(Symb.d.b); - if (sec->sh_type != ELF::SHT_SYMTAB) + if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM) // FIXME: Proper error handling. report_fatal_error("Invalid symbol table section!"); return sec; @@ -681,10 +1334,10 @@ ELFObjectFile::getSection(DataRefImpl Symb) const { template const typename ELFObjectFile::Elf_Shdr * -ELFObjectFile::getSection(uint16_t index) const { - if (index == 0 || index >= ELF::SHN_LORESERVE) +ELFObjectFile::getSection(uint32_t index) const { + if (index == 0) return 0; - if (!SectionHeaderTable || index >= Header->e_shnum) + if (!SectionHeaderTable || index >= getNumSections()) // FIXME: Proper error handling. report_fatal_error("Invalid section index!"); @@ -695,7 +1348,7 @@ ELFObjectFile::getSection(uint16_t index) const { template const char *ELFObjectFile - ::getString(uint16_t section, + ::getString(uint32_t section, ELF::Elf32_Word offset) const { return getString(getSection(section), offset); } @@ -711,6 +1364,24 @@ const char *ELFObjectFile return (const char *)base() + section->sh_offset + offset; } +template +error_code ELFObjectFile + ::getSymbolName(const Elf_Sym *symb, + StringRef &Result) const { + if (symb->st_name == 0) { + const Elf_Shdr *section = getSection(symb); + if (!section) + Result = ""; + else + Result = getString(dot_shstrtab_sec, section->sh_name); + return object_error::success; + } + + // Use the default symbol table name section. + Result = getString(dot_strtab_sec, symb->st_name); + return object_error::success; +} + // EI_CLASS, EI_DATA. static std::pair getElfArchType(MemoryBuffer *Object) { diff --git a/lib/Object/MachOObject.cpp b/lib/Object/MachOObject.cpp index 9890febfb616..9cdac8681ddd 100644 --- a/lib/Object/MachOObject.cpp +++ b/lib/Object/MachOObject.cpp @@ -9,6 +9,7 @@ #include "llvm/Object/MachOObject.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Host.h" #include "llvm/Support/SwapByteOrder.h" @@ -243,6 +244,18 @@ void MachOObject::ReadDysymtabLoadCommand(const LoadCommandInfo &LCI, ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res); } +template<> +void SwapStruct(macho::LinkeditDataLoadCommand &Value) { + SwapValue(Value.Type); + SwapValue(Value.Size); + SwapValue(Value.DataOffset); + SwapValue(Value.DataSize); +} +void MachOObject::ReadLinkeditDataLoadCommand(const LoadCommandInfo &LCI, + InMemoryStruct &Res) const { + ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res); +} + template<> void SwapStruct(macho::IndirectSymbolTableEntry &Value) { SwapValue(Value.Index); @@ -343,6 +356,31 @@ void MachOObject::ReadSymbol64TableEntry(uint64_t SymbolTableOffset, ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); } + +void MachOObject::ReadULEB128s(uint64_t Index, + SmallVectorImpl &Out) const { + const char *ptr = Buffer->getBufferStart() + Index; + uint64_t data = 0; + uint64_t delta = 0; + uint32_t shift = 0; + while (true) { + assert(ptr < Buffer->getBufferEnd() && "index out of bounds"); + assert(shift < 64 && "too big for uint64_t"); + + uint8_t byte = *ptr++; + delta |= ((byte & 0x7F) << shift); + shift += 7; + if (byte < 0x80) { + if (delta == 0) + break; + data += delta; + Out.push_back(data); + delta = 0; + shift = 0; + } + } +} + /* ** */ // Object Dumping Facilities void MachOObject::dump() const { print(dbgs()); dbgs() << '\n'; } diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 26a6e136d753..507df5865eb1 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -13,11 +13,9 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/Triple.h" +#include "llvm/Object/MachO.h" #include "llvm/Object/MachOFormat.h" -#include "llvm/Object/MachOObject.h" -#include "llvm/Object/ObjectFile.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/MachO.h" #include #include @@ -27,56 +25,24 @@ using namespace llvm; using namespace object; namespace llvm { +namespace object { -typedef MachOObject::LoadCommandInfo LoadCommandInfo; - -class MachOObjectFile : public ObjectFile { -public: - MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, error_code &ec) +MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, + error_code &ec) : ObjectFile(Binary::isMachO, Object, ec), MachOObj(MOO), - RegisteredStringTable(std::numeric_limits::max()) {} + RegisteredStringTable(std::numeric_limits::max()) { + DataRefImpl DRI; + DRI.d.a = DRI.d.b = 0; + moveToNextSection(DRI); + uint32_t LoadCommandCount = MachOObj->getHeader().NumLoadCommands; + while (DRI.d.a < LoadCommandCount) { + Sections.push_back(DRI); + DRI.d.b++; + moveToNextSection(DRI); + } +} - virtual symbol_iterator begin_symbols() const; - virtual symbol_iterator end_symbols() const; - virtual section_iterator begin_sections() const; - virtual section_iterator end_sections() const; - - virtual uint8_t getBytesInAddress() const; - virtual StringRef getFileFormatName() const; - virtual unsigned getArch() const; - -protected: - virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; - virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; - virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; - virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; - virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; - virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const; - - virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; - virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; - virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; - virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; - virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; - virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; - virtual error_code sectionContainsSymbol(DataRefImpl DRI, DataRefImpl S, - bool &Result) const; - -private: - MachOObject *MachOObj; - mutable uint32_t RegisteredStringTable; - - void moveToNextSection(DataRefImpl &DRI) const; - void getSymbolTableEntry(DataRefImpl DRI, - InMemoryStruct &Res) const; - void getSymbol64TableEntry(DataRefImpl DRI, - InMemoryStruct &Res) const; - void moveToNextSymbol(DataRefImpl &DRI) const; - void getSection(DataRefImpl DRI, InMemoryStruct &Res) const; - void getSection64(DataRefImpl DRI, - InMemoryStruct &Res) const; -}; ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { error_code ec; @@ -158,6 +124,27 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, return object_error::success; } +error_code MachOObjectFile::getSymbolOffset(DataRefImpl DRI, + uint64_t &Result) const { + uint64_t SectionOffset; + uint8_t SectionIndex; + if (MachOObj->is64Bit()) { + InMemoryStruct Entry; + getSymbol64TableEntry(DRI, Entry); + Result = Entry->Value; + SectionIndex = Entry->SectionIndex; + } else { + InMemoryStruct Entry; + getSymbolTableEntry(DRI, Entry); + Result = Entry->Value; + SectionIndex = Entry->SectionIndex; + } + getSectionAddress(Sections[SectionIndex-1], SectionOffset); + Result -= SectionOffset; + + return object_error::success; +} + error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, uint64_t &Result) const { if (MachOObj->is64Bit()) { @@ -227,7 +214,51 @@ error_code MachOObjectFile::isSymbolInternal(DataRefImpl DRI, return object_error::success; } -ObjectFile::symbol_iterator MachOObjectFile::begin_symbols() const { +error_code MachOObjectFile::isSymbolGlobal(DataRefImpl Symb, bool &Res) const { + + if (MachOObj->is64Bit()) { + InMemoryStruct Entry; + getSymbol64TableEntry(Symb, Entry); + Res = Entry->Type & MachO::NlistMaskExternal; + } else { + InMemoryStruct Entry; + getSymbolTableEntry(Symb, Entry); + Res = Entry->Type & MachO::NlistMaskExternal; + } + return object_error::success; +} + +error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, + SymbolRef::SymbolType &Res) const { + uint8_t n_type; + if (MachOObj->is64Bit()) { + InMemoryStruct Entry; + getSymbol64TableEntry(Symb, Entry); + n_type = Entry->Type; + } else { + InMemoryStruct Entry; + getSymbolTableEntry(Symb, Entry); + n_type = Entry->Type; + } + Res = SymbolRef::ST_Other; + + // If this is a STAB debugging symbol, we can do nothing more. + if (n_type & MachO::NlistMaskStab) + return object_error::success; + + switch (n_type & MachO::NlistMaskType) { + case MachO::NListTypeUndefined : + Res = SymbolRef::ST_External; + break; + case MachO::NListTypeSection : + Res = SymbolRef::ST_Function; + break; + } + return object_error::success; +} + + +symbol_iterator MachOObjectFile::begin_symbols() const { // DRI.d.a = segment number; DRI.d.b = symbol index. DataRefImpl DRI; DRI.d.a = DRI.d.b = 0; @@ -235,7 +266,7 @@ ObjectFile::symbol_iterator MachOObjectFile::begin_symbols() const { return symbol_iterator(SymbolRef(DRI, this)); } -ObjectFile::symbol_iterator MachOObjectFile::end_symbols() const { +symbol_iterator MachOObjectFile::end_symbols() const { DataRefImpl DRI; DRI.d.a = MachOObj->getHeader().NumLoadCommands; DRI.d.b = 0; @@ -283,6 +314,13 @@ MachOObjectFile::getSection(DataRefImpl DRI, MachOObj->ReadSection(LCI, DRI.d.b, Res); } +std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { + SectionList::const_iterator loc = + std::find(Sections.begin(), Sections.end(), Sec); + assert(loc != Sections.end() && "Sec is not a valid section!"); + return std::distance(Sections.begin(), loc); +} + void MachOObjectFile::getSection64(DataRefImpl DRI, InMemoryStruct &Res) const { @@ -371,6 +409,20 @@ error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, return object_error::success; } +error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, + uint64_t &Result) const { + if (is64BitLoadCommand(MachOObj, DRI)) { + InMemoryStruct Sect; + getSection64(DRI, Sect); + Result = uint64_t(1) << Sect->Align; + } else { + InMemoryStruct Sect; + getSection(DRI, Sect); + Result = uint64_t(1) << Sect->Align; + } + return object_error::success; +} + error_code MachOObjectFile::isSectionText(DataRefImpl DRI, bool &Result) const { if (is64BitLoadCommand(MachOObj, DRI)) { @@ -385,35 +437,185 @@ error_code MachOObjectFile::isSectionText(DataRefImpl DRI, return object_error::success; } -error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, - DataRefImpl Symb, - bool &Result) const { - if (MachOObj->is64Bit()) { - InMemoryStruct Entry; - getSymbol64TableEntry(Symb, Entry); - Result = Entry->SectionIndex == 1 + Sec.d.a + Sec.d.b; - } else { - InMemoryStruct Entry; - getSymbolTableEntry(Symb, Entry); - Result = Entry->SectionIndex == 1 + Sec.d.a + Sec.d.b; - } +error_code MachOObjectFile::isSectionData(DataRefImpl DRI, + bool &Result) const { + // FIXME: Unimplemented. + Result = false; return object_error::success; } -ObjectFile::section_iterator MachOObjectFile::begin_sections() const { +error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, + bool &Result) const { + // FIXME: Unimplemented. + Result = false; + return object_error::success; +} + +error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, + DataRefImpl Symb, + bool &Result) const { + SymbolRef::SymbolType ST; + getSymbolType(Symb, ST); + if (ST == SymbolRef::ST_External) { + Result = false; + return object_error::success; + } + + uint64_t SectBegin, SectEnd; + getSectionAddress(Sec, SectBegin); + getSectionSize(Sec, SectEnd); + SectEnd += SectBegin; + + if (MachOObj->is64Bit()) { + InMemoryStruct Entry; + getSymbol64TableEntry(Symb, Entry); + uint64_t SymAddr= Entry->Value; + Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); + } else { + InMemoryStruct Entry; + getSymbolTableEntry(Symb, Entry); + uint64_t SymAddr= Entry->Value; + Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); + } + + return object_error::success; +} + +relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { + DataRefImpl ret; + ret.d.a = 0; + ret.d.b = getSectionIndex(Sec); + return relocation_iterator(RelocationRef(ret, this)); +} +relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { + uint32_t last_reloc; + if (is64BitLoadCommand(MachOObj, Sec)) { + InMemoryStruct Sect; + getSection64(Sec, Sect); + last_reloc = Sect->NumRelocationTableEntries; + } else { + InMemoryStruct Sect; + getSection(Sec, Sect); + last_reloc = Sect->NumRelocationTableEntries; + } + DataRefImpl ret; + ret.d.a = last_reloc; + ret.d.b = getSectionIndex(Sec); + return relocation_iterator(RelocationRef(ret, this)); +} + +section_iterator MachOObjectFile::begin_sections() const { DataRefImpl DRI; DRI.d.a = DRI.d.b = 0; moveToNextSection(DRI); return section_iterator(SectionRef(DRI, this)); } -ObjectFile::section_iterator MachOObjectFile::end_sections() const { +section_iterator MachOObjectFile::end_sections() const { DataRefImpl DRI; DRI.d.a = MachOObj->getHeader().NumLoadCommands; DRI.d.b = 0; return section_iterator(SectionRef(DRI, this)); } +/*===-- Relocations -------------------------------------------------------===*/ + +void MachOObjectFile:: +getRelocation(DataRefImpl Rel, + InMemoryStruct &Res) const { + uint32_t relOffset; + if (MachOObj->is64Bit()) { + InMemoryStruct Sect; + getSection64(Sections[Rel.d.b], Sect); + relOffset = Sect->RelocationTableOffset; + } else { + InMemoryStruct Sect; + getSection(Sections[Rel.d.b], Sect); + relOffset = Sect->RelocationTableOffset; + } + MachOObj->ReadRelocationEntry(relOffset, Rel.d.a, Res); +} +error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, + RelocationRef &Res) const { + ++Rel.d.a; + Res = RelocationRef(Rel, this); + return object_error::success; +} +error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, + uint64_t &Res) const { + const uint8_t* sectAddress = base(); + if (MachOObj->is64Bit()) { + InMemoryStruct Sect; + getSection64(Sections[Rel.d.b], Sect); + sectAddress += Sect->Offset; + } else { + InMemoryStruct Sect; + getSection(Sections[Rel.d.b], Sect); + sectAddress += Sect->Offset; + } + InMemoryStruct RE; + getRelocation(Rel, RE); + Res = reinterpret_cast(sectAddress + RE->Word0); + return object_error::success; +} +error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, + SymbolRef &Res) const { + InMemoryStruct RE; + getRelocation(Rel, RE); + uint32_t SymbolIdx = RE->Word1 & 0xffffff; + bool isExtern = (RE->Word1 >> 27) & 1; + + DataRefImpl Sym; + Sym.d.a = Sym.d.b = 0; + moveToNextSymbol(Sym); + if (isExtern) { + for (unsigned i = 0; i < SymbolIdx; i++) { + Sym.d.b++; + moveToNextSymbol(Sym); + assert(Sym.d.a < MachOObj->getHeader().NumLoadCommands && + "Relocation symbol index out of range!"); + } + } + Res = SymbolRef(Sym, this); + return object_error::success; +} +error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, + uint32_t &Res) const { + InMemoryStruct RE; + getRelocation(Rel, RE); + Res = RE->Word1; + return object_error::success; +} +error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl &Result) const { + return object_error::success; +} +error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, + int64_t &Res) const { + InMemoryStruct RE; + getRelocation(Rel, RE); + bool isExtern = (RE->Word1 >> 27) & 1; + Res = 0; + if (!isExtern) { + const uint8_t* sectAddress = base(); + if (MachOObj->is64Bit()) { + InMemoryStruct Sect; + getSection64(Sections[Rel.d.b], Sect); + sectAddress += Sect->Offset; + } else { + InMemoryStruct Sect; + getSection(Sections[Rel.d.b], Sect); + sectAddress += Sect->Offset; + } + Res = reinterpret_cast(sectAddress); + } + return object_error::success; +} +error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, + SmallVectorImpl &Result) const { + return object_error::success; +} + /*===-- Miscellaneous -----------------------------------------------------===*/ uint8_t MachOObjectFile::getBytesInAddress() const { @@ -465,5 +667,5 @@ unsigned MachOObjectFile::getArch() const { } } +} // end namespace object } // end namespace llvm - diff --git a/lib/Object/Object.cpp b/lib/Object/Object.cpp index 9a373ad21bd2..2ea8db978670 100644 --- a/lib/Object/Object.cpp +++ b/lib/Object/Object.cpp @@ -27,8 +27,8 @@ void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) { } LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile) { - ObjectFile::section_iterator SI = unwrap(ObjectFile)->begin_sections(); - return wrap(new ObjectFile::section_iterator(SI)); + section_iterator SI = unwrap(ObjectFile)->begin_sections(); + return wrap(new section_iterator(SI)); } void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) { diff --git a/lib/Object/ObjectFile.cpp b/lib/Object/ObjectFile.cpp index a7798df33fe5..69d8ed0e5e9a 100644 --- a/lib/Object/ObjectFile.cpp +++ b/lib/Object/ObjectFile.cpp @@ -45,6 +45,7 @@ ObjectFile *ObjectFile::createObjectFile(MemoryBuffer *Object) { case sys::Mach_O_DynamicLinker_FileType: case sys::Mach_O_Bundle_FileType: case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType: + case sys::Mach_O_DSYMCompanion_FileType: return createMachOObjectFile(Object); case sys::COFF_FileType: return createCOFFObjectFile(Object); diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index c64da6e137ea..f2388944929b 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -832,6 +832,7 @@ APFloat::incrementSignificand() /* Our callers should never cause us to overflow. */ assert(carry == 0); + (void)carry; } /* Add the significand of the RHS. Returns the carry flag. */ @@ -926,6 +927,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) APFloat extendedAddend(*addend); status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored); assert(status == opOK); + (void)status; lost_fraction = addOrSubtractSignificand(extendedAddend, false); /* Restore our state. */ @@ -1190,7 +1192,7 @@ APFloat::normalize(roundingMode rounding_mode, if (omsb) { /* OMSB is numbered from 1. We want to place it in the integer - bit numbered PRECISON if possible, with a compensating change in + bit numbered PRECISION if possible, with a compensating change in the exponent. */ exponentChange = omsb - semantics->precision; @@ -1389,6 +1391,7 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract) /* The code above is intended to ensure that no borrow is necessary. */ assert(!carry); + (void)carry; } else { if (bits > 0) { APFloat temp_rhs(rhs); @@ -1402,6 +1405,7 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract) /* We have a guard bit; generating a carry cannot happen. */ assert(!carry); + (void)carry; } return lost_fraction; @@ -2098,7 +2102,7 @@ APFloat::convertToInteger(APSInt &result, opStatus status = convertToInteger( parts.data(), bitWidth, result.isSigned(), rounding_mode, isExact); // Keeps the original signed-ness. - result = APInt(bitWidth, (unsigned)parts.size(), parts.data()); + result = APInt(bitWidth, parts); return status; } @@ -2121,7 +2125,7 @@ APFloat::convertFromUnsignedParts(const integerPart *src, dstCount = partCount(); precision = semantics->precision; - /* We want the most significant PRECISON bits of SRC. There may not + /* We want the most significant PRECISION bits of SRC. There may not be that many; extract what we can. */ if (precision <= omsb) { exponent = omsb - 1; @@ -2192,7 +2196,7 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts, roundingMode rounding_mode) { unsigned int partCount = partCountForBits(width); - APInt api = APInt(width, partCount, parts); + APInt api = APInt(width, makeArrayRef(parts, partCount)); sign = false; if (isSigned && APInt::tcExtractBit(parts, width - 1)) { @@ -2746,7 +2750,7 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const words[0] = mysignificand; words[1] = ((uint64_t)(sign & 1) << 15) | (myexponent & 0x7fffLL); - return APInt(80, 2, words); + return APInt(80, words); } APInt @@ -2791,7 +2795,7 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const words[1] = ((uint64_t)(sign2 & 1) << 63) | ((myexponent2 & 0x7ff) << 52) | (mysignificand2 & 0xfffffffffffffLL); - return APInt(128, 2, words); + return APInt(128, words); } APInt @@ -2827,7 +2831,7 @@ APFloat::convertQuadrupleAPFloatToAPInt() const ((myexponent & 0x7fff) << 48) | (mysignificand2 & 0xffffffffffffLL); - return APInt(128, 2, words); + return APInt(128, words); } APInt @@ -3239,8 +3243,9 @@ APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) { significand[i] = ~((integerPart) 0); // ...and then clear the top bits for internal consistency. - significand[N-1] &= - (((integerPart) 1) << ((Sem.precision % integerPartWidth) - 1)) - 1; + if (Sem.precision % integerPartWidth != 0) + significand[N-1] &= + (((integerPart) 1) << (Sem.precision % integerPartWidth)) - 1; return Val; } @@ -3270,7 +3275,7 @@ APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) { Val.exponent = Sem.minExponent; Val.zeroSignificand(); Val.significandParts()[partCountForBits(Sem.precision)-1] |= - (((integerPart) 1) << ((Sem.precision % integerPartWidth) - 1)); + (((integerPart) 1) << ((Sem.precision - 1) % integerPartWidth)); return Val; } @@ -3413,8 +3418,8 @@ void APFloat::toString(SmallVectorImpl &Str, // Decompose the number into an APInt and an exponent. int exp = exponent - ((int) semantics->precision - 1); APInt significand(semantics->precision, - partCountForBits(semantics->precision), - significandParts()); + makeArrayRef(significandParts(), + partCountForBits(semantics->precision))); // Set FormatPrecision if zero. We want to do this before we // truncate trailing zeros, as those are part of the precision. @@ -3451,7 +3456,7 @@ void APFloat::toString(SmallVectorImpl &Str, // <= semantics->precision + e * 137 / 59 // (log_2(5) ~ 2.321928 < 2.322034 ~ 137/59) - unsigned precision = semantics->precision + 137 * texp / 59; + unsigned precision = semantics->precision + (137 * texp + 136) / 59; // Multiply significand by 5^e. // N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8) diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 76265d445f45..3774c5223c46 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -48,18 +48,20 @@ inline static uint64_t* getMemory(unsigned numWords) { inline static unsigned getDigit(char cdigit, uint8_t radix) { unsigned r; - if (radix == 16) { + if (radix == 16 || radix == 36) { r = cdigit - '0'; if (r <= 9) return r; r = cdigit - 'A'; - if (r <= 5) + if (r <= radix - 11U) return r + 10; r = cdigit - 'a'; - if (r <= 5) + if (r <= radix - 11U) return r + 10; + + radix = 10; } r = cdigit - '0'; @@ -83,25 +85,33 @@ void APInt::initSlowCase(const APInt& that) { memcpy(pVal, that.pVal, getNumWords() * APINT_WORD_SIZE); } - -APInt::APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]) - : BitWidth(numBits), VAL(0) { +void APInt::initFromArray(ArrayRef bigVal) { assert(BitWidth && "Bitwidth too small"); - assert(bigVal && "Null pointer detected!"); + assert(bigVal.data() && "Null pointer detected!"); if (isSingleWord()) VAL = bigVal[0]; else { // Get memory, cleared to 0 pVal = getClearedMemory(getNumWords()); // Calculate the number of words to copy - unsigned words = std::min(numWords, getNumWords()); + unsigned words = std::min(bigVal.size(), getNumWords()); // Copy the words from bigVal to pVal - memcpy(pVal, bigVal, words * APINT_WORD_SIZE); + memcpy(pVal, bigVal.data(), words * APINT_WORD_SIZE); } // Make sure unused high bits are cleared clearUnusedBits(); } +APInt::APInt(unsigned numBits, ArrayRef bigVal) + : BitWidth(numBits), VAL(0) { + initFromArray(bigVal); +} + +APInt::APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]) + : BitWidth(numBits), VAL(0) { + initFromArray(makeArrayRef(bigVal, numWords)); +} + APInt::APInt(unsigned numbits, StringRef Str, uint8_t radix) : BitWidth(numbits), VAL(0) { assert(BitWidth && "Bitwidth too small"); @@ -376,6 +386,7 @@ APInt& APInt::operator*=(const APInt& RHS) { clearAllBits(); unsigned wordsToCopy = destWords >= getNumWords() ? getNumWords() : destWords; memcpy(pVal, dest, wordsToCopy * APINT_WORD_SIZE); + clearUnusedBits(); // delete dest array and return delete[] dest; @@ -461,7 +472,7 @@ APInt APInt::operator*(const APInt& RHS) const { return APInt(BitWidth, VAL * RHS.VAL); APInt Result(*this); Result *= RHS; - return Result.clearUnusedBits(); + return Result; } APInt APInt::operator+(const APInt& RHS) const { @@ -613,8 +624,9 @@ void APInt::flipBit(unsigned bitPosition) { unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) { assert(!str.empty() && "Invalid string length"); - assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && - "Radix should be 2, 8, 10, or 16!"); + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2 || + radix == 36) && + "Radix should be 2, 8, 10, 16, or 36!"); size_t slen = str.size(); @@ -636,6 +648,8 @@ unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) { if (radix == 16) return slen * 4 + isNegative; + // FIXME: base 36 + // This is grossly inefficient but accurate. We could probably do something // with a computation of roughly slen*64/20 and then adjust by the value of // the first few digits. But, I'm not sure how accurate that could be. @@ -644,7 +658,9 @@ unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) { // be too large. This avoids the assertion in the constructor. This // calculation doesn't work appropriately for the numbers 0-9, so just use 4 // bits in that case. - unsigned sufficient = slen == 1 ? 4 : slen * 64/18; + unsigned sufficient + = radix == 10? (slen == 1 ? 4 : slen * 64/18) + : (slen == 1 ? 7 : slen * 16/3); // Convert to the actual binary value. APInt tmp(sufficient, StringRef(p, slen), radix); @@ -2107,8 +2123,9 @@ APInt APInt::sshl_ov(unsigned ShAmt, bool &Overflow) const { void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) { // Check our assumptions here assert(!str.empty() && "Invalid string length"); - assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) && - "Radix should be 2, 8, 10, or 16!"); + assert((radix == 10 || radix == 8 || radix == 16 || radix == 2 || + radix == 36) && + "Radix should be 2, 8, 10, 16, or 36!"); StringRef::iterator p = str.begin(); size_t slen = str.size(); @@ -2165,7 +2182,8 @@ void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) { void APInt::toString(SmallVectorImpl &Str, unsigned Radix, bool Signed, bool formatAsCLiteral) const { - assert((Radix == 10 || Radix == 8 || Radix == 16 || Radix == 2) && + assert((Radix == 10 || Radix == 8 || Radix == 16 || Radix == 2 || + Radix == 36) && "Radix should be 2, 8, 10, or 16!"); const char *Prefix = ""; @@ -2195,7 +2213,7 @@ void APInt::toString(SmallVectorImpl &Str, unsigned Radix, return; } - static const char Digits[] = "0123456789ABCDEF"; + static const char Digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (isSingleWord()) { char Buffer[65]; @@ -2249,7 +2267,7 @@ void APInt::toString(SmallVectorImpl &Str, unsigned Radix, // For the 2, 8 and 16 bit cases, we can just shift instead of divide // because the number of bits per digit (1, 3 and 4 respectively) divides // equaly. We just shift until the value is zero. - if (Radix != 10) { + if (Radix == 2 || Radix == 8 || Radix == 16) { // Just shift tmp right for each digit width until it becomes zero unsigned ShiftAmt = (Radix == 16 ? 4 : (Radix == 8 ? 3 : 1)); unsigned MaskAmt = Radix - 1; @@ -2260,7 +2278,7 @@ void APInt::toString(SmallVectorImpl &Str, unsigned Radix, Tmp = Tmp.lshr(ShiftAmt); } } else { - APInt divisor(4, 10); + APInt divisor(Radix == 10? 4 : 8, Radix); while (Tmp != 0) { APInt APdigit(1, 0); APInt tmp2(Tmp.getBitWidth(), 0); diff --git a/lib/Support/Atomic.cpp b/lib/Support/Atomic.cpp index c7b4bff27948..94760cc069fc 100644 --- a/lib/Support/Atomic.cpp +++ b/lib/Support/Atomic.cpp @@ -22,7 +22,7 @@ using namespace llvm; #endif void sys::MemoryFence() { -#if LLVM_MULTITHREADED==0 +#if LLVM_HAS_ATOMICS == 0 return; #else # if defined(__GNUC__) @@ -38,7 +38,7 @@ void sys::MemoryFence() { sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr, sys::cas_flag new_value, sys::cas_flag old_value) { -#if LLVM_MULTITHREADED==0 +#if LLVM_HAS_ATOMICS == 0 sys::cas_flag result = *ptr; if (result == old_value) *ptr = new_value; @@ -53,7 +53,7 @@ sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr, } sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) { -#if LLVM_MULTITHREADED==0 +#if LLVM_HAS_ATOMICS == 0 ++(*ptr); return *ptr; #elif defined(__GNUC__) @@ -66,7 +66,7 @@ sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) { } sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) { -#if LLVM_MULTITHREADED==0 +#if LLVM_HAS_ATOMICS == 0 --(*ptr); return *ptr; #elif defined(__GNUC__) @@ -79,7 +79,7 @@ sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) { } sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) { -#if LLVM_MULTITHREADED==0 +#if LLVM_HAS_ATOMICS == 0 *ptr += val; return *ptr; #elif defined(__GNUC__) diff --git a/lib/Support/BlockFrequency.cpp b/lib/Support/BlockFrequency.cpp new file mode 100644 index 000000000000..a63bf83f2039 --- /dev/null +++ b/lib/Support/BlockFrequency.cpp @@ -0,0 +1,126 @@ +//====--------------- lib/Support/BlockFrequency.cpp -----------*- 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 Block Frequency class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/BranchProbability.h" +#include "llvm/Support/BlockFrequency.h" +#include "llvm/Support/raw_ostream.h" +#include + +using namespace llvm; + +namespace { + +/// mult96bit - Multiply FREQ by N and store result in W array. +void mult96bit(uint64_t freq, uint32_t N, uint64_t W[2]) { + uint64_t u0 = freq & UINT32_MAX; + uint64_t u1 = freq >> 32; + + // Represent 96-bit value as w[2]:w[1]:w[0]; + uint32_t w[3] = { 0, 0, 0 }; + + uint64_t t = u0 * N; + uint64_t k = t >> 32; + w[0] = t; + t = u1 * N + k; + w[1] = t; + w[2] = t >> 32; + + // W[1] - higher bits. + // W[0] - lower bits. + W[0] = w[0] + ((uint64_t) w[1] << 32); + W[1] = w[2]; +} + + +/// div96bit - Divide 96-bit value stored in W array by D. Return 64-bit frequency. +uint64_t div96bit(uint64_t W[2], uint32_t D) { + uint64_t y = W[0]; + uint64_t x = W[1]; + int i; + + for (i = 1; i <= 64 && x; ++i) { + uint32_t t = (int)x >> 31; + x = (x << 1) | (y >> 63); + y = y << 1; + if ((x | t) >= D) { + x -= D; + ++y; + } + } + + return y << (64 - i + 1); +} + +} + + +BlockFrequency &BlockFrequency::operator*=(const BranchProbability &Prob) { + uint32_t n = Prob.getNumerator(); + uint32_t d = Prob.getDenominator(); + + assert(n <= d && "Probability must be less or equal to 1."); + + // If we can overflow use 96-bit operations. + if (n > 0 && Frequency > UINT64_MAX / n) { + // 96-bit value represented as W[1]:W[0]. + uint64_t W[2]; + + // Probability is less or equal to 1 which means that results must fit + // 64-bit. + mult96bit(Frequency, n, W); + Frequency = div96bit(W, d); + return *this; + } + + Frequency *= n; + Frequency /= d; + return *this; +} + +const BlockFrequency +BlockFrequency::operator*(const BranchProbability &Prob) const { + BlockFrequency Freq(Frequency); + Freq *= Prob; + return Freq; +} + +BlockFrequency &BlockFrequency::operator+=(const BlockFrequency &Freq) { + uint64_t Before = Freq.Frequency; + Frequency += Freq.Frequency; + + // If overflow, set frequency to the maximum value. + if (Frequency < Before) + Frequency = UINT64_MAX; + + return *this; +} + +const BlockFrequency +BlockFrequency::operator+(const BlockFrequency &Prob) const { + BlockFrequency Freq(Frequency); + Freq += Prob; + return Freq; +} + +void BlockFrequency::print(raw_ostream &OS) const { + OS << Frequency; +} + +namespace llvm { + +raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq) { + Freq.print(OS); + return OS; +} + +} diff --git a/lib/Support/BranchProbability.cpp b/lib/Support/BranchProbability.cpp index 97342da3f078..49d04ed83653 100644 --- a/lib/Support/BranchProbability.cpp +++ b/lib/Support/BranchProbability.cpp @@ -24,9 +24,8 @@ BranchProbability::BranchProbability(uint32_t n, uint32_t d) { D = d; } -raw_ostream &BranchProbability::print(raw_ostream &OS) const { +void BranchProbability::print(raw_ostream &OS) const { OS << N << " / " << D << " = " << ((double)N / D); - return OS; } void BranchProbability::dump() const { diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt index 867d930a0f9b..63a833c38046 100644 --- a/lib/Support/CMakeLists.txt +++ b/lib/Support/CMakeLists.txt @@ -9,11 +9,13 @@ add_llvm_library(LLVMSupport APInt.cpp APSInt.cpp Allocator.cpp + BlockFrequency.cpp BranchProbability.cpp circular_raw_ostream.cpp CommandLine.cpp ConstantRange.cpp CrashRecoveryContext.cpp + DataExtractor.cpp Debug.cpp DeltaAlgorithm.cpp DAGDeltaAlgorithm.cpp @@ -42,7 +44,6 @@ add_llvm_library(LLVMSupport StringPool.cpp StringRef.cpp SystemUtils.cpp - TargetRegistry.cpp Timer.cpp ToolOutputFile.cpp Triple.cpp @@ -72,6 +73,7 @@ add_llvm_library(LLVMSupport SearchForAddressOfSpecialSymbol.cpp Signals.cpp system_error.cpp + TargetRegistry.cpp ThreadLocal.cpp Threading.cpp TimeValue.cpp diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp index 29143377628d..238adcce0a12 100644 --- a/lib/Support/CommandLine.cpp +++ b/lib/Support/CommandLine.cpp @@ -23,7 +23,6 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" -#include "llvm/Target/TargetRegistry.h" #include "llvm/Support/Host.h" #include "llvm/Support/Path.h" #include "llvm/ADT/OwningPtr.h" @@ -45,6 +44,7 @@ TEMPLATE_INSTANTIATION(class basic_parser); TEMPLATE_INSTANTIATION(class basic_parser); TEMPLATE_INSTANTIATION(class basic_parser); TEMPLATE_INSTANTIATION(class basic_parser); +TEMPLATE_INSTANTIATION(class basic_parser); TEMPLATE_INSTANTIATION(class basic_parser); TEMPLATE_INSTANTIATION(class basic_parser); TEMPLATE_INSTANTIATION(class basic_parser); @@ -63,6 +63,7 @@ void parser::anchor() {} void parser::anchor() {} void parser::anchor() {} void parser::anchor() {} +void parser::anchor() {} void parser::anchor() {} void parser::anchor() {} void parser::anchor() {} @@ -1006,6 +1007,16 @@ bool parser::parse(Option &O, StringRef ArgName, return false; } +// parser implementation +// +bool parser::parse(Option &O, StringRef ArgName, + StringRef Arg, unsigned long long &Value){ + + if (Arg.getAsInteger(0, Value)) + return O.error("'" + Arg + "' value invalid for uint argument!"); + return false; +} + // parser/parser implementation // static bool parseDouble(Option &O, StringRef Arg, double &Value) { @@ -1151,6 +1162,7 @@ PRINT_OPT_DIFF(bool) PRINT_OPT_DIFF(boolOrDefault) PRINT_OPT_DIFF(int) PRINT_OPT_DIFF(unsigned) +PRINT_OPT_DIFF(unsigned long long) PRINT_OPT_DIFF(double) PRINT_OPT_DIFF(float) PRINT_OPT_DIFF(char) @@ -1330,10 +1342,7 @@ void cl::PrintOptionValues() { static void (*OverrideVersionPrinter)() = 0; -static int TargetArraySortFn(const void *LHS, const void *RHS) { - typedef std::pair pair_ty; - return strcmp(((const pair_ty*)LHS)->first, ((const pair_ty*)RHS)->first); -} +static std::vector* ExtraVersionPrinters = 0; namespace { class VersionPrinter { @@ -1361,37 +1370,27 @@ class VersionPrinter { << " Built " << __DATE__ << " (" << __TIME__ << ").\n" #endif << " Host: " << sys::getHostTriple() << '\n' - << " Host CPU: " << CPU << '\n' - << '\n' - << " Registered Targets:\n"; - - std::vector > Targets; - size_t Width = 0; - for (TargetRegistry::iterator it = TargetRegistry::begin(), - ie = TargetRegistry::end(); it != ie; ++it) { - Targets.push_back(std::make_pair(it->getName(), &*it)); - Width = std::max(Width, strlen(Targets.back().first)); - } - if (!Targets.empty()) - qsort(&Targets[0], Targets.size(), sizeof(Targets[0]), - TargetArraySortFn); - - for (unsigned i = 0, e = Targets.size(); i != e; ++i) { - OS << " " << Targets[i].first; - OS.indent(Width - strlen(Targets[i].first)) << " - " - << Targets[i].second->getShortDescription() << '\n'; - } - if (Targets.empty()) - OS << " (none)\n"; + << " Host CPU: " << CPU << '\n'; } void operator=(bool OptionWasSpecified) { if (!OptionWasSpecified) return; - if (OverrideVersionPrinter == 0) { - print(); + if (OverrideVersionPrinter != 0) { + (*OverrideVersionPrinter)(); exit(1); } - (*OverrideVersionPrinter)(); + print(); + + // Iterate over any registered extra printers and call them to add further + // information. + if (ExtraVersionPrinters != 0) { + outs() << '\n'; + for (std::vector::iterator I = ExtraVersionPrinters->begin(), + E = ExtraVersionPrinters->end(); + I != E; ++I) + (*I)(); + } + exit(1); } }; @@ -1424,3 +1423,10 @@ void cl::PrintVersionMessage() { void cl::SetVersionPrinter(void (*func)()) { OverrideVersionPrinter = func; } + +void cl::AddExtraVersionPrinter(void (*func)()) { + if (ExtraVersionPrinters == 0) + ExtraVersionPrinters = new std::vector; + + ExtraVersionPrinters->push_back(func); +} diff --git a/lib/Support/ConstantRange.cpp b/lib/Support/ConstantRange.cpp index 81382d08dc23..c29cb53fb9c5 100644 --- a/lib/Support/ConstantRange.cpp +++ b/lib/Support/ConstantRange.cpp @@ -21,11 +21,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Constants.h" +#include "llvm/InstrTypes.h" #include "llvm/Support/ConstantRange.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Instructions.h" using namespace llvm; /// Initialize a full (the default) or empty set for the specified type. @@ -56,56 +55,56 @@ ConstantRange ConstantRange::makeICmpRegion(unsigned Pred, uint32_t W = CR.getBitWidth(); switch (Pred) { - default: assert(!"Invalid ICmp predicate to makeICmpRegion()"); - case ICmpInst::ICMP_EQ: + default: assert(0 && "Invalid ICmp predicate to makeICmpRegion()"); + case CmpInst::ICMP_EQ: return CR; - case ICmpInst::ICMP_NE: + case CmpInst::ICMP_NE: if (CR.isSingleElement()) return ConstantRange(CR.getUpper(), CR.getLower()); return ConstantRange(W); - case ICmpInst::ICMP_ULT: { + case CmpInst::ICMP_ULT: { APInt UMax(CR.getUnsignedMax()); if (UMax.isMinValue()) return ConstantRange(W, /* empty */ false); return ConstantRange(APInt::getMinValue(W), UMax); } - case ICmpInst::ICMP_SLT: { + case CmpInst::ICMP_SLT: { APInt SMax(CR.getSignedMax()); if (SMax.isMinSignedValue()) return ConstantRange(W, /* empty */ false); return ConstantRange(APInt::getSignedMinValue(W), SMax); } - case ICmpInst::ICMP_ULE: { + case CmpInst::ICMP_ULE: { APInt UMax(CR.getUnsignedMax()); if (UMax.isMaxValue()) return ConstantRange(W); return ConstantRange(APInt::getMinValue(W), UMax + 1); } - case ICmpInst::ICMP_SLE: { + case CmpInst::ICMP_SLE: { APInt SMax(CR.getSignedMax()); if (SMax.isMaxSignedValue()) return ConstantRange(W); return ConstantRange(APInt::getSignedMinValue(W), SMax + 1); } - case ICmpInst::ICMP_UGT: { + case CmpInst::ICMP_UGT: { APInt UMin(CR.getUnsignedMin()); if (UMin.isMaxValue()) return ConstantRange(W, /* empty */ false); return ConstantRange(UMin + 1, APInt::getNullValue(W)); } - case ICmpInst::ICMP_SGT: { + case CmpInst::ICMP_SGT: { APInt SMin(CR.getSignedMin()); if (SMin.isMaxSignedValue()) return ConstantRange(W, /* empty */ false); return ConstantRange(SMin + 1, APInt::getSignedMinValue(W)); } - case ICmpInst::ICMP_UGE: { + case CmpInst::ICMP_UGE: { APInt UMin(CR.getUnsignedMin()); if (UMin.isMinValue()) return ConstantRange(W); return ConstantRange(UMin, APInt::getNullValue(W)); } - case ICmpInst::ICMP_SGE: { + case CmpInst::ICMP_SGE: { APInt SMin(CR.getSignedMin()); if (SMin.isMinSignedValue()) return ConstantRange(W); diff --git a/lib/Support/CrashRecoveryContext.cpp b/lib/Support/CrashRecoveryContext.cpp index 899c3890d78a..263114c06f98 100644 --- a/lib/Support/CrashRecoveryContext.cpp +++ b/lib/Support/CrashRecoveryContext.cpp @@ -12,6 +12,7 @@ #include "llvm/Config/config.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/ThreadLocal.h" +#include "llvm/Support/ErrorHandling.h" #include #include using namespace llvm; @@ -123,7 +124,56 @@ CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) { #ifdef LLVM_ON_WIN32 -// FIXME: No real Win32 implementation currently. +#include "Windows/Windows.h" + +// On Windows, we can make use of vectored exception handling to +// catch most crashing situations. Note that this does mean +// we will be alerted of exceptions *before* structured exception +// handling has the opportunity to catch it. But that isn't likely +// to cause problems because nowhere in the project is SEH being +// used. +// +// Vectored exception handling is built on top of SEH, and so it +// works on a per-thread basis. +// +// The vectored exception handler functionality was added in Windows +// XP, so if support for older versions of Windows is required, +// it will have to be added. +// +// If we want to support as far back as Win2k, we could use the +// SetUnhandledExceptionFilter API, but there's a risk of that +// being entirely overwritten (it's not a chain). + +static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) +{ + // Lookup the current thread local recovery object. + const CrashRecoveryContextImpl *CRCI = CurrentContext.get(); + + if (!CRCI) { + // Something has gone horribly wrong, so let's just tell everyone + // to keep searching + CrashRecoveryContext::Disable(); + return EXCEPTION_CONTINUE_SEARCH; + } + + // TODO: We can capture the stack backtrace here and store it on the + // implementation if we so choose. + + // Handle the crash + const_cast(CRCI)->HandleCrash(); + + // Note that we don't actually get here because HandleCrash calls + // longjmp, which means the HandleCrash function never returns. + llvm_unreachable("Handled the crash, should have longjmp'ed out of here"); + return EXCEPTION_CONTINUE_SEARCH; +} + +// Because the Enable and Disable calls are static, it means that +// there may not actually be an Impl available, or even a current +// CrashRecoveryContext at all. So we make use of a thread-local +// exception table. The handles contained in here will either be +// non-NULL, valid VEH handles, or NULL. +static sys::ThreadLocal sCurrentExceptionHandle; void CrashRecoveryContext::Enable() { sys::ScopedLock L(gCrashRecoveryContexMutex); @@ -132,6 +182,13 @@ void CrashRecoveryContext::Enable() { return; gCrashRecoveryEnabled = true; + + // We can set up vectored exception handling now. We will install our + // handler as the front of the list, though there's no assurances that + // it will remain at the front (another call could install itself before + // our handler). This 1) isn't likely, and 2) shouldn't cause problems. + PVOID handle = ::AddVectoredExceptionHandler(1, ExceptionHandler); + sCurrentExceptionHandle.set(handle); } void CrashRecoveryContext::Disable() { @@ -141,6 +198,15 @@ void CrashRecoveryContext::Disable() { return; gCrashRecoveryEnabled = false; + + PVOID currentHandle = const_cast(sCurrentExceptionHandle.get()); + if (currentHandle) { + // Now we can remove the vectored exception handler from the chain + ::RemoveVectoredExceptionHandler(currentHandle); + + // Reset the handle in our thread-local set. + sCurrentExceptionHandle.set(NULL); + } } #else diff --git a/lib/Support/DataExtractor.cpp b/lib/Support/DataExtractor.cpp new file mode 100644 index 000000000000..b946c1df8363 --- /dev/null +++ b/lib/Support/DataExtractor.cpp @@ -0,0 +1,175 @@ +//===-- DataExtractor.cpp -------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/SwapByteOrder.h" +using namespace llvm; + +template +static T getU(uint32_t *offset_ptr, const DataExtractor *de, + bool isLittleEndian, const char *Data) { + T val = 0; + uint32_t offset = *offset_ptr; + if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) { + std::memcpy(&val, &Data[offset], sizeof(val)); + if (sys::isLittleEndianHost() != isLittleEndian) + val = sys::SwapByteOrder(val); + + // Advance the offset + *offset_ptr += sizeof(val); + } + return val; +} + +template +static T *getUs(uint32_t *offset_ptr, T *dst, uint32_t count, + const DataExtractor *de, bool isLittleEndian, const char *Data){ + uint32_t offset = *offset_ptr; + + if (count > 0 && de->isValidOffsetForDataOfSize(offset, sizeof(*dst)*count)) { + for (T *value_ptr = dst, *end = dst + count; value_ptr != end; + ++value_ptr, offset += sizeof(*dst)) + *value_ptr = getU(offset_ptr, de, isLittleEndian, Data); + // Advance the offset + *offset_ptr = offset; + // Return a non-NULL pointer to the converted data as an indicator of + // success + return dst; + } + return NULL; +} + +uint8_t DataExtractor::getU8(uint32_t *offset_ptr) const { + return getU(offset_ptr, this, IsLittleEndian, Data.data()); +} + +uint8_t * +DataExtractor::getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const { + return getUs(offset_ptr, dst, count, this, IsLittleEndian, + Data.data()); +} + + +uint16_t DataExtractor::getU16(uint32_t *offset_ptr) const { + return getU(offset_ptr, this, IsLittleEndian, Data.data()); +} + +uint16_t *DataExtractor::getU16(uint32_t *offset_ptr, uint16_t *dst, + uint32_t count) const { + return getUs(offset_ptr, dst, count, this, IsLittleEndian, + Data.data()); +} + +uint32_t DataExtractor::getU32(uint32_t *offset_ptr) const { + return getU(offset_ptr, this, IsLittleEndian, Data.data()); +} + +uint32_t *DataExtractor::getU32(uint32_t *offset_ptr, uint32_t *dst, + uint32_t count) const { + return getUs(offset_ptr, dst, count, this, IsLittleEndian, + Data.data());; +} + +uint64_t DataExtractor::getU64(uint32_t *offset_ptr) const { + return getU(offset_ptr, this, IsLittleEndian, Data.data()); +} + +uint64_t *DataExtractor::getU64(uint32_t *offset_ptr, uint64_t *dst, + uint32_t count) const { + return getUs(offset_ptr, dst, count, this, IsLittleEndian, + Data.data()); +} + +uint64_t +DataExtractor::getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const { + switch (byte_size) { + case 1: + return getU8(offset_ptr); + case 2: + return getU16(offset_ptr); + case 4: + return getU32(offset_ptr); + case 8: + return getU64(offset_ptr); + } + llvm_unreachable("getUnsigned unhandled case!"); +} + +int64_t +DataExtractor::getSigned(uint32_t *offset_ptr, uint32_t byte_size) const { + switch (byte_size) { + case 1: + return (int8_t)getU8(offset_ptr); + case 2: + return (int16_t)getU16(offset_ptr); + case 4: + return (int32_t)getU32(offset_ptr); + case 8: + return (int64_t)getU64(offset_ptr); + } + llvm_unreachable("getSigned unhandled case!"); +} + +const char *DataExtractor::getCStr(uint32_t *offset_ptr) const { + uint32_t offset = *offset_ptr; + StringRef::size_type pos = Data.find('\0', offset); + if (pos != StringRef::npos) { + *offset_ptr = pos + 1; + return Data.data() + offset; + } + return NULL; +} + +uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const { + uint64_t result = 0; + if (Data.empty()) + return 0; + + unsigned shift = 0; + uint32_t offset = *offset_ptr; + uint8_t byte = 0; + + while (isValidOffset(offset)) { + byte = Data[offset++]; + result |= (byte & 0x7f) << shift; + shift += 7; + if ((byte & 0x80) == 0) + break; + } + + *offset_ptr = offset; + return result; +} + +int64_t DataExtractor::getSLEB128(uint32_t *offset_ptr) const { + int64_t result = 0; + if (Data.empty()) + return 0; + + unsigned shift = 0; + uint32_t offset = *offset_ptr; + uint8_t byte = 0; + + while (isValidOffset(offset)) { + byte = Data[offset++]; + result |= (byte & 0x7f) << shift; + shift += 7; + if ((byte & 0x80) == 0) + break; + } + + // Sign bit of byte is 2nd high order bit (0x40) + if (shift < 64 && (byte & 0x40)) + result |= -(1 << shift); + + *offset_ptr = offset; + return result; +} diff --git a/lib/Support/Disassembler.cpp b/lib/Support/Disassembler.cpp index 6362aff43a9d..c6d73bcad3e4 100644 --- a/lib/Support/Disassembler.cpp +++ b/lib/Support/Disassembler.cpp @@ -1,4 +1,4 @@ -//===- lib/System/Disassembler.cpp ------------------------------*- C++ -*-===// +//===- lib/Support/Disassembler.cpp -----------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // diff --git a/lib/Support/Dwarf.cpp b/lib/Support/Dwarf.cpp index 0813321b6f79..95a9550f9663 100644 --- a/lib/Support/Dwarf.cpp +++ b/lib/Support/Dwarf.cpp @@ -82,6 +82,19 @@ const char *llvm::dwarf::TagString(unsigned Tag) { case DW_TAG_arg_variable: return "DW_TAG_arg_variable"; case DW_TAG_return_variable: return "DW_TAG_return_variable"; case DW_TAG_vector_type: return "DW_TAG_vector_type"; + case DW_TAG_rvalue_reference_type: return "DW_TAG_rvalue_reference_type"; + case DW_TAG_template_alias: return "DW_TAG_template_alias"; + case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop"; + case DW_TAG_type_unit: return "DW_TAG_type_unit"; + case DW_TAG_format_label: return "DW_TAG_format_label"; + case DW_TAG_function_template: return "DW_TAG_function_template"; + case DW_TAG_class_template: return "DW_TAG_class_template"; + case DW_TAG_GNU_template_template_param: + return "DW_TAG_GNU_template_template_param"; + case DW_TAG_GNU_template_parameter_pack: + return "DW_TAG_GNU_template_parameter_pack"; + case DW_TAG_GNU_formal_parameter_pack: + return "DW_TAG_GNU_formal_parameter_pack"; } return 0; } @@ -186,7 +199,30 @@ const char *llvm::dwarf::AttributeString(unsigned Attribute) { case DW_AT_elemental: return "DW_AT_elemental"; case DW_AT_pure: return "DW_AT_pure"; case DW_AT_recursive: return "DW_AT_recursive"; + case DW_AT_signature: return "DW_AT_signature"; + case DW_AT_main_subprogram: return "DW_AT_main_subprogram"; + case DW_AT_data_bit_offset: return "DW_AT_data_bit_offset"; + case DW_AT_const_expr: return "DW_AT_const_expr"; + case DW_AT_enum_class: return "DW_AT_enum_class"; + case DW_AT_linkage_name: return "DW_AT_linkage_name"; + case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin"; + case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin"; + case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin"; + case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor"; + case DW_AT_MIPS_software_pipeline_depth: + return "DW_AT_MIPS_software_pipeline_depth"; case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name"; + case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride"; + case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name"; + case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin"; + case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines"; + case DW_AT_MIPS_stride_byte: return "DW_AT_MIPS_stride_byte"; + case DW_AT_MIPS_stride_elem: return "DW_AT_MIPS_stride_elem"; + case DW_AT_MIPS_ptr_dopetype: return "DW_AT_MIPS_ptr_dopetype"; + case DW_AT_MIPS_allocatable_dopetype: + return "DW_AT_MIPS_allocatable_dopetype"; + case DW_AT_MIPS_assumed_shape_dopetype: + return "DW_AT_MIPS_assumed_shape_dopetype"; case DW_AT_sf_names: return "DW_AT_sf_names"; case DW_AT_src_info: return "DW_AT_src_info"; case DW_AT_mac_info: return "DW_AT_mac_info"; @@ -194,6 +230,8 @@ const char *llvm::dwarf::AttributeString(unsigned Attribute) { case DW_AT_body_begin: return "DW_AT_body_begin"; case DW_AT_body_end: return "DW_AT_body_end"; case DW_AT_GNU_vector: return "DW_AT_GNU_vector"; + case DW_AT_GNU_template_name: return "DW_AT_GNU_template_name"; + case DW_AT_MIPS_assumed_size: return "DW_AT_MIPS_assumed_size"; case DW_AT_lo_user: return "DW_AT_lo_user"; case DW_AT_hi_user: return "DW_AT_hi_user"; case DW_AT_APPLE_optimized: return "DW_AT_APPLE_optimized"; @@ -237,6 +275,10 @@ const char *llvm::dwarf::FormEncodingString(unsigned Encoding) { case DW_FORM_ref8: return "DW_FORM_ref8"; case DW_FORM_ref_udata: return "DW_FORM_ref_udata"; case DW_FORM_indirect: return "DW_FORM_indirect"; + case DW_FORM_sec_offset: return "DW_FORM_sec_offset"; + case DW_FORM_exprloc: return "DW_FORM_exprloc"; + case DW_FORM_flag_present: return "DW_FORM_flag_present"; + case DW_FORM_ref_sig8: return "DW_FORM_ref_sig8"; } return 0; } @@ -397,6 +439,8 @@ const char *llvm::dwarf::OperationEncodingString(unsigned Encoding) { case DW_OP_form_tls_address: return "DW_OP_form_tls_address"; case DW_OP_call_frame_cfa: return "DW_OP_call_frame_cfa"; case DW_OP_bit_piece: return "DW_OP_bit_piece"; + case DW_OP_implicit_value: return "DW_OP_implicit_value"; + case DW_OP_stack_value: return "DW_OP_stack_value"; case DW_OP_lo_user: return "DW_OP_lo_user"; case DW_OP_hi_user: return "DW_OP_hi_user"; } @@ -416,6 +460,7 @@ const char *llvm::dwarf::AttributeEncodingString(unsigned Encoding) { case DW_ATE_unsigned: return "DW_ATE_unsigned"; case DW_ATE_unsigned_char: return "DW_ATE_unsigned_char"; case DW_ATE_imaginary_float: return "DW_ATE_imaginary_float"; + case DW_ATE_UTF: return "DW_ATE_UTF"; case DW_ATE_packed_decimal: return "DW_ATE_packed_decimal"; case DW_ATE_numeric_string: return "DW_ATE_numeric_string"; case DW_ATE_edited: return "DW_ATE_edited"; @@ -602,6 +647,7 @@ const char *llvm::dwarf::LNExtendedString(unsigned Encoding) { case DW_LNE_end_sequence: return "DW_LNE_end_sequence"; case DW_LNE_set_address: return "DW_LNE_set_address"; case DW_LNE_define_file: return "DW_LNE_define_file"; + case DW_LNE_set_discriminator: return "DW_LNE_set_discriminator"; case DW_LNE_lo_user: return "DW_LNE_lo_user"; case DW_LNE_hi_user: return "DW_LNE_hi_user"; } @@ -651,6 +697,9 @@ const char *llvm::dwarf::CallFrameString(unsigned Encoding) { case DW_CFA_val_offset: return "DW_CFA_val_offset"; case DW_CFA_val_offset_sf: return "DW_CFA_val_offset_sf"; case DW_CFA_val_expression: return "DW_CFA_val_expression"; + case DW_CFA_MIPS_advance_loc8: return "DW_CFA_MIPS_advance_loc8"; + case DW_CFA_GNU_window_save: return "DW_CFA_GNU_window_save"; + case DW_CFA_GNU_args_size: return "DW_CFA_GNU_args_size"; case DW_CFA_lo_user: return "DW_CFA_lo_user"; case DW_CFA_hi_user: return "DW_CFA_hi_user"; } diff --git a/lib/Support/DynamicLibrary.cpp b/lib/Support/DynamicLibrary.cpp index 455c3801cc68..fb02c07e4af8 100644 --- a/lib/Support/DynamicLibrary.cpp +++ b/lib/Support/DynamicLibrary.cpp @@ -9,28 +9,26 @@ // // This header file implements the operating system DynamicLibrary concept. // -// FIXME: This file leaks the ExplicitSymbols and OpenedHandles vector, and is -// not thread safe! +// FIXME: This file leaks ExplicitSymbols and OpenedHandles! // //===----------------------------------------------------------------------===// +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/Mutex.h" #include "llvm/Config/config.h" #include #include -#include -#include // Collection of symbol name/value pairs to be searched prior to any libraries. -static std::map *ExplicitSymbols = 0; +static llvm::StringMap *ExplicitSymbols = 0; namespace { struct ExplicitSymbolsDeleter { ~ExplicitSymbolsDeleter() { - if (ExplicitSymbols) - delete ExplicitSymbols; + delete ExplicitSymbols; } }; @@ -38,13 +36,22 @@ struct ExplicitSymbolsDeleter { static ExplicitSymbolsDeleter Dummy; -void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName, + +static llvm::sys::SmartMutex& getMutex() { + static llvm::sys::SmartMutex HandlesMutex; + return HandlesMutex; +} + +void llvm::sys::DynamicLibrary::AddSymbol(StringRef symbolName, void *symbolValue) { + SmartScopedLock lock(getMutex()); if (ExplicitSymbols == 0) - ExplicitSymbols = new std::map(); + ExplicitSymbols = new llvm::StringMap(); (*ExplicitSymbols)[symbolName] = symbolValue; } +char llvm::sys::DynamicLibrary::Invalid = 0; + #ifdef LLVM_ON_WIN32 #include "Windows/DynamicLibrary.inc" @@ -61,66 +68,78 @@ using namespace llvm::sys; //=== independent code. //===----------------------------------------------------------------------===// -static std::vector *OpenedHandles = 0; +static DenseSet *OpenedHandles = 0; +DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, + std::string *errMsg) { + SmartScopedLock lock(getMutex()); -static SmartMutex& getMutex() { - static SmartMutex HandlesMutex; - return HandlesMutex; -} - - -bool DynamicLibrary::LoadLibraryPermanently(const char *Filename, - std::string *ErrMsg) { - void *H = dlopen(Filename, RTLD_LAZY|RTLD_GLOBAL); - if (H == 0) { - if (ErrMsg) *ErrMsg = dlerror(); - return true; + void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL); + if (handle == 0) { + if (errMsg) *errMsg = dlerror(); + return DynamicLibrary(); } + #ifdef __CYGWIN__ // Cygwin searches symbols only in the main // with the handle of dlopen(NULL, RTLD_GLOBAL). - if (Filename == NULL) - H = RTLD_DEFAULT; + if (filename == NULL) + handle = RTLD_DEFAULT; #endif - SmartScopedLock Lock(getMutex()); + if (OpenedHandles == 0) - OpenedHandles = new std::vector(); - OpenedHandles->push_back(H); - return false; + OpenedHandles = new DenseSet(); + + // If we've already loaded this library, dlclose() the handle in order to + // keep the internal refcount at +1. + if (!OpenedHandles->insert(handle).second) + dlclose(handle); + + return DynamicLibrary(handle); } + +void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { + if (!isValid()) + return NULL; + return dlsym(Data, symbolName); +} + #else using namespace llvm; using namespace llvm::sys; -bool DynamicLibrary::LoadLibraryPermanently(const char *Filename, - std::string *ErrMsg) { - if (ErrMsg) *ErrMsg = "dlopen() not supported on this platform"; - return true; +DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, + std::string *errMsg) { + if (errMsg) *errMsg = "dlopen() not supported on this platform"; + return DynamicLibrary(); } + +void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { + return NULL; +} + #endif namespace llvm { void *SearchForAddressOfSpecialSymbol(const char* symbolName); } -void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { +void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) { + SmartScopedLock Lock(getMutex()); + // First check symbols added via AddSymbol(). if (ExplicitSymbols) { - std::map::iterator I = - ExplicitSymbols->find(symbolName); - std::map::iterator E = ExplicitSymbols->end(); + StringMap::iterator i = ExplicitSymbols->find(symbolName); - if (I != E) - return I->second; + if (i != ExplicitSymbols->end()) + return i->second; } #if HAVE_DLFCN_H // Now search the libraries. - SmartScopedLock Lock(getMutex()); if (OpenedHandles) { - for (std::vector::iterator I = OpenedHandles->begin(), + for (DenseSet::iterator I = OpenedHandles->begin(), E = OpenedHandles->end(); I != E; ++I) { //lt_ptr ptr = lt_dlsym(*I, symbolName); void *ptr = dlsym(*I, symbolName); diff --git a/lib/Support/FoldingSet.cpp b/lib/Support/FoldingSet.cpp index 1568342e9c9d..17b827132f57 100644 --- a/lib/Support/FoldingSet.cpp +++ b/lib/Support/FoldingSet.cpp @@ -64,10 +64,8 @@ void FoldingSetNodeID::AddPointer(const void *Ptr) { // depend on the host. It doesn't matter however, because hashing on // pointer values in inherently unstable. Nothing should depend on the // ordering of nodes in the folding set. - intptr_t PtrI = (intptr_t)Ptr; - Bits.push_back(unsigned(PtrI)); - if (sizeof(intptr_t) > sizeof(unsigned)) - Bits.push_back(unsigned(uint64_t(PtrI) >> 32)); + Bits.append(reinterpret_cast(&Ptr), + reinterpret_cast(&Ptr+1)); } void FoldingSetNodeID::AddInteger(signed I) { Bits.push_back(I); diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp index c525a1228129..a19e4b41189b 100644 --- a/lib/Support/Host.cpp +++ b/lib/Support/Host.cpp @@ -213,13 +213,13 @@ std::string sys::getHostCPUName() { case 30: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz. // As found in a Summer 2010 model iMac. case 37: // Intel Core i7, laptop version. + case 44: // Intel Core i7 processor and Intel Xeon processor. All + // processors are manufactured using the 32 nm process. return "corei7"; // SandyBridge: case 42: // Intel Core i7 processor. All processors are manufactured // using the 32 nm process. - case 44: // Intel Core i7 processor and Intel Xeon processor. All - // processors are manufactured using the 32 nm process. case 45: return "corei7-avx"; diff --git a/lib/Support/IncludeFile.cpp b/lib/Support/IncludeFile.cpp index 5da88261ce53..e67acb3d1d67 100644 --- a/lib/Support/IncludeFile.cpp +++ b/lib/Support/IncludeFile.cpp @@ -1,4 +1,4 @@ -//===- lib/System/IncludeFile.cpp - Ensure Linking Of Implementation -----===// +//===- lib/Support/IncludeFile.cpp - Ensure Linking Of Implementation -----===// // // The LLVM Compiler Infrastructure // diff --git a/lib/Support/Memory.cpp b/lib/Support/Memory.cpp index a9689b2c39f2..2a1642ac2e85 100644 --- a/lib/Support/Memory.cpp +++ b/lib/Support/Memory.cpp @@ -16,6 +16,10 @@ #include "llvm/Support/Valgrind.h" #include "llvm/Config/config.h" +#if defined(__mips__) +#include +#endif + namespace llvm { using namespace sys; } @@ -66,6 +70,8 @@ void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr, char *Start = (char*) Addr; char *End = Start + Len; __clear_cache(Start, End); +# elif defined(__mips__) + cacheflush((char*)Addr, Len, BCACHE); # endif #endif // end apple diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp index d264be9aced1..0771af5fee07 100644 --- a/lib/Support/MemoryBuffer.cpp +++ b/lib/Support/MemoryBuffer.cpp @@ -275,16 +275,16 @@ static bool shouldUseMmap(int FD, error_code MemoryBuffer::getOpenFile(int FD, const char *Filename, OwningPtr &result, - size_t FileSize, size_t MapSize, - off_t Offset, + uint64_t FileSize, uint64_t MapSize, + int64_t Offset, bool RequiresNullTerminator) { static int PageSize = sys::Process::GetPageSize(); // Default is to map the full file. - if (MapSize == size_t(-1)) { + if (MapSize == uint64_t(-1)) { // If we don't know the file size, use fstat to find out. fstat on an open // file descriptor is cheaper than stat on a random path. - if (FileSize == size_t(-1)) { + if (FileSize == uint64_t(-1)) { struct stat FileInfo; // TODO: This should use fstat64 when available. if (fstat(FD, &FileInfo) == -1) { diff --git a/lib/Support/MemoryObject.cpp b/lib/Support/MemoryObject.cpp index 91e3ecd23a2e..b20ab8923813 100644 --- a/lib/Support/MemoryObject.cpp +++ b/lib/Support/MemoryObject.cpp @@ -19,8 +19,11 @@ int MemoryObject::readBytes(uint64_t address, uint64_t* copied) const { uint64_t current = address; uint64_t limit = getBase() + getExtent(); - - while (current - address < size && current < limit) { + + if (current + size > limit) + return -1; + + while (current - address < size) { if (readByte(current, &buf[(current - address)])) return -1; diff --git a/lib/Support/Mutex.cpp b/lib/Support/Mutex.cpp index b408973bbad1..8874e943f4c2 100644 --- a/lib/Support/Mutex.cpp +++ b/lib/Support/Mutex.cpp @@ -152,6 +152,6 @@ MutexImpl::tryacquire() #elif defined( LLVM_ON_WIN32) #include "Windows/Mutex.inc" #else -#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp +#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp #endif #endif diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp index 8fbaf2d42bf9..e5b7cd3bfbc2 100644 --- a/lib/Support/Path.cpp +++ b/lib/Support/Path.cpp @@ -121,7 +121,7 @@ sys::IdentifyFileType(const char *magic, unsigned length) { case 7: return Mach_O_DynamicLinker_FileType; case 8: return Mach_O_Bundle_FileType; case 9: return Mach_O_DynamicallyLinkedSharedLibStub_FileType; - case 10: break; // FIXME: MH_DSYM companion file with only debug. + case 10: return Mach_O_DSYMCompanion_FileType; } break; } diff --git a/lib/Support/PathV2.cpp b/lib/Support/PathV2.cpp index 896c94c071bc..bebe442e2478 100644 --- a/lib/Support/PathV2.cpp +++ b/lib/Support/PathV2.cpp @@ -490,6 +490,36 @@ bool is_separator(char value) { } } +void system_temp_directory(bool erasedOnReboot, SmallVectorImpl &result) { + result.clear(); + + // Check whether the temporary directory is specified by an environment + // variable. + const char *EnvironmentVariable; +#ifdef LLVM_ON_WIN32 + EnvironmentVariable = "TEMP"; +#else + EnvironmentVariable = "TMPDIR"; +#endif + if (char *RequestedDir = getenv(EnvironmentVariable)) { + result.append(RequestedDir, RequestedDir + strlen(RequestedDir)); + return; + } + + // Fall back to a system default. + const char *DefaultResult; +#ifdef LLVM_ON_WIN32 + (void)erasedOnReboot; + DefaultResult = "C:\\TEMP"; +#else + if (erasedOnReboot) + DefaultResult = "/tmp"; + else + DefaultResult = "/var/tmp"; +#endif + result.append(DefaultResult, DefaultResult + strlen(DefaultResult)); +} + bool has_root_name(const Twine &path) { SmallString<128> path_storage; StringRef p = path.toStringRef(path_storage); @@ -626,7 +656,7 @@ error_code create_directories(const Twine &path, bool &existed) { if (error_code ec = fs::exists(parent, parent_exists)) return ec; if (!parent_exists) - return create_directories(parent, existed); + if (error_code ec = create_directories(parent, existed)) return ec; return create_directory(p, existed); } @@ -682,14 +712,12 @@ bool is_other(file_status status) { !is_symlink(status); } -void directory_entry::replace_filename(const Twine &filename, file_status st, - file_status symlink_st) { +void directory_entry::replace_filename(const Twine &filename, file_status st) { SmallString<128> path(Path.begin(), Path.end()); path::remove_filename(path); path::append(path, filename); Path = path.str(); Status = st; - SymlinkStatus = symlink_st; } error_code has_magic(const Twine &path, const Twine &magic, bool &result) { diff --git a/lib/Support/PrettyStackTrace.cpp b/lib/Support/PrettyStackTrace.cpp index 082b7012eb23..ef3307317c4a 100644 --- a/lib/Support/PrettyStackTrace.cpp +++ b/lib/Support/PrettyStackTrace.cpp @@ -62,7 +62,7 @@ extern "C" { CRASH_REPORTER_CLIENT_HIDDEN struct crashreporter_annotations_t gCRAnnotations __attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION))) - = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0 }; + = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 }; } #elif defined (__APPLE__) && HAVE_CRASHREPORTER_INFO static const char *__crashreporter_info__ = 0; diff --git a/lib/Support/RWMutex.cpp b/lib/Support/RWMutex.cpp index fc02f9cf7c11..d0b1e10b56fb 100644 --- a/lib/Support/RWMutex.cpp +++ b/lib/Support/RWMutex.cpp @@ -152,6 +152,6 @@ RWMutexImpl::writer_release() #elif defined( LLVM_ON_WIN32) #include "Windows/RWMutex.inc" #else -#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp +#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp #endif #endif diff --git a/lib/Support/SearchForAddressOfSpecialSymbol.cpp b/lib/Support/SearchForAddressOfSpecialSymbol.cpp index d63830185c32..2d23902bb85c 100644 --- a/lib/Support/SearchForAddressOfSpecialSymbol.cpp +++ b/lib/Support/SearchForAddressOfSpecialSymbol.cpp @@ -28,21 +28,6 @@ static void *DoSearch(const char* symbolName) { #ifdef __APPLE__ { - EXPLICIT_SYMBOL(__ashldi3); - EXPLICIT_SYMBOL(__ashrdi3); - EXPLICIT_SYMBOL(__cmpdi2); - EXPLICIT_SYMBOL(__divdi3); - EXPLICIT_SYMBOL(__fixdfdi); - EXPLICIT_SYMBOL(__fixsfdi); - EXPLICIT_SYMBOL(__fixunsdfdi); - EXPLICIT_SYMBOL(__fixunssfdi); - EXPLICIT_SYMBOL(__floatdidf); - EXPLICIT_SYMBOL(__floatdisf); - EXPLICIT_SYMBOL(__lshrdi3); - EXPLICIT_SYMBOL(__moddi3); - EXPLICIT_SYMBOL(__udivdi3); - EXPLICIT_SYMBOL(__umoddi3); - // __eprintf is sometimes used for assert() handling on x86. // // FIXME: Currently disabled when using Clang, as we don't always have our diff --git a/lib/Support/StringExtras.cpp b/lib/Support/StringExtras.cpp index eb2fa084218a..49c5ac4252c8 100644 --- a/lib/Support/StringExtras.cpp +++ b/lib/Support/StringExtras.cpp @@ -51,11 +51,10 @@ std::pair llvm::getToken(StringRef Source, void llvm::SplitString(StringRef Source, SmallVectorImpl &OutFragments, StringRef Delimiters) { - StringRef S2, S; - tie(S2, S) = getToken(Source, Delimiters); - while (!S2.empty()) { - OutFragments.push_back(S2); - tie(S2, S) = getToken(S, Delimiters); + std::pair S = getToken(Source, Delimiters); + while (!S.first.empty()) { + OutFragments.push_back(S.first); + S = getToken(S.second, Delimiters); } } diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp index 8c3fc094cd11..b5b4f9476026 100644 --- a/lib/Support/StringRef.cpp +++ b/lib/Support/StringRef.cpp @@ -46,12 +46,12 @@ int StringRef::compare_lower(StringRef RHS) const { /// compare_numeric - Compare strings, handle embedded numbers. int StringRef::compare_numeric(StringRef RHS) const { for (size_t I = 0, E = min(Length, RHS.Length); I != E; ++I) { - if (Data[I] == RHS.Data[I]) - continue; + // Check for sequences of digits. if (ascii_isdigit(Data[I]) && ascii_isdigit(RHS.Data[I])) { - // The longer sequence of numbers is larger. This doesn't really handle - // prefixed zeros well. - for (size_t J = I+1; J != E+1; ++J) { + // The longer sequence of numbers is considered larger. + // This doesn't really handle prefixed zeros well. + size_t J; + for (J = I + 1; J != E + 1; ++J) { bool ld = J < Length && ascii_isdigit(Data[J]); bool rd = J < RHS.Length && ascii_isdigit(RHS.Data[J]); if (ld != rd) @@ -59,8 +59,15 @@ int StringRef::compare_numeric(StringRef RHS) const { if (!rd) break; } + // The two number sequences have the same length (J-I), just memcmp them. + if (int Res = compareMemory(Data + I, RHS.Data + I, J - I)) + return Res < 0 ? -1 : 1; + // Identical number sequences, continue search after the numbers. + I = J - 1; + continue; } - return (unsigned char)Data[I] < (unsigned char)RHS.Data[I] ? -1 : 1; + if (Data[I] != RHS.Data[I]) + return (unsigned char)Data[I] < (unsigned char)RHS.Data[I] ? -1 : 1; } if (Length == RHS.Length) return 0; diff --git a/lib/Support/TargetRegistry.cpp b/lib/Support/TargetRegistry.cpp index 293a5d7a0168..7497bfe035c6 100644 --- a/lib/Support/TargetRegistry.cpp +++ b/lib/Support/TargetRegistry.cpp @@ -7,9 +7,13 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Target/TargetRegistry.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Host.h" +#include "llvm/Support/raw_ostream.h" #include +#include using namespace llvm; // Clients are responsible for avoid race conditions in registration. @@ -90,3 +94,29 @@ const Target *TargetRegistry::getClosestTargetForJIT(std::string &Error) { return TheTarget; } +static int TargetArraySortFn(const void *LHS, const void *RHS) { + typedef std::pair pair_ty; + return ((const pair_ty*)LHS)->first.compare(((const pair_ty*)RHS)->first); +} + +void TargetRegistry::printRegisteredTargetsForVersion() { + std::vector > Targets; + size_t Width = 0; + for (TargetRegistry::iterator I = TargetRegistry::begin(), + E = TargetRegistry::end(); + I != E; ++I) { + Targets.push_back(std::make_pair(I->getName(), &*I)); + Width = std::max(Width, Targets.back().first.size()); + } + array_pod_sort(Targets.begin(), Targets.end(), TargetArraySortFn); + + raw_ostream &OS = outs(); + OS << " Registered Targets:\n"; + for (unsigned i = 0, e = Targets.size(); i != e; ++i) { + OS << " " << Targets[i].first; + OS.indent(Width - Targets[i].first.size()) << " - " + << Targets[i].second->getShortDescription() << '\n'; + } + if (Targets.empty()) + OS << " (none)\n"; +} diff --git a/lib/Support/ThreadLocal.cpp b/lib/Support/ThreadLocal.cpp index 6b43048da155..fdb251c0a36b 100644 --- a/lib/Support/ThreadLocal.cpp +++ b/lib/Support/ThreadLocal.cpp @@ -79,6 +79,6 @@ void ThreadLocalImpl::removeInstance() { #elif defined( LLVM_ON_WIN32) #include "Windows/ThreadLocal.inc" #else -#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/ThreadLocal.cpp +#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 set in Support/ThreadLocal.cpp #endif #endif diff --git a/lib/Support/Threading.cpp b/lib/Support/Threading.cpp index 29579567ac6c..8f0bb93eb4d1 100644 --- a/lib/Support/Threading.cpp +++ b/lib/Support/Threading.cpp @@ -24,7 +24,7 @@ static bool multithreaded_mode = false; static sys::Mutex* global_lock = 0; bool llvm::llvm_start_multithreaded() { -#ifdef LLVM_MULTITHREADED +#if ENABLE_THREADS != 0 assert(!multithreaded_mode && "Already multithreaded!"); multithreaded_mode = true; global_lock = new sys::Mutex(true); @@ -39,7 +39,7 @@ bool llvm::llvm_start_multithreaded() { } void llvm::llvm_stop_multithreaded() { -#ifdef LLVM_MULTITHREADED +#if ENABLE_THREADS != 0 assert(multithreaded_mode && "Not currently multithreaded!"); // We fence here to insure that all threaded operations are complete BEFORE we @@ -63,7 +63,7 @@ void llvm::llvm_release_global_lock() { if (multithreaded_mode) global_lock->release(); } -#if defined(LLVM_MULTITHREADED) && defined(HAVE_PTHREAD_H) +#if ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H) #include struct ThreadInfo { @@ -102,11 +102,42 @@ void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData, error: ::pthread_attr_destroy(&Attr); } +#elif ENABLE_THREADS!=0 && defined(LLVM_ON_WIN32) +#include "Windows/Windows.h" +#include +struct ThreadInfo { + void (*func)(void*); + void *param; +}; + +static unsigned __stdcall ThreadCallback(void *param) { + struct ThreadInfo *info = reinterpret_cast(param); + info->func(info->param); + + return 0; +} + +void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData, + unsigned RequestedStackSize) { + struct ThreadInfo param = { Fn, UserData }; + + HANDLE hThread = (HANDLE)::_beginthreadex(NULL, + RequestedStackSize, ThreadCallback, + ¶m, 0, NULL); + + if (hThread) { + // We actually don't care whether the wait succeeds or fails, in + // the same way we don't care whether the pthread_join call succeeds + // or fails. There's not much we could do if this were to fail. But + // on success, this call will wait until the thread finishes executing + // before returning. + (void)::WaitForSingleObject(hThread, INFINITE); + ::CloseHandle(hThread); + } +} #else - -// No non-pthread implementation, currently. - +// Support for non-Win32, non-pthread implementation. void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData, unsigned RequestedStackSize) { (void) RequestedStackSize; diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp index 7e094ee78f36..c61af372d79c 100644 --- a/lib/Support/Triple.cpp +++ b/lib/Support/Triple.cpp @@ -8,16 +8,11 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/Triple.h" - #include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Twine.h" -#include #include using namespace llvm; -// - const char *Triple::getArchTypeName(ArchType Kind) { switch (Kind) { case InvalidArch: return ""; @@ -29,6 +24,8 @@ const char *Triple::getArchTypeName(ArchType Kind) { case cellspu: return "cellspu"; case mips: return "mips"; case mipsel: return "mipsel"; + case mips64: return "mips64"; + case mips64el:return "mips64el"; case msp430: return "msp430"; case ppc64: return "powerpc64"; case ppc: return "powerpc"; @@ -43,6 +40,8 @@ const char *Triple::getArchTypeName(ArchType Kind) { case mblaze: return "mblaze"; case ptx32: return "ptx32"; case ptx64: return "ptx64"; + case le32: return "le32"; + case amdil: return "amdil"; } return ""; @@ -77,6 +76,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) { case ptx32: return "ptx"; case ptx64: return "ptx"; + case le32: return "le32"; + case amdil: return "amdil"; } } @@ -102,6 +103,7 @@ const char *Triple::getOSTypeName(OSType Kind) { case DragonFly: return "dragonfly"; case FreeBSD: return "freebsd"; case IOS: return "ios"; + case KFreeBSD: return "kfreebsd"; case Linux: return "linux"; case Lv2: return "lv2"; case MacOSX: return "macosx"; @@ -114,6 +116,7 @@ const char *Triple::getOSTypeName(OSType Kind) { case Haiku: return "haiku"; case Minix: return "minix"; case RTEMS: return "rtems"; + case NativeClient: return "nacl"; } return ""; @@ -144,10 +147,16 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { return mips; if (Name == "mipsel") return mipsel; + if (Name == "mips64") + return mips64; + if (Name == "mips64el") + return mips64el; if (Name == "msp430") return msp430; if (Name == "ppc64") return ppc64; + if (Name == "ppc32") + return ppc; if (Name == "ppc") return ppc; if (Name == "mblaze") @@ -172,6 +181,10 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { return ptx32; if (Name == "ptx64") return ptx64; + if (Name == "le32") + return le32; + if (Name == "amdil") + return amdil; return UnknownArch; } @@ -207,13 +220,16 @@ Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) { // This is derived from the driver driver. if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" || - Str == "armv6" || Str == "armv7") + Str == "armv6" || Str == "armv7" || Str == "armv7f" || Str == "armv7k" || + Str == "armv7s") return Triple::arm; if (Str == "ptx32") return Triple::ptx32; if (Str == "ptx64") return Triple::ptx64; + if (Str == "amdil") + return Triple::amdil; return Triple::UnknownArch; } @@ -249,6 +265,10 @@ const char *Triple::getArchNameForAssembler() { return "ptx32"; if (Str == "ptx64") return "ptx64"; + if (Str == "le32") + return "le32"; + if (Str == "amdil") + return "amdil"; return NULL; } @@ -288,6 +308,10 @@ Triple::ArchType Triple::ParseArch(StringRef ArchName) { else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" || ArchName == "psp") return mipsel; + else if (ArchName == "mips64" || ArchName == "mips64eb") + return mips64; + else if (ArchName == "mips64el") + return mips64el; else if (ArchName == "sparc") return sparc; else if (ArchName == "sparcv9") @@ -302,6 +326,10 @@ Triple::ArchType Triple::ParseArch(StringRef ArchName) { return ptx32; else if (ArchName == "ptx64") return ptx64; + else if (ArchName == "le32") + return le32; + else if (ArchName == "amdil") + return amdil; else return UnknownArch; } @@ -330,6 +358,8 @@ Triple::OSType Triple::ParseOS(StringRef OSName) { return FreeBSD; else if (OSName.startswith("ios")) return IOS; + else if (OSName.startswith("kfreebsd")) + return KFreeBSD; else if (OSName.startswith("linux")) return Linux; else if (OSName.startswith("lv2")) @@ -354,6 +384,8 @@ Triple::OSType Triple::ParseOS(StringRef OSName) { return Minix; else if (OSName.startswith("rtems")) return RTEMS; + else if (OSName.startswith("nacl")) + return NativeClient; else return UnknownOS; } diff --git a/lib/Support/Twine.cpp b/lib/Support/Twine.cpp index d62123cc985e..3d04bc34f0eb 100644 --- a/lib/Support/Twine.cpp +++ b/lib/Support/Twine.cpp @@ -16,7 +16,7 @@ using namespace llvm; std::string Twine::str() const { // If we're storing only a std::string, just return it. if (LHSKind == StdStringKind && RHSKind == EmptyKind) - return *static_cast(LHS); + return *LHS.stdString; // Otherwise, flatten and copy the contents first. SmallString<256> Vec; @@ -40,9 +40,9 @@ StringRef Twine::toNullTerminatedStringRef(SmallVectorImpl &Out) const { switch (getLHSKind()) { case CStringKind: // Already null terminated, yay! - return StringRef(static_cast(LHS)); + return StringRef(LHS.cString); case StdStringKind: { - const std::string *str = static_cast(LHS); + const std::string *str = LHS.stdString; return StringRef(str->c_str(), str->size()); } default: @@ -55,48 +55,51 @@ StringRef Twine::toNullTerminatedStringRef(SmallVectorImpl &Out) const { return StringRef(Out.data(), Out.size()); } -void Twine::printOneChild(raw_ostream &OS, const void *Ptr, +void Twine::printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const { switch (Kind) { case Twine::NullKind: break; case Twine::EmptyKind: break; case Twine::TwineKind: - static_cast(Ptr)->print(OS); + Ptr.twine->print(OS); break; case Twine::CStringKind: - OS << static_cast(Ptr); + OS << Ptr.cString; break; case Twine::StdStringKind: - OS << *static_cast(Ptr); + OS << *Ptr.stdString; break; case Twine::StringRefKind: - OS << *static_cast(Ptr); + OS << *Ptr.stringRef; + break; + case Twine::CharKind: + OS << Ptr.character; break; case Twine::DecUIKind: - OS << (unsigned)(uintptr_t)Ptr; + OS << Ptr.decUI; break; case Twine::DecIKind: - OS << (int)(intptr_t)Ptr; + OS << Ptr.decI; break; case Twine::DecULKind: - OS << *static_cast(Ptr); + OS << *Ptr.decUL; break; case Twine::DecLKind: - OS << *static_cast(Ptr); + OS << *Ptr.decL; break; case Twine::DecULLKind: - OS << *static_cast(Ptr); + OS << *Ptr.decULL; break; case Twine::DecLLKind: - OS << *static_cast(Ptr); + OS << *Ptr.decLL; break; case Twine::UHexKind: - OS.write_hex(*static_cast(Ptr)); + OS.write_hex(*Ptr.uHex); break; } } -void Twine::printOneChildRepr(raw_ostream &OS, const void *Ptr, +void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr, NodeKind Kind) const { switch (Kind) { case Twine::NullKind: @@ -105,40 +108,43 @@ void Twine::printOneChildRepr(raw_ostream &OS, const void *Ptr, OS << "empty"; break; case Twine::TwineKind: OS << "rope:"; - static_cast(Ptr)->printRepr(OS); + Ptr.twine->printRepr(OS); break; case Twine::CStringKind: OS << "cstring:\"" - << static_cast(Ptr) << "\""; + << Ptr.cString << "\""; break; case Twine::StdStringKind: OS << "std::string:\"" - << static_cast(Ptr) << "\""; + << Ptr.stdString << "\""; break; case Twine::StringRefKind: OS << "stringref:\"" - << static_cast(Ptr) << "\""; + << Ptr.stringRef << "\""; + break; + case Twine::CharKind: + OS << "char:\"" << Ptr.character << "\""; break; case Twine::DecUIKind: - OS << "decUI:\"" << (unsigned)(uintptr_t)Ptr << "\""; + OS << "decUI:\"" << Ptr.decUI << "\""; break; case Twine::DecIKind: - OS << "decI:\"" << (int)(intptr_t)Ptr << "\""; + OS << "decI:\"" << Ptr.decI << "\""; break; case Twine::DecULKind: - OS << "decUL:\"" << *static_cast(Ptr) << "\""; + OS << "decUL:\"" << *Ptr.decUL << "\""; break; case Twine::DecLKind: - OS << "decL:\"" << *static_cast(Ptr) << "\""; + OS << "decL:\"" << *Ptr.decL << "\""; break; case Twine::DecULLKind: - OS << "decULL:\"" << *static_cast(Ptr) << "\""; + OS << "decULL:\"" << *Ptr.decULL << "\""; break; case Twine::DecLLKind: - OS << "decLL:\"" << *static_cast(Ptr) << "\""; + OS << "decLL:\"" << *Ptr.decLL << "\""; break; case Twine::UHexKind: - OS << "uhex:\"" << static_cast(Ptr) << "\""; + OS << "uhex:\"" << Ptr.uHex << "\""; break; } } diff --git a/lib/Support/Unix/Host.inc b/lib/Support/Unix/Host.inc index 5fd0e5e0790b..dda3ce2c6f97 100644 --- a/lib/Support/Unix/Host.inc +++ b/lib/Support/Unix/Host.inc @@ -22,6 +22,7 @@ #include #include #include +#include // ::getenv using namespace llvm; diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc index f295b92e4a5b..85c7c4022f48 100644 --- a/lib/Support/Unix/Path.inc +++ b/lib/Support/Unix/Path.inc @@ -252,8 +252,8 @@ Path::GetUserHomeDirectory() { Path Path::GetCurrentDirectory() { char pathname[MAXPATHLEN]; - if (!getcwd(pathname,MAXPATHLEN)) { - assert (false && "Could not query current working directory."); + if (!getcwd(pathname, MAXPATHLEN)) { + assert(false && "Could not query current working directory."); return Path(); } diff --git a/lib/Support/Unix/PathV2.inc b/lib/Support/Unix/PathV2.inc index 03ff28367e44..bbbc344661be 100644 --- a/lib/Support/Unix/PathV2.inc +++ b/lib/Support/Unix/PathV2.inc @@ -42,6 +42,9 @@ #if HAVE_STDIO_H #include #endif +#if HAVE_LIMITS_H +#include +#endif using namespace llvm; @@ -342,19 +345,22 @@ error_code status(const Twine &path, file_status &result) { } error_code unique_file(const Twine &model, int &result_fd, - SmallVectorImpl &result_path) { + SmallVectorImpl &result_path, + bool makeAbsolute) { SmallString<128> Model; model.toVector(Model); // Null terminate. Model.c_str(); - // Make model absolute by prepending a temp directory if it's not already. - bool absolute = path::is_absolute(Twine(Model)); - if (!absolute) { - SmallString<128> TDir; - if (error_code ec = TempDir(TDir)) return ec; - path::append(TDir, Twine(Model)); - Model.swap(TDir); + if (makeAbsolute) { + // Make model absolute by prepending a temp directory if it's not already. + bool absolute = path::is_absolute(Twine(Model)); + if (!absolute) { + SmallString<128> TDir; + if (error_code ec = TempDir(TDir)) return ec; + path::append(TDir, Twine(Model)); + Model.swap(TDir); + } } // Replace '%' with random chars. From here on, DO NOT modify model. It may be diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc index 5cdb11ccebc4..da440fd48f3d 100644 --- a/lib/Support/Unix/Process.inc +++ b/lib/Support/Unix/Process.inc @@ -293,3 +293,7 @@ const char *Process::OutputBold(bool bg) { const char *Process::ResetColor() { return "\033[0m"; } + +void Process::SetWorkingDirectory(std::string Path) { + ::chdir(Path.c_str()); +} diff --git a/lib/Support/Windows/DynamicLibrary.inc b/lib/Support/Windows/DynamicLibrary.inc index fc5f5809cb40..83da82a949ca 100644 --- a/lib/Support/Windows/DynamicLibrary.inc +++ b/lib/Support/Windows/DynamicLibrary.inc @@ -39,7 +39,7 @@ using namespace sys; //=== and must not be UNIX code. //===----------------------------------------------------------------------===// -static std::vector OpenedHandles; +static DenseSet *OpenedHandles; extern "C" { @@ -63,30 +63,43 @@ extern "C" { #endif stricmp(ModuleName, "msvcrt20") != 0 && stricmp(ModuleName, "msvcrt40") != 0) { - OpenedHandles.push_back((HMODULE)ModuleBase); + OpenedHandles->insert((HMODULE)ModuleBase); } return TRUE; } } -bool DynamicLibrary::LoadLibraryPermanently(const char *filename, - std::string *ErrMsg) { - if (filename) { - HMODULE a_handle = LoadLibrary(filename); +DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename, + std::string *errMsg) { + SmartScopedLock lock(getMutex()); - if (a_handle == 0) - return MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : "); + if (!filename) { + // When no file is specified, enumerate all DLLs and EXEs in the process. + if (OpenedHandles == 0) + OpenedHandles = new DenseSet(); - OpenedHandles.push_back(a_handle); - } else { - // When no file is specified, enumerate all DLLs and EXEs in the - // process. EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0); + // Dummy library that represents "search all handles". + // This is mostly to ensure that the return value still shows up as "valid". + return DynamicLibrary(&OpenedHandles); + } + + HMODULE a_handle = LoadLibrary(filename); + + if (a_handle == 0) { + MakeErrMsg(errMsg, std::string(filename) + ": Can't open : "); + return DynamicLibrary(); } - // Because we don't remember the handle, we will never free it; hence, - // it is loaded permanently. - return false; + if (OpenedHandles == 0) + OpenedHandles = new DenseSet(); + + // If we've already loaded this library, FreeLibrary() the handle in order to + // keep the internal refcount at +1. + if (!OpenedHandles->insert(a_handle).second) + FreeLibrary(a_handle); + + return DynamicLibrary(a_handle); } // Stack probing routines are in the support library (e.g. libgcc), but we don't @@ -101,21 +114,24 @@ bool DynamicLibrary::LoadLibraryPermanently(const char *filename, #undef EXPLICIT_SYMBOL2 void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { + SmartScopedLock Lock(getMutex()); + // First check symbols added via AddSymbol(). if (ExplicitSymbols) { - std::map::iterator I = - ExplicitSymbols->find(symbolName); - std::map::iterator E = ExplicitSymbols->end(); - if (I != E) - return I->second; + StringMap::iterator i = ExplicitSymbols->find(symbolName); + + if (i != ExplicitSymbols->end()) + return i->second; } // Now search the libraries. - for (std::vector::iterator I = OpenedHandles.begin(), - E = OpenedHandles.end(); I != E; ++I) { - FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName); - if (ptr) { - return (void *)(intptr_t)ptr; + if (OpenedHandles) { + for (DenseSet::iterator I = OpenedHandles->begin(), + E = OpenedHandles->end(); I != E; ++I) { + FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName); + if (ptr) { + return (void *)(intptr_t)ptr; + } } } @@ -134,4 +150,14 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) { return 0; } + +void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) { + if (!isValid()) + return NULL; + if (Data == &OpenedHandles) + return SearchForAddressOfSymbol(symbolName); + return (void *)(intptr_t)GetProcAddress((HMODULE)Data, symbolName); +} + + } diff --git a/lib/Support/Windows/Memory.inc b/lib/Support/Windows/Memory.inc index 9f69e7367e6f..fcc72837c456 100644 --- a/lib/Support/Windows/Memory.inc +++ b/lib/Support/Windows/Memory.inc @@ -32,11 +32,16 @@ MemoryBlock Memory::AllocateRWX(size_t NumBytes, static const size_t pageSize = Process::GetPageSize(); size_t NumPages = (NumBytes+pageSize-1)/pageSize; - //FIXME: support NearBlock if ever needed on Win64. + PVOID start = NearBlock ? static_cast(NearBlock->base()) + + NearBlock->size() : NULL; - void *pa = VirtualAlloc(NULL, NumPages*pageSize, MEM_COMMIT, + void *pa = VirtualAlloc(start, NumPages*pageSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (pa == NULL) { + if (NearBlock) { + // Try again without the NearBlock hint + return AllocateRWX(NumBytes, NULL, ErrMsg); + } MakeErrMsg(ErrMsg, "Can't allocate RWX Memory: "); return MemoryBlock(); } @@ -54,20 +59,62 @@ bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) { return false; } +static DWORD getProtection(const void *addr) { + MEMORY_BASIC_INFORMATION info; + if (sizeof(info) == ::VirtualQuery(addr, &info, sizeof(info))) { + return info.Protect; + } + return 0; +} + bool Memory::setWritable(MemoryBlock &M, std::string *ErrMsg) { + if (!setRangeWritable(M.Address, M.Size)) { + return MakeErrMsg(ErrMsg, "Cannot set memory to writeable: "); + } return true; } bool Memory::setExecutable(MemoryBlock &M, std::string *ErrMsg) { - return false; -} - -bool Memory::setRangeWritable(const void *Addr, size_t Size) { + if (!setRangeExecutable(M.Address, M.Size)) { + return MakeErrMsg(ErrMsg, "Cannot set memory to executable: "); + } return true; } +bool Memory::setRangeWritable(const void *Addr, size_t Size) { + DWORD prot = getProtection(Addr); + if (!prot) + return false; + + if (prot == PAGE_EXECUTE || prot == PAGE_EXECUTE_READ) { + prot = PAGE_EXECUTE_READWRITE; + } else if (prot == PAGE_NOACCESS || prot == PAGE_READONLY) { + prot = PAGE_READWRITE; + } + + DWORD oldProt; + sys::Memory::InvalidateInstructionCache(Addr, Size); + return ::VirtualProtect(const_cast(Addr), Size, prot, &oldProt) + == TRUE; +} + bool Memory::setRangeExecutable(const void *Addr, size_t Size) { - return false; + DWORD prot = getProtection(Addr); + if (!prot) + return false; + + if (prot == PAGE_NOACCESS) { + prot = PAGE_EXECUTE; + } else if (prot == PAGE_READONLY) { + prot = PAGE_EXECUTE_READ; + } else if (prot == PAGE_READWRITE) { + prot = PAGE_EXECUTE_READWRITE; + } + + DWORD oldProt; + sys::Memory::InvalidateInstructionCache(Addr, Size); + return ::VirtualProtect(const_cast(Addr), Size, prot, &oldProt) + == TRUE; } } diff --git a/lib/Support/Windows/PathV2.inc b/lib/Support/Windows/PathV2.inc index af71b73cd693..bc597b2dcc89 100644 --- a/lib/Support/Windows/PathV2.inc +++ b/lib/Support/Windows/PathV2.inc @@ -445,13 +445,35 @@ error_code file_size(const Twine &path, uint64_t &result) { return success; } +static bool isReservedName(StringRef path) { + // This list of reserved names comes from MSDN, at: + // http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx + static const char *sReservedNames[] = { "nul", "con", "prn", "aux", + "com1", "com2", "com3", "com4", "com5", "com6", + "com7", "com8", "com9", "lpt1", "lpt2", "lpt3", + "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9" }; + + // First, check to see if this is a device namespace, which always + // starts with \\.\, since device namespaces are not legal file paths. + if (path.startswith("\\\\.\\")) + return true; + + // Then compare against the list of ancient reserved names + for (size_t i = 0; i < sizeof(sReservedNames) / sizeof(const char *); ++i) { + if (path.equals_lower(sReservedNames[i])) + return true; + } + + // The path isn't what we consider reserved. + return false; +} + error_code status(const Twine &path, file_status &result) { SmallString<128> path_storage; SmallVector path_utf16; StringRef path8 = path.toStringRef(path_storage); - // FIXME: We should detect as many "special file name" as possible. - if (path8.compare_lower("nul") == 0) { + if (isReservedName(path8)) { result = file_status(file_type::character_file); return success; } @@ -501,7 +523,8 @@ handle_status_error: } error_code unique_file(const Twine &model, int &result_fd, - SmallVectorImpl &result_path) { + SmallVectorImpl &result_path, + bool makeAbsolute) { // Use result_path as temp storage. result_path.set_size(0); StringRef m = model.toStringRef(result_path); @@ -509,17 +532,19 @@ error_code unique_file(const Twine &model, int &result_fd, SmallVector model_utf16; if (error_code ec = UTF8ToUTF16(m, model_utf16)) return ec; - // Make model absolute by prepending a temp directory if it's not already. - bool absolute = path::is_absolute(m); - - if (!absolute) { - SmallVector temp_dir; - if (error_code ec = TempDir(temp_dir)) return ec; - // Handle c: by removing it. - if (model_utf16.size() > 2 && model_utf16[1] == L':') { - model_utf16.erase(model_utf16.begin(), model_utf16.begin() + 2); + if (makeAbsolute) { + // Make model absolute by prepending a temp directory if it's not already. + bool absolute = path::is_absolute(m); + + if (!absolute) { + SmallVector temp_dir; + if (error_code ec = TempDir(temp_dir)) return ec; + // Handle c: by removing it. + if (model_utf16.size() > 2 && model_utf16[1] == L':') { + model_utf16.erase(model_utf16.begin(), model_utf16.begin() + 2); + } + model_utf16.insert(model_utf16.begin(), temp_dir.begin(), temp_dir.end()); } - model_utf16.insert(model_utf16.begin(), temp_dir.begin(), temp_dir.end()); } // Replace '%' with random chars. From here on, DO NOT modify model. It may be diff --git a/lib/Support/Windows/Process.inc b/lib/Support/Windows/Process.inc index 06a7f0054d50..fe54eb1a7972 100644 --- a/lib/Support/Windows/Process.inc +++ b/lib/Support/Windows/Process.inc @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef __MINGW32__ #if (HAVE_LIBPSAPI != 1) @@ -219,4 +220,8 @@ const char *Process::ResetColor() { return 0; } +void Process::SetWorkingDirectory(std::string Path) { + ::_chdir(Path.c_str()); +} + } diff --git a/lib/Support/Windows/RWMutex.inc b/lib/Support/Windows/RWMutex.inc index 471f8fa294be..26b9bba9052c 100644 --- a/lib/Support/Windows/RWMutex.inc +++ b/lib/Support/Windows/RWMutex.inc @@ -18,39 +18,115 @@ #include "Windows.h" -// FIXME: Windows does not have reader-writer locks pre-Vista. If you want -// real reader-writer locks, you a threads implementation for Windows. - namespace llvm { using namespace sys; +// Windows has slim read-writer lock support on Vista and higher, so we +// will attempt to load the APIs. If they exist, we will use them, and +// if not, we will fall back on critical sections. When we drop support +// for XP, we can stop lazy-loading these APIs and just use them directly. +#if defined(__MINGW32__) + // Taken from WinNT.h + typedef struct _RTL_SRWLOCK { + PVOID Ptr; + } RTL_SRWLOCK, *PRTL_SRWLOCK; + + // Taken from WinBase.h + typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK; +#endif + +static VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL; +static VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL; +static VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL; +static VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL; +static VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL; + +static bool sHasSRW = false; + +static bool loadSRW() { + static bool sChecked = false; + if (!sChecked) { + sChecked = true; + + HMODULE hLib = ::LoadLibrary(TEXT("Kernel32")); + if (hLib) { + fpInitializeSRWLock = + (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, + "InitializeSRWLock"); + fpAcquireSRWLockExclusive = + (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, + "AcquireSRWLockExclusive"); + fpAcquireSRWLockShared = + (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, + "AcquireSRWLockShared"); + fpReleaseSRWLockExclusive = + (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, + "ReleaseSRWLockExclusive"); + fpReleaseSRWLockShared = + (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib, + "ReleaseSRWLockShared"); + ::FreeLibrary(hLib); + + if (fpInitializeSRWLock != NULL) { + sHasSRW = true; + } + } + } + return sHasSRW; +} + RWMutexImpl::RWMutexImpl() { - data_ = calloc(1, sizeof(CRITICAL_SECTION)); - InitializeCriticalSection(static_cast(data_)); + if (loadSRW()) { + data_ = calloc(1, sizeof(SRWLOCK)); + fpInitializeSRWLock(static_cast(data_)); + } else { + data_ = calloc(1, sizeof(CRITICAL_SECTION)); + InitializeCriticalSection(static_cast(data_)); + } } RWMutexImpl::~RWMutexImpl() { - DeleteCriticalSection(static_cast(data_)); - free(data_); + if (sHasSRW) { + // Nothing to do in the case of slim reader/writers + } else { + DeleteCriticalSection(static_cast(data_)); + free(data_); + } } bool RWMutexImpl::reader_acquire() { - EnterCriticalSection(static_cast(data_)); + if (sHasSRW) { + fpAcquireSRWLockShared(static_cast(data_)); + } else { + EnterCriticalSection(static_cast(data_)); + } return true; } bool RWMutexImpl::reader_release() { - LeaveCriticalSection(static_cast(data_)); + if (sHasSRW) { + fpReleaseSRWLockShared(static_cast(data_)); + } else { + LeaveCriticalSection(static_cast(data_)); + } return true; } bool RWMutexImpl::writer_acquire() { - EnterCriticalSection(static_cast(data_)); + if (sHasSRW) { + fpAcquireSRWLockExclusive(static_cast(data_)); + } else { + EnterCriticalSection(static_cast(data_)); + } return true; } bool RWMutexImpl::writer_release() { - LeaveCriticalSection(static_cast(data_)); + if (sHasSRW) { + fpReleaseSRWLockExclusive(static_cast(data_)); + } else { + LeaveCriticalSection(static_cast(data_)); + } return true; } diff --git a/lib/Support/Windows/Signals.inc b/lib/Support/Windows/Signals.inc index 14f3f21f02a1..0d4b8a26b023 100644 --- a/lib/Support/Windows/Signals.inc +++ b/lib/Support/Windows/Signals.inc @@ -23,14 +23,133 @@ #endif #include -#ifdef __MINGW32__ +#ifdef _MSC_VER + #pragma comment(lib, "psapi.lib") + #pragma comment(lib, "dbghelp.lib") +#elif __MINGW32__ #if ((HAVE_LIBIMAGEHLP != 1) || (HAVE_LIBPSAPI != 1)) #error "libimagehlp.a & libpsapi.a should be present" #endif -#else - #pragma comment(lib, "psapi.lib") - #pragma comment(lib, "dbghelp.lib") -#endif + // The version of g++ that comes with MinGW does *not* properly understand + // the ll format specifier for printf. However, MinGW passes the format + // specifiers on to the MSVCRT entirely, and the CRT understands the ll + // specifier. So these warnings are spurious in this case. Since we compile + // with -Wall, this will generate these warnings which should be ignored. So + // we will turn off the warnings for this just file. However, MinGW also does + // not support push and pop for diagnostics, so we have to manually turn it + // back on at the end of the file. + #pragma GCC diagnostic ignored "-Wformat" + #pragma GCC diagnostic ignored "-Wformat-extra-args" + + #if !defined(__MINGW64_VERSION_MAJOR) + // MinGW.org does not have updated support for the 64-bit versions of the + // DebugHlp APIs. So we will have to load them manually. The structures and + // method signatures were pulled from DbgHelp.h in the Windows Platform SDK, + // and adjusted for brevity. + typedef struct _IMAGEHLP_LINE64 { + DWORD SizeOfStruct; + PVOID Key; + DWORD LineNumber; + PCHAR FileName; + DWORD64 Address; + } IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; + + typedef struct _IMAGEHLP_SYMBOL64 { + DWORD SizeOfStruct; + DWORD64 Address; + DWORD Size; + DWORD Flags; + DWORD MaxNameLength; + CHAR Name[1]; + } IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; + + typedef struct _tagADDRESS64 { + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; + } ADDRESS64, *LPADDRESS64; + + typedef struct _KDHELP64 { + DWORD64 Thread; + DWORD ThCallbackStack; + DWORD ThCallbackBStore; + DWORD NextCallback; + DWORD FramePointer; + DWORD64 KiCallUserMode; + DWORD64 KeUserCallbackDispatcher; + DWORD64 SystemRangeStart; + DWORD64 KiUserExceptionDispatcher; + DWORD64 StackBase; + DWORD64 StackLimit; + DWORD64 Reserved[5]; + } KDHELP64, *PKDHELP64; + + typedef struct _tagSTACKFRAME64 { + ADDRESS64 AddrPC; + ADDRESS64 AddrReturn; + ADDRESS64 AddrFrame; + ADDRESS64 AddrStack; + ADDRESS64 AddrBStore; + PVOID FuncTableEntry; + DWORD64 Params[4]; + BOOL Far; + BOOL Virtual; + DWORD64 Reserved[3]; + KDHELP64 KdHelp; + } STACKFRAME64, *LPSTACKFRAME64; + +typedef BOOL (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess, + DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize, + LPDWORD lpNumberOfBytesRead); + +typedef PVOID (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( HANDLE ahProcess, + DWORD64 AddrBase); + +typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess, + DWORD64 Address); + +typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess, + HANDLE hThread, LPADDRESS64 lpaddr); + +typedef BOOL (WINAPI *fpStackWalk64)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64, + PVOID, PREAD_PROCESS_MEMORY_ROUTINE64, + PFUNCTION_TABLE_ACCESS_ROUTINE64, + PGET_MODULE_BASE_ROUTINE64, + PTRANSLATE_ADDRESS_ROUTINE64); +static fpStackWalk64 StackWalk64; + +typedef DWORD64 (WINAPI *fpSymGetModuleBase64)(HANDLE, DWORD64); +static fpSymGetModuleBase64 SymGetModuleBase64; + +typedef BOOL (WINAPI *fpSymGetSymFromAddr64)(HANDLE, DWORD64, + PDWORD64, PIMAGEHLP_SYMBOL64); +static fpSymGetSymFromAddr64 SymGetSymFromAddr64; + +typedef BOOL (WINAPI *fpSymGetLineFromAddr64)(HANDLE, DWORD64, + PDWORD, PIMAGEHLP_LINE64); +static fpSymGetLineFromAddr64 SymGetLineFromAddr64; + +typedef PVOID (WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64); +static fpSymFunctionTableAccess64 SymFunctionTableAccess64; + +static bool load64BitDebugHelp(void) { + HMODULE hLib = ::LoadLibrary("Dbghelp.dll"); + if (hLib) { + StackWalk64 = (fpStackWalk64) + ::GetProcAddress(hLib, "StackWalk64"); + SymGetModuleBase64 = (fpSymGetModuleBase64) + ::GetProcAddress(hLib, "SymGetModuleBase64"); + SymGetSymFromAddr64 = (fpSymGetSymFromAddr64) + ::GetProcAddress(hLib, "SymGetSymFromAddr64"); + SymGetLineFromAddr64 = (fpSymGetLineFromAddr64) + ::GetProcAddress(hLib, "SymGetLineFromAddr64"); + SymFunctionTableAccess64 = (fpSymFunctionTableAccess64) + ::GetProcAddress(hLib, "SymFunctionTableAccess64"); + } + return StackWalk64 != NULL; +} + #endif // !defined(__MINGW64_VERSION_MAJOR) +#endif // __MINGW32__ // Forward declare. static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep); @@ -90,6 +209,18 @@ static int CRTReportHook(int ReportType, char *Message, int *Return) { #endif static void RegisterHandler() { +#if __MINGW32__ && !defined(__MINGW64_VERSION_MAJOR) + // On MinGW.org, we need to load up the symbols explicitly, because the + // Win32 framework they include does not have support for the 64-bit + // versions of the APIs we need. If we cannot load up the APIs (which + // would be unexpected as they should exist on every version of Windows + // we support), we will bail out since there would be nothing to report. + if (!load64BitDebugHelp()) { + assert(false && "These APIs should always be available"); + return; + } +#endif + if (RegisteredUnhandledExceptionFilter) { EnterCriticalSection(&CriticalSection); return; @@ -213,20 +344,28 @@ void llvm::sys::RunInterruptHandlers() { static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) { Cleanup(); -#ifdef _WIN64 - // TODO: provide a x64 friendly version of the following -#else - // Initialize the STACKFRAME structure. - STACKFRAME StackFrame; + STACKFRAME64 StackFrame; memset(&StackFrame, 0, sizeof(StackFrame)); + DWORD machineType; +#if defined(_M_X64) + machineType = IMAGE_FILE_MACHINE_AMD64; + StackFrame.AddrPC.Offset = ep->ContextRecord->Rip; + StackFrame.AddrPC.Mode = AddrModeFlat; + StackFrame.AddrStack.Offset = ep->ContextRecord->Rsp; + StackFrame.AddrStack.Mode = AddrModeFlat; + StackFrame.AddrFrame.Offset = ep->ContextRecord->Rbp; + StackFrame.AddrFrame.Mode = AddrModeFlat; +#elif defined(_M_IX86) + machineType = IMAGE_FILE_MACHINE_I386; StackFrame.AddrPC.Offset = ep->ContextRecord->Eip; StackFrame.AddrPC.Mode = AddrModeFlat; StackFrame.AddrStack.Offset = ep->ContextRecord->Esp; StackFrame.AddrStack.Mode = AddrModeFlat; StackFrame.AddrFrame.Offset = ep->ContextRecord->Ebp; StackFrame.AddrFrame.Mode = AddrModeFlat; +#endif HANDLE hProcess = GetCurrentProcess(); HANDLE hThread = GetCurrentThread(); @@ -236,9 +375,9 @@ static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) { SymInitialize(hProcess, NULL, TRUE); while (true) { - if (!StackWalk(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame, - ep->ContextRecord, NULL, SymFunctionTableAccess, - SymGetModuleBase, NULL)) { + if (!StackWalk64(machineType, hProcess, hThread, &StackFrame, + ep->ContextRecord, NULL, SymFunctionTableAccess64, + SymGetModuleBase64, NULL)) { break; } @@ -246,54 +385,66 @@ static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) { break; // Print the PC in hexadecimal. - DWORD PC = StackFrame.AddrPC.Offset; - fprintf(stderr, "%08lX", PC); + DWORD64 PC = StackFrame.AddrPC.Offset; +#if defined(_M_X64) + fprintf(stderr, "0x%016llX", PC); +#elif defined(_M_IX86) + fprintf(stderr, "0x%08lX", static_cast(PC)); +#endif // Print the parameters. Assume there are four. +#if defined(_M_X64) + fprintf(stderr, " (0x%016llX 0x%016llX 0x%016llX 0x%016llX)", + StackFrame.Params[0], + StackFrame.Params[1], + StackFrame.Params[2], + StackFrame.Params[3]); +#elif defined(_M_IX86) fprintf(stderr, " (0x%08lX 0x%08lX 0x%08lX 0x%08lX)", - StackFrame.Params[0], - StackFrame.Params[1], StackFrame.Params[2], StackFrame.Params[3]); - + static_cast(StackFrame.Params[0]), + static_cast(StackFrame.Params[1]), + static_cast(StackFrame.Params[2]), + static_cast(StackFrame.Params[3])); +#endif // Verify the PC belongs to a module in this process. - if (!SymGetModuleBase(hProcess, PC)) { + if (!SymGetModuleBase64(hProcess, PC)) { fputs(" \n", stderr); continue; } // Print the symbol name. char buffer[512]; - IMAGEHLP_SYMBOL *symbol = reinterpret_cast(buffer); - memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL)); - symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); - symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL); + IMAGEHLP_SYMBOL64 *symbol = reinterpret_cast(buffer); + memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL64)); + symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); + symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL64); - DWORD dwDisp; - if (!SymGetSymFromAddr(hProcess, PC, &dwDisp, symbol)) { + DWORD64 dwDisp; + if (!SymGetSymFromAddr64(hProcess, PC, &dwDisp, symbol)) { fputc('\n', stderr); continue; } buffer[511] = 0; if (dwDisp > 0) - fprintf(stderr, ", %s()+%04lu bytes(s)", symbol->Name, dwDisp); + fprintf(stderr, ", %s() + 0x%llX bytes(s)", symbol->Name, dwDisp); else fprintf(stderr, ", %s", symbol->Name); // Print the source file and line number information. - IMAGEHLP_LINE line; + IMAGEHLP_LINE64 line; + DWORD dwLineDisp; memset(&line, 0, sizeof(line)); line.SizeOfStruct = sizeof(line); - if (SymGetLineFromAddr(hProcess, PC, &dwDisp, &line)) { + if (SymGetLineFromAddr64(hProcess, PC, &dwLineDisp, &line)) { fprintf(stderr, ", %s, line %lu", line.FileName, line.LineNumber); - if (dwDisp > 0) - fprintf(stderr, "+%04lu byte(s)", dwDisp); + if (dwLineDisp > 0) + fprintf(stderr, " + 0x%lX byte(s)", dwLineDisp); } fputc('\n', stderr); } -#endif - if (ExitOnUnhandledExceptions) _exit(-3); @@ -326,3 +477,12 @@ static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) { LeaveCriticalSection(&CriticalSection); return FALSE; } + +#if __MINGW32__ + // We turned these warnings off for this file so that MinGW-g++ doesn't + // complain about the ll format specifiers used. Now we are turning the + // warnings back on. If MinGW starts to support diagnostic stacks, we can + // replace this with a pop. + #pragma GCC diagnostic warning "-Wformat" + #pragma GCC diagnostic warning "-Wformat-extra-args" +#endif diff --git a/lib/Support/Windows/Windows.h b/lib/Support/Windows/Windows.h index 4a1553b599d7..67b6f015114f 100644 --- a/lib/Support/Windows/Windows.h +++ b/lib/Support/Windows/Windows.h @@ -19,9 +19,9 @@ // mingw-w64 tends to define it as 0x0502 in its headers. #undef _WIN32_WINNT -// Require at least Windows 2000 API. -#define _WIN32_WINNT 0x0500 -#define _WIN32_IE 0x0500 // MinGW at it again. +// Require at least Windows XP(5.1) API. +#define _WIN32_WINNT 0x0501 +#define _WIN32_IE 0x0600 // MinGW at it again. #define WIN32_LEAN_AND_MEAN #include "llvm/Config/config.h" // Get build system configuration settings diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index 5a71fa3d8cea..4927e9a7b9d4 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -84,7 +84,7 @@ void raw_ostream::SetBuffered() { } void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, - BufferKind Mode) { + BufferKind Mode) { assert(((Mode == Unbuffered && BufferStart == 0 && Size == 0) || (Mode != Unbuffered && BufferStart && Size)) && "stream must be unbuffered or have at least one byte"); @@ -121,7 +121,8 @@ raw_ostream &raw_ostream::operator<<(unsigned long N) { raw_ostream &raw_ostream::operator<<(long N) { if (N < 0) { *this << '-'; - N = -N; + // Avoid undefined behavior on LONG_MIN with a cast. + N = -(unsigned long)N; } return this->operator<<(static_cast(N)); @@ -284,7 +285,7 @@ raw_ostream &raw_ostream::write(unsigned char C) { raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) { // Group exceptional cases into a single branch. - if (BUILTIN_EXPECT(OutBufCur+Size > OutBufEnd, false)) { + if (BUILTIN_EXPECT(size_t(OutBufEnd - OutBufCur) < Size, false)) { if (BUILTIN_EXPECT(!OutBufStart, false)) { if (BufferMode == Unbuffered) { write_impl(Ptr, Size); diff --git a/lib/TableGen/CMakeLists.txt b/lib/TableGen/CMakeLists.txt new file mode 100644 index 000000000000..0db41346911d --- /dev/null +++ b/lib/TableGen/CMakeLists.txt @@ -0,0 +1,16 @@ +## FIXME: This only requires RTTI because tblgen uses it. Fix that. +set(LLVM_REQUIRES_RTTI 1) +set(LLVM_REQUIRES_EH 1) + +add_llvm_library(LLVMTableGen + Error.cpp + Main.cpp + Record.cpp + TableGenBackend.cpp + TGLexer.cpp + TGParser.cpp + ) + +add_llvm_library_dependencies(LLVMTableGen + LLVMSupport + ) diff --git a/utils/TableGen/Error.cpp b/lib/TableGen/Error.cpp similarity index 96% rename from utils/TableGen/Error.cpp rename to lib/TableGen/Error.cpp index 3f6cda897729..5b2cbbfec4b5 100644 --- a/utils/TableGen/Error.cpp +++ b/lib/TableGen/Error.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "Error.h" +#include "llvm/TableGen/Error.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" diff --git a/lib/TableGen/Main.cpp b/lib/TableGen/Main.cpp new file mode 100644 index 000000000000..01bc55e9898b --- /dev/null +++ b/lib/TableGen/Main.cpp @@ -0,0 +1,124 @@ +//===- Main.cpp - Top-Level TableGen implementation -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// TableGen is a tool which can be used to build up a description of something, +// then invoke one or more "tablegen backends" to emit information about the +// description in some predefined format. In practice, this is used by the LLVM +// code generators to automate generation of a code generator through a +// high-level description of the target. +// +//===----------------------------------------------------------------------===// + +#include "TGParser.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/system_error.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenAction.h" +#include +#include +using namespace llvm; + +namespace { + cl::opt + OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), + cl::init("-")); + + cl::opt + DependFilename("d", cl::desc("Dependency filename"), cl::value_desc("filename"), + cl::init("")); + + cl::opt + InputFilename(cl::Positional, cl::desc(""), cl::init("-")); + + cl::list + IncludeDirs("I", cl::desc("Directory of include files"), + cl::value_desc("directory"), cl::Prefix); +} + +namespace llvm { + +int TableGenMain(char *argv0, TableGenAction &Action) { + RecordKeeper Records; + + try { + // Parse the input file. + OwningPtr File; + if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) { + errs() << "Could not open input file '" << InputFilename << "': " + << ec.message() <<"\n"; + return 1; + } + MemoryBuffer *F = File.take(); + + // Tell SrcMgr about this buffer, which is what TGParser will pick up. + SrcMgr.AddNewSourceBuffer(F, SMLoc()); + + // Record the location of the include directory so that the lexer can find + // it later. + SrcMgr.setIncludeDirs(IncludeDirs); + + TGParser Parser(SrcMgr, Records); + + if (Parser.ParseFile()) + return 1; + + std::string Error; + tool_output_file Out(OutputFilename.c_str(), Error); + if (!Error.empty()) { + errs() << argv0 << ": error opening " << OutputFilename + << ":" << Error << "\n"; + return 1; + } + if (!DependFilename.empty()) { + if (OutputFilename == "-") { + errs() << argv0 << ": the option -d must be used together with -o\n"; + return 1; + } + tool_output_file DepOut(DependFilename.c_str(), Error); + if (!Error.empty()) { + errs() << argv0 << ": error opening " << DependFilename + << ":" << Error << "\n"; + return 1; + } + DepOut.os() << OutputFilename << ":"; + const std::vector &Dependencies = Parser.getDependencies(); + for (std::vector::const_iterator I = Dependencies.begin(), + E = Dependencies.end(); + I != E; ++I) { + DepOut.os() << " " << (*I); + } + DepOut.os() << "\n"; + DepOut.keep(); + } + + if (Action(Out.os(), Records)) + return 1; + + // Declare success. + Out.keep(); + return 0; + + } catch (const TGError &Error) { + PrintError(Error); + } catch (const std::string &Error) { + PrintError(Error); + } catch (const char *Error) { + PrintError(Error); + } catch (...) { + errs() << argv0 << ": Unknown unexpected exception occurred.\n"; + } + + return 1; +} + +} diff --git a/lib/TableGen/Makefile b/lib/TableGen/Makefile new file mode 100644 index 000000000000..44724389e1d0 --- /dev/null +++ b/lib/TableGen/Makefile @@ -0,0 +1,18 @@ +##===- lib/TableGen/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 = LLVMTableGen +BUILD_ARCHIVE = 1 + +## FIXME: This only requires RTTI because tblgen uses it. Fix that. +REQUIRES_RTTI = 1 +REQUIRES_EH = 1 + +include $(LEVEL)/Makefile.common diff --git a/utils/TableGen/Record.cpp b/lib/TableGen/Record.cpp similarity index 68% rename from utils/TableGen/Record.cpp rename to lib/TableGen/Record.cpp index 730eca1b3ca5..b7c51cae953c 100644 --- a/utils/TableGen/Record.cpp +++ b/lib/TableGen/Record.cpp @@ -11,20 +11,84 @@ // //===----------------------------------------------------------------------===// -#include "Record.h" -#include "Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/Error.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" using namespace llvm; +//===----------------------------------------------------------------------===// +// std::string wrapper for DenseMap purposes +//===----------------------------------------------------------------------===// + +/// TableGenStringKey - This is a wrapper for std::string suitable for +/// using as a key to a DenseMap. Because there isn't a particularly +/// good way to indicate tombstone or empty keys for strings, we want +/// to wrap std::string to indicate that this is a "special" string +/// not expected to take on certain values (those of the tombstone and +/// empty keys). This makes things a little safer as it clarifies +/// that DenseMap is really not appropriate for general strings. + +class TableGenStringKey { +public: + TableGenStringKey(const std::string &str) : data(str) {} + TableGenStringKey(const char *str) : data(str) {} + + const std::string &str() const { return data; } + +private: + std::string data; +}; + +/// Specialize DenseMapInfo for TableGenStringKey. +namespace llvm { + +template<> struct DenseMapInfo { + static inline TableGenStringKey getEmptyKey() { + TableGenStringKey Empty("<<>>"); + return Empty; + } + static inline TableGenStringKey getTombstoneKey() { + TableGenStringKey Tombstone("<<>>"); + return Tombstone; + } + static unsigned getHashValue(const TableGenStringKey& Val) { + return HashString(Val.str()); + } + static bool isEqual(const TableGenStringKey& LHS, + const TableGenStringKey& RHS) { + return LHS.str() == RHS.str(); + } +}; + +} + //===----------------------------------------------------------------------===// // Type implementations //===----------------------------------------------------------------------===// +BitRecTy BitRecTy::Shared; +IntRecTy IntRecTy::Shared; +StringRecTy StringRecTy::Shared; +CodeRecTy CodeRecTy::Shared; +DagRecTy DagRecTy::Shared; + void RecTy::dump() const { print(errs()); } +ListRecTy *RecTy::getListTy() { + if (!ListTy) + ListTy = new ListRecTy(this); + return ListTy; +} + Init *BitRecTy::convertValue(BitsInit *BI) { if (BI->getNumBits() != 1) return 0; // Only accept if just one bit! return BI->getBit(0); @@ -38,7 +102,7 @@ Init *BitRecTy::convertValue(IntInit *II) { int64_t Val = II->getValue(); if (Val != 0 && Val != 1) return 0; // Only accept 0 or 1 for a bit! - return new BitInit(Val != 0); + return BitInit::get(Val != 0); } Init *BitRecTy::convertValue(TypedInit *VI) { @@ -47,23 +111,32 @@ Init *BitRecTy::convertValue(TypedInit *VI) { return 0; } +BitsRecTy *BitsRecTy::get(unsigned Sz) { + static std::vector Shared; + if (Sz >= Shared.size()) + Shared.resize(Sz + 1); + BitsRecTy *&Ty = Shared[Sz]; + if (!Ty) + Ty = new BitsRecTy(Sz); + return Ty; +} + std::string BitsRecTy::getAsString() const { return "bits<" + utostr(Size) + ">"; } Init *BitsRecTy::convertValue(UnsetInit *UI) { - BitsInit *Ret = new BitsInit(Size); + SmallVector NewBits(Size); for (unsigned i = 0; i != Size; ++i) - Ret->setBit(i, new UnsetInit()); - return Ret; + NewBits[i] = UnsetInit::get(); + + return BitsInit::get(NewBits); } Init *BitsRecTy::convertValue(BitInit *UI) { if (Size != 1) return 0; // Can only convert single bit. - BitsInit *Ret = new BitsInit(1); - Ret->setBit(0, UI); - return Ret; + return BitsInit::get(UI); } /// canFitInBitfield - Return true if the number of bits is large enough to hold @@ -83,11 +156,12 @@ Init *BitsRecTy::convertValue(IntInit *II) { if (!canFitInBitfield(Value, Size)) return 0; - BitsInit *Ret = new BitsInit(Size); - for (unsigned i = 0; i != Size; ++i) - Ret->setBit(i, new BitInit(Value & (1LL << i))); + SmallVector NewBits(Size); - return Ret; + for (unsigned i = 0; i != Size; ++i) + NewBits[i] = BitInit::get(Value & (1LL << i)); + + return BitsInit::get(NewBits); } Init *BitsRecTy::convertValue(BitsInit *BI) { @@ -100,17 +174,15 @@ Init *BitsRecTy::convertValue(BitsInit *BI) { Init *BitsRecTy::convertValue(TypedInit *VI) { if (BitsRecTy *BRT = dynamic_cast(VI->getType())) if (BRT->Size == Size) { - BitsInit *Ret = new BitsInit(Size); + SmallVector NewBits(Size); + for (unsigned i = 0; i != Size; ++i) - Ret->setBit(i, new VarBitInit(VI, i)); - return Ret; + NewBits[i] = VarBitInit::get(VI, i); + return BitsInit::get(NewBits); } - if (Size == 1 && dynamic_cast(VI->getType())) { - BitsInit *Ret = new BitsInit(1); - Ret->setBit(0, VI); - return Ret; - } + if (Size == 1 && dynamic_cast(VI->getType())) + return BitsInit::get(VI); if (TernOpInit *Tern = dynamic_cast(VI)) { if (Tern->getOpcode() == TernOpInit::IF) { @@ -126,30 +198,31 @@ Init *BitsRecTy::convertValue(TypedInit *VI) { int64_t RHSVal = RHSi->getValue(); if (canFitInBitfield(MHSVal, Size) && canFitInBitfield(RHSVal, Size)) { - BitsInit *Ret = new BitsInit(Size); + SmallVector NewBits(Size); for (unsigned i = 0; i != Size; ++i) - Ret->setBit(i, new TernOpInit(TernOpInit::IF, LHS, - new IntInit((MHSVal & (1LL << i)) ? 1 : 0), - new IntInit((RHSVal & (1LL << i)) ? 1 : 0), - VI->getType())); + NewBits[i] = + TernOpInit::get(TernOpInit::IF, LHS, + IntInit::get((MHSVal & (1LL << i)) ? 1 : 0), + IntInit::get((RHSVal & (1LL << i)) ? 1 : 0), + VI->getType()); - return Ret; + return BitsInit::get(NewBits); } } else { BitsInit *MHSbs = dynamic_cast(MHS); BitsInit *RHSbs = dynamic_cast(RHS); if (MHSbs && RHSbs) { - BitsInit *Ret = new BitsInit(Size); + SmallVector NewBits(Size); for (unsigned i = 0; i != Size; ++i) - Ret->setBit(i, new TernOpInit(TernOpInit::IF, LHS, - MHSbs->getBit(i), - RHSbs->getBit(i), - VI->getType())); + NewBits[i] = TernOpInit::get(TernOpInit::IF, LHS, + MHSbs->getBit(i), + RHSbs->getBit(i), + VI->getType()); - return Ret; + return BitsInit::get(NewBits); } } } @@ -159,7 +232,7 @@ Init *BitsRecTy::convertValue(TypedInit *VI) { } Init *IntRecTy::convertValue(BitInit *BI) { - return new IntInit(BI->getValue()); + return IntInit::get(BI->getValue()); } Init *IntRecTy::convertValue(BitsInit *BI) { @@ -170,7 +243,7 @@ Init *IntRecTy::convertValue(BitsInit *BI) { } else { return 0; } - return new IntInit(Result); + return IntInit::get(Result); } Init *IntRecTy::convertValue(TypedInit *TI) { @@ -184,7 +257,7 @@ Init *StringRecTy::convertValue(UnOpInit *BO) { Init *L = BO->getOperand()->convertInitializerTo(this); if (L == 0) return 0; if (L != BO->getOperand()) - return new UnOpInit(UnOpInit::CAST, L, new StringRecTy); + return UnOpInit::get(UnOpInit::CAST, L, new StringRecTy); return BO; } @@ -197,7 +270,7 @@ Init *StringRecTy::convertValue(BinOpInit *BO) { Init *R = BO->getRHS()->convertInitializerTo(this); if (L == 0 || R == 0) return 0; if (L != BO->getLHS() || R != BO->getRHS()) - return new BinOpInit(BinOpInit::STRCONCAT, L, R, new StringRecTy); + return BinOpInit::get(BinOpInit::STRCONCAT, L, R, new StringRecTy); return BO; } @@ -231,7 +304,7 @@ Init *ListRecTy::convertValue(ListInit *LI) { return 0; } - return new ListInit(Elements, new ListRecTy(Ty)); + return ListInit::get(Elements, this); } Init *ListRecTy::convertValue(TypedInit *TI) { @@ -259,7 +332,7 @@ Init *DagRecTy::convertValue(UnOpInit *BO) { Init *L = BO->getOperand()->convertInitializerTo(this); if (L == 0) return 0; if (L != BO->getOperand()) - return new UnOpInit(UnOpInit::CAST, L, new DagRecTy); + return UnOpInit::get(UnOpInit::CAST, L, new DagRecTy); return BO; } return 0; @@ -271,12 +344,16 @@ Init *DagRecTy::convertValue(BinOpInit *BO) { Init *R = BO->getRHS()->convertInitializerTo(this); if (L == 0 || R == 0) return 0; if (L != BO->getLHS() || R != BO->getRHS()) - return new BinOpInit(BinOpInit::CONCAT, L, R, new DagRecTy); + return BinOpInit::get(BinOpInit::CONCAT, L, R, new DagRecTy); return BO; } return 0; } +RecordRecTy *RecordRecTy::get(Record *R) { + return &dynamic_cast(*R->getDefInit()->getType()); +} + std::string RecordRecTy::getAsString() const { return Rec->getName(); } @@ -326,7 +403,7 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) { iend = T1SuperClasses.end(); i != iend; ++i) { - RecordRecTy *SuperRecTy1 = new RecordRecTy(*i); + RecordRecTy *SuperRecTy1 = RecordRecTy::get(*i); RecTy *NewType1 = resolveTypes(SuperRecTy1, T2); if (NewType1 != 0) { if (NewType1 != SuperRecTy1) { @@ -345,7 +422,7 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) { iend = T2SuperClasses.end(); i != iend; ++i) { - RecordRecTy *SuperRecTy2 = new RecordRecTy(*i); + RecordRecTy *SuperRecTy2 = RecordRecTy::get(*i); RecTy *NewType2 = resolveTypes(T1, SuperRecTy2); if (NewType2 != 0) { if (NewType2 != SuperRecTy2) { @@ -369,16 +446,60 @@ RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) { void Init::dump() const { return print(errs()); } -Init *BitsInit::convertInitializerBitRange(const std::vector &Bits) { - BitsInit *BI = new BitsInit(Bits.size()); +UnsetInit *UnsetInit::get() { + static UnsetInit TheInit; + return &TheInit; +} + +BitInit *BitInit::get(bool V) { + static BitInit True(true); + static BitInit False(false); + + return V ? &True : &False; +} + +static void +ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef Range) { + ID.AddInteger(Range.size()); + + for (ArrayRef::iterator i = Range.begin(), + iend = Range.end(); + i != iend; + ++i) + ID.AddPointer(*i); +} + +BitsInit *BitsInit::get(ArrayRef Range) { + typedef FoldingSet Pool; + static Pool ThePool; + + FoldingSetNodeID ID; + ProfileBitsInit(ID, Range); + + void *IP = 0; + if (BitsInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) + return I; + + BitsInit *I = new BitsInit(Range); + ThePool.InsertNode(I, IP); + + return I; +} + +void BitsInit::Profile(FoldingSetNodeID &ID) const { + ProfileBitsInit(ID, Bits); +} + +Init * +BitsInit::convertInitializerBitRange(const std::vector &Bits) const { + SmallVector NewBits(Bits.size()); + for (unsigned i = 0, e = Bits.size(); i != e; ++i) { - if (Bits[i] >= getNumBits()) { - delete BI; + if (Bits[i] >= getNumBits()) return 0; - } - BI->setBit(i, getBit(Bits[i])); + NewBits[i] = getBit(Bits[i]); } - return BI; + return BitsInit::get(NewBits); } std::string BitsInit::getAsString() const { @@ -396,9 +517,9 @@ std::string BitsInit::getAsString() const { // resolveReferences - If there are any field references that refer to fields // that have been filled in, we can propagate the values now. // -Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) { +Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) const { bool Changed = false; - BitsInit *New = new BitsInit(getNumBits()); + SmallVector NewBits(getNumBits()); for (unsigned i = 0, e = Bits.size(); i != e; ++i) { Init *B; @@ -409,40 +530,107 @@ Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) { CurBit = CurBit->resolveReferences(R, RV); Changed |= B != CurBit; } while (B != CurBit); - New->setBit(i, CurBit); + NewBits[i] = CurBit; } if (Changed) - return New; - delete New; - return this; + return BitsInit::get(NewBits); + + return const_cast(this); +} + +IntInit *IntInit::get(int64_t V) { + typedef DenseMap Pool; + static Pool ThePool; + + IntInit *&I = ThePool[V]; + if (!I) I = new IntInit(V); + return I; } std::string IntInit::getAsString() const { return itostr(Value); } -Init *IntInit::convertInitializerBitRange(const std::vector &Bits) { - BitsInit *BI = new BitsInit(Bits.size()); +Init * +IntInit::convertInitializerBitRange(const std::vector &Bits) const { + SmallVector NewBits(Bits.size()); for (unsigned i = 0, e = Bits.size(); i != e; ++i) { - if (Bits[i] >= 64) { - delete BI; + if (Bits[i] >= 64) return 0; - } - BI->setBit(i, new BitInit(Value & (INT64_C(1) << Bits[i]))); + + NewBits[i] = BitInit::get(Value & (INT64_C(1) << Bits[i])); } - return BI; + return BitsInit::get(NewBits); } -Init *ListInit::convertInitListSlice(const std::vector &Elements) { +StringInit *StringInit::get(const std::string &V) { + typedef StringMap Pool; + static Pool ThePool; + + StringInit *&I = ThePool[V]; + if (!I) I = new StringInit(V); + return I; +} + +CodeInit *CodeInit::get(const std::string &V) { + typedef StringMap Pool; + static Pool ThePool; + + CodeInit *&I = ThePool[V]; + if (!I) I = new CodeInit(V); + return I; +} + +static void ProfileListInit(FoldingSetNodeID &ID, + ArrayRef Range, + RecTy *EltTy) { + ID.AddInteger(Range.size()); + ID.AddPointer(EltTy); + + for (ArrayRef::iterator i = Range.begin(), + iend = Range.end(); + i != iend; + ++i) + ID.AddPointer(*i); +} + +ListInit *ListInit::get(ArrayRef Range, RecTy *EltTy) { + typedef FoldingSet Pool; + static Pool ThePool; + + // Just use the FoldingSetNodeID to compute a hash. Use a DenseMap + // for actual storage. + FoldingSetNodeID ID; + ProfileListInit(ID, Range, EltTy); + + void *IP = 0; + if (ListInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) + return I; + + ListInit *I = new ListInit(Range, EltTy); + ThePool.InsertNode(I, IP); + return I; +} + +void ListInit::Profile(FoldingSetNodeID &ID) const { + ListRecTy *ListType = dynamic_cast(getType()); + assert(ListType && "Bad type for ListInit!"); + RecTy *EltTy = ListType->getElementType(); + + ProfileListInit(ID, Values, EltTy); +} + +Init * +ListInit::convertInitListSlice(const std::vector &Elements) const { std::vector Vals; for (unsigned i = 0, e = Elements.size(); i != e; ++i) { if (Elements[i] >= getSize()) return 0; Vals.push_back(getElement(Elements[i])); } - return new ListInit(Vals, getType()); + return ListInit::get(Vals, getType()); } Record *ListInit::getElementAsRecord(unsigned i) const { @@ -452,7 +640,7 @@ Record *ListInit::getElementAsRecord(unsigned i) const { return DI->getDef(); } -Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) { +Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) const { std::vector Resolved; Resolved.reserve(getSize()); bool Changed = false; @@ -470,12 +658,12 @@ Init *ListInit::resolveReferences(Record &R, const RecordVal *RV) { } if (Changed) - return new ListInit(Resolved, getType()); - return this; + return ListInit::get(Resolved, getType()); + return const_cast(this); } Init *ListInit::resolveListElementReference(Record &R, const RecordVal *IRV, - unsigned Elt) { + unsigned Elt) const { if (Elt >= getSize()) return 0; // Out of range reference. Init *E = getElement(Elt); @@ -497,7 +685,7 @@ std::string ListInit::getAsString() const { } Init *OpInit::resolveBitReference(Record &R, const RecordVal *IRV, - unsigned Bit) { + unsigned Bit) const { Init *Folded = Fold(&R, 0); if (Folded != this) { @@ -511,20 +699,41 @@ Init *OpInit::resolveBitReference(Record &R, const RecordVal *IRV, } Init *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV, - unsigned Elt) { - Init *Folded = Fold(&R, 0); + unsigned Elt) const { + Init *Resolved = resolveReferences(R, IRV); + OpInit *OResolved = dynamic_cast(Resolved); + if (OResolved) { + Resolved = OResolved->Fold(&R, 0); + } - if (Folded != this) { - TypedInit *Typed = dynamic_cast(Folded); + if (Resolved != this) { + TypedInit *Typed = dynamic_cast(Resolved); + assert(Typed && "Expected typed init for list reference"); if (Typed) { - return Typed->resolveListElementReference(R, IRV, Elt); + Init *New = Typed->resolveListElementReference(R, IRV, Elt); + if (New) + return New; + return VarListElementInit::get(Typed, Elt); } } return 0; } -Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { +UnOpInit *UnOpInit::get(UnaryOp opc, Init *lhs, RecTy *Type) { + typedef std::pair, RecTy *> Key; + + typedef DenseMap Pool; + static Pool ThePool; + + Key TheKey(std::make_pair(std::make_pair(opc, lhs), Type)); + + UnOpInit *&I = ThePool[TheKey]; + if (!I) I = new UnOpInit(opc, lhs, Type); + return I; +} + +Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { switch (getOpcode()) { default: assert(0 && "Unknown unop"); case CAST: { @@ -536,7 +745,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { DefInit *LHSd = dynamic_cast(LHS); if (LHSd) { - return new StringInit(LHSd->getDef()->getName()); + return StringInit::get(LHSd->getDef()->getName()); } } else { StringInit *LHSs = dynamic_cast(LHS); @@ -548,7 +757,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { if (const RecordVal *RV = CurRec->getValue(Name)) { if (RV->getType() != getType()) throw "type mismatch in cast"; - return new VarInit(Name, RV->getType()); + return VarInit::get(Name, RV->getType()); } std::string TemplateArgName = CurRec->getName()+":"+Name; @@ -559,7 +768,7 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { if (RV->getType() != getType()) throw "type mismatch in cast"; - return new VarInit(TemplateArgName, RV->getType()); + return VarInit::get(TemplateArgName, RV->getType()); } } @@ -572,12 +781,12 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { if (RV->getType() != getType()) throw "type mismatch in cast"; - return new VarInit(MCName, RV->getType()); + return VarInit::get(MCName, RV->getType()); } } if (Record *D = (CurRec->getRecords()).getDef(Name)) - return new DefInit(D); + return DefInit::get(D); throw TGError(CurRec->getLoc(), "Undefined reference:'" + Name + "'\n"); } @@ -602,8 +811,13 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { assert(0 && "Empty list in cdr"); return 0; } - ListInit *Result = new ListInit(LHSl->begin()+1, LHSl->end(), - LHSl->getType()); + // Note the +1. We can't just pass the result of getValues() + // directly. + ArrayRef::iterator begin = LHSl->getValues().begin()+1; + ArrayRef::iterator end = LHSl->getValues().end(); + ListInit *Result = + ListInit::get(ArrayRef(begin, end - begin), + LHSl->getType()); return Result; } break; @@ -612,31 +826,31 @@ Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { ListInit *LHSl = dynamic_cast(LHS); if (LHSl) { if (LHSl->getSize() == 0) { - return new IntInit(1); + return IntInit::get(1); } else { - return new IntInit(0); + return IntInit::get(0); } } StringInit *LHSs = dynamic_cast(LHS); if (LHSs) { if (LHSs->getValue().empty()) { - return new IntInit(1); + return IntInit::get(1); } else { - return new IntInit(0); + return IntInit::get(0); } } break; } } - return this; + return const_cast(this); } -Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) { +Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) const { Init *lhs = LHS->resolveReferences(R, RV); if (LHS != lhs) - return (new UnOpInit(getOpcode(), lhs, getType()))->Fold(&R, 0); + return (UnOpInit::get(getOpcode(), lhs, getType()))->Fold(&R, 0); return Fold(&R, 0); } @@ -651,7 +865,25 @@ std::string UnOpInit::getAsString() const { return Result + "(" + LHS->getAsString() + ")"; } -Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { +BinOpInit *BinOpInit::get(BinaryOp opc, Init *lhs, + Init *rhs, RecTy *Type) { + typedef std::pair< + std::pair, Init *>, + RecTy * + > Key; + + typedef DenseMap Pool; + static Pool ThePool; + + Key TheKey(std::make_pair(std::make_pair(std::make_pair(opc, lhs), rhs), + Type)); + + BinOpInit *&I = ThePool[TheKey]; + if (!I) I = new BinOpInit(opc, lhs, rhs, Type); + return I; +} + +Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { switch (getOpcode()) { default: assert(0 && "Unknown binop"); case CONCAT: { @@ -672,7 +904,7 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { Args.push_back(RHSs->getArg(i)); ArgNames.push_back(RHSs->getArgName(i)); } - return new DagInit(LHSs->getOperator(), "", Args, ArgNames); + return DagInit::get(LHSs->getOperator(), "", Args, ArgNames); } break; } @@ -680,26 +912,26 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { StringInit *LHSs = dynamic_cast(LHS); StringInit *RHSs = dynamic_cast(RHS); if (LHSs && RHSs) - return new StringInit(LHSs->getValue() + RHSs->getValue()); + return StringInit::get(LHSs->getValue() + RHSs->getValue()); break; } case EQ: { // try to fold eq comparison for 'bit' and 'int', otherwise fallback // to string objects. IntInit* L = - dynamic_cast(LHS->convertInitializerTo(new IntRecTy())); + dynamic_cast(LHS->convertInitializerTo(IntRecTy::get())); IntInit* R = - dynamic_cast(RHS->convertInitializerTo(new IntRecTy())); + dynamic_cast(RHS->convertInitializerTo(IntRecTy::get())); if (L && R) - return new IntInit(L->getValue() == R->getValue()); + return IntInit::get(L->getValue() == R->getValue()); StringInit *LHSs = dynamic_cast(LHS); StringInit *RHSs = dynamic_cast(RHS); // Make sure we've resolved if (LHSs && RHSs) - return new IntInit(LHSs->getValue() == RHSs->getValue()); + return IntInit::get(LHSs->getValue() == RHSs->getValue()); break; } @@ -717,20 +949,20 @@ Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { case SRA: Result = LHSv >> RHSv; break; case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break; } - return new IntInit(Result); + return IntInit::get(Result); } break; } } - return this; + return const_cast(this); } -Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) { +Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) const { Init *lhs = LHS->resolveReferences(R, RV); Init *rhs = RHS->resolveReferences(R, RV); if (LHS != lhs || RHS != rhs) - return (new BinOpInit(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0); + return (BinOpInit::get(getOpcode(), lhs, rhs, getType()))->Fold(&R, 0); return Fold(&R, 0); } @@ -747,6 +979,31 @@ std::string BinOpInit::getAsString() const { return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")"; } +TernOpInit *TernOpInit::get(TernaryOp opc, Init *lhs, + Init *mhs, Init *rhs, + RecTy *Type) { + typedef std::pair< + std::pair< + std::pair, Init *>, + Init * + >, + Init * + > Key; + + typedef DenseMap Pool; + static Pool ThePool; + + Key TheKey(std::make_pair(std::make_pair(std::make_pair(std::make_pair(opc, + Type), + lhs), + mhs), + rhs)); + + TernOpInit *&I = ThePool[TheKey]; + if (!I) I = new TernOpInit(opc, lhs, mhs, rhs, Type); + return I; +} + static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, Record *CurRec, MultiClass *CurMultiClass); @@ -787,12 +1044,11 @@ static Init *EvaluateOperation(OpInit *RHSo, Init *LHS, Init *Arg, } // Now run the operator and use its result as the new leaf - OpInit *NewOp = RHSo->clone(NewOperands); + const OpInit *NewOp = RHSo->clone(NewOperands); Init *NewVal = NewOp->Fold(CurRec, CurMultiClass); - if (NewVal != NewOp) { - delete NewOp; + if (NewVal != NewOp) return NewVal; - } + return 0; } @@ -843,13 +1099,13 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, args.push_back(std::make_pair(Arg, ArgName)); } - return new DagInit(Val, "", args); + return DagInit::get(Val, "", args); } if (MHSl) { std::vector NewOperands; std::vector NewList(MHSl->begin(), MHSl->end()); - for (ListInit::iterator li = NewList.begin(), + for (std::vector::iterator li = NewList.begin(), liend = NewList.end(); li != liend; ++li) { @@ -865,20 +1121,18 @@ static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type, } // Now run the operator and use its result as the new list item - OpInit *NewOp = RHSo->clone(NewOperands); + const OpInit *NewOp = RHSo->clone(NewOperands); Init *NewItem = NewOp->Fold(CurRec, CurMultiClass); - if (NewItem != NewOp) { + if (NewItem != NewOp) *li = NewItem; - delete NewOp; - } } - return new ListInit(NewList, MHSl->getType()); + return ListInit::get(NewList, MHSl->getType()); } } return 0; } -Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { +Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const { switch (getOpcode()) { default: assert(0 && "Unknown binop"); case SUBST: { @@ -902,14 +1156,14 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { if (LHSd->getAsString() == RHSd->getAsString()) { Val = MHSd->getDef(); } - return new DefInit(Val); + return DefInit::get(Val); } if (RHSv) { std::string Val = RHSv->getName(); if (LHSv->getAsString() == RHSv->getAsString()) { Val = MHSv->getName(); } - return new VarInit(Val, getType()); + return VarInit::get(Val, getType()); } if (RHSs) { std::string Val = RHSs->getValue(); @@ -924,7 +1178,7 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { idx = found + MHSs->getValue().size(); } while (found != std::string::npos); - return new StringInit(Val); + return StringInit::get(Val); } } break; @@ -941,7 +1195,7 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { case IF: { IntInit *LHSi = dynamic_cast(LHS); - if (Init *I = LHS->convertInitializerTo(new IntRecTy())) + if (Init *I = LHS->convertInitializerTo(IntRecTy::get())) LHSi = dynamic_cast(I); if (LHSi) { if (LHSi->getValue()) { @@ -954,26 +1208,27 @@ Init *TernOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) { } } - return this; + return const_cast(this); } -Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) { +Init *TernOpInit::resolveReferences(Record &R, + const RecordVal *RV) const { Init *lhs = LHS->resolveReferences(R, RV); if (Opc == IF && lhs != LHS) { IntInit *Value = dynamic_cast(lhs); - if (Init *I = lhs->convertInitializerTo(new IntRecTy())) + if (Init *I = lhs->convertInitializerTo(IntRecTy::get())) Value = dynamic_cast(I); if (Value != 0) { // Short-circuit if (Value->getValue()) { Init *mhs = MHS->resolveReferences(R, RV); - return (new TernOpInit(getOpcode(), lhs, mhs, - RHS, getType()))->Fold(&R, 0); + return (TernOpInit::get(getOpcode(), lhs, mhs, + RHS, getType()))->Fold(&R, 0); } else { Init *rhs = RHS->resolveReferences(R, RV); - return (new TernOpInit(getOpcode(), lhs, MHS, - rhs, getType()))->Fold(&R, 0); + return (TernOpInit::get(getOpcode(), lhs, MHS, + rhs, getType()))->Fold(&R, 0); } } } @@ -982,7 +1237,8 @@ Init *TernOpInit::resolveReferences(Record &R, const RecordVal *RV) { Init *rhs = RHS->resolveReferences(R, RV); if (LHS != lhs || MHS != mhs || RHS != rhs) - return (new TernOpInit(getOpcode(), lhs, mhs, rhs, getType()))->Fold(&R, 0); + return (TernOpInit::get(getOpcode(), lhs, mhs, rhs, + getType()))->Fold(&R, 0); return Fold(&R, 0); } @@ -1008,39 +1264,53 @@ RecTy *TypedInit::getFieldType(const std::string &FieldName) const { return 0; } -Init *TypedInit::convertInitializerBitRange(const std::vector &Bits) { +Init * +TypedInit::convertInitializerBitRange(const std::vector &Bits) const { BitsRecTy *T = dynamic_cast(getType()); if (T == 0) return 0; // Cannot subscript a non-bits variable. unsigned NumBits = T->getNumBits(); - BitsInit *BI = new BitsInit(Bits.size()); + SmallVector NewBits(Bits.size()); for (unsigned i = 0, e = Bits.size(); i != e; ++i) { - if (Bits[i] >= NumBits) { - delete BI; + if (Bits[i] >= NumBits) return 0; - } - BI->setBit(i, new VarBitInit(this, Bits[i])); + + NewBits[i] = VarBitInit::get(const_cast(this), Bits[i]); } - return BI; + return BitsInit::get(NewBits); } -Init *TypedInit::convertInitListSlice(const std::vector &Elements) { +Init * +TypedInit::convertInitListSlice(const std::vector &Elements) const { ListRecTy *T = dynamic_cast(getType()); if (T == 0) return 0; // Cannot subscript a non-list variable. if (Elements.size() == 1) - return new VarListElementInit(this, Elements[0]); + return VarListElementInit::get(const_cast(this), Elements[0]); std::vector ListInits; ListInits.reserve(Elements.size()); for (unsigned i = 0, e = Elements.size(); i != e; ++i) - ListInits.push_back(new VarListElementInit(this, Elements[i])); - return new ListInit(ListInits, T); + ListInits.push_back(VarListElementInit::get(const_cast(this), + Elements[i])); + return ListInit::get(ListInits, T); } +VarInit *VarInit::get(const std::string &VN, RecTy *T) { + typedef std::pair Key; + typedef DenseMap Pool; + static Pool ThePool; + + Key TheKey(std::make_pair(T, VN)); + + VarInit *&I = ThePool[TheKey]; + if (!I) I = new VarInit(VN, T); + return I; +} + Init *VarInit::resolveBitReference(Record &R, const RecordVal *IRV, - unsigned Bit) { + unsigned Bit) const { if (R.isTemplateArg(getName())) return 0; if (IRV && IRV->getName() != getName()) return 0; @@ -1060,8 +1330,9 @@ Init *VarInit::resolveBitReference(Record &R, const RecordVal *IRV, return 0; } -Init *VarInit::resolveListElementReference(Record &R, const RecordVal *IRV, - unsigned Elt) { +Init *VarInit::resolveListElementReference(Record &R, + const RecordVal *IRV, + unsigned Elt) const { if (R.isTemplateArg(getName())) return 0; if (IRV && IRV->getName() != getName()) return 0; @@ -1069,9 +1340,9 @@ Init *VarInit::resolveListElementReference(Record &R, const RecordVal *IRV, assert(RV && "Reference to a non-existent variable?"); ListInit *LI = dynamic_cast(RV->getValue()); if (!LI) { - VarInit *VI = dynamic_cast(RV->getValue()); + TypedInit *VI = dynamic_cast(RV->getValue()); assert(VI && "Invalid list element!"); - return new VarListElementInit(VI, Elt); + return VarListElementInit::get(VI, Elt); } if (Elt >= LI->getSize()) @@ -1114,48 +1385,91 @@ Init *VarInit::getFieldInit(Record &R, const RecordVal *RV, /// If a value is set for the variable later, this method will be called on /// users of the value to allow the value to propagate out. /// -Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) { +Init *VarInit::resolveReferences(Record &R, const RecordVal *RV) const { if (RecordVal *Val = R.getValue(VarName)) if (RV == Val || (RV == 0 && !dynamic_cast(Val->getValue()))) return Val->getValue(); - return this; + return const_cast(this); +} + +VarBitInit *VarBitInit::get(TypedInit *T, unsigned B) { + typedef std::pair Key; + typedef DenseMap Pool; + + static Pool ThePool; + + Key TheKey(std::make_pair(T, B)); + + VarBitInit *&I = ThePool[TheKey]; + if (!I) I = new VarBitInit(T, B); + return I; } std::string VarBitInit::getAsString() const { return TI->getAsString() + "{" + utostr(Bit) + "}"; } -Init *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) { +Init *VarBitInit::resolveReferences(Record &R, const RecordVal *RV) const { if (Init *I = getVariable()->resolveBitReference(R, RV, getBitNum())) return I; - return this; + return const_cast(this); +} + +VarListElementInit *VarListElementInit::get(TypedInit *T, + unsigned E) { + typedef std::pair Key; + typedef DenseMap Pool; + + static Pool ThePool; + + Key TheKey(std::make_pair(T, E)); + + VarListElementInit *&I = ThePool[TheKey]; + if (!I) I = new VarListElementInit(T, E); + return I; } std::string VarListElementInit::getAsString() const { return TI->getAsString() + "[" + utostr(Element) + "]"; } -Init *VarListElementInit::resolveReferences(Record &R, const RecordVal *RV) { +Init * +VarListElementInit::resolveReferences(Record &R, const RecordVal *RV) const { if (Init *I = getVariable()->resolveListElementReference(R, RV, getElementNum())) return I; - return this; + return const_cast(this); } Init *VarListElementInit::resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) { + unsigned Bit) const { // FIXME: This should be implemented, to support references like: // bit B = AA[0]{1}; return 0; } -Init *VarListElementInit:: -resolveListElementReference(Record &R, const RecordVal *RV, unsigned Elt) { - // FIXME: This should be implemented, to support references like: - // int B = AA[0][1]; +Init *VarListElementInit:: resolveListElementReference(Record &R, + const RecordVal *RV, + unsigned Elt) const { + Init *Result = TI->resolveListElementReference(R, RV, Element); + + if (Result) { + TypedInit *TInit = dynamic_cast(Result); + if (TInit) { + Init *Result2 = TInit->resolveListElementReference(R, RV, Elt); + if (Result2) return Result2; + return new VarListElementInit(TInit, Elt); + } + return Result; + } + return 0; } +DefInit *DefInit::get(Record *R) { + return R->getDefInit(); +} + RecTy *DefInit::getFieldType(const std::string &FieldName) const { if (const RecordVal *RV = Def->getValue(FieldName)) return RV->getType(); @@ -1172,8 +1486,20 @@ std::string DefInit::getAsString() const { return Def->getName(); } +FieldInit *FieldInit::get(Init *R, const std::string &FN) { + typedef std::pair Key; + typedef DenseMap Pool; + static Pool ThePool; + + Key TheKey(std::make_pair(R, FN)); + + FieldInit *&I = ThePool[TheKey]; + if (!I) I = new FieldInit(R, FN); + return I; +} + Init *FieldInit::resolveBitReference(Record &R, const RecordVal *RV, - unsigned Bit) { + unsigned Bit) const { if (Init *BitsVal = Rec->getFieldInit(R, RV, FieldName)) if (BitsInit *BI = dynamic_cast(BitsVal)) { assert(Bit < BI->getNumBits() && "Bit reference out of range!"); @@ -1186,7 +1512,7 @@ Init *FieldInit::resolveBitReference(Record &R, const RecordVal *RV, } Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV, - unsigned Elt) { + unsigned Elt) const { if (Init *ListVal = Rec->getFieldInit(R, RV, FieldName)) if (ListInit *LI = dynamic_cast(ListVal)) { if (Elt >= LI->getSize()) return 0; @@ -1201,22 +1527,83 @@ Init *FieldInit::resolveListElementReference(Record &R, const RecordVal *RV, return 0; } -Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) { +Init *FieldInit::resolveReferences(Record &R, const RecordVal *RV) const { Init *NewRec = RV ? Rec->resolveReferences(R, RV) : Rec; Init *BitsVal = NewRec->getFieldInit(R, RV, FieldName); if (BitsVal) { Init *BVR = BitsVal->resolveReferences(R, RV); - return BVR->isComplete() ? BVR : this; + return BVR->isComplete() ? BVR : const_cast(this); } if (NewRec != Rec) { - return new FieldInit(NewRec, FieldName); + return FieldInit::get(NewRec, FieldName); } - return this; + return const_cast(this); } -Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) { +void ProfileDagInit(FoldingSetNodeID &ID, + Init *V, + const std::string &VN, + ArrayRef ArgRange, + ArrayRef NameRange) { + ID.AddPointer(V); + ID.AddString(VN); + + ArrayRef::iterator Arg = ArgRange.begin(); + ArrayRef::iterator Name = NameRange.begin(); + while (Arg != ArgRange.end()) { + assert(Name != NameRange.end() && "Arg name underflow!"); + ID.AddPointer(*Arg++); + ID.AddString(*Name++); + } + assert(Name == NameRange.end() && "Arg name overflow!"); +} + +DagInit * +DagInit::get(Init *V, const std::string &VN, + ArrayRef ArgRange, + ArrayRef NameRange) { + typedef FoldingSet Pool; + static Pool ThePool; + + FoldingSetNodeID ID; + ProfileDagInit(ID, V, VN, ArgRange, NameRange); + + void *IP = 0; + if (DagInit *I = ThePool.FindNodeOrInsertPos(ID, IP)) + return I; + + DagInit *I = new DagInit(V, VN, ArgRange, NameRange); + ThePool.InsertNode(I, IP); + + return I; +} + +DagInit * +DagInit::get(Init *V, const std::string &VN, + const std::vector > &args) { + typedef std::pair PairType; + + std::vector Args; + std::vector Names; + + for (std::vector::const_iterator i = args.begin(), + iend = args.end(); + i != iend; + ++i) { + Args.push_back(i->first); + Names.push_back(i->second); + } + + return DagInit::get(V, VN, Args, Names); +} + +void DagInit::Profile(FoldingSetNodeID &ID) const { + ProfileDagInit(ID, Val, ValName, Args, ArgNames); +} + +Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) const { std::vector NewArgs; for (unsigned i = 0, e = Args.size(); i != e; ++i) NewArgs.push_back(Args[i]->resolveReferences(R, RV)); @@ -1224,9 +1611,9 @@ Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) { Init *Op = Val->resolveReferences(R, RV); if (Args != NewArgs || Op != Val) - return new DagInit(Op, ValName, NewArgs, ArgNames); + return DagInit::get(Op, ValName, NewArgs, ArgNames); - return this; + return const_cast(this); } @@ -1250,12 +1637,24 @@ std::string DagInit::getAsString() const { // Other implementations //===----------------------------------------------------------------------===// -RecordVal::RecordVal(const std::string &N, RecTy *T, unsigned P) +RecordVal::RecordVal(Init *N, RecTy *T, unsigned P) : Name(N), Ty(T), Prefix(P) { - Value = Ty->convertValue(new UnsetInit()); + Value = Ty->convertValue(UnsetInit::get()); assert(Value && "Cannot create unset value for current type!"); } +RecordVal::RecordVal(const std::string &N, RecTy *T, unsigned P) + : Name(StringInit::get(N)), Ty(T), Prefix(P) { + Value = Ty->convertValue(UnsetInit::get()); + assert(Value && "Cannot create unset value for current type!"); +} + +const std::string &RecordVal::getName() const { + StringInit *NameString = dynamic_cast(Name); + assert(NameString && "RecordVal name is not a string!"); + return NameString->getValue(); +} + void RecordVal::dump() const { errs() << *this; } void RecordVal::print(raw_ostream &OS, bool PrintSem) const { @@ -1270,16 +1669,61 @@ void RecordVal::print(raw_ostream &OS, bool PrintSem) const { unsigned Record::LastID = 0; -void Record::setName(const std::string &Name) { - if (TrackedRecords.getDef(getName()) == this) { - TrackedRecords.removeDef(getName()); - this->Name = Name; +void Record::checkName() { + // Ensure the record name has string type. + const TypedInit *TypedName = dynamic_cast(Name); + assert(TypedName && "Record name is not typed!"); + RecTy *Type = TypedName->getType(); + if (dynamic_cast(Type) == 0) { + llvm_unreachable("Record name is not a string!"); + } +} + +DefInit *Record::getDefInit() { + if (!TheInit) + TheInit = new DefInit(this, new RecordRecTy(this)); + return TheInit; +} + +const std::string &Record::getName() const { + const StringInit *NameString = + dynamic_cast(Name); + assert(NameString && "Record name is not a string!"); + return NameString->getValue(); +} + +void Record::setName(Init *NewName) { + if (TrackedRecords.getDef(Name->getAsUnquotedString()) == this) { + TrackedRecords.removeDef(Name->getAsUnquotedString()); + Name = NewName; TrackedRecords.addDef(this); } else { - TrackedRecords.removeClass(getName()); - this->Name = Name; + TrackedRecords.removeClass(Name->getAsUnquotedString()); + Name = NewName; TrackedRecords.addClass(this); } + checkName(); + // Since the Init for the name was changed, see if we can resolve + // any of it using members of the Record. + Init *ComputedName = Name->resolveReferences(*this, 0); + if (ComputedName != Name) { + setName(ComputedName); + } + // DO NOT resolve record values to the name at this point because + // there might be default values for arguments of this def. Those + // arguments might not have been resolved yet so we don't want to + // prematurely assume values for those arguments were not passed to + // this def. + // + // Nonetheless, it may be that some of this Record's values + // reference the record name. Indeed, the reason for having the + // record name be an Init is to provide this flexibility. The extra + // resolve steps after completely instantiating defs takes care of + // this. See TGParser::ParseDef and TGParser::ParseDefm. +} + +void Record::setName(const std::string &Name) { + setName(StringInit::get(Name)); } /// resolveReferencesTo - If anything in this record refers to RV, replace the @@ -1351,7 +1795,7 @@ std::string Record::getValueAsString(StringRef FieldName) const { throw "Record `" + getName() + "' does not have a field named `" + FieldName.str() + "'!\n"; - if (const StringInit *SI = dynamic_cast(R->getValue())) + if (StringInit *SI = dynamic_cast(R->getValue())) return SI->getValue(); throw "Record `" + getName() + "', field `" + FieldName.str() + "' does not have a string initializer!"; @@ -1516,7 +1960,7 @@ std::string Record::getValueAsCode(StringRef FieldName) const { throw "Record `" + getName() + "' does not have a field named `" + FieldName.str() + "'!\n"; - if (const CodeInit *CI = dynamic_cast(R->getValue())) + if (CodeInit *CI = dynamic_cast(R->getValue())) return CI->getValue(); throw "Record `" + getName() + "', field `" + FieldName.str() + "' does not have a code initializer!"; diff --git a/utils/TableGen/TGLexer.cpp b/lib/TableGen/TGLexer.cpp similarity index 90% rename from utils/TableGen/TGLexer.cpp rename to lib/TableGen/TGLexer.cpp index b4b90ff64eb6..8c1b4290548d 100644 --- a/utils/TableGen/TGLexer.cpp +++ b/lib/TableGen/TGLexer.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "TGLexer.h" -#include "Error.h" +#include "llvm/TableGen/Error.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Config/config.h" @@ -208,40 +208,40 @@ tgtok::TokKind TGLexer::LexVarName() { tgtok::TokKind TGLexer::LexIdentifier() { // The first letter is [a-zA-Z_#]. const char *IdentStart = TokStart; - + // Match the rest of the identifier regex: [0-9a-zA-Z_#]* while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_' || *CurPtr == '#') ++CurPtr; - - + // Check to see if this identifier is a keyword. - unsigned Len = CurPtr-IdentStart; - - if (Len == 3 && !memcmp(IdentStart, "int", 3)) return tgtok::Int; - if (Len == 3 && !memcmp(IdentStart, "bit", 3)) return tgtok::Bit; - if (Len == 4 && !memcmp(IdentStart, "bits", 4)) return tgtok::Bits; - if (Len == 6 && !memcmp(IdentStart, "string", 6)) return tgtok::String; - if (Len == 4 && !memcmp(IdentStart, "list", 4)) return tgtok::List; - if (Len == 4 && !memcmp(IdentStart, "code", 4)) return tgtok::Code; - if (Len == 3 && !memcmp(IdentStart, "dag", 3)) return tgtok::Dag; - - if (Len == 5 && !memcmp(IdentStart, "class", 5)) return tgtok::Class; - if (Len == 3 && !memcmp(IdentStart, "def", 3)) return tgtok::Def; - if (Len == 4 && !memcmp(IdentStart, "defm", 4)) return tgtok::Defm; - if (Len == 10 && !memcmp(IdentStart, "multiclass", 10)) - return tgtok::MultiClass; - if (Len == 5 && !memcmp(IdentStart, "field", 5)) return tgtok::Field; - if (Len == 3 && !memcmp(IdentStart, "let", 3)) return tgtok::Let; - if (Len == 2 && !memcmp(IdentStart, "in", 2)) return tgtok::In; - - if (Len == 7 && !memcmp(IdentStart, "include", 7)) { + StringRef Str(IdentStart, CurPtr-IdentStart); + + if (Str == "include") { if (LexInclude()) return tgtok::Error; return Lex(); } - - CurStrVal.assign(IdentStart, CurPtr); - return tgtok::Id; + + tgtok::TokKind Kind = StringSwitch(Str) + .Case("int", tgtok::Int) + .Case("bit", tgtok::Bit) + .Case("bits", tgtok::Bits) + .Case("string", tgtok::String) + .Case("list", tgtok::List) + .Case("code", tgtok::Code) + .Case("dag", tgtok::Dag) + .Case("class", tgtok::Class) + .Case("def", tgtok::Def) + .Case("defm", tgtok::Defm) + .Case("multiclass", tgtok::MultiClass) + .Case("field", tgtok::Field) + .Case("let", tgtok::Let) + .Case("in", tgtok::In) + .Default(tgtok::Id); + + if (Kind == tgtok::Id) + CurStrVal.assign(Str.begin(), Str.end()); + return Kind; } /// LexInclude - We just read the "include" token. Get the string token that diff --git a/utils/TableGen/TGLexer.h b/lib/TableGen/TGLexer.h similarity index 100% rename from utils/TableGen/TGLexer.h rename to lib/TableGen/TGLexer.h diff --git a/utils/TableGen/TGParser.cpp b/lib/TableGen/TGParser.cpp similarity index 88% rename from utils/TableGen/TGParser.cpp rename to lib/TableGen/TGParser.cpp index 59097f986f79..e7f00baf4931 100644 --- a/utils/TableGen/TGParser.cpp +++ b/lib/TableGen/TGParser.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "TGParser.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include #include @@ -106,9 +106,9 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const std::string &ValName, return Error(Loc, "Value '" + ValName + "' is not a bits type"); // Convert the incoming value to a bits type of the appropriate size... - Init *BI = V->convertInitializerTo(new BitsRecTy(BitList.size())); + Init *BI = V->convertInitializerTo(BitsRecTy::get(BitList.size())); if (BI == 0) { - V->convertInitializerTo(new BitsRecTy(BitList.size())); + V->convertInitializerTo(BitsRecTy::get(BitList.size())); return Error(Loc, "Initializer is not compatible with bit range"); } @@ -116,22 +116,22 @@ bool TGParser::SetValue(Record *CurRec, SMLoc Loc, const std::string &ValName, BitsInit *BInit = dynamic_cast(BI); assert(BInit != 0); - BitsInit *NewVal = new BitsInit(CurVal->getNumBits()); + SmallVector NewBits(CurVal->getNumBits()); // Loop over bits, assigning values as appropriate. for (unsigned i = 0, e = BitList.size(); i != e; ++i) { unsigned Bit = BitList[i]; - if (NewVal->getBit(Bit)) + if (NewBits[Bit]) return Error(Loc, "Cannot set bit #" + utostr(Bit) + " of value '" + ValName + "' more than once"); - NewVal->setBit(Bit, BInit->getBit(i)); + NewBits[Bit] = BInit->getBit(i); } for (unsigned i = 0, e = CurVal->getNumBits(); i != e; ++i) - if (NewVal->getBit(i) == 0) - NewVal->setBit(i, CurVal->getBit(i)); + if (NewBits[i] == 0) + NewBits[i] = CurVal->getBit(i); - V = NewVal; + V = BitsInit::get(NewBits); } if (RV->setValue(V)) @@ -581,13 +581,13 @@ bool TGParser::ParseOptionalBitList(std::vector &Ranges) { RecTy *TGParser::ParseType() { switch (Lex.getCode()) { default: TokError("Unknown token when expecting a type"); return 0; - case tgtok::String: Lex.Lex(); return new StringRecTy(); - case tgtok::Bit: Lex.Lex(); return new BitRecTy(); - case tgtok::Int: Lex.Lex(); return new IntRecTy(); - case tgtok::Code: Lex.Lex(); return new CodeRecTy(); - case tgtok::Dag: Lex.Lex(); return new DagRecTy(); + case tgtok::String: Lex.Lex(); return StringRecTy::get(); + case tgtok::Bit: Lex.Lex(); return BitRecTy::get(); + case tgtok::Int: Lex.Lex(); return IntRecTy::get(); + case tgtok::Code: Lex.Lex(); return CodeRecTy::get(); + case tgtok::Dag: Lex.Lex(); return DagRecTy::get(); case tgtok::Id: - if (Record *R = ParseClassID()) return new RecordRecTy(R); + if (Record *R = ParseClassID()) return RecordRecTy::get(R); return 0; case tgtok::Bits: { if (Lex.Lex() != tgtok::less) { // Eat 'bits' @@ -604,7 +604,7 @@ RecTy *TGParser::ParseType() { return 0; } Lex.Lex(); // Eat '>' - return new BitsRecTy(Val); + return BitsRecTy::get(Val); } case tgtok::List: { if (Lex.Lex() != tgtok::less) { // Eat 'bits' @@ -620,7 +620,7 @@ RecTy *TGParser::ParseType() { return 0; } Lex.Lex(); // Eat '>' - return new ListRecTy(SubType); + return ListRecTy::get(SubType); } } } @@ -647,13 +647,16 @@ Init *TGParser::ParseIDValue(Record *CurRec, const std::string &Name, SMLoc NameLoc) { if (CurRec) { if (const RecordVal *RV = CurRec->getValue(Name)) - return new VarInit(Name, RV->getType()); + return VarInit::get(Name, RV->getType()); std::string TemplateArgName = CurRec->getName()+":"+Name; + if (CurMultiClass) + TemplateArgName = CurMultiClass->Rec.getName()+"::"+TemplateArgName; + if (CurRec->isTemplateArg(TemplateArgName)) { const RecordVal *RV = CurRec->getValue(TemplateArgName); assert(RV && "Template arg doesn't exist??"); - return new VarInit(TemplateArgName, RV->getType()); + return VarInit::get(TemplateArgName, RV->getType()); } } @@ -662,12 +665,12 @@ Init *TGParser::ParseIDValue(Record *CurRec, if (CurMultiClass->Rec.isTemplateArg(MCName)) { const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); assert(RV && "Template arg doesn't exist??"); - return new VarInit(MCName, RV->getType()); + return VarInit::get(MCName, RV->getType()); } } if (Record *D = Records.getDef(Name)) - return new DefInit(D); + return DefInit::get(D); Error(NameLoc, "Variable not defined: '" + Name + "'"); return 0; @@ -715,7 +718,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { case tgtok::XEmpty: Lex.Lex(); // eat the operation Code = UnOpInit::EMPTY; - Type = new IntRecTy; + Type = IntRecTy::get(); break; } if (Lex.getCode() != tgtok::l_paren) { @@ -767,7 +770,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { if (Code == UnOpInit::HEAD) { Type = Itemt->getType(); } else { - Type = new ListRecTy(Itemt->getType()); + Type = ListRecTy::get(Itemt->getType()); } } else { assert(LHSt && "expected list type argument in unary operator"); @@ -790,7 +793,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { return 0; } Lex.Lex(); // eat the ')' - return (new UnOpInit(Code, LHS, Type))->Fold(CurRec, CurMultiClass); + return (UnOpInit::get(Code, LHS, Type))->Fold(CurRec, CurMultiClass); } case tgtok::XConcat: @@ -808,14 +811,14 @@ Init *TGParser::ParseOperation(Record *CurRec) { switch (OpTok) { default: assert(0 && "Unhandled code!"); - case tgtok::XConcat: Code = BinOpInit::CONCAT; Type = new DagRecTy(); break; - case tgtok::XSRA: Code = BinOpInit::SRA; Type = new IntRecTy(); break; - case tgtok::XSRL: Code = BinOpInit::SRL; Type = new IntRecTy(); break; - case tgtok::XSHL: Code = BinOpInit::SHL; Type = new IntRecTy(); break; - case tgtok::XEq: Code = BinOpInit::EQ; Type = new BitRecTy(); break; + case tgtok::XConcat: Code = BinOpInit::CONCAT;Type = DagRecTy::get(); break; + case tgtok::XSRA: Code = BinOpInit::SRA; Type = IntRecTy::get(); break; + case tgtok::XSRL: Code = BinOpInit::SRL; Type = IntRecTy::get(); break; + case tgtok::XSHL: Code = BinOpInit::SHL; Type = IntRecTy::get(); break; + case tgtok::XEq: Code = BinOpInit::EQ; Type = BitRecTy::get(); break; case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; - Type = new StringRecTy(); + Type = StringRecTy::get(); break; } @@ -848,14 +851,14 @@ Init *TGParser::ParseOperation(Record *CurRec) { if (Code == BinOpInit::STRCONCAT) { while (InitList.size() > 2) { Init *RHS = InitList.pop_back_val(); - RHS = (new BinOpInit(Code, InitList.back(), RHS, Type)) - ->Fold(CurRec, CurMultiClass); + RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type)) + ->Fold(CurRec, CurMultiClass); InitList.back() = RHS; } } if (InitList.size() == 2) - return (new BinOpInit(Code, InitList[0], InitList[1], Type)) + return (BinOpInit::get(Code, InitList[0], InitList[1], Type)) ->Fold(CurRec, CurMultiClass); Error(OpLoc, "expected two operands to operator"); @@ -932,14 +935,14 @@ Init *TGParser::ParseOperation(Record *CurRec) { if (MHSbits && RHSbits && MHSbits->getNumBits() == RHSbits->getNumBits()) { - Type = new BitRecTy(); + Type = BitRecTy::get(); break; } else { BitInit *MHSbit = dynamic_cast(MHS); BitInit *RHSbit = dynamic_cast(RHS); if (MHSbit && RHSbit) { - Type = new BitRecTy(); + Type = BitRecTy::get(); break; } } @@ -982,7 +985,7 @@ Init *TGParser::ParseOperation(Record *CurRec) { break; } } - return (new TernOpInit(Code, LHS, MHS, RHS, Type))->Fold(CurRec, + return (TernOpInit::get(Code, LHS, MHS, RHS, Type))->Fold(CurRec, CurMultiClass); } } @@ -1042,7 +1045,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { Init *R = 0; switch (Lex.getCode()) { default: TokError("Unknown token when parsing a value"); break; - case tgtok::IntVal: R = new IntInit(Lex.getCurIntVal()); Lex.Lex(); break; + case tgtok::IntVal: R = IntInit::get(Lex.getCurIntVal()); Lex.Lex(); break; case tgtok::StrVal: { std::string Val = Lex.getCurStrVal(); Lex.Lex(); @@ -1053,15 +1056,15 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { Lex.Lex(); } - R = new StringInit(Val); + R = StringInit::get(Val); break; } case tgtok::CodeFragment: - R = new CodeInit(Lex.getCurStrVal()); + R = CodeInit::get(Lex.getCurStrVal()); Lex.Lex(); break; case tgtok::question: - R = new UnsetInit(); + R = UnsetInit::get(); Lex.Lex(); break; case tgtok::Id: { @@ -1110,7 +1113,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { Records.addDef(NewRec); // The result of the expression is a reference to the new record. - return new DefInit(NewRec); + return DefInit::get(NewRec); } case tgtok::l_brace: { // Value ::= '{' ValueList '}' SMLoc BraceLoc = Lex.getLoc(); @@ -1127,17 +1130,18 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { } Lex.Lex(); // eat the '}' - BitsInit *Result = new BitsInit(Vals.size()); + SmallVector NewBits(Vals.size()); + for (unsigned i = 0, e = Vals.size(); i != e; ++i) { - Init *Bit = Vals[i]->convertInitializerTo(new BitRecTy()); + Init *Bit = Vals[i]->convertInitializerTo(BitRecTy::get()); if (Bit == 0) { Error(BraceLoc, "Element #" + utostr(i) + " (" + Vals[i]->getAsString()+ ") is not convertable to a bit"); return 0; } - Result->setBit(Vals.size()-i-1, Bit); + NewBits[Vals.size()-i-1] = Bit; } - return Result; + return BitsInit::get(NewBits); } case tgtok::l_square: { // Value ::= '[' ValueList ']' Lex.Lex(); // eat the '[' @@ -1236,7 +1240,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { DeducedEltTy = EltTy; } - return new ListInit(Vals, DeducedEltTy); + return ListInit::get(Vals, DeducedEltTy); } case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')' Lex.Lex(); // eat the '(' @@ -1271,7 +1275,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType) { } Lex.Lex(); // eat the ')' - return new DagInit(Operator, OperatorName, DagArgs); + return DagInit::get(Operator, OperatorName, DagArgs); } case tgtok::XHead: @@ -1361,7 +1365,7 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType) { Result->getAsString() + "'"); return 0; } - Result = new FieldInit(Result, Lex.getCurStrVal()); + Result = FieldInit::get(Result, Lex.getCurStrVal()); Lex.Lex(); // eat field name break; } @@ -1415,6 +1419,10 @@ std::vector TGParser::ParseValueList(Record *CurRec, Record *ArgsRec, if (ArgsRec != 0 && EltTy == 0) { const std::vector &TArgs = ArgsRec->getTemplateArgs(); const RecordVal *RV = ArgsRec->getValue(TArgs[ArgN]); + if (!RV) { + errs() << "Cannot find template arg " << ArgN << " (" << TArgs[ArgN] + << ")\n"; + } assert(RV && "Template argument record not found??"); ItemType = RV->getType(); ++ArgN; @@ -1689,6 +1697,9 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { return true; if (CurMultiClass == 0) // Def's in multiclasses aren't really defs. + // See Record::setName(). This resolve step will see any new name + // for the def that might have been created when resolving + // inheritance, values and arguments above. CurRec->resolveReferences(); // If ObjectBody has template arguments, it's an error. @@ -1709,7 +1720,6 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { return false; } - /// ParseClass - Parse a tblgen class definition. /// /// ClassInst ::= CLASS ID TemplateArgList? ObjectBody @@ -1911,6 +1921,115 @@ bool TGParser::ParseMultiClass() { return false; } +Record *TGParser:: +InstantiateMulticlassDef(MultiClass &MC, + Record *DefProto, + const std::string &DefmPrefix, + SMLoc DefmPrefixLoc) { + // Add in the defm name. If the defm prefix is empty, give each + // instantiated def a unique name. Otherwise, if "#NAME#" exists in the + // name, substitute the prefix for #NAME#. Otherwise, use the defm name + // as a prefix. + std::string DefName = DefProto->getName(); + if (DefmPrefix.empty()) { + DefName = GetNewAnonymousName(); + } else { + std::string::size_type idx = DefName.find("#NAME#"); + if (idx != std::string::npos) { + DefName.replace(idx, 6, DefmPrefix); + } else { + // Add the suffix to the defm name to get the new name. + DefName = DefmPrefix + DefName; + } + } + + Record *CurRec = new Record(DefName, DefmPrefixLoc, Records); + + SubClassReference Ref; + Ref.RefLoc = DefmPrefixLoc; + Ref.Rec = DefProto; + AddSubClass(CurRec, Ref); + + return CurRec; +} + +bool TGParser::ResolveMulticlassDefArgs(MultiClass &MC, + Record *CurRec, + SMLoc DefmPrefixLoc, + SMLoc SubClassLoc, + const std::vector &TArgs, + std::vector &TemplateVals, + bool DeleteArgs) { + // Loop over all of the template arguments, setting them to the specified + // value or leaving them as the default if necessary. + for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { + // Check if a value is specified for this temp-arg. + if (i < TemplateVals.size()) { + // Set it now. + if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector(), + TemplateVals[i])) + return true; + + // Resolve it next. + CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); + + if (DeleteArgs) + // Now remove it. + CurRec->removeValue(TArgs[i]); + + } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { + return Error(SubClassLoc, "value not specified for template argument #"+ + utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" + + MC.Rec.getName() + "'"); + } + } + return false; +} + +bool TGParser::ResolveMulticlassDef(MultiClass &MC, + Record *CurRec, + Record *DefProto, + SMLoc DefmPrefixLoc) { + // If the mdef is inside a 'let' expression, add to each def. + for (unsigned i = 0, e = LetStack.size(); i != e; ++i) + for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) + if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name, + LetStack[i][j].Bits, LetStack[i][j].Value)) + return Error(DefmPrefixLoc, "when instantiating this defm"); + + // Ensure redefinition doesn't happen. + if (Records.getDef(CurRec->getName())) + return Error(DefmPrefixLoc, "def '" + CurRec->getName() + + "' already defined, instantiating defm with subdef '" + + DefProto->getName() + "'"); + + // Don't create a top level definition for defm inside multiclasses, + // instead, only update the prototypes and bind the template args + // with the new created definition. + if (CurMultiClass) { + for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); + i != e; ++i) + if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName()) + return Error(DefmPrefixLoc, "defm '" + CurRec->getName() + + "' already defined in this multiclass!"); + CurMultiClass->DefPrototypes.push_back(CurRec); + + // Copy the template arguments for the multiclass into the new def. + const std::vector &TA = + CurMultiClass->Rec.getTemplateArgs(); + + for (unsigned i = 0, e = TA.size(); i != e; ++i) { + const RecordVal *RV = CurMultiClass->Rec.getValue(TA[i]); + assert(RV && "Template arg doesn't exist?"); + CurRec->addValue(*RV); + } + } else { + Records.addDef(CurRec); + } + + return false; +} + /// ParseDefm - Parse the instantiation of a multiclass. /// /// DefMInst ::= DEFM ID ':' DefmSubClassRef ';' @@ -1960,99 +2079,19 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) { Record *DefProto = MC->DefPrototypes[i]; - // Add in the defm name. If the defm prefix is empty, give each - // instantiated def a unique name. Otherwise, if "#NAME#" exists in the - // name, substitute the prefix for #NAME#. Otherwise, use the defm name - // as a prefix. - std::string DefName = DefProto->getName(); - if (DefmPrefix.empty()) { - DefName = GetNewAnonymousName(); - } else { - std::string::size_type idx = DefName.find("#NAME#"); - if (idx != std::string::npos) { - DefName.replace(idx, 6, DefmPrefix); - } else { - // Add the suffix to the defm name to get the new name. - DefName = DefmPrefix + DefName; - } - } + Record *CurRec = InstantiateMulticlassDef(*MC, DefProto, DefmPrefix, DefmPrefixLoc); - Record *CurRec = new Record(DefName, DefmPrefixLoc, Records); + if (ResolveMulticlassDefArgs(*MC, CurRec, DefmPrefixLoc, SubClassLoc, + TArgs, TemplateVals, true/*Delete args*/)) + return Error(SubClassLoc, "could not instantiate def"); - SubClassReference Ref; - Ref.RefLoc = DefmPrefixLoc; - Ref.Rec = DefProto; - AddSubClass(CurRec, Ref); - - // Loop over all of the template arguments, setting them to the specified - // value or leaving them as the default if necessary. - for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { - // Check if a value is specified for this temp-arg. - if (i < TemplateVals.size()) { - // Set it now. - if (SetValue(CurRec, DefmPrefixLoc, TArgs[i], std::vector(), - TemplateVals[i])) - return true; - - // Resolve it next. - CurRec->resolveReferencesTo(CurRec->getValue(TArgs[i])); - - // Now remove it. - CurRec->removeValue(TArgs[i]); - - } else if (!CurRec->getValue(TArgs[i])->getValue()->isComplete()) { - return Error(SubClassLoc, - "value not specified for template argument #"+ - utostr(i) + " (" + TArgs[i] + ") of multiclassclass '" + - MC->Rec.getName() + "'"); - } - } - - // If the mdef is inside a 'let' expression, add to each def. - for (unsigned i = 0, e = LetStack.size(); i != e; ++i) - for (unsigned j = 0, e = LetStack[i].size(); j != e; ++j) - if (SetValue(CurRec, LetStack[i][j].Loc, LetStack[i][j].Name, - LetStack[i][j].Bits, LetStack[i][j].Value)) { - Error(DefmPrefixLoc, "when instantiating this defm"); - return true; - } - - // Ensure redefinition doesn't happen. - if (Records.getDef(CurRec->getName())) - return Error(DefmPrefixLoc, "def '" + CurRec->getName() + - "' already defined, instantiating defm with subdef '" + - DefProto->getName() + "'"); - - // Don't create a top level definition for defm inside multiclasses, - // instead, only update the prototypes and bind the template args - // with the new created definition. - if (CurMultiClass) { - for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); - i != e; ++i) { - if (CurMultiClass->DefPrototypes[i]->getName() == CurRec->getName()) { - Error(DefmPrefixLoc, "defm '" + CurRec->getName() + - "' already defined in this multiclass!"); - return 0; - } - } - CurMultiClass->DefPrototypes.push_back(CurRec); - - // Copy the template arguments for the multiclass into the new def. - const std::vector &TA = - CurMultiClass->Rec.getTemplateArgs(); - - for (unsigned i = 0, e = TA.size(); i != e; ++i) { - const RecordVal *RV = CurMultiClass->Rec.getValue(TA[i]); - assert(RV && "Template arg doesn't exist?"); - CurRec->addValue(*RV); - } - } else { - Records.addDef(CurRec); - } + if (ResolveMulticlassDef(*MC, CurRec, DefProto, DefmPrefixLoc)) + return Error(SubClassLoc, "could not instantiate def"); NewRecDefs.push_back(CurRec); } + if (Lex.getCode() != tgtok::comma) break; Lex.Lex(); // eat ','. @@ -2101,6 +2140,9 @@ bool TGParser::ParseDefm(MultiClass *CurMultiClass) { if (!CurMultiClass) for (unsigned i = 0, e = NewRecDefs.size(); i != e; ++i) + // See Record::setName(). This resolve step will see any new + // name for the def that might have been created when resolving + // inheritance, values and arguments above. NewRecDefs[i]->resolveReferences(); if (Lex.getCode() != tgtok::semi) diff --git a/utils/TableGen/TGParser.h b/lib/TableGen/TGParser.h similarity index 82% rename from utils/TableGen/TGParser.h rename to lib/TableGen/TGParser.h index dce7e1dec94d..db8a62029746 100644 --- a/utils/TableGen/TGParser.h +++ b/lib/TableGen/TGParser.h @@ -15,7 +15,7 @@ #define TGPARSER_H #include "TGLexer.h" -#include "Error.h" +#include "llvm/TableGen/Error.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/SourceMgr.h" #include @@ -24,7 +24,7 @@ namespace llvm { class Record; class RecordVal; class RecordKeeper; - struct RecTy; + class RecTy; class Init; struct MultiClass; struct SubClassReference; @@ -83,6 +83,21 @@ class TGParser { bool ParseObject(MultiClass *MC); bool ParseClass(); bool ParseMultiClass(); + Record *InstantiateMulticlassDef(MultiClass &MC, + Record *DefProto, + const std::string &DefmPrefix, + SMLoc DefmPrefixLoc); + bool ResolveMulticlassDefArgs(MultiClass &MC, + Record *DefProto, + SMLoc DefmPrefixLoc, + SMLoc SubClassLoc, + const std::vector &TArgs, + std::vector &TemplateVals, + bool DeleteArgs); + bool ResolveMulticlassDef(MultiClass &MC, + Record *CurRec, + Record *DefProto, + SMLoc DefmPrefixLoc); bool ParseDefm(MultiClass *CurMultiClass); bool ParseDef(MultiClass *CurMultiClass); bool ParseTopLevelLet(MultiClass *CurMultiClass); diff --git a/utils/TableGen/TableGenBackend.cpp b/lib/TableGen/TableGenBackend.cpp similarity index 92% rename from utils/TableGen/TableGenBackend.cpp rename to lib/TableGen/TableGenBackend.cpp index b3e33b5f9c24..29588db324cf 100644 --- a/utils/TableGen/TableGenBackend.cpp +++ b/lib/TableGen/TableGenBackend.cpp @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#include "TableGenBackend.h" -#include "Record.h" +#include "llvm/TableGen/TableGenBackend.h" +#include "llvm/TableGen/Record.h" using namespace llvm; void TableGenBackend::EmitSourceFileHeader(const std::string &Desc, diff --git a/lib/Target/ARM/ARM.h b/lib/Target/ARM/ARM.h index 08dc340f8541..16d0da3b8ac7 100644 --- a/lib/Target/ARM/ARM.h +++ b/lib/Target/ARM/ARM.h @@ -15,7 +15,7 @@ #ifndef TARGET_ARM_H #define TARGET_ARM_H -#include "ARMBaseInfo.h" +#include "MCTargetDesc/ARMBaseInfo.h" #include "MCTargetDesc/ARMMCTargetDesc.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" @@ -29,19 +29,7 @@ class ARMBaseTargetMachine; class FunctionPass; class JITCodeEmitter; class MachineInstr; -class MCCodeEmitter; class MCInst; -class MCInstrInfo; -class MCObjectWriter; -class MCSubtargetInfo; -class TargetAsmBackend; -class formatted_raw_ostream; - -MCCodeEmitter *createARMMCCodeEmitter(const MCInstrInfo &MCII, - const MCSubtargetInfo &STI, - MCContext &Ctx); - -TargetAsmBackend *createARMAsmBackend(const Target &, const std::string &); FunctionPass *createARMISelDag(ARMBaseTargetMachine &TM, CodeGenOpt::Level OptLevel); @@ -53,7 +41,6 @@ FunctionPass *createARMLoadStoreOptimizationPass(bool PreAlloc = false); FunctionPass *createARMExpandPseudoPass(); FunctionPass *createARMGlobalMergePass(const TargetLowering* tli); FunctionPass *createARMConstantIslandPass(); -FunctionPass *createNEONMoveFixPass(); FunctionPass *createMLxExpansionPass(); FunctionPass *createThumb2ITBlockPass(); FunctionPass *createThumb2SizeReductionPass(); @@ -61,12 +48,6 @@ FunctionPass *createThumb2SizeReductionPass(); void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, ARMAsmPrinter &AP); -/// createARMMachObjectWriter - Construct an ARM Mach-O object writer. -MCObjectWriter *createARMMachObjectWriter(raw_ostream &OS, - bool Is64Bit, - uint32_t CPUType, - uint32_t CPUSubtype); - } // end namespace llvm; #endif diff --git a/lib/Target/ARM/ARM.td b/lib/Target/ARM/ARM.td index cf333ccd49ba..5c727ad6e343 100644 --- a/lib/Target/ARM/ARM.td +++ b/lib/Target/ARM/ARM.td @@ -23,6 +23,9 @@ include "llvm/Target/Target.td" def ModeThumb : SubtargetFeature<"thumb-mode", "InThumbMode", "true", "Thumb mode">; +def ModeNaCl : SubtargetFeature<"nacl-mode", "InNaClMode", "true", + "Native client mode">; + //===----------------------------------------------------------------------===// // ARM Subtarget features. // @@ -85,12 +88,16 @@ def FeatureAvoidPartialCPSR : SubtargetFeature<"avoid-partial-cpsr", /// Some M architectures don't have the DSP extension (v7E-M vs. v7M) def FeatureDSPThumb2 : SubtargetFeature<"t2dsp", "Thumb2DSP", "true", - "Supports v7 DSP instructions in Thumb2.">; + "Supports v7 DSP instructions in Thumb2">; // Multiprocessing extension. def FeatureMP : SubtargetFeature<"mp", "HasMPExtension", "true", "Supports Multiprocessing extension">; +// M-series ISA? +def FeatureMClass : SubtargetFeature<"mclass", "IsMClass", "true", + "Is microcontroller profile ('M' series)">; + // ARM ISAs. def HasV4TOps : SubtargetFeature<"v4t", "HasV4TOps", "true", "Support ARM v4T instructions">; @@ -105,7 +112,7 @@ def HasV6Ops : SubtargetFeature<"v6", "HasV6Ops", "true", [HasV5TEOps]>; def HasV6T2Ops : SubtargetFeature<"v6t2", "HasV6T2Ops", "true", "Support ARM v6t2 instructions", - [HasV6Ops, FeatureThumb2, FeatureDSPThumb2]>; + [HasV6Ops, FeatureThumb2]>; def HasV7Ops : SubtargetFeature<"v7", "HasV7Ops", "true", "Support ARM v7 instructions", [HasV6T2Ops]>; @@ -182,12 +189,14 @@ def : Processor<"mpcore", ARMV6Itineraries, [HasV6Ops, FeatureVFP2, // V6M Processors. def : Processor<"cortex-m0", ARMV6Itineraries, [HasV6Ops, FeatureNoARM, - FeatureDB]>; + FeatureDB, FeatureMClass]>; // V6T2 Processors. -def : Processor<"arm1156t2-s", ARMV6Itineraries, [HasV6T2Ops]>; +def : Processor<"arm1156t2-s", ARMV6Itineraries, [HasV6T2Ops, + FeatureDSPThumb2]>; def : Processor<"arm1156t2f-s", ARMV6Itineraries, [HasV6T2Ops, FeatureVFP2, - FeatureHasSlowFPVMLx]>; + FeatureHasSlowFPVMLx, + FeatureDSPThumb2]>; // V7a Processors. def : Processor<"cortex-a8", CortexA8Itineraries, @@ -203,14 +212,14 @@ def : Processor<"cortex-a9-mp", CortexA9Itineraries, // V7M Processors. def : ProcNoItin<"cortex-m3", [HasV7Ops, FeatureThumb2, FeatureNoARM, FeatureDB, - FeatureHWDiv]>; + FeatureHWDiv, FeatureMClass]>; // V7EM Processors. def : ProcNoItin<"cortex-m4", [HasV7Ops, FeatureThumb2, FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, FeatureT2XtPk, FeatureVFP2, - FeatureVFPOnlySP]>; + FeatureVFPOnlySP, FeatureMClass]>; //===----------------------------------------------------------------------===// // Register File Description diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index dbc3ee41f3da..ea3319fb0e03 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -15,15 +15,15 @@ #define DEBUG_TYPE "asm-printer" #include "ARM.h" #include "ARMAsmPrinter.h" -#include "ARMAddressingModes.h" #include "ARMBuildAttrs.h" #include "ARMBaseRegisterInfo.h" #include "ARMConstantPoolValue.h" #include "ARMMachineFunctionInfo.h" -#include "ARMMCExpr.h" #include "ARMTargetMachine.h" #include "ARMTargetObjectFile.h" #include "InstPrinter/ARMInstPrinter.h" +#include "MCTargetDesc/ARMAddressingModes.h" +#include "MCTargetDesc/ARMMCExpr.h" #include "llvm/Analysis/DebugInfo.h" #include "llvm/Constants.h" #include "llvm/Module.h" @@ -45,13 +45,13 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegistry.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" #include using namespace llvm; @@ -92,7 +92,7 @@ namespace { case ARMBuildAttrs::Advanced_SIMD_arch: case ARMBuildAttrs::VFP_arch: Streamer.EmitRawText(StringRef("\t.fpu ") + LowercaseString(String)); - break; + break; default: assert(0 && "Unsupported Text attribute in ASM Mode"); break; } } @@ -100,13 +100,41 @@ namespace { }; class ObjectAttributeEmitter : public AttributeEmitter { + // This structure holds all attributes, accounting for + // their string/numeric value, so we can later emmit them + // in declaration order, keeping all in the same vector + struct AttributeItemType { + enum { + HiddenAttribute = 0, + NumericAttribute, + TextAttribute + } Type; + unsigned Tag; + unsigned IntValue; + StringRef StringValue; + } AttributeItem; + MCObjectStreamer &Streamer; StringRef CurrentVendor; - SmallString<64> Contents; + SmallVector Contents; + + // Account for the ULEB/String size of each item, + // not just the number of items + size_t ContentsSize; + // FIXME: this should be in a more generic place, but + // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf + size_t getULEBSize(int Value) { + size_t Size = 0; + do { + Value >>= 7; + Size += sizeof(int8_t); // Is this really necessary? + } while (Value); + return Size; + } public: ObjectAttributeEmitter(MCObjectStreamer &Streamer_) : - Streamer(Streamer_), CurrentVendor("") { } + Streamer(Streamer_), CurrentVendor(""), ContentsSize(0) { } void MaybeSwitchVendor(StringRef Vendor) { assert(!Vendor.empty() && "Vendor cannot be empty."); @@ -124,20 +152,32 @@ namespace { } void EmitAttribute(unsigned Attribute, unsigned Value) { - // FIXME: should be ULEB - Contents += Attribute; - Contents += Value; + AttributeItemType attr = { + AttributeItemType::NumericAttribute, + Attribute, + Value, + StringRef("") + }; + ContentsSize += getULEBSize(Attribute); + ContentsSize += getULEBSize(Value); + Contents.push_back(attr); } void EmitTextAttribute(unsigned Attribute, StringRef String) { - Contents += Attribute; - Contents += UppercaseString(String); - Contents += 0; + AttributeItemType attr = { + AttributeItemType::TextAttribute, + Attribute, + 0, + String + }; + ContentsSize += getULEBSize(Attribute); + // String + \0 + ContentsSize += String.size()+1; + + Contents.push_back(attr); } void Finish() { - const size_t ContentsSize = Contents.size(); - // Vendor size + Vendor name + '\0' const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; @@ -151,7 +191,23 @@ namespace { Streamer.EmitIntValue(ARMBuildAttrs::File, 1); Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); - Streamer.EmitBytes(Contents, 0); + // Size should have been accounted for already, now + // emit each field as its type (ULEB or String) + for (unsigned int i=0; i>1)) DW_OP_bit_piece(32, 0) // S[2x+1] = DW_OP_regx(256 + (x>>1)) DW_OP_bit_piece(32, 32) - + unsigned SReg = Reg - ARM::S0; bool odd = SReg & 0x1; unsigned Rx = 256 + (SReg >> 1); @@ -209,12 +265,13 @@ void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const { } else if (Reg >= ARM::Q0 && Reg <= ARM::Q15) { assert(ARM::Q0 + 15 == ARM::Q15 && "Unexpected ARM Q register numbering"); // Q registers Q0-Q15 are described by composing two D registers together. - // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1) DW_OP_piece(8) + // Qx = DW_OP_regx(256+2x) DW_OP_piece(8) DW_OP_regx(256+2x+1) + // DW_OP_piece(8) unsigned QReg = Reg - ARM::Q0; unsigned D1 = 256 + 2 * QReg; unsigned D2 = D1 + 1; - + OutStreamer.AddComment("DW_OP_regx for Q register: D1"); EmitInt8(dwarf::DW_OP_regx); EmitULEB128(D1); @@ -233,6 +290,8 @@ void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const { } void ARMAsmPrinter::EmitFunctionEntryLabel() { + OutStreamer.ForceCodeRegion(); + if (AFI->isThumbFunction()) { OutStreamer.EmitAssemblerFlag(MCAF_Code16); OutStreamer.EmitThumbFunc(CurrentFnSym); @@ -395,16 +454,16 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, // This takes advantage of the 2 operand-ness of ldm/stm and that we've // already got the operands in registers that are operands to the // inline asm statement. - + O << "{" << ARMInstPrinter::getRegisterName(RegBegin); - + // FIXME: The register allocator not only may not have given us the // registers in sequence, but may not be in ascending registers. This // will require changes in the register allocator that'll need to be // propagated down here if the operands change. unsigned RegOps = OpNum + 1; while (MI->getOperand(RegOps).isReg()) { - O << ", " + O << ", " << ARMInstPrinter::getRegisterName(MI->getOperand(RegOps).getReg()); RegOps++; } @@ -413,14 +472,34 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, return false; } + case 'R': // The most significant register of a pair. + case 'Q': { // The least significant register of a pair. + if (OpNum == 0) + return true; + const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); + if (!FlagsOP.isImm()) + return true; + unsigned Flags = FlagsOP.getImm(); + unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); + if (NumVals != 2) + return true; + unsigned RegOp = ExtraCode[0] == 'Q' ? OpNum : OpNum + 1; + if (RegOp >= MI->getNumOperands()) + return true; + const MachineOperand &MO = MI->getOperand(RegOp); + if (!MO.isReg()) + return true; + unsigned Reg = MO.getReg(); + O << ARMInstPrinter::getRegisterName(Reg); + return false; + } + // These modifiers are not yet supported. case 'p': // The high single-precision register of a VFP double-precision // register. case 'e': // The low doubleword register of a NEON quad register. case 'f': // The high doubleword register of a NEON quad register. case 'h': // A range of VFP/NEON registers suitable for VLD1/VST1. - case 'Q': // The least significant register of a pair. - case 'R': // The most significant register of a pair. case 'H': // The highest-numbered register of a pair. return true; } @@ -437,7 +516,7 @@ bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. - + switch (ExtraCode[0]) { case 'A': // A memory operand for a VLD1/VST1 instruction. default: return true; // Unknown modifier. @@ -448,7 +527,7 @@ bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, return false; } } - + const MachineOperand &MO = MI->getOperand(OpNum); assert(MO.isReg() && "unexpected inline asm memory operand"); O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]"; @@ -772,13 +851,19 @@ EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { OS << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); MCSym = OutContext.GetOrCreateSymbol(OS.str()); } else if (ACPV->isBlockAddress()) { - MCSym = GetBlockAddressSymbol(ACPV->getBlockAddress()); + const BlockAddress *BA = + cast(ACPV)->getBlockAddress(); + MCSym = GetBlockAddressSymbol(BA); } else if (ACPV->isGlobalValue()) { - const GlobalValue *GV = ACPV->getGV(); + const GlobalValue *GV = cast(ACPV)->getGV(); MCSym = GetARMGVSymbol(GV); + } else if (ACPV->isMachineBasicBlock()) { + const MachineBasicBlock *MBB = cast(ACPV)->getMBB(); + MCSym = MBB->getSymbol(); } else { assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); - MCSym = GetExternalSymbolSymbol(ACPV->getSymbol()); + const char *Sym = cast(ACPV)->getSymbol(); + MCSym = GetExternalSymbolSymbol(Sym); } // Create an MCSymbol for the reference. @@ -822,6 +907,9 @@ void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id unsigned JTI = MO1.getIndex(); + // Tag the jump table appropriately for precise disassembly. + OutStreamer.EmitJumpTable32Region(); + // Emit a label for the jump table. MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); OutStreamer.EmitLabel(JTISymbol); @@ -847,6 +935,11 @@ void ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) { Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol, OutContext), OutContext); + // If we're generating a table of Thumb addresses in static relocation + // model, we need to add one to keep interworking correctly. + else if (AFI->isThumbFunction()) + Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(1,OutContext), + OutContext); OutStreamer.EmitValue(Expr, 4); } } @@ -859,6 +952,14 @@ void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { unsigned JTI = MO1.getIndex(); // Emit a label for the jump table. + if (MI->getOpcode() == ARM::t2TBB_JT) { + OutStreamer.EmitJumpTable8Region(); + } else if (MI->getOpcode() == ARM::t2TBH_JT) { + OutStreamer.EmitJumpTable16Region(); + } else { + OutStreamer.EmitJumpTable32Region(); + } + MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm()); OutStreamer.EmitLabel(JTISymbol); @@ -881,6 +982,8 @@ void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) { MCInst BrInst; BrInst.setOpcode(ARM::t2B); BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); + BrInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + BrInst.addOperand(MCOperand::CreateReg(0)); OutStreamer.EmitInstruction(BrInst); continue; } @@ -994,7 +1097,8 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { i != NumOps; ++i) RegList.push_back(MI->getOperand(i).getReg()); break; - case ARM::STR_PRE: + case ARM::STR_PRE_IMM: + case ARM::STR_PRE_REG: assert(MI->getOperand(2).getReg() == ARM::SP && "Only stack pointer as a source reg is supported"); RegList.push_back(SrcReg); @@ -1074,10 +1178,20 @@ extern cl::opt EnableARMEHABI; #include "ARMGenMCPseudoLowering.inc" void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { + if (MI->getOpcode() != ARM::CONSTPOOL_ENTRY) + OutStreamer.EmitCodeRegion(); + + // Emit unwinding stuff for frame-related instructions + if (EnableARMEHABI && MI->getFlag(MachineInstr::FrameSetup)) + EmitUnwindingInstruction(MI); + // Do any auto-generated pseudo lowerings. if (emitPseudoExpansionLowering(OutStreamer, MI)) return; + assert(!convertAddSubFlagsOpcode(MI->getOpcode()) && + "Pseudo flag setting opcode should be expanded early"); + // Check for manual lowerings. unsigned Opc = MI->getOpcode(); switch (Opc) { @@ -1372,6 +1486,10 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); EmitAlignment(2); + + // Mark the constant pool entry as data if we're not already in a data + // region. + OutStreamer.EmitDataRegion(); OutStreamer.EmitLabel(GetCPISymbol(LabelId)); const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; @@ -1379,7 +1497,6 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); else EmitGlobalConstant(MCPE.Val.ConstVal); - return; } case ARM::t2BR_JT: { @@ -1590,6 +1707,8 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { MCInst TmpInst; TmpInst.setOpcode(ARM::tB); TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); + TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); + TmpInst.addOperand(MCOperand::CreateReg(0)); OutStreamer.EmitInstruction(TmpInst); } { @@ -1804,10 +1923,6 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { MCInst TmpInst; LowerARMMachineInstrToMCInst(MI, TmpInst, *this); - // Emit unwinding stuff for frame-related instructions - if (EnableARMEHABI && MI->getFlag(MachineInstr::FrameSetup)) - EmitUnwindingInstruction(MI); - OutStreamer.EmitInstruction(TmpInst); } @@ -1815,20 +1930,9 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { // Target Registry Stuff //===----------------------------------------------------------------------===// -static MCInstPrinter *createARMMCInstPrinter(const Target &T, - unsigned SyntaxVariant, - const MCAsmInfo &MAI) { - if (SyntaxVariant == 0) - return new ARMInstPrinter(MAI); - return 0; -} - // Force static initialization. extern "C" void LLVMInitializeARMAsmPrinter() { RegisterAsmPrinter X(TheARMTarget); RegisterAsmPrinter Y(TheThumbTarget); - - TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); - TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); } diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 649bd7d5ce3f..408edfc20d4c 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -13,11 +13,11 @@ #include "ARMBaseInstrInfo.h" #include "ARM.h" -#include "ARMAddressingModes.h" #include "ARMConstantPoolValue.h" #include "ARMHazardRecognizer.h" #include "ARMMachineFunctionInfo.h" #include "ARMRegisterInfo.h" +#include "MCTargetDesc/ARMAddressingModes.h" #include "llvm/Constants.h" #include "llvm/Function.h" #include "llvm/GlobalValue.h" @@ -29,6 +29,7 @@ #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/Support/BranchProbability.h" #include "llvm/Support/CommandLine.h" @@ -45,6 +46,10 @@ static cl::opt EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden, cl::desc("Enable ARM 2-addr to 3-addr conv")); +static cl::opt +WidenVMOVS("widen-vmovs", cl::Hidden, + cl::desc("Widen ARM vmovs to vmovd when possible")); + /// ARM_MLxEntry - Record information about MLA / MLS instructions. struct ARM_MLxEntry { unsigned MLxOpc; // MLA / MLS opcode @@ -171,7 +176,7 @@ ARMBaseInstrInfo::convertToThreeAddress(MachineFunction::iterator &MFI, ARM_AM::ShiftOpc ShOpc = ARM_AM::getAM2ShiftOpc(OffImm); unsigned SOOpc = ARM_AM::getSORegOpc(ShOpc, Amt); UpdateMI = BuildMI(MF, MI->getDebugLoc(), - get(isSub ? ARM::SUBrs : ARM::ADDrs), WBReg) + get(isSub ? ARM::SUBrsi : ARM::ADDrsi), WBReg) .addReg(BaseReg).addReg(OffReg).addReg(0).addImm(SOOpc) .addImm(Pred).addReg(0).addReg(0); } else @@ -399,6 +404,7 @@ ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, ? ARM::B : (AFI->isThumb2Function() ? ARM::t2B : ARM::tB); int BccOpc = !AFI->isThumbFunction() ? ARM::Bcc : (AFI->isThumb2Function() ? ARM::t2Bcc : ARM::tBcc); + bool isThumb = AFI->isThumbFunction() || AFI->isThumb2Function(); // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); @@ -406,9 +412,12 @@ ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, "ARM branch conditions have two components!"); if (FBB == 0) { - if (Cond.empty()) // Unconditional branch? - BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB); - else + if (Cond.empty()) { // Unconditional branch? + if (isThumb) + BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB).addImm(ARMCC::AL).addReg(0); + else + BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB); + } else BuildMI(&MBB, DL, get(BccOpc)).addMBB(TBB) .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); return 1; @@ -417,7 +426,10 @@ ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, // Two-way conditional branch. BuildMI(&MBB, DL, get(BccOpc)).addMBB(TBB) .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); - BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB); + if (isThumb) + BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB).addImm(ARMCC::AL).addReg(0); + else + BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB); return 2; } @@ -627,7 +639,7 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB, bool SPRDest = ARM::SPRRegClass.contains(DestReg); bool SPRSrc = ARM::SPRRegClass.contains(SrcReg); - unsigned Opc; + unsigned Opc = 0; if (SPRDest && SPRSrc) Opc = ARM::VMOVS; else if (GPRDest && SPRSrc) @@ -638,19 +650,40 @@ void ARMBaseInstrInfo::copyPhysReg(MachineBasicBlock &MBB, Opc = ARM::VMOVD; else if (ARM::QPRRegClass.contains(DestReg, SrcReg)) Opc = ARM::VORRq; - else if (ARM::QQPRRegClass.contains(DestReg, SrcReg)) - Opc = ARM::VMOVQQ; - else if (ARM::QQQQPRRegClass.contains(DestReg, SrcReg)) - Opc = ARM::VMOVQQQQ; - else - llvm_unreachable("Impossible reg-to-reg copy"); - MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc), DestReg); - MIB.addReg(SrcReg, getKillRegState(KillSrc)); - if (Opc == ARM::VORRq) + if (Opc) { + MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc), DestReg); MIB.addReg(SrcReg, getKillRegState(KillSrc)); - if (Opc != ARM::VMOVQQ && Opc != ARM::VMOVQQQQ) + if (Opc == ARM::VORRq) + MIB.addReg(SrcReg, getKillRegState(KillSrc)); AddDefaultPred(MIB); + return; + } + + // Generate instructions for VMOVQQ and VMOVQQQQ pseudos in place. + if (ARM::QQPRRegClass.contains(DestReg, SrcReg) || + ARM::QQQQPRRegClass.contains(DestReg, SrcReg)) { + const TargetRegisterInfo *TRI = &getRegisterInfo(); + assert(ARM::qsub_0 + 3 == ARM::qsub_3 && "Expected contiguous enum."); + unsigned EndSubReg = ARM::QQPRRegClass.contains(DestReg, SrcReg) ? + ARM::qsub_1 : ARM::qsub_3; + for (unsigned i = ARM::qsub_0, e = EndSubReg + 1; i != e; ++i) { + unsigned Dst = TRI->getSubReg(DestReg, i); + unsigned Src = TRI->getSubReg(SrcReg, i); + MachineInstrBuilder Mov = + AddDefaultPred(BuildMI(MBB, I, I->getDebugLoc(), get(ARM::VORRq)) + .addReg(Dst, RegState::Define) + .addReg(Src, getKillRegState(KillSrc)) + .addReg(Src, getKillRegState(KillSrc))); + if (i == EndSubReg) { + Mov->addRegisterDefined(DestReg, TRI); + if (KillSrc) + Mov->addRegisterKilled(SrcReg, TRI); + } + } + return; + } + llvm_unreachable("Impossible reg-to-reg copy"); } static const @@ -683,82 +716,84 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MFI.getObjectSize(FI), Align); - // tGPR is used sometimes in ARM instructions that need to avoid using - // certain registers. Just treat it as GPR here. Likewise, rGPR. - if (RC == ARM::tGPRRegisterClass || RC == ARM::tcGPRRegisterClass - || RC == ARM::rGPRRegisterClass) - RC = ARM::GPRRegisterClass; - - switch (RC->getID()) { - case ARM::GPRRegClassID: - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STRi12)) + switch (RC->getSize()) { + case 4: + if (ARM::GPRRegClass.hasSubClassEq(RC)) { + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STRi12)) .addReg(SrcReg, getKillRegState(isKill)) .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); - break; - case ARM::SPRRegClassID: - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRS)) + } else if (ARM::SPRRegClass.hasSubClassEq(RC)) { + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRS)) .addReg(SrcReg, getKillRegState(isKill)) .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); - break; - case ARM::DPRRegClassID: - case ARM::DPR_VFP2RegClassID: - case ARM::DPR_8RegClassID: - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRD)) + } else + llvm_unreachable("Unknown reg class!"); + break; + case 8: + if (ARM::DPRRegClass.hasSubClassEq(RC)) { + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRD)) .addReg(SrcReg, getKillRegState(isKill)) .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); - break; - case ARM::QPRRegClassID: - case ARM::QPR_VFP2RegClassID: - case ARM::QPR_8RegClassID: - if (Align >= 16 && getRegisterInfo().needsStackRealignment(MF)) { - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q64Pseudo)) + } else + llvm_unreachable("Unknown reg class!"); + break; + case 16: + if (ARM::QPRRegClass.hasSubClassEq(RC)) { + if (Align >= 16 && getRegisterInfo().needsStackRealignment(MF)) { + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q64Pseudo)) .addFrameIndex(FI).addImm(16) .addReg(SrcReg, getKillRegState(isKill)) .addMemOperand(MMO)); - } else { - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMQIA)) + } else { + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMQIA)) .addReg(SrcReg, getKillRegState(isKill)) .addFrameIndex(FI) .addMemOperand(MMO)); - } - break; - case ARM::QQPRRegClassID: - case ARM::QQPR_VFP2RegClassID: - if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) { - // FIXME: It's possible to only store part of the QQ register if the - // spilled def has a sub-register index. - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1d64QPseudo)) + } + } else + llvm_unreachable("Unknown reg class!"); + break; + case 32: + if (ARM::QQPRRegClass.hasSubClassEq(RC)) { + if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) { + // FIXME: It's possible to only store part of the QQ register if the + // spilled def has a sub-register index. + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1d64QPseudo)) .addFrameIndex(FI).addImm(16) .addReg(SrcReg, getKillRegState(isKill)) .addMemOperand(MMO)); - } else { - MachineInstrBuilder MIB = - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMDIA)) + } else { + MachineInstrBuilder MIB = + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMDIA)) .addFrameIndex(FI)) - .addMemOperand(MMO); - MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI); - MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI); - AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI); - } - break; - case ARM::QQQQPRRegClassID: { - MachineInstrBuilder MIB = - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMDIA)) - .addFrameIndex(FI)) - .addMemOperand(MMO); - MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI); - MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::dsub_4, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::dsub_5, 0, TRI); - MIB = AddDReg(MIB, SrcReg, ARM::dsub_6, 0, TRI); - AddDReg(MIB, SrcReg, ARM::dsub_7, 0, TRI); - break; - } - default: - llvm_unreachable("Unknown regclass!"); + .addMemOperand(MMO); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI); + AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI); + } + } else + llvm_unreachable("Unknown reg class!"); + break; + case 64: + if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) { + MachineInstrBuilder MIB = + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTMDIA)) + .addFrameIndex(FI)) + .addMemOperand(MMO); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_0, getKillRegState(isKill), TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_1, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_2, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_3, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_4, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_5, 0, TRI); + MIB = AddDReg(MIB, SrcReg, ARM::dsub_6, 0, TRI); + AddDReg(MIB, SrcReg, ARM::dsub_7, 0, TRI); + } else + llvm_unreachable("Unknown reg class!"); + break; + default: + llvm_unreachable("Unknown reg class!"); } } @@ -809,6 +844,12 @@ ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI, return 0; } +unsigned ARMBaseInstrInfo::isStoreToStackSlotPostFE(const MachineInstr *MI, + int &FrameIndex) const { + const MachineMemOperand *Dummy; + return MI->getDesc().mayStore() && hasStoreToStackSlot(MI, Dummy, FrameIndex); +} + void ARMBaseInstrInfo:: loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg, int FI, @@ -826,72 +867,77 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MFI.getObjectSize(FI), Align); - // tGPR is used sometimes in ARM instructions that need to avoid using - // certain registers. Just treat it as GPR here. - if (RC == ARM::tGPRRegisterClass || RC == ARM::tcGPRRegisterClass - || RC == ARM::rGPRRegisterClass) - RC = ARM::GPRRegisterClass; + switch (RC->getSize()) { + case 4: + if (ARM::GPRRegClass.hasSubClassEq(RC)) { + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDRi12), DestReg) + .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); - switch (RC->getID()) { - case ARM::GPRRegClassID: - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::LDRi12), DestReg) + } else if (ARM::SPRRegClass.hasSubClassEq(RC)) { + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRS), DestReg) .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); + } else + llvm_unreachable("Unknown reg class!"); break; - case ARM::SPRRegClassID: - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRS), DestReg) + case 8: + if (ARM::DPRRegClass.hasSubClassEq(RC)) { + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg) .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); + } else + llvm_unreachable("Unknown reg class!"); break; - case ARM::DPRRegClassID: - case ARM::DPR_VFP2RegClassID: - case ARM::DPR_8RegClassID: - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg) - .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); - break; - case ARM::QPRRegClassID: - case ARM::QPR_VFP2RegClassID: - case ARM::QPR_8RegClassID: - if (Align >= 16 && getRegisterInfo().needsStackRealignment(MF)) { - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q64Pseudo), DestReg) + case 16: + if (ARM::QPRRegClass.hasSubClassEq(RC)) { + if (Align >= 16 && getRegisterInfo().needsStackRealignment(MF)) { + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q64Pseudo), DestReg) .addFrameIndex(FI).addImm(16) .addMemOperand(MMO)); - } else { - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMQIA), DestReg) - .addFrameIndex(FI) - .addMemOperand(MMO)); - } + } else { + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMQIA), DestReg) + .addFrameIndex(FI) + .addMemOperand(MMO)); + } + } else + llvm_unreachable("Unknown reg class!"); break; - case ARM::QQPRRegClassID: - case ARM::QQPR_VFP2RegClassID: - if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) { - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1d64QPseudo), DestReg) + case 32: + if (ARM::QQPRRegClass.hasSubClassEq(RC)) { + if (Align >= 16 && getRegisterInfo().canRealignStack(MF)) { + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1d64QPseudo), DestReg) .addFrameIndex(FI).addImm(16) .addMemOperand(MMO)); - } else { - MachineInstrBuilder MIB = + } else { + MachineInstrBuilder MIB = AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMDIA)) .addFrameIndex(FI)) - .addMemOperand(MMO); + .addMemOperand(MMO); + MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_3, RegState::Define, TRI); + MIB.addReg(DestReg, RegState::Define | RegState::Implicit); + } + } else + llvm_unreachable("Unknown reg class!"); + break; + case 64: + if (ARM::QQQQPRRegClass.hasSubClassEq(RC)) { + MachineInstrBuilder MIB = + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMDIA)) + .addFrameIndex(FI)) + .addMemOperand(MMO); MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::Define, TRI); MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::Define, TRI); MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::Define, TRI); - AddDReg(MIB, DestReg, ARM::dsub_3, RegState::Define, TRI); - } + MIB = AddDReg(MIB, DestReg, ARM::dsub_3, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_4, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_5, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_6, RegState::Define, TRI); + MIB = AddDReg(MIB, DestReg, ARM::dsub_7, RegState::Define, TRI); + MIB.addReg(DestReg, RegState::Define | RegState::Implicit); + } else + llvm_unreachable("Unknown reg class!"); break; - case ARM::QQQQPRRegClassID: { - MachineInstrBuilder MIB = - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDMDIA)) - .addFrameIndex(FI)) - .addMemOperand(MMO); - MIB = AddDReg(MIB, DestReg, ARM::dsub_0, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::dsub_1, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::dsub_2, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::dsub_3, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::dsub_4, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::dsub_5, RegState::Define, TRI); - MIB = AddDReg(MIB, DestReg, ARM::dsub_6, RegState::Define, TRI); - AddDReg(MIB, DestReg, ARM::dsub_7, RegState::Define, TRI); - break; - } default: llvm_unreachable("Unknown regclass!"); } @@ -944,6 +990,78 @@ ARMBaseInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, return 0; } +unsigned ARMBaseInstrInfo::isLoadFromStackSlotPostFE(const MachineInstr *MI, + int &FrameIndex) const { + const MachineMemOperand *Dummy; + return MI->getDesc().mayLoad() && hasLoadFromStackSlot(MI, Dummy, FrameIndex); +} + +bool ARMBaseInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const{ + // This hook gets to expand COPY instructions before they become + // copyPhysReg() calls. Look for VMOVS instructions that can legally be + // widened to VMOVD. We prefer the VMOVD when possible because it may be + // changed into a VORR that can go down the NEON pipeline. + if (!WidenVMOVS || !MI->isCopy()) + return false; + + // Look for a copy between even S-registers. That is where we keep floats + // when using NEON v2f32 instructions for f32 arithmetic. + unsigned DstRegS = MI->getOperand(0).getReg(); + unsigned SrcRegS = MI->getOperand(1).getReg(); + if (!ARM::SPRRegClass.contains(DstRegS, SrcRegS)) + return false; + + const TargetRegisterInfo *TRI = &getRegisterInfo(); + unsigned DstRegD = TRI->getMatchingSuperReg(DstRegS, ARM::ssub_0, + &ARM::DPRRegClass); + unsigned SrcRegD = TRI->getMatchingSuperReg(SrcRegS, ARM::ssub_0, + &ARM::DPRRegClass); + if (!DstRegD || !SrcRegD) + return false; + + // We want to widen this into a DstRegD = VMOVD SrcRegD copy. This is only + // legal if the COPY already defines the full DstRegD, and it isn't a + // sub-register insertion. + if (!MI->definesRegister(DstRegD, TRI) || MI->readsRegister(DstRegD, TRI)) + return false; + + // A dead copy shouldn't show up here, but reject it just in case. + if (MI->getOperand(0).isDead()) + return false; + + // All clear, widen the COPY. + DEBUG(dbgs() << "widening: " << *MI); + + // Get rid of the old of DstRegD. Leave it if it defines a Q-reg + // or some other super-register. + int ImpDefIdx = MI->findRegisterDefOperandIdx(DstRegD); + if (ImpDefIdx != -1) + MI->RemoveOperand(ImpDefIdx); + + // Change the opcode and operands. + MI->setDesc(get(ARM::VMOVD)); + MI->getOperand(0).setReg(DstRegD); + MI->getOperand(1).setReg(SrcRegD); + AddDefaultPred(MachineInstrBuilder(MI)); + + // We are now reading SrcRegD instead of SrcRegS. This may upset the + // register scavenger and machine verifier, so we need to indicate that we + // are reading an undefined value from SrcRegD, but a proper value from + // SrcRegS. + MI->getOperand(1).setIsUndef(); + MachineInstrBuilder(MI).addReg(SrcRegS, RegState::Implicit); + + // SrcRegD may actually contain an unrelated value in the ssub_1 + // sub-register. Don't kill it. Only kill the ssub_0 sub-register. + if (MI->getOperand(1).isKill()) { + MI->getOperand(1).setIsKill(false); + MI->addRegisterKilled(SrcRegS, TRI, true); + } + + DEBUG(dbgs() << "replaced by: " << *MI); + return true; +} + MachineInstr* ARMBaseInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, uint64_t Offset, @@ -974,17 +1092,24 @@ static unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI) { // instructions, so that's probably OK, but is PIC always correct when // we get here? if (ACPV->isGlobalValue()) - NewCPV = new ARMConstantPoolValue(ACPV->getGV(), PCLabelId, - ARMCP::CPValue, 4); + NewCPV = ARMConstantPoolConstant:: + Create(cast(ACPV)->getGV(), PCLabelId, + ARMCP::CPValue, 4); else if (ACPV->isExtSymbol()) - NewCPV = new ARMConstantPoolValue(MF.getFunction()->getContext(), - ACPV->getSymbol(), PCLabelId, 4); + NewCPV = ARMConstantPoolSymbol:: + Create(MF.getFunction()->getContext(), + cast(ACPV)->getSymbol(), PCLabelId, 4); else if (ACPV->isBlockAddress()) - NewCPV = new ARMConstantPoolValue(ACPV->getBlockAddress(), PCLabelId, - ARMCP::CPBlockAddress, 4); + NewCPV = ARMConstantPoolConstant:: + Create(cast(ACPV)->getBlockAddress(), PCLabelId, + ARMCP::CPBlockAddress, 4); else if (ACPV->isLSDA()) - NewCPV = new ARMConstantPoolValue(MF.getFunction(), PCLabelId, - ARMCP::CPLSDA, 4); + NewCPV = ARMConstantPoolConstant::Create(MF.getFunction(), PCLabelId, + ARMCP::CPLSDA, 4); + else if (ACPV->isMachineBasicBlock()) + NewCPV = ARMConstantPoolMBB:: + Create(MF.getFunction()->getContext(), + cast(ACPV)->getMBB(), PCLabelId, 4); else llvm_unreachable("Unexpected ARM constantpool value type!!"); CPI = MCP->getConstantPoolIndex(NewCPV, MCPE.getAlignment()); @@ -1289,7 +1414,7 @@ isProfitableToIfCvt(MachineBasicBlock &TMBB, // Attempt to estimate the relative costs of predication versus branching. unsigned TUnpredCost = Probability.getNumerator() * TCycles; TUnpredCost /= Probability.getDenominator(); - + uint32_t Comp = Probability.getDenominator() - Probability.getNumerator(); unsigned FUnpredCost = Comp * FCycles; FUnpredCost /= Probability.getDenominator(); @@ -1330,6 +1455,57 @@ int llvm::getMatchingCondBranchOpcode(int Opc) { } +/// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether the +/// instruction is encoded with an 'S' bit is determined by the optional CPSR +/// def operand. +/// +/// This will go away once we can teach tblgen how to set the optional CPSR def +/// operand itself. +struct AddSubFlagsOpcodePair { + unsigned PseudoOpc; + unsigned MachineOpc; +}; + +static AddSubFlagsOpcodePair AddSubFlagsOpcodeMap[] = { + {ARM::ADDSri, ARM::ADDri}, + {ARM::ADDSrr, ARM::ADDrr}, + {ARM::ADDSrsi, ARM::ADDrsi}, + {ARM::ADDSrsr, ARM::ADDrsr}, + + {ARM::SUBSri, ARM::SUBri}, + {ARM::SUBSrr, ARM::SUBrr}, + {ARM::SUBSrsi, ARM::SUBrsi}, + {ARM::SUBSrsr, ARM::SUBrsr}, + + {ARM::RSBSri, ARM::RSBri}, + {ARM::RSBSrr, ARM::RSBrr}, + {ARM::RSBSrsi, ARM::RSBrsi}, + {ARM::RSBSrsr, ARM::RSBrsr}, + + {ARM::t2ADDSri, ARM::t2ADDri}, + {ARM::t2ADDSrr, ARM::t2ADDrr}, + {ARM::t2ADDSrs, ARM::t2ADDrs}, + + {ARM::t2SUBSri, ARM::t2SUBri}, + {ARM::t2SUBSrr, ARM::t2SUBrr}, + {ARM::t2SUBSrs, ARM::t2SUBrs}, + + {ARM::t2RSBSri, ARM::t2RSBri}, + {ARM::t2RSBSrs, ARM::t2RSBrs}, +}; + +unsigned llvm::convertAddSubFlagsOpcode(unsigned OldOpc) { + static const int NPairs = + sizeof(AddSubFlagsOpcodeMap) / sizeof(AddSubFlagsOpcodePair); + for (AddSubFlagsOpcodePair *OpcPair = &AddSubFlagsOpcodeMap[0], + *End = &AddSubFlagsOpcodeMap[NPairs]; OpcPair != End; ++OpcPair) { + if (OldOpc == OpcPair->PseudoOpc) { + return OpcPair->MachineOpc; + } + } + return 0; +} + void llvm::emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, @@ -1862,7 +2038,6 @@ ARMBaseInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData, case ARM::STMIB_UPD: case ARM::tLDMIA: case ARM::tLDMIA_UPD: - case ARM::tSTMIA: case ARM::tSTMIA_UPD: case ARM::tPOP_RET: case ARM::tPOP: @@ -2128,7 +2303,6 @@ ARMBaseInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, case ARM::STMDA_UPD: case ARM::STMDB_UPD: case ARM::STMIB_UPD: - case ARM::tSTMIA: case ARM::tSTMIA_UPD: case ARM::tPOP_RET: case ARM::tPOP: @@ -2567,6 +2741,15 @@ hasLowDefLatency(const InstrItineraryData *ItinData, return false; } +bool ARMBaseInstrInfo::verifyInstruction(const MachineInstr *MI, + StringRef &ErrInfo) const { + if (convertAddSubFlagsOpcode(MI->getOpcode())) { + ErrInfo = "Pseudo flag setting opcodes only exist in Selection DAG"; + return false; + } + return true; +} + bool ARMBaseInstrInfo::isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc, unsigned &AddSubOpc, @@ -2582,3 +2765,66 @@ ARMBaseInstrInfo::isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc, HasLane = Entry.HasLane; return true; } + +//===----------------------------------------------------------------------===// +// Execution domains. +//===----------------------------------------------------------------------===// +// +// Some instructions go down the NEON pipeline, some go down the VFP pipeline, +// and some can go down both. The vmov instructions go down the VFP pipeline, +// but they can be changed to vorr equivalents that are executed by the NEON +// pipeline. +// +// We use the following execution domain numbering: +// +enum ARMExeDomain { + ExeGeneric = 0, + ExeVFP = 1, + ExeNEON = 2 +}; +// +// Also see ARMInstrFormats.td and Domain* enums in ARMBaseInfo.h +// +std::pair +ARMBaseInstrInfo::getExecutionDomain(const MachineInstr *MI) const { + // VMOVD is a VFP instruction, but can be changed to NEON if it isn't + // predicated. + if (MI->getOpcode() == ARM::VMOVD && !isPredicated(MI)) + return std::make_pair(ExeVFP, (1<getDesc().TSFlags & ARMII::DomainMask; + + if (Domain & ARMII::DomainNEON) + return std::make_pair(ExeNEON, 0); + + // Certain instructions can go either way on Cortex-A8. + // Treat them as NEON instructions. + if ((Domain & ARMII::DomainNEONA8) && Subtarget.isCortexA8()) + return std::make_pair(ExeNEON, 0); + + if (Domain & ARMII::DomainVFP) + return std::make_pair(ExeVFP, 0); + + return std::make_pair(ExeGeneric, 0); +} + +void +ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { + // We only know how to change VMOVD into VORR. + assert(MI->getOpcode() == ARM::VMOVD && "Can only swizzle VMOVD"); + if (Domain != ExeNEON) + return; + + // Zap the predicate operands. + assert(!isPredicated(MI) && "Cannot predicate a VORRd"); + MI->RemoveOperand(3); + MI->RemoveOperand(2); + + // Change to a VORRd which requires two identical use operands. + MI->setDesc(get(ARM::VORRd)); + + // Add the extra source operand and new predicates. + // This will go before any implicit ops. + AddDefaultPred(MachineInstrBuilder(MI).addOperand(MI->getOperand(1))); +} diff --git a/lib/Target/ARM/ARMBaseInstrInfo.h b/lib/Target/ARM/ARMBaseInstrInfo.h index 507e8974bf7b..0f9f32179a31 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/lib/Target/ARM/ARMBaseInstrInfo.h @@ -27,146 +27,6 @@ namespace llvm { class ARMSubtarget; class ARMBaseRegisterInfo; -/// ARMII - This namespace holds all of the target specific flags that -/// instruction info tracks. -/// -namespace ARMII { - enum { - //===------------------------------------------------------------------===// - // Instruction Flags. - - //===------------------------------------------------------------------===// - // This four-bit field describes the addressing mode used. - AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h - - // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load - // and store ops only. Generic "updating" flag is used for ld/st multiple. - // The index mode enums are declared in ARMBaseInfo.h - IndexModeShift = 5, - IndexModeMask = 3 << IndexModeShift, - - //===------------------------------------------------------------------===// - // Instruction encoding formats. - // - FormShift = 7, - FormMask = 0x3f << FormShift, - - // Pseudo instructions - Pseudo = 0 << FormShift, - - // Multiply instructions - MulFrm = 1 << FormShift, - - // Branch instructions - BrFrm = 2 << FormShift, - BrMiscFrm = 3 << FormShift, - - // Data Processing instructions - DPFrm = 4 << FormShift, - DPSoRegFrm = 5 << FormShift, - - // Load and Store - LdFrm = 6 << FormShift, - StFrm = 7 << FormShift, - LdMiscFrm = 8 << FormShift, - StMiscFrm = 9 << FormShift, - LdStMulFrm = 10 << FormShift, - - LdStExFrm = 11 << FormShift, - - // Miscellaneous arithmetic instructions - ArithMiscFrm = 12 << FormShift, - SatFrm = 13 << FormShift, - - // Extend instructions - ExtFrm = 14 << FormShift, - - // VFP formats - VFPUnaryFrm = 15 << FormShift, - VFPBinaryFrm = 16 << FormShift, - VFPConv1Frm = 17 << FormShift, - VFPConv2Frm = 18 << FormShift, - VFPConv3Frm = 19 << FormShift, - VFPConv4Frm = 20 << FormShift, - VFPConv5Frm = 21 << FormShift, - VFPLdStFrm = 22 << FormShift, - VFPLdStMulFrm = 23 << FormShift, - VFPMiscFrm = 24 << FormShift, - - // Thumb format - ThumbFrm = 25 << FormShift, - - // Miscelleaneous format - MiscFrm = 26 << FormShift, - - // NEON formats - NGetLnFrm = 27 << FormShift, - NSetLnFrm = 28 << FormShift, - NDupFrm = 29 << FormShift, - NLdStFrm = 30 << FormShift, - N1RegModImmFrm= 31 << FormShift, - N2RegFrm = 32 << FormShift, - NVCVTFrm = 33 << FormShift, - NVDupLnFrm = 34 << FormShift, - N2RegVShLFrm = 35 << FormShift, - N2RegVShRFrm = 36 << FormShift, - N3RegFrm = 37 << FormShift, - N3RegVShFrm = 38 << FormShift, - NVExtFrm = 39 << FormShift, - NVMulSLFrm = 40 << FormShift, - NVTBLFrm = 41 << FormShift, - - //===------------------------------------------------------------------===// - // Misc flags. - - // UnaryDP - Indicates this is a unary data processing instruction, i.e. - // it doesn't have a Rn operand. - UnaryDP = 1 << 13, - - // Xform16Bit - Indicates this Thumb2 instruction may be transformed into - // a 16-bit Thumb instruction if certain conditions are met. - Xform16Bit = 1 << 14, - - //===------------------------------------------------------------------===// - // Code domain. - DomainShift = 15, - DomainMask = 7 << DomainShift, - DomainGeneral = 0 << DomainShift, - DomainVFP = 1 << DomainShift, - DomainNEON = 2 << DomainShift, - DomainNEONA8 = 4 << DomainShift, - - //===------------------------------------------------------------------===// - // Field shifts - such shifts are used to set field while generating - // machine instructions. - // - // FIXME: This list will need adjusting/fixing as the MC code emitter - // takes shape and the ARMCodeEmitter.cpp bits go away. - ShiftTypeShift = 4, - - M_BitShift = 5, - ShiftImmShift = 5, - ShiftShift = 7, - N_BitShift = 7, - ImmHiShift = 8, - SoRotImmShift = 8, - RegRsShift = 8, - ExtRotImmShift = 10, - RegRdLoShift = 12, - RegRdShift = 12, - RegRdHiShift = 16, - RegRnShift = 16, - S_BitShift = 20, - W_BitShift = 21, - AM3_I_BitShift = 22, - D_BitShift = 22, - U_BitShift = 23, - P_BitShift = 24, - I_BitShift = 25, - CondShift = 28 - }; -} - class ARMBaseInstrInfo : public ARMGenInstrInfo { const ARMSubtarget &Subtarget; @@ -241,6 +101,10 @@ class ARMBaseInstrInfo : public ARMGenInstrInfo { int &FrameIndex) const; virtual unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const; + virtual unsigned isLoadFromStackSlotPostFE(const MachineInstr *MI, + int &FrameIndex) const; + virtual unsigned isStoreToStackSlotPostFE(const MachineInstr *MI, + int &FrameIndex) const; virtual void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, @@ -259,6 +123,8 @@ class ARMBaseInstrInfo : public ARMGenInstrInfo { const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const; + virtual bool expandPostRAPseudo(MachineBasicBlock::iterator MI) const; + virtual MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, uint64_t Offset, @@ -346,6 +212,12 @@ class ARMBaseInstrInfo : public ARMGenInstrInfo { int getOperandLatency(const InstrItineraryData *ItinData, SDNode *DefNode, unsigned DefIdx, SDNode *UseNode, unsigned UseIdx) const; + + /// VFP/NEON execution domains. + std::pair + getExecutionDomain(const MachineInstr *MI) const; + void setExecutionDomain(MachineInstr *MI, unsigned Domain) const; + private: int getVLDMDefCycle(const InstrItineraryData *ItinData, const MCInstrDesc &DefMCID, @@ -382,6 +254,9 @@ class ARMBaseInstrInfo : public ARMGenInstrInfo { bool hasLowDefLatency(const InstrItineraryData *ItinData, const MachineInstr *DefMI, unsigned DefIdx) const; + /// verifyInstruction - Perform target specific instruction verification. + bool verifyInstruction(const MachineInstr *MI, StringRef &ErrInfo) const; + private: /// Modeling special VFP / NEON fp MLA / MLS hazards. @@ -464,6 +339,12 @@ ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg); int getMatchingCondBranchOpcode(int Opc); + +/// Map pseudo instructions that imply an 'S' bit onto real opcodes. Whether +/// the instruction is encoded with an 'S' bit is determined by the optional +/// CPSR def operand. +unsigned convertAddSubFlagsOpcode(unsigned OldOpc); + /// emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of /// instructions to materializea destreg = basereg + immediate in ARM / Thumb2 /// code. diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index ba422952ac1a..7c42342229a2 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -12,13 +12,13 @@ //===----------------------------------------------------------------------===// #include "ARM.h" -#include "ARMAddressingModes.h" #include "ARMBaseInstrInfo.h" #include "ARMBaseRegisterInfo.h" #include "ARMFrameLowering.h" #include "ARMInstrInfo.h" #include "ARMMachineFunctionInfo.h" #include "ARMSubtarget.h" +#include "MCTargetDesc/ARMAddressingModes.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" @@ -27,7 +27,6 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineLocation.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/Support/Debug.h" @@ -57,7 +56,7 @@ EnableBasePointer("arm-use-base-pointer", cl::Hidden, cl::init(true), ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii, const ARMSubtarget &sti) - : ARMGenRegisterInfo(), TII(tii), STI(sti), + : ARMGenRegisterInfo(ARM::LR), TII(tii), STI(sti), FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11), BasePtr(ARM::R6) { } @@ -354,7 +353,7 @@ const TargetRegisterClass* ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC) const { const TargetRegisterClass *Super = RC; - TargetRegisterClass::sc_iterator I = RC->superclasses_begin(); + TargetRegisterClass::sc_iterator I = RC->getSuperClasses(); do { switch (Super->getID()) { case ARM::GPRRegClassID: @@ -375,6 +374,13 @@ ARMBaseRegisterInfo::getPointerRegClass(unsigned Kind) const { return ARM::GPRRegisterClass; } +const TargetRegisterClass * +ARMBaseRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { + if (RC == &ARM::CCRRegClass) + return 0; // Can't copy CCR registers. + return RC; +} + unsigned ARMBaseRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const { @@ -487,19 +493,19 @@ ARMBaseRegisterInfo::getRawAllocationOrder(const TargetRegisterClass *RC, if (!TFI->hasFP(MF)) { if (!STI.isR9Reserved()) - return ArrayRef(GPREven1); + return makeArrayRef(GPREven1); else - return ArrayRef(GPREven4); + return makeArrayRef(GPREven4); } else if (FramePtr == ARM::R7) { if (!STI.isR9Reserved()) - return ArrayRef(GPREven2); + return makeArrayRef(GPREven2); else - return ArrayRef(GPREven5); + return makeArrayRef(GPREven5); } else { // FramePtr == ARM::R11 if (!STI.isR9Reserved()) - return ArrayRef(GPREven3); + return makeArrayRef(GPREven3); else - return ArrayRef(GPREven6); + return makeArrayRef(GPREven6); } } else if (HintType == ARMRI::RegPairOdd) { if (isPhysicalRegister(HintReg) && getRegisterPairOdd(HintReg, MF) == 0) @@ -509,19 +515,19 @@ ARMBaseRegisterInfo::getRawAllocationOrder(const TargetRegisterClass *RC, if (!TFI->hasFP(MF)) { if (!STI.isR9Reserved()) - return ArrayRef(GPROdd1); + return makeArrayRef(GPROdd1); else - return ArrayRef(GPROdd4); + return makeArrayRef(GPROdd4); } else if (FramePtr == ARM::R7) { if (!STI.isR9Reserved()) - return ArrayRef(GPROdd2); + return makeArrayRef(GPROdd2); else - return ArrayRef(GPROdd5); + return makeArrayRef(GPROdd5); } else { // FramePtr == ARM::R11 if (!STI.isR9Reserved()) - return ArrayRef(GPROdd3); + return makeArrayRef(GPROdd3); else - return ArrayRef(GPROdd6); + return makeArrayRef(GPROdd6); } } return RC->getRawAllocationOrder(MF); @@ -649,10 +655,6 @@ cannotEliminateFrame(const MachineFunction &MF) const { || needsStackRealignment(MF); } -unsigned ARMBaseRegisterInfo::getRARegister() const { - return ARM::LR; -} - unsigned ARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const { const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); @@ -672,99 +674,54 @@ unsigned ARMBaseRegisterInfo::getEHHandlerRegister() const { return 0; } -int ARMBaseRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { - return ARMGenRegisterInfo::getDwarfRegNumFull(RegNum, 0); -} - -int ARMBaseRegisterInfo::getLLVMRegNum(unsigned DwarfRegNo, bool isEH) const { - return ARMGenRegisterInfo::getLLVMRegNumFull(DwarfRegNo,0); -} - unsigned ARMBaseRegisterInfo::getRegisterPairEven(unsigned Reg, const MachineFunction &MF) const { switch (Reg) { default: break; // Return 0 if either register of the pair is a special register. // So no R12, etc. - case ARM::R1: - return ARM::R0; - case ARM::R3: - return ARM::R2; - case ARM::R5: - return ARM::R4; + case ARM::R1: return ARM::R0; + case ARM::R3: return ARM::R2; + case ARM::R5: return ARM::R4; case ARM::R7: return (isReservedReg(MF, ARM::R7) || isReservedReg(MF, ARM::R6)) ? 0 : ARM::R6; - case ARM::R9: - return isReservedReg(MF, ARM::R9) ? 0 :ARM::R8; - case ARM::R11: - return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10; + case ARM::R9: return isReservedReg(MF, ARM::R9) ? 0 :ARM::R8; + case ARM::R11: return isReservedReg(MF, ARM::R11) ? 0 : ARM::R10; - case ARM::S1: - return ARM::S0; - case ARM::S3: - return ARM::S2; - case ARM::S5: - return ARM::S4; - case ARM::S7: - return ARM::S6; - case ARM::S9: - return ARM::S8; - case ARM::S11: - return ARM::S10; - case ARM::S13: - return ARM::S12; - case ARM::S15: - return ARM::S14; - case ARM::S17: - return ARM::S16; - case ARM::S19: - return ARM::S18; - case ARM::S21: - return ARM::S20; - case ARM::S23: - return ARM::S22; - case ARM::S25: - return ARM::S24; - case ARM::S27: - return ARM::S26; - case ARM::S29: - return ARM::S28; - case ARM::S31: - return ARM::S30; + case ARM::S1: return ARM::S0; + case ARM::S3: return ARM::S2; + case ARM::S5: return ARM::S4; + case ARM::S7: return ARM::S6; + case ARM::S9: return ARM::S8; + case ARM::S11: return ARM::S10; + case ARM::S13: return ARM::S12; + case ARM::S15: return ARM::S14; + case ARM::S17: return ARM::S16; + case ARM::S19: return ARM::S18; + case ARM::S21: return ARM::S20; + case ARM::S23: return ARM::S22; + case ARM::S25: return ARM::S24; + case ARM::S27: return ARM::S26; + case ARM::S29: return ARM::S28; + case ARM::S31: return ARM::S30; - case ARM::D1: - return ARM::D0; - case ARM::D3: - return ARM::D2; - case ARM::D5: - return ARM::D4; - case ARM::D7: - return ARM::D6; - case ARM::D9: - return ARM::D8; - case ARM::D11: - return ARM::D10; - case ARM::D13: - return ARM::D12; - case ARM::D15: - return ARM::D14; - case ARM::D17: - return ARM::D16; - case ARM::D19: - return ARM::D18; - case ARM::D21: - return ARM::D20; - case ARM::D23: - return ARM::D22; - case ARM::D25: - return ARM::D24; - case ARM::D27: - return ARM::D26; - case ARM::D29: - return ARM::D28; - case ARM::D31: - return ARM::D30; + case ARM::D1: return ARM::D0; + case ARM::D3: return ARM::D2; + case ARM::D5: return ARM::D4; + case ARM::D7: return ARM::D6; + case ARM::D9: return ARM::D8; + case ARM::D11: return ARM::D10; + case ARM::D13: return ARM::D12; + case ARM::D15: return ARM::D14; + case ARM::D17: return ARM::D16; + case ARM::D19: return ARM::D18; + case ARM::D21: return ARM::D20; + case ARM::D23: return ARM::D22; + case ARM::D25: return ARM::D24; + case ARM::D27: return ARM::D26; + case ARM::D29: return ARM::D28; + case ARM::D31: return ARM::D30; } return 0; @@ -776,85 +733,48 @@ unsigned ARMBaseRegisterInfo::getRegisterPairOdd(unsigned Reg, default: break; // Return 0 if either register of the pair is a special register. // So no R12, etc. - case ARM::R0: - return ARM::R1; - case ARM::R2: - return ARM::R3; - case ARM::R4: - return ARM::R5; + case ARM::R0: return ARM::R1; + case ARM::R2: return ARM::R3; + case ARM::R4: return ARM::R5; case ARM::R6: return (isReservedReg(MF, ARM::R7) || isReservedReg(MF, ARM::R6)) ? 0 : ARM::R7; - case ARM::R8: - return isReservedReg(MF, ARM::R9) ? 0 :ARM::R9; - case ARM::R10: - return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11; + case ARM::R8: return isReservedReg(MF, ARM::R9) ? 0 :ARM::R9; + case ARM::R10: return isReservedReg(MF, ARM::R11) ? 0 : ARM::R11; - case ARM::S0: - return ARM::S1; - case ARM::S2: - return ARM::S3; - case ARM::S4: - return ARM::S5; - case ARM::S6: - return ARM::S7; - case ARM::S8: - return ARM::S9; - case ARM::S10: - return ARM::S11; - case ARM::S12: - return ARM::S13; - case ARM::S14: - return ARM::S15; - case ARM::S16: - return ARM::S17; - case ARM::S18: - return ARM::S19; - case ARM::S20: - return ARM::S21; - case ARM::S22: - return ARM::S23; - case ARM::S24: - return ARM::S25; - case ARM::S26: - return ARM::S27; - case ARM::S28: - return ARM::S29; - case ARM::S30: - return ARM::S31; + case ARM::S0: return ARM::S1; + case ARM::S2: return ARM::S3; + case ARM::S4: return ARM::S5; + case ARM::S6: return ARM::S7; + case ARM::S8: return ARM::S9; + case ARM::S10: return ARM::S11; + case ARM::S12: return ARM::S13; + case ARM::S14: return ARM::S15; + case ARM::S16: return ARM::S17; + case ARM::S18: return ARM::S19; + case ARM::S20: return ARM::S21; + case ARM::S22: return ARM::S23; + case ARM::S24: return ARM::S25; + case ARM::S26: return ARM::S27; + case ARM::S28: return ARM::S29; + case ARM::S30: return ARM::S31; - case ARM::D0: - return ARM::D1; - case ARM::D2: - return ARM::D3; - case ARM::D4: - return ARM::D5; - case ARM::D6: - return ARM::D7; - case ARM::D8: - return ARM::D9; - case ARM::D10: - return ARM::D11; - case ARM::D12: - return ARM::D13; - case ARM::D14: - return ARM::D15; - case ARM::D16: - return ARM::D17; - case ARM::D18: - return ARM::D19; - case ARM::D20: - return ARM::D21; - case ARM::D22: - return ARM::D23; - case ARM::D24: - return ARM::D25; - case ARM::D26: - return ARM::D27; - case ARM::D28: - return ARM::D29; - case ARM::D30: - return ARM::D31; + case ARM::D0: return ARM::D1; + case ARM::D2: return ARM::D3; + case ARM::D4: return ARM::D5; + case ARM::D6: return ARM::D7; + case ARM::D8: return ARM::D9; + case ARM::D10: return ARM::D11; + case ARM::D12: return ARM::D13; + case ARM::D14: return ARM::D15; + case ARM::D16: return ARM::D17; + case ARM::D18: return ARM::D19; + case ARM::D20: return ARM::D21; + case ARM::D22: return ARM::D23; + case ARM::D24: return ARM::D25; + case ARM::D26: return ARM::D27; + case ARM::D28: return ARM::D29; + case ARM::D30: return ARM::D31; } return 0; @@ -1111,11 +1031,11 @@ materializeFrameBaseRegister(MachineBasicBlock *MBB, MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo(); MRI.constrainRegClass(BaseReg, TII.getRegClass(MCID, 0, this)); - MachineInstrBuilder MIB = BuildMI(*MBB, Ins, DL, MCID, BaseReg) - .addFrameIndex(FrameIdx).addImm(Offset); + MachineInstrBuilder MIB = AddDefaultPred(BuildMI(*MBB, Ins, DL, MCID, BaseReg) + .addFrameIndex(FrameIdx).addImm(Offset)); if (!AFI->isThumb1OnlyFunction()) - AddDefaultCC(AddDefaultPred(MIB)); + AddDefaultCC(MIB); } void @@ -1143,6 +1063,7 @@ ARMBaseRegisterInfo::resolveFrameIndex(MachineBasicBlock::iterator I, Done = rewriteT2FrameIndex(MI, i, BaseReg, Off, TII); } assert (Done && "Unable to resolve frame index!"); + (void)Done; } bool ARMBaseRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI, diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.h b/lib/Target/ARM/ARMBaseRegisterInfo.h index b4b4059e7361..fee17ff3c1ca 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -33,19 +33,6 @@ namespace ARMRI { }; } -/// isARMLowRegister - Returns true if the register is low register r0-r7. -/// -static inline bool isARMLowRegister(unsigned Reg) { - using namespace ARM; - switch (Reg) { - case R0: case R1: case R2: case R3: - case R4: case R5: case R6: case R7: - return true; - default: - return false; - } -} - /// isARMArea1Register - Returns true if the register is a low register (r0-r7) /// or a stack/pc register that we should push/pop. static inline bool isARMArea1Register(unsigned Reg, bool isDarwin) { @@ -129,6 +116,8 @@ class ARMBaseRegisterInfo : public ARMGenRegisterInfo { unsigned &NewSubIdx) const; const TargetRegisterClass *getPointerRegClass(unsigned Kind = 0) const; + const TargetRegisterClass* + getCrossCopyRegClass(const TargetRegisterClass *RC) const; const TargetRegisterClass* getLargestLegalSuperClass(const TargetRegisterClass *RC) const; @@ -164,7 +153,6 @@ class ARMBaseRegisterInfo : public ARMGenRegisterInfo { bool cannotEliminateFrame(const MachineFunction &MF) const; // Debug information queries. - unsigned getRARegister() const; unsigned getFrameRegister(const MachineFunction &MF) const; unsigned getBaseRegister() const { return BasePtr; } @@ -172,9 +160,6 @@ class ARMBaseRegisterInfo : public ARMGenRegisterInfo { unsigned getEHExceptionRegister() const; unsigned getEHHandlerRegister() const; - int getDwarfRegNum(unsigned RegNum, bool isEH) const; - int getLLVMRegNum(unsigned RegNum, bool isEH) const; - bool isLowRegister(unsigned Reg) const; diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index d6fca6277501..4148d4ab10e9 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -14,12 +14,12 @@ #define DEBUG_TYPE "jit" #include "ARM.h" -#include "ARMAddressingModes.h" #include "ARMConstantPoolValue.h" #include "ARMInstrInfo.h" #include "ARMRelocations.h" #include "ARMSubtarget.h" #include "ARMTargetMachine.h" +#include "MCTargetDesc/ARMAddressingModes.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" @@ -161,11 +161,11 @@ namespace { // are already handled elsewhere. They are placeholders to allow this // encoder to continue to function until the MC encoder is sufficiently // far along that this one can be eliminated entirely. - unsigned NEONThumb2DataIPostEncoder(const MachineInstr &MI, unsigned Val) + unsigned NEONThumb2DataIPostEncoder(const MachineInstr &MI, unsigned Val) const { return 0; } - unsigned NEONThumb2LoadStorePostEncoder(const MachineInstr &MI,unsigned Val) + unsigned NEONThumb2LoadStorePostEncoder(const MachineInstr &MI,unsigned Val) const { return 0; } - unsigned NEONThumb2DupPostEncoder(const MachineInstr &MI,unsigned Val) + unsigned NEONThumb2DupPostEncoder(const MachineInstr &MI,unsigned Val) const { return 0; } unsigned VFPThumb2PostEncoder(const MachineInstr&MI, unsigned Val) const { return 0; } @@ -189,13 +189,17 @@ namespace { unsigned Op) const { return 0; } unsigned getARMBranchTargetOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getARMBLXTargetOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } unsigned getCCOutOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getSOImmOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getT2SOImmOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } - unsigned getSORegOpValue(const MachineInstr &MI, unsigned Op) + unsigned getSORegRegOpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } + unsigned getSORegImmOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getThumbAddrModeRegRegOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } @@ -203,8 +207,12 @@ namespace { const { return 0; } unsigned getT2AddrModeImm8OpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getT2Imm8s4OpValue(const MachineInstr &MI, unsigned Op) + const { return 0; } unsigned getT2AddrModeImm8s4OpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getT2AddrModeImm0_1020s4OpValue(const MachineInstr &MI,unsigned Op) + const { return 0; } unsigned getT2AddrModeImm8OffsetOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getT2AddrModeImm12OffsetOpValue(const MachineInstr &MI,unsigned Op) @@ -213,10 +221,6 @@ namespace { const { return 0; } unsigned getT2SORegOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } - unsigned getRotImmOpValue(const MachineInstr &MI, unsigned Op) - const { return 0; } - unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op) - const { return 0; } unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op) @@ -230,8 +234,6 @@ namespace { const { return 0; } unsigned getBitfieldInvertedMaskOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } - unsigned getMsbOpValue(const MachineInstr &MI, - unsigned Op) const { return 0; } unsigned getSsatBitPosValue(const MachineInstr &MI, unsigned Op) const { return 0; } uint32_t getLdStmModeOpValue(const MachineInstr &MI, unsigned OpIdx) @@ -268,6 +270,8 @@ namespace { const { return 0;} uint32_t getAddrMode2OffsetOpValue(const MachineInstr &MI, unsigned OpIdx) const { return 0;} + uint32_t getPostIdxRegOpValue(const MachineInstr &MI, unsigned OpIdx) + const { return 0;} uint32_t getAddrMode3OffsetOpValue(const MachineInstr &MI, unsigned OpIdx) const { return 0;} uint32_t getAddrMode3OpValue(const MachineInstr &MI, unsigned Op) @@ -632,15 +636,16 @@ void ARMCodeEmitter::emitConstPoolInstruction(const MachineInstr &MI) { << (void*)MCE.getCurrentPCValue() << " " << *ACPV << '\n'); assert(ACPV->isGlobalValue() && "unsupported constant pool value"); - const GlobalValue *GV = ACPV->getGV(); + const GlobalValue *GV = cast(ACPV)->getGV(); if (GV) { Reloc::Model RelocM = TM.getRelocationModel(); emitGlobalAddress(GV, ARM::reloc_arm_machine_cp_entry, isa(GV), Subtarget->GVIsIndirectSymbol(GV, RelocM), (intptr_t)ACPV); - } else { - emitExternalSymbolAddress(ACPV->getSymbol(), ARM::reloc_arm_absolute); + } else { + const char *Sym = cast(ACPV)->getSymbol(); + emitExternalSymbolAddress(Sym, ARM::reloc_arm_absolute); } emitWordLE(0); } else { @@ -983,7 +988,7 @@ unsigned ARMCodeEmitter::getMachineSoImmOpValue(unsigned SoImm) { unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI, const MCInstrDesc &MCID) const { - for (unsigned i = MI.getNumOperands(), e = MCID.getNumOperands(); i >= e; --i){ + for (unsigned i = MI.getNumOperands(), e = MCID.getNumOperands(); i >= e;--i){ const MachineOperand &MO = MI.getOperand(i-1); if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) return 1 << ARMII::S_BitShift; diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp index f45ebdc53500..3e3a4134c704 100644 --- a/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -15,10 +15,10 @@ #define DEBUG_TYPE "arm-cp-islands" #include "ARM.h" -#include "ARMAddressingModes.h" #include "ARMMachineFunctionInfo.h" #include "ARMInstrInfo.h" #include "Thumb2InstrInfo.h" +#include "MCTargetDesc/ARMAddressingModes.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" @@ -739,7 +739,11 @@ MachineBasicBlock *ARMConstantIslands::SplitBlockBeforeInstr(MachineInstr *MI) { // There doesn't seem to be meaningful DebugInfo available; this doesn't // correspond to anything in the source. unsigned Opc = isThumb ? (isThumb2 ? ARM::t2B : ARM::tB) : ARM::B; - BuildMI(OrigBB, DebugLoc(), TII->get(Opc)).addMBB(NewBB); + if (!isThumb) + BuildMI(OrigBB, DebugLoc(), TII->get(Opc)).addMBB(NewBB); + else + BuildMI(OrigBB, DebugLoc(), TII->get(Opc)).addMBB(NewBB) + .addImm(ARMCC::AL).addReg(0); ++NumSplit; // Update the CFG. All succs of OrigBB are now succs of NewBB. @@ -1151,7 +1155,11 @@ void ARMConstantIslands::CreateNewWater(unsigned CPUserIndex, // targets will be exchanged, and the altered branch may be out of // range, so the machinery has to know about it. int UncondBr = isThumb ? ((isThumb2) ? ARM::t2B : ARM::tB) : ARM::B; - BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB); + if (!isThumb) + BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB); + else + BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB) + .addImm(ARMCC::AL).addReg(0); unsigned MaxDisp = getUnconditionalBrDisp(UncondBr); ImmBranches.push_back(ImmBranch(&UserMBB->back(), MaxDisp, false, UncondBr)); @@ -1512,7 +1520,11 @@ ARMConstantIslands::FixUpConditionalBr(MachineFunction &MF, ImmBranch &Br) { .addMBB(NextBB).addImm(CC).addReg(CCReg); Br.MI = &MBB->back(); BBSizes[MBB->getNumber()] += TII->GetInstSizeInBytes(&MBB->back()); - BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB); + if (isThumb) + BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB) + .addImm(ARMCC::AL).addReg(0); + else + BuildMI(MBB, DebugLoc(), TII->get(Br.UncondBr)).addMBB(DestBB); BBSizes[MBB->getNumber()] += TII->GetInstSizeInBytes(&MBB->back()); unsigned MaxDisp = getUnconditionalBrDisp(Br.UncondBr); ImmBranches.push_back(ImmBranch(&MBB->back(), MaxDisp, false, Br.UncondBr)); @@ -1891,7 +1903,8 @@ AdjustJTTargetBlockForward(MachineBasicBlock *BB, MachineBasicBlock *JTBB) // There doesn't seem to be meaningful DebugInfo available; this doesn't // correspond directly to anything in the source. assert (isThumb2 && "Adjusting for TB[BH] but not in Thumb2?"); - BuildMI(NewBB, DebugLoc(), TII->get(ARM::t2B)).addMBB(BB); + BuildMI(NewBB, DebugLoc(), TII->get(ARM::t2B)).addMBB(BB) + .addImm(ARMCC::AL).addReg(0); // Update internal data structures to account for the newly inserted MBB. MF.RenumberBlocks(NewBB); diff --git a/lib/Target/ARM/ARMConstantPoolValue.cpp b/lib/Target/ARM/ARMConstantPoolValue.cpp index 165a1d849ad5..aadfd4779db3 100644 --- a/lib/Target/ARM/ARMConstantPoolValue.cpp +++ b/lib/Target/ARM/ARMConstantPoolValue.cpp @@ -17,79 +17,57 @@ #include "llvm/Constants.h" #include "llvm/GlobalValue.h" #include "llvm/Type.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/Support/raw_ostream.h" #include using namespace llvm; -ARMConstantPoolValue::ARMConstantPoolValue(const Constant *cval, unsigned id, - ARMCP::ARMCPKind K, +//===----------------------------------------------------------------------===// +// ARMConstantPoolValue +//===----------------------------------------------------------------------===// + +ARMConstantPoolValue::ARMConstantPoolValue(Type *Ty, unsigned id, + ARMCP::ARMCPKind kind, unsigned char PCAdj, - ARMCP::ARMCPModifier Modif, - bool AddCA) - : MachineConstantPoolValue((const Type*)cval->getType()), - CVal(cval), S(NULL), LabelId(id), Kind(K), PCAdjust(PCAdj), - Modifier(Modif), AddCurrentAddress(AddCA) {} + ARMCP::ARMCPModifier modifier, + bool addCurrentAddress) + : MachineConstantPoolValue(Ty), LabelId(id), Kind(kind), + PCAdjust(PCAdj), Modifier(modifier), + AddCurrentAddress(addCurrentAddress) {} -ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, - const char *s, unsigned id, +ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C, unsigned id, + ARMCP::ARMCPKind kind, unsigned char PCAdj, - ARMCP::ARMCPModifier Modif, - bool AddCA) - : MachineConstantPoolValue((const Type*)Type::getInt32Ty(C)), - CVal(NULL), S(strdup(s)), LabelId(id), Kind(ARMCP::CPExtSymbol), - PCAdjust(PCAdj), Modifier(Modif), AddCurrentAddress(AddCA) {} + ARMCP::ARMCPModifier modifier, + bool addCurrentAddress) + : MachineConstantPoolValue((Type*)Type::getInt32Ty(C)), + LabelId(id), Kind(kind), PCAdjust(PCAdj), Modifier(modifier), + AddCurrentAddress(addCurrentAddress) {} -ARMConstantPoolValue::ARMConstantPoolValue(const GlobalValue *gv, - ARMCP::ARMCPModifier Modif) - : MachineConstantPoolValue((const Type*)Type::getInt32Ty(gv->getContext())), - CVal(gv), S(NULL), LabelId(0), Kind(ARMCP::CPValue), PCAdjust(0), - Modifier(Modif), AddCurrentAddress(false) {} +ARMConstantPoolValue::~ARMConstantPoolValue() {} -const GlobalValue *ARMConstantPoolValue::getGV() const { - return dyn_cast_or_null(CVal); -} - -const BlockAddress *ARMConstantPoolValue::getBlockAddress() const { - return dyn_cast_or_null(CVal); -} - -static bool CPV_streq(const char *S1, const char *S2) { - if (S1 == S2) - return true; - if (S1 && S2 && strcmp(S1, S2) == 0) - return true; - return false; +const char *ARMConstantPoolValue::getModifierText() const { + switch (Modifier) { + default: llvm_unreachable("Unknown modifier!"); + // FIXME: Are these case sensitive? It'd be nice to lower-case all the + // strings if that's legal. + case ARMCP::no_modifier: return "none"; + case ARMCP::TLSGD: return "tlsgd"; + case ARMCP::GOT: return "GOT"; + case ARMCP::GOTOFF: return "GOTOFF"; + case ARMCP::GOTTPOFF: return "gottpoff"; + case ARMCP::TPOFF: return "tpoff"; + } } int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment) { - unsigned AlignMask = Alignment - 1; - const std::vector Constants = CP->getConstants(); - for (unsigned i = 0, e = Constants.size(); i != e; ++i) { - if (Constants[i].isMachineConstantPoolEntry() && - (Constants[i].getAlignment() & AlignMask) == 0) { - ARMConstantPoolValue *CPV = - (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; - if (CPV->CVal == CVal && - CPV->LabelId == LabelId && - CPV->PCAdjust == PCAdjust && - CPV_streq(CPV->S, S) && - CPV->Modifier == Modifier) - return i; - } - } - + assert(false && "Shouldn't be calling this directly!"); return -1; } -ARMConstantPoolValue::~ARMConstantPoolValue() { - free((void*)S); -} - void -ARMConstantPoolValue::AddSelectionDAGCSEId(FoldingSetNodeID &ID) { - ID.AddPointer(CVal); - ID.AddPointer(S); +ARMConstantPoolValue::addSelectionDAGCSEId(FoldingSetNodeID &ID) { ID.AddInteger(LabelId); ID.AddInteger(PCAdjust); } @@ -97,9 +75,7 @@ ARMConstantPoolValue::AddSelectionDAGCSEId(FoldingSetNodeID &ID) { bool ARMConstantPoolValue::hasSameValue(ARMConstantPoolValue *ACPV) { if (ACPV->Kind == Kind && - ACPV->CVal == CVal && ACPV->PCAdjust == PCAdjust && - CPV_streq(ACPV->S, S) && ACPV->Modifier == Modifier) { if (ACPV->LabelId == LabelId) return true; @@ -115,12 +91,7 @@ void ARMConstantPoolValue::dump() const { errs() << " " << *this; } - void ARMConstantPoolValue::print(raw_ostream &O) const { - if (CVal) - O << CVal->getName(); - else - O << S; if (Modifier) O << "(" << getModifierText() << ")"; if (PCAdjust != 0) { O << "-(LPC" << LabelId << "+" << (unsigned)PCAdjust; @@ -128,3 +99,221 @@ void ARMConstantPoolValue::print(raw_ostream &O) const { O << ")"; } } + +//===----------------------------------------------------------------------===// +// ARMConstantPoolConstant +//===----------------------------------------------------------------------===// + +ARMConstantPoolConstant::ARMConstantPoolConstant(Type *Ty, + const Constant *C, + unsigned ID, + ARMCP::ARMCPKind Kind, + unsigned char PCAdj, + ARMCP::ARMCPModifier Modifier, + bool AddCurrentAddress) + : ARMConstantPoolValue(Ty, ID, Kind, PCAdj, Modifier, AddCurrentAddress), + CVal(C) {} + +ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C, + unsigned ID, + ARMCP::ARMCPKind Kind, + unsigned char PCAdj, + ARMCP::ARMCPModifier Modifier, + bool AddCurrentAddress) + : ARMConstantPoolValue((Type*)C->getType(), ID, Kind, PCAdj, Modifier, + AddCurrentAddress), + CVal(C) {} + +ARMConstantPoolConstant * +ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) { + return new ARMConstantPoolConstant(C, ID, ARMCP::CPValue, 0, + ARMCP::no_modifier, false); +} + +ARMConstantPoolConstant * +ARMConstantPoolConstant::Create(const GlobalValue *GV, + ARMCP::ARMCPModifier Modifier) { + return new ARMConstantPoolConstant((Type*)Type::getInt32Ty(GV->getContext()), + GV, 0, ARMCP::CPValue, 0, + Modifier, false); +} + +ARMConstantPoolConstant * +ARMConstantPoolConstant::Create(const Constant *C, unsigned ID, + ARMCP::ARMCPKind Kind, unsigned char PCAdj) { + return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, + ARMCP::no_modifier, false); +} + +ARMConstantPoolConstant * +ARMConstantPoolConstant::Create(const Constant *C, unsigned ID, + ARMCP::ARMCPKind Kind, unsigned char PCAdj, + ARMCP::ARMCPModifier Modifier, + bool AddCurrentAddress) { + return new ARMConstantPoolConstant(C, ID, Kind, PCAdj, Modifier, + AddCurrentAddress); +} + +const GlobalValue *ARMConstantPoolConstant::getGV() const { + return dyn_cast_or_null(CVal); +} + +const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const { + return dyn_cast_or_null(CVal); +} + +int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, + unsigned Alignment) { + unsigned AlignMask = Alignment - 1; + const std::vector Constants = CP->getConstants(); + for (unsigned i = 0, e = Constants.size(); i != e; ++i) { + if (Constants[i].isMachineConstantPoolEntry() && + (Constants[i].getAlignment() & AlignMask) == 0) { + ARMConstantPoolValue *CPV = + (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; + ARMConstantPoolConstant *APC = dyn_cast(CPV); + if (!APC) continue; + if (APC->CVal == CVal && equals(APC)) + return i; + } + } + + return -1; +} + +bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { + const ARMConstantPoolConstant *ACPC = dyn_cast(ACPV); + return ACPC && ACPC->CVal == CVal && ARMConstantPoolValue::hasSameValue(ACPV); +} + +void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { + ID.AddPointer(CVal); + ARMConstantPoolValue::addSelectionDAGCSEId(ID); +} + +void ARMConstantPoolConstant::print(raw_ostream &O) const { + O << CVal->getName(); + ARMConstantPoolValue::print(O); +} + +//===----------------------------------------------------------------------===// +// ARMConstantPoolSymbol +//===----------------------------------------------------------------------===// + +ARMConstantPoolSymbol::ARMConstantPoolSymbol(LLVMContext &C, const char *s, + unsigned id, + unsigned char PCAdj, + ARMCP::ARMCPModifier Modifier, + bool AddCurrentAddress) + : ARMConstantPoolValue(C, id, ARMCP::CPExtSymbol, PCAdj, Modifier, + AddCurrentAddress), + S(strdup(s)) {} + +ARMConstantPoolSymbol::~ARMConstantPoolSymbol() { + free((void*)S); +} + +ARMConstantPoolSymbol * +ARMConstantPoolSymbol::Create(LLVMContext &C, const char *s, + unsigned ID, unsigned char PCAdj) { + return new ARMConstantPoolSymbol(C, s, ID, PCAdj, ARMCP::no_modifier, false); +} + +static bool CPV_streq(const char *S1, const char *S2) { + if (S1 == S2) + return true; + if (S1 && S2 && strcmp(S1, S2) == 0) + return true; + return false; +} + +int ARMConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP, + unsigned Alignment) { + unsigned AlignMask = Alignment - 1; + const std::vector Constants = CP->getConstants(); + for (unsigned i = 0, e = Constants.size(); i != e; ++i) { + if (Constants[i].isMachineConstantPoolEntry() && + (Constants[i].getAlignment() & AlignMask) == 0) { + ARMConstantPoolValue *CPV = + (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; + ARMConstantPoolSymbol *APS = dyn_cast(CPV); + if (!APS) continue; + + if (CPV_streq(APS->S, S) && equals(APS)) + return i; + } + } + + return -1; +} + +bool ARMConstantPoolSymbol::hasSameValue(ARMConstantPoolValue *ACPV) { + const ARMConstantPoolSymbol *ACPS = dyn_cast(ACPV); + return ACPS && CPV_streq(ACPS->S, S) && + ARMConstantPoolValue::hasSameValue(ACPV); +} + +void ARMConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) { + ID.AddPointer(S); + ARMConstantPoolValue::addSelectionDAGCSEId(ID); +} + +void ARMConstantPoolSymbol::print(raw_ostream &O) const { + O << S; + ARMConstantPoolValue::print(O); +} + +//===----------------------------------------------------------------------===// +// ARMConstantPoolMBB +//===----------------------------------------------------------------------===// + +ARMConstantPoolMBB::ARMConstantPoolMBB(LLVMContext &C, + const MachineBasicBlock *mbb, + unsigned id, unsigned char PCAdj, + ARMCP::ARMCPModifier Modifier, + bool AddCurrentAddress) + : ARMConstantPoolValue(C, id, ARMCP::CPMachineBasicBlock, PCAdj, + Modifier, AddCurrentAddress), + MBB(mbb) {} + +ARMConstantPoolMBB *ARMConstantPoolMBB::Create(LLVMContext &C, + const MachineBasicBlock *mbb, + unsigned ID, + unsigned char PCAdj) { + return new ARMConstantPoolMBB(C, mbb, ID, PCAdj, ARMCP::no_modifier, false); +} + +int ARMConstantPoolMBB::getExistingMachineCPValue(MachineConstantPool *CP, + unsigned Alignment) { + unsigned AlignMask = Alignment - 1; + const std::vector Constants = CP->getConstants(); + for (unsigned i = 0, e = Constants.size(); i != e; ++i) { + if (Constants[i].isMachineConstantPoolEntry() && + (Constants[i].getAlignment() & AlignMask) == 0) { + ARMConstantPoolValue *CPV = + (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; + ARMConstantPoolMBB *APMBB = dyn_cast(CPV); + if (!APMBB) continue; + + if (APMBB->MBB == MBB && equals(APMBB)) + return i; + } + } + + return -1; +} + +bool ARMConstantPoolMBB::hasSameValue(ARMConstantPoolValue *ACPV) { + const ARMConstantPoolMBB *ACPMBB = dyn_cast(ACPV); + return ACPMBB && ACPMBB->MBB == MBB && + ARMConstantPoolValue::hasSameValue(ACPV); +} + +void ARMConstantPoolMBB::addSelectionDAGCSEId(FoldingSetNodeID &ID) { + ID.AddPointer(MBB); + ARMConstantPoolValue::addSelectionDAGCSEId(ID); +} + +void ARMConstantPoolMBB::print(raw_ostream &O) const { + ARMConstantPoolValue::print(O); +} diff --git a/lib/Target/ARM/ARMConstantPoolValue.h b/lib/Target/ARM/ARMConstantPoolValue.h index d008811c40e4..0d0def32b7d8 100644 --- a/lib/Target/ARM/ARMConstantPoolValue.h +++ b/lib/Target/ARM/ARMConstantPoolValue.h @@ -20,17 +20,19 @@ namespace llvm { -class Constant; class BlockAddress; +class Constant; class GlobalValue; class LLVMContext; +class MachineBasicBlock; namespace ARMCP { enum ARMCPKind { CPValue, CPExtSymbol, CPBlockAddress, - CPLSDA + CPLSDA, + CPMachineBasicBlock }; enum ARMCPModifier { @@ -47,8 +49,6 @@ namespace ARMCP { /// represent PC-relative displacement between the address of the load /// instruction and the constant being loaded, i.e. (&GV-(LPIC+8)). class ARMConstantPoolValue : public MachineConstantPoolValue { - const Constant *CVal; // Constant being loaded. - const char *S; // ExtSymbol being loaded. unsigned LabelId; // Label id of the load. ARMCP::ARMCPKind Kind; // Kind of constant. unsigned char PCAdjust; // Extra adjustment if constantpool is pc-relative. @@ -56,60 +56,54 @@ class ARMConstantPoolValue : public MachineConstantPoolValue { ARMCP::ARMCPModifier Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8)) bool AddCurrentAddress; -public: - ARMConstantPoolValue(const Constant *cval, unsigned id, - ARMCP::ARMCPKind Kind = ARMCP::CPValue, - unsigned char PCAdj = 0, - ARMCP::ARMCPModifier Modifier = ARMCP::no_modifier, - bool AddCurrentAddress = false); - ARMConstantPoolValue(LLVMContext &C, const char *s, unsigned id, - unsigned char PCAdj = 0, - ARMCP::ARMCPModifier Modifier = ARMCP::no_modifier, - bool AddCurrentAddress = false); - ARMConstantPoolValue(const GlobalValue *GV, ARMCP::ARMCPModifier Modifier); - ARMConstantPoolValue(); - ~ARMConstantPoolValue(); +protected: + ARMConstantPoolValue(Type *Ty, unsigned id, ARMCP::ARMCPKind Kind, + unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, + bool AddCurrentAddress); + + ARMConstantPoolValue(LLVMContext &C, unsigned id, ARMCP::ARMCPKind Kind, + unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, + bool AddCurrentAddress); +public: + virtual ~ARMConstantPoolValue(); - const GlobalValue *getGV() const; - const char *getSymbol() const { return S; } - const BlockAddress *getBlockAddress() const; ARMCP::ARMCPModifier getModifier() const { return Modifier; } - const char *getModifierText() const { - switch (Modifier) { - default: llvm_unreachable("Unknown modifier!"); - // FIXME: Are these case sensitive? It'd be nice to lower-case all the - // strings if that's legal. - case ARMCP::no_modifier: return "none"; - case ARMCP::TLSGD: return "tlsgd"; - case ARMCP::GOT: return "GOT"; - case ARMCP::GOTOFF: return "GOTOFF"; - case ARMCP::GOTTPOFF: return "gottpoff"; - case ARMCP::TPOFF: return "tpoff"; - } - } + const char *getModifierText() const; bool hasModifier() const { return Modifier != ARMCP::no_modifier; } + bool mustAddCurrentAddress() const { return AddCurrentAddress; } + unsigned getLabelId() const { return LabelId; } unsigned char getPCAdjustment() const { return PCAdjust; } + bool isGlobalValue() const { return Kind == ARMCP::CPValue; } bool isExtSymbol() const { return Kind == ARMCP::CPExtSymbol; } - bool isBlockAddress() { return Kind == ARMCP::CPBlockAddress; } - bool isLSDA() { return Kind == ARMCP::CPLSDA; } + bool isBlockAddress() const { return Kind == ARMCP::CPBlockAddress; } + bool isLSDA() const { return Kind == ARMCP::CPLSDA; } + bool isMachineBasicBlock() const{ return Kind == ARMCP::CPMachineBasicBlock; } virtual unsigned getRelocationInfo() const { return 2; } virtual int getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment); - virtual void AddSelectionDAGCSEId(FoldingSetNodeID &ID); + virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID); - /// hasSameValue - Return true if this ARM constpool value - /// can share the same constantpool entry as another ARM constpool value. - bool hasSameValue(ARMConstantPoolValue *ACPV); + /// hasSameValue - Return true if this ARM constpool value can share the same + /// constantpool entry as another ARM constpool value. + virtual bool hasSameValue(ARMConstantPoolValue *ACPV); + bool equals(const ARMConstantPoolValue *A) const { + return this->LabelId == A->LabelId && + this->PCAdjust == A->PCAdjust && + this->Modifier == A->Modifier; + } + + virtual void print(raw_ostream &O) const; void print(raw_ostream *O) const { if (O) print(*O); } - void print(raw_ostream &O) const; void dump() const; + + static bool classof(const ARMConstantPoolValue *) { return true; } }; inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) { @@ -117,6 +111,123 @@ inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) { return O; } +/// ARMConstantPoolConstant - ARM-specific constant pool values for Constants, +/// Functions, and BlockAddresses. +class ARMConstantPoolConstant : public ARMConstantPoolValue { + const Constant *CVal; // Constant being loaded. + + ARMConstantPoolConstant(const Constant *C, + unsigned ID, + ARMCP::ARMCPKind Kind, + unsigned char PCAdj, + ARMCP::ARMCPModifier Modifier, + bool AddCurrentAddress); + ARMConstantPoolConstant(Type *Ty, const Constant *C, + unsigned ID, + ARMCP::ARMCPKind Kind, + unsigned char PCAdj, + ARMCP::ARMCPModifier Modifier, + bool AddCurrentAddress); + +public: + static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID); + static ARMConstantPoolConstant *Create(const GlobalValue *GV, + ARMCP::ARMCPModifier Modifier); + static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, + ARMCP::ARMCPKind Kind, + unsigned char PCAdj); + static ARMConstantPoolConstant *Create(const Constant *C, unsigned ID, + ARMCP::ARMCPKind Kind, + unsigned char PCAdj, + ARMCP::ARMCPModifier Modifier, + bool AddCurrentAddress); + + const GlobalValue *getGV() const; + const BlockAddress *getBlockAddress() const; + + virtual int getExistingMachineCPValue(MachineConstantPool *CP, + unsigned Alignment); + + /// hasSameValue - Return true if this ARM constpool value can share the same + /// constantpool entry as another ARM constpool value. + virtual bool hasSameValue(ARMConstantPoolValue *ACPV); + + virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID); + + virtual void print(raw_ostream &O) const; + static bool classof(const ARMConstantPoolValue *APV) { + return APV->isGlobalValue() || APV->isBlockAddress() || APV->isLSDA(); + } + static bool classof(const ARMConstantPoolConstant *) { return true; } +}; + +/// ARMConstantPoolSymbol - ARM-specific constantpool values for external +/// symbols. +class ARMConstantPoolSymbol : public ARMConstantPoolValue { + const char *S; // ExtSymbol being loaded. + + ARMConstantPoolSymbol(LLVMContext &C, const char *s, unsigned id, + unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, + bool AddCurrentAddress); + +public: + ~ARMConstantPoolSymbol(); + + static ARMConstantPoolSymbol *Create(LLVMContext &C, const char *s, + unsigned ID, unsigned char PCAdj); + + const char *getSymbol() const { return S; } + + virtual int getExistingMachineCPValue(MachineConstantPool *CP, + unsigned Alignment); + + virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID); + + /// hasSameValue - Return true if this ARM constpool value can share the same + /// constantpool entry as another ARM constpool value. + virtual bool hasSameValue(ARMConstantPoolValue *ACPV); + + virtual void print(raw_ostream &O) const; + + static bool classof(const ARMConstantPoolValue *ACPV) { + return ACPV->isExtSymbol(); + } + static bool classof(const ARMConstantPoolSymbol *) { return true; } +}; + +/// ARMConstantPoolMBB - ARM-specific constantpool value of a machine basic +/// block. +class ARMConstantPoolMBB : public ARMConstantPoolValue { + const MachineBasicBlock *MBB; // Machine basic block. + + ARMConstantPoolMBB(LLVMContext &C, const MachineBasicBlock *mbb, unsigned id, + unsigned char PCAdj, ARMCP::ARMCPModifier Modifier, + bool AddCurrentAddress); + +public: + static ARMConstantPoolMBB *Create(LLVMContext &C, + const MachineBasicBlock *mbb, + unsigned ID, unsigned char PCAdj); + + const MachineBasicBlock *getMBB() const { return MBB; } + + virtual int getExistingMachineCPValue(MachineConstantPool *CP, + unsigned Alignment); + + virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID); + + /// hasSameValue - Return true if this ARM constpool value can share the same + /// constantpool entry as another ARM constpool value. + virtual bool hasSameValue(ARMConstantPoolValue *ACPV); + + virtual void print(raw_ostream &O) const; + + static bool classof(const ARMConstantPoolValue *ACPV) { + return ACPV->isMachineBasicBlock(); + } + static bool classof(const ARMConstantPoolMBB *) { return true; } +}; + } // End llvm namespace #endif diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp index 94b72fdb9a7e..7872cb90f4e7 100644 --- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -16,19 +16,24 @@ #define DEBUG_TYPE "arm-pseudo" #include "ARM.h" -#include "ARMAddressingModes.h" #include "ARMBaseInstrInfo.h" #include "ARMBaseRegisterInfo.h" #include "ARMMachineFunctionInfo.h" #include "ARMRegisterInfo.h" +#include "MCTargetDesc/ARMAddressingModes.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/raw_ostream.h" // FIXME: for debug only. remove! using namespace llvm; +static cl::opt +VerifyARMPseudo("verify-arm-pseudo-expand", cl::Hidden, + cl::desc("Verify machine code after expanding ARM pseudos")); + namespace { class ARMExpandPseudo : public MachineFunctionPass { public: @@ -741,8 +746,22 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, MI.eraseFromParent(); return true; } - case ARM::MOVCCs: { - BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVs), + case ARM::MOVCCsi: { + BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi), + (MI.getOperand(1).getReg())) + .addReg(MI.getOperand(2).getReg(), + getKillRegState(MI.getOperand(2).isKill())) + .addImm(MI.getOperand(3).getImm()) + .addImm(MI.getOperand(4).getImm()) // 'pred' + .addReg(MI.getOperand(5).getReg()) + .addReg(0); // 's' bit + + MI.eraseFromParent(); + return true; + } + + case ARM::MOVCCsr: { + BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsr), (MI.getOperand(1).getReg())) .addReg(MI.getOperand(2).getReg(), getKillRegState(MI.getOperand(2).isKill())) @@ -837,10 +856,9 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, case ARM::MOVsrl_flag: case ARM::MOVsra_flag: { // These are just fancy MOVs insructions. - AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVs), + AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi), MI.getOperand(0).getReg()) .addOperand(MI.getOperand(1)) - .addReg(0) .addImm(ARM_AM::getSORegOpc((Opcode == ARM::MOVsrl_flag ? ARM_AM::lsr : ARM_AM::asr), 1))) @@ -851,10 +869,9 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, case ARM::RRX: { // This encodes as "MOVs Rd, Rm, rrx MachineInstrBuilder MIB = - AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVs), + AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),TII->get(ARM::MOVsi), MI.getOperand(0).getReg()) .addOperand(MI.getOperand(1)) - .addOperand(MI.getOperand(1)) .addImm(ARM_AM::getSORegOpc(ARM_AM::rrx, 0))) .addReg(0); TransferImpOps(MI, MIB, MIB); @@ -953,34 +970,6 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, ExpandMOV32BitImm(MBB, MBBI); return true; - case ARM::VMOVQQ: { - unsigned DstReg = MI.getOperand(0).getReg(); - bool DstIsDead = MI.getOperand(0).isDead(); - unsigned EvenDst = TRI->getSubReg(DstReg, ARM::qsub_0); - unsigned OddDst = TRI->getSubReg(DstReg, ARM::qsub_1); - unsigned SrcReg = MI.getOperand(1).getReg(); - bool SrcIsKill = MI.getOperand(1).isKill(); - unsigned EvenSrc = TRI->getSubReg(SrcReg, ARM::qsub_0); - unsigned OddSrc = TRI->getSubReg(SrcReg, ARM::qsub_1); - MachineInstrBuilder Even = - AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), - TII->get(ARM::VORRq)) - .addReg(EvenDst, - RegState::Define | getDeadRegState(DstIsDead)) - .addReg(EvenSrc, getKillRegState(SrcIsKill)) - .addReg(EvenSrc, getKillRegState(SrcIsKill))); - MachineInstrBuilder Odd = - AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), - TII->get(ARM::VORRq)) - .addReg(OddDst, - RegState::Define | getDeadRegState(DstIsDead)) - .addReg(OddSrc, getKillRegState(SrcIsKill)) - .addReg(OddSrc, getKillRegState(SrcIsKill))); - TransferImpOps(MI, Even, Odd); - MI.eraseFromParent(); - return true; - } - case ARM::VLDMQIA: { unsigned NewOpc = ARM::VLDMDIA; MachineInstrBuilder MIB = @@ -1316,6 +1305,8 @@ bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) { for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) Modified |= ExpandMBB(*MFI); + if (VerifyARMPseudo) + MF.verify(this, "After expanding ARM pseudo instructions."); return Modified; } diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index f469d7efe11a..9bc7ef21d8a3 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -14,13 +14,13 @@ //===----------------------------------------------------------------------===// #include "ARM.h" -#include "ARMAddressingModes.h" #include "ARMBaseInstrInfo.h" #include "ARMCallingConv.h" #include "ARMRegisterInfo.h" #include "ARMTargetMachine.h" #include "ARMSubtarget.h" #include "ARMConstantPoolValue.h" +#include "MCTargetDesc/ARMAddressingModes.h" #include "llvm/CallingConv.h" #include "llvm/DerivedTypes.h" #include "llvm/GlobalVariable.h" @@ -171,8 +171,8 @@ class ARMFastISel : public FastISel { // Utility routines. private: - bool isTypeLegal(const Type *Ty, MVT &VT); - bool isLoadTypeLegal(const Type *Ty, MVT &VT); + bool isTypeLegal(Type *Ty, MVT &VT); + bool isLoadTypeLegal(Type *Ty, MVT &VT); bool ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr); bool ARMEmitStore(EVT VT, unsigned SrcReg, Address &Addr); bool ARMComputeAddress(const Value *Obj, Address &Addr); @@ -502,11 +502,19 @@ unsigned ARMFastISel::ARMMaterializeFP(const ConstantFP *CFP, EVT VT) { // This checks to see if we can use VFP3 instructions to materialize // a constant, otherwise we have to go through the constant pool. if (TLI.isFPImmLegal(Val, VT)) { - unsigned Opc = is64bit ? ARM::FCONSTD : ARM::FCONSTS; + int Imm; + unsigned Opc; + if (is64bit) { + Imm = ARM_AM::getFP64Imm(Val); + Opc = ARM::FCONSTD; + } else { + Imm = ARM_AM::getFP32Imm(Val); + Opc = ARM::FCONSTS; + } unsigned DestReg = createResultReg(TLI.getRegClassFor(VT)); AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), DestReg) - .addFPImm(CFP)); + .addImm(Imm)); return DestReg; } @@ -590,8 +598,9 @@ unsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, EVT VT) { // Grab index. unsigned PCAdj = (RelocM != Reloc::PIC_) ? 0 : (Subtarget->isThumb() ? 4 : 8); unsigned Id = AFI->createPICLabelUId(); - ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, Id, - ARMCP::CPValue, PCAdj); + ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create(GV, Id, + ARMCP::CPValue, + PCAdj); unsigned Idx = MCP.getConstantPoolIndex(CPV, Align); // Load value. @@ -615,8 +624,8 @@ unsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, EVT VT) { if (Subtarget->GVIsIndirectSymbol(GV, RelocM)) { unsigned NewDestReg = createResultReg(TLI.getRegClassFor(VT)); if (isThumb) - MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(ARM::t2LDRi12), - NewDestReg) + MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(ARM::t2LDRi12), NewDestReg) .addReg(DestReg) .addImm(0); else @@ -673,7 +682,7 @@ unsigned ARMFastISel::TargetMaterializeAlloca(const AllocaInst *AI) { return 0; } -bool ARMFastISel::isTypeLegal(const Type *Ty, MVT &VT) { +bool ARMFastISel::isTypeLegal(Type *Ty, MVT &VT) { EVT evt = TLI.getValueType(Ty, true); // Only handle simple types. @@ -685,7 +694,7 @@ bool ARMFastISel::isTypeLegal(const Type *Ty, MVT &VT) { return TLI.isTypeLegal(VT); } -bool ARMFastISel::isLoadTypeLegal(const Type *Ty, MVT &VT) { +bool ARMFastISel::isLoadTypeLegal(Type *Ty, MVT &VT) { if (isTypeLegal(Ty, VT)) return true; // If this is a type than can be sign or zero-extended to a basic operation @@ -714,7 +723,7 @@ bool ARMFastISel::ARMComputeAddress(const Value *Obj, Address &Addr) { U = C; } - if (const PointerType *Ty = dyn_cast(Obj->getType())) + if (PointerType *Ty = dyn_cast(Obj->getType())) if (Ty->getAddressSpace() > 255) // Fast instruction selection doesn't support the special // address spaces. @@ -749,7 +758,7 @@ bool ARMFastISel::ARMComputeAddress(const Value *Obj, Address &Addr) { for (User::const_op_iterator i = U->op_begin() + 1, e = U->op_end(); i != e; ++i, ++GTI) { const Value *Op = *i; - if (const StructType *STy = dyn_cast(*GTI)) { + if (StructType *STy = dyn_cast(*GTI)) { const StructLayout *SL = TD.getStructLayout(STy); unsigned Idx = cast(Op)->getZExtValue(); TmpOffset += SL->getElementOffset(Idx); @@ -946,6 +955,10 @@ bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg, Address &Addr) { } bool ARMFastISel::SelectLoad(const Instruction *I) { + // Atomic loads need special handling. + if (cast(I)->isAtomic()) + return false; + // Verify we have a legal type before going any further. MVT VT; if (!isLoadTypeLegal(I->getType(), VT)) @@ -1008,6 +1021,10 @@ bool ARMFastISel::SelectStore(const Instruction *I) { Value *Op0 = I->getOperand(0); unsigned SrcReg = 0; + // Atomic stores need special handling. + if (cast(I)->isAtomic()) + return false; + // Verify we have a legal type before going any further. MVT VT; if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT)) @@ -1085,7 +1102,7 @@ bool ARMFastISel::SelectBranch(const Instruction *I) { // TODO: Factor this out. if (const CmpInst *CI = dyn_cast(BI->getCondition())) { MVT SourceVT; - const Type *Ty = CI->getOperand(0)->getType(); + Type *Ty = CI->getOperand(0)->getType(); if (CI->hasOneUse() && (CI->getParent() == I->getParent()) && isTypeLegal(Ty, SourceVT)) { bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy()); @@ -1201,7 +1218,7 @@ bool ARMFastISel::SelectCmp(const Instruction *I) { const CmpInst *CI = cast(I); MVT VT; - const Type *Ty = CI->getOperand(0)->getType(); + Type *Ty = CI->getOperand(0)->getType(); if (!isTypeLegal(Ty, VT)) return false; @@ -1309,7 +1326,7 @@ bool ARMFastISel::SelectSIToFP(const Instruction *I) { if (!Subtarget->hasVFP2()) return false; MVT DstVT; - const Type *Ty = I->getType(); + Type *Ty = I->getType(); if (!isTypeLegal(Ty, DstVT)) return false; @@ -1328,7 +1345,7 @@ bool ARMFastISel::SelectSIToFP(const Instruction *I) { unsigned Opc; if (Ty->isFloatTy()) Opc = ARM::VSITOS; else if (Ty->isDoubleTy()) Opc = ARM::VSITOD; - else return 0; + else return false; unsigned ResultReg = createResultReg(TLI.getRegClassFor(DstVT)); AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), @@ -1343,7 +1360,7 @@ bool ARMFastISel::SelectFPToSI(const Instruction *I) { if (!Subtarget->hasVFP2()) return false; MVT DstVT; - const Type *RetTy = I->getType(); + Type *RetTy = I->getType(); if (!isTypeLegal(RetTy, DstVT)) return false; @@ -1351,10 +1368,10 @@ bool ARMFastISel::SelectFPToSI(const Instruction *I) { if (Op == 0) return false; unsigned Opc; - const Type *OpTy = I->getOperand(0)->getType(); + Type *OpTy = I->getOperand(0)->getType(); if (OpTy->isFloatTy()) Opc = ARM::VTOSIZS; else if (OpTy->isDoubleTy()) Opc = ARM::VTOSIZD; - else return 0; + else return false; // f64->s32 or f32->s32 both need an intermediate f32 reg. unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::f32)); @@ -1401,7 +1418,7 @@ bool ARMFastISel::SelectSelect(const Instruction *I) { bool ARMFastISel::SelectSDiv(const Instruction *I) { MVT VT; - const Type *Ty = I->getType(); + Type *Ty = I->getType(); if (!isTypeLegal(Ty, VT)) return false; @@ -1429,7 +1446,7 @@ bool ARMFastISel::SelectSDiv(const Instruction *I) { bool ARMFastISel::SelectSRem(const Instruction *I) { MVT VT; - const Type *Ty = I->getType(); + Type *Ty = I->getType(); if (!isTypeLegal(Ty, VT)) return false; @@ -1456,7 +1473,7 @@ bool ARMFastISel::SelectBinaryOp(const Instruction *I, unsigned ISDOpcode) { // operations, but can't figure out how to. Just use the vfp instructions // if we have them. // FIXME: It'd be nice to use NEON instructions. - const Type *Ty = I->getType(); + Type *Ty = I->getType(); bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy()); if (isFloat && !Subtarget->hasVFP2()) return false; @@ -1711,7 +1728,7 @@ bool ARMFastISel::SelectRet(const Instruction *I) { // Analyze operands of the call, assigning locations to each operand. SmallVector ValLocs; - CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, TM, ValLocs, I->getContext()); + CCState CCInfo(CC, F.isVarArg(), *FuncInfo.MF, TM, ValLocs,I->getContext()); CCInfo.AnalyzeReturn(Outs, CCAssignFnForCall(CC, true /* is Ret */)); const Value *RV = Ret->getOperand(0); @@ -1778,7 +1795,7 @@ bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) { CallingConv::ID CC = TLI.getLibcallCallingConv(Call); // Handle *simple* calls for now. - const Type *RetTy = I->getType(); + Type *RetTy = I->getType(); MVT RetVT; if (RetTy->isVoidTy()) RetVT = MVT::isVoid; @@ -1802,7 +1819,7 @@ bool ARMFastISel::ARMEmitLibcall(const Instruction *I, RTLIB::Libcall Call) { unsigned Arg = getRegForValue(Op); if (Arg == 0) return false; - const Type *ArgTy = Op->getType(); + Type *ArgTy = Op->getType(); MVT ArgVT; if (!isTypeLegal(ArgTy, ArgVT)) return false; @@ -1870,13 +1887,13 @@ bool ARMFastISel::SelectCall(const Instruction *I) { // TODO: Avoid some calling conventions? // Let SDISel handle vararg functions. - const PointerType *PT = cast(CS.getCalledValue()->getType()); - const FunctionType *FTy = cast(PT->getElementType()); + PointerType *PT = cast(CS.getCalledValue()->getType()); + FunctionType *FTy = cast(PT->getElementType()); if (FTy->isVarArg()) return false; // Handle *simple* calls for now. - const Type *RetTy = I->getType(); + Type *RetTy = I->getType(); MVT RetVT; if (RetTy->isVoidTy()) RetVT = MVT::isVoid; @@ -1915,7 +1932,7 @@ bool ARMFastISel::SelectCall(const Instruction *I) { CS.paramHasAttr(AttrInd, Attribute::ByVal)) return false; - const Type *ArgTy = (*i)->getType(); + Type *ArgTy = (*i)->getType(); MVT ArgVT; if (!isTypeLegal(ArgTy, ArgVT)) return false; @@ -1969,9 +1986,9 @@ bool ARMFastISel::SelectIntCast(const Instruction *I) { // On ARM, in general, integer casts don't involve legal types; this code // handles promotable integers. The high bits for a type smaller than // the register size are assumed to be undefined. - const Type *DestTy = I->getType(); + Type *DestTy = I->getType(); Value *Op = I->getOperand(0); - const Type *SrcTy = Op->getType(); + Type *SrcTy = Op->getType(); EVT SrcVT, DestVT; SrcVT = TLI.getValueType(SrcTy, true); @@ -2002,16 +2019,18 @@ bool ARMFastISel::SelectIntCast(const Instruction *I) { switch (SrcVT.getSimpleVT().SimpleTy) { default: return false; case MVT::i16: + if (!Subtarget->hasV6Ops()) return false; if (isZext) - Opc = isThumb ? ARM::t2UXTHr : ARM::UXTHr; + Opc = isThumb ? ARM::t2UXTH : ARM::UXTH; else - Opc = isThumb ? ARM::t2SXTHr : ARM::SXTHr; + Opc = isThumb ? ARM::t2SXTH : ARM::SXTH; break; case MVT::i8: + if (!Subtarget->hasV6Ops()) return false; if (isZext) - Opc = isThumb ? ARM::t2UXTBr : ARM::UXTBr; + Opc = isThumb ? ARM::t2UXTB : ARM::UXTB; else - Opc = isThumb ? ARM::t2SXTBr : ARM::SXTBr; + Opc = isThumb ? ARM::t2SXTB : ARM::SXTB; break; case MVT::i1: if (isZext) { @@ -2033,6 +2052,8 @@ bool ARMFastISel::SelectIntCast(const Instruction *I) { .addReg(SrcReg); if (isBoolZext) MIB.addImm(1); + else + MIB.addImm(0); AddOptionalDefs(MIB); UpdateValueMap(I, DestReg); return true; diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp index 381b404519e2..2d1de6fe8e9d 100644 --- a/lib/Target/ARM/ARMFrameLowering.cpp +++ b/lib/Target/ARM/ARMFrameLowering.cpp @@ -12,10 +12,10 @@ //===----------------------------------------------------------------------===// #include "ARMFrameLowering.h" -#include "ARMAddressingModes.h" #include "ARMBaseInstrInfo.h" #include "ARMBaseRegisterInfo.h" #include "ARMMachineFunctionInfo.h" +#include "MCTargetDesc/ARMAddressingModes.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -93,7 +93,8 @@ static bool isCSRestore(MachineInstr *MI, return false; return true; } - if ((MI->getOpcode() == ARM::LDR_POST || + if ((MI->getOpcode() == ARM::LDR_POST_IMM || + MI->getOpcode() == ARM::LDR_POST_REG || MI->getOpcode() == ARM::t2LDR_POST) && isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs) && MI->getOperand(1).getReg() == ARM::SP) @@ -413,6 +414,9 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF, MIB.addExternalSymbol(JumpTarget.getSymbolName(), JumpTarget.getTargetFlags()); } + + // Add the default predicate in Thumb mode. + if (STI.isThumb()) MIB.addImm(ARMCC::AL).addReg(0); } else if (RetOpcode == ARM::TCRETURNri) { BuildMI(MBB, MBBI, dl, TII.get(STI.isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr)). @@ -502,7 +506,7 @@ ARMFrameLowering::ResolveFrameIndexReference(const MachineFunction &MF, } } } else if (AFI->isThumb2Function()) { - // Use add , sp, # + // Use add , sp, # // ldr , [sp, #] // if at all possible to save space. if (Offset >= 0 && (Offset & 3) == 0 && Offset <= 1020) @@ -587,14 +591,8 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB, MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(StrOpc), ARM::SP) .addReg(Regs[0].first, getKillRegState(Regs[0].second)) - .addReg(ARM::SP).setMIFlags(MIFlags); - // ARM mode needs an extra reg0 here due to addrmode2. Will go away once - // that refactoring is complete (eventually). - if (StrOpc == ARM::STR_PRE) { - MIB.addReg(0); - MIB.addImm(ARM_AM::getAM2Opc(ARM_AM::sub, 4, ARM_AM::no_shift)); - } else - MIB.addImm(-4); + .addReg(ARM::SP).setMIFlags(MIFlags) + .addImm(-4); AddDefaultPred(MIB); } Regs.clear(); @@ -651,8 +649,10 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, .addReg(ARM::SP)); for (unsigned i = 0, e = Regs.size(); i < e; ++i) MIB.addReg(Regs[i], getDefRegState(true)); - if (DeleteRet) + if (DeleteRet) { + MIB->copyImplicitOps(&*MI); MI->eraseFromParent(); + } MI = MIB; } else if (Regs.size() == 1) { // If we adjusted the reg to PC from LR above, switch it back here. We @@ -665,7 +665,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, .addReg(ARM::SP); // ARM mode needs an extra reg0 here due to addrmode2. Will go away once // that refactoring is complete (eventually). - if (LdrOpc == ARM::LDR_POST) { + if (LdrOpc == ARM::LDR_POST_REG || LdrOpc == ARM::LDR_POST_IMM) { MIB.addReg(0); MIB.addImm(ARM_AM::getAM2Opc(ARM_AM::add, 4, ARM_AM::no_shift)); } else @@ -687,7 +687,8 @@ bool ARMFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, ARMFunctionInfo *AFI = MF.getInfo(); unsigned PushOpc = AFI->isThumbFunction() ? ARM::t2STMDB_UPD : ARM::STMDB_UPD; - unsigned PushOneOpc = AFI->isThumbFunction() ? ARM::t2STR_PRE : ARM::STR_PRE; + unsigned PushOneOpc = AFI->isThumbFunction() ? + ARM::t2STR_PRE : ARM::STR_PRE_IMM; unsigned FltOpc = ARM::VSTMDDB_UPD; emitPushInst(MBB, MI, CSI, PushOpc, PushOneOpc, false, &isARMArea1Register, MachineInstr::FrameSetup); @@ -711,7 +712,7 @@ bool ARMFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, bool isVarArg = AFI->getVarArgsRegSaveSize() > 0; unsigned PopOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD; - unsigned LdrOpc = AFI->isThumbFunction() ? ARM::t2LDR_POST : ARM::LDR_POST; + unsigned LdrOpc = AFI->isThumbFunction() ? ARM::t2LDR_POST :ARM::LDR_POST_IMM; unsigned FltOpc = ARM::VLDMDIA_UPD; emitPopInst(MBB, MI, CSI, FltOpc, 0, isVarArg, true, &isARMArea3Register); emitPopInst(MBB, MI, CSI, PopOpc, LdrOpc, isVarArg, false, diff --git a/lib/Target/ARM/ARMGlobalMerge.cpp b/lib/Target/ARM/ARMGlobalMerge.cpp index 8d77b2d8383e..5f863ea241ca 100644 --- a/lib/Target/ARM/ARMGlobalMerge.cpp +++ b/lib/Target/ARM/ARMGlobalMerge.cpp @@ -100,8 +100,8 @@ namespace { GlobalCmp(const TargetData *td) : TD(td) { } bool operator()(const GlobalVariable *GV1, const GlobalVariable *GV2) { - const Type *Ty1 = cast(GV1->getType())->getElementType(); - const Type *Ty2 = cast(GV2->getType())->getElementType(); + Type *Ty1 = cast(GV1->getType())->getElementType(); + Type *Ty2 = cast(GV2->getType())->getElementType(); return (TD->getTypeAllocSize(Ty1) < TD->getTypeAllocSize(Ty2)); } @@ -123,7 +123,7 @@ bool ARMGlobalMerge::doMerge(SmallVectorImpl &Globals, // FIXME: Find better heuristics std::stable_sort(Globals.begin(), Globals.end(), GlobalCmp(TD)); - const Type *Int32Ty = Type::getInt32Ty(M.getContext()); + Type *Int32Ty = Type::getInt32Ty(M.getContext()); for (size_t i = 0, e = Globals.size(); i != e; ) { size_t j = 0; @@ -150,7 +150,7 @@ bool ARMGlobalMerge::doMerge(SmallVectorImpl &Globals, ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, k-i) }; - Constant *GEP = ConstantExpr::getInBoundsGetElementPtr(MergedGV, Idx, 2); + Constant *GEP = ConstantExpr::getInBoundsGetElementPtr(MergedGV, Idx); Globals[k]->replaceAllUsesWith(GEP); Globals[k]->eraseFromParent(); } @@ -176,7 +176,7 @@ bool ARMGlobalMerge::doInitialization(Module &M) { // Ignore fancy-aligned globals for now. unsigned Alignment = I->getAlignment(); - const Type *Ty = I->getType()->getElementType(); + Type *Ty = I->getType()->getElementType(); if (Alignment > TD->getABITypeAlignment(Ty)) continue; diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 2c9481b86c55..5ee009c04c5b 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -14,8 +14,8 @@ #define DEBUG_TYPE "arm-isel" #include "ARM.h" #include "ARMBaseInstrInfo.h" -#include "ARMAddressingModes.h" #include "ARMTargetMachine.h" +#include "MCTargetDesc/ARMAddressingModes.h" #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" @@ -47,6 +47,11 @@ CheckVMLxHazard("check-vmlx-hazard", cl::Hidden, cl::desc("Check fp vmla / vmls hazard at isel time"), cl::init(true)); +static cl::opt +DisableARMIntABS("disable-arm-int-abs", cl::Hidden, + cl::desc("Enable / disable ARM integer abs transform"), + cl::init(false)); + //===--------------------------------------------------------------------===// /// ARMDAGToDAGISel - ARM specific code to select ARM machine /// instructions for SelectionDAG operations. @@ -90,13 +95,20 @@ class ARMDAGToDAGISel : public SelectionDAGISel { bool hasNoVMLxHazardUse(SDNode *N) const; bool isShifterOpProfitable(const SDValue &Shift, ARM_AM::ShiftOpc ShOpcVal, unsigned ShAmt); - bool SelectShifterOperandReg(SDValue N, SDValue &A, + bool SelectRegShifterOperand(SDValue N, SDValue &A, SDValue &B, SDValue &C, bool CheckProfitability = true); - bool SelectShiftShifterOperandReg(SDValue N, SDValue &A, + bool SelectImmShifterOperand(SDValue N, SDValue &A, + SDValue &B, bool CheckProfitability = true); + bool SelectShiftRegShifterOperand(SDValue N, SDValue &A, SDValue &B, SDValue &C) { // Don't apply the profitability check - return SelectShifterOperandReg(N, A, B, C, false); + return SelectRegShifterOperand(N, A, B, C, false); + } + bool SelectShiftImmShifterOperand(SDValue N, SDValue &A, + SDValue &B) { + // Don't apply the profitability check + return SelectImmShifterOperand(N, A, B, false); } bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm); @@ -122,8 +134,13 @@ class ARMDAGToDAGISel : public SelectionDAGISel { return true; } - bool SelectAddrMode2Offset(SDNode *Op, SDValue N, + bool SelectAddrMode2OffsetReg(SDNode *Op, SDValue N, SDValue &Offset, SDValue &Opc); + bool SelectAddrMode2OffsetImm(SDNode *Op, SDValue N, + SDValue &Offset, SDValue &Opc); + bool SelectAddrMode2OffsetImmPre(SDNode *Op, SDValue N, + SDValue &Offset, SDValue &Opc); + bool SelectAddrOffsetNone(SDValue N, SDValue &Base); bool SelectAddrMode3(SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc); bool SelectAddrMode3Offset(SDNode *Op, SDValue N, @@ -240,8 +257,13 @@ class ARMDAGToDAGISel : public SelectionDAGISel { ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag); + // Select special operations if node forms integer ABS pattern + SDNode *SelectABSOp(SDNode *N); + SDNode *SelectConcatVector(SDNode *N); + SDNode *SelectAtomic64(SDNode *Node, unsigned Opc); + /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for /// inline asm expressions. virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, @@ -291,10 +313,10 @@ static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned& Imm) { /// (N * Scale) where (N in [\arg RangeMin, \arg RangeMax). /// /// \param ScaledConstant [out] - On success, the pre-scaled constant value. -static bool isScaledConstantInRange(SDValue Node, unsigned Scale, +static bool isScaledConstantInRange(SDValue Node, int Scale, int RangeMin, int RangeMax, int &ScaledConstant) { - assert(Scale && "Invalid scale!"); + assert(Scale > 0 && "Invalid scale!"); // Check that this is a constant. const ConstantSDNode *C = dyn_cast(Node); @@ -365,15 +387,14 @@ bool ARMDAGToDAGISel::isShifterOpProfitable(const SDValue &Shift, return ShOpcVal == ARM_AM::lsl && ShAmt == 2; } -bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue N, +bool ARMDAGToDAGISel::SelectImmShifterOperand(SDValue N, SDValue &BaseReg, - SDValue &ShReg, SDValue &Opc, bool CheckProfitability) { if (DisableShifterOp) return false; - ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); + ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); // Don't match base register only case. That is matched to a separate // lower complexity pattern with explicit register operand. @@ -381,19 +402,42 @@ bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue N, BaseReg = N.getOperand(0); unsigned ShImmVal = 0; - if (ConstantSDNode *RHS = dyn_cast(N.getOperand(1))) { - ShReg = CurDAG->getRegister(0, MVT::i32); - ShImmVal = RHS->getZExtValue() & 31; - } else { - ShReg = N.getOperand(1); - if (CheckProfitability && !isShifterOpProfitable(N, ShOpcVal, ShImmVal)) - return false; - } + ConstantSDNode *RHS = dyn_cast(N.getOperand(1)); + if (!RHS) return false; + ShImmVal = RHS->getZExtValue() & 31; Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), MVT::i32); return true; } +bool ARMDAGToDAGISel::SelectRegShifterOperand(SDValue N, + SDValue &BaseReg, + SDValue &ShReg, + SDValue &Opc, + bool CheckProfitability) { + if (DisableShifterOp) + return false; + + ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); + + // Don't match base register only case. That is matched to a separate + // lower complexity pattern with explicit register operand. + if (ShOpcVal == ARM_AM::no_shift) return false; + + BaseReg = N.getOperand(0); + unsigned ShImmVal = 0; + ConstantSDNode *RHS = dyn_cast(N.getOperand(1)); + if (RHS) return false; + + ShReg = N.getOperand(1); + if (CheckProfitability && !isShifterOpProfitable(N, ShOpcVal, ShImmVal)) + return false; + Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), + MVT::i32); + return true; +} + + bool ARMDAGToDAGISel::SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm) { @@ -483,13 +527,10 @@ bool ARMDAGToDAGISel::SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, return false; } - if (Subtarget->isCortexA9() && !N.hasOneUse()) - // Compute R +/- (R << N) and reuse it. - return false; - // Otherwise this is R +/- [possibly shifted] R. ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::SUB ? ARM_AM::sub:ARM_AM::add; - ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1)); + ARM_AM::ShiftOpc ShOpcVal = + ARM_AM::getShiftOpcForNode(N.getOperand(1).getOpcode()); unsigned ShAmt = 0; Base = N.getOperand(0); @@ -515,16 +556,14 @@ bool ARMDAGToDAGISel::SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, // Try matching (R shl C) + (R). if (N.getOpcode() != ISD::SUB && ShOpcVal == ARM_AM::no_shift && !(Subtarget->isCortexA9() || N.getOperand(0).hasOneUse())) { - ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0)); + ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0).getOpcode()); if (ShOpcVal != ARM_AM::no_shift) { // Check to see if the RHS of the shift is a constant, if not, we can't // fold it. if (ConstantSDNode *Sh = dyn_cast(N.getOperand(0).getOperand(1))) { ShAmt = Sh->getZExtValue(); - if (!Subtarget->isCortexA9() || - (N.hasOneUse() && - isShifterOpProfitable(N.getOperand(0), ShOpcVal, ShAmt))) { + if (isShifterOpProfitable(N.getOperand(0), ShOpcVal, ShAmt)) { Offset = N.getOperand(0).getOperand(0); Base = N.getOperand(1); } else { @@ -630,7 +669,8 @@ AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N, // Otherwise this is R +/- [possibly shifted] R. ARM_AM::AddrOpc AddSub = N.getOpcode() != ISD::SUB ? ARM_AM::add:ARM_AM::sub; - ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1)); + ARM_AM::ShiftOpc ShOpcVal = + ARM_AM::getShiftOpcForNode(N.getOperand(1).getOpcode()); unsigned ShAmt = 0; Base = N.getOperand(0); @@ -656,16 +696,14 @@ AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N, // Try matching (R shl C) + (R). if (N.getOpcode() != ISD::SUB && ShOpcVal == ARM_AM::no_shift && !(Subtarget->isCortexA9() || N.getOperand(0).hasOneUse())) { - ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0)); + ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0).getOpcode()); if (ShOpcVal != ARM_AM::no_shift) { // Check to see if the RHS of the shift is a constant, if not, we can't // fold it. if (ConstantSDNode *Sh = dyn_cast(N.getOperand(0).getOperand(1))) { ShAmt = Sh->getZExtValue(); - if (!Subtarget->isCortexA9() || - (N.hasOneUse() && - isShifterOpProfitable(N.getOperand(0), ShOpcVal, ShAmt))) { + if (isShifterOpProfitable(N.getOperand(0), ShOpcVal, ShAmt)) { Offset = N.getOperand(0).getOperand(0); Base = N.getOperand(1); } else { @@ -683,7 +721,7 @@ AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N, return AM2_SHOP; } -bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N, +bool ARMDAGToDAGISel::SelectAddrMode2OffsetReg(SDNode *Op, SDValue N, SDValue &Offset, SDValue &Opc) { unsigned Opcode = Op->getOpcode(); ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) @@ -692,16 +730,11 @@ bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N, ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) ? ARM_AM::add : ARM_AM::sub; int Val; - if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) { // 12 bits. - Offset = CurDAG->getRegister(0, MVT::i32); - Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val, - ARM_AM::no_shift), - MVT::i32); - return true; - } + if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) + return false; Offset = N; - ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); + ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); unsigned ShAmt = 0; if (ShOpcVal != ARM_AM::no_shift) { // Check to see if the RHS of the shift is a constant, if not, we can't fold @@ -724,6 +757,50 @@ bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N, return true; } +bool ARMDAGToDAGISel::SelectAddrMode2OffsetImmPre(SDNode *Op, SDValue N, + SDValue &Offset, SDValue &Opc) { + unsigned Opcode = Op->getOpcode(); + ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) + ? cast(Op)->getAddressingMode() + : cast(Op)->getAddressingMode(); + ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) + ? ARM_AM::add : ARM_AM::sub; + int Val; + if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) { // 12 bits. + if (AddSub == ARM_AM::sub) Val *= -1; + Offset = CurDAG->getRegister(0, MVT::i32); + Opc = CurDAG->getTargetConstant(Val, MVT::i32); + return true; + } + + return false; +} + + +bool ARMDAGToDAGISel::SelectAddrMode2OffsetImm(SDNode *Op, SDValue N, + SDValue &Offset, SDValue &Opc) { + unsigned Opcode = Op->getOpcode(); + ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) + ? cast(Op)->getAddressingMode() + : cast(Op)->getAddressingMode(); + ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) + ? ARM_AM::add : ARM_AM::sub; + int Val; + if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) { // 12 bits. + Offset = CurDAG->getRegister(0, MVT::i32); + Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val, + ARM_AM::no_shift), + MVT::i32); + return true; + } + + return false; +} + +bool ARMDAGToDAGISel::SelectAddrOffsetNone(SDValue N, SDValue &Base) { + Base = N; + return true; +} bool ARMDAGToDAGISel::SelectAddrMode3(SDValue N, SDValue &Base, SDValue &Offset, @@ -1079,7 +1156,7 @@ bool ARMDAGToDAGISel::SelectT2ShifterOperandReg(SDValue N, SDValue &BaseReg, if (DisableShifterOp) return false; - ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N); + ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); // Don't match base register only case. That is matched to a separate // lower complexity pattern with explicit register operand. @@ -1208,21 +1285,15 @@ bool ARMDAGToDAGISel::SelectT2AddrModeSoReg(SDValue N, return false; } - if (Subtarget->isCortexA9() && !N.hasOneUse()) { - // Compute R + (R << [1,2,3]) and reuse it. - Base = N; - return false; - } - // Look for (R + R) or (R + (R << [1,2,3])). unsigned ShAmt = 0; Base = N.getOperand(0); OffReg = N.getOperand(1); // Swap if it is ((R << c) + R). - ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg); + ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(OffReg.getOpcode()); if (ShOpcVal != ARM_AM::lsl) { - ShOpcVal = ARM_AM::getShiftOpcForNode(Base); + ShOpcVal = ARM_AM::getShiftOpcForNode(Base.getOpcode()); if (ShOpcVal == ARM_AM::lsl) std::swap(Base, OffReg); } @@ -1266,10 +1337,19 @@ SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDNode *N) { bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC); unsigned Opcode = 0; bool Match = false; - if (LoadedVT == MVT::i32 && - SelectAddrMode2Offset(N, LD->getOffset(), Offset, AMOpc)) { - Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST; + if (LoadedVT == MVT::i32 && isPre && + SelectAddrMode2OffsetImmPre(N, LD->getOffset(), Offset, AMOpc)) { + Opcode = ARM::LDR_PRE_IMM; Match = true; + } else if (LoadedVT == MVT::i32 && !isPre && + SelectAddrMode2OffsetImm(N, LD->getOffset(), Offset, AMOpc)) { + Opcode = ARM::LDR_POST_IMM; + Match = true; + } else if (LoadedVT == MVT::i32 && + SelectAddrMode2OffsetReg(N, LD->getOffset(), Offset, AMOpc)) { + Opcode = isPre ? ARM::LDR_PRE_REG : ARM::LDR_POST_REG; + Match = true; + } else if (LoadedVT == MVT::i16 && SelectAddrMode3Offset(N, LD->getOffset(), Offset, AMOpc)) { Match = true; @@ -1283,20 +1363,37 @@ SDNode *ARMDAGToDAGISel::SelectARMIndexedLoad(SDNode *N) { Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST; } } else { - if (SelectAddrMode2Offset(N, LD->getOffset(), Offset, AMOpc)) { + if (isPre && + SelectAddrMode2OffsetImmPre(N, LD->getOffset(), Offset, AMOpc)) { Match = true; - Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST; + Opcode = ARM::LDRB_PRE_IMM; + } else if (!isPre && + SelectAddrMode2OffsetImm(N, LD->getOffset(), Offset, AMOpc)) { + Match = true; + Opcode = ARM::LDRB_POST_IMM; + } else if (SelectAddrMode2OffsetReg(N, LD->getOffset(), Offset, AMOpc)) { + Match = true; + Opcode = isPre ? ARM::LDRB_PRE_REG : ARM::LDRB_POST_REG; } } } if (Match) { - SDValue Chain = LD->getChain(); - SDValue Base = LD->getBasePtr(); - SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG), - CurDAG->getRegister(0, MVT::i32), Chain }; - return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, MVT::i32, - MVT::Other, Ops, 6); + if (Opcode == ARM::LDR_PRE_IMM || Opcode == ARM::LDRB_PRE_IMM) { + SDValue Chain = LD->getChain(); + SDValue Base = LD->getBasePtr(); + SDValue Ops[]= { Base, AMOpc, getAL(CurDAG), + CurDAG->getRegister(0, MVT::i32), Chain }; + return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, + MVT::i32, MVT::Other, Ops, 5); + } else { + SDValue Chain = LD->getChain(); + SDValue Base = LD->getBasePtr(); + SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG), + CurDAG->getRegister(0, MVT::i32), Chain }; + return CurDAG->getMachineNode(Opcode, N->getDebugLoc(), MVT::i32, + MVT::i32, MVT::Other, Ops, 6); + } } return NULL; @@ -1966,7 +2063,8 @@ SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N, Srl_imm)) { assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); - unsigned Width = CountTrailingOnes_32(And_imm); + // Note: The width operand is encoded as width-1. + unsigned Width = CountTrailingOnes_32(And_imm) - 1; unsigned LSB = Srl_imm; SDValue Reg0 = CurDAG->getRegister(0, MVT::i32); SDValue Ops[] = { N->getOperand(0).getOperand(0), @@ -1986,7 +2084,8 @@ SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N, unsigned Srl_imm = 0; if (isInt32Immediate(N->getOperand(1), Srl_imm)) { assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!"); - unsigned Width = 32 - Srl_imm; + // Note: The width operand is encoded as width-1. + unsigned Width = 32 - Srl_imm - 1; int LSB = Srl_imm - Shl_imm; if (LSB < 0) return NULL; @@ -2034,10 +2133,16 @@ SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, SDValue CPTmp0; SDValue CPTmp1; SDValue CPTmp2; - if (SelectShifterOperandReg(TrueVal, CPTmp0, CPTmp1, CPTmp2)) { + if (SelectImmShifterOperand(TrueVal, CPTmp0, CPTmp2)) { + SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); + SDValue Ops[] = { FalseVal, CPTmp0, CPTmp2, CC, CCR, InFlag }; + return CurDAG->SelectNodeTo(N, ARM::MOVCCsi, MVT::i32, Ops, 6); + } + + if (SelectRegShifterOperand(TrueVal, CPTmp0, CPTmp1, CPTmp2)) { SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32); SDValue Ops[] = { FalseVal, CPTmp0, CPTmp1, CPTmp2, CC, CCR, InFlag }; - return CurDAG->SelectNodeTo(N, ARM::MOVCCs, MVT::i32, Ops, 7); + return CurDAG->SelectNodeTo(N, ARM::MOVCCsr, MVT::i32, Ops, 7); } return 0; } @@ -2198,6 +2303,56 @@ SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDNode *N) { return CurDAG->SelectNodeTo(N, Opc, VT, Ops, 5); } +/// Target-specific DAG combining for ISD::XOR. +/// Target-independent combining lowers SELECT_CC nodes of the form +/// select_cc setg[ge] X, 0, X, -X +/// select_cc setgt X, -1, X, -X +/// select_cc setl[te] X, 0, -X, X +/// select_cc setlt X, 1, -X, X +/// which represent Integer ABS into: +/// Y = sra (X, size(X)-1); xor (add (X, Y), Y) +/// ARM instruction selection detects the latter and matches it to +/// ARM::ABS or ARM::t2ABS machine node. +SDNode *ARMDAGToDAGISel::SelectABSOp(SDNode *N){ + SDValue XORSrc0 = N->getOperand(0); + SDValue XORSrc1 = N->getOperand(1); + DebugLoc DL = N->getDebugLoc(); + EVT VT = N->getValueType(0); + + if (DisableARMIntABS) + return NULL; + + if (Subtarget->isThumb1Only()) + return NULL; + + if (XORSrc0.getOpcode() != ISD::ADD || + XORSrc1.getOpcode() != ISD::SRA) + return NULL; + + SDValue ADDSrc0 = XORSrc0.getOperand(0); + SDValue ADDSrc1 = XORSrc0.getOperand(1); + SDValue SRASrc0 = XORSrc1.getOperand(0); + SDValue SRASrc1 = XORSrc1.getOperand(1); + ConstantSDNode *SRAConstant = dyn_cast(SRASrc1); + EVT XType = SRASrc0.getValueType(); + unsigned Size = XType.getSizeInBits() - 1; + + if (ADDSrc1 == XORSrc1 && + ADDSrc0 == SRASrc0 && + XType.isInteger() && + SRAConstant != NULL && + Size == SRAConstant->getZExtValue()) { + + unsigned Opcode = ARM::ABS; + if (Subtarget->isThumb2()) + Opcode = ARM::t2ABS; + + return CurDAG->SelectNodeTo(N, Opcode, VT, ADDSrc0); + } + + return NULL; +} + SDNode *ARMDAGToDAGISel::SelectConcatVector(SDNode *N) { // The only time a CONCAT_VECTORS operation can have legal types is when // two 64-bit vectors are concatenated to a 128-bit vector. @@ -2207,6 +2362,25 @@ SDNode *ARMDAGToDAGISel::SelectConcatVector(SDNode *N) { return PairDRegs(VT, N->getOperand(0), N->getOperand(1)); } +SDNode *ARMDAGToDAGISel::SelectAtomic64(SDNode *Node, unsigned Opc) { + SmallVector Ops; + Ops.push_back(Node->getOperand(1)); // Ptr + Ops.push_back(Node->getOperand(2)); // Low part of Val1 + Ops.push_back(Node->getOperand(3)); // High part of Val1 + if (Opc == ARM::ATOMCMPXCHG6432) { + Ops.push_back(Node->getOperand(4)); // Low part of Val2 + Ops.push_back(Node->getOperand(5)); // High part of Val2 + } + Ops.push_back(Node->getOperand(0)); // Chain + MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); + MemOp[0] = cast(Node)->getMemOperand(); + SDNode *ResNode = CurDAG->getMachineNode(Opc, Node->getDebugLoc(), + MVT::i32, MVT::i32, MVT::Other, + Ops.data() ,Ops.size()); + cast(ResNode)->setMemRefs(MemOp, MemOp + 1); + return ResNode; +} + SDNode *ARMDAGToDAGISel::Select(SDNode *N) { DebugLoc dl = N->getDebugLoc(); @@ -2215,6 +2389,14 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { switch (N->getOpcode()) { default: break; + case ISD::XOR: { + // Select special operations if XOR node forms integer ABS pattern + SDNode *ResNode = SelectABSOp(N); + if (ResNode) + return ResNode; + // Other cases are autogenerated. + break; + } case ISD::Constant: { unsigned Val = cast(N)->getZExtValue(); bool UseCP = true; @@ -2269,8 +2451,9 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { int FI = cast(N)->getIndex(); SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); if (Subtarget->isThumb1Only()) { - return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, TFI, - CurDAG->getTargetConstant(0, MVT::i32)); + SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32), + getAL(CurDAG), CurDAG->getRegister(0, MVT::i32) }; + return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, Ops, 4); } else { unsigned Opc = ((Subtarget->isThumb() && Subtarget->hasThumb2()) ? ARM::t2ADDri : ARM::ADDri); @@ -2307,7 +2490,7 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { return CurDAG->SelectNodeTo(N, ARM::t2ADDrs, MVT::i32, Ops, 6); } else { SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; - return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7); + return CurDAG->SelectNodeTo(N, ARM::ADDrsi, MVT::i32, Ops, 7); } } if (isPowerOf2_32(RHSV+1)) { // 2^n-1? @@ -2323,7 +2506,7 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { return CurDAG->SelectNodeTo(N, ARM::t2RSBrs, MVT::i32, Ops, 6); } else { SDValue Ops[] = { V, V, Reg0, ShImmOp, getAL(CurDAG), Reg0, Reg0 }; - return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7); + return CurDAG->SelectNodeTo(N, ARM::RSBrsi, MVT::i32, Ops, 7); } } } @@ -2986,6 +3169,23 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { case ISD::CONCAT_VECTORS: return SelectConcatVector(N); + + case ARMISD::ATOMOR64_DAG: + return SelectAtomic64(N, ARM::ATOMOR6432); + case ARMISD::ATOMXOR64_DAG: + return SelectAtomic64(N, ARM::ATOMXOR6432); + case ARMISD::ATOMADD64_DAG: + return SelectAtomic64(N, ARM::ATOMADD6432); + case ARMISD::ATOMSUB64_DAG: + return SelectAtomic64(N, ARM::ATOMSUB6432); + case ARMISD::ATOMNAND64_DAG: + return SelectAtomic64(N, ARM::ATOMNAND6432); + case ARMISD::ATOMAND64_DAG: + return SelectAtomic64(N, ARM::ATOMAND6432); + case ARMISD::ATOMSWAP64_DAG: + return SelectAtomic64(N, ARM::ATOMSWAP6432); + case ARMISD::ATOMCMPXCHG64_DAG: + return SelectAtomic64(N, ARM::ATOMCMPXCHG6432); } return SelectCode(N); diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index cf8c5baa8e7d..e44e35673aeb 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -14,7 +14,6 @@ #define DEBUG_TYPE "arm-isel" #include "ARM.h" -#include "ARMAddressingModes.h" #include "ARMCallingConv.h" #include "ARMConstantPoolValue.h" #include "ARMISelLowering.h" @@ -24,6 +23,7 @@ #include "ARMSubtarget.h" #include "ARMTargetMachine.h" #include "ARMTargetObjectFile.h" +#include "MCTargetDesc/ARMAddressingModes.h" #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/Function.h" @@ -38,6 +38,7 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/CodeGen/SelectionDAG.h" @@ -106,7 +107,7 @@ void ARMTargetLowering::addTypeForNEON(EVT VT, EVT PromotedLdStVT, EVT ElemTy = VT.getVectorElementType(); if (ElemTy != MVT::i64 && ElemTy != MVT::f64) - setOperationAction(ISD::VSETCC, VT.getSimpleVT(), Custom); + setOperationAction(ISD::SETCC, VT.getSimpleVT(), Custom); setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT.getSimpleVT(), Custom); if (ElemTy != MVT::i32) { setOperationAction(ISD::SINT_TO_FP, VT.getSimpleVT(), Expand); @@ -178,6 +179,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) RegInfo = TM.getRegisterInfo(); Itins = TM.getInstrItineraryData(); + setBooleanVectorContents(ZeroOrNegativeOneBooleanContent); + if (Subtarget->isTargetDarwin()) { // Uses VFP for Thumb libfuncs if available. if (Subtarget->isThumb() && Subtarget->hasVFP2()) { @@ -419,6 +422,13 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setLibcallName(RTLIB::MEMSET, "__aeabi_memset"); } + // Use divmod compiler-rt calls for iOS 5.0 and later. + if (Subtarget->getTargetTriple().getOS() == Triple::IOS && + !Subtarget->getTargetTriple().isOSVersionLT(5, 0)) { + setLibcallName(RTLIB::SDIVREM_I32, "__divmodsi4"); + setLibcallName(RTLIB::UDIVREM_I32, "__udivmodsi4"); + } + if (Subtarget->isThumb1Only()) addRegisterClass(MVT::i32, ARM::tGPRRegisterClass); else @@ -453,7 +463,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::FDIV, MVT::v2f64, Expand); setOperationAction(ISD::FREM, MVT::v2f64, Expand); setOperationAction(ISD::FCOPYSIGN, MVT::v2f64, Expand); - setOperationAction(ISD::VSETCC, MVT::v2f64, Expand); + setOperationAction(ISD::SETCC, MVT::v2f64, Expand); setOperationAction(ISD::FNEG, MVT::v2f64, Expand); setOperationAction(ISD::FABS, MVT::v2f64, Expand); setOperationAction(ISD::FSQRT, MVT::v2f64, Expand); @@ -485,8 +495,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::SDIV, MVT::v8i8, Custom); setOperationAction(ISD::UDIV, MVT::v4i16, Custom); setOperationAction(ISD::UDIV, MVT::v8i8, Custom); - setOperationAction(ISD::VSETCC, MVT::v1i64, Expand); - setOperationAction(ISD::VSETCC, MVT::v2i64, Expand); + setOperationAction(ISD::SETCC, MVT::v1i64, Expand); + setOperationAction(ISD::SETCC, MVT::v2i64, Expand); // Neon does not have single instruction SINT_TO_FP and UINT_TO_FP with // a destination type that is wider than the source. setOperationAction(ISD::SINT_TO_FP, MVT::v4i16, Custom); @@ -551,6 +561,14 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::SRL, MVT::i64, Custom); setOperationAction(ISD::SRA, MVT::i64, Custom); + if (!Subtarget->isThumb1Only()) { + // FIXME: We should do this for Thumb1 as well. + setOperationAction(ISD::ADDC, MVT::i32, Custom); + setOperationAction(ISD::ADDE, MVT::i32, Custom); + setOperationAction(ISD::SUBC, MVT::i32, Custom); + setOperationAction(ISD::SUBE, MVT::i32, Custom); + } + // ARM does not have ROTL. setOperationAction(ISD::ROTL, MVT::i32, Expand); setOperationAction(ISD::CTTZ, MVT::i32, Custom); @@ -596,62 +614,46 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); // ARMv6 Thumb1 (except for CPUs that support dmb / dsb) and earlier use // the default expansion. + // FIXME: This should be checking for v6k, not just v6. if (Subtarget->hasDataBarrier() || (Subtarget->hasV6Ops() && !Subtarget->isThumb())) { // membarrier needs custom lowering; the rest are legal and handled // normally. setOperationAction(ISD::MEMBARRIER, MVT::Other, Custom); + setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom); + // Custom lowering for 64-bit ops + setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i64, Custom); + setOperationAction(ISD::ATOMIC_LOAD_SUB, MVT::i64, Custom); + setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i64, Custom); + setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i64, Custom); + setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i64, Custom); + setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, Custom); + setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i64, Custom); + // Automatically insert fences (dmb ist) around ATOMIC_SWAP etc. + setInsertFencesForAtomic(true); } else { // Set them all for expansion, which will force libcalls. setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand); - setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i8, Expand); - setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i16, Expand); + setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand); setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i32, Expand); - setOperationAction(ISD::ATOMIC_SWAP, MVT::i8, Expand); - setOperationAction(ISD::ATOMIC_SWAP, MVT::i16, Expand); setOperationAction(ISD::ATOMIC_SWAP, MVT::i32, Expand); - setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i8, Expand); - setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i16, Expand); setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i32, Expand); - setOperationAction(ISD::ATOMIC_LOAD_SUB, MVT::i8, Expand); - setOperationAction(ISD::ATOMIC_LOAD_SUB, MVT::i16, Expand); setOperationAction(ISD::ATOMIC_LOAD_SUB, MVT::i32, Expand); - setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i8, Expand); - setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i16, Expand); setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i32, Expand); - setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i8, Expand); - setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i16, Expand); setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i32, Expand); - setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i8, Expand); - setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i16, Expand); setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i32, Expand); - setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i8, Expand); - setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i16, Expand); setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i32, Expand); - setOperationAction(ISD::ATOMIC_LOAD_MIN, MVT::i8, Expand); - setOperationAction(ISD::ATOMIC_LOAD_MIN, MVT::i16, Expand); setOperationAction(ISD::ATOMIC_LOAD_MIN, MVT::i32, Expand); - setOperationAction(ISD::ATOMIC_LOAD_MAX, MVT::i8, Expand); - setOperationAction(ISD::ATOMIC_LOAD_MAX, MVT::i16, Expand); setOperationAction(ISD::ATOMIC_LOAD_MAX, MVT::i32, Expand); - setOperationAction(ISD::ATOMIC_LOAD_UMIN, MVT::i8, Expand); - setOperationAction(ISD::ATOMIC_LOAD_UMIN, MVT::i16, Expand); setOperationAction(ISD::ATOMIC_LOAD_UMIN, MVT::i32, Expand); - setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i8, Expand); - setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i16, Expand); setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i32, Expand); + // Mark ATOMIC_LOAD and ATOMIC_STORE custom so we can handle the + // Unordered/Monotonic case. + setOperationAction(ISD::ATOMIC_LOAD, MVT::i32, Custom); + setOperationAction(ISD::ATOMIC_STORE, MVT::i32, Custom); // Since the libcalls include locking, fold in the fences setShouldFoldAtomicFences(true); } - // 64-bit versions are always libcalls (for now) - setOperationAction(ISD::ATOMIC_CMP_SWAP, MVT::i64, Expand); - setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, Expand); - setOperationAction(ISD::ATOMIC_LOAD_ADD, MVT::i64, Expand); - setOperationAction(ISD::ATOMIC_LOAD_SUB, MVT::i64, Expand); - setOperationAction(ISD::ATOMIC_LOAD_AND, MVT::i64, Expand); - setOperationAction(ISD::ATOMIC_LOAD_OR, MVT::i64, Expand); - setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i64, Expand); - setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i64, Expand); setOperationAction(ISD::PREFETCH, MVT::Other, Custom); @@ -839,6 +841,11 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { case ARMISD::SRA_FLAG: return "ARMISD::SRA_FLAG"; case ARMISD::RRX: return "ARMISD::RRX"; + case ARMISD::ADDC: return "ARMISD::ADDC"; + case ARMISD::ADDE: return "ARMISD::ADDE"; + case ARMISD::SUBC: return "ARMISD::SUBC"; + case ARMISD::SUBE: return "ARMISD::SUBE"; + case ARMISD::VMOVRRD: return "ARMISD::VMOVRRD"; case ARMISD::VMOVDRR: return "ARMISD::VMOVDRR"; @@ -935,6 +942,11 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { } } +EVT ARMTargetLowering::getSetCCResultType(EVT VT) const { + if (!VT.isVector()) return getPointerTy(); + return VT.changeVectorElementTypeToInteger(); +} + /// getRegClassFor - Return the register class that should be used for the /// specified value type. TargetRegisterClass *ARMTargetLowering::getRegClassFor(EVT VT) const { @@ -1210,8 +1222,8 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee, MachineFunction &MF = DAG.getMachineFunction(); bool IsStructRet = (Outs.empty()) ? false : Outs[0].Flags.isSRet(); bool IsSibCall = false; - // Temporarily disable tail calls so things don't break. - if (!EnableARMTailCalls) + // Disable tail calls if they're not supported. + if (!EnableARMTailCalls && !Subtarget->supportsTailCall()) isTailCall = false; if (isTailCall) { // Check if it's really possible to do a tail call. @@ -1336,10 +1348,12 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee, SDValue Src = DAG.getNode(ISD::ADD, dl, getPointerTy(), Arg, SrcOffset); SDValue SizeNode = DAG.getConstant(Flags.getByValSize() - 4*offset, MVT::i32); + // TODO: Disable AlwaysInline when it becomes possible + // to emit a nested call sequence. MemOpChains.push_back(DAG.getMemcpy(Chain, dl, Dst, Src, SizeNode, Flags.getByValAlign(), /*isVolatile=*/false, - /*AlwaysInline=*/false, + /*AlwaysInline=*/true, MachinePointerInfo(0), MachinePointerInfo(0))); @@ -1404,9 +1418,9 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee, const GlobalValue *GV = G->getGlobal(); // Create a constant pool entry for the callee address unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); - ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, - ARMPCLabelIndex, - ARMCP::CPValue, 0); + ARMConstantPoolValue *CPV = + ARMConstantPoolConstant::Create(GV, ARMPCLabelIndex, ARMCP::CPValue, 0); + // Get the address of the callee into a register SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4); CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); @@ -1419,8 +1433,9 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // Create a constant pool entry for the callee address unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); - ARMConstantPoolValue *CPV = new ARMConstantPoolValue(*DAG.getContext(), - Sym, ARMPCLabelIndex, 0); + ARMConstantPoolValue *CPV = + ARMConstantPoolSymbol::Create(*DAG.getContext(), Sym, + ARMPCLabelIndex, 0); // Get the address of the callee into a register SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4); CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); @@ -1441,9 +1456,8 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee, // tBX takes a register source operand. if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) { unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); - ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, - ARMPCLabelIndex, - ARMCP::CPValue, 4); + ARMConstantPoolValue *CPV = + ARMConstantPoolConstant::Create(GV, ARMPCLabelIndex, ARMCP::CPValue, 4); SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4); CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); Callee = DAG.getLoad(getPointerTy(), dl, @@ -1470,8 +1484,9 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee, const char *Sym = S->getSymbol(); if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) { unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); - ARMConstantPoolValue *CPV = new ARMConstantPoolValue(*DAG.getContext(), - Sym, ARMPCLabelIndex, 4); + ARMConstantPoolValue *CPV = + ARMConstantPoolSymbol::Create(*DAG.getContext(), Sym, + ARMPCLabelIndex, 4); SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4); CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); Callee = DAG.getLoad(getPointerTy(), dl, @@ -1940,9 +1955,9 @@ SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op, } else { unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; ARMPCLabelIndex = AFI->createPICLabelUId(); - ARMConstantPoolValue *CPV = new ARMConstantPoolValue(BA, ARMPCLabelIndex, - ARMCP::CPBlockAddress, - PCAdj); + ARMConstantPoolValue *CPV = + ARMConstantPoolConstant::Create(BA, ARMPCLabelIndex, + ARMCP::CPBlockAddress, PCAdj); CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); } CPAddr = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, CPAddr); @@ -1966,8 +1981,8 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, ARMFunctionInfo *AFI = MF.getInfo(); unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); ARMConstantPoolValue *CPV = - new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, - ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true); + ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, + ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true); SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4); Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument); Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Argument, @@ -1982,11 +1997,11 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, ArgListTy Args; ArgListEntry Entry; Entry.Node = Argument; - Entry.Ty = (const Type *) Type::getInt32Ty(*DAG.getContext()); + Entry.Ty = (Type *) Type::getInt32Ty(*DAG.getContext()); Args.push_back(Entry); // FIXME: is there useful debug info available here? std::pair CallResult = - LowerCallTo(Chain, (const Type *) Type::getInt32Ty(*DAG.getContext()), + LowerCallTo(Chain, (Type *) Type::getInt32Ty(*DAG.getContext()), false, false, false, false, 0, CallingConv::C, false, /*isReturnValueUsed=*/true, DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, dl); @@ -2013,8 +2028,9 @@ ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA, // Initial exec model. unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; ARMConstantPoolValue *CPV = - new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, - ARMCP::CPValue, PCAdj, ARMCP::GOTTPOFF, true); + ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, + ARMCP::CPValue, PCAdj, ARMCP::GOTTPOFF, + true); Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4); Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset); Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, @@ -2030,7 +2046,8 @@ ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA, false, false, 0); } else { // local exec model - ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMCP::TPOFF); + ARMConstantPoolValue *CPV = + ARMConstantPoolConstant::Create(GV, ARMCP::TPOFF); Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4); Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset); Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, @@ -2066,7 +2083,8 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op, if (RelocM == Reloc::PIC_) { bool UseGOTOFF = GV->hasLocalLinkage() || GV->hasHiddenVisibility(); ARMConstantPoolValue *CPV = - new ARMConstantPoolValue(GV, UseGOTOFF ? ARMCP::GOTOFF : ARMCP::GOT); + ARMConstantPoolConstant::Create(GV, + UseGOTOFF ? ARMCP::GOTOFF : ARMCP::GOT); SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), @@ -2135,7 +2153,8 @@ SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op, ARMPCLabelIndex = AFI->createPICLabelUId(); unsigned PCAdj = (RelocM != Reloc::PIC_) ? 0 : (Subtarget->isThumb()?4:8); ARMConstantPoolValue *CPV = - new ARMConstantPoolValue(GV, ARMPCLabelIndex, ARMCP::CPValue, PCAdj); + ARMConstantPoolConstant::Create(GV, ARMPCLabelIndex, ARMCP::CPValue, + PCAdj); CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); } CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); @@ -2167,9 +2186,9 @@ SDValue ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op, EVT PtrVT = getPointerTy(); DebugLoc dl = Op.getDebugLoc(); unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; - ARMConstantPoolValue *CPV = new ARMConstantPoolValue(*DAG.getContext(), - "_GLOBAL_OFFSET_TABLE_", - ARMPCLabelIndex, PCAdj); + ARMConstantPoolValue *CPV = + ARMConstantPoolSymbol::Create(*DAG.getContext(), "_GLOBAL_OFFSET_TABLE_", + ARMPCLabelIndex, PCAdj); 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, @@ -2191,7 +2210,8 @@ SDValue ARMTargetLowering::LowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const { DebugLoc dl = Op.getDebugLoc(); SDValue Val = DAG.getConstant(0, MVT::i32); - return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, MVT::i32, Op.getOperand(0), + return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, + DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0), Op.getOperand(1), Val); } @@ -2224,8 +2244,8 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG, unsigned PCAdj = (RelocM != Reloc::PIC_) ? 0 : (Subtarget->isThumb() ? 4 : 8); ARMConstantPoolValue *CPV = - new ARMConstantPoolValue(MF.getFunction(), ARMPCLabelIndex, - ARMCP::CPLSDA, PCAdj); + ARMConstantPoolConstant::Create(MF.getFunction(), ARMPCLabelIndex, + ARMCP::CPLSDA, PCAdj); CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); SDValue Result = @@ -2277,6 +2297,25 @@ static SDValue LowerMEMBARRIER(SDValue Op, SelectionDAG &DAG, DAG.getConstant(DMBOpt, MVT::i32)); } + +static SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG, + const ARMSubtarget *Subtarget) { + // FIXME: handle "fence singlethread" more efficiently. + DebugLoc dl = Op.getDebugLoc(); + if (!Subtarget->hasDataBarrier()) { + // Some ARMv6 cpus can support data barriers with an mcr instruction. + // Thumb1 and pre-v6 ARM mode use a libcall instead and should never get + // here. + assert(Subtarget->hasV6Ops() && !Subtarget->isThumb() && + "Unexpected ISD::MEMBARRIER encountered. Should be libcall!"); + return DAG.getNode(ARMISD::MEMBARRIER_MCR, dl, MVT::Other, Op.getOperand(0), + DAG.getConstant(0, MVT::i32)); + } + + return DAG.getNode(ARMISD::MEMBARRIER, dl, MVT::Other, Op.getOperand(0), + DAG.getConstant(ARM_MB::ISH, MVT::i32)); +} + static SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG, const ARMSubtarget *Subtarget) { // ARM pre v5TE and Thumb1 does not have preload instructions. @@ -2754,7 +2793,7 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const { SDValue ARMcc; SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32); SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl); - return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMcc, CCR, Cmp); + return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMcc, CCR,Cmp); } ARMCC::CondCodes CondCode, CondCode2; @@ -2993,8 +3032,8 @@ static SDValue LowerVectorINT_TO_FP(SDValue Op, SelectionDAG &DAG) { EVT VT = Op.getValueType(); DebugLoc dl = Op.getDebugLoc(); - EVT OperandVT = Op.getOperand(0).getValueType(); - assert(OperandVT == MVT::v4i16 && "Invalid type for custom lowering!"); + assert(Op.getOperand(0).getValueType() == MVT::v4i16 && + "Invalid type for custom lowering!"); if (VT != MVT::v4f32) return DAG.UnrollVectorOp(Op.getNode()); @@ -3905,8 +3944,7 @@ SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG, } // Try an immediate VMVN. - uint64_t NegatedImm = (SplatBits.getZExtValue() ^ - ((1LL << SplatBitSize) - 1)); + uint64_t NegatedImm = (~SplatBits).getZExtValue(); Val = isNEONModifiedImm(NegatedImm, SplatUndef.getZExtValue(), SplatBitSize, DAG, VmovVT, VT.is128BitVector(), @@ -4019,6 +4057,14 @@ SDValue ARMTargetLowering::ReconstructShuffle(SDValue Op, // A shuffle can only come from building a vector from various // elements of other vectors. return SDValue(); + } else if (V.getOperand(0).getValueType().getVectorElementType() != + VT.getVectorElementType()) { + // This code doesn't know how to handle shuffles where the vector + // element types do not match (this happens because type legalization + // promotes the return type of EXTRACT_VECTOR_ELT). + // FIXME: It might be appropriate to extend this code to handle + // mismatched types. + return SDValue(); } // Record this extraction against the appropriate vector if possible... @@ -4819,6 +4865,71 @@ static SDValue LowerUDIV(SDValue Op, SelectionDAG &DAG) { return N0; } +static SDValue LowerADDC_ADDE_SUBC_SUBE(SDValue Op, SelectionDAG &DAG) { + EVT VT = Op.getNode()->getValueType(0); + SDVTList VTs = DAG.getVTList(VT, MVT::i32); + + unsigned Opc; + bool ExtraOp = false; + switch (Op.getOpcode()) { + default: assert(0 && "Invalid code"); + case ISD::ADDC: Opc = ARMISD::ADDC; break; + case ISD::ADDE: Opc = ARMISD::ADDE; ExtraOp = true; break; + case ISD::SUBC: Opc = ARMISD::SUBC; break; + case ISD::SUBE: Opc = ARMISD::SUBE; ExtraOp = true; break; + } + + if (!ExtraOp) + return DAG.getNode(Opc, Op->getDebugLoc(), VTs, Op.getOperand(0), + Op.getOperand(1)); + return DAG.getNode(Opc, Op->getDebugLoc(), VTs, Op.getOperand(0), + Op.getOperand(1), Op.getOperand(2)); +} + +static SDValue LowerAtomicLoadStore(SDValue Op, SelectionDAG &DAG) { + // Monotonic load/store is legal for all targets + if (cast(Op)->getOrdering() <= Monotonic) + return Op; + + // Aquire/Release load/store is not legal for targets without a + // dmb or equivalent available. + return SDValue(); +} + + +static void +ReplaceATOMIC_OP_64(SDNode *Node, SmallVectorImpl& Results, + SelectionDAG &DAG, unsigned NewOp) { + DebugLoc dl = Node->getDebugLoc(); + assert (Node->getValueType(0) == MVT::i64 && + "Only know how to expand i64 atomics"); + + SmallVector Ops; + Ops.push_back(Node->getOperand(0)); // Chain + Ops.push_back(Node->getOperand(1)); // Ptr + // Low part of Val1 + Ops.push_back(DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, + Node->getOperand(2), DAG.getIntPtrConstant(0))); + // High part of Val1 + Ops.push_back(DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, + Node->getOperand(2), DAG.getIntPtrConstant(1))); + if (NewOp == ARMISD::ATOMCMPXCHG64_DAG) { + // High part of Val1 + Ops.push_back(DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, + Node->getOperand(3), DAG.getIntPtrConstant(0))); + // High part of Val2 + Ops.push_back(DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, + Node->getOperand(3), DAG.getIntPtrConstant(1))); + } + SDVTList Tys = DAG.getVTList(MVT::i32, MVT::i32, MVT::Other); + SDValue Result = + DAG.getMemIntrinsicNode(NewOp, dl, Tys, Ops.data(), Ops.size(), MVT::i64, + cast(Node)->getMemOperand()); + SDValue OpsF[] = { Result.getValue(0), Result.getValue(1) }; + Results.push_back(DAG.getNode(ISD::BUILD_PAIR, dl, MVT::i64, OpsF, 2)); + Results.push_back(Result.getValue(2)); +} + SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { default: llvm_unreachable("Don't know how to custom lower this!"); @@ -4834,6 +4945,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::BR_JT: return LowerBR_JT(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG); case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG, Subtarget); + case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG, Subtarget); case ISD::PREFETCH: return LowerPREFETCH(Op, DAG, Subtarget); case ISD::SINT_TO_FP: case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG); @@ -4856,7 +4968,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::SRL_PARTS: case ISD::SRA_PARTS: return LowerShiftRightParts(Op, DAG); case ISD::CTTZ: return LowerCTTZ(Op.getNode(), DAG, Subtarget); - case ISD::VSETCC: return LowerVSETCC(Op, DAG); + case ISD::SETCC: return LowerVSETCC(Op, DAG); case ISD::BUILD_VECTOR: return LowerBUILD_VECTOR(Op, DAG, Subtarget); case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG); case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG); @@ -4865,6 +4977,12 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::MUL: return LowerMUL(Op, DAG); case ISD::SDIV: return LowerSDIV(Op, DAG); case ISD::UDIV: return LowerUDIV(Op, DAG); + case ISD::ADDC: + case ISD::ADDE: + case ISD::SUBC: + case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG); + case ISD::ATOMIC_LOAD: + case ISD::ATOMIC_STORE: return LowerAtomicLoadStore(Op, DAG); } return SDValue(); } @@ -4886,6 +5004,30 @@ void ARMTargetLowering::ReplaceNodeResults(SDNode *N, case ISD::SRA: Res = Expand64BitShift(N, DAG, Subtarget); break; + case ISD::ATOMIC_LOAD_ADD: + ReplaceATOMIC_OP_64(N, Results, DAG, ARMISD::ATOMADD64_DAG); + return; + case ISD::ATOMIC_LOAD_AND: + ReplaceATOMIC_OP_64(N, Results, DAG, ARMISD::ATOMAND64_DAG); + return; + case ISD::ATOMIC_LOAD_NAND: + ReplaceATOMIC_OP_64(N, Results, DAG, ARMISD::ATOMNAND64_DAG); + return; + case ISD::ATOMIC_LOAD_OR: + ReplaceATOMIC_OP_64(N, Results, DAG, ARMISD::ATOMOR64_DAG); + return; + case ISD::ATOMIC_LOAD_SUB: + ReplaceATOMIC_OP_64(N, Results, DAG, ARMISD::ATOMSUB64_DAG); + return; + case ISD::ATOMIC_LOAD_XOR: + ReplaceATOMIC_OP_64(N, Results, DAG, ARMISD::ATOMXOR64_DAG); + return; + case ISD::ATOMIC_SWAP: + ReplaceATOMIC_OP_64(N, Results, DAG, ARMISD::ATOMSWAP64_DAG); + return; + case ISD::ATOMIC_CMP_SWAP: + ReplaceATOMIC_OP_64(N, Results, DAG, ARMISD::ATOMCMPXCHG64_DAG); + return; } if (Res.getNode()) Results.push_back(Res); @@ -4963,7 +5105,10 @@ ARMTargetLowering::EmitAtomicCmpSwap(MachineInstr *MI, // cmp dest, oldval // bne exitMBB BB = loop1MBB; - AddDefaultPred(BuildMI(BB, dl, TII->get(ldrOpc), dest).addReg(ptr)); + MachineInstrBuilder MIB = BuildMI(BB, dl, TII->get(ldrOpc), dest).addReg(ptr); + if (ldrOpc == ARM::t2LDREX) + MIB.addImm(0); + AddDefaultPred(MIB); AddDefaultPred(BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPrr : ARM::CMPrr)) .addReg(dest).addReg(oldval)); BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc)) @@ -4976,8 +5121,10 @@ ARMTargetLowering::EmitAtomicCmpSwap(MachineInstr *MI, // cmp scratch, #0 // bne loop1MBB BB = loop2MBB; - AddDefaultPred(BuildMI(BB, dl, TII->get(strOpc), scratch).addReg(newval) - .addReg(ptr)); + MIB = BuildMI(BB, dl, TII->get(strOpc), scratch).addReg(newval).addReg(ptr); + if (strOpc == ARM::t2STREX) + MIB.addImm(0); + AddDefaultPred(MIB); AddDefaultPred(BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri)) .addReg(scratch).addImm(0)); BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc)) @@ -5063,7 +5210,10 @@ ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, // bne- loopMBB // fallthrough --> exitMBB BB = loopMBB; - AddDefaultPred(BuildMI(BB, dl, TII->get(ldrOpc), dest).addReg(ptr)); + MachineInstrBuilder MIB = BuildMI(BB, dl, TII->get(ldrOpc), dest).addReg(ptr); + if (ldrOpc == ARM::t2LDREX) + MIB.addImm(0); + AddDefaultPred(MIB); if (BinOpcode) { // operand order needs to go the other way for NAND if (BinOpcode == ARM::BICrr || BinOpcode == ARM::t2BICrr) @@ -5074,8 +5224,10 @@ ARMTargetLowering::EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *BB, addReg(dest).addReg(incr)).addReg(0); } - AddDefaultPred(BuildMI(BB, dl, TII->get(strOpc), scratch).addReg(scratch2) - .addReg(ptr)); + MIB = BuildMI(BB, dl, TII->get(strOpc), scratch).addReg(scratch2).addReg(ptr); + if (strOpc == ARM::t2STREX) + MIB.addImm(0); + AddDefaultPred(MIB); AddDefaultPred(BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri)) .addReg(scratch).addImm(0)); BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc)) @@ -5125,12 +5277,12 @@ ARMTargetLowering::EmitAtomicBinaryMinMax(MachineInstr *MI, case 1: ldrOpc = isThumb2 ? ARM::t2LDREXB : ARM::LDREXB; strOpc = isThumb2 ? ARM::t2STREXB : ARM::STREXB; - extendOpc = isThumb2 ? ARM::t2SXTBr : ARM::SXTBr; + extendOpc = isThumb2 ? ARM::t2SXTB : ARM::SXTB; break; case 2: ldrOpc = isThumb2 ? ARM::t2LDREXH : ARM::LDREXH; strOpc = isThumb2 ? ARM::t2STREXH : ARM::STREXH; - extendOpc = isThumb2 ? ARM::t2SXTHr : ARM::SXTHr; + extendOpc = isThumb2 ? ARM::t2SXTH : ARM::SXTH; break; case 4: ldrOpc = isThumb2 ? ARM::t2LDREX : ARM::LDREX; @@ -5170,12 +5322,17 @@ ARMTargetLowering::EmitAtomicBinaryMinMax(MachineInstr *MI, // bne- loopMBB // fallthrough --> exitMBB BB = loopMBB; - AddDefaultPred(BuildMI(BB, dl, TII->get(ldrOpc), dest).addReg(ptr)); + MachineInstrBuilder MIB = BuildMI(BB, dl, TII->get(ldrOpc), dest).addReg(ptr); + if (ldrOpc == ARM::t2LDREX) + MIB.addImm(0); + AddDefaultPred(MIB); // Sign extend the value, if necessary. if (signExtend && extendOpc) { oldval = MRI.createVirtualRegister(ARM::GPRRegisterClass); - AddDefaultPred(BuildMI(BB, dl, TII->get(extendOpc), oldval).addReg(dest)); + AddDefaultPred(BuildMI(BB, dl, TII->get(extendOpc), oldval) + .addReg(dest) + .addImm(0)); } // Build compare and cmov instructions. @@ -5184,8 +5341,10 @@ ARMTargetLowering::EmitAtomicBinaryMinMax(MachineInstr *MI, BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2MOVCCr : ARM::MOVCCr), scratch2) .addReg(oldval).addReg(incr).addImm(Cond).addReg(ARM::CPSR); - AddDefaultPred(BuildMI(BB, dl, TII->get(strOpc), scratch).addReg(scratch2) - .addReg(ptr)); + MIB = BuildMI(BB, dl, TII->get(strOpc), scratch).addReg(scratch2).addReg(ptr); + if (strOpc == ARM::t2STREX) + MIB.addImm(0); + AddDefaultPred(MIB); AddDefaultPred(BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri)) .addReg(scratch).addImm(0)); BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc)) @@ -5203,6 +5362,589 @@ ARMTargetLowering::EmitAtomicBinaryMinMax(MachineInstr *MI, return BB; } +MachineBasicBlock * +ARMTargetLowering::EmitAtomicBinary64(MachineInstr *MI, MachineBasicBlock *BB, + unsigned Op1, unsigned Op2, + bool NeedsCarry, bool IsCmpxchg) const { + // This also handles ATOMIC_SWAP, indicated by Op1==0. + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineFunction *MF = BB->getParent(); + MachineFunction::iterator It = BB; + ++It; + + unsigned destlo = MI->getOperand(0).getReg(); + unsigned desthi = MI->getOperand(1).getReg(); + unsigned ptr = MI->getOperand(2).getReg(); + unsigned vallo = MI->getOperand(3).getReg(); + unsigned valhi = MI->getOperand(4).getReg(); + DebugLoc dl = MI->getDebugLoc(); + bool isThumb2 = Subtarget->isThumb2(); + + MachineRegisterInfo &MRI = BB->getParent()->getRegInfo(); + if (isThumb2) { + MRI.constrainRegClass(destlo, ARM::rGPRRegisterClass); + MRI.constrainRegClass(desthi, ARM::rGPRRegisterClass); + MRI.constrainRegClass(ptr, ARM::rGPRRegisterClass); + } + + unsigned ldrOpc = isThumb2 ? ARM::t2LDREXD : ARM::LDREXD; + unsigned strOpc = isThumb2 ? ARM::t2STREXD : ARM::STREXD; + + MachineBasicBlock *loopMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *contBB = 0, *cont2BB = 0; + if (IsCmpxchg) { + contBB = MF->CreateMachineBasicBlock(LLVM_BB); + cont2BB = MF->CreateMachineBasicBlock(LLVM_BB); + } + MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB); + MF->insert(It, loopMBB); + if (IsCmpxchg) { + MF->insert(It, contBB); + MF->insert(It, cont2BB); + } + MF->insert(It, exitMBB); + + // Transfer the remainder of BB and its successor edges to exitMBB. + exitMBB->splice(exitMBB->begin(), BB, + llvm::next(MachineBasicBlock::iterator(MI)), + BB->end()); + exitMBB->transferSuccessorsAndUpdatePHIs(BB); + + TargetRegisterClass *TRC = + isThumb2 ? ARM::tGPRRegisterClass : ARM::GPRRegisterClass; + unsigned storesuccess = MRI.createVirtualRegister(TRC); + + // thisMBB: + // ... + // fallthrough --> loopMBB + BB->addSuccessor(loopMBB); + + // loopMBB: + // ldrexd r2, r3, ptr + // r0, r2, incr + // r1, r3, incr + // strexd storesuccess, r0, r1, ptr + // cmp storesuccess, #0 + // bne- loopMBB + // fallthrough --> exitMBB + // + // Note that the registers are explicitly specified because there is not any + // way to force the register allocator to allocate a register pair. + // + // FIXME: The hardcoded registers are not necessary for Thumb2, but we + // need to properly enforce the restriction that the two output registers + // for ldrexd must be different. + BB = loopMBB; + // Load + AddDefaultPred(BuildMI(BB, dl, TII->get(ldrOpc)) + .addReg(ARM::R2, RegState::Define) + .addReg(ARM::R3, RegState::Define).addReg(ptr)); + // Copy r2/r3 into dest. (This copy will normally be coalesced.) + BuildMI(BB, dl, TII->get(TargetOpcode::COPY), destlo).addReg(ARM::R2); + BuildMI(BB, dl, TII->get(TargetOpcode::COPY), desthi).addReg(ARM::R3); + + if (IsCmpxchg) { + // Add early exit + for (unsigned i = 0; i < 2; i++) { + AddDefaultPred(BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPrr : + ARM::CMPrr)) + .addReg(i == 0 ? destlo : desthi) + .addReg(i == 0 ? vallo : valhi)); + BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc)) + .addMBB(exitMBB).addImm(ARMCC::NE).addReg(ARM::CPSR); + BB->addSuccessor(exitMBB); + BB->addSuccessor(i == 0 ? contBB : cont2BB); + BB = (i == 0 ? contBB : cont2BB); + } + + // Copy to physregs for strexd + unsigned setlo = MI->getOperand(5).getReg(); + unsigned sethi = MI->getOperand(6).getReg(); + BuildMI(BB, dl, TII->get(TargetOpcode::COPY), ARM::R0).addReg(setlo); + BuildMI(BB, dl, TII->get(TargetOpcode::COPY), ARM::R1).addReg(sethi); + } else if (Op1) { + // Perform binary operation + AddDefaultPred(BuildMI(BB, dl, TII->get(Op1), ARM::R0) + .addReg(destlo).addReg(vallo)) + .addReg(NeedsCarry ? ARM::CPSR : 0, getDefRegState(NeedsCarry)); + AddDefaultPred(BuildMI(BB, dl, TII->get(Op2), ARM::R1) + .addReg(desthi).addReg(valhi)).addReg(0); + } else { + // Copy to physregs for strexd + BuildMI(BB, dl, TII->get(TargetOpcode::COPY), ARM::R0).addReg(vallo); + BuildMI(BB, dl, TII->get(TargetOpcode::COPY), ARM::R1).addReg(valhi); + } + + // Store + AddDefaultPred(BuildMI(BB, dl, TII->get(strOpc), storesuccess) + .addReg(ARM::R0).addReg(ARM::R1).addReg(ptr)); + // Cmp+jump + AddDefaultPred(BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2CMPri : ARM::CMPri)) + .addReg(storesuccess).addImm(0)); + BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc)) + .addMBB(loopMBB).addImm(ARMCC::NE).addReg(ARM::CPSR); + + BB->addSuccessor(loopMBB); + BB->addSuccessor(exitMBB); + + // exitMBB: + // ... + BB = exitMBB; + + MI->eraseFromParent(); // The instruction is gone now. + + return BB; +} + +/// EmitBasePointerRecalculation - For functions using a base pointer, we +/// rematerialize it (via the frame pointer). +void ARMTargetLowering:: +EmitBasePointerRecalculation(MachineInstr *MI, MachineBasicBlock *MBB, + MachineBasicBlock *DispatchBB) const { + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + const ARMBaseInstrInfo *AII = static_cast(TII); + MachineFunction &MF = *MI->getParent()->getParent(); + ARMFunctionInfo *AFI = MF.getInfo(); + const ARMBaseRegisterInfo &RI = AII->getRegisterInfo(); + + if (!RI.hasBasePointer(MF)) return; + + MachineBasicBlock::iterator MBBI = MI; + + int32_t NumBytes = AFI->getFramePtrSpillOffset(); + unsigned FramePtr = RI.getFrameRegister(MF); + assert(MF.getTarget().getFrameLowering()->hasFP(MF) && + "Base pointer without frame pointer?"); + + if (AFI->isThumb2Function()) + llvm::emitT2RegPlusImmediate(*MBB, MBBI, MI->getDebugLoc(), ARM::R6, + FramePtr, -NumBytes, ARMCC::AL, 0, *AII); + else if (AFI->isThumbFunction()) + llvm::emitThumbRegPlusImmediate(*MBB, MBBI, MI->getDebugLoc(), ARM::R6, + FramePtr, -NumBytes, *AII, RI); + else + llvm::emitARMRegPlusImmediate(*MBB, MBBI, MI->getDebugLoc(), ARM::R6, + FramePtr, -NumBytes, ARMCC::AL, 0, *AII); + + if (!RI.needsStackRealignment(MF)) return; + + // If there's dynamic realignment, adjust for it. + MachineFrameInfo *MFI = MF.getFrameInfo(); + unsigned MaxAlign = MFI->getMaxAlignment(); + assert(!AFI->isThumb1OnlyFunction()); + + // Emit bic r6, r6, MaxAlign + unsigned bicOpc = AFI->isThumbFunction() ? ARM::t2BICri : ARM::BICri; + AddDefaultCC( + AddDefaultPred( + BuildMI(*MBB, MBBI, MI->getDebugLoc(), TII->get(bicOpc), ARM::R6) + .addReg(ARM::R6, RegState::Kill) + .addImm(MaxAlign - 1))); +} + +/// SetupEntryBlockForSjLj - Insert code into the entry block that creates and +/// registers the function context. +void ARMTargetLowering:: +SetupEntryBlockForSjLj(MachineInstr *MI, MachineBasicBlock *MBB, + MachineBasicBlock *DispatchBB, int FI) const { + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + MachineFunction *MF = MBB->getParent(); + MachineRegisterInfo *MRI = &MF->getRegInfo(); + MachineConstantPool *MCP = MF->getConstantPool(); + ARMFunctionInfo *AFI = MF->getInfo(); + const Function *F = MF->getFunction(); + + bool isThumb = Subtarget->isThumb(); + bool isThumb2 = Subtarget->isThumb2(); + + unsigned PCLabelId = AFI->createPICLabelUId(); + unsigned PCAdj = (isThumb || isThumb2) ? 4 : 8; + ARMConstantPoolValue *CPV = + ARMConstantPoolMBB::Create(F->getContext(), DispatchBB, PCLabelId, PCAdj); + unsigned CPI = MCP->getConstantPoolIndex(CPV, 4); + + const TargetRegisterClass *TRC = + isThumb ? ARM::tGPRRegisterClass : ARM::GPRRegisterClass; + + // Grab constant pool and fixed stack memory operands. + MachineMemOperand *CPMMO = + MF->getMachineMemOperand(MachinePointerInfo::getConstantPool(), + MachineMemOperand::MOLoad, 4, 4); + + MachineMemOperand *FIMMOSt = + MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), + MachineMemOperand::MOStore, 4, 4); + + EmitBasePointerRecalculation(MI, MBB, DispatchBB); + + // Load the address of the dispatch MBB into the jump buffer. + if (isThumb2) { + // Incoming value: jbuf + // ldr.n r5, LCPI1_1 + // orr r5, r5, #1 + // add r5, pc + // str r5, [$jbuf, #+4] ; &jbuf[1] + unsigned NewVReg1 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::t2LDRpci), NewVReg1) + .addConstantPoolIndex(CPI) + .addMemOperand(CPMMO)); + // Set the low bit because of thumb mode. + unsigned NewVReg2 = MRI->createVirtualRegister(TRC); + AddDefaultCC( + AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::t2ORRri), NewVReg2) + .addReg(NewVReg1, RegState::Kill) + .addImm(0x01))); + unsigned NewVReg3 = MRI->createVirtualRegister(TRC); + BuildMI(*MBB, MI, dl, TII->get(ARM::tPICADD), NewVReg3) + .addReg(NewVReg2, RegState::Kill) + .addImm(PCLabelId); + AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::t2STRi12)) + .addReg(NewVReg3, RegState::Kill) + .addFrameIndex(FI) + .addImm(36) // &jbuf[1] :: pc + .addMemOperand(FIMMOSt)); + } else if (isThumb) { + // Incoming value: jbuf + // ldr.n r1, LCPI1_4 + // add r1, pc + // mov r2, #1 + // orrs r1, r2 + // add r2, $jbuf, #+4 ; &jbuf[1] + // str r1, [r2] + unsigned NewVReg1 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::tLDRpci), NewVReg1) + .addConstantPoolIndex(CPI) + .addMemOperand(CPMMO)); + unsigned NewVReg2 = MRI->createVirtualRegister(TRC); + BuildMI(*MBB, MI, dl, TII->get(ARM::tPICADD), NewVReg2) + .addReg(NewVReg1, RegState::Kill) + .addImm(PCLabelId); + // Set the low bit because of thumb mode. + unsigned NewVReg3 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::tMOVi8), NewVReg3) + .addReg(ARM::CPSR, RegState::Define) + .addImm(1)); + unsigned NewVReg4 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::tORR), NewVReg4) + .addReg(ARM::CPSR, RegState::Define) + .addReg(NewVReg2, RegState::Kill) + .addReg(NewVReg3, RegState::Kill)); + unsigned NewVReg5 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::tADDrSPi), NewVReg5) + .addFrameIndex(FI) + .addImm(36)); // &jbuf[1] :: pc + AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::tSTRi)) + .addReg(NewVReg4, RegState::Kill) + .addReg(NewVReg5, RegState::Kill) + .addImm(0) + .addMemOperand(FIMMOSt)); + } else { + // Incoming value: jbuf + // ldr r1, LCPI1_1 + // add r1, pc, r1 + // str r1, [$jbuf, #+4] ; &jbuf[1] + unsigned NewVReg1 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::LDRi12), NewVReg1) + .addConstantPoolIndex(CPI) + .addImm(0) + .addMemOperand(CPMMO)); + unsigned NewVReg2 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::PICADD), NewVReg2) + .addReg(NewVReg1, RegState::Kill) + .addImm(PCLabelId)); + AddDefaultPred(BuildMI(*MBB, MI, dl, TII->get(ARM::STRi12)) + .addReg(NewVReg2, RegState::Kill) + .addFrameIndex(FI) + .addImm(36) // &jbuf[1] :: pc + .addMemOperand(FIMMOSt)); + } +} + +MachineBasicBlock *ARMTargetLowering:: +EmitSjLjDispatchBlock(MachineInstr *MI, MachineBasicBlock *MBB) const { + const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); + DebugLoc dl = MI->getDebugLoc(); + MachineFunction *MF = MBB->getParent(); + MachineRegisterInfo *MRI = &MF->getRegInfo(); + ARMFunctionInfo *AFI = MF->getInfo(); + MachineFrameInfo *MFI = MF->getFrameInfo(); + int FI = MFI->getFunctionContextIndex(); + + const TargetRegisterClass *TRC = + Subtarget->isThumb() ? ARM::tGPRRegisterClass : ARM::GPRRegisterClass; + + // Get a mapping of the call site numbers to all of the landing pads they're + // associated with. + DenseMap > CallSiteNumToLPad; + unsigned MaxCSNum = 0; + MachineModuleInfo &MMI = MF->getMMI(); + for (MachineFunction::iterator BB = MF->begin(), E = MF->end(); BB != E; ++BB) { + if (!BB->isLandingPad()) continue; + + // FIXME: We should assert that the EH_LABEL is the first MI in the landing + // pad. + for (MachineBasicBlock::iterator + II = BB->begin(), IE = BB->end(); II != IE; ++II) { + if (!II->isEHLabel()) continue; + + MCSymbol *Sym = II->getOperand(0).getMCSymbol(); + if (!MMI.hasCallSiteLandingPad(Sym)) continue; + + SmallVectorImpl &CallSiteIdxs = MMI.getCallSiteLandingPad(Sym); + for (SmallVectorImpl::iterator + CSI = CallSiteIdxs.begin(), CSE = CallSiteIdxs.end(); + CSI != CSE; ++CSI) { + CallSiteNumToLPad[*CSI].push_back(BB); + MaxCSNum = std::max(MaxCSNum, *CSI); + } + break; + } + } + + // Get an ordered list of the machine basic blocks for the jump table. + std::vector LPadList; + SmallPtrSet InvokeBBs; + LPadList.reserve(CallSiteNumToLPad.size()); + for (unsigned I = 1; I <= MaxCSNum; ++I) { + SmallVectorImpl &MBBList = CallSiteNumToLPad[I]; + for (SmallVectorImpl::iterator + II = MBBList.begin(), IE = MBBList.end(); II != IE; ++II) { + LPadList.push_back(*II); + InvokeBBs.insert((*II)->pred_begin(), (*II)->pred_end()); + } + } + + assert(!LPadList.empty() && + "No landing pad destinations for the dispatch jump table!"); + + // Create the jump table and associated information. + MachineJumpTableInfo *JTI = + MF->getOrCreateJumpTableInfo(MachineJumpTableInfo::EK_Inline); + unsigned MJTI = JTI->createJumpTableIndex(LPadList); + unsigned UId = AFI->createJumpTableUId(); + + // Create the MBBs for the dispatch code. + + // Shove the dispatch's address into the return slot in the function context. + MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock(); + DispatchBB->setIsLandingPad(); + + MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock(); + BuildMI(TrapBB, dl, TII->get(Subtarget->isThumb() ? ARM::tTRAP : ARM::TRAP)); + DispatchBB->addSuccessor(TrapBB); + + MachineBasicBlock *DispContBB = MF->CreateMachineBasicBlock(); + DispatchBB->addSuccessor(DispContBB); + + // Insert and renumber MBBs. + MachineBasicBlock *Last = &MF->back(); + MF->insert(MF->end(), DispatchBB); + MF->insert(MF->end(), DispContBB); + MF->insert(MF->end(), TrapBB); + MF->RenumberBlocks(Last); + + // Insert code into the entry block that creates and registers the function + // context. + SetupEntryBlockForSjLj(MI, MBB, DispatchBB, FI); + + MachineMemOperand *FIMMOLd = + MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), + MachineMemOperand::MOLoad | + MachineMemOperand::MOVolatile, 4, 4); + + if (Subtarget->isThumb2()) { + unsigned NewVReg1 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(DispatchBB, dl, TII->get(ARM::t2LDRi12), NewVReg1) + .addFrameIndex(FI) + .addImm(4) + .addMemOperand(FIMMOLd)); + AddDefaultPred(BuildMI(DispatchBB, dl, TII->get(ARM::t2CMPri)) + .addReg(NewVReg1) + .addImm(LPadList.size())); + BuildMI(DispatchBB, dl, TII->get(ARM::t2Bcc)) + .addMBB(TrapBB) + .addImm(ARMCC::HI) + .addReg(ARM::CPSR); + + unsigned NewVReg2 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(DispContBB, dl, TII->get(ARM::t2LEApcrelJT),NewVReg2) + .addJumpTableIndex(MJTI) + .addImm(UId)); + + unsigned NewVReg3 = MRI->createVirtualRegister(TRC); + AddDefaultCC( + AddDefaultPred( + BuildMI(DispContBB, dl, TII->get(ARM::t2ADDrs), NewVReg3) + .addReg(NewVReg2, RegState::Kill) + .addReg(NewVReg1) + .addImm(ARM_AM::getSORegOpc(ARM_AM::lsl, 2)))); + + BuildMI(DispContBB, dl, TII->get(ARM::t2BR_JT)) + .addReg(NewVReg3, RegState::Kill) + .addReg(NewVReg1) + .addJumpTableIndex(MJTI) + .addImm(UId); + } else if (Subtarget->isThumb()) { + unsigned NewVReg1 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(DispatchBB, dl, TII->get(ARM::tLDRspi), NewVReg1) + .addFrameIndex(FI) + .addImm(1) + .addMemOperand(FIMMOLd)); + + AddDefaultPred(BuildMI(DispatchBB, dl, TII->get(ARM::tCMPi8)) + .addReg(NewVReg1) + .addImm(LPadList.size())); + BuildMI(DispatchBB, dl, TII->get(ARM::tBcc)) + .addMBB(TrapBB) + .addImm(ARMCC::HI) + .addReg(ARM::CPSR); + + unsigned NewVReg2 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(DispContBB, dl, TII->get(ARM::tLSLri), NewVReg2) + .addReg(ARM::CPSR, RegState::Define) + .addReg(NewVReg1) + .addImm(2)); + + unsigned NewVReg3 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(DispContBB, dl, TII->get(ARM::tLEApcrelJT), NewVReg3) + .addJumpTableIndex(MJTI) + .addImm(UId)); + + unsigned NewVReg4 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(DispContBB, dl, TII->get(ARM::tADDrr), NewVReg4) + .addReg(ARM::CPSR, RegState::Define) + .addReg(NewVReg2, RegState::Kill) + .addReg(NewVReg3)); + + MachineMemOperand *JTMMOLd = + MF->getMachineMemOperand(MachinePointerInfo::getJumpTable(), + MachineMemOperand::MOLoad, 4, 4); + + unsigned NewVReg5 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(DispContBB, dl, TII->get(ARM::tLDRi), NewVReg5) + .addReg(NewVReg4, RegState::Kill) + .addImm(0) + .addMemOperand(JTMMOLd)); + + unsigned NewVReg6 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(DispContBB, dl, TII->get(ARM::tADDrr), NewVReg6) + .addReg(ARM::CPSR, RegState::Define) + .addReg(NewVReg5, RegState::Kill) + .addReg(NewVReg3)); + + BuildMI(DispContBB, dl, TII->get(ARM::tBR_JTr)) + .addReg(NewVReg6, RegState::Kill) + .addJumpTableIndex(MJTI) + .addImm(UId); + } else { + unsigned NewVReg1 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(DispatchBB, dl, TII->get(ARM::LDRi12), NewVReg1) + .addFrameIndex(FI) + .addImm(4) + .addMemOperand(FIMMOLd)); + AddDefaultPred(BuildMI(DispatchBB, dl, TII->get(ARM::CMPri)) + .addReg(NewVReg1) + .addImm(LPadList.size())); + BuildMI(DispatchBB, dl, TII->get(ARM::Bcc)) + .addMBB(TrapBB) + .addImm(ARMCC::HI) + .addReg(ARM::CPSR); + + unsigned NewVReg2 = MRI->createVirtualRegister(TRC); + AddDefaultCC( + AddDefaultPred(BuildMI(DispContBB, dl, TII->get(ARM::MOVsi), NewVReg2) + .addReg(NewVReg1) + .addImm(ARM_AM::getSORegOpc(ARM_AM::lsl, 2)))); + unsigned NewVReg3 = MRI->createVirtualRegister(TRC); + AddDefaultPred(BuildMI(DispContBB, dl, TII->get(ARM::LEApcrelJT), NewVReg3) + .addJumpTableIndex(MJTI) + .addImm(UId)); + + MachineMemOperand *JTMMOLd = + MF->getMachineMemOperand(MachinePointerInfo::getJumpTable(), + MachineMemOperand::MOLoad, 4, 4); + unsigned NewVReg4 = MRI->createVirtualRegister(TRC); + AddDefaultPred( + BuildMI(DispContBB, dl, TII->get(ARM::LDRrs), NewVReg4) + .addReg(NewVReg2, RegState::Kill) + .addReg(NewVReg3) + .addImm(0) + .addMemOperand(JTMMOLd)); + + BuildMI(DispContBB, dl, TII->get(ARM::BR_JTadd)) + .addReg(NewVReg4, RegState::Kill) + .addReg(NewVReg3) + .addJumpTableIndex(MJTI) + .addImm(UId); + } + + // Add the jump table entries as successors to the MBB. + MachineBasicBlock *PrevMBB = 0; + for (std::vector::iterator + I = LPadList.begin(), E = LPadList.end(); I != E; ++I) { + MachineBasicBlock *CurMBB = *I; + if (PrevMBB != CurMBB) + DispContBB->addSuccessor(CurMBB); + PrevMBB = CurMBB; + } + + const ARMBaseInstrInfo *AII = static_cast(TII); + const ARMBaseRegisterInfo &RI = AII->getRegisterInfo(); + const unsigned *SavedRegs = RI.getCalleeSavedRegs(MF); + for (SmallPtrSet::iterator + I = InvokeBBs.begin(), E = InvokeBBs.end(); I != E; ++I) { + MachineBasicBlock *BB = *I; + + // Remove the landing pad successor from the invoke block and replace it + // with the new dispatch block. + for (MachineBasicBlock::succ_iterator + SI = BB->succ_begin(), SE = BB->succ_end(); SI != SE; ++SI) { + MachineBasicBlock *SMBB = *SI; + if (SMBB->isLandingPad()) { + BB->removeSuccessor(SMBB); + SMBB->setIsLandingPad(false); + } + } + + BB->addSuccessor(DispatchBB); + + // Find the invoke call and mark all of the callee-saved registers as + // 'implicit defined' so that they're spilled. This prevents code from + // moving instructions to before the EH block, where they will never be + // executed. + for (MachineBasicBlock::reverse_iterator + II = BB->rbegin(), IE = BB->rend(); II != IE; ++II) { + if (!II->getDesc().isCall()) continue; + + DenseMap DefRegs; + for (MachineInstr::mop_iterator + OI = II->operands_begin(), OE = II->operands_end(); + OI != OE; ++OI) { + if (!OI->isReg()) continue; + DefRegs[OI->getReg()] = true; + } + + MachineInstrBuilder MIB(&*II); + + for (unsigned i = 0; SavedRegs[i] != 0; ++i) { + if (!TRC->contains(SavedRegs[i])) continue; + if (!DefRegs[SavedRegs[i]]) + MIB.addReg(SavedRegs[i], RegState::ImplicitDefine | RegState::Dead); + } + + break; + } + } + + // The instruction is gone now. + MI->eraseFromParent(); + + return MBB; +} + static MachineBasicBlock *OtherSucc(MachineBasicBlock *MBB, MachineBasicBlock *Succ) { for (MachineBasicBlock::succ_iterator I = MBB->succ_begin(), @@ -5212,72 +5954,6 @@ MachineBasicBlock *OtherSucc(MachineBasicBlock *MBB, MachineBasicBlock *Succ) { llvm_unreachable("Expecting a BB with two successors!"); } -// FIXME: This opcode table should obviously be expressed in the target -// description. We probably just need a "machine opcode" value in the pseudo -// instruction. But the ideal solution maybe to simply remove the "S" version -// of the opcode altogether. -struct AddSubFlagsOpcodePair { - unsigned PseudoOpc; - unsigned MachineOpc; -}; - -static AddSubFlagsOpcodePair AddSubFlagsOpcodeMap[] = { - {ARM::ADCSri, ARM::ADCri}, - {ARM::ADCSrr, ARM::ADCrr}, - {ARM::ADCSrs, ARM::ADCrs}, - {ARM::SBCSri, ARM::SBCri}, - {ARM::SBCSrr, ARM::SBCrr}, - {ARM::SBCSrs, ARM::SBCrs}, - {ARM::RSBSri, ARM::RSBri}, - {ARM::RSBSrr, ARM::RSBrr}, - {ARM::RSBSrs, ARM::RSBrs}, - {ARM::RSCSri, ARM::RSCri}, - {ARM::RSCSrs, ARM::RSCrs}, - {ARM::t2ADCSri, ARM::t2ADCri}, - {ARM::t2ADCSrr, ARM::t2ADCrr}, - {ARM::t2ADCSrs, ARM::t2ADCrs}, - {ARM::t2SBCSri, ARM::t2SBCri}, - {ARM::t2SBCSrr, ARM::t2SBCrr}, - {ARM::t2SBCSrs, ARM::t2SBCrs}, - {ARM::t2RSBSri, ARM::t2RSBri}, - {ARM::t2RSBSrs, ARM::t2RSBrs}, -}; - -// Convert and Add or Subtract with Carry and Flags to a generic opcode with -// CPSR operand. e.g. ADCS (...) -> ADC (... CPSR). -// -// FIXME: Somewhere we should assert that CPSR is in the correct -// position to be recognized by the target descrition as the 'S' bit. -bool ARMTargetLowering::RemapAddSubWithFlags(MachineInstr *MI, - MachineBasicBlock *BB) const { - unsigned OldOpc = MI->getOpcode(); - unsigned NewOpc = 0; - - // This is only called for instructions that need remapping, so iterating over - // the tiny opcode table is not costly. - static const int NPairs = - sizeof(AddSubFlagsOpcodeMap) / sizeof(AddSubFlagsOpcodePair); - for (AddSubFlagsOpcodePair *Pair = &AddSubFlagsOpcodeMap[0], - *End = &AddSubFlagsOpcodeMap[NPairs]; Pair != End; ++Pair) { - if (OldOpc == Pair->PseudoOpc) { - NewOpc = Pair->MachineOpc; - break; - } - } - if (!NewOpc) - return false; - - const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); - DebugLoc dl = MI->getDebugLoc(); - MachineInstrBuilder MIB = BuildMI(*BB, MI, dl, TII->get(NewOpc)); - for (unsigned i = 0; i < MI->getNumOperands(); ++i) - MIB.addOperand(MI->getOperand(i)); - AddDefaultPred(MIB); - MIB.addReg(ARM::CPSR, RegState::Define); // S bit - MI->eraseFromParent(); - return true; -} - MachineBasicBlock * ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { @@ -5286,12 +5962,61 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, bool isThumb2 = Subtarget->isThumb2(); switch (MI->getOpcode()) { default: { - if (RemapAddSubWithFlags(MI, BB)) - return BB; - MI->dump(); llvm_unreachable("Unexpected instr type to insert"); } + // The Thumb2 pre-indexed stores have the same MI operands, they just + // define them differently in the .td files from the isel patterns, so + // they need pseudos. + case ARM::t2STR_preidx: + MI->setDesc(TII->get(ARM::t2STR_PRE)); + return BB; + case ARM::t2STRB_preidx: + MI->setDesc(TII->get(ARM::t2STRB_PRE)); + return BB; + case ARM::t2STRH_preidx: + MI->setDesc(TII->get(ARM::t2STRH_PRE)); + return BB; + + case ARM::STRi_preidx: + case ARM::STRBi_preidx: { + unsigned NewOpc = MI->getOpcode() == ARM::STRi_preidx ? + ARM::STR_PRE_IMM : ARM::STRB_PRE_IMM; + // Decode the offset. + unsigned Offset = MI->getOperand(4).getImm(); + bool isSub = ARM_AM::getAM2Op(Offset) == ARM_AM::sub; + Offset = ARM_AM::getAM2Offset(Offset); + if (isSub) + Offset = -Offset; + + MachineMemOperand *MMO = *MI->memoperands_begin(); + BuildMI(*BB, MI, dl, TII->get(NewOpc)) + .addOperand(MI->getOperand(0)) // Rn_wb + .addOperand(MI->getOperand(1)) // Rt + .addOperand(MI->getOperand(2)) // Rn + .addImm(Offset) // offset (skip GPR==zero_reg) + .addOperand(MI->getOperand(5)) // pred + .addOperand(MI->getOperand(6)) + .addMemOperand(MMO); + MI->eraseFromParent(); + return BB; + } + case ARM::STRr_preidx: + case ARM::STRBr_preidx: + case ARM::STRH_preidx: { + unsigned NewOpc; + switch (MI->getOpcode()) { + default: llvm_unreachable("unexpected opcode!"); + case ARM::STRr_preidx: NewOpc = ARM::STR_PRE_REG; break; + case ARM::STRBr_preidx: NewOpc = ARM::STRB_PRE_REG; break; + case ARM::STRH_preidx: NewOpc = ARM::STRH_PRE; break; + } + MachineInstrBuilder MIB = BuildMI(*BB, MI, dl, TII->get(NewOpc)); + for (unsigned i = 0; i < MI->getNumOperands(); ++i) + MIB.addOperand(MI->getOperand(i)); + MI->eraseFromParent(); + return BB; + } case ARM::ATOMIC_LOAD_ADD_I8: return EmitAtomicBinary(MI, BB, 1, isThumb2 ? ARM::t2ADDrr : ARM::ADDrr); case ARM::ATOMIC_LOAD_ADD_I16: @@ -5370,6 +6095,31 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, case ARM::ATOMIC_CMP_SWAP_I16: return EmitAtomicCmpSwap(MI, BB, 2); case ARM::ATOMIC_CMP_SWAP_I32: return EmitAtomicCmpSwap(MI, BB, 4); + + case ARM::ATOMADD6432: + return EmitAtomicBinary64(MI, BB, isThumb2 ? ARM::t2ADDrr : ARM::ADDrr, + isThumb2 ? ARM::t2ADCrr : ARM::ADCrr, + /*NeedsCarry*/ true); + case ARM::ATOMSUB6432: + return EmitAtomicBinary64(MI, BB, isThumb2 ? ARM::t2SUBrr : ARM::SUBrr, + isThumb2 ? ARM::t2SBCrr : ARM::SBCrr, + /*NeedsCarry*/ true); + case ARM::ATOMOR6432: + return EmitAtomicBinary64(MI, BB, isThumb2 ? ARM::t2ORRrr : ARM::ORRrr, + isThumb2 ? ARM::t2ORRrr : ARM::ORRrr); + case ARM::ATOMXOR6432: + return EmitAtomicBinary64(MI, BB, isThumb2 ? ARM::t2EORrr : ARM::EORrr, + isThumb2 ? ARM::t2EORrr : ARM::EORrr); + case ARM::ATOMAND6432: + return EmitAtomicBinary64(MI, BB, isThumb2 ? ARM::t2ANDrr : ARM::ANDrr, + isThumb2 ? ARM::t2ANDrr : ARM::ANDrr); + case ARM::ATOMSWAP6432: + return EmitAtomicBinary64(MI, BB, 0, 0, false); + case ARM::ATOMCMPXCHG6432: + return EmitAtomicBinary64(MI, BB, isThumb2 ? ARM::t2SUBrr : ARM::SUBrr, + isThumb2 ? ARM::t2SBCrr : ARM::SBCrr, + /*NeedsCarry*/ false, /*IsCmpxchg*/true); + case ARM::tMOVCCr_pseudo: { // To "insert" a SELECT_CC instruction, we actually have to insert the // diamond control-flow pattern. The incoming instruction knows the @@ -5461,13 +6211,159 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc)) .addMBB(destMBB).addImm(ARMCC::EQ).addReg(ARM::CPSR); - BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2B : ARM::B)) - .addMBB(exitMBB); + if (isThumb2) + AddDefaultPred(BuildMI(BB, dl, TII->get(ARM::t2B)).addMBB(exitMBB)); + else + BuildMI(BB, dl, TII->get(ARM::B)) .addMBB(exitMBB); MI->eraseFromParent(); // The pseudo instruction is gone now. return BB; } + + case ARM::ABS: + case ARM::t2ABS: { + // To insert an ABS instruction, we have to insert the + // diamond control-flow pattern. The incoming instruction knows the + // source vreg to test against 0, the destination vreg to set, + // the condition code register to branch on, the + // true/false values to select between, and a branch opcode to use. + // It transforms + // V1 = ABS V0 + // into + // V2 = MOVS V0 + // BCC (branch to SinkBB if V0 >= 0) + // RSBBB: V3 = RSBri V2, 0 (compute ABS if V2 < 0) + // SinkBB: V1 = PHI(V2, V3) + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + MachineFunction::iterator BBI = BB; + ++BBI; + MachineFunction *Fn = BB->getParent(); + MachineBasicBlock *RSBBB = Fn->CreateMachineBasicBlock(LLVM_BB); + MachineBasicBlock *SinkBB = Fn->CreateMachineBasicBlock(LLVM_BB); + Fn->insert(BBI, RSBBB); + Fn->insert(BBI, SinkBB); + + unsigned int ABSSrcReg = MI->getOperand(1).getReg(); + unsigned int ABSDstReg = MI->getOperand(0).getReg(); + bool isThumb2 = Subtarget->isThumb2(); + MachineRegisterInfo &MRI = Fn->getRegInfo(); + // In Thumb mode S must not be specified if source register is the SP or + // PC and if destination register is the SP, so restrict register class + unsigned NewMovDstReg = MRI.createVirtualRegister( + isThumb2 ? ARM::rGPRRegisterClass : ARM::GPRRegisterClass); + unsigned NewRsbDstReg = MRI.createVirtualRegister( + isThumb2 ? ARM::rGPRRegisterClass : ARM::GPRRegisterClass); + + // Transfer the remainder of BB and its successor edges to sinkMBB. + SinkBB->splice(SinkBB->begin(), BB, + llvm::next(MachineBasicBlock::iterator(MI)), + BB->end()); + SinkBB->transferSuccessorsAndUpdatePHIs(BB); + + BB->addSuccessor(RSBBB); + BB->addSuccessor(SinkBB); + + // fall through to SinkMBB + RSBBB->addSuccessor(SinkBB); + + // insert a movs at the end of BB + BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2MOVr : ARM::MOVr), + NewMovDstReg) + .addReg(ABSSrcReg, RegState::Kill) + .addImm((unsigned)ARMCC::AL).addReg(0) + .addReg(ARM::CPSR, RegState::Define); + + // insert a bcc with opposite CC to ARMCC::MI at the end of BB + BuildMI(BB, dl, + TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc)).addMBB(SinkBB) + .addImm(ARMCC::getOppositeCondition(ARMCC::MI)).addReg(ARM::CPSR); + + // insert rsbri in RSBBB + // Note: BCC and rsbri will be converted into predicated rsbmi + // by if-conversion pass + BuildMI(*RSBBB, RSBBB->begin(), dl, + TII->get(isThumb2 ? ARM::t2RSBri : ARM::RSBri), NewRsbDstReg) + .addReg(NewMovDstReg, RegState::Kill) + .addImm(0).addImm((unsigned)ARMCC::AL).addReg(0).addReg(0); + + // insert PHI in SinkBB, + // reuse ABSDstReg to not change uses of ABS instruction + BuildMI(*SinkBB, SinkBB->begin(), dl, + TII->get(ARM::PHI), ABSDstReg) + .addReg(NewRsbDstReg).addMBB(RSBBB) + .addReg(NewMovDstReg).addMBB(BB); + + // remove ABS instruction + MI->eraseFromParent(); + + // return last added BB + return SinkBB; } + } +} + +void ARMTargetLowering::AdjustInstrPostInstrSelection(MachineInstr *MI, + SDNode *Node) const { + const MCInstrDesc &MCID = MI->getDesc(); + if (!MCID.hasPostISelHook()) { + assert(!convertAddSubFlagsOpcode(MI->getOpcode()) && + "Pseudo flag-setting opcodes must be marked with 'hasPostISelHook'"); + return; + } + + // Adjust potentially 's' setting instructions after isel, i.e. ADC, SBC, RSB, + // RSC. Coming out of isel, they have an implicit CPSR def, but the optional + // operand is still set to noreg. If needed, set the optional operand's + // register to CPSR, and remove the redundant implicit def. + // + // e.g. ADCS (...opt:%noreg, CPSR) -> ADC (... opt:CPSR). + + // Rename pseudo opcodes. + unsigned NewOpc = convertAddSubFlagsOpcode(MI->getOpcode()); + if (NewOpc) { + const ARMBaseInstrInfo *TII = + static_cast(getTargetMachine().getInstrInfo()); + MI->setDesc(TII->get(NewOpc)); + } + unsigned ccOutIdx = MCID.getNumOperands() - 1; + + // Any ARM instruction that sets the 's' bit should specify an optional + // "cc_out" operand in the last operand position. + if (!MCID.hasOptionalDef() || !MCID.OpInfo[ccOutIdx].isOptionalDef()) { + assert(!NewOpc && "Optional cc_out operand required"); + return; + } + // Look for an implicit def of CPSR added by MachineInstr ctor. Remove it + // since we already have an optional CPSR def. + bool definesCPSR = false; + bool deadCPSR = false; + for (unsigned i = MCID.getNumOperands(), e = MI->getNumOperands(); + i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (MO.isReg() && MO.isDef() && MO.getReg() == ARM::CPSR) { + definesCPSR = true; + if (MO.isDead()) + deadCPSR = true; + MI->RemoveOperand(i); + break; + } + } + if (!definesCPSR) { + assert(!NewOpc && "Optional cc_out operand required"); + return; + } + assert(deadCPSR == !Node->hasAnyUseOfValue(1) && "inconsistent dead flag"); + if (deadCPSR) { + assert(!MI->getOperand(ccOutIdx).getReg() && + "expect uninitialized optional cc_out operand"); + return; + } + + // If this instruction was defined with an optional CPSR def and its dag node + // had a live implicit CPSR def, then activate the optional CPSR def. + MachineOperand &MO = MI->getOperand(ccOutIdx); + MO.setReg(ARM::CPSR); + MO.setIsDef(true); } //===----------------------------------------------------------------------===// @@ -6975,7 +7871,8 @@ ARMTargetLowering::PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const { SDValue FalseVal = N->getOperand(0); SDValue TrueVal = N->getOperand(1); SDValue ARMcc = N->getOperand(2); - ARMCC::CondCodes CC = (ARMCC::CondCodes)cast(ARMcc)->getZExtValue(); + ARMCC::CondCodes CC = + (ARMCC::CondCodes)cast(ARMcc)->getZExtValue(); // Simplify // mov r1, r0 @@ -6995,7 +7892,7 @@ ARMTargetLowering::PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const { // movne r0, y /// FIXME: Turn this into a target neutral optimization? SDValue Res; - if (CC == ARMCC::NE && FalseVal == RHS) { + if (CC == ARMCC::NE && FalseVal == RHS && FalseVal != LHS) { Res = DAG.getNode(ARMISD::CMOV, dl, VT, LHS, TrueVal, ARMcc, N->getOperand(3), Cmp); } else if (CC == ARMCC::EQ && TrueVal == RHS) { @@ -7235,7 +8132,7 @@ bool ARMTargetLowering::isLegalT2ScaledAddressingMode(const AddrMode &AM, /// isLegalAddressingMode - Return true if the addressing mode represented /// by AM is legal for this target, for a load/store of the specified type. bool ARMTargetLowering::isLegalAddressingMode(const AddrMode &AM, - const Type *Ty) const { + Type *Ty) const { EVT VT = getValueType(Ty, true); if (!isLegalAddressImmediate(AM.BaseOffs, VT, Subtarget)) return false; @@ -7351,7 +8248,8 @@ static bool getARMIndexedAddressParts(SDNode *Ptr, EVT VT, if (Ptr->getOpcode() == ISD::ADD) { isInc = true; - ARM_AM::ShiftOpc ShOpcVal= ARM_AM::getShiftOpcForNode(Ptr->getOperand(0)); + ARM_AM::ShiftOpc ShOpcVal= + ARM_AM::getShiftOpcForNode(Ptr->getOperand(0).getOpcode()); if (ShOpcVal != ARM_AM::no_shift) { Base = Ptr->getOperand(1); Offset = Ptr->getOperand(0); @@ -7536,7 +8434,7 @@ bool ARMTargetLowering::ExpandInlineAsm(CallInst *CI) const { if (AsmPieces.size() == 3 && AsmPieces[0] == "rev" && AsmPieces[1] == "$0" && AsmPieces[2] == "$1" && IA->getConstraintString().compare(0, 4, "=l,l") == 0) { - const IntegerType *Ty = dyn_cast(CI->getType()); + IntegerType *Ty = dyn_cast(CI->getType()); if (Ty && Ty->getBitWidth() == 32) return IntrinsicLowering::LowerToByteSwap(CI); } @@ -7559,6 +8457,9 @@ ARMTargetLowering::getConstraintType(const std::string &Constraint) const { case 'x': return C_RegisterClass; case 't': return C_RegisterClass; case 'j': return C_Other; // Constant for movw. + // An address with a single base register. Due to the way we + // currently handle addresses it is the same as an 'r' memory constraint. + case 'Q': return C_Memory; } } else if (Constraint.size() == 2) { switch (Constraint[0]) { @@ -7582,7 +8483,7 @@ ARMTargetLowering::getSingleConstraintMatchWeight( // but allow it at the lowest weight. if (CallOperandVal == NULL) return CW_Default; - const Type *type = CallOperandVal->getType(); + Type *type = CallOperandVal->getType(); // Look at the constraint type. switch (*constraint) { default: @@ -7618,7 +8519,7 @@ ARMTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, return RCPair(0U, ARM::GPRRegisterClass); case 'h': // High regs or no regs. if (Subtarget->isThumb()) - return RCPair(0U, ARM::hGPRRegisterClass); + return RCPair(0U, ARM::hGPRRegisterClass); break; case 'r': return RCPair(0U, ARM::GPRRegisterClass); @@ -7632,15 +8533,15 @@ ARMTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, break; case 'x': if (VT == MVT::f32) - return RCPair(0U, ARM::SPR_8RegisterClass); + return RCPair(0U, ARM::SPR_8RegisterClass); if (VT.getSizeInBits() == 64) - return RCPair(0U, ARM::DPR_8RegisterClass); + return RCPair(0U, ARM::DPR_8RegisterClass); if (VT.getSizeInBits() == 128) - return RCPair(0U, ARM::QPR_8RegisterClass); + return RCPair(0U, ARM::QPR_8RegisterClass); break; case 't': if (VT == MVT::f32) - return RCPair(0U, ARM::SPRRegisterClass); + return RCPair(0U, ARM::SPRRegisterClass); break; } } @@ -7680,12 +8581,12 @@ void ARMTargetLowering::LowerAsmOperandForConstraint(SDValue Op, switch (ConstraintLetter) { case 'j': - // Constant suitable for movw, must be between 0 and - // 65535. - if (Subtarget->hasV6T2Ops()) - if (CVal >= 0 && CVal <= 65535) - break; - return; + // Constant suitable for movw, must be between 0 and + // 65535. + if (Subtarget->hasV6T2Ops()) + if (CVal >= 0 && CVal <= 65535) + break; + return; case 'I': if (Subtarget->isThumb1Only()) { // This must be a constant between 0 and 255, for ADD @@ -7823,50 +8724,6 @@ ARMTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { return false; } -int ARM::getVFPf32Imm(const APFloat &FPImm) { - APInt Imm = FPImm.bitcastToAPInt(); - uint32_t Sign = Imm.lshr(31).getZExtValue() & 1; - int32_t Exp = (Imm.lshr(23).getSExtValue() & 0xff) - 127; // -126 to 127 - int64_t Mantissa = Imm.getZExtValue() & 0x7fffff; // 23 bits - - // We can handle 4 bits of mantissa. - // mantissa = (16+UInt(e:f:g:h))/16. - if (Mantissa & 0x7ffff) - return -1; - Mantissa >>= 19; - if ((Mantissa & 0xf) != Mantissa) - return -1; - - // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3 - if (Exp < -3 || Exp > 4) - return -1; - Exp = ((Exp+3) & 0x7) ^ 4; - - return ((int)Sign << 7) | (Exp << 4) | Mantissa; -} - -int ARM::getVFPf64Imm(const APFloat &FPImm) { - APInt Imm = FPImm.bitcastToAPInt(); - uint64_t Sign = Imm.lshr(63).getZExtValue() & 1; - int64_t Exp = (Imm.lshr(52).getSExtValue() & 0x7ff) - 1023; // -1022 to 1023 - uint64_t Mantissa = Imm.getZExtValue() & 0xfffffffffffffLL; - - // We can handle 4 bits of mantissa. - // mantissa = (16+UInt(e:f:g:h))/16. - if (Mantissa & 0xffffffffffffLL) - return -1; - Mantissa >>= 48; - if ((Mantissa & 0xf) != Mantissa) - return -1; - - // We can handle 3 bits of exponent: exp == UInt(NOT(b):c:d)-3 - if (Exp < -3 || Exp > 4) - return -1; - Exp = ((Exp+3) & 0x7) ^ 4; - - return ((int)Sign << 7) | (Exp << 4) | Mantissa; -} - bool ARM::isBitFieldInvertedMask(unsigned v) { if (v == 0xffffffff) return 0; @@ -7889,9 +8746,9 @@ bool ARMTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { if (!Subtarget->hasVFP3()) return false; if (VT == MVT::f32) - return ARM::getVFPf32Imm(Imm) != -1; + return ARM_AM::getFP32Imm(Imm) != -1; if (VT == MVT::f64) - return ARM::getVFPf64Imm(Imm) != -1; + return ARM_AM::getFP64Imm(Imm) != -1; return false; } @@ -7933,7 +8790,7 @@ bool ARMTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info, // Conservatively set memVT to the entire set of vectors stored. unsigned NumElts = 0; for (unsigned ArgI = 1, ArgE = I.getNumArgOperands(); ArgI < ArgE; ++ArgI) { - const Type *ArgTy = I.getArgOperand(ArgI)->getType(); + Type *ArgTy = I.getArgOperand(ArgI)->getType(); if (!ArgTy->isVectorTy()) break; NumElts += getTargetData()->getTypeAllocSize(ArgTy) / 8; diff --git a/lib/Target/ARM/ARMISelLowering.h b/lib/Target/ARM/ARMISelLowering.h index 980fb404887e..5da9b27fca68 100644 --- a/lib/Target/ARM/ARMISelLowering.h +++ b/lib/Target/ARM/ARMISelLowering.h @@ -71,6 +71,11 @@ namespace llvm { SRA_FLAG, // V,Flag = sra_flag X -> sra X, 1 + save carry out. RRX, // V = RRX X, Flag -> srl X, 1 + shift in carry flag. + ADDC, // Add with carry + ADDE, // Add using carry + SUBC, // Sub with carry + SUBE, // Sub using carry + VMOVRRD, // double to two gprs. VMOVDRR, // Two gprs to double. @@ -206,18 +211,22 @@ namespace llvm { VST4_UPD, VST2LN_UPD, VST3LN_UPD, - VST4LN_UPD + VST4LN_UPD, + + // 64-bit atomic ops (value split into two registers) + ATOMADD64_DAG, + ATOMSUB64_DAG, + ATOMOR64_DAG, + ATOMXOR64_DAG, + ATOMAND64_DAG, + ATOMNAND64_DAG, + ATOMSWAP64_DAG, + ATOMCMPXCHG64_DAG }; } /// Define some predicates that are used for node matching. namespace ARM { - /// getVFPf32Imm / getVFPf64Imm - If the given fp immediate can be - /// materialized with a VMOV.f32 / VMOV.f64 (i.e. fconsts / fconstd) - /// instruction, returns its 8-bit integer representation. Otherwise, - /// returns -1. - int getVFPf32Imm(const APFloat &FPImm); - int getVFPf64Imm(const APFloat &FPImm); bool isBitFieldInvertedMask(unsigned v); } @@ -240,10 +249,16 @@ namespace llvm { virtual const char *getTargetNodeName(unsigned Opcode) const; + /// getSetCCResultType - Return the value type to use for ISD::SETCC. + virtual EVT getSetCCResultType(EVT VT) const; + virtual MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const; + virtual void + AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const; + SDValue PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const; virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const; @@ -256,7 +271,7 @@ namespace llvm { /// isLegalAddressingMode - Return true if the addressing mode represented /// by AM is legal for this target, for a load/store of the specified type. - virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty)const; + virtual bool isLegalAddressingMode(const AddrMode &AM, Type *Ty)const; bool isLegalT2ScaledAddressingMode(const AddrMode &AM, EVT VT) const; /// isLegalICmpImmediate - Return true if the specified immediate is legal @@ -485,12 +500,28 @@ namespace llvm { MachineBasicBlock *BB, unsigned Size, unsigned BinOpcode) const; + MachineBasicBlock *EmitAtomicBinary64(MachineInstr *MI, + MachineBasicBlock *BB, + unsigned Op1, + unsigned Op2, + bool NeedsCarry = false, + bool IsCmpxchg = false) const; MachineBasicBlock * EmitAtomicBinaryMinMax(MachineInstr *MI, MachineBasicBlock *BB, unsigned Size, bool signExtend, ARMCC::CondCodes Cond) const; + void EmitBasePointerRecalculation(MachineInstr *MI, MachineBasicBlock *MBB, + MachineBasicBlock *DispatchBB) const; + + void SetupEntryBlockForSjLj(MachineInstr *MI, + MachineBasicBlock *MBB, + MachineBasicBlock *DispatchBB, int FI) const; + + MachineBasicBlock *EmitSjLjDispatchBlock(MachineInstr *MI, + MachineBasicBlock *MBB) const; + bool RemapAddSubWithFlags(MachineInstr *MI, MachineBasicBlock *BB) const; }; diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 3ccf22f80b7d..7cbc9111dec3 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -25,7 +25,7 @@ def BrFrm : Format<2>; def BrMiscFrm : Format<3>; def DPFrm : Format<4>; -def DPSoRegFrm : Format<5>; +def DPSoRegRegFrm : Format<5>; def LdFrm : Format<6>; def StFrm : Format<7>; @@ -68,6 +68,7 @@ def N3RegVShFrm : Format<38>; def NVExtFrm : Format<39>; def NVMulSLFrm : Format<40>; def NVTBLFrm : Format<41>; +def DPSoRegImmFrm : Format<42>; // Misc flags. @@ -130,39 +131,15 @@ def VFPNeonA8Domain : Domain<5>; // Instructions in VFP & Neon under A8 // ARM special operands. // -def CondCodeOperand : AsmOperandClass { - let Name = "CondCode"; - let SuperClasses = []; -} - -def CCOutOperand : AsmOperandClass { - let Name = "CCOut"; - let SuperClasses = []; -} - -def MemBarrierOptOperand : AsmOperandClass { - let Name = "MemBarrierOpt"; - let SuperClasses = []; - let ParserMethod = "tryParseMemBarrierOptOperand"; -} - -def ProcIFlagsOperand : AsmOperandClass { - let Name = "ProcIFlags"; - let SuperClasses = []; - let ParserMethod = "tryParseProcIFlagsOperand"; -} - -def MSRMaskOperand : AsmOperandClass { - let Name = "MSRMask"; - let SuperClasses = []; - let ParserMethod = "tryParseMSRMaskOperand"; -} - // ARM imod and iflag operands, used only by the CPS instruction. def imod_op : Operand { let PrintMethod = "printCPSIMod"; } +def ProcIFlagsOperand : AsmOperandClass { + let Name = "ProcIFlags"; + let ParserMethod = "parseProcIFlagsOperand"; +} def iflags_op : Operand { let PrintMethod = "printCPSIFlag"; let ParserMatchClass = ProcIFlagsOperand; @@ -170,17 +147,21 @@ def iflags_op : Operand { // ARM Predicate operand. Default to 14 = always (AL). Second part is CC // register whose default is 0 (no register). -def pred : PredicateOperand { let PrintMethod = "printPredicateOperand"; let ParserMatchClass = CondCodeOperand; + let DecoderMethod = "DecodePredicateOperand"; } // Conditional code result for instructions whose 's' bit is set, e.g. subs. +def CCOutOperand : AsmOperandClass { let Name = "CCOut"; } def cc_out : OptionalDefOperand { let EncoderMethod = "getCCOutOpValue"; let PrintMethod = "printSBitModifierOperand"; let ParserMatchClass = CCOutOperand; + let DecoderMethod = "DecodeCCOutOperand"; } // Same as cc_out except it defaults to setting CPSR. @@ -188,16 +169,27 @@ def s_cc_out : OptionalDefOperand { let EncoderMethod = "getCCOutOpValue"; let PrintMethod = "printSBitModifierOperand"; let ParserMatchClass = CCOutOperand; + let DecoderMethod = "DecodeCCOutOperand"; } // ARM special operands for disassembly only. // +def SetEndAsmOperand : AsmOperandClass { + let Name = "SetEndImm"; + let ParserMethod = "parseSetEndImm"; +} def setend_op : Operand { let PrintMethod = "printSetendOperand"; + let ParserMatchClass = SetEndAsmOperand; } +def MSRMaskOperand : AsmOperandClass { + let Name = "MSRMask"; + let ParserMethod = "parseMSRMaskOperand"; +} def msr_mask : Operand { let PrintMethod = "printMSRMaskOperand"; + let DecoderMethod = "DecodeMSRMask"; let ParserMatchClass = MSRMaskOperand; } @@ -211,21 +203,40 @@ def msr_mask : Operand { // 64 64 - is encoded in imm6<5:0> def shr_imm8 : Operand { let EncoderMethod = "getShiftRight8Imm"; + let DecoderMethod = "DecodeShiftRight8Imm"; } def shr_imm16 : Operand { let EncoderMethod = "getShiftRight16Imm"; + let DecoderMethod = "DecodeShiftRight16Imm"; } def shr_imm32 : Operand { let EncoderMethod = "getShiftRight32Imm"; + let DecoderMethod = "DecodeShiftRight32Imm"; } def shr_imm64 : Operand { let EncoderMethod = "getShiftRight64Imm"; + let DecoderMethod = "DecodeShiftRight64Imm"; } +//===----------------------------------------------------------------------===// +// ARM Assembler alias templates. +// +class ARMInstAlias + : InstAlias, Requires<[IsARM]>; +class tInstAlias + : InstAlias, Requires<[IsThumb]>; +class t2InstAlias + : InstAlias, Requires<[IsThumb2]>; +class VFP2InstAlias + : InstAlias, Requires<[HasVFP2]>; +class VFP3InstAlias + : InstAlias, Requires<[HasVFP3]>; + //===----------------------------------------------------------------------===// // ARM Instruction templates. // + class InstTemplate : Instruction { @@ -240,17 +251,22 @@ class InstTemplate(f), "Pseudo"); - // The layout of TSFlags should be kept in sync with ARMBaseInstrInfo.h. + // The layout of TSFlags should be kept in sync with ARMBaseInfo.h. let TSFlags{4-0} = AM.Value; let TSFlags{6-5} = IndexModeBits; let TSFlags{12-7} = Form; let TSFlags{13} = isUnaryDataProc; let TSFlags{14} = canXformTo16Bit; let TSFlags{17-15} = D.Value; + let TSFlags{18} = thumbArithFlagSetting; let Constraints = cstr; let Itinerary = itin; @@ -262,13 +278,17 @@ class Encoding { class InstARM - : InstTemplate, Encoding; + : InstTemplate, Encoding { + let DecoderNamespace = "ARM"; +} // This Encoding-less class is used by Thumb1 to specify the encoding bits later // on by adding flavors to specific instructions. class InstThumb - : InstTemplate; + : InstTemplate { + let DecoderNamespace = "Thumb"; +} class PseudoInst pattern> : InstTemplate opcod, dag oops, dag iops, InstrItinClass itin, : I { bits<4> Rt; - bits<4> Rn; + bits<4> addr; let Inst{27-23} = 0b00011; let Inst{22-21} = opcod; let Inst{20} = 1; - let Inst{19-16} = Rn; + let Inst{19-16} = addr; let Inst{15-12} = Rt; let Inst{11-0} = 0b111110011111; } @@ -450,14 +470,14 @@ class AIstrex opcod, dag oops, dag iops, InstrItinClass itin, let Inst{3-0} = Rt; } class AIswp pattern> - : AI { + : AI { bits<4> Rt; bits<4> Rt2; - bits<4> Rn; + bits<4> addr; let Inst{27-23} = 0b00010; let Inst{22} = b; let Inst{21-20} = 0b00; - let Inst{19-16} = Rn; + let Inst{19-16} = addr; let Inst{15-12} = Rt; let Inst{11-4} = 0b00001001; let Inst{3-0} = Rt2; @@ -515,22 +535,41 @@ class AI2ldstidx pattern> : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, pattern> { // AM2 store w/ two operands: (GPR, am2offset) - // {13} 1 == Rm, 0 == imm12 // {12} isAdd // {11-0} imm12/Rm bits<14> offset; bits<4> Rn; - let Inst{25} = offset{13}; + let Inst{25} = 1; + let Inst{23} = offset{12}; + let Inst{19-16} = Rn; + let Inst{11-5} = offset{11-5}; + let Inst{4} = 0; + let Inst{3-0} = offset{3-0}; +} + +class AI2stridx_imm pattern> + : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, + pattern> { + // AM2 store w/ two operands: (GPR, am2offset) + // {12} isAdd + // {11-0} imm12/Rm + bits<14> offset; + bits<4> Rn; + let Inst{25} = 0; let Inst{23} = offset{12}; let Inst{19-16} = Rn; let Inst{11-0} = offset{11-0}; } + + // FIXME: Merge with the above class when addrmode2 gets used for STR, STRB // but for now use this class for STRT and STRBT. class AI2stridxT op, bit op20, dag oops, dag iops, Format f, let Inst{11-8} = addr{7-4}; // imm7_4/zero let Inst{7-4} = op; let Inst{3-0} = addr{3-0}; // imm3_0/Rm + + let DecoderMethod = "DecodeAddrMode3Instruction"; } -class AI3ldstidx op, bit op20, bit isLd, bit isPre, dag oops, dag iops, +class AI3ldstidx op, bit op20, bit isPre, dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin, string opc, string asm, string cstr, list pattern> : I op, bit op20, bit isLd, bit isPre, dag oops, dag iops, // FIXME: Merge with the above class when addrmode2 gets used for LDR, LDRB // but for now use this class for LDRSBT, LDRHT, LDSHT. -class AI3ldstidxT op, bit op20, bit isLd, bit isPre, dag oops, dag iops, +class AI3ldstidxT op, bit isLoad, dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin, string opc, string asm, string cstr, list pattern> - : I { + : I { // {13} 1 == imm8, 0 == Rm // {12-9} Rn // {8} isAdd // {7-4} imm7_4/zero // {3-0} imm3_0/Rm - bits<14> addr; + bits<4> addr; bits<4> Rt; let Inst{27-25} = 0b000; - let Inst{24} = isPre; // P bit - let Inst{23} = addr{8}; // U bit - let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm - let Inst{20} = op20; // L bit - let Inst{19-16} = addr{12-9}; // Rn + let Inst{24} = 0; // P bit + let Inst{21} = 1; + let Inst{20} = isLoad; // L bit + let Inst{19-16} = addr; // Rn let Inst{15-12} = Rt; // Rt - let Inst{11-8} = addr{7-4}; // imm7_4/zero let Inst{7-4} = op; - let Inst{3-0} = addr{3-0}; // imm3_0/Rm - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode3"; -} - -class AI3stridx op, bit isByte, bit isPre, dag oops, dag iops, - IndexMode im, Format f, InstrItinClass itin, string opc, - string asm, string cstr, list pattern> - : AI2ldstidx<0, isByte, isPre, oops, iops, im, f, itin, opc, asm, cstr, - pattern> { - // AM3 store w/ two operands: (GPR, am3offset) - bits<14> offset; - bits<4> Rt; - bits<4> Rn; - let Inst{27-25} = 0b000; - let Inst{23} = offset{8}; - let Inst{22} = offset{9}; - let Inst{19-16} = Rn; - let Inst{15-12} = Rt; // Rt - let Inst{11-8} = offset{7-4}; // imm7_4/zero - let Inst{7-4} = op; - let Inst{3-0} = offset{3-0}; // imm3_0/Rm } // stores @@ -648,75 +665,7 @@ class AI3str op, dag oops, dag iops, Format f, InstrItinClass itin, let Inst{11-8} = addr{7-4}; // imm7_4/zero let Inst{7-4} = op; let Inst{3-0} = addr{3-0}; // imm3_0/Rm -} - -// Pre-indexed stores -class AI3sthpr pattern> - : I { - let Inst{4} = 1; - let Inst{5} = 1; // H bit - let Inst{6} = 0; // S bit - let Inst{7} = 1; - let Inst{20} = 0; // L bit - let Inst{21} = 1; // W bit - let Inst{24} = 1; // P bit - let Inst{27-25} = 0b000; -} -class AI3stdpr pattern> - : I { - let Inst{4} = 1; - let Inst{5} = 1; // H bit - let Inst{6} = 1; // S bit - let Inst{7} = 1; - let Inst{20} = 0; // L bit - let Inst{21} = 1; // W bit - let Inst{24} = 1; // P bit - let Inst{27-25} = 0b000; -} - -// Post-indexed stores -class AI3sthpo pattern> - : I { - // {13} 1 == imm8, 0 == Rm - // {12-9} Rn - // {8} isAdd - // {7-4} imm7_4/zero - // {3-0} imm3_0/Rm - bits<14> addr; - bits<4> Rt; - let Inst{3-0} = addr{3-0}; // imm3_0/Rm - let Inst{4} = 1; - let Inst{5} = 1; // H bit - let Inst{6} = 0; // S bit - let Inst{7} = 1; - let Inst{11-8} = addr{7-4}; // imm7_4/zero - let Inst{15-12} = Rt; // Rt - let Inst{19-16} = addr{12-9}; // Rn - let Inst{20} = 0; // L bit - let Inst{21} = 0; // W bit - let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm - let Inst{23} = addr{8}; // U bit - let Inst{24} = 0; // P bit - let Inst{27-25} = 0b000; -} -class AI3stdpo pattern> - : I { - let Inst{4} = 1; - let Inst{5} = 1; // H bit - let Inst{6} = 1; // S bit - let Inst{7} = 1; - let Inst{20} = 0; // L bit - let Inst{21} = 0; // W bit - let Inst{24} = 0; // P bit - let Inst{27-25} = 0b000; + let DecoderMethod = "DecodeAddrMode3Instruction"; } // addrmode4 instructions @@ -843,6 +792,23 @@ class AMiscA1I opcod, bits<4> opc7_4, dag oops, dag iops, } // PKH instructions +def PKHLSLAsmOperand : AsmOperandClass { + let Name = "PKHLSLImm"; + let ParserMethod = "parsePKHLSLImm"; +} +def pkh_lsl_amt: Operand, ImmLeaf= 0 && Imm < 32; }]>{ + let PrintMethod = "printPKHLSLShiftImm"; + let ParserMatchClass = PKHLSLAsmOperand; +} +def PKHASRAsmOperand : AsmOperandClass { + let Name = "PKHASRImm"; + let ParserMethod = "parsePKHASRImm"; +} +def pkh_asr_amt: Operand, ImmLeaf 0 && Imm <= 32; }]>{ + let PrintMethod = "printPKHASRShiftImm"; + let ParserMatchClass = PKHASRAsmOperand; +} + class APKHI opcod, bit tb, dag oops, dag iops, InstrItinClass itin, string opc, string asm, list pattern> : I opcod, bit tb, dag oops, dag iops, InstrItinClass itin, bits<4> Rd; bits<4> Rn; bits<4> Rm; - bits<8> sh; + bits<5> sh; let Inst{27-20} = opcod; let Inst{19-16} = Rn; let Inst{15-12} = Rd; - let Inst{11-7} = sh{7-3}; + let Inst{11-7} = sh; let Inst{6} = tb; let Inst{5-4} = 0b01; let Inst{3-0} = Rm; @@ -949,7 +915,9 @@ class Thumb1sI Predicates = [IsThumb, IsThumb1Only]; + let DecoderNamespace = "ThumbSBit"; } class T1sI Predicates = [IsThumb2]; + let DecoderNamespace = "Thumb2"; } // Same as Thumb2I except it can optionally modify CPSR. Note it's modeled as an @@ -1091,6 +1060,7 @@ class Thumb2sI Predicates = [IsThumb2]; + let DecoderNamespace = "Thumb2"; } // Special cases @@ -1103,6 +1073,7 @@ class Thumb2XI Predicates = [IsThumb2]; + let DecoderNamespace = "Thumb2"; } class ThumbXI Predicates = [IsThumb, IsThumb1Only]; + let DecoderNamespace = "Thumb"; } class T2I pattern> : Thumb2I; class T2Ii8s4 pattern> - : Thumb2I pattern> + : Thumb2I { bits<4> Rt; bits<4> Rt2; @@ -1149,6 +1121,26 @@ class T2Ii8s4 pattern> + : Thumb2I { + bits<4> Rt; + bits<4> Rt2; + bits<4> addr; + bits<9> imm; + let Inst{31-25} = 0b1110100; + let Inst{24} = P; + let Inst{23} = imm{8}; + let Inst{22} = 1; + let Inst{21} = W; + let Inst{20} = isLoad; + let Inst{19-16} = addr; + let Inst{15-12} = Rt{3-0}; + let Inst{11-8} = Rt2{3-0}; + let Inst{7-0} = imm{7-0}; +} class T2sI pattern> @@ -1172,8 +1164,8 @@ class T2XIt pattern> : Thumb2XI; -// T2Iidxldst - Thumb2 indexed load / store instructions. -class T2Iidxldst opcod, bit load, bit pre, +// T2Ipreldst - Thumb2 pre-indexed load / store instructions. +class T2Ipreldst opcod, bit load, bit pre, dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin, string opc, string asm, string cstr, list pattern> @@ -1183,25 +1175,60 @@ class T2Iidxldst opcod, bit load, bit pre, let AsmString = !strconcat(opc, "${p}", asm); let Pattern = pattern; list Predicates = [IsThumb2]; + let DecoderNamespace = "Thumb2"; + + bits<4> Rt; + bits<13> addr; let Inst{31-27} = 0b11111; let Inst{26-25} = 0b00; let Inst{24} = signed; let Inst{23} = 0; let Inst{22-21} = opcod; let Inst{20} = load; + let Inst{19-16} = addr{12-9}; + let Inst{15-12} = Rt{3-0}; let Inst{11} = 1; // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed let Inst{10} = pre; // The P bit. + let Inst{9} = addr{8}; // Sign bit let Inst{8} = 1; // The W bit. + let Inst{7-0} = addr{7-0}; - bits<9> addr; - let Inst{7-0} = addr{7-0}; - let Inst{9} = addr{8}; // Sign bit + let DecoderMethod = "DecodeT2LdStPre"; +} + +// T2Ipostldst - Thumb2 post-indexed load / store instructions. +class T2Ipostldst opcod, bit load, bit pre, + dag oops, dag iops, + AddrMode am, IndexMode im, InstrItinClass itin, + string opc, string asm, string cstr, list pattern> + : InstARM { + let OutOperandList = oops; + let InOperandList = !con(iops, (ins pred:$p)); + let AsmString = !strconcat(opc, "${p}", asm); + let Pattern = pattern; + list Predicates = [IsThumb2]; + let DecoderNamespace = "Thumb2"; bits<4> Rt; bits<4> Rn; + bits<9> offset; + let Inst{31-27} = 0b11111; + let Inst{26-25} = 0b00; + let Inst{24} = signed; + let Inst{23} = 0; + let Inst{22-21} = opcod; + let Inst{20} = load; + let Inst{19-16} = Rn; let Inst{15-12} = Rt{3-0}; - let Inst{19-16} = Rn{3-0}; + let Inst{11} = 1; + // (P, W) = (1, 1) Pre-indexed or (0, 1) Post-indexed + let Inst{10} = pre; // The P bit. + let Inst{9} = offset{8}; // Sign bit + let Inst{8} = 1; // The W bit. + let Inst{7-0} = offset{7-0}; + + let DecoderMethod = "DecodeT2LdStPre"; } // Tv5Pat - Same as Pat<>, but requires V5T Thumb mode. @@ -1242,6 +1269,7 @@ class VFPI Predicates = [HasVFP2]; } @@ -1257,6 +1285,7 @@ class VFPXI Predicates = [HasVFP2]; } @@ -1574,6 +1603,7 @@ class NeonI Predicates = [HasNEON]; + let DecoderNamespace = "NEON"; } // Same as NeonI except it does not have a "data type" specifier. @@ -1586,6 +1616,7 @@ class NeonXI Predicates = [HasNEON]; + let DecoderNamespace = "NEON"; } class NLdSt op21_20, bits<4> op11_8, bits<4> op7_4, @@ -1600,6 +1631,7 @@ class NLdSt op21_20, bits<4> op11_8, bits<4> op7_4, let Inst{7-4} = op7_4; let PostEncoderMethod = "NEONThumb2LoadStorePostEncoder"; + let DecoderNamespace = "NEONLoadStore"; bits<5> Vd; bits<6> Rn; @@ -1643,6 +1675,7 @@ class NDataI { let Inst{31-25} = 0b1111001; let PostEncoderMethod = "NEONThumb2DataIPostEncoder"; + let DecoderNamespace = "NEONData"; } class NDataXI { let Inst{31-25} = 0b1111001; let PostEncoderMethod = "NEONThumb2DataIPostEncoder"; + let DecoderNamespace = "NEONData"; } // NEON "one register and a modified immediate" format. @@ -1677,6 +1711,7 @@ class N1ModImm op21_19, bits<4> op11_8, bit op7, bit op6, let Inst{24} = SIMM{7}; let Inst{18-16} = SIMM{6-4}; let Inst{3-0} = SIMM{3-0}; + let DecoderMethod = "DecodeNEONModImmInstruction"; } // NEON 2 vector register format. @@ -1874,6 +1909,7 @@ class NVLaneOp opcod1, bits<4> opcod2, bits<2> opcod3, list Predicates = [HasNEON]; let PostEncoderMethod = "NEONThumb2DupPostEncoder"; + let DecoderNamespace = "NEONDup"; bits<5> V; bits<4> R; @@ -1915,7 +1951,6 @@ class NVDupLane op19_16, bit op6, dag oops, dag iops, bits<5> Vd; bits<5> Vm; - bits<4> lane; let Inst{22} = Vd{4}; let Inst{15-12} = Vd{3-0}; diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp index adcbf1806fe3..48da03f63bb9 100644 --- a/lib/Target/ARM/ARMInstrInfo.cpp +++ b/lib/Target/ARM/ARMInstrInfo.cpp @@ -13,8 +13,8 @@ #include "ARMInstrInfo.h" #include "ARM.h" -#include "ARMAddressingModes.h" #include "ARMMachineFunctionInfo.h" +#include "MCTargetDesc/ARMAddressingModes.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -30,14 +30,18 @@ ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI) unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const { switch (Opc) { default: break; - case ARM::LDR_PRE: - case ARM::LDR_POST: + case ARM::LDR_PRE_IMM: + case ARM::LDR_PRE_REG: + case ARM::LDR_POST_IMM: + case ARM::LDR_POST_REG: return ARM::LDRi12; case ARM::LDRH_PRE: case ARM::LDRH_POST: return ARM::LDRH; - case ARM::LDRB_PRE: - case ARM::LDRB_POST: + case ARM::LDRB_PRE_IMM: + case ARM::LDRB_PRE_REG: + case ARM::LDRB_POST_IMM: + case ARM::LDRB_POST_REG: return ARM::LDRBi12; case ARM::LDRSH_PRE: case ARM::LDRSH_POST: @@ -45,14 +49,18 @@ unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const { case ARM::LDRSB_PRE: case ARM::LDRSB_POST: return ARM::LDRSB; - case ARM::STR_PRE: - case ARM::STR_POST: + case ARM::STR_PRE_IMM: + case ARM::STR_PRE_REG: + case ARM::STR_POST_IMM: + case ARM::STR_POST_REG: return ARM::STRi12; case ARM::STRH_PRE: case ARM::STRH_POST: return ARM::STRH; - case ARM::STRB_PRE: - case ARM::STRB_POST: + case ARM::STRB_PRE_IMM: + case ARM::STRB_PRE_REG: + case ARM::STRB_POST_IMM: + case ARM::STRB_POST_REG: return ARM::STRBi12; } diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index a42dd1a54ec7..2cf0f09ffc64 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -70,6 +70,18 @@ def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; +def SDTBinaryArithWithFlags : SDTypeProfile<2, 2, + [SDTCisSameAs<0, 2>, + SDTCisSameAs<0, 3>, + SDTCisInt<0>, SDTCisVT<1, i32>]>; + +// SDTBinaryArithWithFlagsInOut - RES1, CPSR = op LHS, RHS, CPSR +def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3, + [SDTCisSameAs<0, 2>, + SDTCisSameAs<0, 3>, + SDTCisInt<0>, + SDTCisVT<1, i32>, + SDTCisVT<4, i32>]>; // Node definitions. def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>; def ARMWrapperDYN : SDNode<"ARMISD::WrapperDYN", SDTIntUnaryOp>; @@ -120,6 +132,12 @@ def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>; def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>; def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>; +def ARMaddc : SDNode<"ARMISD::ADDC", SDTBinaryArithWithFlags, + [SDNPCommutative]>; +def ARMsubc : SDNode<"ARMISD::SUBC", SDTBinaryArithWithFlags>; +def ARMadde : SDNode<"ARMISD::ADDE", SDTBinaryArithWithFlagsInOut>; +def ARMsube : SDNode<"ARMISD::SUBE", SDTBinaryArithWithFlagsInOut>; + def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>; @@ -187,10 +205,16 @@ def IsThumb : Predicate<"Subtarget->isThumb()">, def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">; def IsThumb2 : Predicate<"Subtarget->isThumb2()">, AssemblerPredicate<"ModeThumb,FeatureThumb2">; +def IsMClass : Predicate<"Subtarget->isMClass()">, + AssemblerPredicate<"FeatureMClass">; +def IsARClass : Predicate<"!Subtarget->isMClass()">, + AssemblerPredicate<"!FeatureMClass">; def IsARM : Predicate<"!Subtarget->isThumb()">, AssemblerPredicate<"!ModeThumb">; def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">; def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">; +def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">, + AssemblerPredicate<"ModeNaCl">; // FIXME: Eventually this will be just "hasV6T2Ops". def UseMovt : Predicate<"Subtarget->useMovt()">; @@ -263,24 +287,11 @@ def imm0_65535 : Operand, ImmLeaf : + PatFrag<(ops node:$LHS, node:$RHS, node:$FLAG), res>; class BinOpFrag : PatFrag<(ops node:$LHS, node:$RHS), res>; class UnOpFrag : PatFrag<(ops node:$Src), res>; -/// adde and sube predicates - True based on whether the carry flag output -/// will be needed or not. -def adde_dead_carry : - PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS), - [{return !N->hasAnyUseOfValue(1);}]>; -def sube_dead_carry : - PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS), - [{return !N->hasAnyUseOfValue(1);}]>; -def adde_live_carry : - PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS), - [{return N->hasAnyUseOfValue(1);}]>; -def sube_live_carry : - PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS), - [{return N->hasAnyUseOfValue(1);}]>; - // An 'and' node with a single use. def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{ return N->hasOneUse(); @@ -315,6 +326,7 @@ def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{ def brtarget : Operand { let EncoderMethod = "getBranchTargetOpValue"; let OperandType = "OPERAND_PCREL"; + let DecoderMethod = "DecodeT2BROperand"; } // FIXME: get rid of this one? @@ -345,39 +357,35 @@ def bl_target : Operand { let OperandType = "OPERAND_PCREL"; } +def blx_target : Operand { + // Encoded the same as branch targets. + let EncoderMethod = "getARMBLXTargetOpValue"; + let OperandType = "OPERAND_PCREL"; +} // A list of registers separated by comma. Used by load/store multiple. -def RegListAsmOperand : AsmOperandClass { - let Name = "RegList"; - let SuperClasses = []; -} - -def DPRRegListAsmOperand : AsmOperandClass { - let Name = "DPRRegList"; - let SuperClasses = []; -} - -def SPRRegListAsmOperand : AsmOperandClass { - let Name = "SPRRegList"; - let SuperClasses = []; -} - +def RegListAsmOperand : AsmOperandClass { let Name = "RegList"; } def reglist : Operand { let EncoderMethod = "getRegisterListOpValue"; let ParserMatchClass = RegListAsmOperand; let PrintMethod = "printRegisterList"; + let DecoderMethod = "DecodeRegListOperand"; } +def DPRRegListAsmOperand : AsmOperandClass { let Name = "DPRRegList"; } def dpr_reglist : Operand { let EncoderMethod = "getRegisterListOpValue"; let ParserMatchClass = DPRRegListAsmOperand; let PrintMethod = "printRegisterList"; + let DecoderMethod = "DecodeDPRRegListOperand"; } +def SPRRegListAsmOperand : AsmOperandClass { let Name = "SPRRegList"; } def spr_reglist : Operand { let EncoderMethod = "getRegisterListOpValue"; let ParserMatchClass = SPRRegListAsmOperand; let PrintMethod = "printRegisterList"; + let DecoderMethod = "DecodeSPRRegListOperand"; } // An operand for the CONSTPOOL_ENTRY pseudo-instruction. @@ -397,56 +405,99 @@ def adrlabel : Operand { def neon_vcvt_imm32 : Operand { let EncoderMethod = "getNEONVcvtImm32OpValue"; + let DecoderMethod = "DecodeVCVTImmOperand"; } // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24. -def rot_imm : Operand, ImmLeaf { - let EncoderMethod = "getRotImmOpValue"; +def rot_imm_XFORM: SDNodeXFormgetZExtValue()){ + default: assert(0); + case 0: return CurDAG->getTargetConstant(0, MVT::i32); + case 8: return CurDAG->getTargetConstant(1, MVT::i32); + case 16: return CurDAG->getTargetConstant(2, MVT::i32); + case 24: return CurDAG->getTargetConstant(3, MVT::i32); + } +}]>; +def RotImmAsmOperand : AsmOperandClass { + let Name = "RotImm"; + let ParserMethod = "parseRotImm"; } - -def ShifterAsmOperand : AsmOperandClass { - let Name = "Shifter"; - let SuperClasses = []; +def rot_imm : Operand, PatLeaf<(i32 imm), [{ + int32_t v = N->getZExtValue(); + return v == 8 || v == 16 || v == 24; }], + rot_imm_XFORM> { + let PrintMethod = "printRotImmOperand"; + let ParserMatchClass = RotImmAsmOperand; } // shift_imm: An integer that encodes a shift amount and the type of shift -// (currently either asr or lsl) using the same encoding used for the -// immediates in so_reg operands. +// (asr or lsl). The 6-bit immediate encodes as: +// {5} 0 ==> lsl +// 1 asr +// {4-0} imm5 shift amount. +// asr #32 encoded as imm5 == 0. +def ShifterImmAsmOperand : AsmOperandClass { + let Name = "ShifterImm"; + let ParserMethod = "parseShifterImm"; +} def shift_imm : Operand { let PrintMethod = "printShiftImmOperand"; - let ParserMatchClass = ShifterAsmOperand; + let ParserMatchClass = ShifterImmAsmOperand; } -def ShiftedRegAsmOperand : AsmOperandClass { - let Name = "ShiftedReg"; -} - -// shifter_operand operands: so_reg and so_imm. -def so_reg : Operand, // reg reg imm - ComplexPattern { - let EncoderMethod = "getSORegOpValue"; - let PrintMethod = "printSORegOperand"; +// shifter_operand operands: so_reg_reg, so_reg_imm, and so_imm. +def ShiftedRegAsmOperand : AsmOperandClass { let Name = "RegShiftedReg"; } +def so_reg_reg : Operand, // reg reg imm + ComplexPattern { + let EncoderMethod = "getSORegRegOpValue"; + let PrintMethod = "printSORegRegOperand"; + let DecoderMethod = "DecodeSORegRegOperand"; let ParserMatchClass = ShiftedRegAsmOperand; - let MIOperandInfo = (ops GPR, GPR, shift_imm); + let MIOperandInfo = (ops GPRnopc, GPRnopc, i32imm); } + +def ShiftedImmAsmOperand : AsmOperandClass { let Name = "RegShiftedImm"; } +def so_reg_imm : Operand, // reg imm + ComplexPattern { + let EncoderMethod = "getSORegImmOpValue"; + let PrintMethod = "printSORegImmOperand"; + let DecoderMethod = "DecodeSORegImmOperand"; + let ParserMatchClass = ShiftedImmAsmOperand; + let MIOperandInfo = (ops GPR, i32imm); +} + // FIXME: Does this need to be distinct from so_reg? -def shift_so_reg : Operand, // reg reg imm - ComplexPattern, // reg reg imm + ComplexPattern { - let EncoderMethod = "getSORegOpValue"; - let PrintMethod = "printSORegOperand"; - let MIOperandInfo = (ops GPR, GPR, shift_imm); + let EncoderMethod = "getSORegRegOpValue"; + let PrintMethod = "printSORegRegOperand"; + let DecoderMethod = "DecodeSORegRegOperand"; + let MIOperandInfo = (ops GPR, GPR, i32imm); } +// FIXME: Does this need to be distinct from so_reg? +def shift_so_reg_imm : Operand, // reg reg imm + ComplexPattern { + let EncoderMethod = "getSORegImmOpValue"; + let PrintMethod = "printSORegImmOperand"; + let DecoderMethod = "DecodeSORegImmOperand"; + let MIOperandInfo = (ops GPR, i32imm); +} + + // so_imm - Match a 32-bit shifter_operand immediate operand, which is an // 8-bit immediate rotated by an arbitrary number of bits. +def SOImmAsmOperand: AsmOperandClass { let Name = "ARMSOImm"; } def so_imm : Operand, ImmLeaf { let EncoderMethod = "getSOImmOpValue"; + let ParserMatchClass = SOImmAsmOperand; + let DecoderMethod = "DecodeSOImmOperand"; } // Break so_imm's up into two pieces. This handles immediates with up to 16 @@ -464,7 +515,7 @@ def arm_i32imm : PatLeaf<(imm), [{ return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue()); }]>; -/// imm0_7 predicate - Immediate in the range [0,31]. +/// imm0_7 predicate - Immediate in the range [0,7]. def Imm0_7AsmOperand: AsmOperandClass { let Name = "Imm0_7"; } def imm0_7 : Operand, ImmLeaf= 0 && Imm < 8; @@ -472,7 +523,7 @@ def imm0_7 : Operand, ImmLeaf, ImmLeaf= 0 && Imm < 16; @@ -481,68 +532,83 @@ def imm0_15 : Operand, ImmLeaf, ImmLeaf= 0 && Imm < 32; -}]>; - -/// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'. -def imm0_31_m1 : Operand, ImmLeaf= 0 && Imm < 32; }]> { - let EncoderMethod = "getImmMinusOneOpValue"; + let ParserMatchClass = Imm0_31AsmOperand; } -// i32imm_hilo16 - For movt/movw - sets the MC Encoder method. -// The imm is split into imm{15-12}, imm{11-0} -// -def i32imm_hilo16 : Operand { - let EncoderMethod = "getHiLo16ImmOpValue"; +/// imm0_255 predicate - Immediate in the range [0,255]. +def Imm0_255AsmOperand : AsmOperandClass { let Name = "Imm0_255"; } +def imm0_255 : Operand, ImmLeaf= 0 && Imm < 256; }]> { + let ParserMatchClass = Imm0_255AsmOperand; } +// imm0_65535_expr - For movt/movw - 16-bit immediate that can also reference +// a relocatable expression. +// +// FIXME: This really needs a Thumb version separate from the ARM version. +// While the range is the same, and can thus use the same match class, +// the encoding is different so it should have a different encoder method. +def Imm0_65535ExprAsmOperand: AsmOperandClass { let Name = "Imm0_65535Expr"; } +def imm0_65535_expr : Operand { + let EncoderMethod = "getHiLo16ImmOpValue"; + let ParserMatchClass = Imm0_65535ExprAsmOperand; +} + +/// imm24b - True if the 32-bit immediate is encodable in 24 bits. +def Imm24bitAsmOperand: AsmOperandClass { let Name = "Imm24bit"; } +def imm24b : Operand, ImmLeaf= 0 && Imm <= 0xffffff; +}]> { + let ParserMatchClass = Imm24bitAsmOperand; +} + + /// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield /// e.g., 0xf000ffff +def BitfieldAsmOperand : AsmOperandClass { + let Name = "Bitfield"; + let ParserMethod = "parseBitfield"; +} def bf_inv_mask_imm : Operand, PatLeaf<(imm), [{ return ARM::isBitFieldInvertedMask(N->getZExtValue()); }] > { let EncoderMethod = "getBitfieldInvertedMaskOpValue"; let PrintMethod = "printBitfieldInvMaskImmOperand"; + let DecoderMethod = "DecodeBitfieldMaskOperand"; + let ParserMatchClass = BitfieldAsmOperand; } -/// lsb_pos_imm - position of the lsb bit, used by BFI4p and t2BFI4p -def lsb_pos_imm : Operand, ImmLeaf(Imm); +def imm1_32_XFORM: SDNodeXFormgetTargetConstant((int)N->getZExtValue() - 1, MVT::i32); }]>; - -/// width_imm - number of bits to be copied, used by BFI4p and t2BFI4p -def width_imm : Operand, ImmLeaf 0 && Imm <= 32; -}] > { - let EncoderMethod = "getMsbOpValue"; +def Imm1_32AsmOperand: AsmOperandClass { let Name = "Imm1_32"; } +def imm1_32 : Operand, PatLeaf<(imm), [{ + uint64_t Imm = N->getZExtValue(); + return Imm > 0 && Imm <= 32; + }], + imm1_32_XFORM> { + let PrintMethod = "printImmPlusOneOperand"; + let ParserMatchClass = Imm1_32AsmOperand; } -def ssat_imm : Operand, ImmLeaf 0 && Imm <= 32; -}]> { - let EncoderMethod = "getSsatBitPosValue"; +def imm1_16_XFORM: SDNodeXFormgetTargetConstant((int)N->getZExtValue() - 1, MVT::i32); +}]>; +def Imm1_16AsmOperand: AsmOperandClass { let Name = "Imm1_16"; } +def imm1_16 : Operand, PatLeaf<(imm), [{ return Imm > 0 && Imm <= 16; }], + imm1_16_XFORM> { + let PrintMethod = "printImmPlusOneOperand"; + let ParserMatchClass = Imm1_16AsmOperand; } // Define ARM specific addressing modes. - -def MemMode2AsmOperand : AsmOperandClass { - let Name = "MemMode2"; - let SuperClasses = []; - let ParserMethod = "tryParseMemMode2Operand"; -} - -def MemMode3AsmOperand : AsmOperandClass { - let Name = "MemMode3"; - let SuperClasses = []; - let ParserMethod = "tryParseMemMode3Operand"; -} - // addrmode_imm12 := reg +/- imm12 // +def MemImm12OffsetAsmOperand : AsmOperandClass { let Name = "MemImm12Offset"; } def addrmode_imm12 : Operand, ComplexPattern { // 12-bit immediate operand. Note that instructions using this encode @@ -551,53 +617,129 @@ def addrmode_imm12 : Operand, let EncoderMethod = "getAddrModeImm12OpValue"; let PrintMethod = "printAddrModeImm12Operand"; + let DecoderMethod = "DecodeAddrModeImm12Operand"; + let ParserMatchClass = MemImm12OffsetAsmOperand; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); } // ldst_so_reg := reg +/- reg shop imm // +def MemRegOffsetAsmOperand : AsmOperandClass { let Name = "MemRegOffset"; } def ldst_so_reg : Operand, ComplexPattern { let EncoderMethod = "getLdStSORegOpValue"; // FIXME: Simplify the printer let PrintMethod = "printAddrMode2Operand"; - let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); + let DecoderMethod = "DecodeSORegMemOperand"; + let ParserMatchClass = MemRegOffsetAsmOperand; + let MIOperandInfo = (ops GPR:$base, GPRnopc:$offsreg, i32imm:$shift); } +// postidx_imm8 := +/- [0,255] +// +// 9 bit value: +// {8} 1 is imm8 is non-negative. 0 otherwise. +// {7-0} [0,255] imm8 value. +def PostIdxImm8AsmOperand : AsmOperandClass { let Name = "PostIdxImm8"; } +def postidx_imm8 : Operand { + let PrintMethod = "printPostIdxImm8Operand"; + let ParserMatchClass = PostIdxImm8AsmOperand; + let MIOperandInfo = (ops i32imm); +} + +// postidx_imm8s4 := +/- [0,1020] +// +// 9 bit value: +// {8} 1 is imm8 is non-negative. 0 otherwise. +// {7-0} [0,255] imm8 value, scaled by 4. +def PostIdxImm8s4AsmOperand : AsmOperandClass { let Name = "PostIdxImm8s4"; } +def postidx_imm8s4 : Operand { + let PrintMethod = "printPostIdxImm8s4Operand"; + let ParserMatchClass = PostIdxImm8s4AsmOperand; + let MIOperandInfo = (ops i32imm); +} + + +// postidx_reg := +/- reg +// +def PostIdxRegAsmOperand : AsmOperandClass { + let Name = "PostIdxReg"; + let ParserMethod = "parsePostIdxReg"; +} +def postidx_reg : Operand { + let EncoderMethod = "getPostIdxRegOpValue"; + let DecoderMethod = "DecodePostIdxReg"; + let PrintMethod = "printPostIdxRegOperand"; + let ParserMatchClass = PostIdxRegAsmOperand; + let MIOperandInfo = (ops GPR, i32imm); +} + + // addrmode2 := reg +/- imm12 // := reg +/- reg shop imm // +// FIXME: addrmode2 should be refactored the rest of the way to always +// use explicit imm vs. reg versions above (addrmode_imm12 and ldst_so_reg). +def AddrMode2AsmOperand : AsmOperandClass { let Name = "AddrMode2"; } def addrmode2 : Operand, ComplexPattern { let EncoderMethod = "getAddrMode2OpValue"; let PrintMethod = "printAddrMode2Operand"; - let ParserMatchClass = MemMode2AsmOperand; + let ParserMatchClass = AddrMode2AsmOperand; let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } -def am2offset : Operand, - ComplexPattern, + ComplexPattern { let EncoderMethod = "getAddrMode2OffsetOpValue"; let PrintMethod = "printAddrMode2OffsetOperand"; + // When using this for assembly, it's always as a post-index offset. + let ParserMatchClass = PostIdxRegShiftedAsmOperand; let MIOperandInfo = (ops GPR, i32imm); } +// FIXME: am2offset_imm should only need the immediate, not the GPR. Having +// the GPR is purely vestigal at this point. +def AM2OffsetImmAsmOperand : AsmOperandClass { let Name = "AM2OffsetImm"; } +def am2offset_imm : Operand, + ComplexPattern { + let EncoderMethod = "getAddrMode2OffsetOpValue"; + let PrintMethod = "printAddrMode2OffsetOperand"; + let ParserMatchClass = AM2OffsetImmAsmOperand; + let MIOperandInfo = (ops GPR, i32imm); +} + + // addrmode3 := reg +/- reg // addrmode3 := reg +/- imm8 // +// FIXME: split into imm vs. reg versions. +def AddrMode3AsmOperand : AsmOperandClass { let Name = "AddrMode3"; } def addrmode3 : Operand, ComplexPattern { let EncoderMethod = "getAddrMode3OpValue"; let PrintMethod = "printAddrMode3Operand"; - let ParserMatchClass = MemMode3AsmOperand; + let ParserMatchClass = AddrMode3AsmOperand; let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); } +// FIXME: split into imm vs. reg versions. +// FIXME: parser method to handle +/- register. +def AM3OffsetAsmOperand : AsmOperandClass { + let Name = "AM3Offset"; + let ParserMethod = "parseAM3Offset"; +} def am3offset : Operand, ComplexPattern { let EncoderMethod = "getAddrMode3OffsetOpValue"; let PrintMethod = "printAddrMode3OffsetOperand"; + let ParserMatchClass = AM3OffsetAsmOperand; let MIOperandInfo = (ops GPR, i32imm); } @@ -608,28 +750,28 @@ def ldstm_mode : OptionalDefOperand { let PrintMethod = "printLdStmModeOperand"; } -def MemMode5AsmOperand : AsmOperandClass { - let Name = "MemMode5"; - let SuperClasses = []; -} - // addrmode5 := reg +/- imm8*4 // +def AddrMode5AsmOperand : AsmOperandClass { let Name = "AddrMode5"; } def addrmode5 : Operand, ComplexPattern { let PrintMethod = "printAddrMode5Operand"; - let MIOperandInfo = (ops GPR:$base, i32imm); - let ParserMatchClass = MemMode5AsmOperand; let EncoderMethod = "getAddrMode5OpValue"; + let DecoderMethod = "DecodeAddrMode5Operand"; + let ParserMatchClass = AddrMode5AsmOperand; + let MIOperandInfo = (ops GPR:$base, i32imm); } // addrmode6 := reg with optional alignment // +def AddrMode6AsmOperand : AsmOperandClass { let Name = "AlignedMemory"; } def addrmode6 : Operand, ComplexPattern{ let PrintMethod = "printAddrMode6Operand"; - let MIOperandInfo = (ops GPR:$addr, i32imm); + let MIOperandInfo = (ops GPR:$addr, i32imm:$align); let EncoderMethod = "getAddrMode6AddressOpValue"; + let DecoderMethod = "DecodeAddrMode6Operand"; + let ParserMatchClass = AddrMode6AsmOperand; } def am6offset : Operand, @@ -638,6 +780,7 @@ def am6offset : Operand, let PrintMethod = "printAddrMode6OffsetOperand"; let MIOperandInfo = (ops GPR); let EncoderMethod = "getAddrMode6OffsetOpValue"; + let DecoderMethod = "DecodeGPRRegisterClass"; } // Special version of addrmode6 to handle alignment encoding for VST1/VLD1 @@ -666,19 +809,15 @@ def addrmodepc : Operand, let MIOperandInfo = (ops GPR, i32imm); } -def MemMode7AsmOperand : AsmOperandClass { - let Name = "MemMode7"; - let SuperClasses = []; -} - -// addrmode7 := reg -// Used by load/store exclusive instructions. Useful to enable right assembly -// parsing and printing. Not used for any codegen matching. +// addr_offset_none := reg // -def addrmode7 : Operand { +def MemNoOffsetAsmOperand : AsmOperandClass { let Name = "MemNoOffset"; } +def addr_offset_none : Operand, + ComplexPattern { let PrintMethod = "printAddrMode7Operand"; - let MIOperandInfo = (ops GPR); - let ParserMatchClass = MemMode7AsmOperand; + let DecoderMethod = "DecodeAddrMode7Operand"; + let ParserMatchClass = MemNoOffsetAsmOperand; + let MIOperandInfo = (ops GPR:$base); } def nohash_imm : Operand { @@ -687,25 +826,30 @@ def nohash_imm : Operand { def CoprocNumAsmOperand : AsmOperandClass { let Name = "CoprocNum"; - let SuperClasses = []; - let ParserMethod = "tryParseCoprocNumOperand"; + let ParserMethod = "parseCoprocNumOperand"; +} +def p_imm : Operand { + let PrintMethod = "printPImmediate"; + let ParserMatchClass = CoprocNumAsmOperand; + let DecoderMethod = "DecodeCoprocessor"; } def CoprocRegAsmOperand : AsmOperandClass { let Name = "CoprocReg"; - let SuperClasses = []; - let ParserMethod = "tryParseCoprocRegOperand"; + let ParserMethod = "parseCoprocRegOperand"; } - -def p_imm : Operand { - let PrintMethod = "printPImmediate"; - let ParserMatchClass = CoprocNumAsmOperand; -} - def c_imm : Operand { let PrintMethod = "printCImmediate"; let ParserMatchClass = CoprocRegAsmOperand; } +def CoprocOptionAsmOperand : AsmOperandClass { + let Name = "CoprocOption"; + let ParserMethod = "parseCoprocOptionOperand"; +} +def coproc_option_imm : Operand { + let PrintMethod = "printCoprocOptionImm"; + let ParserMatchClass = CoprocOptionAsmOperand; +} //===----------------------------------------------------------------------===// @@ -748,16 +892,37 @@ multiclass AsI1_bin_irs opcod, string opc, let Inst{11-4} = 0b00000000; let Inst{3-0} = Rm; } - def rs : AsI1 { + [(set GPR:$Rd, (opnode GPR:$Rn, so_reg_imm:$shift))]> { bits<4> Rd; bits<4> Rn; bits<12> shift; let Inst{25} = 0; let Inst{19-16} = Rn; let Inst{15-12} = Rd; - let Inst{11-0} = shift; + let Inst{11-5} = shift{11-5}; + let Inst{4} = 0; + let Inst{3-0} = shift{3-0}; + } + + def rsr : AsI1 { + bits<4> Rd; + bits<4> Rn; + bits<12> shift; + let Inst{25} = 0; + let Inst{19-16} = Rn; + let Inst{15-12} = Rd; + let Inst{11-8} = shift{11-8}; + let Inst{7} = 0; + let Inst{6-5} = shift{6-5}; + let Inst{4} = 1; + let Inst{3-0} = shift{3-0}; } // Assembly aliases for optional destination operand when it's the same @@ -773,56 +938,172 @@ multiclass AsI1_bin_irs opcod, string opc, cc_out:$s)>, Requires<[IsARM]>; def : InstAlias(!strconcat(baseOpc, "rs")) GPR:$Rdn, GPR:$Rdn, - so_reg:$shift, pred:$p, + (!cast(!strconcat(baseOpc, "rsi")) GPR:$Rdn, GPR:$Rdn, + so_reg_imm:$shift, pred:$p, cc_out:$s)>, Requires<[IsARM]>; + def : InstAlias(!strconcat(baseOpc, "rsr")) GPR:$Rdn, GPR:$Rdn, + so_reg_reg:$shift, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; + } -/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the -/// instruction modifies the CPSR register. -let isCodeGenOnly = 1, Defs = [CPSR] in { -multiclass AI1_bin_s_irs opcod, string opc, +/// AsI1_rbin_irs - Same as AsI1_bin_irs except the order of operands are +/// reversed. The 'rr' form is only defined for the disassembler; for codegen +/// it is equivalent to the AsI1_bin_irs counterpart. +multiclass AsI1_rbin_irs opcod, string opc, InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, - PatFrag opnode, bit Commutable = 0> { - def ri : AI1 { + // The register-immediate version is re-materializable. This is useful + // in particular for taking the address of a local. + let isReMaterializable = 1 in { + def ri : AsI1 { + [(set GPR:$Rd, (opnode so_imm:$imm, GPR:$Rn))]> { bits<4> Rd; bits<4> Rn; bits<12> imm; let Inst{25} = 1; - let Inst{20} = 1; let Inst{19-16} = Rn; let Inst{15-12} = Rd; let Inst{11-0} = imm; } - def rr : AI1 { + [/* pattern left blank */]> { bits<4> Rd; bits<4> Rn; bits<4> Rm; - let isCommutable = Commutable; - let Inst{25} = 0; - let Inst{20} = 1; - let Inst{19-16} = Rn; - let Inst{15-12} = Rd; let Inst{11-4} = 0b00000000; + let Inst{25} = 0; let Inst{3-0} = Rm; + let Inst{15-12} = Rd; + let Inst{19-16} = Rn; } - def rs : AI1 { + [(set GPR:$Rd, (opnode so_reg_imm:$shift, GPR:$Rn))]> { bits<4> Rd; bits<4> Rn; bits<12> shift; let Inst{25} = 0; - let Inst{20} = 1; let Inst{19-16} = Rn; let Inst{15-12} = Rd; - let Inst{11-0} = shift; + let Inst{11-5} = shift{11-5}; + let Inst{4} = 0; + let Inst{3-0} = shift{3-0}; } + + def rsr : AsI1 { + bits<4> Rd; + bits<4> Rn; + bits<12> shift; + let Inst{25} = 0; + let Inst{19-16} = Rn; + let Inst{15-12} = Rd; + let Inst{11-8} = shift{11-8}; + let Inst{7} = 0; + let Inst{6-5} = shift{6-5}; + let Inst{4} = 1; + let Inst{3-0} = shift{3-0}; + } + + // Assembly aliases for optional destination operand when it's the same + // as the source operand. + def : InstAlias(!strconcat(baseOpc, "ri")) GPR:$Rdn, GPR:$Rdn, + so_imm:$imm, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; + def : InstAlias(!strconcat(baseOpc, "rr")) GPR:$Rdn, GPR:$Rdn, + GPR:$Rm, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; + def : InstAlias(!strconcat(baseOpc, "rsi")) GPR:$Rdn, GPR:$Rdn, + so_reg_imm:$shift, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; + def : InstAlias(!strconcat(baseOpc, "rsr")) GPR:$Rdn, GPR:$Rdn, + so_reg_reg:$shift, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; + +} + +/// AsI1_rbin_s_is - Same as AsI1_rbin_s_is except it sets 's' bit by default. +/// +/// These opcodes will be converted to the real non-S opcodes by +/// AdjustInstrPostInstrSelection after giving then an optional CPSR operand. +let hasPostISelHook = 1, isCodeGenOnly = 1, isPseudo = 1, Defs = [CPSR] in { +multiclass AsI1_rbin_s_is opcod, string opc, + InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, + PatFrag opnode, bit Commutable = 0> { + def ri : AsI1; + + def rr : AsI1; + + def rsi : AsI1; + + def rsr : AsI1 { + bits<4> Rd; + bits<4> Rn; + bits<12> shift; + let Inst{25} = 0; + let Inst{19-16} = Rn; + let Inst{15-12} = Rd; + let Inst{11-8} = shift{11-8}; + let Inst{7} = 0; + let Inst{6-5} = shift{6-5}; + let Inst{4} = 1; + let Inst{3-0} = shift{3-0}; + } +} +} + +/// AsI1_bin_s_irs - Same as AsI1_bin_irs except it sets the 's' bit by default. +/// +/// These opcodes will be converted to the real non-S opcodes by +/// AdjustInstrPostInstrSelection after giving then an optional CPSR operand. +let hasPostISelHook = 1, isCodeGenOnly = 1, isPseudo = 1, Defs = [CPSR] in { +multiclass AsI1_bin_s_irs opcod, string opc, + InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, + PatFrag opnode, bit Commutable = 0> { + def ri : AsI1; + def rr : AsI1; + def rsi : AsI1; + + def rsr : AsI1; } } @@ -857,128 +1138,102 @@ multiclass AI1_cmp_irs opcod, string opc, let Inst{11-4} = 0b00000000; let Inst{3-0} = Rm; } - def rs : AI1 { + [(opnode GPR:$Rn, so_reg_imm:$shift)]> { bits<4> Rn; bits<12> shift; let Inst{25} = 0; let Inst{20} = 1; let Inst{19-16} = Rn; let Inst{15-12} = 0b0000; - let Inst{11-0} = shift; + let Inst{11-5} = shift{11-5}; + let Inst{4} = 0; + let Inst{3-0} = shift{3-0}; } + def rsr : AI1 { + bits<4> Rn; + bits<12> shift; + let Inst{25} = 0; + let Inst{20} = 1; + let Inst{19-16} = Rn; + let Inst{15-12} = 0b0000; + let Inst{11-8} = shift{11-8}; + let Inst{7} = 0; + let Inst{6-5} = shift{6-5}; + let Inst{4} = 1; + let Inst{3-0} = shift{3-0}; + } + } } /// AI_ext_rrot - A unary operation with two forms: one whose operand is a /// register and one whose operand is a register rotated by 8/16/24. /// FIXME: Remove the 'r' variant. Its rot_imm is zero. -multiclass AI_ext_rrot opcod, string opc, PatFrag opnode> { - def r : AExtI, - Requires<[IsARM, HasV6]> { - bits<4> Rd; - bits<4> Rm; - let Inst{19-16} = 0b1111; - let Inst{15-12} = Rd; - let Inst{11-10} = 0b00; - let Inst{3-0} = Rm; - } - def r_rot : AExtI, - Requires<[IsARM, HasV6]> { - bits<4> Rd; - bits<4> Rm; - bits<2> rot; - let Inst{19-16} = 0b1111; - let Inst{15-12} = Rd; - let Inst{11-10} = rot; - let Inst{3-0} = Rm; - } +class AI_ext_rrot opcod, string opc, PatFrag opnode> + : AExtI, + Requires<[IsARM, HasV6]> { + bits<4> Rd; + bits<4> Rm; + bits<2> rot; + let Inst{19-16} = 0b1111; + let Inst{15-12} = Rd; + let Inst{11-10} = rot; + let Inst{3-0} = Rm; } -multiclass AI_ext_rrot_np opcod, string opc> { - def r : AExtI, - Requires<[IsARM, HasV6]> { - let Inst{19-16} = 0b1111; - let Inst{11-10} = 0b00; - } - def r_rot : AExtI, - Requires<[IsARM, HasV6]> { - bits<2> rot; - let Inst{19-16} = 0b1111; - let Inst{11-10} = rot; - } +class AI_ext_rrot_np opcod, string opc> + : AExtI, + Requires<[IsARM, HasV6]> { + bits<2> rot; + let Inst{19-16} = 0b1111; + let Inst{11-10} = rot; } /// AI_exta_rrot - A binary operation with two forms: one whose operand is a /// register and one whose operand is a register rotated by 8/16/24. -multiclass AI_exta_rrot opcod, string opc, PatFrag opnode> { - def rr : AExtI, - Requires<[IsARM, HasV6]> { - bits<4> Rd; - bits<4> Rm; - bits<4> Rn; - let Inst{19-16} = Rn; - let Inst{15-12} = Rd; - let Inst{11-10} = 0b00; - let Inst{9-4} = 0b000111; - let Inst{3-0} = Rm; - } - def rr_rot : AExtI, - Requires<[IsARM, HasV6]> { - bits<4> Rd; - bits<4> Rm; - bits<4> Rn; - bits<2> rot; - let Inst{19-16} = Rn; - let Inst{15-12} = Rd; - let Inst{11-10} = rot; - let Inst{9-4} = 0b000111; - let Inst{3-0} = Rm; - } +class AI_exta_rrot opcod, string opc, PatFrag opnode> + : AExtI, + Requires<[IsARM, HasV6]> { + bits<4> Rd; + bits<4> Rm; + bits<4> Rn; + bits<2> rot; + let Inst{19-16} = Rn; + let Inst{15-12} = Rd; + let Inst{11-10} = rot; + let Inst{9-4} = 0b000111; + let Inst{3-0} = Rm; } -// For disassembly only. -multiclass AI_exta_rrot_np opcod, string opc> { - def rr : AExtI, - Requires<[IsARM, HasV6]> { - let Inst{11-10} = 0b00; - } - def rr_rot : AExtI, - Requires<[IsARM, HasV6]> { - bits<4> Rn; - bits<2> rot; - let Inst{19-16} = Rn; - let Inst{11-10} = rot; - } +class AI_exta_rrot_np opcod, string opc> + : AExtI, + Requires<[IsARM, HasV6]> { + bits<4> Rn; + bits<2> rot; + let Inst{19-16} = Rn; + let Inst{11-10} = rot; } /// AI1_adde_sube_irs - Define instructions and patterns for adde and sube. multiclass AI1_adde_sube_irs opcod, string opc, PatFrag opnode, string baseOpc, bit Commutable = 0> { - let Uses = [CPSR] in { + let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in { def ri : AsI1, + [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, so_imm:$imm, CPSR))]>, Requires<[IsARM]> { bits<4> Rd; bits<4> Rn; @@ -990,7 +1245,7 @@ multiclass AI1_adde_sube_irs opcod, string opc, PatFrag opnode, } def rr : AsI1, + [(set GPR:$Rd, CPSR, (opnode GPR:$Rn, GPR:$Rm, CPSR))]>, Requires<[IsARM]> { bits<4> Rd; bits<4> Rn; @@ -1002,19 +1257,40 @@ multiclass AI1_adde_sube_irs opcod, string opc, PatFrag opnode, let Inst{15-12} = Rd; let Inst{19-16} = Rn; } - def rs : AsI1, + def rsi : AsI1, Requires<[IsARM]> { bits<4> Rd; bits<4> Rn; bits<12> shift; let Inst{25} = 0; - let Inst{11-0} = shift; - let Inst{15-12} = Rd; let Inst{19-16} = Rn; + let Inst{15-12} = Rd; + let Inst{11-5} = shift{11-5}; + let Inst{4} = 0; + let Inst{3-0} = shift{3-0}; + } + def rsr : AsI1, + Requires<[IsARM]> { + bits<4> Rd; + bits<4> Rn; + bits<12> shift; + let Inst{25} = 0; + let Inst{19-16} = Rn; + let Inst{15-12} = Rd; + let Inst{11-8} = shift{11-8}; + let Inst{7} = 0; + let Inst{6-5} = shift{6-5}; + let Inst{4} = 1; + let Inst{3-0} = shift{3-0}; } } + // Assembly aliases for optional destination operand when it's the same // as the source operand. def : InstAlias opcod, string opc, PatFrag opnode, cc_out:$s)>, Requires<[IsARM]>; def : InstAlias(!strconcat(baseOpc, "rs")) GPR:$Rdn, GPR:$Rdn, - so_reg:$shift, pred:$p, + (!cast(!strconcat(baseOpc, "rsi")) GPR:$Rdn, GPR:$Rdn, + so_reg_imm:$shift, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; + def : InstAlias(!strconcat(baseOpc, "rsr")) GPR:$Rdn, GPR:$Rdn, + so_reg_reg:$shift, pred:$p, cc_out:$s)>, Requires<[IsARM]>; } -// Carry setting variants -// NOTE: CPSR def omitted because it will be handled by the custom inserter. -let usesCustomInserter = 1 in { -multiclass AI1_adde_sube_s_irs { - def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), - 4, IIC_iALUi, - [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>; - def rr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), - 4, IIC_iALUr, - [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> { - let isCommutable = Commutable; +/// AI1_rsc_irs - Define instructions and patterns for rsc +multiclass AI1_rsc_irs opcod, string opc, PatFrag opnode, + string baseOpc> { + let hasPostISelHook = 1, Defs = [CPSR], Uses = [CPSR] in { + def ri : AsI1, + Requires<[IsARM]> { + bits<4> Rd; + bits<4> Rn; + bits<12> imm; + let Inst{25} = 1; + let Inst{15-12} = Rd; + let Inst{19-16} = Rn; + let Inst{11-0} = imm; } - def rs : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), - 4, IIC_iALUsr, - [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>; -} + def rr : AsI1 { + bits<4> Rd; + bits<4> Rn; + bits<4> Rm; + let Inst{11-4} = 0b00000000; + let Inst{25} = 0; + let Inst{3-0} = Rm; + let Inst{15-12} = Rd; + let Inst{19-16} = Rn; + } + def rsi : AsI1, + Requires<[IsARM]> { + bits<4> Rd; + bits<4> Rn; + bits<12> shift; + let Inst{25} = 0; + let Inst{19-16} = Rn; + let Inst{15-12} = Rd; + let Inst{11-5} = shift{11-5}; + let Inst{4} = 0; + let Inst{3-0} = shift{3-0}; + } + def rsr : AsI1, + Requires<[IsARM]> { + bits<4> Rd; + bits<4> Rn; + bits<12> shift; + let Inst{25} = 0; + let Inst{19-16} = Rn; + let Inst{15-12} = Rd; + let Inst{11-8} = shift{11-8}; + let Inst{7} = 0; + let Inst{6-5} = shift{6-5}; + let Inst{4} = 1; + let Inst{3-0} = shift{3-0}; + } + } + + // Assembly aliases for optional destination operand when it's the same + // as the source operand. + def : InstAlias(!strconcat(baseOpc, "ri")) GPR:$Rdn, GPR:$Rdn, + so_imm:$imm, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; + def : InstAlias(!strconcat(baseOpc, "rr")) GPR:$Rdn, GPR:$Rdn, + GPR:$Rm, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; + def : InstAlias(!strconcat(baseOpc, "rsi")) GPR:$Rdn, GPR:$Rdn, + so_reg_imm:$shift, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; + def : InstAlias(!strconcat(baseOpc, "rsr")) GPR:$Rdn, GPR:$Rdn, + so_reg_reg:$shift, pred:$p, + cc_out:$s)>, + Requires<[IsARM]>; } let canFoldAsLoad = 1, isReMaterializable = 1 in { @@ -1082,6 +1429,37 @@ multiclass AI_ldr1 { + // Note: We use the complex addrmode_imm12 rather than just an input + // GPR and a constrained immediate so that we can use this to match + // frame index references and avoid matching constant pool references. + def i12: AI2ldst<0b010, 1, isByte, (outs GPRnopc:$Rt), (ins addrmode_imm12:$addr), + AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr", + [(set GPRnopc:$Rt, (opnode addrmode_imm12:$addr))]> { + bits<4> Rt; + bits<17> addr; + let Inst{23} = addr{12}; // U (add = ('U' == 1)) + let Inst{19-16} = addr{16-13}; // Rn + let Inst{15-12} = Rt; + let Inst{11-0} = addr{11-0}; // imm12 + } + def rs : AI2ldst<0b011, 1, isByte, (outs GPRnopc:$Rt), (ins ldst_so_reg:$shift), + AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift", + [(set GPRnopc:$Rt, (opnode ldst_so_reg:$shift))]> { + bits<4> Rt; + bits<17> shift; + let shift{4} = 0; // Inst{4} = 0 + let Inst{23} = shift{12}; // U (add = ('U' == 1)) + let Inst{19-16} = shift{16-13}; // Rn + let Inst{15-12} = Rt; + let Inst{11-0} = shift{11-0}; + } +} +} + + multiclass AI_str1 { // Note: We use the complex addrmode_imm12 rather than just an input @@ -1110,6 +1488,37 @@ multiclass AI_str1 { + // Note: We use the complex addrmode_imm12 rather than just an input + // GPR and a constrained immediate so that we can use this to match + // frame index references and avoid matching constant pool references. + def i12 : AI2ldst<0b010, 0, isByte, (outs), + (ins GPRnopc:$Rt, addrmode_imm12:$addr), + AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr", + [(opnode GPRnopc:$Rt, addrmode_imm12:$addr)]> { + bits<4> Rt; + bits<17> addr; + let Inst{23} = addr{12}; // U (add = ('U' == 1)) + let Inst{19-16} = addr{16-13}; // Rn + let Inst{15-12} = Rt; + let Inst{11-0} = addr{11-0}; // imm12 + } + def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPRnopc:$Rt, ldst_so_reg:$shift), + AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift", + [(opnode GPRnopc:$Rt, ldst_so_reg:$shift)]> { + bits<4> Rt; + bits<17> shift; + let shift{4} = 0; // Inst{4} = 0 + let Inst{23} = shift{12}; // U (add = ('U' == 1)) + let Inst{19-16} = shift{16-13}; // Rn + let Inst{15-12} = Rt; + let Inst{11-0} = shift{11-0}; + } +} + + //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -1140,42 +1549,66 @@ 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 */]>, +// Atomic pseudo-insts which will be lowered to ldrexd/strexd loops. +// (These psuedos use a hand-written selection code). +let usesCustomInserter = 1, Defs = [CPSR], mayLoad = 1, mayStore = 1 in { +def ATOMOR6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), + (ins GPR:$addr, GPR:$src1, GPR:$src2), + NoItinerary, []>; +def ATOMXOR6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), + (ins GPR:$addr, GPR:$src1, GPR:$src2), + NoItinerary, []>; +def ATOMADD6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), + (ins GPR:$addr, GPR:$src1, GPR:$src2), + NoItinerary, []>; +def ATOMSUB6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), + (ins GPR:$addr, GPR:$src1, GPR:$src2), + NoItinerary, []>; +def ATOMNAND6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), + (ins GPR:$addr, GPR:$src1, GPR:$src2), + NoItinerary, []>; +def ATOMAND6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), + (ins GPR:$addr, GPR:$src1, GPR:$src2), + NoItinerary, []>; +def ATOMSWAP6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), + (ins GPR:$addr, GPR:$src1, GPR:$src2), + NoItinerary, []>; +def ATOMCMPXCHG6432 : PseudoInst<(outs GPR:$dst1, GPR:$dst2), + (ins GPR:$addr, GPR:$cmp1, GPR:$cmp2, + GPR:$set1, GPR:$set2), + NoItinerary, []>; +} + +def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "", []>, Requires<[IsARM, HasV6T2]> { let Inst{27-16} = 0b001100100000; let Inst{15-8} = 0b11110000; let Inst{7-0} = 0b00000000; } -def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "", - [/* For disassembly only; pattern left blank */]>, +def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "", []>, Requires<[IsARM, HasV6T2]> { let Inst{27-16} = 0b001100100000; let Inst{15-8} = 0b11110000; let Inst{7-0} = 0b00000001; } -def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "", - [/* For disassembly only; pattern left blank */]>, +def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "", []>, Requires<[IsARM, HasV6T2]> { let Inst{27-16} = 0b001100100000; let Inst{15-8} = 0b11110000; let Inst{7-0} = 0b00000010; } -def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "", - [/* For disassembly only; pattern left blank */]>, +def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "", []>, Requires<[IsARM, HasV6T2]> { let Inst{27-16} = 0b001100100000; let Inst{15-8} = 0b11110000; let Inst{7-0} = 0b00000011; } -def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel", - "\t$dst, $a, $b", - [/* For disassembly only; pattern left blank */]>, - Requires<[IsARM, HasV6]> { +def SEL : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, NoItinerary, "sel", + "\t$Rd, $Rn, $Rm", []>, Requires<[IsARM, HasV6]> { bits<4> Rd; bits<4> Rn; bits<4> Rm; @@ -1188,8 +1621,7 @@ def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel", } def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "", - [/* For disassembly only; pattern left blank */]>, - Requires<[IsARM, HasV6T2]> { + []>, Requires<[IsARM, HasV6T2]> { let Inst{27-16} = 0b001100100000; let Inst{15-8} = 0b11110000; let Inst{7-0} = 0b00000100; @@ -1206,14 +1638,11 @@ def BKPT : AI<(outs), (ins imm0_65535:$val), MiscFrm, NoItinerary, let Inst{7-4} = 0b0111; } -// Change Processor State is a system instruction -- for disassembly and -// parsing only. -// FIXME: Since the asm parser has currently no clean way to handle optional -// operands, create 3 versions of the same instruction. Once there's a clean -// framework to represent optional operands, change this behavior. +// Change Processor State +// FIXME: We should use InstAlias to handle the optional operands. class CPS : AXI<(outs), iops, MiscFrm, NoItinerary, !strconcat("cps", asm_ops), - [/* For disassembly only; pattern left blank */]>, Requires<[IsARM]> { + []>, Requires<[IsARM]> { bits<2> imod; bits<3> iflags; bits<5> mode; @@ -1229,17 +1658,18 @@ class CPS let Inst{4-0} = mode; } +let DecoderMethod = "DecodeCPSInstruction" in { let M = 1 in - def CPS3p : CPS<(ins imod_op:$imod, iflags_op:$iflags, i32imm:$mode), + def CPS3p : CPS<(ins imod_op:$imod, iflags_op:$iflags, imm0_31:$mode), "$imod\t$iflags, $mode">; let mode = 0, M = 0 in def CPS2p : CPS<(ins imod_op:$imod, iflags_op:$iflags), "$imod\t$iflags">; let imod = 0, iflags = 0, M = 1 in - def CPS1p : CPS<(ins i32imm:$mode), "\t$mode">; + def CPS1p : CPS<(ins imm0_31:$mode), "\t$mode">; +} // Preload signals the memory system of possible future data/instruction access. -// These are for disassembly only. multiclass APreLoad read, bits<1> data, string opc> { def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload, @@ -1271,6 +1701,7 @@ multiclass APreLoad read, bits<1> data, string opc> { let Inst{19-16} = shift{16-13}; // Rn let Inst{15-12} = 0b1111; let Inst{11-0} = shift{11-0}; + let Inst{4} = 0; } } @@ -1278,10 +1709,8 @@ defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>; defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>; defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>; -def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary, - "setend\t$end", - [/* For disassembly only; pattern left blank */]>, - Requires<[IsARM]> { +def SETEND : AXI<(outs), (ins setend_op:$end), MiscFrm, NoItinerary, + "setend\t$end", []>, Requires<[IsARM]> { bits<1> end; let Inst{31-10} = 0b1111000100000001000000; let Inst{9} = end; @@ -1351,14 +1780,17 @@ let neverHasSideEffects = 1, isReMaterializable = 1 in // the instruction. The {24-21} opcode bits are set by the fixup, as we don't // know until then which form of the instruction will be used. def ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label), - MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> { + MiscFrm, IIC_iALUi, "adr", "\t$Rd, $label", []> { bits<4> Rd; - bits<12> label; + bits<14> label; let Inst{27-25} = 0b001; + let Inst{24} = 0; + let Inst{23-22} = label{13-12}; + let Inst{21} = 0; let Inst{20} = 0; let Inst{19-16} = 0b1111; let Inst{15-12} = Rd; - let Inst{11-0} = label; + let Inst{11-0} = label{11-0}; } def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p), 4, IIC_iALUi, []>; @@ -1424,6 +1856,7 @@ let isCall = 1, let Inst{31-28} = 0b1110; bits<24> func; let Inst{23-0} = func; + let DecoderMethod = "DecodeBranchImmInstruction"; } def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func, variable_ops), @@ -1432,6 +1865,7 @@ let isCall = 1, Requires<[IsARM, IsNotDarwin]> { bits<24> func; let Inst{23-0} = func; + let DecoderMethod = "DecodeBranchImmInstruction"; } // ARMv5T and above @@ -1516,6 +1950,7 @@ let isBranch = 1, isTerminator = 1 in { [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> { bits<24> target; let Inst{23-0} = target; + let DecoderMethod = "DecodeBranchImmInstruction"; } let isBarrier = 1 in { @@ -1549,9 +1984,9 @@ let isBranch = 1, isTerminator = 1 in { } -// BLX (immediate) -- for disassembly only -def BLXi : AXI<(outs), (ins br_target:$target), BrMiscFrm, NoItinerary, - "blx\t$target", [/* pattern left blank */]>, +// BLX (immediate) +def BLXi : AXI<(outs), (ins blx_target:$target), BrMiscFrm, NoItinerary, + "blx\t$target", []>, Requires<[IsARM, HasV5T]> { let Inst{31-25} = 0b1111101; bits<25> target; @@ -1614,64 +2049,100 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { } } - - - - -// Secure Monitor Call is a system instruction -- for disassembly only -def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt", - [/* For disassembly only; pattern left blank */]> { +// Secure Monitor Call is a system instruction. +def SMC : ABI<0b0001, (outs), (ins imm0_15:$opt), NoItinerary, "smc", "\t$opt", + []> { bits<4> opt; let Inst{23-4} = 0b01100000000000000111; let Inst{3-0} = opt; } -// Supervisor Call (Software Interrupt) -- for disassembly only +// Supervisor Call (Software Interrupt) let isCall = 1, Uses = [SP] in { -def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc", - [/* For disassembly only; pattern left blank */]> { +def SVC : ABI<0b1111, (outs), (ins imm24b:$svc), IIC_Br, "svc", "\t$svc", []> { bits<24> svc; let Inst{23-0} = svc; } } -// Store Return State is a system instruction -- for disassembly only -let isCodeGenOnly = 1 in { // FIXME: This should not use submode! -def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode), - NoItinerary, "srs${amode}\tsp!, $mode", - [/* For disassembly only; pattern left blank */]> { +// Store Return State +class SRSI + : XI<(outs), (ins imm0_31:$mode), AddrModeNone, 4, IndexModeNone, BrFrm, + NoItinerary, asm, "", []> { + bits<5> mode; let Inst{31-28} = 0b1111; - let Inst{22-20} = 0b110; // W = 1 - let Inst{19-8} = 0xd05; - let Inst{7-5} = 0b000; + let Inst{27-25} = 0b100; + let Inst{22} = 1; + let Inst{21} = wb; + let Inst{20} = 0; + let Inst{19-16} = 0b1101; // SP + let Inst{15-5} = 0b00000101000; + let Inst{4-0} = mode; } -def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode), - NoItinerary, "srs${amode}\tsp, $mode", - [/* For disassembly only; pattern left blank */]> { - let Inst{31-28} = 0b1111; - let Inst{22-20} = 0b100; // W = 0 - let Inst{19-8} = 0xd05; - let Inst{7-5} = 0b000; +def SRSDA : SRSI<0, "srsda\tsp, $mode"> { + let Inst{24-23} = 0; +} +def SRSDA_UPD : SRSI<1, "srsda\tsp!, $mode"> { + let Inst{24-23} = 0; +} +def SRSDB : SRSI<0, "srsdb\tsp, $mode"> { + let Inst{24-23} = 0b10; +} +def SRSDB_UPD : SRSI<1, "srsdb\tsp!, $mode"> { + let Inst{24-23} = 0b10; +} +def SRSIA : SRSI<0, "srsia\tsp, $mode"> { + let Inst{24-23} = 0b01; +} +def SRSIA_UPD : SRSI<1, "srsia\tsp!, $mode"> { + let Inst{24-23} = 0b01; +} +def SRSIB : SRSI<0, "srsib\tsp, $mode"> { + let Inst{24-23} = 0b11; +} +def SRSIB_UPD : SRSI<1, "srsib\tsp!, $mode"> { + let Inst{24-23} = 0b11; } -// Return From Exception is a system instruction -- for disassembly only -def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base), - NoItinerary, "rfe${amode}\t$base!", - [/* For disassembly only; pattern left blank */]> { +// Return From Exception +class RFEI + : XI<(outs), (ins GPR:$Rn), AddrModeNone, 4, IndexModeNone, BrFrm, + NoItinerary, asm, "", []> { + bits<4> Rn; let Inst{31-28} = 0b1111; - let Inst{22-20} = 0b011; // W = 1 - let Inst{15-0} = 0x0a00; + let Inst{27-25} = 0b100; + let Inst{22} = 0; + let Inst{21} = wb; + let Inst{20} = 1; + let Inst{19-16} = Rn; + let Inst{15-0} = 0xa00; } -def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base), - NoItinerary, "rfe${amode}\t$base", - [/* For disassembly only; pattern left blank */]> { - let Inst{31-28} = 0b1111; - let Inst{22-20} = 0b001; // W = 0 - let Inst{15-0} = 0x0a00; +def RFEDA : RFEI<0, "rfeda\t$Rn"> { + let Inst{24-23} = 0; +} +def RFEDA_UPD : RFEI<1, "rfeda\t$Rn!"> { + let Inst{24-23} = 0; +} +def RFEDB : RFEI<0, "rfedb\t$Rn"> { + let Inst{24-23} = 0b10; +} +def RFEDB_UPD : RFEI<1, "rfedb\t$Rn!"> { + let Inst{24-23} = 0b10; +} +def RFEIA : RFEI<0, "rfeia\t$Rn"> { + let Inst{24-23} = 0b01; +} +def RFEIA_UPD : RFEI<1, "rfeia\t$Rn!"> { + let Inst{24-23} = 0b01; +} +def RFEIB : RFEI<0, "rfeib\t$Rn"> { + let Inst{24-23} = 0b11; +} +def RFEIB_UPD : RFEI<1, "rfeib\t$Rn!"> { + let Inst{24-23} = 0b11; } -} // isCodeGenOnly = 1 //===----------------------------------------------------------------------===// // Load / store Instructions. @@ -1682,16 +2153,16 @@ def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base), defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si, UnOpFrag<(load node:$Src)>>; -defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si, +defm LDRB : AI_ldr1nopc<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si, UnOpFrag<(zextloadi8 node:$Src)>>; defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si, BinOpFrag<(store node:$LHS, node:$RHS)>>; -defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si, +defm STRB : AI_str1nopc<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si, BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>; // Special LDR for loads from non-pc-relative constpools. let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1, - isReMaterializable = 1 in + isReMaterializable = 1, isCodeGenOnly = 1 in def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr), AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr", []> { @@ -1727,34 +2198,65 @@ def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2), // Indexed loads multiclass AI2_ldridx { - def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb), - (ins addrmode2:$addr), IndexModePre, LdFrm, itin, + def _PRE_IMM : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb), + (ins addrmode_imm12:$addr), IndexModePre, LdFrm, itin, opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { - // {17-14} Rn - // {13} 1 == Rm, 0 == imm12 - // {12} isAdd - // {11-0} imm12/Rm - bits<18> addr; - let Inst{25} = addr{13}; + bits<17> addr; + let Inst{25} = 0; let Inst{23} = addr{12}; - let Inst{19-16} = addr{17-14}; + let Inst{19-16} = addr{16-13}; let Inst{11-0} = addr{11-0}; - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; + let DecoderMethod = "DecodeLDRPreImm"; + let AsmMatchConverter = "cvtLdWriteBackRegAddrModeImm12"; } - def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), - (ins GPR:$Rn, am2offset:$offset), + + def _PRE_REG : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb), + (ins ldst_so_reg:$addr), IndexModePre, LdFrm, itin, + opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { + bits<17> addr; + let Inst{25} = 1; + let Inst{23} = addr{12}; + let Inst{19-16} = addr{16-13}; + let Inst{11-0} = addr{11-0}; + let Inst{4} = 0; + let DecoderMethod = "DecodeLDRPreReg"; + let AsmMatchConverter = "cvtLdWriteBackRegAddrMode2"; + } + + def _POST_REG : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), + (ins addr_offset_none:$addr, am2offset_reg:$offset), + IndexModePost, LdFrm, itin, + opc, "\t$Rt, $addr, $offset", + "$addr.base = $Rn_wb", []> { + // {12} isAdd + // {11-0} imm12/Rm + bits<14> offset; + bits<4> addr; + let Inst{25} = 1; + let Inst{23} = offset{12}; + let Inst{19-16} = addr; + let Inst{11-0} = offset{11-0}; + + let DecoderMethod = "DecodeAddrMode2IdxInstruction"; + } + + def _POST_IMM : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), + (ins addr_offset_none:$addr, am2offset_imm:$offset), IndexModePost, LdFrm, itin, - opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> { - // {13} 1 == Rm, 0 == imm12 + opc, "\t$Rt, $addr, $offset", + "$addr.base = $Rn_wb", []> { // {12} isAdd // {11-0} imm12/Rm bits<14> offset; - bits<4> Rn; - let Inst{25} = offset{13}; + bits<4> addr; + let Inst{25} = 0; let Inst{23} = offset{12}; - let Inst{19-16} = Rn; + let Inst{19-16} = addr; let Inst{11-0} = offset{11-0}; + + let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } + } let mayLoad = 1, neverHasSideEffects = 1 in { @@ -1762,8 +2264,8 @@ defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>; defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>; } -multiclass AI3_ldridx op, bit op20, string opc, InstrItinClass itin> { - def _PRE : AI3ldstidx op, string opc, InstrItinClass itin> { + def _PRE : AI3ldstidx { @@ -1773,27 +2275,31 @@ multiclass AI3_ldridx op, bit op20, string opc, InstrItinClass itin> { let Inst{19-16} = addr{12-9}; // Rn let Inst{11-8} = addr{7-4}; // imm7_4/zero let Inst{3-0} = addr{3-0}; // imm3_0/Rm + let AsmMatchConverter = "cvtLdWriteBackRegAddrMode3"; + let DecoderMethod = "DecodeAddrMode3Instruction"; } - def _POST : AI3ldstidx { + def _POST : AI3ldstidx { bits<10> offset; - bits<4> Rn; + bits<4> addr; let Inst{23} = offset{8}; // U bit let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm - let Inst{19-16} = Rn; + let Inst{19-16} = addr; let Inst{11-8} = offset{7-4}; // imm7_4/zero let Inst{3-0} = offset{3-0}; // imm3_0/Rm + let DecoderMethod = "DecodeAddrMode3Instruction"; } } let mayLoad = 1, neverHasSideEffects = 1 in { -defm LDRH : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>; -defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>; -defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>; +defm LDRH : AI3_ldridx<0b1011, "ldrh", IIC_iLoad_bh_ru>; +defm LDRSH : AI3_ldridx<0b1111, "ldrsh", IIC_iLoad_bh_ru>; +defm LDRSB : AI3_ldridx<0b1101, "ldrsb", IIC_iLoad_bh_ru>; let hasExtraDefRegAllocReq = 1 in { -def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), +def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), (ins addrmode3:$addr), IndexModePre, LdMiscFrm, IIC_iLoad_d_ru, "ldrd", "\t$Rt, $Rt2, $addr!", @@ -1804,70 +2310,128 @@ def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), let Inst{19-16} = addr{12-9}; // Rn let Inst{11-8} = addr{7-4}; // imm7_4/zero let Inst{3-0} = addr{3-0}; // imm3_0/Rm + let DecoderMethod = "DecodeAddrMode3Instruction"; + let AsmMatchConverter = "cvtLdrdPre"; } -def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), - (ins GPR:$Rn, am3offset:$offset), IndexModePost, - LdMiscFrm, IIC_iLoad_d_ru, - "ldrd", "\t$Rt, $Rt2, [$Rn], $offset", - "$Rn = $Rn_wb", []> { +def LDRD_POST: AI3ldstidx<0b1101, 0, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), + (ins addr_offset_none:$addr, am3offset:$offset), + IndexModePost, LdMiscFrm, IIC_iLoad_d_ru, + "ldrd", "\t$Rt, $Rt2, $addr, $offset", + "$addr.base = $Rn_wb", []> { bits<10> offset; - bits<4> Rn; + bits<4> addr; let Inst{23} = offset{8}; // U bit let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm - let Inst{19-16} = Rn; + let Inst{19-16} = addr; let Inst{11-8} = offset{7-4}; // imm7_4/zero let Inst{3-0} = offset{3-0}; // imm3_0/Rm + let DecoderMethod = "DecodeAddrMode3Instruction"; } } // hasExtraDefRegAllocReq = 1 } // mayLoad = 1, neverHasSideEffects = 1 -// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. +// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT. let mayLoad = 1, neverHasSideEffects = 1 in { -def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb), - (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru, - "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { - // {17-14} Rn - // {13} 1 == Rm, 0 == imm12 +def LDRT_POST_REG : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb), + (ins addr_offset_none:$addr, am2offset_reg:$offset), + IndexModePost, LdFrm, IIC_iLoad_ru, + "ldrt", "\t$Rt, $addr, $offset", + "$addr.base = $Rn_wb", []> { // {12} isAdd // {11-0} imm12/Rm - bits<18> addr; - let Inst{25} = addr{13}; - let Inst{23} = addr{12}; + bits<14> offset; + bits<4> addr; + let Inst{25} = 1; + let Inst{23} = offset{12}; let Inst{21} = 1; // overwrite - let Inst{19-16} = addr{17-14}; - let Inst{11-0} = addr{11-0}; - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; + let Inst{19-16} = addr; + let Inst{11-5} = offset{11-5}; + let Inst{4} = 0; + let Inst{3-0} = offset{3-0}; + let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } -def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), - (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru, - "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { - // {17-14} Rn - // {13} 1 == Rm, 0 == imm12 + +def LDRT_POST_IMM : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$Rn_wb), + (ins addr_offset_none:$addr, am2offset_imm:$offset), + IndexModePost, LdFrm, IIC_iLoad_ru, + "ldrt", "\t$Rt, $addr, $offset", + "$addr.base = $Rn_wb", []> { // {12} isAdd // {11-0} imm12/Rm - bits<18> addr; - let Inst{25} = addr{13}; - let Inst{23} = addr{12}; + bits<14> offset; + bits<4> addr; + let Inst{25} = 0; + let Inst{23} = offset{12}; let Inst{21} = 1; // overwrite - let Inst{19-16} = addr{17-14}; - let Inst{11-0} = addr{11-0}; - let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; + let Inst{19-16} = addr; + let Inst{11-0} = offset{11-0}; + let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } -def LDRSBT : AI3ldstidxT<0b1101, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), - (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, - "ldrsbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { + +def LDRBT_POST_REG : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), + (ins addr_offset_none:$addr, am2offset_reg:$offset), + IndexModePost, LdFrm, IIC_iLoad_bh_ru, + "ldrbt", "\t$Rt, $addr, $offset", + "$addr.base = $Rn_wb", []> { + // {12} isAdd + // {11-0} imm12/Rm + bits<14> offset; + bits<4> addr; + let Inst{25} = 1; + let Inst{23} = offset{12}; let Inst{21} = 1; // overwrite + let Inst{19-16} = addr; + let Inst{11-5} = offset{11-5}; + let Inst{4} = 0; + let Inst{3-0} = offset{3-0}; + let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } -def LDRHT : AI3ldstidxT<0b1011, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), - (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, - "ldrht", "\t$Rt, $addr", "$addr.base = $base_wb", []> { + +def LDRBT_POST_IMM : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), + (ins addr_offset_none:$addr, am2offset_imm:$offset), + IndexModePost, LdFrm, IIC_iLoad_bh_ru, + "ldrbt", "\t$Rt, $addr, $offset", + "$addr.base = $Rn_wb", []> { + // {12} isAdd + // {11-0} imm12/Rm + bits<14> offset; + bits<4> addr; + let Inst{25} = 0; + let Inst{23} = offset{12}; let Inst{21} = 1; // overwrite + let Inst{19-16} = addr; + let Inst{11-0} = offset{11-0}; + let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } -def LDRSHT : AI3ldstidxT<0b1111, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), - (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, - "ldrsht", "\t$Rt, $addr", "$addr.base = $base_wb", []> { - let Inst{21} = 1; // overwrite + +multiclass AI3ldrT op, string opc> { + def i : AI3ldstidxT { + bits<9> offset; + let Inst{23} = offset{8}; + let Inst{22} = 1; + let Inst{11-8} = offset{7-4}; + let Inst{3-0} = offset{3-0}; + let AsmMatchConverter = "cvtLdExtTWriteBackImm"; + } + def r : AI3ldstidxT { + bits<5> Rm; + let Inst{23} = Rm{4}; + let Inst{22} = 0; + let Inst{11-8} = 0; + let Inst{3-0} = Rm{3-0}; + let AsmMatchConverter = "cvtLdExtTWriteBackReg"; + } } + +defm LDRSBT : AI3ldrT<0b1101, "ldrsbt">; +defm LDRHT : AI3ldrT<0b1011, "ldrht">; +defm LDRSHT : AI3ldrT<0b1111, "ldrsht">; } // Store @@ -1881,98 +2445,302 @@ def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm, let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$src2, addrmode3:$addr), StMiscFrm, IIC_iStore_d_r, - "strd", "\t$Rt, $src2, $addr", []>, Requires<[IsARM, HasV5TE]>; + "strd", "\t$Rt, $src2, $addr", []>, + Requires<[IsARM, HasV5TE]> { + let Inst{21} = 0; +} // Indexed stores -def STR_PRE : AI2stridx<0, 1, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), - IndexModePre, StFrm, IIC_iStore_ru, - "str", "\t$Rt, [$Rn, $offset]!", - "$Rn = $Rn_wb,@earlyclobber $Rn_wb", - [(set GPR:$Rn_wb, - (pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>; +multiclass AI2_stridx { + def _PRE_IMM : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addrmode_imm12:$addr), IndexModePre, + StFrm, itin, + opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { + bits<17> addr; + let Inst{25} = 0; + let Inst{23} = addr{12}; // U (add = ('U' == 1)) + let Inst{19-16} = addr{16-13}; // Rn + let Inst{11-0} = addr{11-0}; // imm12 + let AsmMatchConverter = "cvtStWriteBackRegAddrModeImm12"; + let DecoderMethod = "DecodeSTRPreImm"; + } -def STR_POST : AI2stridx<0, 0, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), - IndexModePost, StFrm, IIC_iStore_ru, - "str", "\t$Rt, [$Rn], $offset", - "$Rn = $Rn_wb,@earlyclobber $Rn_wb", - [(set GPR:$Rn_wb, - (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>; + def _PRE_REG : AI2ldstidx<0, isByte, 1, (outs GPR:$Rn_wb), + (ins GPR:$Rt, ldst_so_reg:$addr), + IndexModePre, StFrm, itin, + opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { + bits<17> addr; + let Inst{25} = 1; + let Inst{23} = addr{12}; // U (add = ('U' == 1)) + let Inst{19-16} = addr{16-13}; // Rn + let Inst{11-0} = addr{11-0}; + let Inst{4} = 0; // Inst{4} = 0 + let AsmMatchConverter = "cvtStWriteBackRegAddrMode2"; + let DecoderMethod = "DecodeSTRPreReg"; + } + def _POST_REG : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), + IndexModePost, StFrm, itin, + opc, "\t$Rt, $addr, $offset", + "$addr.base = $Rn_wb", []> { + // {12} isAdd + // {11-0} imm12/Rm + bits<14> offset; + bits<4> addr; + let Inst{25} = 1; + let Inst{23} = offset{12}; + let Inst{19-16} = addr; + let Inst{11-0} = offset{11-0}; -def STRB_PRE : AI2stridx<1, 1, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), - IndexModePre, StFrm, IIC_iStore_bh_ru, - "strb", "\t$Rt, [$Rn, $offset]!", - "$Rn = $Rn_wb,@earlyclobber $Rn_wb", - [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt, - GPR:$Rn, am2offset:$offset))]>; -def STRB_POST: AI2stridx<1, 0, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), - IndexModePost, StFrm, IIC_iStore_bh_ru, - "strb", "\t$Rt, [$Rn], $offset", - "$Rn = $Rn_wb,@earlyclobber $Rn_wb", - [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt, - GPR:$Rn, am2offset:$offset))]>; + let DecoderMethod = "DecodeAddrMode2IdxInstruction"; + } -def STRH_PRE : AI3stridx<0b1011, 0, 1, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn, am3offset:$offset), - IndexModePre, StMiscFrm, IIC_iStore_ru, - "strh", "\t$Rt, [$Rn, $offset]!", - "$Rn = $Rn_wb,@earlyclobber $Rn_wb", - [(set GPR:$Rn_wb, - (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>; + def _POST_IMM : AI2ldstidx<0, isByte, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), + IndexModePost, StFrm, itin, + opc, "\t$Rt, $addr, $offset", + "$addr.base = $Rn_wb", []> { + // {12} isAdd + // {11-0} imm12/Rm + bits<14> offset; + bits<4> addr; + let Inst{25} = 0; + let Inst{23} = offset{12}; + let Inst{19-16} = addr; + let Inst{11-0} = offset{11-0}; -def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb), - (ins GPR:$Rt, GPR:$Rn, am3offset:$offset), - IndexModePost, StMiscFrm, IIC_iStore_bh_ru, - "strh", "\t$Rt, [$Rn], $offset", - "$Rn = $Rn_wb,@earlyclobber $Rn_wb", - [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt, - GPR:$Rn, am3offset:$offset))]>; + let DecoderMethod = "DecodeAddrMode2IdxInstruction"; + } +} + +let mayStore = 1, neverHasSideEffects = 1 in { +defm STR : AI2_stridx<0, "str", IIC_iStore_ru>; +defm STRB : AI2_stridx<1, "strb", IIC_iStore_bh_ru>; +} + +def : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr, + am2offset_reg:$offset), + (STR_POST_REG GPR:$Rt, addr_offset_none:$addr, + am2offset_reg:$offset)>; +def : ARMPat<(post_store GPR:$Rt, addr_offset_none:$addr, + am2offset_imm:$offset), + (STR_POST_IMM GPR:$Rt, addr_offset_none:$addr, + am2offset_imm:$offset)>; +def : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr, + am2offset_reg:$offset), + (STRB_POST_REG GPR:$Rt, addr_offset_none:$addr, + am2offset_reg:$offset)>; +def : ARMPat<(post_truncsti8 GPR:$Rt, addr_offset_none:$addr, + am2offset_imm:$offset), + (STRB_POST_IMM GPR:$Rt, addr_offset_none:$addr, + am2offset_imm:$offset)>; + +// Pseudo-instructions for pattern matching the pre-indexed stores. We can't +// put the patterns on the instruction definitions directly as ISel wants +// the address base and offset to be separate operands, not a single +// complex operand like we represent the instructions themselves. The +// pseudos map between the two. +let usesCustomInserter = 1, + Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in { +def STRi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), + (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p), + 4, IIC_iStore_ru, + [(set GPR:$Rn_wb, + (pre_store GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>; +def STRr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), + (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p), + 4, IIC_iStore_ru, + [(set GPR:$Rn_wb, + (pre_store GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>; +def STRBi_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), + (ins GPR:$Rt, GPR:$Rn, am2offset_imm:$offset, pred:$p), + 4, IIC_iStore_ru, + [(set GPR:$Rn_wb, + (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_imm:$offset))]>; +def STRBr_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), + (ins GPR:$Rt, GPR:$Rn, am2offset_reg:$offset, pred:$p), + 4, IIC_iStore_ru, + [(set GPR:$Rn_wb, + (pre_truncsti8 GPR:$Rt, GPR:$Rn, am2offset_reg:$offset))]>; +def STRH_preidx: ARMPseudoInst<(outs GPR:$Rn_wb), + (ins GPR:$Rt, GPR:$Rn, am3offset:$offset, pred:$p), + 4, IIC_iStore_ru, + [(set GPR:$Rn_wb, + (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>; +} + + + +def STRH_PRE : AI3ldstidx<0b1011, 0, 1, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addrmode3:$addr), IndexModePre, + StMiscFrm, IIC_iStore_bh_ru, + "strh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { + bits<14> addr; + let Inst{23} = addr{8}; // U bit + let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm + let Inst{19-16} = addr{12-9}; // Rn + let Inst{11-8} = addr{7-4}; // imm7_4/zero + let Inst{3-0} = addr{3-0}; // imm3_0/Rm + let AsmMatchConverter = "cvtStWriteBackRegAddrMode3"; + let DecoderMethod = "DecodeAddrMode3Instruction"; +} + +def STRH_POST : AI3ldstidx<0b1011, 0, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addr_offset_none:$addr, am3offset:$offset), + IndexModePost, StMiscFrm, IIC_iStore_bh_ru, + "strh", "\t$Rt, $addr, $offset", "$addr.base = $Rn_wb", + [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt, + addr_offset_none:$addr, + am3offset:$offset))]> { + bits<10> offset; + bits<4> addr; + let Inst{23} = offset{8}; // U bit + let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm + let Inst{19-16} = addr; + let Inst{11-8} = offset{7-4}; // imm7_4/zero + let Inst{3-0} = offset{3-0}; // imm3_0/Rm + let DecoderMethod = "DecodeAddrMode3Instruction"; +} -// For disassembly only let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in { -def STRD_PRE : AI3stdpr<(outs GPR:$base_wb), - (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset), - StMiscFrm, IIC_iStore_d_ru, - "strd", "\t$src1, $src2, [$base, $offset]!", - "$base = $base_wb", []>; +def STRD_PRE : AI3ldstidx<0b1111, 0, 1, (outs GPR:$Rn_wb), + (ins GPR:$Rt, GPR:$Rt2, addrmode3:$addr), + IndexModePre, StMiscFrm, IIC_iStore_d_ru, + "strd", "\t$Rt, $Rt2, $addr!", + "$addr.base = $Rn_wb", []> { + bits<14> addr; + let Inst{23} = addr{8}; // U bit + let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm + let Inst{19-16} = addr{12-9}; // Rn + let Inst{11-8} = addr{7-4}; // imm7_4/zero + let Inst{3-0} = addr{3-0}; // imm3_0/Rm + let DecoderMethod = "DecodeAddrMode3Instruction"; + let AsmMatchConverter = "cvtStrdPre"; +} -// For disassembly only -def STRD_POST: AI3stdpo<(outs GPR:$base_wb), - (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset), - StMiscFrm, IIC_iStore_d_ru, - "strd", "\t$src1, $src2, [$base], $offset", - "$base = $base_wb", []>; +def STRD_POST: AI3ldstidx<0b1111, 0, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr, + am3offset:$offset), + IndexModePost, StMiscFrm, IIC_iStore_d_ru, + "strd", "\t$Rt, $Rt2, $addr, $offset", + "$addr.base = $Rn_wb", []> { + bits<10> offset; + bits<4> addr; + let Inst{23} = offset{8}; // U bit + let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm + let Inst{19-16} = addr; + let Inst{11-8} = offset{7-4}; // imm7_4/zero + let Inst{3-0} = offset{3-0}; // imm3_0/Rm + let DecoderMethod = "DecodeAddrMode3Instruction"; +} } // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 -// STRT, STRBT, and STRHT are for disassembly only. +// STRT, STRBT, and STRHT -def STRT : AI2stridxT<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), - IndexModePost, StFrm, IIC_iStore_ru, - "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb", - [/* For disassembly only; pattern left blank */]> { +def STRBT_POST_REG : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), + IndexModePost, StFrm, IIC_iStore_bh_ru, + "strbt", "\t$Rt, $addr, $offset", + "$addr.base = $Rn_wb", []> { + // {12} isAdd + // {11-0} imm12/Rm + bits<14> offset; + bits<4> addr; + let Inst{25} = 1; + let Inst{23} = offset{12}; let Inst{21} = 1; // overwrite - let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; + let Inst{19-16} = addr; + let Inst{11-5} = offset{11-5}; + let Inst{4} = 0; + let Inst{3-0} = offset{3-0}; + let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } -def STRBT : AI2stridxT<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), - IndexModePost, StFrm, IIC_iStore_bh_ru, - "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb", - [/* For disassembly only; pattern left blank */]> { +def STRBT_POST_IMM : AI2ldstidx<0, 1, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), + IndexModePost, StFrm, IIC_iStore_bh_ru, + "strbt", "\t$Rt, $addr, $offset", + "$addr.base = $Rn_wb", []> { + // {12} isAdd + // {11-0} imm12/Rm + bits<14> offset; + bits<4> addr; + let Inst{25} = 0; + let Inst{23} = offset{12}; let Inst{21} = 1; // overwrite - let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; + let Inst{19-16} = addr; + let Inst{11-0} = offset{11-0}; + let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } -def STRHT: AI3sthpo<(outs GPR:$base_wb), (ins GPR:$Rt, addrmode3:$addr), - StMiscFrm, IIC_iStore_bh_ru, - "strht", "\t$Rt, $addr", "$addr.base = $base_wb", - [/* For disassembly only; pattern left blank */]> { +let mayStore = 1, neverHasSideEffects = 1 in { +def STRT_POST_REG : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addr_offset_none:$addr, am2offset_reg:$offset), + IndexModePost, StFrm, IIC_iStore_ru, + "strt", "\t$Rt, $addr, $offset", + "$addr.base = $Rn_wb", []> { + // {12} isAdd + // {11-0} imm12/Rm + bits<14> offset; + bits<4> addr; + let Inst{25} = 1; + let Inst{23} = offset{12}; let Inst{21} = 1; // overwrite - let AsmMatchConverter = "CvtStWriteBackRegAddrMode3"; + let Inst{19-16} = addr; + let Inst{11-5} = offset{11-5}; + let Inst{4} = 0; + let Inst{3-0} = offset{3-0}; + let DecoderMethod = "DecodeAddrMode2IdxInstruction"; } +def STRT_POST_IMM : AI2ldstidx<0, 0, 0, (outs GPR:$Rn_wb), + (ins GPR:$Rt, addr_offset_none:$addr, am2offset_imm:$offset), + IndexModePost, StFrm, IIC_iStore_ru, + "strt", "\t$Rt, $addr, $offset", + "$addr.base = $Rn_wb", []> { + // {12} isAdd + // {11-0} imm12/Rm + bits<14> offset; + bits<4> addr; + let Inst{25} = 0; + let Inst{23} = offset{12}; + let Inst{21} = 1; // overwrite + let Inst{19-16} = addr; + let Inst{11-0} = offset{11-0}; + let DecoderMethod = "DecodeAddrMode2IdxInstruction"; +} +} + + +multiclass AI3strT op, string opc> { + def i : AI3ldstidxT { + bits<9> offset; + let Inst{23} = offset{8}; + let Inst{22} = 1; + let Inst{11-8} = offset{7-4}; + let Inst{3-0} = offset{3-0}; + let AsmMatchConverter = "cvtStExtTWriteBackImm"; + } + def r : AI3ldstidxT { + bits<5> Rm; + let Inst{23} = Rm{4}; + let Inst{22} = 0; + let Inst{11-8} = 0; + let Inst{3-0} = Rm{3-0}; + let AsmMatchConverter = "cvtStExtTWriteBackReg"; + } +} + + +defm STRHT : AI3strT<0b1011, "strht">; + + //===----------------------------------------------------------------------===// // Load / store multiple Instructions. // @@ -1996,6 +2764,8 @@ multiclass arm_ldst_mult; + // A version for the smaller set of tail call registers. let neverHasSideEffects = 1 in def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm, @@ -2097,15 +2876,33 @@ def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm, let Inst{15-12} = Rd; } -def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src), - DPSoRegFrm, IIC_iMOVsr, - "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>, +def MOVsr : AsI1<0b1101, (outs GPRnopc:$Rd), (ins shift_so_reg_reg:$src), + DPSoRegRegFrm, IIC_iMOVsr, + "mov", "\t$Rd, $src", + [(set GPRnopc:$Rd, shift_so_reg_reg:$src)]>, UnaryDP { + bits<4> Rd; + bits<12> src; + let Inst{15-12} = Rd; + let Inst{19-16} = 0b0000; + let Inst{11-8} = src{11-8}; + let Inst{7} = 0; + let Inst{6-5} = src{6-5}; + let Inst{4} = 1; + let Inst{3-0} = src{3-0}; + let Inst{25} = 0; +} + +def MOVsi : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg_imm:$src), + DPSoRegImmFrm, IIC_iMOVsr, + "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg_imm:$src)]>, UnaryDP { bits<4> Rd; bits<12> src; let Inst{15-12} = Rd; let Inst{19-16} = 0b0000; - let Inst{11-0} = src; + let Inst{11-5} = src{11-5}; + let Inst{4} = 0; + let Inst{3-0} = src{3-0}; let Inst{25} = 0; } @@ -2121,7 +2918,7 @@ def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi, } let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in -def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm_hilo16:$imm), +def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins imm0_65535_expr:$imm), DPFrm, IIC_iMOVi, "movw", "\t$Rd, $imm", [(set GPR:$Rd, imm0_65535:$imm)]>, @@ -2133,16 +2930,22 @@ def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm_hilo16:$imm), let Inst{19-16} = imm{15-12}; let Inst{20} = 0; let Inst{25} = 1; + let DecoderMethod = "DecodeArmMOVTWInstruction"; } +def : InstAlias<"mov${p} $Rd, $imm", + (MOVi16 GPR:$Rd, imm0_65535_expr:$imm, pred:$p)>, + Requires<[IsARM]>; + def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd), (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>; let Constraints = "$src = $Rd" in { -def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm), +def MOVTi16 : AI1<0b1010, (outs GPRnopc:$Rd), + (ins GPR:$src, imm0_65535_expr:$imm), DPFrm, IIC_iMOVi, "movt", "\t$Rd, $imm", - [(set GPR:$Rd, + [(set GPRnopc:$Rd, (or (and GPR:$src, 0xffff), lo16AllZero:$imm))]>, UnaryDP, Requires<[IsARM, HasV6T2]> { @@ -2153,6 +2956,7 @@ def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm), let Inst{19-16} = imm{15-12}; let Inst{20} = 0; let Inst{25} = 1; + let DecoderMethod = "DecodeArmMOVTWInstruction"; } def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd), @@ -2186,30 +2990,28 @@ def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, // Sign extenders -defm SXTB : AI_ext_rrot<0b01101010, +def SXTB : AI_ext_rrot<0b01101010, "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>; -defm SXTH : AI_ext_rrot<0b01101011, +def SXTH : AI_ext_rrot<0b01101011, "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>; -defm SXTAB : AI_exta_rrot<0b01101010, +def SXTAB : AI_exta_rrot<0b01101010, "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; -defm SXTAH : AI_exta_rrot<0b01101011, +def SXTAH : AI_exta_rrot<0b01101011, "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; -// For disassembly only -defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">; +def SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">; -// For disassembly only -defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">; +def SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">; // Zero extenders let AddedComplexity = 16 in { -defm UXTB : AI_ext_rrot<0b01101110, +def UXTB : AI_ext_rrot<0b01101110, "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>; -defm UXTH : AI_ext_rrot<0b01101111, +def UXTH : AI_ext_rrot<0b01101111, "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>; -defm UXTB16 : AI_ext_rrot<0b01101100, +def UXTB16 : AI_ext_rrot<0b01101100, "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>; // FIXME: This pattern incorrectly assumes the shl operator is a rotate. @@ -2217,23 +3019,22 @@ defm UXTB16 : AI_ext_rrot<0b01101100, // instead so we can include a check for masking back in the upper // eight bits of the source into the lower eight bits of the result. //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF), -// (UXTB16r_rot GPR:$Src, 24)>; +// (UXTB16r_rot GPR:$Src, 3)>; def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF), - (UXTB16r_rot GPR:$Src, 8)>; + (UXTB16 GPR:$Src, 1)>; -defm UXTAB : AI_exta_rrot<0b01101110, "uxtab", +def UXTAB : AI_exta_rrot<0b01101110, "uxtab", BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; -defm UXTAH : AI_exta_rrot<0b01101111, "uxtah", +def UXTAH : AI_exta_rrot<0b01101111, "uxtah", BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; } // This isn't safe in general, the add is two 16-bit units, not a 32-bit add. -// For disassembly only -defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">; +def UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">; -def SBFX : I<(outs GPR:$Rd), - (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width), +def SBFX : I<(outs GPRnopc:$Rd), + (ins GPRnopc:$Rn, imm0_31:$lsb, imm1_32:$width), AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>, Requires<[IsARM, HasV6T2]> { @@ -2250,7 +3051,7 @@ def SBFX : I<(outs GPR:$Rd), } def UBFX : I<(outs GPR:$Rd), - (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width), + (ins GPR:$Rn, imm0_31:$lsb, imm1_32:$width), AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>, Requires<[IsARM, HasV6T2]> { @@ -2278,148 +3079,58 @@ defm SUB : AsI1_bin_irs<0b0010, "sub", BinOpFrag<(sub node:$LHS, node:$RHS)>, "SUB">; // ADD and SUB with 's' bit set. -defm ADDS : AI1_bin_s_irs<0b0100, "adds", +// +// Currently, t2ADDS/t2SUBS are pseudo opcodes that exist only in the +// selection DAG. They are "lowered" to real t2ADD/t2SUB opcodes by +// AdjustInstrPostInstrSelection where we determine whether or not to +// set the "s" bit based on CPSR liveness. +// +// FIXME: Eliminate t2ADDS/t2SUBS pseudo opcodes after adding tablegen +// support for an optional CPSR definition that corresponds to the DAG +// node's second value. We can then eliminate the implicit def of CPSR. +defm ADDS : AsI1_bin_s_irs<0b0100, "add", IIC_iALUi, IIC_iALUr, IIC_iALUsr, - BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>; -defm SUBS : AI1_bin_s_irs<0b0010, "subs", + BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>; +defm SUBS : AsI1_bin_s_irs<0b0010, "sub", IIC_iALUi, IIC_iALUr, IIC_iALUsr, - BinOpFrag<(subc node:$LHS, node:$RHS)>>; + BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>; defm ADC : AI1_adde_sube_irs<0b0101, "adc", - BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, + BinOpWithFlagFrag<(ARMadde node:$LHS, node:$RHS, node:$FLAG)>, "ADC", 1>; defm SBC : AI1_adde_sube_irs<0b0110, "sbc", - BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>, + BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>, "SBC">; -// ADC and SUBC with 's' bit set. -let usesCustomInserter = 1 in { -defm ADCS : AI1_adde_sube_s_irs< - BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>; -defm SBCS : AI1_adde_sube_s_irs< - BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>; -} +defm RSB : AsI1_rbin_irs <0b0011, "rsb", + IIC_iALUi, IIC_iALUr, IIC_iALUsr, + BinOpFrag<(sub node:$LHS, node:$RHS)>, "RSB">; -def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm, - IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm", - [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> { - bits<4> Rd; - bits<4> Rn; - bits<12> imm; - let Inst{25} = 1; - let Inst{15-12} = Rd; - let Inst{19-16} = Rn; - let Inst{11-0} = imm; -} +// FIXME: Eliminate them if we can write def : Pat patterns which defines +// CPSR and the implicit def of CPSR is not needed. +defm RSBS : AsI1_rbin_s_is<0b0011, "rsb", + IIC_iALUi, IIC_iALUr, IIC_iALUsr, + BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>; -// The reg/reg form is only defined for the disassembler; for codegen it is -// equivalent to SUBrr. -def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, - IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm", - [/* For disassembly only; pattern left blank */]> { - bits<4> Rd; - bits<4> Rn; - bits<4> Rm; - let Inst{11-4} = 0b00000000; - let Inst{25} = 0; - let Inst{3-0} = Rm; - let Inst{15-12} = Rd; - let Inst{19-16} = Rn; -} - -def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), - DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift", - [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> { - bits<4> Rd; - bits<4> Rn; - bits<12> shift; - let Inst{25} = 0; - let Inst{11-0} = shift; - let Inst{15-12} = Rd; - let Inst{19-16} = Rn; -} - -// RSB with 's' bit set. -// NOTE: CPSR def omitted because it will be handled by the custom inserter. -let usesCustomInserter = 1 in { -def RSBSri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), - 4, IIC_iALUi, - [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]>; -def RSBSrr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), - 4, IIC_iALUr, - [/* For disassembly only; pattern left blank */]>; -def RSBSrs : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), - 4, IIC_iALUsr, - [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]>; -} - -let Uses = [CPSR] in { -def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), - DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm", - [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>, - Requires<[IsARM]> { - bits<4> Rd; - bits<4> Rn; - bits<12> imm; - let Inst{25} = 1; - let Inst{15-12} = Rd; - let Inst{19-16} = Rn; - let Inst{11-0} = imm; -} -// The reg/reg form is only defined for the disassembler; for codegen it is -// equivalent to SUBrr. -def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), - DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm", - [/* For disassembly only; pattern left blank */]> { - bits<4> Rd; - bits<4> Rn; - bits<4> Rm; - let Inst{11-4} = 0b00000000; - let Inst{25} = 0; - let Inst{3-0} = Rm; - let Inst{15-12} = Rd; - let Inst{19-16} = Rn; -} -def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), - DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift", - [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>, - Requires<[IsARM]> { - bits<4> Rd; - bits<4> Rn; - bits<12> shift; - let Inst{25} = 0; - let Inst{11-0} = shift; - let Inst{15-12} = Rd; - let Inst{19-16} = Rn; -} -} - -// NOTE: CPSR def omitted because it will be handled by the custom inserter. -let usesCustomInserter = 1, Uses = [CPSR] in { -def RSCSri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), - 4, IIC_iALUi, - [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>; -def RSCSrs : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), - 4, IIC_iALUsr, - [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>; -} +defm RSC : AI1_rsc_irs<0b0111, "rsc", + BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>, + "RSC">; // (sub X, imm) gets canonicalized to (add X, -imm). Match this form. // The assume-no-carry-in form uses the negation of the input since add/sub // assume opposite meanings of the carry flag (i.e., carry == !borrow). // See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory // details. -def : ARMPat<(add GPR:$src, so_imm_neg:$imm), - (SUBri GPR:$src, so_imm_neg:$imm)>; -def : ARMPat<(addc GPR:$src, so_imm_neg:$imm), - (SUBSri GPR:$src, so_imm_neg:$imm)>; +def : ARMPat<(add GPR:$src, so_imm_neg:$imm), + (SUBri GPR:$src, so_imm_neg:$imm)>; +def : ARMPat<(ARMaddc GPR:$src, so_imm_neg:$imm), + (SUBSri GPR:$src, so_imm_neg:$imm)>; + // The with-carry-in form matches bitwise not instead of the negation. // Effectively, the inverse interpretation of the carry flag already accounts // for part of the negation. -def : ARMPat<(adde_dead_carry GPR:$src, so_imm_not:$imm), - (SBCri GPR:$src, so_imm_not:$imm)>; -def : ARMPat<(adde_live_carry GPR:$src, so_imm_not:$imm), - (SBCSri GPR:$src, so_imm_not:$imm)>; +def : ARMPat<(ARMadde GPR:$src, so_imm_not:$imm, CPSR), + (SBCri GPR:$src, so_imm_not:$imm)>; // Note: These are implemented in C++ code, because they have to generate // ADD/SUBrs instructions, which use a complex pattern that a xform function @@ -2427,12 +3138,13 @@ def : ARMPat<(adde_live_carry GPR:$src, so_imm_not:$imm), // (mul X, 2^n+1) -> (add (X << n), X) // (mul X, 2^n-1) -> (rsb X, (X << n)) -// ARM Arithmetic Instruction -- for disassembly only +// ARM Arithmetic Instruction // GPR:$dst = GPR:$a op GPR:$b class AAI op27_20, bits<8> op11_4, string opc, - list pattern = [/* For disassembly only; pattern left blank */], - dag iops = (ins GPR:$Rn, GPR:$Rm), string asm = "\t$Rd, $Rn, $Rm"> - : AI<(outs GPR:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern> { + list pattern = [], + dag iops = (ins GPRnopc:$Rn, GPRnopc:$Rm), + string asm = "\t$Rd, $Rn, $Rm"> + : AI<(outs GPRnopc:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern> { bits<4> Rn; bits<4> Rd; bits<4> Rm; @@ -2443,17 +3155,19 @@ class AAI op27_20, bits<8> op11_4, string opc, let Inst{3-0} = Rm; } -// Saturating add/subtract -- for disassembly only +// Saturating add/subtract def QADD : AAI<0b00010000, 0b00000101, "qadd", - [(set GPR:$Rd, (int_arm_qadd GPR:$Rm, GPR:$Rn))], - (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">; + [(set GPRnopc:$Rd, (int_arm_qadd GPRnopc:$Rm, GPRnopc:$Rn))], + (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">; def QSUB : AAI<0b00010010, 0b00000101, "qsub", - [(set GPR:$Rd, (int_arm_qsub GPR:$Rm, GPR:$Rn))], - (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">; -def QDADD : AAI<0b00010100, 0b00000101, "qdadd", [], (ins GPR:$Rm, GPR:$Rn), + [(set GPRnopc:$Rd, (int_arm_qsub GPRnopc:$Rm, GPRnopc:$Rn))], + (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">; +def QDADD : AAI<0b00010100, 0b00000101, "qdadd", [], + (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">; -def QDSUB : AAI<0b00010110, 0b00000101, "qdsub", [], (ins GPR:$Rm, GPR:$Rn), +def QDSUB : AAI<0b00010110, 0b00000101, "qdsub", [], + (ins GPRnopc:$Rm, GPRnopc:$Rn), "\t$Rd, $Rm, $Rn">; def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">; @@ -2469,7 +3183,7 @@ def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">; def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">; def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">; -// Signed/Unsigned add/subtract -- for disassembly only +// Signed/Unsigned add/subtract def SASX : AAI<0b01100001, 0b11110011, "sasx">; def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">; @@ -2484,7 +3198,7 @@ def USAX : AAI<0b01100101, 0b11110101, "usax">; def USUB16 : AAI<0b01100101, 0b11110111, "usub16">; def USUB8 : AAI<0b01100101, 0b11111111, "usub8">; -// Signed/Unsigned halving add/subtract -- for disassembly only +// Signed/Unsigned halving add/subtract def SHASX : AAI<0b01100011, 0b11110011, "shasx">; def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">; @@ -2499,7 +3213,7 @@ def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">; def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">; def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">; -// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only +// Unsigned Sum of Absolute Differences [and Accumulate]. def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), MulFrm /* for convenience */, NoItinerary, "usad8", @@ -2531,11 +3245,11 @@ def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), let Inst{3-0} = Rn; } -// Signed/Unsigned saturate -- for disassembly only +// Signed/Unsigned saturate -def SSAT : AI<(outs GPR:$Rd), (ins ssat_imm:$sat_imm, GPR:$a, shift_imm:$sh), - SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh", - [/* For disassembly only; pattern left blank */]> { +def SSAT : AI<(outs GPRnopc:$Rd), + (ins imm1_32:$sat_imm, GPRnopc:$Rn, shift_imm:$sh), + SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []> { bits<4> Rd; bits<5> sat_imm; bits<4> Rn; @@ -2544,14 +3258,14 @@ def SSAT : AI<(outs GPR:$Rd), (ins ssat_imm:$sat_imm, GPR:$a, shift_imm:$sh), let Inst{5-4} = 0b01; let Inst{20-16} = sat_imm; let Inst{15-12} = Rd; - let Inst{11-7} = sh{7-3}; - let Inst{6} = sh{0}; + let Inst{11-7} = sh{4-0}; + let Inst{6} = sh{5}; let Inst{3-0} = Rn; } -def SSAT16 : AI<(outs GPR:$Rd), (ins ssat_imm:$sat_imm, GPR:$Rn), SatFrm, - NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", - [/* For disassembly only; pattern left blank */]> { +def SSAT16 : AI<(outs GPRnopc:$Rd), + (ins imm1_16:$sat_imm, GPRnopc:$Rn), SatFrm, + NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", []> { bits<4> Rd; bits<4> sat_imm; bits<4> Rn; @@ -2562,9 +3276,9 @@ def SSAT16 : AI<(outs GPR:$Rd), (ins ssat_imm:$sat_imm, GPR:$Rn), SatFrm, let Inst{3-0} = Rn; } -def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh), - SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh", - [/* For disassembly only; pattern left blank */]> { +def USAT : AI<(outs GPRnopc:$Rd), + (ins imm0_31:$sat_imm, GPRnopc:$Rn, shift_imm:$sh), + SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []> { bits<4> Rd; bits<5> sat_imm; bits<4> Rn; @@ -2572,15 +3286,15 @@ def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh), let Inst{27-21} = 0b0110111; let Inst{5-4} = 0b01; let Inst{15-12} = Rd; - let Inst{11-7} = sh{7-3}; - let Inst{6} = sh{0}; + let Inst{11-7} = sh{4-0}; + let Inst{6} = sh{5}; let Inst{20-16} = sat_imm; let Inst{3-0} = Rn; } -def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm, - NoItinerary, "usat16", "\t$Rd, $sat_imm, $a", - [/* For disassembly only; pattern left blank */]> { +def USAT16 : AI<(outs GPRnopc:$Rd), + (ins imm0_15:$sat_imm, GPRnopc:$Rn), SatFrm, + NoItinerary, "usat16", "\t$Rd, $sat_imm, $Rn", []> { bits<4> Rd; bits<4> sat_imm; bits<4> Rn; @@ -2591,8 +3305,10 @@ def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm, let Inst{3-0} = Rn; } -def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>; -def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>; +def : ARMV6Pat<(int_arm_ssat GPRnopc:$a, imm:$pos), + (SSAT imm:$pos, GPRnopc:$a, 0)>; +def : ARMV6Pat<(int_arm_usat GPRnopc:$a, imm:$pos), + (USAT imm:$pos, GPRnopc:$a, 0)>; //===----------------------------------------------------------------------===// // Bitwise Instructions. @@ -2611,6 +3327,10 @@ defm BIC : AsI1_bin_irs<0b1110, "bic", IIC_iBITi, IIC_iBITr, IIC_iBITsr, BinOpFrag<(and node:$LHS, (not node:$RHS))>, "BIC">; +// FIXME: bf_inv_mask_imm should be two operands, the lsb and the msb, just +// like in the actual instruction encoding. The complexity of mapping the mask +// to the lsb/msb pair should be handled by ISel, not encapsulated in the +// instruction description. def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm), AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, "bfc", "\t$Rd, $imm", "$src = $Rd", @@ -2622,16 +3342,16 @@ def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm), let Inst{6-0} = 0b0011111; let Inst{15-12} = Rd; let Inst{11-7} = imm{4-0}; // lsb - let Inst{20-16} = imm{9-5}; // width + let Inst{20-16} = imm{9-5}; // msb } // A8.6.18 BFI - Bitfield insert (Encoding A1) -def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm), - AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, - "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd", - [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn, - bf_inv_mask_imm:$imm))]>, - Requires<[IsARM, HasV6T2]> { +def BFI:I<(outs GPRnopc:$Rd), (ins GPRnopc:$src, GPR:$Rn, bf_inv_mask_imm:$imm), + AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, + "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd", + [(set GPRnopc:$Rd, (ARMbfi GPRnopc:$src, GPR:$Rn, + bf_inv_mask_imm:$imm))]>, + Requires<[IsARM, HasV6T2]> { bits<4> Rd; bits<4> Rn; bits<10> imm; @@ -2643,25 +3363,6 @@ def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm), let Inst{3-0} = Rn; } -// GNU as only supports this form of bfi (w/ 4 arguments) -let isAsmParserOnly = 1 in -def BFI4p : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, - lsb_pos_imm:$lsb, width_imm:$width), - AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi, - "bfi", "\t$Rd, $Rn, $lsb, $width", "$src = $Rd", - []>, Requires<[IsARM, HasV6T2]> { - bits<4> Rd; - bits<4> Rn; - bits<5> lsb; - bits<5> width; - let Inst{27-21} = 0b0111110; - let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15 - let Inst{15-12} = Rd; - let Inst{11-7} = lsb; - let Inst{20-16} = width; // Custom encoder => lsb+width-1 - let Inst{3-0} = Rn; -} - def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr, "mvn", "\t$Rd, $Rm", [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP { @@ -2673,15 +3374,31 @@ def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr, let Inst{15-12} = Rd; let Inst{3-0} = Rm; } -def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm, - IIC_iMVNsr, "mvn", "\t$Rd, $shift", - [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP { +def MVNsi : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_imm:$shift), + DPSoRegImmFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift", + [(set GPR:$Rd, (not so_reg_imm:$shift))]>, UnaryDP { bits<4> Rd; bits<12> shift; let Inst{25} = 0; let Inst{19-16} = 0b0000; let Inst{15-12} = Rd; - let Inst{11-0} = shift; + let Inst{11-5} = shift{11-5}; + let Inst{4} = 0; + let Inst{3-0} = shift{3-0}; +} +def MVNsr : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg_reg:$shift), + DPSoRegRegFrm, IIC_iMVNsr, "mvn", "\t$Rd, $shift", + [(set GPR:$Rd, (not so_reg_reg:$shift))]>, UnaryDP { + bits<4> Rd; + bits<12> shift; + let Inst{25} = 0; + let Inst{19-16} = 0b0000; + let Inst{15-12} = Rd; + let Inst{11-8} = shift{11-8}; + let Inst{7} = 0; + let Inst{6-5} = shift{6-5}; + let Inst{4} = 1; + let Inst{3-0} = shift{3-0}; } let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, @@ -2820,8 +3537,8 @@ def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi), bits<4> RdHi; bits<4> Rm; bits<4> Rn; - let Inst{19-16} = RdLo; - let Inst{15-12} = RdHi; + let Inst{19-16} = RdHi; + let Inst{15-12} = RdLo; let Inst{11-8} = Rm; let Inst{3-0} = Rn; } @@ -2855,8 +3572,7 @@ def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), } def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), - IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm", - [/* For disassembly only; pattern left blank */]>, + IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm", []>, Requires<[IsARM, HasV6]> { let Inst{15-12} = 0b1111; } @@ -2869,8 +3585,7 @@ def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd), def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), - IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra", - [/* For disassembly only; pattern left blank */]>, + IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []>, Requires<[IsARM, HasV6]>; def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd), @@ -2881,8 +3596,7 @@ def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd), def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), - IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", - [/* For disassembly only; pattern left blank */]>, + IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []>, Requires<[IsARM, HasV6]>; multiclass AI_smul { @@ -2925,92 +3639,95 @@ multiclass AI_smul { multiclass AI_smla { - def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd), - (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), + let DecoderMethod = "DecodeSMLAInstruction" in { + def BB : AMulxyIa<0b0001000, 0b00, (outs GPRnopc:$Rd), + (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra", - [(set GPR:$Rd, (add GPR:$Ra, - (opnode (sext_inreg GPR:$Rn, i16), - (sext_inreg GPR:$Rm, i16))))]>, + [(set GPRnopc:$Rd, (add GPR:$Ra, + (opnode (sext_inreg GPRnopc:$Rn, i16), + (sext_inreg GPRnopc:$Rm, i16))))]>, Requires<[IsARM, HasV5TE]>; - def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd), - (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), + def BT : AMulxyIa<0b0001000, 0b10, (outs GPRnopc:$Rd), + (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra", - [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16), - (sra GPR:$Rm, (i32 16)))))]>, + [(set GPRnopc:$Rd, + (add GPR:$Ra, (opnode (sext_inreg GPRnopc:$Rn, i16), + (sra GPRnopc:$Rm, (i32 16)))))]>, Requires<[IsARM, HasV5TE]>; - def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd), - (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), + def TB : AMulxyIa<0b0001000, 0b01, (outs GPRnopc:$Rd), + (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra", - [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)), - (sext_inreg GPR:$Rm, i16))))]>, + [(set GPRnopc:$Rd, + (add GPR:$Ra, (opnode (sra GPRnopc:$Rn, (i32 16)), + (sext_inreg GPRnopc:$Rm, i16))))]>, Requires<[IsARM, HasV5TE]>; - def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd), - (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), + def TT : AMulxyIa<0b0001000, 0b11, (outs GPRnopc:$Rd), + (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra", - [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)), - (sra GPR:$Rm, (i32 16)))))]>, + [(set GPRnopc:$Rd, + (add GPR:$Ra, (opnode (sra GPRnopc:$Rn, (i32 16)), + (sra GPRnopc:$Rm, (i32 16)))))]>, Requires<[IsARM, HasV5TE]>; - def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd), - (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), + def WB : AMulxyIa<0b0001001, 0b00, (outs GPRnopc:$Rd), + (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra", - [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn, - (sext_inreg GPR:$Rm, i16)), (i32 16))))]>, + [(set GPRnopc:$Rd, + (add GPR:$Ra, (sra (opnode GPRnopc:$Rn, + (sext_inreg GPRnopc:$Rm, i16)), (i32 16))))]>, Requires<[IsARM, HasV5TE]>; - def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd), - (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), + def WT : AMulxyIa<0b0001001, 0b10, (outs GPRnopc:$Rd), + (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra", - [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn, - (sra GPR:$Rm, (i32 16))), (i32 16))))]>, + [(set GPRnopc:$Rd, + (add GPR:$Ra, (sra (opnode GPRnopc:$Rn, + (sra GPRnopc:$Rm, (i32 16))), (i32 16))))]>, Requires<[IsARM, HasV5TE]>; + } } defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>; defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>; -// Halfword multiply accumulate long: SMLAL -- for disassembly only -def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi), - (ins GPR:$Rn, GPR:$Rm), - IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm", - [/* For disassembly only; pattern left blank */]>, +// Halfword multiply accumulate long: SMLAL. +def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), + (ins GPRnopc:$Rn, GPRnopc:$Rm), + IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm", []>, Requires<[IsARM, HasV5TE]>; -def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi), - (ins GPR:$Rn, GPR:$Rm), - IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm", - [/* For disassembly only; pattern left blank */]>, +def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), + (ins GPRnopc:$Rn, GPRnopc:$Rm), + IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm", []>, Requires<[IsARM, HasV5TE]>; -def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi), - (ins GPR:$Rn, GPR:$Rm), - IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm", - [/* For disassembly only; pattern left blank */]>, +def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), + (ins GPRnopc:$Rn, GPRnopc:$Rm), + IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm", []>, Requires<[IsARM, HasV5TE]>; -def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi), - (ins GPR:$Rn, GPR:$Rm), - IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm", - [/* For disassembly only; pattern left blank */]>, +def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), + (ins GPRnopc:$Rn, GPRnopc:$Rm), + IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm", []>, Requires<[IsARM, HasV5TE]>; -// Helper class for AI_smld -- for disassembly only +// Helper class for AI_smld. class AMulDualIbase : AI, Requires<[IsARM, HasV6]> { bits<4> Rn; bits<4> Rm; - let Inst{4} = 1; - let Inst{5} = swap; - let Inst{6} = sub; - let Inst{7} = 0; - let Inst{21-20} = 0b00; - let Inst{22} = long; let Inst{27-23} = 0b01110; + let Inst{22} = long; + let Inst{21-20} = 0b00; let Inst{11-8} = Rm; + let Inst{7} = 0; + let Inst{6} = sub; + let Inst{5} = swap; + let Inst{4} = 1; let Inst{3-0} = Rn; } class AMulDualI : AMulDualIbase { bits<4> Ra; + bits<4> Rd; + let Inst{19-16} = Rd; let Inst{15-12} = Ra; } class AMulDualI64 { - def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), + def D : AMulDualIa<0, sub, 0, (outs GPRnopc:$Rd), + (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">; - def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), + def DX: AMulDualIa<0, sub, 1, (outs GPRnopc:$Rd), + (ins GPRnopc:$Rn, GPRnopc:$Rm, GPR:$Ra), NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">; - def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi), - (ins GPR:$Rn, GPR:$Rm), NoItinerary, + def LD: AMulDualI64<1, sub, 0, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), + (ins GPRnopc:$Rn, GPRnopc:$Rm), NoItinerary, !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">; - def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi), - (ins GPR:$Rn, GPR:$Rm), NoItinerary, + def LDX : AMulDualI64<1, sub, 1, (outs GPRnopc:$RdLo, GPRnopc:$RdHi), + (ins GPRnopc:$Rn, GPRnopc:$Rm), NoItinerary, !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">; } @@ -3058,10 +3779,10 @@ defm SMLS : AI_smld<1, "smls">; multiclass AI_sdml { - def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), - NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">; - def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), - NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">; + def D:AMulDualI<0, sub, 0, (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, GPRnopc:$Rm), + NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">; + def DX:AMulDualI<0, sub, 1, (outs GPRnopc:$Rd),(ins GPRnopc:$Rn, GPRnopc:$Rm), + NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">; } defm SMUA : AI_sdml<0, "smua">; @@ -3100,55 +3821,38 @@ def : ARMV6Pat<(or (sra (shl GPR:$Rm, (i32 24)), (i32 16)), (and (srl GPR:$Rm, (i32 8)), 0xFF)), (REVSH GPR:$Rm)>; -def lsl_shift_imm : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(Sh, MVT::i32); -}]>; - -def lsl_amt : ImmLeaf 0 && Imm < 32; -}], lsl_shift_imm>; - -def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd), - (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh), +def PKHBT : APKHI<0b01101000, 0, (outs GPRnopc:$Rd), + (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_lsl_amt:$sh), IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh", - [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF), - (and (shl GPR:$Rm, lsl_amt:$sh), - 0xFFFF0000)))]>, + [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF), + (and (shl GPRnopc:$Rm, pkh_lsl_amt:$sh), + 0xFFFF0000)))]>, Requires<[IsARM, HasV6]>; // Alternate cases for PKHBT where identities eliminate some nodes. -def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)), - (PKHBT GPR:$Rn, GPR:$Rm, 0)>; -def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)), - (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>; - -def asr_shift_imm : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(Sh, MVT::i32); -}]>; - -def asr_amt : ImmLeaf 0 && Imm <= 32; -}], asr_shift_imm>; +def : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (and GPRnopc:$Rm, 0xFFFF0000)), + (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, 0)>; +def : ARMV6Pat<(or (and GPRnopc:$Rn, 0xFFFF), (shl GPRnopc:$Rm, imm16_31:$sh)), + (PKHBT GPRnopc:$Rn, GPRnopc:$Rm, imm16_31:$sh)>; // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and // will match the pattern below. -def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd), - (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh), +def PKHTB : APKHI<0b01101000, 1, (outs GPRnopc:$Rd), + (ins GPRnopc:$Rn, GPRnopc:$Rm, pkh_asr_amt:$sh), IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh", - [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000), - (and (sra GPR:$Rm, asr_amt:$sh), - 0xFFFF)))]>, + [(set GPRnopc:$Rd, (or (and GPRnopc:$Rn, 0xFFFF0000), + (and (sra GPRnopc:$Rm, pkh_asr_amt:$sh), + 0xFFFF)))]>, Requires<[IsARM, HasV6]>; // Alternate cases for PKHTB where identities eliminate some nodes. Note that // a shift amount of 0 is *not legal* here, it is PKHBT instead. -def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)), - (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>; -def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), - (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)), - (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>; +def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), + (srl GPRnopc:$src2, imm16_31:$sh)), + (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm16_31:$sh)>; +def : ARMV6Pat<(or (and GPRnopc:$src1, 0xFFFF0000), + (and (srl GPRnopc:$src2, imm1_15:$sh), 0xFFFF)), + (PKHTB GPRnopc:$src1, GPRnopc:$src2, imm1_15:$sh)>; //===----------------------------------------------------------------------===// // Comparison Instructions... @@ -3163,8 +3867,10 @@ def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm), (CMPri GPR:$src, so_imm:$imm)>; def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs), (CMPrr GPR:$src, GPR:$rhs)>; -def : ARMPat<(ARMcmpZ GPR:$src, so_reg:$rhs), - (CMPrs GPR:$src, so_reg:$rhs)>; +def : ARMPat<(ARMcmpZ GPR:$src, so_reg_imm:$rhs), + (CMPrsi GPR:$src, so_reg_imm:$rhs)>; +def : ARMPat<(ARMcmpZ GPR:$src, so_reg_reg:$rhs), + (CMPrsr GPR:$src, so_reg_reg:$rhs)>; // FIXME: We have to be careful when using the CMN instruction and comparison // with 0. One would expect these two pieces of code should give identical @@ -3250,15 +3956,23 @@ def MOVCCr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$false, GPR:$Rm, pred:$p), 4, IIC_iCMOVr, [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>, RegConstraint<"$false = $Rd">; -def MOVCCs : ARMPseudoInst<(outs GPR:$Rd), - (ins GPR:$false, so_reg:$shift, pred:$p), +def MOVCCsi : ARMPseudoInst<(outs GPR:$Rd), + (ins GPR:$false, so_reg_imm:$shift, pred:$p), 4, IIC_iCMOVsr, - [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>, + [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_imm:$shift, + imm:$cc, CCR:$ccr))*/]>, RegConstraint<"$false = $Rd">; +def MOVCCsr : ARMPseudoInst<(outs GPR:$Rd), + (ins GPR:$false, so_reg_reg:$shift, pred:$p), + 4, IIC_iCMOVsr, + [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg_reg:$shift, + imm:$cc, CCR:$ccr))*/]>, + RegConstraint<"$false = $Rd">; + let isMoveImm = 1 in def MOVCCi16 : ARMPseudoInst<(outs GPR:$Rd), - (ins GPR:$false, i32imm_hilo16:$imm, pred:$p), + (ins GPR:$false, imm0_65535_expr:$imm, pred:$p), 4, IIC_iMOVi, []>, RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>; @@ -3288,9 +4002,14 @@ def MVNCCi : ARMPseudoInst<(outs GPR:$Rd), // Atomic operations intrinsics // +def MemBarrierOptOperand : AsmOperandClass { + let Name = "MemBarrierOpt"; + let ParserMethod = "parseMemBarrierOptOperand"; +} def memb_opt : Operand { let PrintMethod = "printMemBOption"; let ParserMatchClass = MemBarrierOptOperand; + let DecoderMethod = "DecodeMemBarrierOption"; } // memory barriers protect the atomic sequences @@ -3321,8 +4040,16 @@ def ISB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, let Inst{3-0} = opt; } +// Pseudo isntruction that combines movs + predicated rsbmi +// to implement integer ABS +let usesCustomInserter = 1, Defs = [CPSR] in { +def ABS : ARMPseudoInst< + (outs GPR:$dst), (ins GPR:$src), + 8, NoItinerary, []>; +} + let usesCustomInserter = 1 in { - let Uses = [CPSR] in { + let Defs = [CPSR] in { def ATOMIC_LOAD_ADD_I8 : PseudoInst< (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>; @@ -3437,44 +4164,47 @@ let usesCustomInserter = 1 in { } let mayLoad = 1 in { -def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary, +def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addr_offset_none:$addr), + NoItinerary, "ldrexb", "\t$Rt, $addr", []>; -def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary, - "ldrexh", "\t$Rt, $addr", []>; -def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary, - "ldrex", "\t$Rt, $addr", []>; +def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addr_offset_none:$addr), + NoItinerary, "ldrexh", "\t$Rt, $addr", []>; +def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins addr_offset_none:$addr), + NoItinerary, "ldrex", "\t$Rt, $addr", []>; let hasExtraDefRegAllocReq = 1 in - def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins addrmode7:$addr), - NoItinerary, "ldrexd", "\t$Rt, $Rt2, $addr", []>; +def LDREXD: AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2),(ins addr_offset_none:$addr), + NoItinerary, "ldrexd", "\t$Rt, $Rt2, $addr", []> { + let DecoderMethod = "DecodeDoubleRegLoad"; +} } let mayStore = 1, Constraints = "@earlyclobber $Rd" in { -def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr), +def STREXB: AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), NoItinerary, "strexb", "\t$Rd, $Rt, $addr", []>; -def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr), +def STREXH: AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), NoItinerary, "strexh", "\t$Rd, $Rt, $addr", []>; -def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr), +def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addr_offset_none:$addr), NoItinerary, "strex", "\t$Rd, $Rt, $addr", []>; } let hasExtraSrcRegAllocReq = 1, Constraints = "@earlyclobber $Rd" in def STREXD : AIstrex<0b01, (outs GPR:$Rd), - (ins GPR:$Rt, GPR:$Rt2, addrmode7:$addr), - NoItinerary, "strexd", "\t$Rd, $Rt, $Rt2, $addr", []>; + (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr), + NoItinerary, "strexd", "\t$Rd, $Rt, $Rt2, $addr", []> { + let DecoderMethod = "DecodeDoubleRegStore"; +} -// Clear-Exclusive is for disassembly only. -def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex", - [/* For disassembly only; pattern left blank */]>, +def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex", []>, Requires<[IsARM, HasV7]> { let Inst{31-0} = 0b11110101011111111111000000011111; } -// SWP/SWPB are deprecated in V6/V7 and for disassembly only. -let mayLoad = 1 in { -def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp", - [/* For disassembly only; pattern left blank */]>; -def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb", - [/* For disassembly only; pattern left blank */]>; +// SWP/SWPB are deprecated in V6/V7. +let mayLoad = 1, mayStore = 1 in { +def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, addr_offset_none:$addr), + "swp", []>; +def SWPB: AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, addr_offset_none:$addr), + "swpb", []>; } //===----------------------------------------------------------------------===// @@ -3526,108 +4256,171 @@ def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, class ACI - : InoP { + : I { let Inst{27-25} = 0b110; } - -multiclass LdStCop op31_28, bit load, dag ops, string opc, string cond>{ - - def _OFFSET : ACI<(outs), - !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops), - !strconcat(opc, cond), "\tp$cop, cr$CRd, $addr"> { - let Inst{31-28} = op31_28; +class ACInoP + : InoP { + let Inst{31-28} = 0b1111; + let Inst{27-25} = 0b110; +} +multiclass LdStCop { + def _OFFSET : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), + asm, "\t$cop, $CRd, $addr"> { + bits<13> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 1; // P = 1 + let Inst{23} = addr{8}; + let Inst{22} = Dbit; let Inst{21} = 0; // W = 0 - let Inst{22} = 0; // D = 0 let Inst{20} = load; + let Inst{19-16} = addr{12-9}; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = addr{7-0}; + let DecoderMethod = "DecodeCopMemInstruction"; } - - def _PRE : ACI<(outs), - !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops), - !strconcat(opc, cond), "\tp$cop, cr$CRd, $addr!", IndexModePre> { - let Inst{31-28} = op31_28; + def _PRE : ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), + asm, "\t$cop, $CRd, $addr!", IndexModePre> { + bits<13> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 1; // P = 1 + let Inst{23} = addr{8}; + let Inst{22} = Dbit; let Inst{21} = 1; // W = 1 - let Inst{22} = 0; // D = 0 let Inst{20} = load; + let Inst{19-16} = addr{12-9}; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = addr{7-0}; + let DecoderMethod = "DecodeCopMemInstruction"; } - - def _POST : ACI<(outs), - !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops), - !strconcat(opc, cond), "\tp$cop, cr$CRd, $addr", IndexModePost> { - let Inst{31-28} = op31_28; + def _POST: ACI<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, + postidx_imm8s4:$offset), + asm, "\t$cop, $CRd, $addr, $offset", IndexModePost> { + bits<9> offset; + bits<4> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 0; // P = 0 + let Inst{23} = offset{8}; + let Inst{22} = Dbit; let Inst{21} = 1; // W = 1 - let Inst{22} = 0; // D = 0 let Inst{20} = load; + let Inst{19-16} = addr; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = offset{7-0}; + let DecoderMethod = "DecodeCopMemInstruction"; } - def _OPTION : ACI<(outs), - !con((ins nohash_imm:$cop,nohash_imm:$CRd,GPR:$base, nohash_imm:$option), - ops), - !strconcat(opc, cond), "\tp$cop, cr$CRd, [$base], \\{$option\\}"> { - let Inst{31-28} = op31_28; + (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, + coproc_option_imm:$option), + asm, "\t$cop, $CRd, $addr, $option"> { + bits<8> option; + bits<4> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 0; // P = 0 let Inst{23} = 1; // U = 1 + let Inst{22} = Dbit; let Inst{21} = 0; // W = 0 - let Inst{22} = 0; // D = 0 let Inst{20} = load; + let Inst{19-16} = addr; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = option; + let DecoderMethod = "DecodeCopMemInstruction"; } - - def L_OFFSET : ACI<(outs), - !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops), - !strconcat(!strconcat(opc, "l"), cond), "\tp$cop, cr$CRd, $addr"> { - let Inst{31-28} = op31_28; +} +multiclass LdSt2Cop { + def _OFFSET : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), + asm, "\t$cop, $CRd, $addr"> { + bits<13> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 1; // P = 1 + let Inst{23} = addr{8}; + let Inst{22} = Dbit; let Inst{21} = 0; // W = 0 - let Inst{22} = 1; // D = 1 let Inst{20} = load; + let Inst{19-16} = addr{12-9}; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = addr{7-0}; + let DecoderMethod = "DecodeCopMemInstruction"; } - - def L_PRE : ACI<(outs), - !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops), - !strconcat(!strconcat(opc, "l"), cond), "\tp$cop, cr$CRd, $addr!", - IndexModePre> { - let Inst{31-28} = op31_28; + def _PRE : ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), + asm, "\t$cop, $CRd, $addr!", IndexModePre> { + bits<13> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 1; // P = 1 + let Inst{23} = addr{8}; + let Inst{22} = Dbit; let Inst{21} = 1; // W = 1 - let Inst{22} = 1; // D = 1 let Inst{20} = load; + let Inst{19-16} = addr{12-9}; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = addr{7-0}; + let DecoderMethod = "DecodeCopMemInstruction"; } - - def L_POST : ACI<(outs), - !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops), - !strconcat(!strconcat(opc, "l"), cond), "\tp$cop, cr$CRd, $addr", - IndexModePost> { - let Inst{31-28} = op31_28; + def _POST: ACInoP<(outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, + postidx_imm8s4:$offset), + asm, "\t$cop, $CRd, $addr, $offset", IndexModePost> { + bits<9> offset; + bits<4> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 0; // P = 0 + let Inst{23} = offset{8}; + let Inst{22} = Dbit; let Inst{21} = 1; // W = 1 - let Inst{22} = 1; // D = 1 let Inst{20} = load; + let Inst{19-16} = addr; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = offset{7-0}; + let DecoderMethod = "DecodeCopMemInstruction"; } - - def L_OPTION : ACI<(outs), - !con((ins nohash_imm:$cop, nohash_imm:$CRd,GPR:$base,nohash_imm:$option), - ops), - !strconcat(!strconcat(opc, "l"), cond), - "\tp$cop, cr$CRd, [$base], \\{$option\\}"> { - let Inst{31-28} = op31_28; + def _OPTION : ACInoP<(outs), + (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, + coproc_option_imm:$option), + asm, "\t$cop, $CRd, $addr, $option"> { + bits<8> option; + bits<4> addr; + bits<4> cop; + bits<4> CRd; let Inst{24} = 0; // P = 0 let Inst{23} = 1; // U = 1 + let Inst{22} = Dbit; let Inst{21} = 0; // W = 0 - let Inst{22} = 1; // D = 1 let Inst{20} = load; + let Inst{19-16} = addr; + let Inst{15-12} = CRd; + let Inst{11-8} = cop; + let Inst{7-0} = option; + let DecoderMethod = "DecodeCopMemInstruction"; } } -defm LDC : LdStCop<{?,?,?,?}, 1, (ins pred:$p), "ldc", "${p}">; -defm LDC2 : LdStCop<0b1111, 1, (ins), "ldc2", "">; -defm STC : LdStCop<{?,?,?,?}, 0, (ins pred:$p), "stc", "${p}">; -defm STC2 : LdStCop<0b1111, 0, (ins), "stc2", "">; +defm LDC : LdStCop <1, 0, "ldc">; +defm LDCL : LdStCop <1, 1, "ldcl">; +defm STC : LdStCop <0, 0, "stc">; +defm STCL : LdStCop <0, 1, "stcl">; +defm LDC2 : LdSt2Cop<1, 0, "ldc2">; +defm LDC2L : LdSt2Cop<1, 1, "ldc2l">; +defm STC2 : LdSt2Cop<0, 0, "stc2">; +defm STC2L : LdSt2Cop<0, 1, "stc2l">; //===----------------------------------------------------------------------===// -// Move between coprocessor and ARM core register -- for disassembly only +// Move between coprocessor and ARM core register. // class MovRCopro; def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */, (outs GPR:$Rt), - (ins p_imm:$cop, i32imm:$opc1, c_imm:$CRn, c_imm:$CRm, - i32imm:$opc2), []>; + (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, + imm0_7:$opc2), []>; def : ARMPat<(int_arm_mrc imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2), (MRC imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; @@ -3697,15 +4490,14 @@ def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */, imm:$CRm, imm:$opc2)]>; def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */, (outs GPR:$Rt), - (ins p_imm:$cop, i32imm:$opc1, c_imm:$CRn, c_imm:$CRm, - i32imm:$opc2), []>; + (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, + imm0_7:$opc2), []>; def : ARMV5TPat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2), (MRC2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; -class MovRRCopro pattern = [/* For disassembly only */]> +class MovRRCopro pattern = []> : ABI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, GPR:$Rt, GPR:$Rt2, c_imm:$CRm), NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> { @@ -3730,8 +4522,7 @@ def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */, imm:$CRm)]>; def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>; -class MovRRCopro2 pattern = [/* For disassembly only */]> +class MovRRCopro2 pattern = []> : ABXI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, GPR:$Rt, GPR:$Rt2, c_imm:$CRm), NoItinerary, !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern> { @@ -3758,20 +4549,22 @@ def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */, def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>; //===----------------------------------------------------------------------===// -// Move between special register and ARM core register -- for disassembly only +// Move between special register and ARM core register // // Move to ARM core register from Special Register -def MRS : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr", - [/* For disassembly only; pattern left blank */]> { +def MRS : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary, + "mrs", "\t$Rd, apsr", []> { bits<4> Rd; let Inst{23-16} = 0b00001111; let Inst{15-12} = Rd; let Inst{7-4} = 0b0000; } -def MRSsys : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary,"mrs","\t$Rd, spsr", - [/* For disassembly only; pattern left blank */]> { +def : InstAlias<"mrs${p} $Rd, cpsr", (MRS GPR:$Rd, pred:$p)>, Requires<[IsARM]>; + +def MRSsys : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary, + "mrs", "\t$Rd, spsr", []> { bits<4> Rd; let Inst{23-16} = 0b01001111; let Inst{15-12} = Rd; @@ -3785,8 +4578,7 @@ def MRSsys : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary,"mrs","\t$Rd, spsr", // operand contains the special register (R Bit) in bit 4 and bits 3-0 contains // the mask with the fields to be accessed in the special register. def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary, - "msr", "\t$mask, $Rn", - [/* For disassembly only; pattern left blank */]> { + "msr", "\t$mask, $Rn", []> { bits<5> mask; bits<4> Rn; @@ -3800,8 +4592,7 @@ def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary, } def MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask, so_imm:$a), NoItinerary, - "msr", "\t$mask, $a", - [/* For disassembly only; pattern left blank */]> { + "msr", "\t$mask, $a", []> { bits<5> mask; bits<12> a; @@ -4030,6 +4821,47 @@ def : ARMV5TEPat<(add GPR:$acc, def : ARMPat<(ARMMemBarrierMCR GPR:$zero), (MCR 15, 0, GPR:$zero, 7, 10, 5)>, Requires<[IsARM, HasV6]>; +// SXT/UXT with no rotate +let AddedComplexity = 16 in { +def : ARMV6Pat<(and GPR:$Src, 0x000000FF), (UXTB GPR:$Src, 0)>; +def : ARMV6Pat<(and GPR:$Src, 0x0000FFFF), (UXTH GPR:$Src, 0)>; +def : ARMV6Pat<(and GPR:$Src, 0x00FF00FF), (UXTB16 GPR:$Src, 0)>; +def : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0x00FF)), + (UXTAB GPR:$Rn, GPR:$Rm, 0)>; +def : ARMV6Pat<(add GPR:$Rn, (and GPR:$Rm, 0xFFFF)), + (UXTAH GPR:$Rn, GPR:$Rm, 0)>; +} + +def : ARMV6Pat<(sext_inreg GPR:$Src, i8), (SXTB GPR:$Src, 0)>; +def : ARMV6Pat<(sext_inreg GPR:$Src, i16), (SXTH GPR:$Src, 0)>; + +def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i8)), + (SXTAB GPR:$Rn, GPRnopc:$Rm, 0)>; +def : ARMV6Pat<(add GPR:$Rn, (sext_inreg GPRnopc:$Rm, i16)), + (SXTAH GPR:$Rn, GPRnopc:$Rm, 0)>; + +// Atomic load/store patterns +def : ARMPat<(atomic_load_8 ldst_so_reg:$src), + (LDRBrs ldst_so_reg:$src)>; +def : ARMPat<(atomic_load_8 addrmode_imm12:$src), + (LDRBi12 addrmode_imm12:$src)>; +def : ARMPat<(atomic_load_16 addrmode3:$src), + (LDRH addrmode3:$src)>; +def : ARMPat<(atomic_load_32 ldst_so_reg:$src), + (LDRrs ldst_so_reg:$src)>; +def : ARMPat<(atomic_load_32 addrmode_imm12:$src), + (LDRi12 addrmode_imm12:$src)>; +def : ARMPat<(atomic_store_8 ldst_so_reg:$ptr, GPR:$val), + (STRBrs GPR:$val, ldst_so_reg:$ptr)>; +def : ARMPat<(atomic_store_8 addrmode_imm12:$ptr, GPR:$val), + (STRBi12 GPR:$val, addrmode_imm12:$ptr)>; +def : ARMPat<(atomic_store_16 addrmode3:$ptr, GPR:$val), + (STRH GPR:$val, addrmode3:$ptr)>; +def : ARMPat<(atomic_store_32 ldst_so_reg:$ptr, GPR:$val), + (STRrs GPR:$val, ldst_so_reg:$ptr)>; +def : ARMPat<(atomic_store_32 addrmode_imm12:$ptr, GPR:$val), + (STRi12 GPR:$val, addrmode_imm12:$ptr)>; + //===----------------------------------------------------------------------===// // Thumb Support @@ -4070,7 +4902,103 @@ def : MnemonicAlias<"swi", "svc">; // Load / Store Multiple def : MnemonicAlias<"ldmfd", "ldm">; def : MnemonicAlias<"ldmia", "ldm">; +def : MnemonicAlias<"ldmea", "ldmdb">; def : MnemonicAlias<"stmfd", "stmdb">; def : MnemonicAlias<"stmia", "stm">; def : MnemonicAlias<"stmea", "stm">; +// PKHBT/PKHTB with default shift amount. PKHTB is equivalent to PKHBT when the +// shift amount is zero (i.e., unspecified). +def : InstAlias<"pkhbt${p} $Rd, $Rn, $Rm", + (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p)>, + Requires<[IsARM, HasV6]>; +def : InstAlias<"pkhtb${p} $Rd, $Rn, $Rm", + (PKHBT GPRnopc:$Rd, GPRnopc:$Rn, GPRnopc:$Rm, 0, pred:$p)>, + Requires<[IsARM, HasV6]>; + +// PUSH/POP aliases for STM/LDM +def : ARMInstAlias<"push${p} $regs", (STMDB_UPD SP, pred:$p, reglist:$regs)>; +def : ARMInstAlias<"pop${p} $regs", (LDMIA_UPD SP, pred:$p, reglist:$regs)>; + +// SSAT/USAT optional shift operand. +def : ARMInstAlias<"ssat${p} $Rd, $sat_imm, $Rn", + (SSAT GPRnopc:$Rd, imm1_32:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>; +def : ARMInstAlias<"usat${p} $Rd, $sat_imm, $Rn", + (USAT GPRnopc:$Rd, imm0_31:$sat_imm, GPRnopc:$Rn, 0, pred:$p)>; + + +// Extend instruction optional rotate operand. +def : ARMInstAlias<"sxtab${p} $Rd, $Rn, $Rm", + (SXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; +def : ARMInstAlias<"sxtah${p} $Rd, $Rn, $Rm", + (SXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; +def : ARMInstAlias<"sxtab16${p} $Rd, $Rn, $Rm", + (SXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; +def : ARMInstAlias<"sxtb${p} $Rd, $Rm", + (SXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; +def : ARMInstAlias<"sxtb16${p} $Rd, $Rm", + (SXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; +def : ARMInstAlias<"sxth${p} $Rd, $Rm", + (SXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; + +def : ARMInstAlias<"uxtab${p} $Rd, $Rn, $Rm", + (UXTAB GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; +def : ARMInstAlias<"uxtah${p} $Rd, $Rn, $Rm", + (UXTAH GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; +def : ARMInstAlias<"uxtab16${p} $Rd, $Rn, $Rm", + (UXTAB16 GPRnopc:$Rd, GPR:$Rn, GPRnopc:$Rm, 0, pred:$p)>; +def : ARMInstAlias<"uxtb${p} $Rd, $Rm", + (UXTB GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; +def : ARMInstAlias<"uxtb16${p} $Rd, $Rm", + (UXTB16 GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; +def : ARMInstAlias<"uxth${p} $Rd, $Rm", + (UXTH GPRnopc:$Rd, GPRnopc:$Rm, 0, pred:$p)>; + + +// RFE aliases +def : MnemonicAlias<"rfefa", "rfeda">; +def : MnemonicAlias<"rfeea", "rfedb">; +def : MnemonicAlias<"rfefd", "rfeia">; +def : MnemonicAlias<"rfeed", "rfeib">; +def : MnemonicAlias<"rfe", "rfeia">; + +// SRS aliases +def : MnemonicAlias<"srsfa", "srsda">; +def : MnemonicAlias<"srsea", "srsdb">; +def : MnemonicAlias<"srsfd", "srsia">; +def : MnemonicAlias<"srsed", "srsib">; +def : MnemonicAlias<"srs", "srsia">; + +// QSAX == QSUBADDX +def : MnemonicAlias<"qsubaddx", "qsax">; +// SASX == SADDSUBX +def : MnemonicAlias<"saddsubx", "sasx">; +// SHASX == SHADDSUBX +def : MnemonicAlias<"shaddsubx", "shasx">; +// SHSAX == SHSUBADDX +def : MnemonicAlias<"shsubaddx", "shsax">; +// SSAX == SSUBADDX +def : MnemonicAlias<"ssubaddx", "ssax">; +// UASX == UADDSUBX +def : MnemonicAlias<"uaddsubx", "uasx">; +// UHASX == UHADDSUBX +def : MnemonicAlias<"uhaddsubx", "uhasx">; +// UHSAX == UHSUBADDX +def : MnemonicAlias<"uhsubaddx", "uhsax">; +// UQASX == UQADDSUBX +def : MnemonicAlias<"uqaddsubx", "uqasx">; +// UQSAX == UQSUBADDX +def : MnemonicAlias<"uqsubaddx", "uqsax">; +// USAX == USUBADDX +def : MnemonicAlias<"usubaddx", "usax">; + +// LDRSBT/LDRHT/LDRSHT post-index offset if optional. +// Note that the write-back output register is a dummy operand for MC (it's +// only meaningful for codegen), so we just pass zero here. +// FIXME: tblgen not cooperating with argument conversions. +//def : InstAlias<"ldrsbt${p} $Rt, $addr", +// (LDRSBTi GPR:$Rt, GPR:$Rt, addr_offset_none:$addr, 0,pred:$p)>; +//def : InstAlias<"ldrht${p} $Rt, $addr", +// (LDRHTi GPR:$Rt, GPR:$Rt, addr_offset_none:$addr, 0, pred:$p)>; +//def : InstAlias<"ldrsht${p} $Rt, $addr", +// (LDRSHTi GPR:$Rt, GPR:$Rt, addr_offset_none:$addr, 0, pred:$p)>; diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 0df62f456343..7aad18695bb3 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -11,6 +11,35 @@ // //===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// NEON-specific Operands. +//===----------------------------------------------------------------------===// +def VectorIndex8Operand : AsmOperandClass { let Name = "VectorIndex8"; } +def VectorIndex16Operand : AsmOperandClass { let Name = "VectorIndex16"; } +def VectorIndex32Operand : AsmOperandClass { let Name = "VectorIndex32"; } +def VectorIndex8 : Operand, ImmLeaf { + let ParserMatchClass = VectorIndex8Operand; + let PrintMethod = "printVectorIndex"; + let MIOperandInfo = (ops i32imm); +} +def VectorIndex16 : Operand, ImmLeaf { + let ParserMatchClass = VectorIndex16Operand; + let PrintMethod = "printVectorIndex"; + let MIOperandInfo = (ops i32imm); +} +def VectorIndex32 : Operand, ImmLeaf { + let ParserMatchClass = VectorIndex32Operand; + let PrintMethod = "printVectorIndex"; + let MIOperandInfo = (ops i32imm); +} + //===----------------------------------------------------------------------===// // NEON-specific DAG Nodes. //===----------------------------------------------------------------------===// @@ -175,7 +204,8 @@ class VLDQQWBPseudo (ins addrmode6:$addr, am6offset:$offset), itin, "$addr.addr = $wb">; class VLDQQQQPseudo - : PseudoNLdSt<(outs QQQQPR:$dst), (ins addrmode6:$addr, QQQQPR:$src),itin,"">; + : PseudoNLdSt<(outs QQQQPR:$dst), (ins addrmode6:$addr, QQQQPR:$src),itin, + "$src = $dst">; class VLDQQQQWBPseudo : PseudoNLdSt<(outs QQQQPR:$dst, GPR:$wb), (ins addrmode6:$addr, am6offset:$offset, QQQQPR:$src), itin, @@ -190,6 +220,7 @@ class VLD1D op7_4, string Dt> "vld1", Dt, "\\{$Vd\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLDInstruction"; } class VLD1Q op7_4, string Dt> : NLdSt<0,0b10,0b1010,op7_4, (outs DPR:$Vd, DPR:$dst2), @@ -197,6 +228,7 @@ class VLD1Q op7_4, string Dt> "vld1", Dt, "\\{$Vd, $dst2\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVLDInstruction"; } def VLD1d8 : VLD1D<{0,0,0,?}, "8">; @@ -221,6 +253,7 @@ class VLD1DWB op7_4, string Dt> "vld1", Dt, "\\{$Vd\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLDInstruction"; } class VLD1QWB op7_4, string Dt> : NLdSt<0,0b10,0b1010,op7_4, (outs DPR:$Vd, DPR:$dst2, GPR:$wb), @@ -228,6 +261,7 @@ class VLD1QWB op7_4, string Dt> "vld1", Dt, "\\{$Vd, $dst2\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVLDInstruction"; } def VLD1d8_UPD : VLD1DWB<{0,0,0,?}, "8">; @@ -252,12 +286,14 @@ class VLD1D3 op7_4, string Dt> "\\{$Vd, $dst2, $dst3\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLDInstruction"; } class VLD1D3WB op7_4, string Dt> : NLdSt<0,0b10,0b0110,op7_4, (outs DPR:$Vd, DPR:$dst2, DPR:$dst3, GPR:$wb), (ins addrmode6:$Rn, am6offset:$Rm), IIC_VLD1x3u, "vld1", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLDInstruction"; } def VLD1d8T : VLD1D3<{0,0,0,?}, "8">; @@ -280,6 +316,7 @@ class VLD1D4 op7_4, string Dt> "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVLDInstruction"; } class VLD1D4WB op7_4, string Dt> : NLdSt<0,0b10,0b0010,op7_4, @@ -288,6 +325,7 @@ class VLD1D4WB op7_4, string Dt> "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVLDInstruction"; } def VLD1d8Q : VLD1D4<{0,0,?,?}, "8">; @@ -310,6 +348,7 @@ class VLD2D op11_8, bits<4> op7_4, string Dt> "vld2", Dt, "\\{$Vd, $dst2\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVLDInstruction"; } class VLD2Q op7_4, string Dt> : NLdSt<0, 0b10, 0b0011, op7_4, @@ -318,6 +357,7 @@ class VLD2Q op7_4, string Dt> "vld2", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVLDInstruction"; } def VLD2d8 : VLD2D<0b1000, {0,0,?,?}, "8">; @@ -343,6 +383,7 @@ class VLD2DWB op11_8, bits<4> op7_4, string Dt> "vld2", Dt, "\\{$Vd, $dst2\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVLDInstruction"; } class VLD2QWB op7_4, string Dt> : NLdSt<0, 0b10, 0b0011, op7_4, @@ -351,6 +392,7 @@ class VLD2QWB op7_4, string Dt> "vld2", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVLDInstruction"; } def VLD2d8_UPD : VLD2DWB<0b1000, {0,0,?,?}, "8">; @@ -384,6 +426,7 @@ class VLD3D op11_8, bits<4> op7_4, string Dt> "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLDInstruction"; } def VLD3d8 : VLD3D<0b0100, {0,0,0,?}, "8">; @@ -402,6 +445,7 @@ class VLD3DWB op11_8, bits<4> op7_4, string Dt> "vld3", Dt, "\\{$Vd, $dst2, $dst3\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLDInstruction"; } def VLD3d8_UPD : VLD3DWB<0b0100, {0,0,0,?}, "8">; @@ -441,6 +485,7 @@ class VLD4D op11_8, bits<4> op7_4, string Dt> "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVLDInstruction"; } def VLD4d8 : VLD4D<0b0000, {0,0,?,?}, "8">; @@ -459,6 +504,7 @@ class VLD4DWB op11_8, bits<4> op7_4, string Dt> "vld4", Dt, "\\{$Vd, $dst2, $dst3, $dst4\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVLDInstruction"; } def VLD4d8_UPD : VLD4DWB<0b0000, {0,0,?,?}, "8">; @@ -530,6 +576,7 @@ class VLD1LN op11_8, bits<4> op7_4, string Dt, ValueType Ty, (i32 (LoadOp addrmode6:$Rn)), imm:$lane))]> { let Rm = 0b1111; + let DecoderMethod = "DecodeVLD1LN"; } class VLD1LN32 op11_8, bits<4> op7_4, string Dt, ValueType Ty, PatFrag LoadOp> @@ -541,6 +588,7 @@ class VLD1LN32 op11_8, bits<4> op7_4, string Dt, ValueType Ty, (i32 (LoadOp addrmode6oneL32:$Rn)), imm:$lane))]> { let Rm = 0b1111; + let DecoderMethod = "DecodeVLD1LN"; } class VLD1QLNPseudo : VLDQLNPseudo { let Pattern = [(set QPR:$dst, (vector_insert (Ty QPR:$src), @@ -580,7 +628,9 @@ class VLD1LNWB op11_8, bits<4> op7_4, string Dt> (ins addrmode6:$Rn, am6offset:$Rm, DPR:$src, nohash_imm:$lane), IIC_VLD1lnu, "vld1", Dt, "\\{$Vd[$lane]\\}, $Rn$Rm", - "$src = $Vd, $Rn.addr = $wb", []>; + "$src = $Vd, $Rn.addr = $wb", []> { + let DecoderMethod = "DecodeVLD1LN"; +} def VLD1LNd8_UPD : VLD1LNWB<0b0000, {?,?,?,0}, "8"> { let Inst{7-5} = lane{2-0}; @@ -607,6 +657,7 @@ class VLD2LN op11_8, bits<4> op7_4, string Dt> "$src1 = $Vd, $src2 = $dst2", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLD2LN"; } def VLD2LNd8 : VLD2LN<0b0001, {?,?,?,?}, "8"> { @@ -642,6 +693,7 @@ class VLD2LNWB op11_8, bits<4> op7_4, string Dt> "\\{$Vd[$lane], $dst2[$lane]\\}, $Rn$Rm", "$src1 = $Vd, $src2 = $dst2, $Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLD2LN"; } def VLD2LNd8_UPD : VLD2LNWB<0b0001, {?,?,?,?}, "8"> { @@ -676,6 +728,7 @@ class VLD3LN op11_8, bits<4> op7_4, string Dt> "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane]\\}, $Rn", "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3", []> { let Rm = 0b1111; + let DecoderMethod = "DecodeVLD3LN"; } def VLD3LNd8 : VLD3LN<0b0010, {?,?,?,0}, "8"> { @@ -712,7 +765,9 @@ class VLD3LNWB op11_8, bits<4> op7_4, string Dt> IIC_VLD3lnu, "vld3", Dt, "\\{$Vd[$lane], $dst2[$lane], $dst3[$lane]\\}, $Rn$Rm", "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $Rn.addr = $wb", - []>; + []> { + let DecoderMethod = "DecodeVLD3LN"; +} def VLD3LNd8_UPD : VLD3LNWB<0b0010, {?,?,?,0}, "8"> { let Inst{7-5} = lane{2-0}; @@ -748,6 +803,7 @@ class VLD4LN op11_8, bits<4> op7_4, string Dt> "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLD4LN"; } def VLD4LNd8 : VLD4LN<0b0011, {?,?,?,?}, "8"> { @@ -788,6 +844,7 @@ class VLD4LNWB op11_8, bits<4> op7_4, string Dt> "$src1 = $Vd, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4, $Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLD4LN" ; } def VLD4LNd8_UPD : VLD4LNWB<0b0011, {?,?,?,?}, "8"> { @@ -825,6 +882,7 @@ class VLD1DUP op7_4, string Dt, ValueType Ty, PatFrag LoadOp> [(set DPR:$Vd, (Ty (NEONvdup (i32 (LoadOp addrmode6dup:$Rn)))))]> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLD1DupInstruction"; } class VLD1QDUPPseudo : VLDQPseudo { let Pattern = [(set QPR:$dst, @@ -852,6 +910,7 @@ class VLD1QDUP op7_4, string Dt> "vld1", Dt, "\\{$Vd[], $dst2[]\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLD1DupInstruction"; } def VLD1DUPq8 : VLD1QDUP<{0,0,1,0}, "8">; @@ -864,12 +923,14 @@ class VLD1DUPWB op7_4, string Dt> (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD1dupu, "vld1", Dt, "\\{$Vd[]\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLD1DupInstruction"; } class VLD1QDUPWB op7_4, string Dt> : NLdSt<1, 0b10, 0b1100, op7_4, (outs DPR:$Vd, DPR:$dst2, GPR:$wb), (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD1dupu, "vld1", Dt, "\\{$Vd[], $dst2[]\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLD1DupInstruction"; } def VLD1DUPd8_UPD : VLD1DUPWB<{0,0,0,0}, "8">; @@ -891,6 +952,7 @@ class VLD2DUP op7_4, string Dt> "vld2", Dt, "\\{$Vd[], $dst2[]\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLD2DupInstruction"; } def VLD2DUPd8 : VLD2DUP<{0,0,0,?}, "8">; @@ -912,6 +974,7 @@ class VLD2DUPWB op7_4, string Dt> (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD2dupu, "vld2", Dt, "\\{$Vd[], $dst2[]\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLD2DupInstruction"; } def VLD2DUPd8_UPD : VLD2DUPWB<{0,0,0,0}, "8">; @@ -932,7 +995,8 @@ class VLD3DUP op7_4, string Dt> (ins addrmode6dup:$Rn), IIC_VLD3dup, "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn", "", []> { let Rm = 0b1111; - let Inst{4} = Rn{4}; + let Inst{4} = 0; + let DecoderMethod = "DecodeVLD3DupInstruction"; } def VLD3DUPd8 : VLD3DUP<{0,0,0,?}, "8">; @@ -954,7 +1018,8 @@ class VLD3DUPWB op7_4, string Dt> (ins addrmode6dup:$Rn, am6offset:$Rm), IIC_VLD3dupu, "vld3", Dt, "\\{$Vd[], $dst2[], $dst3[]\\}, $Rn$Rm", "$Rn.addr = $wb", []> { - let Inst{4} = Rn{4}; + let Inst{4} = 0; + let DecoderMethod = "DecodeVLD3DupInstruction"; } def VLD3DUPd8_UPD : VLD3DUPWB<{0,0,0,0}, "8">; @@ -977,6 +1042,7 @@ class VLD4DUP op7_4, string Dt> "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLD4DupInstruction"; } def VLD4DUPd8 : VLD4DUP<{0,0,0,?}, "8">; @@ -1000,6 +1066,7 @@ class VLD4DUPWB op7_4, string Dt> "vld4", Dt, "\\{$Vd[], $dst2[], $dst3[], $dst4[]\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVLD4DupInstruction"; } def VLD4DUPd8_UPD : VLD4DUPWB<{0,0,0,0}, "8">; @@ -1045,6 +1112,7 @@ class VST1D op7_4, string Dt> IIC_VST1, "vst1", Dt, "\\{$Vd\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVSTInstruction"; } class VST1Q op7_4, string Dt> : NLdSt<0,0b00,0b1010,op7_4, (outs), @@ -1052,6 +1120,7 @@ class VST1Q op7_4, string Dt> "vst1", Dt, "\\{$Vd, $src2\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVSTInstruction"; } def VST1d8 : VST1D<{0,0,0,?}, "8">; @@ -1075,6 +1144,7 @@ class VST1DWB op7_4, string Dt> (ins addrmode6:$Rn, am6offset:$Rm, DPR:$Vd), IIC_VST1u, "vst1", Dt, "\\{$Vd\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVSTInstruction"; } class VST1QWB op7_4, string Dt> : NLdSt<0, 0b00, 0b1010, op7_4, (outs GPR:$wb), @@ -1082,6 +1152,7 @@ class VST1QWB op7_4, string Dt> IIC_VST1x2u, "vst1", Dt, "\\{$Vd, $src2\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVSTInstruction"; } def VST1d8_UPD : VST1DWB<{0,0,0,?}, "8">; @@ -1106,6 +1177,7 @@ class VST1D3 op7_4, string Dt> IIC_VST1x3, "vst1", Dt, "\\{$Vd, $src2, $src3\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVSTInstruction"; } class VST1D3WB op7_4, string Dt> : NLdSt<0, 0b00, 0b0110, op7_4, (outs GPR:$wb), @@ -1114,6 +1186,7 @@ class VST1D3WB op7_4, string Dt> IIC_VST1x3u, "vst1", Dt, "\\{$Vd, $src2, $src3\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVSTInstruction"; } def VST1d8T : VST1D3<{0,0,0,?}, "8">; @@ -1137,6 +1210,7 @@ class VST1D4 op7_4, string Dt> []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVSTInstruction"; } class VST1D4WB op7_4, string Dt> : NLdSt<0, 0b00, 0b0010, op7_4, (outs GPR:$wb), @@ -1145,6 +1219,7 @@ class VST1D4WB op7_4, string Dt> "vst1", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVSTInstruction"; } def VST1d8Q : VST1D4<{0,0,?,?}, "8">; @@ -1167,6 +1242,7 @@ class VST2D op11_8, bits<4> op7_4, string Dt> IIC_VST2, "vst2", Dt, "\\{$Vd, $src2\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVSTInstruction"; } class VST2Q op7_4, string Dt> : NLdSt<0, 0b00, 0b0011, op7_4, (outs), @@ -1175,6 +1251,7 @@ class VST2Q op7_4, string Dt> "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVSTInstruction"; } def VST2d8 : VST2D<0b1000, {0,0,?,?}, "8">; @@ -1200,6 +1277,7 @@ class VST2DWB op11_8, bits<4> op7_4, string Dt> IIC_VST2u, "vst2", Dt, "\\{$Vd, $src2\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVSTInstruction"; } class VST2QWB op7_4, string Dt> : NLdSt<0, 0b00, 0b0011, op7_4, (outs GPR:$wb), @@ -1208,6 +1286,7 @@ class VST2QWB op7_4, string Dt> "vst2", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVSTInstruction"; } def VST2d8_UPD : VST2DWB<0b1000, {0,0,?,?}, "8">; @@ -1241,6 +1320,7 @@ class VST3D op11_8, bits<4> op7_4, string Dt> "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn", "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVSTInstruction"; } def VST3d8 : VST3D<0b0100, {0,0,0,?}, "8">; @@ -1259,6 +1339,7 @@ class VST3DWB op11_8, bits<4> op7_4, string Dt> "vst3", Dt, "\\{$Vd, $src2, $src3\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVSTInstruction"; } def VST3d8_UPD : VST3DWB<0b0100, {0,0,0,?}, "8">; @@ -1298,6 +1379,7 @@ class VST4D op11_8, bits<4> op7_4, string Dt> "", []> { let Rm = 0b1111; let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVSTInstruction"; } def VST4d8 : VST4D<0b0000, {0,0,?,?}, "8">; @@ -1316,6 +1398,7 @@ class VST4DWB op11_8, bits<4> op7_4, string Dt> "vst4", Dt, "\\{$Vd, $src2, $src3, $src4\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{5-4} = Rn{5-4}; + let DecoderMethod = "DecodeVSTInstruction"; } def VST4d8_UPD : VST4DWB<0b0000, {0,0,?,?}, "8">; @@ -1381,6 +1464,7 @@ class VST1LN op11_8, bits<4> op7_4, string Dt, ValueType Ty, IIC_VST1ln, "vst1", Dt, "\\{$Vd[$lane]\\}, $Rn", "", [(StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), addrmode6:$Rn)]> { let Rm = 0b1111; + let DecoderMethod = "DecodeVST1LN"; } class VST1LN32 op11_8, bits<4> op7_4, string Dt, ValueType Ty, PatFrag StoreOp, SDNode ExtractOp> @@ -1389,6 +1473,7 @@ class VST1LN32 op11_8, bits<4> op7_4, string Dt, ValueType Ty, IIC_VST1ln, "vst1", Dt, "\\{$Vd[$lane]\\}, $Rn", "", [(StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), addrmode6oneL32:$Rn)]>{ let Rm = 0b1111; + let DecoderMethod = "DecodeVST1LN"; } class VST1QLNPseudo : VSTQLNPseudo { @@ -1429,7 +1514,9 @@ class VST1LNWB op11_8, bits<4> op7_4, string Dt, ValueType Ty, "\\{$Vd[$lane]\\}, $Rn$Rm", "$Rn.addr = $wb", [(set GPR:$wb, (StoreOp (ExtractOp (Ty DPR:$Vd), imm:$lane), - addrmode6:$Rn, am6offset:$Rm))]>; + addrmode6:$Rn, am6offset:$Rm))]> { + let DecoderMethod = "DecodeVST1LN"; +} class VST1QLNWBPseudo : VSTQLNWBPseudo { let Pattern = [(set GPR:$wb, (StoreOp (ExtractOp (Ty QPR:$src), imm:$lane), @@ -1465,6 +1552,7 @@ class VST2LN op11_8, bits<4> op7_4, string Dt> "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVST2LN"; } def VST2LNd8 : VST2LN<0b0001, {?,?,?,?}, "8"> { @@ -1502,6 +1590,7 @@ class VST2LNWB op11_8, bits<4> op7_4, string Dt> "\\{$src1[$lane], $src2[$lane]\\}, $addr$offset", "$addr.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVST2LN"; } def VST2LNd8_UPD : VST2LNWB<0b0001, {?,?,?,?}, "8"> { @@ -1535,6 +1624,7 @@ class VST3LN op11_8, bits<4> op7_4, string Dt> nohash_imm:$lane), IIC_VST3ln, "vst3", Dt, "\\{$Vd[$lane], $src2[$lane], $src3[$lane]\\}, $Rn", "", []> { let Rm = 0b1111; + let DecoderMethod = "DecodeVST3LN"; } def VST3LNd8 : VST3LN<0b0010, {?,?,?,0}, "8"> { @@ -1569,7 +1659,9 @@ class VST3LNWB op11_8, bits<4> op7_4, string Dt> DPR:$Vd, DPR:$src2, DPR:$src3, nohash_imm:$lane), IIC_VST3lnu, "vst3", Dt, "\\{$Vd[$lane], $src2[$lane], $src3[$lane]\\}, $Rn$Rm", - "$Rn.addr = $wb", []>; + "$Rn.addr = $wb", []> { + let DecoderMethod = "DecodeVST3LN"; +} def VST3LNd8_UPD : VST3LNWB<0b0010, {?,?,?,0}, "8"> { let Inst{7-5} = lane{2-0}; @@ -1604,6 +1696,7 @@ class VST4LN op11_8, bits<4> op7_4, string Dt> "", []> { let Rm = 0b1111; let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVST4LN"; } def VST4LNd8 : VST4LN<0b0011, {?,?,?,?}, "8"> { @@ -1642,6 +1735,7 @@ class VST4LNWB op11_8, bits<4> op7_4, string Dt> "\\{$Vd[$lane], $src2[$lane], $src3[$lane], $src4[$lane]\\}, $Rn$Rm", "$Rn.addr = $wb", []> { let Inst{4} = Rn{4}; + let DecoderMethod = "DecodeVST4LN"; } def VST4LNd8_UPD : VST4LNWB<0b0011, {?,?,?,?}, "8"> { @@ -4039,6 +4133,7 @@ class N2VLShMax op21_16, bits<4> op11_8, bit op7, : N2VLSh { let Inst{21-16} = op21_16; + let DecoderMethod = "DecodeVSHLMaxInstruction"; } def VSHLLi8 : N2VLShMax<1, 1, 0b110010, 0b0011, 0, 0, 0, "vshll", "i8", v8i16, v8i8, NEONvshlli>; @@ -4219,16 +4314,6 @@ def : InstAlias<"vmov${p} $Vd, $Vm", def : InstAlias<"vmov${p} $Vd, $Vm", (VORRq QPR:$Vd, QPR:$Vm, QPR:$Vm, pred:$p)>; -let neverHasSideEffects = 1 in { -// Pseudo vector move instructions for QQ and QQQQ registers. This should -// be expanded after register allocation is completed. -def VMOVQQ : PseudoInst<(outs QQPR:$dst), (ins QQPR:$src), - NoItinerary, []>; - -def VMOVQQQQ : PseudoInst<(outs QQQQPR:$dst), (ins QQQQPR:$src), - NoItinerary, []>; -} // neverHasSideEffects - // VMOV : Vector Move (Immediate) let isReMaterializable = 1 in { @@ -4462,36 +4547,42 @@ def : Pat<(v4f32 (NEONvdup (f32 (bitconvert GPR:$R)))), (VDUP32q GPR:$R)>; // VDUP : Vector Duplicate Lane (from scalar to all elements) class VDUPLND op19_16, string OpcodeStr, string Dt, - ValueType Ty> - : NVDupLane + : NVDupLane; class VDUPLNQ op19_16, string OpcodeStr, string Dt, - ValueType ResTy, ValueType OpTy> - : NVDupLane + : NVDupLane; + VectorIndex32:$lane)))]>; // Inst{19-16} is partially specified depending on the element size. -def VDUPLN8d : VDUPLND<{?,?,?,1}, "vdup", "8", v8i8> { +def VDUPLN8d : VDUPLND<{?,?,?,1}, "vdup", "8", v8i8, VectorIndex8> { + bits<3> lane; let Inst{19-17} = lane{2-0}; } -def VDUPLN16d : VDUPLND<{?,?,1,0}, "vdup", "16", v4i16> { +def VDUPLN16d : VDUPLND<{?,?,1,0}, "vdup", "16", v4i16, VectorIndex16> { + bits<2> lane; let Inst{19-18} = lane{1-0}; } -def VDUPLN32d : VDUPLND<{?,1,0,0}, "vdup", "32", v2i32> { +def VDUPLN32d : VDUPLND<{?,1,0,0}, "vdup", "32", v2i32, VectorIndex32> { + bits<1> lane; let Inst{19} = lane{0}; } -def VDUPLN8q : VDUPLNQ<{?,?,?,1}, "vdup", "8", v16i8, v8i8> { +def VDUPLN8q : VDUPLNQ<{?,?,?,1}, "vdup", "8", v16i8, v8i8, VectorIndex8> { + bits<3> lane; let Inst{19-17} = lane{2-0}; } -def VDUPLN16q : VDUPLNQ<{?,?,1,0}, "vdup", "16", v8i16, v4i16> { +def VDUPLN16q : VDUPLNQ<{?,?,1,0}, "vdup", "16", v8i16, v4i16, VectorIndex16> { + bits<2> lane; let Inst{19-18} = lane{1-0}; } -def VDUPLN32q : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4i32, v2i32> { +def VDUPLN32q : VDUPLNQ<{?,1,0,0}, "vdup", "32", v4i32, v2i32, VectorIndex32> { + bits<1> lane; let Inst{19} = lane{0}; } @@ -4753,6 +4844,7 @@ def VZIPq32 : N2VQShuffle<0b10, 0b00011, IIC_VPERMQ3, "vzip", "32">; // Vector Table Lookup and Table Extension. // VTBL : Vector Table Lookup +let DecoderMethod = "DecodeTBLInstruction" in { def VTBL1 : N3V<1,1,0b11,0b1000,0,0, (outs DPR:$Vd), (ins DPR:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB1, @@ -4815,6 +4907,7 @@ def VTBX3Pseudo def VTBX4Pseudo : PseudoNeonI<(outs DPR:$dst), (ins DPR:$orig, QQPR:$tbl, DPR:$src), IIC_VTBX4, "$orig = $dst", []>; +} // DecoderMethod = "DecodeTBLInstruction" //===----------------------------------------------------------------------===// // NEON instructions for single-precision FP math diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index bfe83eceb13f..cedb54799db0 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -19,6 +19,19 @@ def ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; +def imm_sr_XFORM: SDNodeXFormgetZExtValue(); + return CurDAG->getTargetConstant((Imm == 32 ? 0 : Imm), MVT::i32); +}]>; +def ThumbSRImmAsmOperand: AsmOperandClass { let Name = "ImmThumbSR"; } +def imm_sr : Operand, PatLeaf<(imm), [{ + uint64_t Imm = N->getZExtValue(); + return Imm > 0 && Imm <= 32; +}], imm_sr_XFORM> { + let PrintMethod = "printThumbSRImm"; + let ParserMatchClass = ThumbSRImmAsmOperand; +} + def imm_neg_XFORM : SDNodeXFormgetTargetConstant(-(int)N->getZExtValue(), MVT::i32); }]>; @@ -30,10 +43,6 @@ def imm0_7_neg : PatLeaf<(i32 imm), [{ return (uint32_t)-N->getZExtValue() < 8; }], imm_neg_XFORM>; -def imm0_255_asmoperand : AsmOperandClass { let Name = "Imm0_255"; } -def imm0_255 : Operand, ImmLeaf= 0 && Imm < 256; }]> { - let ParserMatchClass = imm0_255_asmoperand; -} def imm0_255_comp : PatLeaf<(i32 imm), [{ return ~((uint32_t)N->getZExtValue()) < 256; }]>; @@ -69,8 +78,17 @@ def t_adrlabel : Operand { } // Scaled 4 immediate. -def t_imm_s4 : Operand { +def t_imm0_1020s4_asmoperand: AsmOperandClass { let Name = "Imm0_1020s4"; } +def t_imm0_1020s4 : Operand { let PrintMethod = "printThumbS4ImmOperand"; + let ParserMatchClass = t_imm0_1020s4_asmoperand; + let OperandType = "OPERAND_IMMEDIATE"; +} + +def t_imm0_508s4_asmoperand: AsmOperandClass { let Name = "Imm0_508s4"; } +def t_imm0_508s4 : Operand { + let PrintMethod = "printThumbS4ImmOperand"; + let ParserMatchClass = t_imm0_508s4_asmoperand; let OperandType = "OPERAND_IMMEDIATE"; } @@ -79,113 +97,129 @@ def t_imm_s4 : Operand { let OperandType = "OPERAND_PCREL" in { def t_brtarget : Operand { let EncoderMethod = "getThumbBRTargetOpValue"; + let DecoderMethod = "DecodeThumbBROperand"; } def t_bcctarget : Operand { let EncoderMethod = "getThumbBCCTargetOpValue"; + let DecoderMethod = "DecodeThumbBCCTargetOperand"; } def t_cbtarget : Operand { let EncoderMethod = "getThumbCBTargetOpValue"; + let DecoderMethod = "DecodeThumbCmpBROperand"; } def t_bltarget : Operand { let EncoderMethod = "getThumbBLTargetOpValue"; + let DecoderMethod = "DecodeThumbBLTargetOperand"; } def t_blxtarget : Operand { let EncoderMethod = "getThumbBLXTargetOpValue"; + let DecoderMethod = "DecodeThumbBLXOffset"; } } -def MemModeRegThumbAsmOperand : AsmOperandClass { - let Name = "MemModeRegThumb"; - let SuperClasses = []; -} - -def MemModeImmThumbAsmOperand : AsmOperandClass { - let Name = "MemModeImmThumb"; - let SuperClasses = []; -} - // t_addrmode_rr := reg + reg // +def t_addrmode_rr_asm_operand : AsmOperandClass { let Name = "MemThumbRR"; } def t_addrmode_rr : Operand, ComplexPattern { let EncoderMethod = "getThumbAddrModeRegRegOpValue"; let PrintMethod = "printThumbAddrModeRROperand"; + let DecoderMethod = "DecodeThumbAddrModeRR"; + let ParserMatchClass = t_addrmode_rr_asm_operand; let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); } // t_addrmode_rrs := reg + reg // +// We use separate scaled versions because the Select* functions need +// to explicitly check for a matching constant and return false here so that +// the reg+imm forms will match instead. This is a horrible way to do that, +// as it forces tight coupling between the methods, but it's how selectiondag +// currently works. def t_addrmode_rrs1 : Operand, ComplexPattern { let EncoderMethod = "getThumbAddrModeRegRegOpValue"; let PrintMethod = "printThumbAddrModeRROperand"; + let DecoderMethod = "DecodeThumbAddrModeRR"; + let ParserMatchClass = t_addrmode_rr_asm_operand; let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); - let ParserMatchClass = MemModeRegThumbAsmOperand; } def t_addrmode_rrs2 : Operand, ComplexPattern { let EncoderMethod = "getThumbAddrModeRegRegOpValue"; + let DecoderMethod = "DecodeThumbAddrModeRR"; let PrintMethod = "printThumbAddrModeRROperand"; + let ParserMatchClass = t_addrmode_rr_asm_operand; let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); - let ParserMatchClass = MemModeRegThumbAsmOperand; } def t_addrmode_rrs4 : Operand, ComplexPattern { let EncoderMethod = "getThumbAddrModeRegRegOpValue"; + let DecoderMethod = "DecodeThumbAddrModeRR"; let PrintMethod = "printThumbAddrModeRROperand"; + let ParserMatchClass = t_addrmode_rr_asm_operand; let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); - let ParserMatchClass = MemModeRegThumbAsmOperand; } // t_addrmode_is4 := reg + imm5 * 4 // +def t_addrmode_is4_asm_operand : AsmOperandClass { let Name = "MemThumbRIs4"; } def t_addrmode_is4 : Operand, ComplexPattern { let EncoderMethod = "getAddrModeISOpValue"; + let DecoderMethod = "DecodeThumbAddrModeIS"; let PrintMethod = "printThumbAddrModeImm5S4Operand"; + let ParserMatchClass = t_addrmode_is4_asm_operand; let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); - let ParserMatchClass = MemModeImmThumbAsmOperand; } // t_addrmode_is2 := reg + imm5 * 2 // +def t_addrmode_is2_asm_operand : AsmOperandClass { let Name = "MemThumbRIs2"; } def t_addrmode_is2 : Operand, ComplexPattern { let EncoderMethod = "getAddrModeISOpValue"; + let DecoderMethod = "DecodeThumbAddrModeIS"; let PrintMethod = "printThumbAddrModeImm5S2Operand"; + let ParserMatchClass = t_addrmode_is2_asm_operand; let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); - let ParserMatchClass = MemModeImmThumbAsmOperand; } // t_addrmode_is1 := reg + imm5 // +def t_addrmode_is1_asm_operand : AsmOperandClass { let Name = "MemThumbRIs1"; } def t_addrmode_is1 : Operand, ComplexPattern { let EncoderMethod = "getAddrModeISOpValue"; + let DecoderMethod = "DecodeThumbAddrModeIS"; let PrintMethod = "printThumbAddrModeImm5S1Operand"; + let ParserMatchClass = t_addrmode_is1_asm_operand; let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); - let ParserMatchClass = MemModeImmThumbAsmOperand; } // t_addrmode_sp := sp + imm8 * 4 // +// FIXME: This really shouldn't have an explicit SP operand at all. It should +// be implicit, just like in the instruction encoding itself. +def t_addrmode_sp_asm_operand : AsmOperandClass { let Name = "MemThumbSPI"; } def t_addrmode_sp : Operand, ComplexPattern { let EncoderMethod = "getAddrModeThumbSPOpValue"; + let DecoderMethod = "DecodeThumbAddrModeSP"; let PrintMethod = "printThumbAddrModeSPOperand"; + let ParserMatchClass = t_addrmode_sp_asm_operand; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); - let ParserMatchClass = MemModeImmThumbAsmOperand; } // t_addrmode_pc := -}; diff --git a/test/FrontendC++/2009-09-04-modify-crash.cpp b/test/FrontendC++/2009-09-04-modify-crash.cpp deleted file mode 100644 index 89274e09c7ed..000000000000 --- a/test/FrontendC++/2009-09-04-modify-crash.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgxx %s -fapple-kext -S -o - -// The extra check in 71555 caused this to crash on Darwin X86 -// in an assert build. -class foo { - virtual ~foo (); -}; -foo::~foo(){} diff --git a/test/FrontendC++/2009-09-09-packed-layout.cpp b/test/FrontendC++/2009-09-09-packed-layout.cpp deleted file mode 100644 index 921aad79f73c..000000000000 --- a/test/FrontendC++/2009-09-09-packed-layout.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgxx -S -m32 %s -o /dev/null -class X { - public: - virtual ~X(); - short y; -}; -#pragma pack(push, 1) -class Z : public X { - public: enum { foo = ('x') }; - virtual int y() const; -}; -#pragma pack(pop) -class Y : public X { -public: enum { foo = ('y'), bar = 0 }; -}; -X x; -Y y; -Z z; diff --git a/test/FrontendC++/2009-10-27-crash.cpp b/test/FrontendC++/2009-10-27-crash.cpp deleted file mode 100644 index da73988b6976..000000000000 --- a/test/FrontendC++/2009-10-27-crash.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// RUN: %llvmgxx -S %s -o /dev/null -// Radar 7328944 - -typedef struct -{ - unsigned short a : 1; - unsigned short b : 2; - unsigned short c : 1; - unsigned short d : 1; - unsigned short e : 1; - unsigned short f : 1; - unsigned short g : 2; - unsigned short : 7; - union - { - struct - { - unsigned char h : 1; - unsigned char i : 1; - unsigned char j : 1; - unsigned char : 5; - }; - struct - { - unsigned char k : 3; - unsigned char : 5; - }; - }; - unsigned char : 8; -} tt; - -typedef struct -{ - unsigned char s; - tt t; - unsigned int u; -} ttt; - -ttt X = { - 4, - { 0 }, - 55, -}; diff --git a/test/FrontendC++/2009-12-23-MissingSext.cpp b/test/FrontendC++/2009-12-23-MissingSext.cpp deleted file mode 100644 index ee978812c295..000000000000 --- a/test/FrontendC++/2009-12-23-MissingSext.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgxx %s -S -o - | FileCheck %s -// The store of p.y into the temporary was not -// getting extended to 32 bits, so uninitialized -// bits of the temporary were used. 7366161. -struct foo { - char x:8; - signed int y:24; -}; -int bar(struct foo p, int x) { -// CHECK: bar -// CHECK: sext -// CHECK: sext - x = (p.y > x ? x : p.y); - return x; -// CHECK: return -} diff --git a/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp b/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp deleted file mode 100644 index ff45412b4414..000000000000 --- a/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgcc -g -S %s -o - | FileCheck %s -// Here, second to last argument "i32 64" indicates that artificial type is set. -// Test to artificial attribute attahed to "this" pointer type. -// Radar 7655792 and 7655002 - -class A { -public: - int fn1(int i) const { return i + 2; }; -}; - -int foo() { - A a; - // Matching "i32 64, metadata !} ; [ DW_TAG_pointer_type ]" - // CHECK: i32 64, metadata {{![0-9]+\} ; \[ DW_TAG_pointer_type \]}} - return a.fn1(1); -} diff --git a/test/FrontendC++/2010-03-22-empty-baseclass.cpp b/test/FrontendC++/2010-03-22-empty-baseclass.cpp deleted file mode 100644 index bb741c42c842..000000000000 --- a/test/FrontendC++/2010-03-22-empty-baseclass.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// RUN: %llvmgxx -S %s -o - -O2 | FileCheck %s -namespace boost { - namespace detail { - template struct cv_traits_imp {}; - template struct cv_traits_imp {typedef T unqualified_type;}; - } -} -namespace mpl_ {} -namespace boost { - namespace mpl {using namespace mpl_;} - template< typename T > struct remove_cv {typedef typename boost::detail::cv_traits_imp::unqualified_type type;}; - namespace type_traits { - typedef char yes_type; - struct no_type {char padding[8];}; - } -} -namespace mpl_ { - template< bool C_ > struct bool_; - typedef bool_ true_; - typedef bool_ false_; - template< bool C_ > struct bool_ {static const bool value = C_;}; - template< typename T, T N > struct integral_c; -} -namespace boost{ - template struct integral_constant : - public mpl::integral_c {}; - template<> struct integral_constant : public mpl::true_ {}; - template<> struct integral_constant : public mpl::false_ {}; - namespace type_traits { - template struct ice_or; - template - struct ice_or {static const bool value = true; }; - template <> struct ice_or - {static const bool value = false;}; - template struct ice_and; - template - struct ice_and {static const bool value = false;}; - template <> struct ice_and - {static const bool value = true;}; - template struct ice_not {static const bool value = true;}; - }; - namespace detail { - template struct is_union_impl {static const bool value = false;}; - } - template< typename T > struct is_union : - ::boost::integral_constant::value> {}; - namespace detail { - template ::boost::type_traits::yes_type is_class_tester(void(U::*)(void)); - template ::boost::type_traits::no_type is_class_tester(...); - template struct is_class_impl { - static const bool value = (::boost::type_traits::ice_and< sizeof(is_class_tester(0)) - == sizeof(::boost::type_traits::yes_type), - ::boost::type_traits::ice_not< ::boost::is_union::value >::value >::value);}; -} - template struct is_class: - ::boost::integral_constant::value> { }; -namespace detail { - template struct empty_helper_t1: public T {int i[256];}; - struct empty_helper_t2 {int i[256];}; - template struct empty_helper - {static const bool value = false;}; - template struct empty_helper - {static const bool value = (sizeof(empty_helper_t1) == sizeof(empty_helper_t2));}; - template struct is_empty_impl { - typedef typename remove_cv::type cvt; - static const bool value = (::boost::type_traits::ice_or< ::boost::detail::empty_helper - ::value>::value, false>::value); - }; -} -template struct is_empty: -::boost::integral_constant::value> {}; -template struct is_same: -::boost::integral_constant {}; -template struct call_traits {typedef T& reference;}; -namespace details { - template - struct compressed_pair_switch; - template - struct compressed_pair_switch - {static const int value = 1;}; - template class compressed_pair_imp; - template class compressed_pair_imp: - protected ::boost::remove_cv::type { - public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - first_reference first() {return *this;} - second_reference second() {return second_;} - second_type second_; - }; -} -template class compressed_pair: - private ::boost::details::compressed_pair_imp::type, - typename remove_cv::type>::value, - ::boost::is_empty::value, ::boost::is_empty::value>::value> - { - private: - typedef details::compressed_pair_imp::type, - typename remove_cv::type>::value, - ::boost::is_empty::value, ::boost::is_empty::value>::value> base; - public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - first_reference first() {return base::first();} - second_reference second() {return base::second();} - }; -} -struct empty_base_t {}; -struct empty_t : empty_base_t {}; -typedef boost::compressed_pair data_t; -extern "C" {int printf(const char * , ...);} -extern "C" {void abort(void);} -int main (int argc, char * const argv[]) { - data_t x; - x.second() = -3; - // This store should be elided: - x.first() = empty_t(); - // If x.second() has been clobbered by the elided store, fail. - if (x.second() != -3) { - printf("x.second() was clobbered\n"); - // CHECK-NOT: x.second() was clobbered - abort(); - } - return 0; -} -// CHECK: ret i32 diff --git a/test/FrontendC++/2010-04-30-OptimizedMethod-Dbg.cpp b/test/FrontendC++/2010-04-30-OptimizedMethod-Dbg.cpp deleted file mode 100644 index 761c0dc097a4..000000000000 --- a/test/FrontendC++/2010-04-30-OptimizedMethod-Dbg.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -g -S -O2 %s -o - | FileCheck %s - -class foo { -public: - int bar(int x); - static int baz(int x); -}; - -int foo::bar(int x) { - // CHECK: {{i32 [0-9]+, i1 true(, i[0-9]+ [^\}]+[}]|[}]) ; \[ DW_TAG_subprogram \]}} - return x*4 + 1; -} - -int foo::baz(int x) { - // CHECK: {{i32 [0-9]+, i1 true(, i[0-9]+ [^\},]+[}]|[}]) ; \[ DW_TAG_subprogram \]}} - return x*4 + 1; -} - diff --git a/test/FrontendC++/2010-05-10-Var-DbgInfo.cpp b/test/FrontendC++/2010-05-10-Var-DbgInfo.cpp deleted file mode 100644 index e6165c0cce2a..000000000000 --- a/test/FrontendC++/2010-05-10-Var-DbgInfo.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// RUN: %llvmgcc -S -O0 -g %s -o /dev/null -// PR 7104 - -struct A { - int Ai; -}; - -struct B : public A {}; -struct C : public B {}; - -const char * f(int C::*){ return ""; } -int f(int B::*) { return 1; } - -struct D : public C {}; - -const char * g(int B::*){ return ""; } -int g(int D::*) { return 1; } - -void test() -{ - int i = f(&A::Ai); - - const char * str = g(&A::Ai); -} - -// conversion of B::* to C::* is better than conversion of A::* to C::* -typedef void (A::*pmfa)(); -typedef void (B::*pmfb)(); -typedef void (C::*pmfc)(); - -struct X { - operator pmfa(); - operator pmfb(); -}; - - -void g(pmfc); - -void test2(X x) -{ - g(x); -} - diff --git a/test/FrontendC++/2010-05-11-alwaysinlineinstantiation.cpp b/test/FrontendC++/2010-05-11-alwaysinlineinstantiation.cpp deleted file mode 100644 index 9203dbd0bd9f..000000000000 --- a/test/FrontendC++/2010-05-11-alwaysinlineinstantiation.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %llvmgxx -xc++ %s -S -o - | not grep ZN12basic_stringIcEC1Ev -// RUN: %llvmgxx -xc++ %s -S -o - | grep ZN12basic_stringIcED1Ev | count 2 - -template -class basic_string -{ -public: - basic_string(); - ~basic_string(); -}; - -template -__attribute__ ((__visibility__("hidden"), __always_inline__)) inline -basic_string::basic_string() -{ -} - -template -inline -basic_string::~basic_string() -{ -} - -typedef basic_string string; - -extern template class basic_string; - -int main() -{ - string s; -} diff --git a/test/FrontendC++/2010-05-12-PtrToMember-Dbg.cpp b/test/FrontendC++/2010-05-12-PtrToMember-Dbg.cpp deleted file mode 100644 index c2d6abe97fc5..000000000000 --- a/test/FrontendC++/2010-05-12-PtrToMember-Dbg.cpp +++ /dev/null @@ -1,17 +0,0 @@ -//RUN: %llvmgxx -O0 -S -g -o - %s | grep DW_TAG_auto_variable -class Foo -{ - public: - int x; - int y; - Foo (int i, int j) { x = i; y = j; } -}; - - -Foo foo(10, 11); - -int main() { - int Foo::* pmi = &Foo::y; - return foo.*pmi; -} - diff --git a/test/FrontendC++/2010-06-21-LocalVarDbg.cpp b/test/FrontendC++/2010-06-21-LocalVarDbg.cpp deleted file mode 100644 index 48d821508dd6..000000000000 --- a/test/FrontendC++/2010-06-21-LocalVarDbg.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %llvmgxx -g -Os -S %s -o - | llvm-as -disable-output -// Do not use function name to create named metadata used to hold -// local variable info. For example. llvm.dbg.lv.~A is an invalid name. -class A { -public: - ~A() { int i = 0; i++; } -}; - -int foo(int i) { - A a; - return 0; -} - diff --git a/test/FrontendC++/2010-06-22-BitfieldInit.cpp b/test/FrontendC++/2010-06-22-BitfieldInit.cpp deleted file mode 100644 index 8dceb78bfc67..000000000000 --- a/test/FrontendC++/2010-06-22-BitfieldInit.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %llvmgxx -g -S %s -struct TEST2 -{ - int subid:32; - int :0; -}; - -typedef struct _TEST3 -{ - TEST2 foo; - TEST2 foo2; -} TEST3; - -TEST3 test = - { - {0}, - {0} - }; - -int main() { return 0; } diff --git a/test/FrontendC++/2010-06-22-ZeroBitfield.cpp b/test/FrontendC++/2010-06-22-ZeroBitfield.cpp deleted file mode 100644 index 9c4f2629f748..000000000000 --- a/test/FrontendC++/2010-06-22-ZeroBitfield.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgxx -g -S %s -struct s8_0 { unsigned : 0; }; -struct s8_1 { double x; }; -struct s8 { s8_0 a; s8_1 b; }; -s8 f8() { return s8(); } diff --git a/test/FrontendC++/2010-07-19-nowarn.cpp b/test/FrontendC++/2010-07-19-nowarn.cpp deleted file mode 100644 index a61a84ff28b0..000000000000 --- a/test/FrontendC++/2010-07-19-nowarn.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %llvmgcc %s -S -m32 -fasm-blocks -o /dev/null -// This should not warn about unreferenced label. 8195660. -// XFAIL: * -// XTARGET: x86,i386,i686 - -void quarterAsm(int array[], int len) -{ - __asm - { - mov esi, array; - mov ecx, len; - shr ecx, 2; -loop: - movdqa xmm0, [esi]; - psrad xmm0, 2; - movdqa [esi], xmm0; - add esi, 16; - sub ecx, 1; - jnz loop; - } -} diff --git a/test/FrontendC++/2010-07-23-DeclLoc.cpp b/test/FrontendC++/2010-07-23-DeclLoc.cpp deleted file mode 100644 index 9bf432beb727..000000000000 --- a/test/FrontendC++/2010-07-23-DeclLoc.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// RUN: %llvmgxx -S -g %s -o - | FileCheck %s -// Require the template function declaration refer to the correct filename. -// First, locate the function decl in metadata, and pluck out the file handle: -// CHECK: {{extract_dwarf_data_from_header.*extract_dwarf_data_from_header.*extract_dwarf_data_from_header.*[^ ]+", metadata !}}[[filehandle:[0-9]+]], -// Second: Require that filehandle refer to the correct filename: -// CHECK: {{^!}}[[filehandle]] = metadata {{![{].*}} metadata !"decl_should_be_here.hpp", -typedef long unsigned int __darwin_size_t; -typedef __darwin_size_t size_t; -typedef unsigned char uint8_t; -typedef unsigned int uint32_t; -typedef unsigned long long uint64_t; -namespace std { - template class auto_ptr { - _Tp* _M_ptr; - public: - typedef _Tp element_type; - auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { } - element_type& operator*() const throw() { } - }; -} -class Pointer32 { -public: - typedef uint32_t ptr_t; - typedef uint32_t size_t; -}; -class Pointer64 { -public: - typedef uint64_t ptr_t; - typedef uint64_t size_t; -}; -class BigEndian {}; -class LittleEndian {}; -template class SizeAndEndianness { -public: - typedef _SIZE SIZE; -}; -typedef SizeAndEndianness ISA32Little; -typedef SizeAndEndianness ISA32Big; -typedef SizeAndEndianness ISA64Little; -typedef SizeAndEndianness ISA64Big; -template class TRange { -protected: - typename SIZE::ptr_t _location; - typename SIZE::size_t _length; - TRange(typename SIZE::ptr_t location, typename SIZE::size_t length) : _location(location), _length(length) { } -}; -template class TRangeValue : public TRange { - T _value; -public: - TRangeValue(typename SIZE::ptr_t location, typename SIZE::size_t length, T value) : TRange(location, length), _value(value) {}; -}; -template class TAddressRelocator {}; -class CSCppSymbolOwner{}; -class CSCppSymbolOwnerData{}; -template class TRawSymbolOwnerData -{ - TRangeValue< SIZE, uint8_t* > _TEXT_text_section; - const char* _dsym_path; - uint32_t _dylib_current_version; - uint32_t _dylib_compatibility_version; -public: - TRawSymbolOwnerData() : - _TEXT_text_section(0, 0, __null), _dsym_path(__null), _dylib_current_version(0), _dylib_compatibility_version(0) {} -}; -template class TExtendedMachOHeader {}; -# 16 "decl_should_be_here.hpp" -template void extract_dwarf_data_from_header(TExtendedMachOHeader& header, - TRawSymbolOwnerData& symbol_owner_data, - TAddressRelocator* address_relocator) {} -struct CSCppSymbolOwnerHashFunctor { - size_t operator()(const CSCppSymbolOwner& symbol_owner) const { -# 97 "wrong_place_for_decl.cpp" - } -}; -template CSCppSymbolOwnerData* create_symbol_owner_data_arch_specific(CSCppSymbolOwner* symbol_owner, const char* dsym_path) { - typedef typename SIZE_AND_ENDIANNESS::SIZE SIZE; - std::auto_ptr< TRawSymbolOwnerData > data(new TRawSymbolOwnerData()); - std::auto_ptr< TExtendedMachOHeader > header; - extract_dwarf_data_from_header(*header, *data, (TAddressRelocator*)__null); -} -CSCppSymbolOwnerData* create_symbol_owner_data2(CSCppSymbolOwner* symbol_owner, const char* dsym_path) { - create_symbol_owner_data_arch_specific< ISA32Little >(symbol_owner, dsym_path); - create_symbol_owner_data_arch_specific< ISA32Big >(symbol_owner, dsym_path); - create_symbol_owner_data_arch_specific< ISA64Little >(symbol_owner, dsym_path); - create_symbol_owner_data_arch_specific< ISA64Big >(symbol_owner, dsym_path); -} diff --git a/test/FrontendC++/2010-08-31-ByValArg.cpp b/test/FrontendC++/2010-08-31-ByValArg.cpp deleted file mode 100644 index 4ccaabd7d0c9..000000000000 --- a/test/FrontendC++/2010-08-31-ByValArg.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// This regression test checks byval arguments' debug info. -// Radar 8367011 -// RUN: %llvmgcc -S -O0 -g %s -o - | \ -// RUN: llc --disable-cfi --disable-fp-elim -o %t.s -O0 -relocation-model=pic -// RUN: %compile_c %t.s -o %t.o -// RUN: %link %t.o -o %t.exe -// RUN: echo {break get\nrun\np missing_arg.b} > %t.in -// RUN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | \ -// RUN: grep {1 = 4242} - -// XTARGET: x86_64-apple-darwin - -class EVT { -public: - int a; - int b; - int c; -}; - -class VAL { -public: - int x; - int y; -}; -void foo(EVT e); -EVT bar(); - -void get(int *i, unsigned dl, VAL v, VAL *p, unsigned n, EVT missing_arg) { -//CHECK: .ascii "missing_arg" - EVT e = bar(); - if (dl == n) - foo(missing_arg); -} - - -EVT bar() { - EVT e; - return e; -} - -void foo(EVT e) {} - -int main(){ - VAL v; - EVT ma; - ma.a = 1; - ma.b = 4242; - ma.c = 3; - int i = 42; - get (&i, 1, v, &v, 2, ma); - return 0; -} - diff --git a/test/FrontendC++/alignstack.cpp b/test/FrontendC++/alignstack.cpp deleted file mode 100644 index 4f993d669bfa..000000000000 --- a/test/FrontendC++/alignstack.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: %llvmgxx %s -fasm-blocks -S -o - | FileCheck %s -// Complicated expression as jump target -// XFAIL: * -// XTARGET: x86,i386,i686,darwin - -void Method3() -{ -// CHECK: Method3 -// CHECK-NOT: alignstack - asm("foo:"); -// CHECK: return -} - -void Method4() -{ -// CHECK: Method4 -// CHECK: alignstack - asm { - bar: - } -// CHECK: return -} - diff --git a/test/FrontendC++/dg.exp b/test/FrontendC++/dg.exp deleted file mode 100644 index fc852e30acf8..000000000000 --- a/test/FrontendC++/dg.exp +++ /dev/null @@ -1,5 +0,0 @@ -load_lib llvm.exp - -if [ llvm_gcc_supports c++ ] then { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] -} diff --git a/test/FrontendC++/integration-O2.cpp b/test/FrontendC++/integration-O2.cpp deleted file mode 100644 index bb65ac210332..000000000000 --- a/test/FrontendC++/integration-O2.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %llvmgxx %s -O2 -S -o - | FileCheck %s - -// This test verifies that we get expected codegen out of the -O2 optimization -// level from the full optimizer. - - - -// Verify that ipsccp is running and can eliminate globals. -static int test1g = 42; -void test1f1() { - if (test1g == 0) test1g = 0; -} -int test1f2() { - return test1g; -} - -// CHECK: @_Z7test1f2v() -// CHECK: entry: -// CHECK-NEXT: ret i32 42 diff --git a/test/FrontendC++/m64-ptr.cpp b/test/FrontendC++/m64-ptr.cpp deleted file mode 100644 index f91e2f4f858d..000000000000 --- a/test/FrontendC++/m64-ptr.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %llvmgxx %s -S -o - | FileCheck %s -// XFAIL: powerpc-apple-darwin - -// Make sure pointers are passed as pointers, not converted to int. -// The first load should be of type i8** in either 32 or 64 bit mode. -// This formerly happened on x86-64, 7375899. - -class StringRef { -public: - const char *Data; - long Len; -}; -void foo(StringRef X); -void bar(StringRef &A) { -// CHECK: @_Z3barR9StringRef -// CHECK: load i8** - foo(A); -// CHECK: ret void -} diff --git a/test/FrontendC++/member-alignment.cpp b/test/FrontendC++/member-alignment.cpp deleted file mode 100644 index c5b20b279325..000000000000 --- a/test/FrontendC++/member-alignment.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %llvmgxx -S %s -o - | FileCheck %s -// XFAIL: arm,powerpc - -// rdar://7268289 - -class t { -public: - virtual void foo(void); - void bar(void); -}; - -void -t::bar(void) { -// CHECK: _ZN1t3barEv{{.*}} align 2 -} - -void -t::foo(void) { -// CHECK: _ZN1t3fooEv{{.*}} align 2 -} diff --git a/test/FrontendC++/ptr-to-method-devirt.cpp b/test/FrontendC++/ptr-to-method-devirt.cpp deleted file mode 100644 index a5ca5c76559a..000000000000 --- a/test/FrontendC++/ptr-to-method-devirt.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// PR1602 -// RUN: %llvmgxx -S %s -o - -O3 | not grep ptrtoint -// RUN: %llvmgxx -S %s -o - -O3 | grep getelementptr | count 1 - - -struct S { virtual void f(); }; - -typedef void (S::*P)(void); - -const P p = &S::f; - -void g(S s) { - (s.*p)(); - } diff --git a/test/FrontendC++/thunk-linkonce-odr.cpp b/test/FrontendC++/thunk-linkonce-odr.cpp deleted file mode 100644 index ad72e64aa861..000000000000 --- a/test/FrontendC++/thunk-linkonce-odr.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: %llvmgxx %s -S -o - | FileCheck %s -// & - -struct A { - virtual int f() { return 1; } -}; - -struct B { - virtual int f() { return 2; } -}; - -struct C : A, B { - virtual int f() { return 3; } -}; - -struct D : C { - virtual int f() { return 4; } -}; - -static int f(D* d) { - B* b = d; - return b->f(); -}; - -int g() { - D d; - return f(&d); -} - -// Thunks should be marked as "linkonce ODR" not "weak". -// -// CHECK: define linkonce_odr i32 @_ZThn{{[48]}}_N1C1fEv -// CHECK: define linkonce_odr i32 @_ZThn{{[48]}}_N1D1fEv diff --git a/test/FrontendC++/varargs.cpp b/test/FrontendC++/varargs.cpp deleted file mode 100644 index c4de76acc30b..000000000000 --- a/test/FrontendC++/varargs.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %llvmgxx -S %s -o - | FileCheck %s -// rdar://7309675 -// PR4678 - -// test1 should be compmiled to be a varargs function in the IR even -// though there is no way to do a va_begin. Otherwise, the optimizer -// will warn about 'dropped arguments' at the call site. - -// CHECK: define i32 @_Z5test1z(...) -int test1(...) { - return -1; -} - -// CHECK: call i32 (...)* @_Z5test1z(i32 0) -void test() { - test1(0); -} - - diff --git a/test/FrontendC++/weak-external.cpp b/test/FrontendC++/weak-external.cpp deleted file mode 100644 index f4f0ba19ef37..000000000000 --- a/test/FrontendC++/weak-external.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgxx %s -S -O2 -o - | not grep {_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag} -// PR4262 - -// The "basic_string" extern template instantiation declaration is supposed to -// suppress the implicit instantiation of non-inline member functions. Make sure -// that we suppress the implicit instantiation of non-inline member functions -// defined out-of-line. That we aren't instantiating the basic_string -// constructor when we shouldn't be. Such an instantiation forces the implicit -// instantiation of _S_construct. Since _S_construct is a member -// template, it's instantiation is *not* suppressed (despite being in -// basic_string), so we would emit it as a weak definition. - -#include - -void dummysymbol() { - throw(std::runtime_error("string")); -} diff --git a/test/FrontendC++/x86-64-abi-sret-vs-2word-struct-param.cpp b/test/FrontendC++/x86-64-abi-sret-vs-2word-struct-param.cpp deleted file mode 100644 index f81854e0cb92..000000000000 --- a/test/FrontendC++/x86-64-abi-sret-vs-2word-struct-param.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %llvmgxx -S %s -o - | grep byval | count 2 -// XTARGET: x86 -// PR4242 -// (PR 4242 bug is on 64-bit only, test passes on x86-32 as well) - -struct S { - void* data[3]; -}; - -struct T { - void* data[2]; -}; - -extern "C" S fail(int, int, int, int, T t, void* p) { - S s; - s.data[0] = t.data[0]; - s.data[1] = t.data[1]; - s.data[2] = p; - return s; -} - -extern "C" S* succeed(S* sret, int, int, int, int, T t, void* p) { - sret->data[0] = t.data[0]; - sret->data[1] = t.data[1]; - sret->data[2] = p; - return sret; -} diff --git a/test/FrontendC/2002-01-23-LoadQISIReloadFailure.c b/test/FrontendC/2002-01-23-LoadQISIReloadFailure.c deleted file mode 100644 index 1779a99942ea..000000000000 --- a/test/FrontendC/2002-01-23-LoadQISIReloadFailure.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* Regression test. Just compile .c -> .ll to test */ -int foo(void) { - unsigned char *pp; - unsigned w_cnt; - - w_cnt += *pp; - - return w_cnt; -} diff --git a/test/FrontendC/2002-01-24-ComplexSpaceInType.c b/test/FrontendC/2002-01-24-ComplexSpaceInType.c deleted file mode 100644 index 13d92c7306ee..000000000000 --- a/test/FrontendC/2002-01-24-ComplexSpaceInType.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -// This caused generation of the following type name: -// %Array = uninitialized global [10 x %complex int] -// -// which caused problems because of the space int the complex int type -// - -struct { int X, Y; } Array[10]; - -void foo() {} diff --git a/test/FrontendC/2002-01-24-HandleCallInsnSEGV.c b/test/FrontendC/2002-01-24-HandleCallInsnSEGV.c deleted file mode 100644 index e619cf469926..000000000000 --- a/test/FrontendC/2002-01-24-HandleCallInsnSEGV.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -void *dlclose(void*); - -void ap_os_dso_unload(void *handle) -{ - dlclose(handle); - return; /* This return triggers the bug: Weird */ -} diff --git a/test/FrontendC/2002-02-13-ConditionalInCall.c b/test/FrontendC/2002-02-13-ConditionalInCall.c deleted file mode 100644 index f361088c1cf8..000000000000 --- a/test/FrontendC/2002-02-13-ConditionalInCall.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* Test problem where bad code was generated with a ?: statement was - in a function call argument */ - -void foo(int, double, float); - -void bar(int x) { - foo(x, x ? 1.0 : 12.5, 1.0f); -} - diff --git a/test/FrontendC/2002-02-13-ReloadProblem.c b/test/FrontendC/2002-02-13-ReloadProblem.c deleted file mode 100644 index 2ae97b72276b..000000000000 --- a/test/FrontendC/2002-02-13-ReloadProblem.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* This triggered a problem in reload, fixed by disabling most of the - * steps of compilation in GCC. Before this change, the code went through - * the entire backend of GCC, even though it was unnecessary for LLVM output - * now it is skipped entirely, and since reload doesn't run, it can't cause - * a problem. - */ - -extern int tolower(int); - -const char *rangematch(const char *pattern, int test, int c) { - - if ((c <= test) | (tolower(c) <= tolower((unsigned char)test))) - return 0; - - return pattern; -} diff --git a/test/FrontendC/2002-02-13-TypeVarNameCollision.c b/test/FrontendC/2002-02-13-TypeVarNameCollision.c deleted file mode 100644 index 2dede68a38dd..000000000000 --- a/test/FrontendC/2002-02-13-TypeVarNameCollision.c +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* This testcase causes a symbol table collision. Type names and variable - * names should be in distinct namespaces - */ - -typedef struct foo { - int X, Y; -} FOO; - -static FOO foo[100]; - -int test() { - return foo[4].Y; -} - diff --git a/test/FrontendC/2002-02-13-UnnamedLocal.c b/test/FrontendC/2002-02-13-UnnamedLocal.c deleted file mode 100644 index 85aa615205cf..000000000000 --- a/test/FrontendC/2002-02-13-UnnamedLocal.c +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* Testcase for a problem where GCC allocated xqic to a register, - * and did not have a VAR_DECL that explained the stack slot to LLVM. - * Now the LLVM code synthesizes a stack slot if one is presented that - * has not been previously recognized. This is where alloca's named - * 'local' come from now. - */ - -typedef struct { - short x; -} foostruct; - -int foo(foostruct ic); - -void test() { - foostruct xqic; - foo(xqic); -} - - diff --git a/test/FrontendC/2002-02-14-EntryNodePreds.c b/test/FrontendC/2002-02-14-EntryNodePreds.c deleted file mode 100644 index 851af912174b..000000000000 --- a/test/FrontendC/2002-02-14-EntryNodePreds.c +++ /dev/null @@ -1,37 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* GCC Used to generate code that contained a branch to the entry node of - * the do_merge function. This is illegal LLVM code. To fix this, GCC now - * inserts an entry node regardless of whether or not it has to insert allocas. - */ - -struct edge_rec -{ - struct VERTEX *v; - struct edge_rec *next; - int wasseen; - int more_data; -}; - -typedef struct edge_rec *QUAD_EDGE; - -typedef struct { - QUAD_EDGE left, right; -} EDGE_PAIR; - -struct EDGE_STACK { - int ptr; - QUAD_EDGE *elts; - int stack_size; -}; - -int do_merge(QUAD_EDGE ldo, QUAD_EDGE rdo) { - int lvalid; - QUAD_EDGE basel,rcand; - while (1) { - if (!lvalid) { - return (int)basel->next; - } - } -} - diff --git a/test/FrontendC/2002-02-16-RenamingTest.c b/test/FrontendC/2002-02-16-RenamingTest.c deleted file mode 100644 index 6042b67dc0cf..000000000000 --- a/test/FrontendC/2002-02-16-RenamingTest.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* test that locals are renamed with . notation */ - -void abc(void *); - -void Test5(double X) { - abc(&X); - { - int X; - abc(&X); - { - float X; - abc(&X); - } - } -} - diff --git a/test/FrontendC/2002-02-17-ArgumentAddress.c b/test/FrontendC/2002-02-17-ArgumentAddress.c deleted file mode 100644 index acd7e37a7563..000000000000 --- a/test/FrontendC/2002-02-17-ArgumentAddress.c +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -int test(int X) { - return X; -} - -void abc(int *X); -int def(int Y, int Z) { - abc(&Z); - return Y; -} - -struct Test { short X, x; int Y, Z; }; - -int Testing(struct Test *A) { - return A->X+A->Y; -} - -int Test2(int X, struct Test A, int Y) { - return X+Y+A.X+A.Y; -} -int Test3(struct Test A, struct Test B) { - return A.X+A.Y+B.Y+B.Z; -} - -struct Test Test4(struct Test A) { - return A; -} - -int Test6() { - int B[200]; - return B[4]; -} - -struct STest2 { int X; short Y[4]; double Z; }; - -struct STest2 Test7(struct STest2 X) { - return X; -} diff --git a/test/FrontendC/2002-02-18-64bitConstant.c b/test/FrontendC/2002-02-18-64bitConstant.c deleted file mode 100644 index a88587a960de..000000000000 --- a/test/FrontendC/2002-02-18-64bitConstant.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* GCC wasn't handling 64 bit constants right fixed */ - -#include - -int main() { - long long Var = 123455678902ll; - printf("%lld\n", Var); -} diff --git a/test/FrontendC/2002-02-18-StaticData.c b/test/FrontendC/2002-02-18-StaticData.c deleted file mode 100644 index 76cb0e670a7a..000000000000 --- a/test/FrontendC/2002-02-18-StaticData.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -double FOO = 17; -double BAR = 12.0; -float XX = 12.0f; - -static char *procnames[] = { - "EXIT" -}; - -void *Data[] = { &FOO, &BAR, &XX }; - diff --git a/test/FrontendC/2002-03-11-LargeCharInString.c b/test/FrontendC/2002-03-11-LargeCharInString.c deleted file mode 100644 index b383d03f7997..000000000000 --- a/test/FrontendC/2002-03-11-LargeCharInString.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -#include - -int test(char *X) { - /* LLVM-GCC used to emit: - %.LC0 = internal global [3 x sbyte] c"\1F\FFFFFF8B\00" - */ - return strcmp(X, "\037\213"); -} diff --git a/test/FrontendC/2002-03-12-ArrayInitialization.c b/test/FrontendC/2002-03-12-ArrayInitialization.c deleted file mode 100644 index 1997a3cd0d9e..000000000000 --- a/test/FrontendC/2002-03-12-ArrayInitialization.c +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* GCC would generate bad code if not enough initializers are - specified for an array. - */ - -int a[10] = { 0, 2}; - -char str[10] = "x"; - -void *Arr[5] = { 0, 0 }; - -float F[12] = { 1.23f, 34.7f }; - -struct Test { int X; double Y; }; - -struct Test Array[10] = { { 2, 12.0 }, { 3, 24.0 } }; - -int B[4][4] = { { 1, 2, 3, 4}, { 5, 6, 7 }, { 8, 9 } }; diff --git a/test/FrontendC/2002-03-12-StructInitialize.c b/test/FrontendC/2002-03-12-StructInitialize.c deleted file mode 100644 index 9eb11e187a11..000000000000 --- a/test/FrontendC/2002-03-12-StructInitialize.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -typedef struct Connection_Type { - long to; - char type[10]; - long length; -} Connection; - -Connection link[3] -= { {1, "link1", 10}, - {2, "link2", 20}, - {3, "link3", 30} }; - diff --git a/test/FrontendC/2002-03-12-StructInitializer.c b/test/FrontendC/2002-03-12-StructInitializer.c deleted file mode 100644 index fa333b78a95f..000000000000 --- a/test/FrontendC/2002-03-12-StructInitializer.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* GCC was not emitting string constants of the correct length when - * embedded into a structure field like this. It thought the strlength - * was -1. - */ - -typedef struct Connection_Type { - long to; - char type[10]; - long length; -} Connection; - -Connection link[3] -= { {1, "link1", 10}, - {2, "link2", 20}, - {3, "link3", 30} }; - diff --git a/test/FrontendC/2002-03-14-BrokenPHINode.c b/test/FrontendC/2002-03-14-BrokenPHINode.c deleted file mode 100644 index 48d9ab705a72..000000000000 --- a/test/FrontendC/2002-03-14-BrokenPHINode.c +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* GCC was generating PHI nodes with an arity < #pred of the basic block the - * PHI node lived in. This was breaking LLVM because the number of entries - * in a PHI node must equal the number of predecessors for a basic block. - */ - -int trys(char *s, int x) -{ - int asa; - double Val; - int LLS; - if (x) { - asa = LLS + asa; - } else { - } - return asa+(int)Val; -} - diff --git a/test/FrontendC/2002-03-14-BrokenSSA.c b/test/FrontendC/2002-03-14-BrokenSSA.c deleted file mode 100644 index 9dc674aea27f..000000000000 --- a/test/FrontendC/2002-03-14-BrokenSSA.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* This code used to break GCC's SSA computation code. It would create - uses of B & C that are not dominated by their definitions. See: - http://gcc.gnu.org/ml/gcc/2002-03/msg00697.html - */ -int bar(); -int foo() -{ - int a,b,c; - - a = b + c; - b = bar(); - c = bar(); - return a + b + c; -} - diff --git a/test/FrontendC/2002-03-14-QuotesInStrConst.c b/test/FrontendC/2002-03-14-QuotesInStrConst.c deleted file mode 100644 index 63eaeef46a41..000000000000 --- a/test/FrontendC/2002-03-14-QuotesInStrConst.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* GCC was not escaping quotes in string constants correctly, so this would - * get emitted: - * %.LC1 = internal global [32 x sbyte] c"*** Word "%s" on line %d is not\00" - */ - -const char *Foo() { - return "*** Word \"%s\" on line %d is not"; -} diff --git a/test/FrontendC/2002-04-07-SwitchStmt.c b/test/FrontendC/2002-04-07-SwitchStmt.c deleted file mode 100644 index 33e9c3d7a78a..000000000000 --- a/test/FrontendC/2002-04-07-SwitchStmt.c +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -int printf(const char *, ...); -int foo(); - -int main() { - while (foo()) { - switch (foo()) { - case 0: - case 1: - case 2: - case 3: - printf("3"); - case 4: printf("4"); - case 5: - case 6: - default: - break; - } - } - return 0; -} diff --git a/test/FrontendC/2002-04-08-LocalArray.c b/test/FrontendC/2002-04-08-LocalArray.c deleted file mode 100644 index 1dc51a092844..000000000000 --- a/test/FrontendC/2002-04-08-LocalArray.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* GCC is not outputting the static array to the LLVM backend, so bad things - * happen. Note that if this is defined static, everything seems fine. - */ -double test(unsigned X) { - double student_t[30]={0.0 , 12.706 , 4.303 , 3.182 , 2.776 , 2.571 , - 2.447 , 2.365 , 2.306 , 2.262 , 2.228 , - 2.201 , 2.179 , 2.160 , 2.145 , 2.131 , - 2.120 , 2.110 , 2.101 , 2.093 , 2.086 , - 2.080 , 2.074 , 2.069 , 2.064 , 2.060 , - 2.056 , 2.052 , 2.048 , 2.045 }; - return student_t[X]; -} diff --git a/test/FrontendC/2002-04-09-StructRetVal.c b/test/FrontendC/2002-04-09-StructRetVal.c deleted file mode 100644 index de3b6fc26e0a..000000000000 --- a/test/FrontendC/2002-04-09-StructRetVal.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -struct S { - int i; - short s1, s2; -}; - -struct S func_returning_struct(void); - -void loop(void) { - func_returning_struct(); -} diff --git a/test/FrontendC/2002-04-10-StructParameters.c b/test/FrontendC/2002-04-10-StructParameters.c deleted file mode 100644 index aaaba2abdde7..000000000000 --- a/test/FrontendC/2002-04-10-StructParameters.c +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -typedef struct { - char p; - short q; - char r; - int X; - short Y, Z; - int Q; -} foo; - -int test(foo X, float); -int testE(char,short,char,int,int,float); -void test3(foo *X) { - X->q = 1; -} - -void test2(foo Y) { - testE(Y.p, Y.q, Y.r, Y.X, Y.Y, 0.1f); - test(Y, 0.1f); - test2(Y); - test3(&Y); -} - diff --git a/test/FrontendC/2002-05-23-StaticValues.c b/test/FrontendC/2002-05-23-StaticValues.c deleted file mode 100644 index a5753b95f16e..000000000000 --- a/test/FrontendC/2002-05-23-StaticValues.c +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* Make sure the frontend is correctly marking static stuff as internal! */ - -int X; -static int Y = 12; - -static void foo(int Z) { - Y = Z; -} - -void *test() { - foo(12); - return &Y; -} diff --git a/test/FrontendC/2002-05-23-TypeNameCollision.c b/test/FrontendC/2002-05-23-TypeNameCollision.c deleted file mode 100644 index 25d114965d48..000000000000 --- a/test/FrontendC/2002-05-23-TypeNameCollision.c +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* Testcase for when struct tag conflicts with typedef name... grr */ - -typedef struct foo { - struct foo *X; - int Y; -} * foo; - -foo F1; -struct foo *F2; - -enum bar { test1, test2 }; - -typedef float bar; - -enum bar B1; -bar B2; - diff --git a/test/FrontendC/2002-05-24-Alloca.c b/test/FrontendC/2002-05-24-Alloca.c deleted file mode 100644 index 128bc8b7cfc0..000000000000 --- a/test/FrontendC/2002-05-24-Alloca.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -#include -#include -#include - -int main(int argc, char **argv) { - char *C = (char*)alloca(argc); - strcpy(C, argv[0]); - puts(C); -} diff --git a/test/FrontendC/2002-06-25-FWriteInterfaceFailure.c b/test/FrontendC/2002-06-25-FWriteInterfaceFailure.c deleted file mode 100644 index 4380dc7b2279..000000000000 --- a/test/FrontendC/2002-06-25-FWriteInterfaceFailure.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -#include - -void test() { - fprintf(stderr, "testing\n"); -} diff --git a/test/FrontendC/2002-07-14-MiscListTests.c b/test/FrontendC/2002-07-14-MiscListTests.c deleted file mode 100644 index 4a5459ad7131..000000000000 --- a/test/FrontendC/2002-07-14-MiscListTests.c +++ /dev/null @@ -1,71 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -// Test list stuff - -void *malloc(unsigned); - -// Test opaque structure support. the list type is defined later -struct list; - -struct list *PassThroughList(struct list *L) { - return L; -} - - -// Recursive data structure tests... - -typedef struct list { - int Data; - struct list *Next; -} list; - -list *Data; - -void foo() { - static int Foo = 0; // Test static local variable - Foo += 1; // Increment static variable - - Data = (list*)malloc(12); // This is not a proper list allocation -} - -extern list ListNode1; -list ListNode3 = { 4, 0 }; -list ListNode2 = { 3, &ListNode3 }; -list ListNode0 = { 1, &ListNode1 }; -list ListNode1 = { 2, &ListNode2 }; - - -list ListArray[10]; - -// Iterative insert fn -void InsertIntoListTail(list **L, int Data) { - while (*L) - L = &(*L)->Next; - *L = (list*)malloc(sizeof(list)); - (*L)->Data = Data; - (*L)->Next = 0; -} - -// Recursive list search fn -list *FindData(list *L, int Data) { - if (L == 0) return 0; - if (L->Data == Data) return L; - return FindData(L->Next, Data); -} - -void foundIt(void); - -// Driver fn... -void DoListStuff() { - list *MyList = 0; - InsertIntoListTail(&MyList, 100); - InsertIntoListTail(&MyList, 12); - InsertIntoListTail(&MyList, 42); - InsertIntoListTail(&MyList, 1123); - InsertIntoListTail(&MyList, 1213); - - if (FindData(MyList, 75)) foundIt(); - if (FindData(MyList, 42)) foundIt(); - if (FindData(MyList, 700)) foundIt(); -} - diff --git a/test/FrontendC/2002-07-14-MiscTests.c b/test/FrontendC/2002-07-14-MiscTests.c deleted file mode 100644 index 57c412083a6e..000000000000 --- a/test/FrontendC/2002-07-14-MiscTests.c +++ /dev/null @@ -1,57 +0,0 @@ -// RUN: %llvmgcc -w -S %s -o - | llvm-as -o /dev/null - -/* These are random tests that I used when working on the GCC frontend - originally. */ - -// test floating point comparison! -int floatcomptest(double *X, double *Y, float *x, float *y) { - return *X < *Y || *x < *y; -} - -extern void *malloc(unsigned); - -// Exposed a bug -void *memset_impl(void *dstpp, int c, unsigned len) { - long long int dstp = (long long int) dstpp; - - while (dstp % 4 != 0) - { - ((unsigned char *) dstp)[0] = c; - dstp += 1; - len -= 1; - } - return dstpp; -} - -// TEST problem with signed/unsigned versions of the same constants being shared -// incorrectly! -// -static char *temp; -static int remaining; -static char *localmalloc(int size) { - char *blah; - - if (size>remaining) - { - temp = (char *) malloc(32768); - remaining = 32768; - return temp; - } - return 0; -} - -typedef struct { double X; double Y; int Z; } PBVTest; - -PBVTest testRetStruct(float X, double Y, int Z) { - PBVTest T = { X, Y, Z }; - return T; -} -PBVTest testRetStruct2(void); // external func no inlining - - -double CallRetStruct(float X, double Y, int Z) { - PBVTest T = testRetStruct2(); - return T.X+X+Y+Z; -} - - diff --git a/test/FrontendC/2002-07-14-MiscTests2.c b/test/FrontendC/2002-07-14-MiscTests2.c deleted file mode 100644 index f2c7c81c4daa..000000000000 --- a/test/FrontendC/2002-07-14-MiscTests2.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -// Test ?: in function calls -extern fp(int, char*); -char *Ext; -void -__bb_exit_func (void) -{ - fp (12, Ext ? Ext : ""); -} - - diff --git a/test/FrontendC/2002-07-14-MiscTests3.c b/test/FrontendC/2002-07-14-MiscTests3.c deleted file mode 100644 index 7ef7e232d99e..000000000000 --- a/test/FrontendC/2002-07-14-MiscTests3.c +++ /dev/null @@ -1,187 +0,0 @@ -// RUN: %llvmgcc -w -S %s -o - | llvm-as -o /dev/null - - - -void *malloc(unsigned); - -//#include -int puts(const char *s); - -struct FunStructTest { - int Test1; - char *Pointer; - int Array[12]; -}; - -struct SubStruct { - short X, Y; -}; - -struct Quad { - int w; - struct SubStruct SS; - struct SubStruct *SSP; - char c; - int y; -}; - -struct Quad GlobalQuad = { 4, {1, 2}, 0, 3, 156 }; - -typedef int (*FuncPtr)(int); - -unsigned PtrFunc(int (*Func)(int), int X) { - return Func(X); -} - -char PtrFunc2(FuncPtr FuncTab[30], int Num) { - return FuncTab[Num]('b'); -} - -extern char SmallArgs2(char w, char x, long long Zrrk, char y, char z); -extern int SomeFunc(void); -char SmallArgs(char w, char x, char y, char z) { - SomeFunc(); - return SmallArgs2(w-1, x+1, y, z, w); -} - -static int F0(struct Quad Q, int i) { /* Pass Q by value */ - struct Quad R; - if (i) R.SS = Q.SS; - Q.SSP = &R.SS; - Q.w = Q.y = Q.c = 1; - return Q.SS.Y + i + R.y - Q.c; -} - -int F1(struct Quad *Q, int i) { /* Pass Q by address */ - struct Quad R; -#if 0 - if (i) R.SS = Q->SS; -#else - if (i) R = *Q; -#endif - Q->w = Q->y = Q->c = 1; - return Q->SS.Y+i+R.y-Q->c; -} - - -int BadFunc(float Val) { - int Result; - if (Val > 12.345) Result = 4; - return Result; /* Test use of undefined value */ -} - -int RealFunc(void) { - return SomeUndefinedFunction(1, 4, 5); -} - -extern int EF1(int *, char *, int *); - -int Func(int Param, long long Param2) { - int Result = Param; - - {{{{ - char c; int X; - EF1(&Result, &c, &X); - }}} - - { // c & X are duplicate names! - char c; int X; - EF1(&Result, &c, &X); - } - - } - return Result; -} - - -short FunFunc(long long x, char z) { - return x+z; -} - -unsigned castTest(int X) { return X; } - -double TestAdd(double X, float Y) { - return X+Y+.5; -} - -int func(int i, int j) { - while (i != 20) - i += 2; - - j += func(2, i); - return (i * 3 + j*2)*j; -} - -int SumArray(int Array[], int Num) { - int i, Result = 0; - for (i = 0; i < Num; ++i) - Result += Array[i]; - - return Result; -} - -int ArrayParam(int Values[100]) { - return EF1((int*)Values[50], (char*)1, &Values[50]); -} - -int ArrayToSum(void) { - int A[100], i; - for (i = 0; i < 100; ++i) - A[i] = i*4; - - return A[A[0]]; //SumArray(A, 100); -} - - -int ExternFunc(long long, unsigned*, short, unsigned char); - -int main(int argc, char *argv[]) { - unsigned i; - puts("Hello world!\n"); - - ExternFunc(-1, 0, (short)argc, 2); - //func(argc, argc); - - for (i = 0; i < 10; i++) - puts(argv[3]); - return 0; -} - -double MathFunc(double X, double Y, double Z, - double AA, double BB, double CC, double DD, - double EE, double FF, double GG, double HH, - double aAA, double aBB, double aCC, double aDD, - double aEE, double aFF) { - return X + Y + Z + AA + BB + CC + DD + EE + FF + GG + HH - + aAA + aBB + aCC + aDD + aEE + aFF; -} - - - -void strcpy(char *s1, char *s2) { - while (*s1++ = *s2++); -} - -void strcat(char *s1, char *s2) { - while (*s1++); - s1--; - while (*s1++ = *s2++); -} - -int strcmp(char *s1, char *s2) { - while (*s1++ == *s2++); - if (*s1 == 0) { - if (*s2 == 0) { - return 0; - } else { - return -1; - } - } else { - if (*s2 == 0) { - return 1; - } else { - return (*(--s1) - *(--s2)); - } - } -} - diff --git a/test/FrontendC/2002-07-16-HardStringInit.c b/test/FrontendC/2002-07-16-HardStringInit.c deleted file mode 100644 index 2785e5189d9b..000000000000 --- a/test/FrontendC/2002-07-16-HardStringInit.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - char auto_kibitz_list[100][20] = { - {"diepx"}, - {"ferret"}, - {"knightc"}, - {"knightcap"}}; - diff --git a/test/FrontendC/2002-07-17-StringConstant.c b/test/FrontendC/2002-07-17-StringConstant.c deleted file mode 100644 index 9ba0c25213da..000000000000 --- a/test/FrontendC/2002-07-17-StringConstant.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -char * foo() { return "\\begin{"; } diff --git a/test/FrontendC/2002-07-29-Casts.c b/test/FrontendC/2002-07-29-Casts.c deleted file mode 100644 index 44bb61019554..000000000000 --- a/test/FrontendC/2002-07-29-Casts.c +++ /dev/null @@ -1,86 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -#include -#include -#include - -int -main(int argc, char** argv) -{ - char c1; - short s1, ssf1, ssd1; - unsigned char ubs0; - signed char bs0; - unsigned char ubc0, uc2; - unsigned short us2, usf1, usd1; - int ic3, is3, sif1, sid1; - unsigned int uic4, uis4, uif1, uid1; - long slf1, sld1; - unsigned long ulf1, uld1; - float f1; - double d1; - - /* Test integer to integer conversions */ - - c1 = (char) (argc >= 2)? atoi(argv[1]) : 0xff64; /* 100 = 'd' */ - s1 = (short) (argc >= 3)? atoi(argv[2]) : -769; /* 0xf7ff = -769 */ - - ubc0 = (unsigned char) c1; /* 100 = 'd' */ - ubs0 = (unsigned char) s1; /* 0xff = 255 */ - bs0 = (signed char) s1; /* 0xff = -1 */ - - uc2 = (unsigned char) c1; /* 100 = 'd' */ - us2 = (unsigned short) s1; /* 0xf7ff = 64767 */ - - ic3 = (int) c1; /* 100 = 'd' */ - is3 = (int) s1; /* 0xfffff7ff = -769 */ - - uic4 = (unsigned int) c1; /* 100 = 'd' */ - uis4 = (unsigned int) s1; /* 0xfffff7ff = 4294966527 */ - - printf("ubc0 = '%c'\n", ubc0); - printf("ubs0 = %u\n", ubs0); - printf("bs0 = %d\n", bs0); - printf("c1 = '%c'\n", c1); - printf("s1 = %d\n", s1); - printf("uc2 = '%c'\n", uc2); - printf("us2 = %u\n", us2); - printf("ic3 = '%c'\n", ic3); - printf("is3 = %d\n", is3); - printf("uic4 = '%c'\n", uic4); - printf("uis4 = %u\n", uis4); - - /* Test floating-point to integer conversions */ - f1 = (float) (argc >= 4)? atof(argv[3]) : 1.0; - d1 = (argc >= 5)? atof(argv[4]) : 2.0; - - usf1 = (unsigned short) f1; - usd1 = (unsigned short) d1; - uif1 = (unsigned int) f1; - uid1 = (unsigned int) d1; - ulf1 = (unsigned long) f1; - uld1 = (unsigned long) d1; - - ssf1 = (short) f1; - ssd1 = (short) d1; - sif1 = (int) f1; - sid1 = (int) d1; - slf1 = (long) f1; - sld1 = (long) d1; - - printf("usf1 = %u\n", usf1); - printf("usd1 = %u\n", usd1); - printf("uif1 = %u\n", uif1); - printf("uid1 = %u\n", uid1); - printf("ulf1 = %u\n", ulf1); - printf("uld1 = %u\n", uld1); - - printf("ssf1 = %d\n", ssf1); - printf("ssd1 = %d\n", ssd1); - printf("sif1 = %d\n", sif1); - printf("sid1 = %d\n", sid1); - printf("slf1 = %d\n", slf1); - printf("sld1 = %d\n", sld1); - - return 0; -} diff --git a/test/FrontendC/2002-07-30-SubregSetAssertion.c b/test/FrontendC/2002-07-30-SubregSetAssertion.c deleted file mode 100644 index af72eda65242..000000000000 --- a/test/FrontendC/2002-07-30-SubregSetAssertion.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -union X { - void *B; -}; - -union X foo() { - union X A; - A.B = (void*)123; - return A; -} diff --git a/test/FrontendC/2002-07-30-UnionTest.c b/test/FrontendC/2002-07-30-UnionTest.c deleted file mode 100644 index c931b8024f0c..000000000000 --- a/test/FrontendC/2002-07-30-UnionTest.c +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -union X; -struct Empty {}; -union F {}; -union Q { union Q *X; }; -union X { - char C; - int A, Z; - long long B; - void *b1; - struct { int A; long long Z; } Q; -}; - -union X foo(union X A) { - A.C = 123; - A.A = 39249; - //A.B = (void*)123040123321; - A.B = 12301230123123LL; - A.Z = 1; - return A; -} diff --git a/test/FrontendC/2002-07-30-VarArgsCallFailure.c b/test/FrontendC/2002-07-30-VarArgsCallFailure.c deleted file mode 100644 index 5d93947a7273..000000000000 --- a/test/FrontendC/2002-07-30-VarArgsCallFailure.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -int tcount; -void test(char *, const char*, int); -void foo() { - char Buf[10]; - test(Buf, "n%%%d", tcount++); -} diff --git a/test/FrontendC/2002-07-31-BadAssert.c b/test/FrontendC/2002-07-31-BadAssert.c deleted file mode 100644 index 5c3d74cfb6be..000000000000 --- a/test/FrontendC/2002-07-31-BadAssert.c +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -typedef struct -{ - unsigned char type; /* Indicates, NORMAL, SUBNORMAL, etc. */ -} InternalFPF; - - -static void SetInternalFPFZero(InternalFPF *dest) { - dest->type=0; -} - -void denormalize(InternalFPF *ptr) { - SetInternalFPFZero(ptr); -} - diff --git a/test/FrontendC/2002-07-31-SubregFailure.c b/test/FrontendC/2002-07-31-SubregFailure.c deleted file mode 100644 index 72fcb496cb00..000000000000 --- a/test/FrontendC/2002-07-31-SubregFailure.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -typedef union { - long (*ap)[4]; -} ptrs; - -void DoAssignIteration() { - ptrs abase; - abase.ap+=27; - Assignment(*abase.ap); -} - - diff --git a/test/FrontendC/2002-08-02-UnionTest.c b/test/FrontendC/2002-08-02-UnionTest.c deleted file mode 100644 index e2b8c3dd401c..000000000000 --- a/test/FrontendC/2002-08-02-UnionTest.c +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* In this testcase, the return value of foo() is being promotedto a register - * which breaks stuff - */ -#include - -union X { char X; void *B; int a, b, c, d;}; - -union X foo() { - union X Global; - Global.B = (void*)123; /* Interesting part */ - return Global; -} - -int main() { - union X test = foo(); - printf("0x%p", test.B); -} diff --git a/test/FrontendC/2002-08-19-RecursiveLocals.c b/test/FrontendC/2002-08-19-RecursiveLocals.c deleted file mode 100644 index 59220ac9b0d8..000000000000 --- a/test/FrontendC/2002-08-19-RecursiveLocals.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* This testcase doesn't actually test a bug, it's just the result of me - * figuring out the syntax for forward declaring a static variable. */ -struct list { - int x; - struct list *Next; -}; - -static struct list B; /* Forward declare static */ -static struct list A = { 7, &B }; -static struct list B = { 8, &A }; - -extern struct list D; /* forward declare normal var */ - -struct list C = { 7, &D }; -struct list D = { 8, &C }; - diff --git a/test/FrontendC/2002-09-08-PointerShifts.c b/test/FrontendC/2002-09-08-PointerShifts.c deleted file mode 100644 index 86ff2f98afc4..000000000000 --- a/test/FrontendC/2002-09-08-PointerShifts.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -int foo(int *A, unsigned X) { - return A[X]; -} diff --git a/test/FrontendC/2002-09-18-UnionProblem.c b/test/FrontendC/2002-09-18-UnionProblem.c deleted file mode 100644 index 54588f12142a..000000000000 --- a/test/FrontendC/2002-09-18-UnionProblem.c +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -struct DWstruct { - char high, low; -}; - -typedef union { - struct DWstruct s; - short ll; -} DWunion; - -short __udivmodhi4 (char n1, char bm) { - DWunion rr; - - if (bm == 0) - { - rr.s.high = n1; - } - else - { - rr.s.high = bm; - } - - return rr.ll; -} diff --git a/test/FrontendC/2002-09-19-StarInLabel.c b/test/FrontendC/2002-09-19-StarInLabel.c deleted file mode 100644 index 171acca2f118..000000000000 --- a/test/FrontendC/2002-09-19-StarInLabel.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -extern void start() __asm__("start"); -extern void _start() __asm__("_start"); -extern void __start() __asm__("__start"); -void start() {} -void _start() {} -void __start() {} - diff --git a/test/FrontendC/2002-10-12-TooManyArguments.c b/test/FrontendC/2002-10-12-TooManyArguments.c deleted file mode 100644 index 73c267ad30dd..000000000000 --- a/test/FrontendC/2002-10-12-TooManyArguments.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -void foo() {} - -void bar() { - foo(1, 2, 3); /* Too many arguments passed */ -} diff --git a/test/FrontendC/2002-12-15-GlobalBoolTest.c b/test/FrontendC/2002-12-15-GlobalBoolTest.c deleted file mode 100644 index c27a23abc6ec..000000000000 --- a/test/FrontendC/2002-12-15-GlobalBoolTest.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -_Bool X = 0; - diff --git a/test/FrontendC/2002-12-15-GlobalConstantTest.c b/test/FrontendC/2002-12-15-GlobalConstantTest.c deleted file mode 100644 index 26de48fbb77f..000000000000 --- a/test/FrontendC/2002-12-15-GlobalConstantTest.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -const char *W = "foo"; -const int X = 7; -int Y = 8; -const char * const Z = "bar"; - diff --git a/test/FrontendC/2002-12-15-GlobalRedefinition.c b/test/FrontendC/2002-12-15-GlobalRedefinition.c deleted file mode 100644 index 3b76953b0940..000000000000 --- a/test/FrontendC/2002-12-15-GlobalRedefinition.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -extern char algbrfile[9]; -char algbrfile[9] = "abcdefgh"; - diff --git a/test/FrontendC/2002-12-15-StructParameters.c b/test/FrontendC/2002-12-15-StructParameters.c deleted file mode 100644 index 90ab1ff44044..000000000000 --- a/test/FrontendC/2002-12-15-StructParameters.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -typedef struct -{ - void *stack; - unsigned size; - unsigned avail; -} compile_stack_type; - -void foo(void*); -void bar(compile_stack_type T, unsigned); - -void test() { - compile_stack_type CST; - foo(&CST); - - bar(CST, 12); -} diff --git a/test/FrontendC/2003-01-30-UnionInit.c b/test/FrontendC/2003-01-30-UnionInit.c deleted file mode 100644 index 576958442aec..000000000000 --- a/test/FrontendC/2003-01-30-UnionInit.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -o /dev/null - -union foo { - struct { char A, B; } X; - int C; -}; - -union foo V = { {1, 2} }; diff --git a/test/FrontendC/2003-03-03-DeferredType.c b/test/FrontendC/2003-03-03-DeferredType.c deleted file mode 100644 index 9e60df6f6a0a..000000000000 --- a/test/FrontendC/2003-03-03-DeferredType.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - - - -struct foo A; - -struct foo { - int x; -double D; -}; - diff --git a/test/FrontendC/2003-06-22-UnionCrash.c b/test/FrontendC/2003-06-22-UnionCrash.c deleted file mode 100644 index 54d8dc6dda9a..000000000000 --- a/test/FrontendC/2003-06-22-UnionCrash.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -struct Blend_Map_Entry { - union { - float Colour[5]; - double Point_Slope[2]; - } Vals; -}; - -void test(struct Blend_Map_Entry* Foo) -{ -} - diff --git a/test/FrontendC/2003-06-23-GCC-fold-infinite-recursion.c b/test/FrontendC/2003-06-23-GCC-fold-infinite-recursion.c deleted file mode 100644 index 80562c8849b0..000000000000 --- a/test/FrontendC/2003-06-23-GCC-fold-infinite-recursion.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -double Test(double A, double B, double C, double D) { - return -(A-B) - (C-D); -} - diff --git a/test/FrontendC/2003-06-26-CFECrash.c b/test/FrontendC/2003-06-26-CFECrash.c deleted file mode 100644 index 10a7ed44458f..000000000000 --- a/test/FrontendC/2003-06-26-CFECrash.c +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -typedef struct min_info { - long offset; - unsigned file_attr; -} min_info; - -typedef struct Globals { - char answerbuf; - min_info info[1]; - min_info *pInfo; -} Uz_Globs; - -extern Uz_Globs G; - -int extract_or_test_files() { - G.pInfo = G.info; -} - diff --git a/test/FrontendC/2003-06-29-MultipleFunctionDefinition.c b/test/FrontendC/2003-06-29-MultipleFunctionDefinition.c deleted file mode 100644 index be042cedf9fd..000000000000 --- a/test/FrontendC/2003-06-29-MultipleFunctionDefinition.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -/* This is apparently legal C. - */ -extern __inline__ void test() { } - -void test() { -} diff --git a/test/FrontendC/2003-07-22-ArrayAccessTypeSafety.c b/test/FrontendC/2003-07-22-ArrayAccessTypeSafety.c deleted file mode 100644 index 51e66c9b8395..000000000000 --- a/test/FrontendC/2003-07-22-ArrayAccessTypeSafety.c +++ /dev/null @@ -1,7 +0,0 @@ -/* RUN: %llvmgcc -xc %s -S -o - | grep -v alloca | not grep bitcast - */ - -void test(int* array, long long N) { - array[N] = N[array] = 33; -} - diff --git a/test/FrontendC/2003-08-06-BuiltinSetjmpLongjmp.c b/test/FrontendC/2003-08-06-BuiltinSetjmpLongjmp.c deleted file mode 100644 index 12b4f7b93329..000000000000 --- a/test/FrontendC/2003-08-06-BuiltinSetjmpLongjmp.c +++ /dev/null @@ -1,14 +0,0 @@ -/* RUN: %llvmgcc -xc %s -S -o - | not grep __builtin_ - * - * __builtin_longjmp/setjmp should get transformed into llvm.setjmp/longjmp - * just like explicit setjmp/longjmp calls are. - */ - -void jumpaway(int *ptr) { - __builtin_longjmp(ptr,1); -} - -int main(void) { - __builtin_setjmp(0); - jumpaway(0); -} diff --git a/test/FrontendC/2003-08-17-DeadCodeShortCircuit.c b/test/FrontendC/2003-08-17-DeadCodeShortCircuit.c deleted file mode 100644 index 9ae633ee0812..000000000000 --- a/test/FrontendC/2003-08-17-DeadCodeShortCircuit.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o %t.o - -int test(_Bool pos, _Bool color) { - return 0; - return (pos && color); -} - diff --git a/test/FrontendC/2003-08-18-SigSetJmp.c b/test/FrontendC/2003-08-18-SigSetJmp.c deleted file mode 100644 index fc0d7659de6d..000000000000 --- a/test/FrontendC/2003-08-18-SigSetJmp.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -#include - -sigjmp_buf B; -int foo() { - sigsetjmp(B, 1); - bar(); -} diff --git a/test/FrontendC/2003-08-18-StructAsValue.c b/test/FrontendC/2003-08-18-StructAsValue.c deleted file mode 100644 index 26cb78a4d243..000000000000 --- a/test/FrontendC/2003-08-18-StructAsValue.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -typedef struct { - int op; -} event_t; - -event_t test(int X) { - event_t foo = { 1 }, bar = { 2 }; - return X ? foo : bar; -} diff --git a/test/FrontendC/2003-08-20-BadBitfieldRef.c b/test/FrontendC/2003-08-20-BadBitfieldRef.c deleted file mode 100644 index ef54d8ad9c0d..000000000000 --- a/test/FrontendC/2003-08-20-BadBitfieldRef.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -void foo() -{ - char *ap; - ap[1] == '-' && ap[2] == 0; -} - diff --git a/test/FrontendC/2003-08-20-PrototypeMismatch.c b/test/FrontendC/2003-08-20-PrototypeMismatch.c deleted file mode 100644 index 85c89f694c57..000000000000 --- a/test/FrontendC/2003-08-20-PrototypeMismatch.c +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - - -static int foo(int); - -static int foo(C) -char C; -{ - return C; -} - -void test() { - foo(7); -} diff --git a/test/FrontendC/2003-08-20-vfork-bug.c b/test/FrontendC/2003-08-20-vfork-bug.c deleted file mode 100644 index cfe316162ad3..000000000000 --- a/test/FrontendC/2003-08-20-vfork-bug.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -extern int vfork(void); -test() { - vfork(); -} diff --git a/test/FrontendC/2003-08-21-BinOp-Type-Mismatch.c b/test/FrontendC/2003-08-21-BinOp-Type-Mismatch.c deleted file mode 100644 index a1d4574dcdb1..000000000000 --- a/test/FrontendC/2003-08-21-BinOp-Type-Mismatch.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -struct bar; - -void foo() -{ - unsigned int frame, focus; - (struct bar *) focus == (focus ? ((struct bar *) frame) : 0); -} - diff --git a/test/FrontendC/2003-08-21-StmtExpr.c b/test/FrontendC/2003-08-21-StmtExpr.c deleted file mode 100644 index 7f7d22ea9d7b..000000000000 --- a/test/FrontendC/2003-08-21-StmtExpr.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -typedef struct { - unsigned long val; -} structty; - -void bar(structty new_mask); -static void foo() { - bar(({ structty mask; mask; })); -} - diff --git a/test/FrontendC/2003-08-21-WideString.c b/test/FrontendC/2003-08-21-WideString.c deleted file mode 100644 index bf67a21896b0..000000000000 --- a/test/FrontendC/2003-08-21-WideString.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -#include - -struct { - wchar_t *name; -} syms = { L"NUL" }; diff --git a/test/FrontendC/2003-08-23-LocalUnionTest.c b/test/FrontendC/2003-08-23-LocalUnionTest.c deleted file mode 100644 index 987accca1cc1..000000000000 --- a/test/FrontendC/2003-08-23-LocalUnionTest.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - - -union foo { int X; }; - -int test(union foo* F) { - { - union foo { float X; } A; - } -} diff --git a/test/FrontendC/2003-08-29-BitFieldStruct.c b/test/FrontendC/2003-08-29-BitFieldStruct.c deleted file mode 100644 index 57273cd86393..000000000000 --- a/test/FrontendC/2003-08-29-BitFieldStruct.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -struct Word { - short bar; - short baz; - int final:1; - short quux; -} *word_limit; - -void foo () -{ - word_limit->final = (word_limit->final && word_limit->final); -} diff --git a/test/FrontendC/2003-08-29-HugeCharConst.c b/test/FrontendC/2003-08-29-HugeCharConst.c deleted file mode 100644 index 236eb2e27482..000000000000 --- a/test/FrontendC/2003-08-29-HugeCharConst.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -void foo() { - unsigned char int_latin1[] = "f\200\372b\200\343\200\340"; -} diff --git a/test/FrontendC/2003-08-29-StructLayoutBug.c b/test/FrontendC/2003-08-29-StructLayoutBug.c deleted file mode 100644 index 16731945b77c..000000000000 --- a/test/FrontendC/2003-08-29-StructLayoutBug.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -struct foo { - unsigned int I:1; - unsigned char J[1]; - unsigned int K:1; - }; - -void test(struct foo *X) {} - diff --git a/test/FrontendC/2003-08-30-AggregateInitializer.c b/test/FrontendC/2003-08-30-AggregateInitializer.c deleted file mode 100644 index 58c77b6aa04f..000000000000 --- a/test/FrontendC/2003-08-30-AggregateInitializer.c +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgcc -S %s -o /dev/null - -struct istruct { - unsigned char C; -}; - -struct foo { - unsigned int I:1; - struct istruct J; - unsigned char L[1]; - unsigned int K:1; -}; - -struct foo F = { 1, { 7 }, { 123 } , 1 }; - - diff --git a/test/FrontendC/2003-08-30-LargeIntegerBitfieldMember.c b/test/FrontendC/2003-08-30-LargeIntegerBitfieldMember.c deleted file mode 100644 index e1ca88cdc6f1..000000000000 --- a/test/FrontendC/2003-08-30-LargeIntegerBitfieldMember.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -struct foo { - unsigned int I:1; - unsigned char J[1][123]; - unsigned int K:1; - }; - -struct foo F; diff --git a/test/FrontendC/2003-09-18-BitfieldTests.c b/test/FrontendC/2003-09-18-BitfieldTests.c deleted file mode 100644 index 2d74cb401dc2..000000000000 --- a/test/FrontendC/2003-09-18-BitfieldTests.c +++ /dev/null @@ -1,30 +0,0 @@ -// RUN: %llvmgcc -w -S %s -o - | llvm-as -o /dev/null - - -typedef struct BF { - int A : 1; - char B; - int C : 13; -} BF; - -char *test1(BF *b) { - return &b->B; // Must be able to address non-bitfield -} - -void test2(BF *b) { // Increment and decrement operators - b->A++; - --b->C; -} - -void test3(BF *b) { - b->C = 12345; // Store -} - -int test4(BF *b) { - return b->C; // Load -} - -void test5(BF *b, int i) { // array ref - b[i].C = 12345; -} - diff --git a/test/FrontendC/2003-09-30-StructLayout.c b/test/FrontendC/2003-09-30-StructLayout.c deleted file mode 100644 index 177d1f49b2fb..000000000000 --- a/test/FrontendC/2003-09-30-StructLayout.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -enum En { - ENUM_VAL -}; - -struct St { - unsigned char A; - enum En B; - unsigned char C; - enum En D; - float E; -}; - - -void func(struct St* A) { - A->D = ENUM_VAL; -} diff --git a/test/FrontendC/2003-10-02-UnionLValueError.c b/test/FrontendC/2003-10-02-UnionLValueError.c deleted file mode 100644 index a4d17a4a0ba5..000000000000 --- a/test/FrontendC/2003-10-02-UnionLValueError.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -#include - -union U{ - int i[8]; - char s[80]; -}; - -void format_message(char *buffer, union U *u) { - sprintf(buffer, u->s); -} - diff --git a/test/FrontendC/2003-10-06-NegateExprType.c b/test/FrontendC/2003-10-06-NegateExprType.c deleted file mode 100644 index fb8329b344b3..000000000000 --- a/test/FrontendC/2003-10-06-NegateExprType.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -extern int A[10]; -void Func(int *B) { - B - &A[5]; -} - diff --git a/test/FrontendC/2003-10-09-UnionInitializerBug.c b/test/FrontendC/2003-10-09-UnionInitializerBug.c deleted file mode 100644 index 57e113a7cc29..000000000000 --- a/test/FrontendC/2003-10-09-UnionInitializerBug.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -struct Foo { - unsigned a; - unsigned b; - unsigned c; -}; - -struct Bar { - union { - void **a; - struct Foo b; - }u; -}; - -struct Bar test = {0}; - diff --git a/test/FrontendC/2003-10-28-ident.c b/test/FrontendC/2003-10-28-ident.c deleted file mode 100644 index 06cacf87a907..000000000000 --- a/test/FrontendC/2003-10-28-ident.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -#ident "foo" diff --git a/test/FrontendC/2003-10-29-AsmRename.c b/test/FrontendC/2003-10-29-AsmRename.c deleted file mode 100644 index d07ccf7fd2c2..000000000000 --- a/test/FrontendC/2003-10-29-AsmRename.c +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -struct foo { int X; }; -struct bar { int Y; }; - -extern int Func(struct foo*) __asm__("Func64"); -extern int Func64(struct bar*); - -int Func(struct foo *F) { - return 1; -} - -int Func64(struct bar* B) { - return 0; -} - - -int test() { - Func(0); /* should be renamed to call Func64 */ - Func64(0); -} diff --git a/test/FrontendC/2003-11-01-C99-CompoundLiteral.c b/test/FrontendC/2003-11-01-C99-CompoundLiteral.c deleted file mode 100644 index 2912c97c546a..000000000000 --- a/test/FrontendC/2003-11-01-C99-CompoundLiteral.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -typedef struct { int foo; } spinlock_t; -typedef struct wait_queue_head_t { spinlock_t lock; } wait_queue_head_t; -void call_usermodehelper(void) { - struct wait_queue_head_t work = { lock: (spinlock_t) { 0 }, }; -} - diff --git a/test/FrontendC/2003-11-01-EmptyStructCrash.c b/test/FrontendC/2003-11-01-EmptyStructCrash.c deleted file mode 100644 index c1161195dafc..000000000000 --- a/test/FrontendC/2003-11-01-EmptyStructCrash.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -typedef struct { } the_coolest_struct_in_the_world; -extern the_coolest_struct_in_the_world xyzzy; -void *foo() { return &xyzzy; } - diff --git a/test/FrontendC/2003-11-01-GlobalUnionInit.c b/test/FrontendC/2003-11-01-GlobalUnionInit.c deleted file mode 100644 index 7cd707348ca3..000000000000 --- a/test/FrontendC/2003-11-01-GlobalUnionInit.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -union bdflush_param { - struct { int x; } b_un; - int y[1]; -} bdf_prm = {{30}}; - diff --git a/test/FrontendC/2003-11-03-AddrArrayElement.c b/test/FrontendC/2003-11-03-AddrArrayElement.c deleted file mode 100644 index 4337da7d1e43..000000000000 --- a/test/FrontendC/2003-11-03-AddrArrayElement.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o - | grep getelementptr - -// This should be turned into a tasty getelementptr instruction, not a nasty -// series of casts and address arithmetic. - -char Global[100]; - -char *test1(unsigned i) { - return &Global[i]; -} - diff --git a/test/FrontendC/2003-11-04-EmptyStruct.c b/test/FrontendC/2003-11-04-EmptyStruct.c deleted file mode 100644 index b4f37befffa0..000000000000 --- a/test/FrontendC/2003-11-04-EmptyStruct.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -typedef struct { } rwlock_t; -struct fs_struct { rwlock_t lock; int umask; }; -void __copy_fs_struct(struct fs_struct *fs) { fs->lock = (rwlock_t) { }; } - diff --git a/test/FrontendC/2003-11-04-OutOfMemory.c b/test/FrontendC/2003-11-04-OutOfMemory.c deleted file mode 100644 index 40cb6c2e21e4..000000000000 --- a/test/FrontendC/2003-11-04-OutOfMemory.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -void schedule_timeout(signed long timeout) -{ - switch (timeout) - { - case ((long)(~0UL>>1)): break; - } -} diff --git a/test/FrontendC/2003-11-08-PointerSubNotGetelementptr.c b/test/FrontendC/2003-11-08-PointerSubNotGetelementptr.c deleted file mode 100644 index 58f9f82e1543..000000000000 --- a/test/FrontendC/2003-11-08-PointerSubNotGetelementptr.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o - | grep getelementptr - -char *test(char* C) { - return C-1; // Should turn into a GEP -} - -int *test2(int* I) { - return I-1; -} diff --git a/test/FrontendC/2003-11-12-VoidString.c b/test/FrontendC/2003-11-12-VoidString.c deleted file mode 100644 index 5770b3661a96..000000000000 --- a/test/FrontendC/2003-11-12-VoidString.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -void query_newnamebuf(void) { ((void)"query_newnamebuf"); } - diff --git a/test/FrontendC/2003-11-13-TypeSafety.c b/test/FrontendC/2003-11-13-TypeSafety.c deleted file mode 100644 index 9b76bb11c984..000000000000 --- a/test/FrontendC/2003-11-13-TypeSafety.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o - | grep getelementptr - -int *test(int *X, int Y) { - return X + Y; -} diff --git a/test/FrontendC/2003-11-16-StaticArrayInit.c b/test/FrontendC/2003-11-16-StaticArrayInit.c deleted file mode 100644 index eb83b3ad0c61..000000000000 --- a/test/FrontendC/2003-11-16-StaticArrayInit.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -void bar () { - static char x[10]; - static char *xend = x + 10; -} - - diff --git a/test/FrontendC/2003-11-18-CondExprLValue.c b/test/FrontendC/2003-11-18-CondExprLValue.c deleted file mode 100644 index 68ee622c6419..000000000000 --- a/test/FrontendC/2003-11-18-CondExprLValue.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -typedef struct { unsigned long pgprot; } pgprot_t; - -void split_large_page(unsigned long addr, pgprot_t prot) -{ - (addr ? prot : ((pgprot_t) { 0x001 } )).pgprot; -} - diff --git a/test/FrontendC/2003-11-19-AddressOfRegister.c b/test/FrontendC/2003-11-19-AddressOfRegister.c deleted file mode 100644 index 69dc54d9289c..000000000000 --- a/test/FrontendC/2003-11-19-AddressOfRegister.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o /dev/null |& not grep warning - -struct item { - short delta[4]; -}; - -int TEST(int nt) { - register struct item *aa; - aa[nt].delta; - return 1; -} - diff --git a/test/FrontendC/2003-11-19-BitFieldArray.c b/test/FrontendC/2003-11-19-BitFieldArray.c deleted file mode 100644 index 250268a3b859..000000000000 --- a/test/FrontendC/2003-11-19-BitFieldArray.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -struct _GIOChannel { - int write_buf; - char partial_write_buf[6]; - int d :1; -}; - -void g_io_channel_init (struct _GIOChannel *channel) { - channel->partial_write_buf[0]; -} - diff --git a/test/FrontendC/2003-11-20-Bitfields.c b/test/FrontendC/2003-11-20-Bitfields.c deleted file mode 100644 index 4be9942ccf3c..000000000000 --- a/test/FrontendC/2003-11-20-Bitfields.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -struct face_cachel { - unsigned int reverse :1; - unsigned char font_specified[1]; -}; - -void -ensure_face_cachel_contains_charset (struct face_cachel *cachel) { - cachel->font_specified[0] = 0; -} - diff --git a/test/FrontendC/2003-11-20-ComplexDivision.c b/test/FrontendC/2003-11-20-ComplexDivision.c deleted file mode 100644 index 172de8c0e192..000000000000 --- a/test/FrontendC/2003-11-20-ComplexDivision.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -int test() { - __complex__ double C; - double D; - C / D; -} diff --git a/test/FrontendC/2003-11-20-UnionBitfield.c b/test/FrontendC/2003-11-20-UnionBitfield.c deleted file mode 100644 index f999c2077721..000000000000 --- a/test/FrontendC/2003-11-20-UnionBitfield.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -struct printf_spec { - unsigned int minus_flag:1; - char converter; -}; - -void parse_doprnt_spec () { - struct printf_spec spec; - spec.minus_flag = 1; -} - diff --git a/test/FrontendC/2003-11-26-PointerShift.c b/test/FrontendC/2003-11-26-PointerShift.c deleted file mode 100644 index 6b5205a6e7ed..000000000000 --- a/test/FrontendC/2003-11-26-PointerShift.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -unsigned long do_csum(const unsigned char *buff, int len, unsigned long result) { - if (2 & (unsigned long) buff) result += 1; - return result; -} diff --git a/test/FrontendC/2003-11-27-ConstructorCast.c b/test/FrontendC/2003-11-27-ConstructorCast.c deleted file mode 100644 index 15eb76947951..000000000000 --- a/test/FrontendC/2003-11-27-ConstructorCast.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -struct i387_soft_struct { - long cwd; -}; -union i387_union { - struct i387_soft_struct soft; -}; -struct thread_struct { - union i387_union i387; -}; -void _init_task_union(void) { - struct thread_struct thread = (struct thread_struct) { {{0}} }; -} diff --git a/test/FrontendC/2003-11-27-UnionCtorInitialization.c b/test/FrontendC/2003-11-27-UnionCtorInitialization.c deleted file mode 100644 index e3ae1e96a682..000000000000 --- a/test/FrontendC/2003-11-27-UnionCtorInitialization.c +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -struct i387_soft_struct { - long cwd; - long twd; - long fip; -}; -union i387_union { - struct i387_soft_struct soft; -}; -struct thread_struct { - union i387_union i387; -}; -void _init_task_union(void) { - struct thread_struct thread = (struct thread_struct) { {{0}} }; -} diff --git a/test/FrontendC/2003-12-14-ExternInlineSupport.c b/test/FrontendC/2003-12-14-ExternInlineSupport.c deleted file mode 100644 index a45eb98dca2a..000000000000 --- a/test/FrontendC/2003-12-14-ExternInlineSupport.c +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o - | not grep dead_function - -extern __inline__ void dead_function() {} diff --git a/test/FrontendC/2004-01-01-UnknownInitSize.c b/test/FrontendC/2004-01-01-UnknownInitSize.c deleted file mode 100644 index b26b6cd87560..000000000000 --- a/test/FrontendC/2004-01-01-UnknownInitSize.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -S %s -o /dev/null - -/* - * This regression test ensures that the C front end can compile initializers - * even when it cannot determine the size (as below). -*/ -struct one -{ - int a; - int values []; -}; - -struct one hobbit = {5, {1, 2, 3}}; - diff --git a/test/FrontendC/2004-01-08-ExternInlineRedefine.c b/test/FrontendC/2004-01-08-ExternInlineRedefine.c deleted file mode 100644 index 4366b9b56593..000000000000 --- a/test/FrontendC/2004-01-08-ExternInlineRedefine.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -extern __inline long int -__strtol_l (int a) -{ - return 0; -} - -long int -__strtol_l (int a) -{ - return 0; -} diff --git a/test/FrontendC/2004-02-12-LargeAggregateCopy.c b/test/FrontendC/2004-02-12-LargeAggregateCopy.c deleted file mode 100644 index 93b7fe44bf60..000000000000 --- a/test/FrontendC/2004-02-12-LargeAggregateCopy.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o - | grep llvm.memcpy - -struct X { int V[10000]; }; -struct X Global1, Global2; -void test() { - Global2 = Global1; -} - diff --git a/test/FrontendC/2004-02-13-BuiltinFrameReturnAddress.c b/test/FrontendC/2004-02-13-BuiltinFrameReturnAddress.c deleted file mode 100644 index f115b5a5f013..000000000000 --- a/test/FrontendC/2004-02-13-BuiltinFrameReturnAddress.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o - | grep llvm.*address | count 4 - -void *test1() { - return __builtin_return_address(1); -} -void *test2() { - return __builtin_frame_address(0); -} diff --git a/test/FrontendC/2004-02-13-IllegalVararg.c b/test/FrontendC/2004-02-13-IllegalVararg.c deleted file mode 100644 index 0d003c8033ca..000000000000 --- a/test/FrontendC/2004-02-13-IllegalVararg.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %llvmgcc -xc %s -w -S -o - | llc -// XFAIL: * -// See PR2452 - -#include - -float test(int X, ...) { - va_list ap; - float F; - va_start(ap, X); - F = va_arg(ap, float); - return F; -} diff --git a/test/FrontendC/2004-02-13-Memset.c b/test/FrontendC/2004-02-13-Memset.c deleted file mode 100644 index fb6ed2352ea3..000000000000 --- a/test/FrontendC/2004-02-13-Memset.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o - | grep llvm.memset | count 3 - -void *memset(void*, int, long); -void bzero(void*, long); - -void test(int* X, char *Y) { - memset(X, 4, 1000); - bzero(Y, 100); -} diff --git a/test/FrontendC/2004-02-14-ZeroInitializer.c b/test/FrontendC/2004-02-14-ZeroInitializer.c deleted file mode 100644 index bede9078741f..000000000000 --- a/test/FrontendC/2004-02-14-ZeroInitializer.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o - | grep zeroinitializer - -int X[1000]; - diff --git a/test/FrontendC/2004-02-20-Builtins.c b/test/FrontendC/2004-02-20-Builtins.c deleted file mode 100644 index c056a8405f73..000000000000 --- a/test/FrontendC/2004-02-20-Builtins.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -O3 -xc %s -S -o - | not grep builtin - -#include - -void zsqrtxxx(float num) { - num = sqrt(num); -} - diff --git a/test/FrontendC/2004-03-07-ComplexDivEquals.c b/test/FrontendC/2004-03-07-ComplexDivEquals.c deleted file mode 100644 index c6c805a7b32c..000000000000 --- a/test/FrontendC/2004-03-07-ComplexDivEquals.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -void test(__complex__ double D, double X) { - D /= X; -} diff --git a/test/FrontendC/2004-03-07-ExternalConstant.c b/test/FrontendC/2004-03-07-ExternalConstant.c deleted file mode 100644 index 4a9094bdf344..000000000000 --- a/test/FrontendC/2004-03-07-ExternalConstant.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o - | grep constant - -extern const int a[]; // 'a' should be marked constant even though it's external! -int foo () { - return a[0]; -} - diff --git a/test/FrontendC/2004-03-09-LargeArrayInitializers.c b/test/FrontendC/2004-03-09-LargeArrayInitializers.c deleted file mode 100644 index 265206fabb66..000000000000 --- a/test/FrontendC/2004-03-09-LargeArrayInitializers.c +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -// Test that these initializers are handled efficiently - -int test(int x) { - const int XX[1000] = { 0, 0 }; - const char S [1000] = "foo"; - - const int array[] = { - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, 17, 23, 123, 123, 49, - }; - return array[x]; -} diff --git a/test/FrontendC/2004-03-15-SimpleIndirectGoto.c b/test/FrontendC/2004-03-15-SimpleIndirectGoto.c deleted file mode 100644 index a3f27b2a3301..000000000000 --- a/test/FrontendC/2004-03-15-SimpleIndirectGoto.c +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -int code[]={0,0,0,0,1}; -void foo(int x) { - volatile int b; - b = 0xffffffff; -} -void bar(int *pc) { - static const void *l[] = {&&lab0, &&end}; - - foo(0); - goto *l[*pc]; - lab0: - foo(0); - pc++; - goto *l[*pc]; - end: - return; -} -int main() { - bar(code); - return 0; -} diff --git a/test/FrontendC/2004-03-16-AsmRegisterCrash.c b/test/FrontendC/2004-03-16-AsmRegisterCrash.c deleted file mode 100644 index f13368c25627..000000000000 --- a/test/FrontendC/2004-03-16-AsmRegisterCrash.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -int foo() { -#ifdef __ppc__ - register int X __asm__("r1"); -#else - register int X __asm__("ebx"); -#endif - return X; -} diff --git a/test/FrontendC/2004-05-07-VarArrays.c b/test/FrontendC/2004-05-07-VarArrays.c deleted file mode 100644 index 3a39c4fe63aa..000000000000 --- a/test/FrontendC/2004-05-07-VarArrays.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -int foo(int len, char arr[][len], int X) { - return arr[X][0]; -} diff --git a/test/FrontendC/2004-05-21-IncompleteEnum.c b/test/FrontendC/2004-05-21-IncompleteEnum.c deleted file mode 100644 index 958a8d1c0ea1..000000000000 --- a/test/FrontendC/2004-05-21-IncompleteEnum.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc -w -S %s -o - | llvm-as -o /dev/null - -void test(enum foo *X) { -} - diff --git a/test/FrontendC/2004-06-08-OpaqueStructArg.c b/test/FrontendC/2004-06-08-OpaqueStructArg.c deleted file mode 100644 index 5dfdd83c9e2a..000000000000 --- a/test/FrontendC/2004-06-08-OpaqueStructArg.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - struct fu; - void foo(struct fu); - void bar() { - foo; - } diff --git a/test/FrontendC/2004-06-17-UnorderedBuiltins.c b/test/FrontendC/2004-06-17-UnorderedBuiltins.c deleted file mode 100644 index 02780f0f0577..000000000000 --- a/test/FrontendC/2004-06-17-UnorderedBuiltins.c +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -_Bool A, B, C, D, E, F, G, H; -void TestF(float X, float Y) { - A = __builtin_isgreater(X, Y); - B = __builtin_isgreaterequal(X, Y); - C = __builtin_isless(X, Y); - D = __builtin_islessequal(X, Y); - E = __builtin_islessgreater(X, Y); - F = __builtin_isunordered(X, Y); - //G = __builtin_isordered(X, Y); // Our current snapshot of GCC doesn't include this builtin - H = __builtin_isunordered(X, Y); -} -void TestD(double X, double Y) { - A = __builtin_isgreater(X, Y); - B = __builtin_isgreaterequal(X, Y); - C = __builtin_isless(X, Y); - D = __builtin_islessequal(X, Y); - E = __builtin_islessgreater(X, Y); - F = __builtin_isunordered(X, Y); - //G = __builtin_isordered(X, Y); // Our current snapshot doesn't include this builtin. FIXME - H = __builtin_isunordered(X, Y); -} diff --git a/test/FrontendC/2004-06-17-UnorderedCompares.c b/test/FrontendC/2004-06-17-UnorderedCompares.c deleted file mode 100644 index 286e7bc7cf70..000000000000 --- a/test/FrontendC/2004-06-17-UnorderedCompares.c +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %llvmgcc -xc -std=c99 %s -S -o - | grep -v llvm.isunordered | not grep call - -#include - -_Bool A, B, C, D, E, F; -void TestF(float X, float Y) { - A = __builtin_isgreater(X, Y); - B = __builtin_isgreaterequal(X, Y); - C = __builtin_isless(X, Y); - D = __builtin_islessequal(X, Y); - E = __builtin_islessgreater(X, Y); - F = __builtin_isunordered(X, Y); -} -void TestD(double X, double Y) { - A = __builtin_isgreater(X, Y); - B = __builtin_isgreaterequal(X, Y); - C = __builtin_isless(X, Y); - D = __builtin_islessequal(X, Y); - E = __builtin_islessgreater(X, Y); - F = __builtin_isunordered(X, Y); -} diff --git a/test/FrontendC/2004-06-18-VariableLengthArrayOfStructures.c b/test/FrontendC/2004-06-18-VariableLengthArrayOfStructures.c deleted file mode 100644 index 3e450a4b9366..000000000000 --- a/test/FrontendC/2004-06-18-VariableLengthArrayOfStructures.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -struct S { }; - -int xxxx(int a) { - struct S comps[a]; - comps[0]; -} - diff --git a/test/FrontendC/2004-07-06-FunctionCast.c b/test/FrontendC/2004-07-06-FunctionCast.c deleted file mode 100644 index 6d80f86fa1eb..000000000000 --- a/test/FrontendC/2004-07-06-FunctionCast.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -static int unused_func(void) { - return 1; -} - -int foo(void) { - (void)unused_func; /* avoid compiler warning */ - return 2; -} diff --git a/test/FrontendC/2004-08-06-LargeStructTest.c b/test/FrontendC/2004-08-06-LargeStructTest.c deleted file mode 100644 index 8fbb7f8368c4..000000000000 --- a/test/FrontendC/2004-08-06-LargeStructTest.c +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - - -#define A(X) int X; -#define B(X) A(X##0) A(X##1) A(X##2) A(X##3) A(X##4) A(X##5) A(X##6) A(X##7) \ - A(X##8) A(X##9) A(X##A) A(X##B) A(X##C) A(X##D) A(X##E) A(X##F) -#define C(X) B(X##0) B(X##1) B(X##2) B(X##3) B(X##4) B(X##5) B(X##6) B(X##7) \ - B(X##8) B(X##9) B(X##A) B(X##B) B(X##C) B(X##D) B(X##E) B(X##F) - -struct foo { - C(x); // 256 - C(y); // 256 - C(z); -}; - - -int test(struct foo *F) { - return F->xA1 + F->yFF + F->zC4; -} diff --git a/test/FrontendC/2004-11-25-UnnamedBitfieldPadding.c b/test/FrontendC/2004-11-25-UnnamedBitfieldPadding.c deleted file mode 100644 index b3f4a829a9eb..000000000000 --- a/test/FrontendC/2004-11-25-UnnamedBitfieldPadding.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -o /dev/null -// This is a testcase for PR461 -typedef struct { - unsigned min_align: 1; - unsigned : 1; -} addr_diff_vec_flags; - -addr_diff_vec_flags X; diff --git a/test/FrontendC/2004-11-27-InvalidConstantExpr.c b/test/FrontendC/2004-11-27-InvalidConstantExpr.c deleted file mode 100644 index ee8642fa3aa2..000000000000 --- a/test/FrontendC/2004-11-27-InvalidConstantExpr.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | not grep {foo\\* sub} -// This should not produce a subtrace constantexpr of a pointer -struct foo { - int Y; - char X[100]; -} F; - -int test(char *Y) { - return Y - F.X; -} diff --git a/test/FrontendC/2004-11-27-StaticFunctionRedeclare.c b/test/FrontendC/2004-11-27-StaticFunctionRedeclare.c deleted file mode 100644 index 994ac8f8436f..000000000000 --- a/test/FrontendC/2004-11-27-StaticFunctionRedeclare.c +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | \ -// RUN: opt -std-compile-opts -S | not grep {declare i32.*func} - -// There should not be an unresolved reference to func here. Believe it or not, -// the "expected result" is a function named 'func' which is internal and -// referenced by bar(). - -// This is PR244 - -static int func(); -void bar() { - int func(); - foo(func); -} -static int func(char** A, char ** B) {} diff --git a/test/FrontendC/2004-11-27-VariableSizeInStructure.c b/test/FrontendC/2004-11-27-VariableSizeInStructure.c deleted file mode 100644 index bd63ae3b0122..000000000000 --- a/test/FrontendC/2004-11-27-VariableSizeInStructure.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc %s -S -o /dev/null - -// GCC allows variable sized arrays in structures, crazy! - -// This is PR360. - -int sub1(int i, char *pi) { - typedef int foo[i]; - struct bar {foo f1; int f2;} *p = (struct bar *) pi; - return p->f2; -} diff --git a/test/FrontendC/2005-01-02-ConstantInits.c b/test/FrontendC/2005-01-02-ConstantInits.c deleted file mode 100644 index 735278e0f930..000000000000 --- a/test/FrontendC/2005-01-02-ConstantInits.c +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -// This tests all kinds of hard cases with initializers and -// array subscripts. This corresponds to PR487. - -struct X { int a[2]; }; - -int test() { - static int i23 = (int) &(((struct X *)0)->a[1]); - return i23; -} - -int i = (int) &( ((struct X *)0) -> a[1]); - -int Arr[100]; - -int foo(int i) { return bar(&Arr[49])+bar(&Arr[i]); } -int foo2(int i) { - static const int *X = &Arr[49]; - static int i23 = (int) &( ((struct X *)0) -> a[0]); - int *P = Arr; - ++P; - return bar(Arr+i); -} diff --git a/test/FrontendC/2005-01-02-PointerDifference.c b/test/FrontendC/2005-01-02-PointerDifference.c deleted file mode 100644 index 2c108e5f6cac..000000000000 --- a/test/FrontendC/2005-01-02-PointerDifference.c +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o - | grep -v div - -int Diff(int *P, int *Q) { return P-Q; } diff --git a/test/FrontendC/2005-01-02-VAArgError-ICE.c b/test/FrontendC/2005-01-02-VAArgError-ICE.c deleted file mode 100644 index db8255846274..000000000000 --- a/test/FrontendC/2005-01-02-VAArgError-ICE.c +++ /dev/null @@ -1,10 +0,0 @@ -// This file is erroneous, but should not cause the compiler to ICE. -// PR481 -// RUN: %llvmgcc %s -S -o /dev/null |& not grep {internal compiler error} - -#include -int flags(int a, int b, ...) { - va_list args; - va_start(args,a); // not the last named arg - foo(args); -} diff --git a/test/FrontendC/2005-02-20-AggregateSAVEEXPR.c b/test/FrontendC/2005-02-20-AggregateSAVEEXPR.c deleted file mode 100644 index 7a9553303314..000000000000 --- a/test/FrontendC/2005-02-20-AggregateSAVEEXPR.c +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %llvmgcc %s -o /dev/null -S -// Note: -// We fail this on Sparc because the C library seems to be missing complex.h -// and the corresponding C99 complex support. -// -// We could modify the test to use only GCC extensions, but I don't know if -// that would change the nature of the test. -// -// XFAIL: sparc - -#ifdef __CYGWIN__ - #include -#else - #include -#endif - -int foo(complex float c) { - return creal(c); -} diff --git a/test/FrontendC/2005-02-27-MarkGlobalConstant.c b/test/FrontendC/2005-02-27-MarkGlobalConstant.c deleted file mode 100644 index 6806c94c10b3..000000000000 --- a/test/FrontendC/2005-02-27-MarkGlobalConstant.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -xc %s -S -o - | grep {private unnamed_addr constant } - -// The synthetic global made by the CFE for big initializer should be marked -// constant. - -void bar(); -void foo() { - char Blah[] = "asdlfkajsdlfkajsd;lfkajds;lfkjasd;flkajsd;lkfja;sdlkfjasd"; - bar(Blah); -} diff --git a/test/FrontendC/2005-03-05-OffsetOfHack.c b/test/FrontendC/2005-03-05-OffsetOfHack.c deleted file mode 100644 index 8df7231df6ac..000000000000 --- a/test/FrontendC/2005-03-05-OffsetOfHack.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -struct s { - unsigned long int field[0]; -}; - -#define OFFS \ - (((char *) &((struct s *) 0)->field[0]) - (char *) 0) - -int foo[OFFS]; - - diff --git a/test/FrontendC/2005-03-06-OffsetOfStructCrash.c b/test/FrontendC/2005-03-06-OffsetOfStructCrash.c deleted file mode 100644 index 91e686280233..000000000000 --- a/test/FrontendC/2005-03-06-OffsetOfStructCrash.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -struct Y {}; -struct XXX { - struct Y F; -}; - -void test1() { - (int)&((struct XXX*)(((void *)0)))->F; -} - -void test2() { - &((struct XXX*)(((void *)0)))->F; -} diff --git a/test/FrontendC/2005-03-11-Prefetch.c b/test/FrontendC/2005-03-11-Prefetch.c deleted file mode 100644 index bf7965304f1d..000000000000 --- a/test/FrontendC/2005-03-11-Prefetch.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | llvm-as | llvm-dis | grep llvm.prefetch - -void foo(int *P) { - __builtin_prefetch(P); - __builtin_prefetch(P, 1); -} diff --git a/test/FrontendC/2005-04-09-ComplexOps.c b/test/FrontendC/2005-04-09-ComplexOps.c deleted file mode 100644 index 2962b7455344..000000000000 --- a/test/FrontendC/2005-04-09-ComplexOps.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -#include -#define I 1.0iF - -double __complex test(double X) { return ~-(X*I); } - -_Bool EQ(double __complex A, double __complex B) { return A == B; } -_Bool NE(double __complex A, double __complex B) { return A != B; } diff --git a/test/FrontendC/2005-05-06-CountBuiltins.c b/test/FrontendC/2005-05-06-CountBuiltins.c deleted file mode 100644 index da40a142ae90..000000000000 --- a/test/FrontendC/2005-05-06-CountBuiltins.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | llvm-as | llvm-dis | not grep call.*__builtin - -int G, H, I; -void foo(int P) { - G = __builtin_clz(P); - H = __builtin_ctz(P); - I = __builtin_popcount(P); -} - -long long g, h, i; -void fooll(float P) { - g = __builtin_clzll(P); - g = __builtin_clzll(P); - h = __builtin_ctzll(P); - i = __builtin_popcountll(P); -} - diff --git a/test/FrontendC/2005-05-10-GlobalUnionInit.c b/test/FrontendC/2005-05-10-GlobalUnionInit.c deleted file mode 100644 index 443064c921d5..000000000000 --- a/test/FrontendC/2005-05-10-GlobalUnionInit.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -union A { // { uint } - union B { double *C; } D; -} E = { { (double*)12312 } }; - diff --git a/test/FrontendC/2005-06-15-ExpandGotoInternalProblem.c b/test/FrontendC/2005-06-15-ExpandGotoInternalProblem.c deleted file mode 100644 index 0f076c9bf79f..000000000000 --- a/test/FrontendC/2005-06-15-ExpandGotoInternalProblem.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -std=c99 %s -S -o - | \ -// RUN: opt -std-compile-opts -disable-output -// PR580 - -int X, Y; -int foo() { - int i; - for (i=0; i<100; i++ ) - { - break; - i = ( X || Y ) ; - } -} - diff --git a/test/FrontendC/2005-07-20-SqrtNoErrno.c b/test/FrontendC/2005-07-20-SqrtNoErrno.c deleted file mode 100644 index a321a3884e8b..000000000000 --- a/test/FrontendC/2005-07-20-SqrtNoErrno.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc %s -S -o - -fno-math-errno | FileCheck %s -// llvm.sqrt has undefined behavior on negative inputs, so it is -// inappropriate to translate C/C++ sqrt to this. -#include - -float foo(float X) { -// CHECK: foo -// CHECK: sqrtf(float %1) nounwind readonly - // Check that this is marked readonly when errno is ignored. - return sqrtf(X); -} diff --git a/test/FrontendC/2005-07-26-UnionInitCrash.c b/test/FrontendC/2005-07-26-UnionInitCrash.c deleted file mode 100644 index 563278a9c68e..000000000000 --- a/test/FrontendC/2005-07-26-UnionInitCrash.c +++ /dev/null @@ -1,3 +0,0 @@ -// PR607 -// RUN: %llvmgcc %s -S -o - -union { char bytes[8]; double alignment; }EQ1 = {0,0,0,0,0,0,0,0}; diff --git a/test/FrontendC/2005-07-28-IncorrectWeakGlobal.c b/test/FrontendC/2005-07-28-IncorrectWeakGlobal.c deleted file mode 100644 index 1a8c409439ce..000000000000 --- a/test/FrontendC/2005-07-28-IncorrectWeakGlobal.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | grep TheGlobal | not grep weak - -extern int TheGlobal; -int foo() { return TheGlobal; } -int TheGlobal = 1; diff --git a/test/FrontendC/2005-09-20-ComplexConstants.c b/test/FrontendC/2005-09-20-ComplexConstants.c deleted file mode 100644 index 209adc502fa5..000000000000 --- a/test/FrontendC/2005-09-20-ComplexConstants.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | llvm-as -o /dev/null - -const double _Complex x[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - diff --git a/test/FrontendC/2005-09-24-AsmUserPrefix.c b/test/FrontendC/2005-09-24-AsmUserPrefix.c deleted file mode 100644 index 952c7b3c35da..000000000000 --- a/test/FrontendC/2005-09-24-AsmUserPrefix.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | opt -std-compile-opts | llc | \ -// RUN: not grep _foo2 - -void foo() __asm__("foo2"); - -void bar() { - foo(); -} diff --git a/test/FrontendC/2005-09-24-BitFieldCrash.c b/test/FrontendC/2005-09-24-BitFieldCrash.c deleted file mode 100644 index b4c85ffb2d83..000000000000 --- a/test/FrontendC/2005-09-24-BitFieldCrash.c +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -struct tree_common {}; - -struct tree_int_cst { - struct tree_common common; - struct tree_int_cst_lowhi { - unsigned long long low; - long long high; - } int_cst; -}; - -enum XXX { yyy }; - -struct tree_function_decl { - struct tree_common common; - long long locus, y; - __extension__ enum XXX built_in_class : 2; - -}; - - -union tree_node { - struct tree_int_cst int_cst; - struct tree_function_decl function_decl; -}; - - -void foo (union tree_node * decl) { - decl->function_decl.built_in_class != 0; -} - - diff --git a/test/FrontendC/2005-10-18-VariableSizedElementCrash.c b/test/FrontendC/2005-10-18-VariableSizedElementCrash.c deleted file mode 100644 index b9166621db4a..000000000000 --- a/test/FrontendC/2005-10-18-VariableSizedElementCrash.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -int sub1(int i, char *pi) { - typedef int foo[i]; - struct bar {foo f1; int f2:3; int f3:4;} *p = (struct bar *) pi; - xxx(p->f1); - return p->f3; -} - diff --git a/test/FrontendC/2005-12-04-AttributeUsed.c b/test/FrontendC/2005-12-04-AttributeUsed.c deleted file mode 100644 index f47e977f4861..000000000000 --- a/test/FrontendC/2005-12-04-AttributeUsed.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | llvm-as | llvm-dis | \ -// RUN: grep llvm.used | grep foo | grep X - -int X __attribute__((used)); -int Y; - -__attribute__((used)) void foo() {} - diff --git a/test/FrontendC/2005-12-04-DeclarationLineNumbers.c b/test/FrontendC/2005-12-04-DeclarationLineNumbers.c deleted file mode 100644 index f3f69ddb0bcc..000000000000 --- a/test/FrontendC/2005-12-04-DeclarationLineNumbers.c +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: %llvmgcc %s -S -g -o - | grep DW_TAG_compile_unit | count 1 -// PR664: ensure that line #'s are emitted for declarations - - -short test(short br_data_0, -short br_data_1, -short br_data_2, -short br_data_3, -short br_data_4, -short br_data_5, -short br_data_6, -short br_data_7) { - -short sm07 = br_data_0 + br_data_7; -short sm16 = br_data_1 + br_data_6; -short sm25 = br_data_2 + br_data_5; -short sm34 = br_data_3 + br_data_4; -short s0734 = sm07 + sm34; -short s1625 = sm16 + sm25; - -return s0734 + s1625; -} - diff --git a/test/FrontendC/2006-01-13-Includes.c b/test/FrontendC/2006-01-13-Includes.c deleted file mode 100644 index 7fa0b3b5a6dc..000000000000 --- a/test/FrontendC/2006-01-13-Includes.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc %s -g -S -o - | grep {test/FrontendC} -// PR676 - -#include - -void test() { - printf("Hello World\n"); -} diff --git a/test/FrontendC/2006-01-13-StackSave.c b/test/FrontendC/2006-01-13-StackSave.c deleted file mode 100644 index ae8d90821016..000000000000 --- a/test/FrontendC/2006-01-13-StackSave.c +++ /dev/null @@ -1,11 +0,0 @@ -// PR691 -// RUN: %llvmgcc %s -S -o - | opt -std-compile-opts | \ -// RUN: llvm-dis | grep llvm.stacksave - -void test(int N) { - int i; - for (i = 0; i < N; ++i) { - int VLA[i]; - external(VLA); - } -} diff --git a/test/FrontendC/2006-01-16-BitCountIntrinsicsUnsigned.c b/test/FrontendC/2006-01-16-BitCountIntrinsicsUnsigned.c deleted file mode 100644 index eafcb62814bc..000000000000 --- a/test/FrontendC/2006-01-16-BitCountIntrinsicsUnsigned.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep {llvm.ctlz.i32(i32} | count 3 -// RUN: %llvmgcc -S %s -o - | grep {llvm.ctlz.i32(i32} | grep declare | count 1 - -unsigned t2(unsigned X) { - return __builtin_clz(X); -} -int t1(int X) { - return __builtin_clz(X); -} diff --git a/test/FrontendC/2006-01-23-FileScopeAsm.c b/test/FrontendC/2006-01-23-FileScopeAsm.c deleted file mode 100644 index 80e719556237..000000000000 --- a/test/FrontendC/2006-01-23-FileScopeAsm.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | opt -std-compile-opts | \ -// RUN: llvm-dis | grep {foo\[12345\]} | count 5 - -__asm__ ("foo1"); -__asm__ ("foo2"); -__asm__ ("foo3"); -__asm__ ("foo4"); -__asm__ ("foo5"); diff --git a/test/FrontendC/2006-03-03-MissingInitializer.c b/test/FrontendC/2006-03-03-MissingInitializer.c deleted file mode 100644 index 5e027b1894ac..000000000000 --- a/test/FrontendC/2006-03-03-MissingInitializer.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | opt -std-compile-opts | \ -// RUN: llvm-dis | grep {@nate.*internal unnamed_addr global i32 0} - -struct X { int *XX; int Y;}; - -void foo() { - static int nate = 0; - struct X bob = { &nate, 14 }; - bar(&bob); -} - diff --git a/test/FrontendC/2006-03-16-VectorCtor.c b/test/FrontendC/2006-03-16-VectorCtor.c deleted file mode 100644 index b95593b12147..000000000000 --- a/test/FrontendC/2006-03-16-VectorCtor.c +++ /dev/null @@ -1,10 +0,0 @@ -// Test that basic generic vector support works -// RUN: %llvmgcc %s -S -o - - -typedef int v4si __attribute__ ((__vector_size__ (16))); -void test(v4si *P, v4si *Q, float X) { - *P = (v4si){ X, X, X, X } * *Q; -} - -v4si G = (v4si){ 0.1, 1.2, 4.2, 17.2 }; - diff --git a/test/FrontendC/2006-03-17-KnRMismatch.c b/test/FrontendC/2006-03-17-KnRMismatch.c deleted file mode 100644 index 19391122fcad..000000000000 --- a/test/FrontendC/2006-03-17-KnRMismatch.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -void regnode(int op); - -void regnode(op) -char op; -{ -} diff --git a/test/FrontendC/2006-05-01-AppleAlignmentPragma.c b/test/FrontendC/2006-05-01-AppleAlignmentPragma.c deleted file mode 100644 index 233968b51aa3..000000000000 --- a/test/FrontendC/2006-05-01-AppleAlignmentPragma.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -#ifdef __APPLE__ -/* test that X is laid out correctly when this pragma is used. */ -#pragma options align=mac68k -#endif - -struct S { - unsigned A; - unsigned short B; -} X; - diff --git a/test/FrontendC/2006-05-19-SingleEltReturn.c b/test/FrontendC/2006-05-19-SingleEltReturn.c deleted file mode 100644 index 70c94c620527..000000000000 --- a/test/FrontendC/2006-05-19-SingleEltReturn.c +++ /dev/null @@ -1,23 +0,0 @@ -// Test returning a single element aggregate value containing a double. -// RUN: %llvmgcc %s -S -o - - -struct X { - double D; -}; - -struct Y { - struct X x; -}; - -struct Y bar(); - -void foo(struct Y *P) { - *P = bar(); -} - -struct Y bar() { - struct Y a; - a.x.D = 0; - return a; -} - diff --git a/test/FrontendC/2006-07-31-PR854.c b/test/FrontendC/2006-07-31-PR854.c deleted file mode 100644 index 3802de8fc459..000000000000 --- a/test/FrontendC/2006-07-31-PR854.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -w %s -S -o - -// PR854 - struct kernel_symbol { - unsigned long value; - }; - unsigned long loops_per_jiffy = (1<<12); - static const char __kstrtab_loops_per_jiffy[] -__attribute__((section("__ksymtab_strings"))) = "loops_per_jiffy"; - static const struct kernel_symbol __ksymtab_loops_per_jiffy -__attribute__((__used__)) __attribute__((section("__ksymtab"))) = { (unsigned -long)&loops_per_jiffy, __kstrtab_loops_per_jiffy }; diff --git a/test/FrontendC/2006-09-11-BitfieldRefCrash.c b/test/FrontendC/2006-09-11-BitfieldRefCrash.c deleted file mode 100644 index d06cc3afbf3d..000000000000 --- a/test/FrontendC/2006-09-11-BitfieldRefCrash.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc %s -S -o - -// PR906 - -struct state_struct { - unsigned long long phys_frame: 50; - unsigned valid : 2; -} s; - -int mem_access(struct state_struct *p) { - return p->valid; -} - diff --git a/test/FrontendC/2006-09-18-fwrite-cast-crash.c b/test/FrontendC/2006-09-18-fwrite-cast-crash.c deleted file mode 100644 index a693c5666f21..000000000000 --- a/test/FrontendC/2006-09-18-fwrite-cast-crash.c +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %llvmgcc %s -S -o /dev/null -// PR910 -// XFAIL: * -// See PR2452 - -struct l_struct_2E_FILE { char x; }; -unsigned fwrite(signed char *, unsigned , unsigned , signed char *); -static signed char str301[39]; -static void Usage(signed char *ltmp_611_6) { - struct l_struct_2E_FILE *ltmp_6202_16; - unsigned ltmp_6203_92; - ltmp_6203_92 = /*tail*/ ((unsigned (*) (signed char *, unsigned , unsigned , -struct l_struct_2E_FILE *))(void*)fwrite)((&(str301[0u])), 38u, 1u, ltmp_6202_16); -} - diff --git a/test/FrontendC/2006-09-21-IncompleteElementType.c b/test/FrontendC/2006-09-21-IncompleteElementType.c deleted file mode 100644 index a5091821cb69..000000000000 --- a/test/FrontendC/2006-09-21-IncompleteElementType.c +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: not %llvmgcc %s -S -o /dev/null |& not grep {internal compiler error} - -struct A X[(927 - 37) / sizeof(struct A)]; diff --git a/test/FrontendC/2006-09-25-DebugFilename.c b/test/FrontendC/2006-09-25-DebugFilename.c deleted file mode 100644 index eea52ba7608c..000000000000 --- a/test/FrontendC/2006-09-25-DebugFilename.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: not %llvmgcc -xc %s -S -o /dev/null |& \ -// RUN: grep fluffy | grep 2006-09-25-DebugFilename.c -#include "2006-09-25-DebugFilename.h" -int func1() { return hfunc1(); } -int func2() { fluffy; return hfunc1(); } - diff --git a/test/FrontendC/2006-09-25-DebugFilename.h b/test/FrontendC/2006-09-25-DebugFilename.h deleted file mode 100644 index 9b03666b3c27..000000000000 --- a/test/FrontendC/2006-09-25-DebugFilename.h +++ /dev/null @@ -1,6 +0,0 @@ -extern int exfunc(int a); - -static inline int hfunc1() -{ - return exfunc(1); -} diff --git a/test/FrontendC/2006-09-28-SimpleAsm.c b/test/FrontendC/2006-09-28-SimpleAsm.c deleted file mode 100644 index e3040200a60b..000000000000 --- a/test/FrontendC/2006-09-28-SimpleAsm.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | grep {ext: xorl %eax, eax; movl} -// RUN: %llvmgcc %s -S -o - | grep {nonext: xorl %eax, %eax; mov} -// PR924 - -void bar() { - // Extended asm - asm volatile ("ext: xorl %%eax, eax; movl eax, fs; movl eax, gs %%blah %= %% " : : "r"(1)); - // Non-extended asm. - asm volatile ("nonext: xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs %%blah %= %% "); -} diff --git a/test/FrontendC/2006-10-30-ArrayCrash.c b/test/FrontendC/2006-10-30-ArrayCrash.c deleted file mode 100644 index 09464dd3a067..000000000000 --- a/test/FrontendC/2006-10-30-ArrayCrash.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc -O3 -S -o - %s -// PR954, PR911 - -extern void foo(); - -struct S { - short f1[3]; - unsigned int f2 : 1; -}; - -void bar() -{ - struct S *A; - - if (A->f2) - foo(); -} diff --git a/test/FrontendC/2006-12-14-ordered_expr.c b/test/FrontendC/2006-12-14-ordered_expr.c deleted file mode 100644 index 8ff2eb607210..000000000000 --- a/test/FrontendC/2006-12-14-ordered_expr.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -O3 -S %s -o - | grep {fcmp ord float %X, %Y} - -int test2(float X, float Y) { - return !__builtin_isunordered(X, Y); -} - diff --git a/test/FrontendC/2007-01-06-KNR-Proto.c b/test/FrontendC/2007-01-06-KNR-Proto.c deleted file mode 100644 index 6aa74d4cb25f..000000000000 --- a/test/FrontendC/2007-01-06-KNR-Proto.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S -o - %s -// PR1083 - -int svc_register (void (*dispatch) (int)); - -int svc_register (dispatch) - void (*dispatch) (); -{ -} - diff --git a/test/FrontendC/2007-01-20-VectorICE.c b/test/FrontendC/2007-01-20-VectorICE.c deleted file mode 100644 index c2dcdef19443..000000000000 --- a/test/FrontendC/2007-01-20-VectorICE.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -typedef float __m128 __attribute__((__vector_size__(16))); -typedef long long __v2di __attribute__((__vector_size__(16))); -typedef int __v4si __attribute__((__vector_size__(16))); - -__v2di bar(void); -void foo(int X, __v4si *P) { - *P = X == 2 ? bar() : bar(); -} - diff --git a/test/FrontendC/2007-01-24-InlineAsmCModifier.c b/test/FrontendC/2007-01-24-InlineAsmCModifier.c deleted file mode 100644 index c601ccf2eb19..000000000000 --- a/test/FrontendC/2007-01-24-InlineAsmCModifier.c +++ /dev/null @@ -1,10 +0,0 @@ -// Verify that the %c modifier works and strips off any prefixes from -// immediates. -// RUN: %llvmgcc -S %s -o - | llc | grep {pickANumber: 789514} - -void foo() { - __asm__ volatile("/* " "pickANumber" ": %c0 */"::"i"(0xC0C0A)); - - // Check that non-c modifiers work also (not greped for above). - __asm__ volatile("/* " "pickANumber2 " ": %0 */"::"i"(123)); -} diff --git a/test/FrontendC/2007-02-04-AddrLValue-2.c b/test/FrontendC/2007-02-04-AddrLValue-2.c deleted file mode 100644 index fa20faff3e15..000000000000 --- a/test/FrontendC/2007-02-04-AddrLValue-2.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %llvmgcc %s -O3 -S -o - -// PR1173 - -struct S { char s; }; -struct T { struct S t; }; - -struct S *const p = &((struct T * const) (0x4000))->t; - -void -foo (void) -{ - p->s = 0; -} diff --git a/test/FrontendC/2007-02-04-AddrLValue.c b/test/FrontendC/2007-02-04-AddrLValue.c deleted file mode 100644 index 214fce7747ce..000000000000 --- a/test/FrontendC/2007-02-04-AddrLValue.c +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: %llvmgcc %s -O3 -S -o - -// PR1176 - -typedef struct -{ - char *key; - char *value; -} T1; - -typedef struct -{ - long type; - char *value; -} T3; - -T1 a[] = -{ - { - "", - ((char *)&((T3) {1, (char *) 1})) - } -}; - diff --git a/test/FrontendC/2007-02-04-EmptyStruct.c b/test/FrontendC/2007-02-04-EmptyStruct.c deleted file mode 100644 index 5ad2c705cce8..000000000000 --- a/test/FrontendC/2007-02-04-EmptyStruct.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc %s -O3 -S -o - -// PR1175 - -struct empty { }; - -void foo(struct empty *p) { - p++; -} - diff --git a/test/FrontendC/2007-02-04-WITH_SIZE_EXPR.c b/test/FrontendC/2007-02-04-WITH_SIZE_EXPR.c deleted file mode 100644 index d5a9fbb0ecc2..000000000000 --- a/test/FrontendC/2007-02-04-WITH_SIZE_EXPR.c +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %llvmgcc %s -O3 -S -o - -// PR1174 - -void zzz (char *s1, char *s2, int len, int *q) -{ - int z = 5; - unsigned int i, b; - struct { char a[z]; } x; - - for (i = 0; i < len; i++) - s1[i] = s2[i]; - - b = z & 0x3; - - len += (b == 0 ? 0 : 1) + z; - - *q = len; - - foo (x, x); -} - diff --git a/test/FrontendC/2007-02-05-nested.c b/test/FrontendC/2007-02-05-nested.c deleted file mode 100644 index bd6d30695ba0..000000000000 --- a/test/FrontendC/2007-02-05-nested.c +++ /dev/null @@ -1,54 +0,0 @@ -// RUN: %llvmgcc -S -fnested-functions -O0 -o - %s -// PR915 - -extern void abort(void); - -void nest(int n) -{ - int a = 0; - int b = 5; - int c = 0; - int d = 7; - - void o(int i, int j) - { - if (i!=j) - abort(); - } - - void f(x) - int x; /* K&R style */ - { - int e = 0; - int f = 2; - int g = 0; - - void y(void) - { - c = n; - e = 1; - g = x; - } - - void z(void) - { - a = 4; - g = 3; - } - - a = 5; - y(); - c = x; - z(); - o(1,e); - o(2,f); - o(3,g); - } - - c = 2; - f(6); - o(4,a); - o(5,b); - o(6,c); - o(7,d); -} diff --git a/test/FrontendC/2007-02-07-AddrLabel.c b/test/FrontendC/2007-02-07-AddrLabel.c deleted file mode 100644 index 03ed4c987e44..000000000000 --- a/test/FrontendC/2007-02-07-AddrLabel.c +++ /dev/null @@ -1,10 +0,0 @@ -// PR947 -// RUN: %llvmgcc %s -S -o - - -void foo() { - void *ptr; - label: - ptr = &&label; - - goto *ptr; - } diff --git a/test/FrontendC/2007-02-16-VariableSizeStructArg.c b/test/FrontendC/2007-02-16-VariableSizeStructArg.c deleted file mode 100644 index ec6971acdb10..000000000000 --- a/test/FrontendC/2007-02-16-VariableSizeStructArg.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S -w %s -o - -// PR1170 -int f(int a, struct {int b[a];} c) { return c.b[0]; } - -int g(struct {int b[1];} c) { - return c.b[0]; -} diff --git a/test/FrontendC/2007-02-16-VoidPtrDiff.c b/test/FrontendC/2007-02-16-VoidPtrDiff.c deleted file mode 100644 index 15df28cae3fe..000000000000 --- a/test/FrontendC/2007-02-16-VoidPtrDiff.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -void foo(void *ptr, int test) { - (ptr - ((void *) test + 0x2000)); -} diff --git a/test/FrontendC/2007-02-16-WritableStrings.c b/test/FrontendC/2007-02-16-WritableStrings.c deleted file mode 100644 index 8fa7f15dc6c3..000000000000 --- a/test/FrontendC/2007-02-16-WritableStrings.c +++ /dev/null @@ -1,7 +0,0 @@ -// Test the -fwritable-strings option. - -// RUN: %llvmgcc -O3 -S -o - -fwritable-strings %s | \ -// RUN: grep {internal unnamed_addr global} -// RUN: %llvmgcc -O3 -S -o - %s | grep {private unnamed_addr constant} - -char *X = "foo"; diff --git a/test/FrontendC/2007-02-25-C-DotDotDot.c b/test/FrontendC/2007-02-25-C-DotDotDot.c deleted file mode 100644 index 3f96fd1f9e1f..000000000000 --- a/test/FrontendC/2007-02-25-C-DotDotDot.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -O0 -S -o - -fno-inline -fno-unit-at-a-time %s | \ -// RUN: grep {call float @foo} - -// Make sure the call to foo is compiled as: -// call float @foo() -// not -// call float (...)* bitcast (float ()* @foo to float (...)*)( ) - -static float foo() { return 0.0; } -float bar() { return foo()*10.0;} - - diff --git a/test/FrontendC/2007-03-01-VarSizeArrayIdx.c b/test/FrontendC/2007-03-01-VarSizeArrayIdx.c deleted file mode 100644 index 6ebe79672f58..000000000000 --- a/test/FrontendC/2007-03-01-VarSizeArrayIdx.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc %s -O3 -S -o - | grep mul -// PR1233 - -float foo(int w, float A[][w], int g, int h) { - return A[g][0]; -} - diff --git a/test/FrontendC/2007-03-05-DataLayout.c b/test/FrontendC/2007-03-05-DataLayout.c deleted file mode 100644 index 18819f169080..000000000000 --- a/test/FrontendC/2007-03-05-DataLayout.c +++ /dev/null @@ -1,53 +0,0 @@ -// Testcase for PR1242 -// RUN: %llvmgcc -S %s -o - | grep datalayout | \ -// RUN: not grep {"\[Ee\]-p:\[36\]\[24\]:\[36\]\[24\]"} -// END. -#include -#define NDIM 3 -#define BODY 01 -typedef double vector[NDIM]; -typedef struct bnode* bodyptr; -// { i16, double, [3 x double], i32, i32, [3 x double], [3 x double], [3 x -// double], double, \2 *, \2 * } -struct bnode { - short int type; - double mass; - vector pos; - int proc; - int new_proc; - vector vel; - vector acc; - vector new_acc; - double phi; - bodyptr next; - bodyptr proc_next; -} body; - -#define Type(x) ((x)->type) -#define Mass(x) ((x)->mass) -#define Pos(x) ((x)->pos) -#define Proc(x) ((x)->proc) -#define New_Proc(x) ((x)->new_proc) -#define Vel(x) ((x)->vel) -#define Acc(x) ((x)->acc) -#define New_Acc(x) ((x)->new_acc) -#define Phi(x) ((x)->phi) -#define Next(x) ((x)->next) -#define Proc_Next(x) ((x)->proc_next) - -bodyptr ubody_alloc(int p) -{ - register bodyptr tmp; - tmp = (bodyptr)malloc(sizeof(body)); - - Type(tmp) = BODY; - Proc(tmp) = p; - Proc_Next(tmp) = NULL; - New_Proc(tmp) = p; - return tmp; -} - -int main(int argc, char** argv) { - bodyptr b = ubody_alloc(17); - return 0; -} diff --git a/test/FrontendC/2007-03-06-VarSizeInStruct1.c b/test/FrontendC/2007-03-06-VarSizeInStruct1.c deleted file mode 100644 index b4ae56549318..000000000000 --- a/test/FrontendC/2007-03-06-VarSizeInStruct1.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc %s -w -S -o - -void* p (int n) { - struct f { - char w; char x[n]; char z[]; - } F; - F.x[0]='x'; - return &F; -} diff --git a/test/FrontendC/2007-03-06-VarSizeInStruct2.c b/test/FrontendC/2007-03-06-VarSizeInStruct2.c deleted file mode 100644 index 13bc3aaf9ae7..000000000000 --- a/test/FrontendC/2007-03-06-VarSizeInStruct2.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc %s -S -o - -char p (int n) { - struct f { - char w; char x[n]; char y[n]; - } F; - - return F.x[0]; -} diff --git a/test/FrontendC/2007-03-26-BitfieldAfterZeroWidth.c b/test/FrontendC/2007-03-26-BitfieldAfterZeroWidth.c deleted file mode 100644 index 9b6a8690a336..000000000000 --- a/test/FrontendC/2007-03-26-BitfieldAfterZeroWidth.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc %s -S -o - -struct W {}; -struct Y { - struct W w; - int i:1; -} __attribute__ ((packed)) y; diff --git a/test/FrontendC/2007-03-26-ZeroWidthBitfield.c b/test/FrontendC/2007-03-26-ZeroWidthBitfield.c deleted file mode 100644 index 89bfb8e1cb09..000000000000 --- a/test/FrontendC/2007-03-26-ZeroWidthBitfield.c +++ /dev/null @@ -1,2 +0,0 @@ -// RUN: %llvmgcc %s -S -o - -struct Z { int :0; } z; diff --git a/test/FrontendC/2007-03-27-ArrayCompatible.c b/test/FrontendC/2007-03-27-ArrayCompatible.c deleted file mode 100644 index fa3d2db23cc3..000000000000 --- a/test/FrontendC/2007-03-27-ArrayCompatible.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S %s -O2 -o - | grep {ret i8 0} -static char c(int n) { - char x[2][n]; - x[1][0]=0; - return *(n+(char *)x); -} - -char d(void) { - return c(2); -} diff --git a/test/FrontendC/2007-03-27-VarLengthArray.c b/test/FrontendC/2007-03-27-VarLengthArray.c deleted file mode 100644 index b555690068d9..000000000000 --- a/test/FrontendC/2007-03-27-VarLengthArray.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep {getelementptr inbounds \\\[0 x i32\\\]} -extern void f(int *); -int e(int m, int n) { - int x[n]; - f(x); - return x[m]; -} diff --git a/test/FrontendC/2007-04-05-PackedBitFields-2.c b/test/FrontendC/2007-04-05-PackedBitFields-2.c deleted file mode 100644 index d9db4206c169..000000000000 --- a/test/FrontendC/2007-04-05-PackedBitFields-2.c +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -# define pck __attribute__((packed)) - - -struct pck F { - unsigned long long i : 12, - j : 23, - k : 27, - l; -}; -struct F f1; - -void foo() { - f1.l = 5; -} diff --git a/test/FrontendC/2007-04-05-PackedBitFields.c b/test/FrontendC/2007-04-05-PackedBitFields.c deleted file mode 100644 index f9de35639b0d..000000000000 --- a/test/FrontendC/2007-04-05-PackedBitFields.c +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -# define pck __attribute__((packed)) - - -struct pck E { - unsigned long long l, - i : 12, - j : 23, - k : 29; }; - -struct E e1; - -void foo() { - e1.k = 5; -} diff --git a/test/FrontendC/2007-04-05-PackedStruct.c b/test/FrontendC/2007-04-05-PackedStruct.c deleted file mode 100644 index 0d524c489ea8..000000000000 --- a/test/FrontendC/2007-04-05-PackedStruct.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -#pragma pack(push, 2) - -enum { - tA = 0, - tB = 1 -}; - -struct MyStruct { - unsigned long A; - char C; - void * B; -}; - -void bar(){ -struct MyStruct MS = { tB, 0 }; -} diff --git a/test/FrontendC/2007-04-05-PadBeforeZeroLengthField.c b/test/FrontendC/2007-04-05-PadBeforeZeroLengthField.c deleted file mode 100644 index acc382199255..000000000000 --- a/test/FrontendC/2007-04-05-PadBeforeZeroLengthField.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc %s -S -o - -struct c__ { unsigned int type:4; }; -union A { struct c__ c; } __attribute__((aligned(8))); -struct B { - unsigned int retainCount; - union A objects[]; -}; -void foo(union A * objects, struct B *array, unsigned long k) -{ array->objects[k] = objects[k]; } diff --git a/test/FrontendC/2007-04-05-UnPackedStruct.c b/test/FrontendC/2007-04-05-UnPackedStruct.c deleted file mode 100644 index 9e168ed34feb..000000000000 --- a/test/FrontendC/2007-04-05-UnPackedStruct.c +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - - -enum { - tA = 0, - tB = 1 -}; - -struct MyStruct { - unsigned long A; - void * B; -}; - -void bar(){ -struct MyStruct MS = { tB, 0 }; -} diff --git a/test/FrontendC/2007-04-11-InlineAsmStruct.c b/test/FrontendC/2007-04-11-InlineAsmStruct.c deleted file mode 100644 index 6c6c1509903d..000000000000 --- a/test/FrontendC/2007-04-11-InlineAsmStruct.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | llc - -struct V { short X, Y; }; -int bar() { - struct V bar; - __asm__ volatile("foo %0\n" : "=r"(bar)); - return bar.X; -} - diff --git a/test/FrontendC/2007-04-11-InlineAsmUnion.c b/test/FrontendC/2007-04-11-InlineAsmUnion.c deleted file mode 100644 index 014470102d32..000000000000 --- a/test/FrontendC/2007-04-11-InlineAsmUnion.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | llc - -union U { int x; float p; }; -void foo() { - union U bar; - __asm__ volatile("foo %0\n" : "=r"(bar)); -} diff --git a/test/FrontendC/2007-04-11-InlineStorageClassC89.c b/test/FrontendC/2007-04-11-InlineStorageClassC89.c deleted file mode 100644 index 834fb07a2623..000000000000 --- a/test/FrontendC/2007-04-11-InlineStorageClassC89.c +++ /dev/null @@ -1,46 +0,0 @@ -// RUN: %llvmgcc %s -S -O0 -o - | grep define | grep xglobWeak | \ -// RUN: grep weak | count 1 -// RUN: %llvmgcc %s -S -O0 -o - | grep define | grep xextWeak | \ -// RUN: grep weak | count 1 -// RUN: %llvmgcc %s -S -O0 -o - | grep define | \ -// RUN: grep xWeaknoinline | grep weak | count 1 -// RUN: %llvmgcc %s -S -O0 -o - | grep define | \ -// RUN: grep xWeakextnoinline | grep weak | count 1 -// RUN: %llvmgcc %s -S -O0 -o - | grep define | \ -// RUN: grep xglobnoWeak | grep -v internal | grep -v weak | \ -// RUN: grep -v linkonce | count 1 -// RUN: %llvmgcc %s -S -O0 -o - | grep define | \ -// RUN: grep xstatnoWeak | grep internal | count 1 -// RUN: %llvmgcc %s -S -O0 -o - | grep define | \ -// RUN: grep xextnoWeak | grep available_externally | grep -v weak | \ -// RUN: grep -v linkonce | count 1 -inline int xglobWeak(int) __attribute__((weak)); -inline int xglobWeak (int i) { - return i*2; -} -inline int xextWeak(int) __attribute__((weak)); -extern inline int xextWeak (int i) { - return i*4; -} -int xWeaknoinline(int) __attribute__((weak)); -int xWeaknoinline(int i) { - return i*8; -} -int xWeakextnoinline(int) __attribute__((weak)); -extern int xWeakextnoinline(int i) { - return i*16; -} -inline int xglobnoWeak (int i) { - return i*32; -} -static inline int xstatnoWeak (int i) { - return i*64; -} -extern inline int xextnoWeak (int i) { - return i*128; -} -int j(int y) { - return xglobnoWeak(y)+xstatnoWeak(y)+xextnoWeak(y)+ - xglobWeak(y)+xextWeak(y)+ - xWeakextnoinline(y)+xWeaknoinline(y); -} diff --git a/test/FrontendC/2007-04-11-InlineStorageClassC99.c b/test/FrontendC/2007-04-11-InlineStorageClassC99.c deleted file mode 100644 index 6031071e3464..000000000000 --- a/test/FrontendC/2007-04-11-InlineStorageClassC99.c +++ /dev/null @@ -1,46 +0,0 @@ -// RUN: %llvmgcc -std=c99 %s -S -O0 -o - | grep declare | \ -// RUN: grep xglobWeak | grep extern_weak | count 1 -// RUN: %llvmgcc -std=c99 %s -S -O0 -o - | grep define | \ -// RUN: grep xextWeak | grep weak | count 1 -// RUN: %llvmgcc -std=c99 %s -S -O0 -o - | grep define | \ -// RUN: grep xWeaknoinline | grep weak | count 1 -// RUN: %llvmgcc -std=c99 %s -S -O0 -o - | grep define | \ -// RUN: grep xWeakextnoinline | grep weak | count 1 -// RUN: %llvmgcc -std=c99 %s -S -O0 -o - | grep define | \ -// RUN: grep xglobnoWeak | grep available_externally | grep -v weak | \ -// RUN: grep -v linkonce | count 1 -// RUN: %llvmgcc -std=c99 %s -S -O0 -o - | grep define | \ -// RUN: grep xstatnoWeak | grep internal | count 1 -// RUN: %llvmgcc -std=c99 %s -S -O0 -o - | grep define | \ -// RUN: grep xextnoWeak | grep -v available_externally | grep -v weak | \ -// RUN: grep -v linkonce | count 1 -inline int xglobWeak(int) __attribute__((weak)); -inline int xglobWeak (int i) { - return i*2; -} -inline int xextWeak(int) __attribute__((weak)); -extern inline int xextWeak (int i) { - return i*4; -} -int xWeaknoinline(int) __attribute__((weak)); -int xWeaknoinline(int i) { - return i*8; -} -int xWeakextnoinline(int) __attribute__((weak)); -extern int xWeakextnoinline(int i) { - return i*16; -} -inline int xglobnoWeak (int i) { - return i*32; -} -static inline int xstatnoWeak (int i) { - return i*64; -} -extern inline int xextnoWeak (int i) { - return i*128; -} -int j(int y) { - return xglobnoWeak(y)+xstatnoWeak(y)+xextnoWeak(y)+ - xglobWeak(y)+xextWeak(y)+ - xWeakextnoinline(y)+xWeaknoinline(y); -} diff --git a/test/FrontendC/2007-04-11-PR1321.c b/test/FrontendC/2007-04-11-PR1321.c deleted file mode 100644 index f391329a0f11..000000000000 --- a/test/FrontendC/2007-04-11-PR1321.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc %s -S -o /dev/null - -struct X { - unsigned int e0 : 17; - unsigned int e1 : 17; - unsigned int e2 : 17; - unsigned int e3 : 17; - unsigned int e4 : 17; - unsigned int e5 : 17; - unsigned int e6 : 17; - unsigned int e7 : 17; -} __attribute__((packed)) x; diff --git a/test/FrontendC/2007-04-13-InlineAsmStruct2.c b/test/FrontendC/2007-04-13-InlineAsmStruct2.c deleted file mode 100644 index 44ddeb3f95d8..000000000000 --- a/test/FrontendC/2007-04-13-InlineAsmStruct2.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | grep {call void asm} - -struct V { short X, Y; }; -int bar() { - struct V bar; - __asm__ volatile("foo %0\n" :: "r"(bar)); - return bar.X; -} - diff --git a/test/FrontendC/2007-04-13-InlineAsmUnion2.c b/test/FrontendC/2007-04-13-InlineAsmUnion2.c deleted file mode 100644 index a0944a7b6407..000000000000 --- a/test/FrontendC/2007-04-13-InlineAsmUnion2.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | grep {call void asm} - -union U { int x; char* p; }; -void foo() { - union U bar; - __asm__ volatile("foo %0\n" :: "r"(bar)); -} diff --git a/test/FrontendC/2007-04-14-FNoBuiltin.c b/test/FrontendC/2007-04-14-FNoBuiltin.c deleted file mode 100644 index 88bf0e014309..000000000000 --- a/test/FrontendC/2007-04-14-FNoBuiltin.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -O2 -fno-builtin -o - | grep call.*printf -// Check that -fno-builtin is honored. - -extern int printf(const char*, ...); -void foo(const char *msg) { - printf("%s\n",msg); -} diff --git a/test/FrontendC/2007-04-17-ZeroSizeBitFields.c b/test/FrontendC/2007-04-17-ZeroSizeBitFields.c deleted file mode 100644 index ec7b7ea273f4..000000000000 --- a/test/FrontendC/2007-04-17-ZeroSizeBitFields.c +++ /dev/null @@ -1,4 +0,0 @@ -// PR 1332 -// RUN: %llvmgcc %s -S -o /dev/null - -struct Z { int a:1; int :0; int c:1; } z; diff --git a/test/FrontendC/2007-04-24-VolatileStructCopy.c b/test/FrontendC/2007-04-24-VolatileStructCopy.c deleted file mode 100644 index d49e75e02541..000000000000 --- a/test/FrontendC/2007-04-24-VolatileStructCopy.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -O3 -S -o - %s | grep {volatile store} -// PR1352 - -struct foo { - int x; -}; - -void copy(volatile struct foo *p, struct foo *q) { - *p = *q; -} diff --git a/test/FrontendC/2007-04-24-bit-not-expr.c b/test/FrontendC/2007-04-24-bit-not-expr.c deleted file mode 100644 index fab0b90bb15f..000000000000 --- a/test/FrontendC/2007-04-24-bit-not-expr.c +++ /dev/null @@ -1,7 +0,0 @@ -// PR 1346 -// RUN: %llvmgcc -S %s -o /dev/null -extern bar(void *); - -void f(void *cd) { - bar(((void *)((unsigned long)(cd) ^ -1))); -} diff --git a/test/FrontendC/2007-04-24-str-const.c b/test/FrontendC/2007-04-24-str-const.c deleted file mode 100644 index 3c3dab372ab5..000000000000 --- a/test/FrontendC/2007-04-24-str-const.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc -S %s -o /dev/null -static char *str; - -static const struct { - const char *name; - unsigned type; -} scan_special[] = { - {"shift", 1}, - {0, 0} -}; - -static void -sb(void) -{ - while (*str == ' ' || *str == '\t') - str++; -} diff --git a/test/FrontendC/2007-05-07-NestedStructReturn.c b/test/FrontendC/2007-05-07-NestedStructReturn.c deleted file mode 100644 index aea58e3ae8bb..000000000000 --- a/test/FrontendC/2007-05-07-NestedStructReturn.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %llvmgcc %s -S -fnested-functions -o - | grep {sret *%agg.result} - -struct X { long m, n, o, p; }; - -struct X p(int n) { - struct X c(int m) { - struct X x; - x.m = m; - x.n = n; - return x; - } - return c(n); -} diff --git a/test/FrontendC/2007-05-07-PaddingElements.c b/test/FrontendC/2007-05-07-PaddingElements.c deleted file mode 100644 index 1e4f4d0a7512..000000000000 --- a/test/FrontendC/2007-05-07-PaddingElements.c +++ /dev/null @@ -1,12 +0,0 @@ -// PR 1278 -// RUN: %llvmgcc %s -S -O0 -o - | grep {struct.s} | not grep "4 x i8] zeroinitializer" -// RUN: %llvmgcc %s -S -O0 -o - | not grep "i32 0, i32 2" -struct s { - double d1; - int s1; -}; - -struct s foo(void) { - struct s S = {1.1, 2}; - return S; -} diff --git a/test/FrontendC/2007-05-08-PCH.c b/test/FrontendC/2007-05-08-PCH.c deleted file mode 100644 index aa277ece99e0..000000000000 --- a/test/FrontendC/2007-05-08-PCH.c +++ /dev/null @@ -1,7 +0,0 @@ -// PR 1400 -// RUN: %llvmgcc -x c-header %s -o /dev/null - -int main() { - return 0; -} - diff --git a/test/FrontendC/2007-05-11-str-const.c b/test/FrontendC/2007-05-11-str-const.c deleted file mode 100644 index 46a74c19e017..000000000000 --- a/test/FrontendC/2007-05-11-str-const.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc -S -g %s -o /dev/null - -static unsigned char out[]={0,1}; -static const unsigned char str1[]="1"; - diff --git a/test/FrontendC/2007-05-15-PaddingElement.c b/test/FrontendC/2007-05-15-PaddingElement.c deleted file mode 100644 index bad6a11dae81..000000000000 --- a/test/FrontendC/2007-05-15-PaddingElement.c +++ /dev/null @@ -1,23 +0,0 @@ -// PR 1419 - -// RUN: %llvmgcc -xc -O2 %s -S -o - | grep "ret i32 1" -struct A { - short x; - long long :0; -}; - -struct B { - char a; - char b; - unsigned char i; -}; - -union X { struct A a; struct B b; }; - -int check(void) { - union X x, y; - - y.b.i = 0xff; - x = y; - return (x.b.i == 0xff); -} diff --git a/test/FrontendC/2007-05-16-EmptyStruct.c b/test/FrontendC/2007-05-16-EmptyStruct.c deleted file mode 100644 index 7b2ab61bccaf..000000000000 --- a/test/FrontendC/2007-05-16-EmptyStruct.c +++ /dev/null @@ -1,5 +0,0 @@ -// PR 1417 - -// RUN: %llvmgcc -xc %s -S -o - | grep "struct.anon = type \{\}" - -struct { } *X; diff --git a/test/FrontendC/2007-05-29-UnionCopy.c b/test/FrontendC/2007-05-29-UnionCopy.c deleted file mode 100644 index 95ab388c842f..000000000000 --- a/test/FrontendC/2007-05-29-UnionCopy.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -S -o - %s | grep memcpy -// PR1421 - -struct A { - char c; - int i; -}; - -struct B { - int c; - unsigned char x; -}; - -union U { struct A a; struct B b; }; - -void check(union U *u, union U *v) { - *u = *v; -} diff --git a/test/FrontendC/2007-06-05-NoInlineAttribute.c b/test/FrontendC/2007-06-05-NoInlineAttribute.c deleted file mode 100644 index 9543538fb1b9..000000000000 --- a/test/FrontendC/2007-06-05-NoInlineAttribute.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %llvmgcc -O2 -S %s -o - | grep call - -static int bar(int x, int y) __attribute__((noinline)); - -static int bar(int x, int y) -{ - return x + y; -} - -int foo(int a, int b) { - return bar(b, a); -} - diff --git a/test/FrontendC/2007-06-15-AnnotateAttribute.c b/test/FrontendC/2007-06-15-AnnotateAttribute.c deleted file mode 100644 index 115c3f73b90b..000000000000 --- a/test/FrontendC/2007-06-15-AnnotateAttribute.c +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep llvm.global.annotations -// RUN: %llvmgcc -S %s -o - | grep llvm.var.annotation | count 3 - -#include - -/* Global variable with attribute */ -int X __attribute__((annotate("GlobalValAnnotation"))); - -/* Function with attribute */ -int foo(int y) __attribute__((annotate("GlobalValAnnotation"))) - __attribute__((noinline)); - -int foo(int y __attribute__((annotate("LocalValAnnotation")))) { - int x __attribute__((annotate("LocalValAnnotation"))); - x = 34; - return y + x; -} - -int main() { - static int a __attribute__((annotate("GlobalValAnnotation"))); - a = foo(2); - printf("hello world%d\n", a); - return 0; -} diff --git a/test/FrontendC/2007-06-18-SextAttrAggregate.c b/test/FrontendC/2007-06-18-SextAttrAggregate.c deleted file mode 100644 index c395db220dc6..000000000000 --- a/test/FrontendC/2007-06-18-SextAttrAggregate.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc %s -o - -S -O3 | grep {i8 signext} -// PR1513 - -struct s{ -long a; -long b; -}; - -void f(struct s a, char *b, signed char C) { - -} diff --git a/test/FrontendC/2007-07-29-RestrictPtrArg.c b/test/FrontendC/2007-07-29-RestrictPtrArg.c deleted file mode 100644 index 5925d972b269..000000000000 --- a/test/FrontendC/2007-07-29-RestrictPtrArg.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep noalias - -void foo(int * __restrict myptr1, int * myptr2) { - myptr1[0] = 0; - myptr2[0] = 0; -} diff --git a/test/FrontendC/2007-08-01-LoadStoreAlign.c b/test/FrontendC/2007-08-01-LoadStoreAlign.c deleted file mode 100644 index 5365c06c2579..000000000000 --- a/test/FrontendC/2007-08-01-LoadStoreAlign.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc -O3 -S -o - %s | grep {align 1} | count 2 -// RUN: %llvmgcc -O3 -S -o - %s | llc - -struct p { - char a; - int b; -} __attribute__ ((packed)); - -struct p t = { 1, 10 }; -struct p u; - -int main () { - int tmp = t.b; - u.b = tmp; - return tmp; - -} diff --git a/test/FrontendC/2007-08-21-ComplexCst.c b/test/FrontendC/2007-08-21-ComplexCst.c deleted file mode 100644 index ebdee14bba35..000000000000 --- a/test/FrontendC/2007-08-21-ComplexCst.c +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: %llvmgcc -O2 -S %s -o /dev/null -void f(_Complex float z); -void g() { f(1.0i); } diff --git a/test/FrontendC/2007-08-22-CTTZ.c b/test/FrontendC/2007-08-22-CTTZ.c deleted file mode 100644 index 9e74f24cdcb8..000000000000 --- a/test/FrontendC/2007-08-22-CTTZ.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -O2 -S -o - %s | grep {llvm.cttz.i64} | count 2 -// RUN: %llvmgcc -O2 -S -o - %s | not grep {lshr} - -int bork(unsigned long long x) { - return __builtin_ctzll(x); -} diff --git a/test/FrontendC/2007-09-05-ConstCtor.c b/test/FrontendC/2007-09-05-ConstCtor.c deleted file mode 100644 index adae4a69b103..000000000000 --- a/test/FrontendC/2007-09-05-ConstCtor.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -xc -Os -S %s -o /dev/null -// PR1641 - -struct A { - unsigned long l; -}; - -void bar(struct A *a); - -void bork() { - const unsigned long vcgt = 1234; - struct A a = { vcgt }; - bar(&a); -} diff --git a/test/FrontendC/2007-09-12-PragmaPack.c b/test/FrontendC/2007-09-12-PragmaPack.c deleted file mode 100644 index 4fc7f48be01c..000000000000 --- a/test/FrontendC/2007-09-12-PragmaPack.c +++ /dev/null @@ -1,30 +0,0 @@ -// RUN: %llvmgcc -O3 -S -o - %s | grep {18} - -#include - -#pragma pack(push, 1) -typedef struct -{ - uint32_t a; -} foo; - -typedef struct { - uint8_t major; - uint8_t minor; - uint16_t build; -} VERSION; - -typedef struct { - uint8_t a[5]; - VERSION version; - uint8_t b; - foo d; - uint32_t guard; -} bar; -#pragma pack(pop) - - -unsigned barsize(void) { - return sizeof(bar); -} - diff --git a/test/FrontendC/2007-09-14-NegatePointer.c b/test/FrontendC/2007-09-14-NegatePointer.c deleted file mode 100644 index cb49e46ddb11..000000000000 --- a/test/FrontendC/2007-09-14-NegatePointer.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -o - -// PR1662 - -int foo(unsigned char *test) { - return 0U - (unsigned int )test; -} - diff --git a/test/FrontendC/2007-09-17-WeakRef.c b/test/FrontendC/2007-09-17-WeakRef.c deleted file mode 100644 index 6c420ea38a78..000000000000 --- a/test/FrontendC/2007-09-17-WeakRef.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -O1 -S %s -o - | grep icmp -// PR1678 - -extern void B (void); -static __typeof(B) A __attribute__ ((__weakref__("B"))); -int active (void) -{ - static void *const p = __extension__ (void *) &A; - return p != 0; -} diff --git a/test/FrontendC/2007-09-20-GcrootAttribute.c b/test/FrontendC/2007-09-20-GcrootAttribute.c deleted file mode 100644 index b67b474c4c1b..000000000000 --- a/test/FrontendC/2007-09-20-GcrootAttribute.c +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep llvm.gcroot -// RUN: %llvmgcc -S %s -o - | grep llvm.gcroot | count 6 -// RUN: %llvmgcc -S %s -o - | llvm-as - -typedef struct foo_s -{ - int a; -} foo, __attribute__ ((gcroot)) *foo_p; - -foo my_foo; - -int alpha () -{ - foo my_foo2 = my_foo; - - return my_foo2.a; -} - -int bar (foo a) -{ - foo_p b; - return b->a; -} - -foo_p baz (foo_p a, foo_p b, foo_p *c) -{ - a = b = *c; - return a; -} diff --git a/test/FrontendC/2007-09-26-Alignment.c b/test/FrontendC/2007-09-26-Alignment.c deleted file mode 100644 index 1638fed05873..000000000000 --- a/test/FrontendC/2007-09-26-Alignment.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep {align 16} -extern p(int *); -int q(void) { - int x __attribute__ ((aligned (16))); - p(&x); - return x; -} diff --git a/test/FrontendC/2007-09-27-ComplexIntCompare.c b/test/FrontendC/2007-09-27-ComplexIntCompare.c deleted file mode 100644 index 50626e548c61..000000000000 --- a/test/FrontendC/2007-09-27-ComplexIntCompare.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc -S %s -o - -// PR1708 - -#include - -struct s { _Complex unsigned short x; }; -struct s gs = { 100 + 200i }; -struct s __attribute__((noinline)) foo (void) { return gs; } - -int main () -{ - if (foo ().x != gs.x) - abort (); - exit (0); -} - - diff --git a/test/FrontendC/2007-09-28-PackedUnionMember.c b/test/FrontendC/2007-09-28-PackedUnionMember.c deleted file mode 100644 index 79f48ceaeeae..000000000000 --- a/test/FrontendC/2007-09-28-PackedUnionMember.c +++ /dev/null @@ -1,38 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -#pragma pack(push, 2) -struct H { - unsigned long f1; - unsigned long f2; - union { - struct opaque1 *f3; - struct opaque2 *f4; - struct { - struct opaque3 *f5; - unsigned short f6; - } f7; - } f8; -}; -#pragma pack(pop) - -struct E { - unsigned long f1; - unsigned long f2; -}; - -typedef long (*FuncPtr) (); - -extern long bork(FuncPtr handler, const struct E *list); - -static long hndlr() -{ - struct H cmd = { 4, 412 }; - return 0; -} -void foo(void *inWindow) { - static const struct E events[] = { - { 123124, 1 } - }; - bork(hndlr, events); -} - diff --git a/test/FrontendC/2007-10-01-BuildArrayRef.c b/test/FrontendC/2007-10-01-BuildArrayRef.c deleted file mode 100644 index e87a5b630540..000000000000 --- a/test/FrontendC/2007-10-01-BuildArrayRef.c +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: not %llvmgcc_only -c %s -o /dev/null |& FileCheck %s -// PR 1603 -void func() -{ - const int *arr; - arr[0] = 1; // CHECK: error: assignment of read-only location -} - -struct foo { - int bar; -}; -struct foo sfoo = { 0 }; - -int func2() -{ - const struct foo *fp; - fp = &sfoo; - fp[0].bar = 1; // CHECK: error: assignment of read-only member 'bar' - return sfoo.bar; -} diff --git a/test/FrontendC/2007-10-02-VolatileArray.c b/test/FrontendC/2007-10-02-VolatileArray.c deleted file mode 100644 index 7e8bf24a84b8..000000000000 --- a/test/FrontendC/2007-10-02-VolatileArray.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep volatile -// PR1647 - -void foo(volatile int *p) -{ -p[0] = 0; -} diff --git a/test/FrontendC/2007-10-15-VoidPtr.c b/test/FrontendC/2007-10-15-VoidPtr.c deleted file mode 100644 index c5948b93e163..000000000000 --- a/test/FrontendC/2007-10-15-VoidPtr.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc -S %s -o /dev/null -void bork(void **data) { - (*(unsigned short *) (&(data[37])[927]) = 0); -} diff --git a/test/FrontendC/2007-10-30-Volatile.c b/test/FrontendC/2007-10-30-Volatile.c deleted file mode 100644 index 7a75b05d5d2b..000000000000 --- a/test/FrontendC/2007-10-30-Volatile.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -o /dev/null -Wall -Werror -void bork() { - char * volatile p; - volatile int cc; - p += cc; -} diff --git a/test/FrontendC/2007-11-07-AlignedMemcpy.c b/test/FrontendC/2007-11-07-AlignedMemcpy.c deleted file mode 100644 index eb9d22c62523..000000000000 --- a/test/FrontendC/2007-11-07-AlignedMemcpy.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc -S %s -o /dev/null -void bork() { - int Qux[33] = {0}; -} diff --git a/test/FrontendC/2007-11-07-CopyAggregateAlign.c b/test/FrontendC/2007-11-07-CopyAggregateAlign.c deleted file mode 100644 index 8bd94b00a783..000000000000 --- a/test/FrontendC/2007-11-07-CopyAggregateAlign.c +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep "align 2" | count 6 -struct A { char s, t, u, v; short a; }; -void q() { struct A a, b; a = b; } diff --git a/test/FrontendC/2007-11-07-ZeroAggregateAlign.c b/test/FrontendC/2007-11-07-ZeroAggregateAlign.c deleted file mode 100644 index 424120d6c217..000000000000 --- a/test/FrontendC/2007-11-07-ZeroAggregateAlign.c +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep "align 2" -struct A { short s; short t; int i; }; -void q() { struct A a = {0}; } diff --git a/test/FrontendC/2007-11-27-SExtZExt.c b/test/FrontendC/2007-11-27-SExtZExt.c deleted file mode 100644 index 8ea4786af369..000000000000 --- a/test/FrontendC/2007-11-27-SExtZExt.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep "signext" | count 4 - -signed char foo1() { return 1; } - -void foo2(signed short a) { } - -signed char foo3(void) { return 1; } - -void foo4(a) signed short a; { } - - - diff --git a/test/FrontendC/2007-11-28-GlobalInitializer.c b/test/FrontendC/2007-11-28-GlobalInitializer.c deleted file mode 100644 index c8c7a594d0b6..000000000000 --- a/test/FrontendC/2007-11-28-GlobalInitializer.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -o - -// PR1744 -typedef struct foo { int x; char *p; } FOO; -extern FOO yy[]; - -int *y = &((yy + 1)->x); -void *z = &((yy + 1)->x); - diff --git a/test/FrontendC/2007-12-16-AsmNoUnwind.c b/test/FrontendC/2007-12-16-AsmNoUnwind.c deleted file mode 100644 index b080e6a511e8..000000000000 --- a/test/FrontendC/2007-12-16-AsmNoUnwind.c +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | grep nounwind - -void bar() { asm (""); } diff --git a/test/FrontendC/2007-12-VarArrayDebug.c b/test/FrontendC/2007-12-VarArrayDebug.c deleted file mode 100644 index 966789eef30d..000000000000 --- a/test/FrontendC/2007-12-VarArrayDebug.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -S -g -O %s -o - | llc -// RUN: %llvmgcc -S -g %s -o - | llc - -extern void foo (void); - -static -void baz (int i) -{ - foo (); - typedef char A[i]; - struct { A b; } *x = 0; -} - -void -bar (i) -{ - baz (i); -} diff --git a/test/FrontendC/2008-01-04-WideBitfield.c b/test/FrontendC/2008-01-04-WideBitfield.c deleted file mode 100644 index a0045a402762..000000000000 --- a/test/FrontendC/2008-01-04-WideBitfield.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %llvmgcc -S -o - %s -// PR1386 -#include - -struct X { - unsigned char pad : 4; - uint64_t a : 64; -} __attribute__((packed)) x; - -uint64_t f(void) -{ - return x.a; -} diff --git a/test/FrontendC/2008-01-07-UnusualIntSize.c b/test/FrontendC/2008-01-07-UnusualIntSize.c deleted file mode 100644 index 91beaf3528de..000000000000 --- a/test/FrontendC/2008-01-07-UnusualIntSize.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc %s -S -o - -O | grep i33 -// PR1721 - -struct s { - unsigned long long u33: 33; -} a, b; - -// This should turn into a real 33-bit add, not a 64-bit add. -_Bool test(void) { - return a.u33 + b.u33 != 0; -} diff --git a/test/FrontendC/2008-01-11-ChainConsistency.c b/test/FrontendC/2008-01-11-ChainConsistency.c deleted file mode 100644 index 13e48a34ac52..000000000000 --- a/test/FrontendC/2008-01-11-ChainConsistency.c +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: %llvmgcc -S %s -o - -fnested-functions | not grep nest - -void n1(void) { void a(void) { a(); } a(); } diff --git a/test/FrontendC/2008-01-21-PackedBitFields.c b/test/FrontendC/2008-01-21-PackedBitFields.c deleted file mode 100644 index 4c38dee408cb..000000000000 --- a/test/FrontendC/2008-01-21-PackedBitFields.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -typedef double Al1Double __attribute__((aligned(1))); -struct x { int a:23; Al1Double v; }; -struct x X = { 5, 3.0 }; -double foo() { return X.v; } - diff --git a/test/FrontendC/2008-01-21-PackedStructField.c b/test/FrontendC/2008-01-21-PackedStructField.c deleted file mode 100644 index 9cc1731063f5..000000000000 --- a/test/FrontendC/2008-01-21-PackedStructField.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -struct X { long double b; unsigned char c; double __attribute__((packed)) d; }; -struct X x = { 3.0L, 5, 3.0 }; - - -struct S2504 { - int e:17; - __attribute__((packed)) unsigned long long int f; -} ; -int fails; - extern struct S2504 s2504; -void check2504va (int z) { - struct S2504 arg, *p; - long long int i = 0; - arg.f = i; -} - diff --git a/test/FrontendC/2008-01-24-StructAlignAndBitFields.c b/test/FrontendC/2008-01-24-StructAlignAndBitFields.c deleted file mode 100644 index 380a7ef77ca5..000000000000 --- a/test/FrontendC/2008-01-24-StructAlignAndBitFields.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -struct U { char a; short b; int c:25; char d; } u; - diff --git a/test/FrontendC/2008-01-25-ByValReadNone.c b/test/FrontendC/2008-01-25-ByValReadNone.c deleted file mode 100644 index 4cb1a6394eaa..000000000000 --- a/test/FrontendC/2008-01-25-ByValReadNone.c +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %llvmgcc -O3 -S -o - %s | not grep readonly -// RUN: %llvmgcc -O3 -S -o - %s | not grep readnone - - -// The struct being passed byval means that we cannot mark the -// function readnone. Readnone would allow stores to the arg to -// be deleted in the caller. We also don't allow readonly since -// the callee might write to the byval parameter. The inliner -// would have to assume the worse and introduce an explicit -// temporary when inlining such a function, which is costly for -// the common case in which the byval argument is not written. -struct S { int A[1000]; }; -int __attribute__ ((const)) f(struct S x) { x.A[1] = 0; return x.A[0]; } -int g(struct S x) __attribute__ ((pure)); -int h(struct S x) { return g(x); } diff --git a/test/FrontendC/2008-01-25-ZeroSizedAggregate.c b/test/FrontendC/2008-01-25-ZeroSizedAggregate.c deleted file mode 100644 index 643caffb6d2a..000000000000 --- a/test/FrontendC/2008-01-25-ZeroSizedAggregate.c +++ /dev/null @@ -1,39 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - -// Aggregates of size zero should be dropped from argument list. -typedef long int Tlong; -struct S2411 { - __attribute__((aligned)) Tlong:0; -}; - -extern struct S2411 a2411[5]; -extern void checkx2411(struct S2411); -void test2411(void) { - checkx2411(a2411[0]); -} - -// Proper handling of zero sized fields during type conversion. -typedef unsigned long long int Tal2ullong __attribute__((aligned(2))); -struct S2525 { - Tal2ullong: 0; - struct { - } e; -}; -struct S2525 s2525; - -struct { - signed char f; - char :0; - struct{}h; - char * i[5]; -} data; - -// Taking address of a zero sized field. -struct Z {}; -struct Y { - int i; - struct Z z; -}; -void *f(struct Y *y) { - return &y->z; -} diff --git a/test/FrontendC/2008-01-28-PragmaMark.c b/test/FrontendC/2008-01-28-PragmaMark.c deleted file mode 100644 index 6a4b5b52ff2f..000000000000 --- a/test/FrontendC/2008-01-28-PragmaMark.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -Werror -S %s -o /dev/null -#pragma mark LLVM's world -#ifdef DO_ERROR -#error LLVM's world -#endif -int i; diff --git a/test/FrontendC/2008-01-28-UnionSize.c b/test/FrontendC/2008-01-28-UnionSize.c deleted file mode 100644 index ea2c863b1848..000000000000 --- a/test/FrontendC/2008-01-28-UnionSize.c +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %llvmgcc %s -S -o - -// PR 1861 - -typedef unsigned char __u8; -typedef unsigned int __u32; -typedef unsigned short u16; -typedef __u32 __le32; -struct bcm43xx_plcp_hdr6 { - union { - __le32 data; - __u8 raw[6]; - } - __attribute__((__packed__)); -} - __attribute__((__packed__)); -struct bcm43xx_txhdr { - union { - struct { - struct bcm43xx_plcp_hdr6 plcp; - }; - }; -} - __attribute__((__packed__)); -static void bcm43xx_generate_rts(struct bcm43xx_txhdr *txhdr ) { } diff --git a/test/FrontendC/2008-02-11-AnnotateBuiltin.c b/test/FrontendC/2008-02-11-AnnotateBuiltin.c deleted file mode 100644 index 32bc7a827450..000000000000 --- a/test/FrontendC/2008-02-11-AnnotateBuiltin.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | llvm-as | llvm-dis | grep llvm.annotation - -int main() { - int x = 0; - return __builtin_annotation(x, "annotate"); -} - diff --git a/test/FrontendC/2008-03-03-CtorAttrType.c b/test/FrontendC/2008-03-03-CtorAttrType.c deleted file mode 100644 index 96648f4ec5a6..000000000000 --- a/test/FrontendC/2008-03-03-CtorAttrType.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | grep llvm.global_ctors -int __attribute__((constructor)) foo(void) { - return 0; -} -void __attribute__((constructor)) bar(void) {} - diff --git a/test/FrontendC/2008-03-05-syncPtr.c b/test/FrontendC/2008-03-05-syncPtr.c deleted file mode 100644 index 7b271f7ee747..000000000000 --- a/test/FrontendC/2008-03-05-syncPtr.c +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | grep llvm.atomic -// XFAIL: sparc-sun-solaris2|arm -// Feature currently implemented only for x86, alpha, powerpc. - -int* foo(int** a, int* b, int* c) { -return __sync_val_compare_and_swap (a, b, c); -} - -int foo2(int** a, int* b, int* c) { -return __sync_bool_compare_and_swap (a, b, c); -} - -int* foo3(int** a, int b) { - return __sync_fetch_and_add (a, b); -} - -int* foo4(int** a, int b) { - return __sync_fetch_and_sub (a, b); -} - -int* foo5(int** a, int* b) { - return __sync_lock_test_and_set (a, b); -} - -int* foo6(int** a, int*** b) { - return __sync_lock_test_and_set (a, b); -} diff --git a/test/FrontendC/2008-03-24-BitField-And-Alloca.c b/test/FrontendC/2008-03-24-BitField-And-Alloca.c deleted file mode 100644 index 641bcf1dbeb9..000000000000 --- a/test/FrontendC/2008-03-24-BitField-And-Alloca.c +++ /dev/null @@ -1,89 +0,0 @@ -// RUN: %llvmgcc -O2 -S %s -o - | not grep alloca -// RUN: %llvmgcc -m32 -O2 -S %s -o - | not grep {store } - -enum { - PP_C, - PP_D, - PP_R, - PP_2D, - PP_1D, - PP_SR, - PP_S2D, - PP_S1D, - PP_SC -}; - -enum { - G_VP, - G_FP, - G_VS, - G_GS, - G_FS -}; - -enum { - G_NONE, - G_B, - G_R -}; - -typedef union _Key { - struct { - unsigned int count : 2; - unsigned int Aconst : 1; - unsigned int Bconst : 1; - unsigned int Cconst : 1; - unsigned int Xused : 1; - unsigned int Yused : 1; - unsigned int Zused : 1; - unsigned int Wused : 1; - unsigned int ttype : 3; - unsigned int scalar : 1; - unsigned int AType : 4; - unsigned int BType : 4; - unsigned int CType : 4; - unsigned int RType : 4; - unsigned int Size : 2; - unsigned int prec : 1; - - unsigned int ASize : 2; - unsigned int BSize : 2; - unsigned int CSize : 2; - unsigned int tTex : 4; - unsigned int proj : 1; - unsigned int lod : 2; - unsigned int dvts : 1; - unsigned int uipad : 18; - } key_io; - struct { - unsigned int key0; - unsigned int key1; - } key; - unsigned long long lkey; -} Key; - -static void foo(const Key iospec, int* ret) -{ - *ret=0; - if(((iospec.key_io.lod == G_B) && - (iospec.key_io.ttype != G_VS) && - (iospec.key_io.ttype != G_GS) && - (iospec.key_io.ttype != G_FS)) || - - (((iospec.key_io.tTex == PP_C) || - (iospec.key_io.tTex == PP_SC)) && - ((iospec.key_io.tTex == PP_SR) || - (iospec.key_io.tTex == PP_S2D) || - (iospec.key_io.tTex == PP_S1D) || - (iospec.key_io.tTex == PP_SC)))) - *ret=1; -} - - -extern int bar(unsigned long long key_token2) -{ - int ret; - __attribute__ ((unused)) Key iospec = (Key) key_token2; - foo(iospec, &ret); - return ret; -} diff --git a/test/FrontendC/2008-03-26-PackedBitFields.c b/test/FrontendC/2008-03-26-PackedBitFields.c deleted file mode 100644 index 7214281d020c..000000000000 --- a/test/FrontendC/2008-03-26-PackedBitFields.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc %s -S -o - - - -struct S1757 { - long double c; - long int __attribute__((packed)) e:28; -} x; diff --git a/test/FrontendC/2008-04-08-NoExceptions.c b/test/FrontendC/2008-04-08-NoExceptions.c deleted file mode 100644 index 257fee23b068..000000000000 --- a/test/FrontendC/2008-04-08-NoExceptions.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S -o - %s | grep nounwind | count 2 -// RUN: %llvmgcc -S -o - %s | not grep {declare.*nounwind} - -void f(void); -void g(void) { - f(); -} diff --git a/test/FrontendC/2008-05-06-CFECrash.c b/test/FrontendC/2008-05-06-CFECrash.c deleted file mode 100644 index 94d556c1ec29..000000000000 --- a/test/FrontendC/2008-05-06-CFECrash.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc -S -O2 %s -o /dev/null -// PR2292. -__inline__ __attribute__ ((__pure__)) int g (void) {} -void f (int k) { k = g (); } diff --git a/test/FrontendC/2008-05-12-TempUsedBeforeDef.c b/test/FrontendC/2008-05-12-TempUsedBeforeDef.c deleted file mode 100644 index 21724c1c830f..000000000000 --- a/test/FrontendC/2008-05-12-TempUsedBeforeDef.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -w -S -o /dev/null %s -// PR2264. -unsigned foo = 8L; -unsigned bar = 0L; -volatile unsigned char baz = 6L; -int test() { - char qux = 1L; - for (; baz >= -29; baz--) - bork(bar && foo, qux); -} diff --git a/test/FrontendC/2008-05-19-AlwaysInline.c b/test/FrontendC/2008-05-19-AlwaysInline.c deleted file mode 100644 index 8dcb57b1862e..000000000000 --- a/test/FrontendC/2008-05-19-AlwaysInline.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc %s -S -fno-unit-at-a-time -O0 -o - | not grep sabrina -// RUN: %llvmgcc %s -S -funit-at-a-time -O0 -o - | not grep sabrina - -static inline int sabrina (void) __attribute__((always_inline)); -static inline int sabrina (void) -{ - return 13; -} -int bar (void) -{ - return sabrina () + 68; -} diff --git a/test/FrontendC/2008-07-08-FAbsAttributes.c b/test/FrontendC/2008-07-08-FAbsAttributes.c deleted file mode 100644 index 1eb01dcedbe6..000000000000 --- a/test/FrontendC/2008-07-08-FAbsAttributes.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep readnone -// PR2520 -#include -double f(double *x, double *y) { return fabs(*x + *y); } diff --git a/test/FrontendC/2008-08-07-AlignPadding1.c b/test/FrontendC/2008-08-07-AlignPadding1.c deleted file mode 100644 index 6be9fe4ed3b5..000000000000 --- a/test/FrontendC/2008-08-07-AlignPadding1.c +++ /dev/null @@ -1,29 +0,0 @@ -/* RUN: %llvmgcc %s -S -o - -O0 | grep {zeroinitializer.*zeroinitializer.*zeroinitializer.*zeroinitializer.*zeroinitializer.*zeroinitializer} - -The FE must generate padding here both at the end of each PyG_Head and -between array elements. Reduced from Python. */ - -typedef union _gc_head { - struct { - union _gc_head *gc_next; - union _gc_head *gc_prev; - long gc_refs; - } gc; - int dummy __attribute__((aligned(16))); -} PyGC_Head; - -struct gc_generation { - PyGC_Head head; - int threshold; - int count; -}; - -#define GEN_HEAD(n) (&generations[n].head) - -/* linked lists of container objects */ -static struct gc_generation generations[3] = { - /* PyGC_Head, threshold, count */ - {{{GEN_HEAD(0), GEN_HEAD(0), 0}}, 700, 0}, - {{{GEN_HEAD(1), GEN_HEAD(1), 0}}, 10, 0}, - {{{GEN_HEAD(2), GEN_HEAD(2), 0}}, 10, 0}, -}; diff --git a/test/FrontendC/2008-08-07-AlignPadding2.c b/test/FrontendC/2008-08-07-AlignPadding2.c deleted file mode 100644 index 51135ba633a2..000000000000 --- a/test/FrontendC/2008-08-07-AlignPadding2.c +++ /dev/null @@ -1,18 +0,0 @@ -/* RUN: %llvmgcc %s -S -o - -O0 | grep zeroinitializer | count 1 - -The FE must not generate padding here between array elements. PR 2533. */ - -typedef struct { - const char *name; - int flags; - union { - int x; - } u; -} OptionDef; - -const OptionDef options[] = { - /* main options */ - { "a", 0, {3} }, - { "b", 0, {4} }, - { 0, }, -}; diff --git a/test/FrontendC/2008-08-07-GEPIntToPtr.c b/test/FrontendC/2008-08-07-GEPIntToPtr.c deleted file mode 100644 index 3ef3b66b88f8..000000000000 --- a/test/FrontendC/2008-08-07-GEPIntToPtr.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep {i8 1} -// PR2603 - -struct A { - char num_fields; -}; - -struct B { - char a, b[1]; -}; - -const struct A Foo = { - (char *)(&( (struct B *)(16) )->b[0]) - (char *)(16) -}; diff --git a/test/FrontendC/2008-09-03-WeakAlias.c b/test/FrontendC/2008-09-03-WeakAlias.c deleted file mode 100644 index 2e5f3dae8a00..000000000000 --- a/test/FrontendC/2008-09-03-WeakAlias.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -S -O1 -o - %s | grep icmp -// PR1678 -extern void B (void); -static __typeof(B) A __attribute__ ((__weakref__("B"))); -int active (void) -{ - static void *const p = __extension__ (void *) &A; - return p != 0; -} diff --git a/test/FrontendC/2008-10-13-FrontendCrash.c b/test/FrontendC/2008-10-13-FrontendCrash.c deleted file mode 100644 index c9731e34ced8..000000000000 --- a/test/FrontendC/2008-10-13-FrontendCrash.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc %s -S -o - -// PR2797 - -unsigned int -func_48 (signed char p_49) -{ - signed char l_340; - func_44 (1&((1 ^ 1 == (lshift_u_s (1)) != (l_340 < 1)) & 1L)); -} diff --git a/test/FrontendC/2008-10-30-ZeroPlacement.c b/test/FrontendC/2008-10-30-ZeroPlacement.c deleted file mode 100644 index d73442dca8b9..000000000000 --- a/test/FrontendC/2008-10-30-ZeroPlacement.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -S %s -// PR2987 -struct S2045 -{ - unsigned short int a; - union { } b; - union __attribute__ ((aligned (4))) { } c[0]; -}; -struct S2045 s2045; diff --git a/test/FrontendC/2008-11-02-WeakAlias.c b/test/FrontendC/2008-11-02-WeakAlias.c deleted file mode 100644 index d10e57f5efe0..000000000000 --- a/test/FrontendC/2008-11-02-WeakAlias.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc -S -o - %s | grep weak -// PR2691 - -void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ"))); -void native_init_IRQ(void) {} diff --git a/test/FrontendC/2008-11-08-InstCombineSelect.c b/test/FrontendC/2008-11-08-InstCombineSelect.c deleted file mode 100644 index b850d3ff6f25..000000000000 --- a/test/FrontendC/2008-11-08-InstCombineSelect.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc %s -S -O2 -o - -// PR3028 - -int g_187; -int g_204; -int g_434; - -int func_89 (void) -{ - return 1; -} - -void func_20 (int p_22) -{ - if (1 & p_22 | g_204 & (1 < g_187) - func_89 ()) - g_434 = 1; -} diff --git a/test/FrontendC/2008-11-11-AnnotateStructFieldAttribute.c b/test/FrontendC/2008-11-11-AnnotateStructFieldAttribute.c deleted file mode 100644 index 8af59d54f751..000000000000 --- a/test/FrontendC/2008-11-11-AnnotateStructFieldAttribute.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep llvm.ptr.annotation | count 3 - -#include - -/* Struct with element X being annotated */ -struct foo { - int X __attribute__((annotate("StructAnnotation"))); - int Y; - int Z; -}; - - -void test(struct foo *F) { - F->X = 42; - F->Z = 1; - F->Y = F->X; -} - diff --git a/test/FrontendC/2008-12-23-AsmIntPointerTie.c b/test/FrontendC/2008-12-23-AsmIntPointerTie.c deleted file mode 100644 index 57061422b8f2..000000000000 --- a/test/FrontendC/2008-12-23-AsmIntPointerTie.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc %s -S -O1 -o - - -#include - -int test(void *b) { - intptr_t a; - __asm__ __volatile__ ("%0 %1 " : "=r" (a): "0" (b)); - return a; -} diff --git a/test/FrontendC/2009-01-05-BlockInlining.c b/test/FrontendC/2009-01-05-BlockInlining.c deleted file mode 100644 index 8fb6e54514a5..000000000000 --- a/test/FrontendC/2009-01-05-BlockInlining.c +++ /dev/null @@ -1,28 +0,0 @@ -// RUN: %llvmgcc %s -S -O2 -o %t.s -// RUN: grep {call i32 .*printf.*argc} %t.s | count 3 -// RUN: not grep __block_holder_tmp %t.s -// rdar://5865221 - -// All of these should be inlined equivalently into a single printf call. - -static int fun(int x) { - return x+1; -} - -static int block(int x) { - return (^(int x){return x+1;})(x); -} - -static void print(int result) { - printf("%d\n", result); -} - -int main (int argc, const char * argv[]) { - int x = argc-1; - print(fun(x)); - print(block(x)); - int (^block_inline)(int) = ^(int x){return x+1;}; - print(block_inline(x)); - return 0; -} - diff --git a/test/FrontendC/2009-01-20-k8.c b/test/FrontendC/2009-01-20-k8.c deleted file mode 100644 index 2cd15387390c..000000000000 --- a/test/FrontendC/2009-01-20-k8.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc %s -S -march=k8 -o /dev/null -// XFAIL: * -// XTARGET: x86,i386,i686 -long double x; diff --git a/test/FrontendC/2009-01-21-InvalidIterator.c b/test/FrontendC/2009-01-21-InvalidIterator.c deleted file mode 100644 index 6ac61f8a748b..000000000000 --- a/test/FrontendC/2009-01-21-InvalidIterator.c +++ /dev/null @@ -1,74 +0,0 @@ -// RUN: %llvmgcc %s -S -g -o /dev/null - -typedef long unsigned int size_t; -typedef unsigned short int uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long int uint64_t; -typedef uint16_t Elf64_Half; -typedef uint32_t Elf64_Word; -typedef uint64_t Elf64_Xword; -typedef uint64_t Elf64_Addr; -typedef uint64_t Elf64_Off; -typedef struct -{ - Elf64_Word p_type; - Elf64_Off p_offset; - Elf64_Addr p_vaddr; - Elf64_Xword p_align; -} -Elf64_Phdr; -struct dl_phdr_info -{ - const char *dlpi_name; - const Elf64_Phdr *dlpi_phdr; - Elf64_Half dlpi_phnum; - unsigned long long int dlpi_adds; -}; -typedef unsigned _Unwind_Ptr; -struct object -{ - union - { - const struct dwarf_fde *single; - struct dwarf_fde **array; - struct fde_vector *sort; - } - u; - union - { - struct - { - } - b; - } - s; - struct object *next; -}; -typedef int sword; -typedef unsigned int uword; -struct dwarf_fde -{ - uword length; - sword CIE_delta; - unsigned char pc_begin[]; -}; -typedef struct dwarf_fde fde; -struct unw_eh_callback_data -{ - const fde *ret; - struct frame_hdr_cache_element *link; -} -frame_hdr_cache[8]; - -_Unwind_Ptr -base_from_cb_data (struct unw_eh_callback_data *data) -{ -} - -void -_Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) -{ - const unsigned char *p; - const struct unw_eh_frame_hdr *hdr; - struct object ob; -} diff --git a/test/FrontendC/2009-02-13-zerosize-union-field-ppc.c b/test/FrontendC/2009-02-13-zerosize-union-field-ppc.c deleted file mode 100644 index 947166d54ac4..000000000000 --- a/test/FrontendC/2009-02-13-zerosize-union-field-ppc.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc %s -m32 -S -o - | grep {i32 32} | count 3 -// XFAIL: * -// XTARGET: powerpc -// Every printf has 'i32 0' for the GEP of the string; no point counting those. -typedef unsigned int Foo __attribute__((aligned(32))); -typedef union{Foo:0;}a; -typedef union{int x; Foo:0;}b; -extern int printf(const char*, ...); -main() { - printf("%ld\n", sizeof(a)); - printf("%ld\n", __alignof__(a)); - printf("%ld\n", sizeof(b)); - printf("%ld\n", __alignof__(b)); -} diff --git a/test/FrontendC/2009-02-13-zerosize-union-field.c b/test/FrontendC/2009-02-13-zerosize-union-field.c deleted file mode 100644 index ad335583d46f..000000000000 --- a/test/FrontendC/2009-02-13-zerosize-union-field.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc %s -m32 -S -o - | grep {i32 1} | count 1 -// RUN: %llvmgcc %s -m32 -S -o - | grep {i32 4} | count 2 -// XFAIL: powerpc -// Every printf has 'i32 0' for the GEP of the string; no point counting those. -typedef unsigned int Foo __attribute__((aligned(32))); -typedef union{Foo:0;}a; -typedef union{int x; Foo:0;}b; -extern int printf(const char*, ...); -main() { - printf("%ld\n", sizeof(a)); - printf("%ld\n", __alignof__(a)); - printf("%ld\n", sizeof(b)); - printf("%ld\n", __alignof__(b)); -} diff --git a/test/FrontendC/2009-02-17-BitField-dbg.c b/test/FrontendC/2009-02-17-BitField-dbg.c deleted file mode 100644 index 88d2cbba48d8..000000000000 --- a/test/FrontendC/2009-02-17-BitField-dbg.c +++ /dev/null @@ -1,14 +0,0 @@ -// Check bitfields. -// RUN: %llvmgcc -S -O0 -g %s -o - | \ -// RUN: llc -disable-cfi --disable-fp-elim -o 2009-02-17-BitField-dbg.s -// RUN: %compile_c 2009-02-17-BitField-dbg.s -o 2009-02-17-BitField-dbg.o -// RUN: echo {ptype mystruct} > %t2 -// 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" -// - -struct { - int a:4; - int b:2; -} mystruct; - diff --git a/test/FrontendC/2009-03-01-MallocNoAlias.c b/test/FrontendC/2009-03-01-MallocNoAlias.c deleted file mode 100644 index 22ff6cb5c301..000000000000 --- a/test/FrontendC/2009-03-01-MallocNoAlias.c +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | grep noalias - -void * __attribute__ ((malloc)) foo (void) { return 0; } diff --git a/test/FrontendC/2009-03-08-ZeroEltStructCrash.c b/test/FrontendC/2009-03-08-ZeroEltStructCrash.c deleted file mode 100644 index 454e0fb79c68..000000000000 --- a/test/FrontendC/2009-03-08-ZeroEltStructCrash.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -S %s -o - -// PR3744 -struct Empty {}; -struct Union { - union { - int zero_arr[0]; - } contents; -}; -static inline void Foo(struct Union *u) { - int *array = u->contents.zero_arr; -} -static void Bar(struct Union *u) { - Foo(u); -} diff --git a/test/FrontendC/2009-03-09-WeakDeclarations-1.c b/test/FrontendC/2009-03-09-WeakDeclarations-1.c deleted file mode 100644 index 13ea84f7bae9..000000000000 --- a/test/FrontendC/2009-03-09-WeakDeclarations-1.c +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %llvmgcc_only %s -c -o /dev/null |& \ -// RUN: egrep {(14|15|22): warning:} | \ -// RUN: wc -l | grep --quiet 3 -// XTARGET: darwin,linux -// XFAIL: * -// END. -// Insist upon warnings for inappropriate weak attributes. -// Note the line numbers (14|15|22) embedded in the check. - -// O.K. -extern int ext_weak_import __attribute__ ((__weak_import__)); - -// These are inappropriate, and should generate warnings: -int decl_weak_import __attribute__ ((__weak_import__)); -int decl_initialized_weak_import __attribute__ ((__weak_import__)) = 13; - -// O.K. -extern int ext_f(void) __attribute__ ((__weak_import__)); - -// These are inappropriate, and should generate warnings: -int def_f(void) __attribute__ ((__weak_import__)); -int __attribute__ ((__weak_import__)) decl_f(void) {return 0;}; diff --git a/test/FrontendC/2009-03-13-dbg.c b/test/FrontendC/2009-03-13-dbg.c deleted file mode 100644 index 46abd3a96382..000000000000 --- a/test/FrontendC/2009-03-13-dbg.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc %s -S -g -o /dev/null -// XTARGET: darwin,linux -// XFAIL: * -void foo() {} - diff --git a/test/FrontendC/2009-04-22-UnknownSize.c b/test/FrontendC/2009-04-22-UnknownSize.c deleted file mode 100644 index 7db9c0730c80..000000000000 --- a/test/FrontendC/2009-04-22-UnknownSize.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: not %llvmgcc -O1 %s -S -o /dev/null |& grep {error: storage size} -// PR2958 -static struct foo s; -struct foo *p = &s; diff --git a/test/FrontendC/2009-04-28-UnionArrayCrash.c b/test/FrontendC/2009-04-28-UnionArrayCrash.c deleted file mode 100644 index 75851d0f5c01..000000000000 --- a/test/FrontendC/2009-04-28-UnionArrayCrash.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -S %s -o - -// PR4082 -union U { - int I; - double F; -}; - -union U arr[] = { { .I = 4 }, { .F = 123.} }; -union U *P = &arr[0]; - - diff --git a/test/FrontendC/2009-05-04-EnumInreg.c b/test/FrontendC/2009-05-04-EnumInreg.c deleted file mode 100644 index fb0c03e439e6..000000000000 --- a/test/FrontendC/2009-05-04-EnumInreg.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -S -m32 -mregparm=3 %s -o - | grep {inreg %action} -// XFAIL: * -// XTARGET: x86,i386,i686 -// PR3967 - -enum kobject_action { - KOBJ_ADD, - KOBJ_REMOVE, - KOBJ_CHANGE, - KOBJ_MOVE, - KOBJ_ONLINE, - KOBJ_OFFLINE, - KOBJ_MAX -}; - -struct kobject; - -int kobject_uevent(struct kobject *kobj, enum kobject_action action) {} diff --git a/test/FrontendC/2009-05-17-AlwaysInline.c b/test/FrontendC/2009-05-17-AlwaysInline.c deleted file mode 100644 index a93fabe05258..000000000000 --- a/test/FrontendC/2009-05-17-AlwaysInline.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc -S %s -O0 -o - -mllvm -disable-llvm-optzns | grep bar -// Check that the gcc inliner is turned off. - -#include -static __inline__ __attribute__ ((always_inline)) - int bar (int x) -{ - return 4; -} - -void -foo () -{ - long long b = 1; - int Y = bar (4); - printf ("%d\n", Y); -} diff --git a/test/FrontendC/2009-06-14-HighlyAligned.c b/test/FrontendC/2009-06-14-HighlyAligned.c deleted file mode 100644 index 227db74f47a0..000000000000 --- a/test/FrontendC/2009-06-14-HighlyAligned.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc %s -S -o /dev/null -// PR4332 - -static int highly_aligned __attribute__((aligned(4096))); - -int f() { - return highly_aligned; -} diff --git a/test/FrontendC/2009-06-18-StaticInitTailPadPack.c b/test/FrontendC/2009-06-18-StaticInitTailPadPack.c deleted file mode 100644 index 17f35c04a9ec..000000000000 --- a/test/FrontendC/2009-06-18-StaticInitTailPadPack.c +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: %llvmgcc %s -S -o - -// rdar://6983634 - - typedef struct A *Foo; -#pragma pack(push, 2) - struct Bar { - Foo f1; - unsigned short f2; - float f3; - }; - struct Baz { - struct Bar f1; - struct Bar f2; - }; - struct Qux { - unsigned long f1; - struct Baz f2; - }; -extern const struct Qux Bork; -const struct Qux Bork = { - 0, - { - {0}, - {0} - } -}; diff --git a/test/FrontendC/2009-07-14-VoidPtr.c b/test/FrontendC/2009-07-14-VoidPtr.c deleted file mode 100644 index 8001c56ad52a..000000000000 --- a/test/FrontendC/2009-07-14-VoidPtr.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -o - -// PR4556 - -extern void foo; -void *bar = &foo; - diff --git a/test/FrontendC/2009-07-15-pad-wchar_t-array.c b/test/FrontendC/2009-07-15-pad-wchar_t-array.c deleted file mode 100644 index 41bdef25ecca..000000000000 --- a/test/FrontendC/2009-07-15-pad-wchar_t-array.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null - -#include -signed short _iodbcdm_sqlerror( ) -{ - wchar_t _sqlState[6] = { L"\0" }; -} diff --git a/test/FrontendC/2009-07-17-VoidParameter.c b/test/FrontendC/2009-07-17-VoidParameter.c deleted file mode 100644 index d5769524386c..000000000000 --- a/test/FrontendC/2009-07-17-VoidParameter.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc -S %s -o - -// PR4214 -typedef void vt; -void (*func_ptr)(vt my_vt); diff --git a/test/FrontendC/2009-07-22-StructLayout.c b/test/FrontendC/2009-07-22-StructLayout.c deleted file mode 100644 index 74904da33e0c..000000000000 --- a/test/FrontendC/2009-07-22-StructLayout.c +++ /dev/null @@ -1,34 +0,0 @@ -// RUN: %llvmgcc %s -S -o /dev/null -// PR4590 - -typedef unsigned char __u8; -typedef unsigned int __le32; -typedef unsigned int __u32; -typedef unsigned short __le16; -typedef unsigned short __u16; - -struct usb_cdc_ether_desc { - __u8 bLength; - __u8 bDescriptorType; - __u8 bDescriptorSubType; - - __u8 iMACAddress; - __le32 bmEthernetStatistics; - __le16 wMaxSegmentSize; - __le16 wNumberMCFilters; - __u8 bNumberPowerFilters; -} __attribute__ ((packed)); - - -static struct usb_cdc_ether_desc ecm_desc __attribute__ ((__section__(".init.data"))) = { - .bLength = sizeof ecm_desc, - .bDescriptorType = ((0x01 << 5) | 0x04), - .bDescriptorSubType = 0x0f, - - - - .bmEthernetStatistics = (( __le32)(__u32)(0)), - .wMaxSegmentSize = (( __le16)(__u16)(1514)), - .wNumberMCFilters = (( __le16)(__u16)(0)), - .bNumberPowerFilters = 0, -}; diff --git a/test/FrontendC/2009-08-11-AsmBlocksComplexJumpTarget.c b/test/FrontendC/2009-08-11-AsmBlocksComplexJumpTarget.c deleted file mode 100644 index e141c9a16c80..000000000000 --- a/test/FrontendC/2009-08-11-AsmBlocksComplexJumpTarget.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc %s -fasm-blocks -S -o - | grep {\\\*1192} -// Complicated expression as jump target -// XFAIL: * -// XTARGET: x86,i386,i686 - -asm void Method3() -{ - mov eax,[esp+4] - jmp [eax+(299-1)*4] -} diff --git a/test/FrontendC/2009-09-24-SqrtErrno.c b/test/FrontendC/2009-09-24-SqrtErrno.c deleted file mode 100644 index 09fc8764ea51..000000000000 --- a/test/FrontendC/2009-09-24-SqrtErrno.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc %s -S -o - -fmath-errno | FileCheck %s -// llvm.sqrt has undefined behavior on negative inputs, so it is -// inappropriate to translate C/C++ sqrt to this. -#include - -float foo(float X) { -// CHECK: foo -// CHECK-NOT: readonly -// CHECK: return - // Check that this is not marked readonly when errno is used. - return sqrtf(X); -} diff --git a/test/FrontendC/2009-12-07-BitFieldAlignment.c b/test/FrontendC/2009-12-07-BitFieldAlignment.c deleted file mode 100644 index 02ff8bce1821..000000000000 --- a/test/FrontendC/2009-12-07-BitFieldAlignment.c +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %llvmgcc -m32 %s -S -o - | FileCheck %s -// Set alignment on bitfield accesses. - -struct S { - int a, b; - void *c; - unsigned d : 8; - unsigned e : 8; -}; - -void f0(struct S *a) { -// CHECK: load {{.*}}, align 4 -// CHECK: store {{.*}}, align 4 - a->e = 0; -} diff --git a/test/FrontendC/2010-01-05-LinkageName.c b/test/FrontendC/2010-01-05-LinkageName.c deleted file mode 100644 index 279df03e8e98..000000000000 --- a/test/FrontendC/2010-01-05-LinkageName.c +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %llvmgcc -O2 -S -g %s -o - | llc -disable-cfi -o 2010-01-05-LinkageName.s -O0 -// RUN: %compile_c 2010-01-05-LinkageName.s -o 2010-01-05-LinkageName.s - -struct tm {}; -long mktime(struct tm *) __asm("_mktime$UNIX2003"); -tzload(name, sp, doextend){} -long mktime(tmp) - struct tm *const tmp; -{ - tzset(); -} -timelocal(tmp) { - return mktime(tmp); -} - diff --git a/test/FrontendC/2010-01-13-MemBarrier.c b/test/FrontendC/2010-01-13-MemBarrier.c deleted file mode 100644 index a540e59c6caa..000000000000 --- a/test/FrontendC/2010-01-13-MemBarrier.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | FileCheck %s -// XFAIL: sparc -// rdar://7536390 - -unsigned t(unsigned *ptr, unsigned val) { - // CHECK: @t - // CHECK: call void @llvm.memory.barrier - // CHECK-NEXT: call i32 @llvm.atomic.swap.i32 - // CHECK-NEXT: call void @llvm.memory.barrier - return __sync_lock_test_and_set(ptr, val); -} diff --git a/test/FrontendC/2010-01-14-FnType-DebugInfo.c b/test/FrontendC/2010-01-14-FnType-DebugInfo.c deleted file mode 100644 index beaad91330bc..000000000000 --- a/test/FrontendC/2010-01-14-FnType-DebugInfo.c +++ /dev/null @@ -1,4 +0,0 @@ -// RUN: %llvmgcc %s -S -g -o /dev/null -typedef void (*sigcatch_t)( struct sigcontext *); -sigcatch_t sigcatch[50] = {(sigcatch_t) 0}; - diff --git a/test/FrontendC/2010-01-14-StaticVariable.c b/test/FrontendC/2010-01-14-StaticVariable.c deleted file mode 100644 index 0635900bbce8..000000000000 --- a/test/FrontendC/2010-01-14-StaticVariable.c +++ /dev/null @@ -1,12 +0,0 @@ -// This is a regression test on debug info to make sure that llvm emitted -// debug info does not crash gdb. -// RUN: %llvmgcc -S -O0 -g %s -o - | \ -// RUN: llc -disable-cfi --disable-fp-elim -o %t.s -O0 -relocation-model=pic -// RUN: %compile_c %t.s -o %t.o -// RUN: echo {quit\n} > %t.in -// RUN: gdb -q -batch -n -x %t.in %t.o > /dev/null - -int foo() { - static int i = 42; - return i; -} diff --git a/test/FrontendC/2010-01-18-Inlined-Debug.c b/test/FrontendC/2010-01-18-Inlined-Debug.c deleted file mode 100644 index 4aec7b264765..000000000000 --- a/test/FrontendC/2010-01-18-Inlined-Debug.c +++ /dev/null @@ -1,12 +0,0 @@ -// PR: 6058 -// RUN: %llvmgcc -g -S %s -o - | llc -O0 -o /dev/null - -static inline int foo(double) __attribute__ ((always_inline)); -static inline int foo(double __x) { return __x; } - -void bar(double x) { - foo(x); -} - - - diff --git a/test/FrontendC/2010-02-10-PointerName.c b/test/FrontendC/2010-02-10-PointerName.c deleted file mode 100644 index 7880fa8345ee..000000000000 --- a/test/FrontendC/2010-02-10-PointerName.c +++ /dev/null @@ -1,7 +0,0 @@ -// 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/FrontendC/2010-02-15-DbgStaticVar.c b/test/FrontendC/2010-02-15-DbgStaticVar.c deleted file mode 100644 index 7827d96ce61d..000000000000 --- a/test/FrontendC/2010-02-15-DbgStaticVar.c +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: %llvmgcc -g -S %s -o - | grep "metadata ..b., metadata ..b., metadata ...," -// Test to check intentionally empty linkage name for a static variable. -// Radar 7651244. -static int foo(int a) -{ - static int b = 1; - return b+a; -} - -int main() { - int j = foo(1); - return 0; -} diff --git a/test/FrontendC/2010-02-16-DbgVarScope.c b/test/FrontendC/2010-02-16-DbgVarScope.c deleted file mode 100644 index 24910adc056b..000000000000 --- a/test/FrontendC/2010-02-16-DbgVarScope.c +++ /dev/null @@ -1,30 +0,0 @@ -// RUN: %llvmgcc -S -O0 -g %s -o - | \ -// RUN: llc -disable-cfi --disable-fp-elim -o %t.s -O0 -relocation-model=pic -// RUN: %compile_c %t.s -o %t.o -// RUN: %link %t.o -o %t.exe -// RUN: echo {break 24\nrun\np loc\n} > %t.in -// RN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | \ -// RN: grep {$1 = 1} - -int g1 = 1; -int g2 = 2; - -int __attribute__((always_inline)) bar() { - return g2 - g1; -} -void foobar() {} - -void foo(int s) { - unsigned loc = 0; - if (s) { - loc = 1; - foobar(); - } else { - loc = bar(); - foobar(); - } -} - -int main() { - foo(0); -} diff --git a/test/FrontendC/2010-02-18-Dbg-VectorType.c b/test/FrontendC/2010-02-18-Dbg-VectorType.c deleted file mode 100644 index d34031f09a18..000000000000 --- a/test/FrontendC/2010-02-18-Dbg-VectorType.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -S -O0 -g %s -o - | grep DW_TAG_typedef | grep float4 -typedef float float4 __attribute__((vector_size(16))); - -int main(){ - volatile float4 x = (float4) { 0.0f, 1.0f, 2.0f, 3.0f }; - x += x; - return 0; -} - diff --git a/test/FrontendC/2010-03-10-arm-asmreg.c b/test/FrontendC/2010-03-10-arm-asmreg.c deleted file mode 100644 index 70d3681ea40e..000000000000 --- a/test/FrontendC/2010-03-10-arm-asmreg.c +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %llvmgcc %s -S -O0 -o - | FileCheck %s -// pr6552 - -// XFAIL: * -// XTARGET: arm - -extern void bar(unsigned int ip); - -// CHECK: mov r0, r12 -void foo(void) -{ - register unsigned int ip __asm ("ip"); - bar(ip); -} - diff --git a/test/FrontendC/2010-03-5-LexicalScope.c b/test/FrontendC/2010-03-5-LexicalScope.c deleted file mode 100644 index 93a841a8f29d..000000000000 --- a/test/FrontendC/2010-03-5-LexicalScope.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S -O0 -g %s -o - | grep DW_TAG_lexical_block | count 3 -int foo(int i) { - if (i) { - int j = 2; - } - else { - int j = 3; - } - return i; -} diff --git a/test/FrontendC/2010-05-14-Optimized-VarType.c b/test/FrontendC/2010-05-14-Optimized-VarType.c deleted file mode 100644 index 2aa85b5846ea..000000000000 --- a/test/FrontendC/2010-05-14-Optimized-VarType.c +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: %llvmgcc %s -Os -S -g -o - | grep DW_TAG_structure_type | count 1 -// Variable 'a' is optimized but the debug info should preserve its type info. -#include - -struct foo { - int Attribute; -}; - -void *getfoo(void) __attribute__((noinline)); - -void *getfoo(void) -{ - int *x = malloc(sizeof(int)); - *x = 42; - return (void *)x; -} - -int main(int argc, char *argv[]) { - struct foo *a = (struct foo *)getfoo(); - - return a->Attribute; -} - diff --git a/test/FrontendC/2010-05-18-asmsched.c b/test/FrontendC/2010-05-18-asmsched.c deleted file mode 100644 index ca7625f41f2b..000000000000 --- a/test/FrontendC/2010-05-18-asmsched.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc %s -S -O3 -o - | llc -march=x86-64 -mtriple=x86_64-apple-darwin | FileCheck %s -// r9 used to be clobbered before its value was moved to r10. 7993104. - -void foo(int x, int y) { -// CHECK: bar -// CHECK-NOT: {{, %r9$}} -// CHECK: movq %r9, -// CHECK: movq {{.*}}, %r9 -// CHECK: bar - register int lr9 asm("r9") = x; - register int lr10 asm("r10") = y; - int foo; - asm volatile("bar" : "=r"(lr9) : "r"(lr9), "r"(lr10)); - foo = lr9; - lr9 = x; - lr10 = foo; - asm volatile("bar" : "=r"(lr9) : "r"(lr9), "r"(lr10)); -} diff --git a/test/FrontendC/2010-05-18-palignr.c b/test/FrontendC/2010-05-18-palignr.c deleted file mode 100644 index 0b78eed0dcd0..000000000000 --- a/test/FrontendC/2010-05-18-palignr.c +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %llvmgcc -mssse3 -S -o - %s | llc -mtriple=x86_64-apple-darwin | FileCheck %s -// XFAIL: * -// XTARGET: x86,i386,i686 - -#include - -int main () -{ -#if defined( __SSSE3__ ) - -#define vec_rld_epi16( _a, _i ) ({ vSInt16 _t = _a; _t = _mm_alignr_epi8( _t, _t, _i ); /*return*/ _t; }) - typedef int16_t vSInt16 __attribute__ ((__vector_size__ (16))); - - short dtbl[] = {1,2,3,4,5,6,7,8}; - vSInt16 *vdtbl = (vSInt16*) dtbl; - - vSInt16 v0; - v0 = *vdtbl; - // CHECK: pshufd $57 - v0 = vec_rld_epi16( v0, 4 ); - - return 0; -#endif -} diff --git a/test/FrontendC/2010-05-26-AsmSideEffect.c b/test/FrontendC/2010-05-26-AsmSideEffect.c deleted file mode 100644 index acc38b783ba3..000000000000 --- a/test/FrontendC/2010-05-26-AsmSideEffect.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | FileCheck %s -// Radar 8026855 - -int test (void *src) { - register int w0 asm ("0"); - // CHECK: call i32 asm sideeffect - asm ("ldr %0, [%1]": "=r" (w0): "r" (src)); - // The asm to read the value of w0 has a sideeffect for a different reason - // (see 2010-05-18-asmsched.c) but that's not what this is testing for. - // CHECK: call i32 asm - return w0; -} diff --git a/test/FrontendC/2010-05-31-palignr.c b/test/FrontendC/2010-05-31-palignr.c deleted file mode 100644 index 9da3145153f7..000000000000 --- a/test/FrontendC/2010-05-31-palignr.c +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: not %llvmgcc -mssse3 -S -o /dev/null %s |& grep "error: mask must be an immediate" -// XFAIL: * -// XTARGET: x86,i386,i686 - -#include - -extern int i; - -int main () -{ -#if defined( __SSSE3__ ) - - typedef int16_t vSInt16 __attribute__ ((__vector_size__ (16))); - - short dtbl[] = {1,2,3,4,5,6,7,8}; - vSInt16 *vdtbl = (vSInt16*) dtbl; - - vSInt16 v0; - v0 = *vdtbl; - v0 = _mm_alignr_epi8(v0, v0, i); - - return 0; -#endif -} diff --git a/test/FrontendC/2010-06-11-SaveExpr.c b/test/FrontendC/2010-06-11-SaveExpr.c deleted file mode 100644 index d1c122d79b48..000000000000 --- a/test/FrontendC/2010-06-11-SaveExpr.c +++ /dev/null @@ -1,8 +0,0 @@ -// RUN: %llvmgcc -S %s -// Test case by Eric Postpischil! -void foo(void) -{ - char a[1]; - int t = 1; - ((char (*)[t]) a)[0][0] = 0; -} diff --git a/test/FrontendC/2010-06-17-asmcrash.c b/test/FrontendC/2010-06-17-asmcrash.c deleted file mode 100644 index 5063054fd464..000000000000 --- a/test/FrontendC/2010-06-17-asmcrash.c +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgcc -S -o - %s | llc -mtriple=x86_64-apple-darwin | FileCheck %s -// XFAIL: * -// XTARGET: x86,i386,i686 - -typedef long long int64_t; -typedef unsigned char uint8_t; -typedef int64_t x86_reg; - -void avg_pixels8_mmx2(uint8_t *block, const uint8_t *pixels, int line_size, int h) -{ - __asm__ volatile("# %0 %1 %2 %3" - :"+g"(h), "+S"(pixels), "+D"(block) - :"r" ((x86_reg)line_size) - :"%""rax", "memory"); -// CHECK: # %ecx %rsi %rdi %rdx - } diff --git a/test/FrontendC/2010-06-28-DbgLocalVar.c b/test/FrontendC/2010-06-28-DbgLocalVar.c deleted file mode 100644 index e5df8856c0dd..000000000000 --- a/test/FrontendC/2010-06-28-DbgLocalVar.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -S -O2 -g %s -o - | llc -O2 -o %t.s -// RUN: grep DW_TAG_structure_type %t.s | count 2 -// Radar 8122864 - -// Code is not generated for function foo, but preserve type information of -// local variable xyz. -static foo() { - struct X { int a; int b; } xyz; -} - -int bar() { - foo(); - return 1; -} diff --git a/test/FrontendC/2010-06-28-nowarn.c b/test/FrontendC/2010-06-28-nowarn.c deleted file mode 100644 index 3db8df10c189..000000000000 --- a/test/FrontendC/2010-06-28-nowarn.c +++ /dev/null @@ -1,21 +0,0 @@ -// RUN: %llvmgcc %s -S -m32 -fasm-blocks -o /dev/null -// This should not warn about unreferenced label. 7729514. -// XFAIL: * -// XTARGET: x86,i386,i686 - -void quarterAsm(int array[], int len) -{ - __asm - { - mov esi, array; - mov ecx, len; - shr ecx, 2; -loop: - movdqa xmm0, [esi]; - psrad xmm0, 2; - movdqa [esi], xmm0; - add esi, 16; - sub ecx, 1; - jnz loop; - } -} diff --git a/test/FrontendC/2010-07-08-DeclDebugLineNo.c b/test/FrontendC/2010-07-08-DeclDebugLineNo.c deleted file mode 100644 index 491b7dbe749f..000000000000 --- a/test/FrontendC/2010-07-08-DeclDebugLineNo.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -S -O0 -g %s -o - | FileCheck %s -// Insure that dbg.declare lines for locals refer to correct line number records. -// Radar 8152866. -void foo() { - int l = 0; // line #4: CHECK: {{call.*llvm.dbg.declare.*%l.*\!dbg }}[[variable_l:![0-9]+]] - int p = 0; // line #5: CHECK: {{call.*llvm.dbg.declare.*%p.*\!dbg }}[[variable_p:![0-9]+]] -} -// Now match the line number records: -// CHECK: {{^}}[[variable_l]]{{ = metadata ![{]i32 5,}} -// CHECK: {{^}}[[variable_p]]{{ = metadata ![{]i32 6,}} diff --git a/test/FrontendC/2010-07-14-overconservative-align.c b/test/FrontendC/2010-07-14-overconservative-align.c deleted file mode 100644 index c4a9caac6666..000000000000 --- a/test/FrontendC/2010-07-14-overconservative-align.c +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | FileCheck %s -// PR 5995 -struct s { - int word; - struct { - int filler __attribute__ ((aligned (8))); - }; -}; - -void func (struct s *s) -{ -// CHECK: load %struct.s** %s_addr, align {{[48]}} - s->word = 0; -} diff --git a/test/FrontendC/2010-07-14-ref-off-end.c b/test/FrontendC/2010-07-14-ref-off-end.c deleted file mode 100644 index c7fdd95a7aa0..000000000000 --- a/test/FrontendC/2010-07-14-ref-off-end.c +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %llvmgcc %s -S -m32 -o - | FileCheck %s -// Formerly this generated code that did a load past the end of the structure. -// That was fixed by 46726, but that patch had bad side effects and was -// reverted. This has been fixed another way in the meantime. -extern void abort(); -extern void exit(int); -struct T -{ -unsigned i:8; -unsigned c:24; -}; -f(struct T t) -{ -struct T s[1]; -s[0]=t; -return(char)s->c; -} -main() -{ -// CHECK: getelementptr inbounds %struct.T* %t, i32 0, i32 0 -// CHECK: getelementptr inbounds %struct.T* %t, i32 0, i32 0 -struct T t; -t.i=0xff; -t.c=0xffff11; -if(f(t)!=0x11)abort(); -exit(0); -} diff --git a/test/FrontendC/2010-07-27-MinNoFoldConst.c b/test/FrontendC/2010-07-27-MinNoFoldConst.c deleted file mode 100644 index ea711e5dddc8..000000000000 --- a/test/FrontendC/2010-07-27-MinNoFoldConst.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | FileCheck %s -extern int printf(const char *, ...); -static void bad(unsigned int v1, unsigned int v2) { - printf("%u\n", 1631381461u * (((v2 - 1273463329u <= v1 - 1273463329u) ? v2 : v1) - 1273463329u) + 121322179u); -} -// Radar 8198362 -// GCC FE wants to convert the above to -// 1631381461u * MIN(v2 - 1273463329u, v1 - 1273463329u) -// and then to -// MIN(1631381461u * v2 - 4047041419, 1631381461u * v1 - 4047041419) -// -// 1631381461u * 1273463329u = 2077504466193943669, but 32-bit overflow clips -// this to 4047041419. This breaks the comparison implicit in the MIN(). -// Two multiply operations suggests the bad optimization is happening; -// one multiplication, after the MIN(), is correct. -// CHECK: mul -// CHECK-NOT: mul -// CHECK: ret diff --git a/test/FrontendC/2010-08-12-asm-aggr-arg.c b/test/FrontendC/2010-08-12-asm-aggr-arg.c deleted file mode 100644 index 81ec14b28826..000000000000 --- a/test/FrontendC/2010-08-12-asm-aggr-arg.c +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgcc %s -S -O0 -o - | FileCheck %s -// Radar 8288710: A small aggregate can be passed as an integer. Make sure -// we don't get an error with "input constraint with a matching output -// constraint of incompatible type!" - -struct wrapper { - int i; -}; - -// CHECK: xyz -int test(int i) { - struct wrapper w; - w.i = i; - __asm__("xyz" : "=r" (w) : "0" (w)); - return w.i; -} diff --git a/test/FrontendC/2010-11-16-asmblock.c b/test/FrontendC/2010-11-16-asmblock.c deleted file mode 100644 index 2d9768150e98..000000000000 --- a/test/FrontendC/2010-11-16-asmblock.c +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgcc -S %s -fasm-blocks -o - | FileCheck %s -// XFAIL: * -// XTARGET: x86,i386,i686 -// 84282548 - -void foo() -{ -// CHECK: %0 = call i32 asm sideeffect "", "={ecx}"() nounwind -// CHECK: %1 = call i32 asm sideeffect alignstack "sall $$3, $0", "={ecx},{ecx},~{dirflag},~{fpsr},~{flags},~{memory}"(i32 %0) nounwind -// CHECK: store i32 %1, i32* %"%ecx" - __asm { - sal ecx, 3; - add esi, ecx; - add edi, ecx; - } -} diff --git a/test/FrontendC/2010-12-01-CommonGlobal.c b/test/FrontendC/2010-12-01-CommonGlobal.c deleted file mode 100644 index 3f6d7e885807..000000000000 --- a/test/FrontendC/2010-12-01-CommonGlobal.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | llvm-as -o /dev/null -// Don't crash on a common-linkage constant global. -extern const int kABSourceTypeProperty; -int foo(void) { - return kABSourceTypeProperty; -} -const int kABSourceTypeProperty; diff --git a/test/FrontendC/2011-02-21-DATA-common.c b/test/FrontendC/2011-02-21-DATA-common.c deleted file mode 100644 index 650ae7edddbd..000000000000 --- a/test/FrontendC/2011-02-21-DATA-common.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc -S %s -o /dev/null -struct rtxc_snapshot { - int a, b, c, d; -}; -__attribute__ ((section("__DATA, __common"))) static struct rtxc_snapshot rtxc_log_A[4]; diff --git a/test/FrontendC/2011-03-02-UnionInitializer.c b/test/FrontendC/2011-03-02-UnionInitializer.c deleted file mode 100644 index a5ea75e08c01..000000000000 --- a/test/FrontendC/2011-03-02-UnionInitializer.c +++ /dev/null @@ -1,2 +0,0 @@ -// RUN: %llvmgcc -S %s -union { int :3; double f; } u17_017 = {17.17}; diff --git a/test/FrontendC/2011-03-08-ZeroFieldUnionInitializer.c b/test/FrontendC/2011-03-08-ZeroFieldUnionInitializer.c deleted file mode 100644 index 1fd8a8782464..000000000000 --- a/test/FrontendC/2011-03-08-ZeroFieldUnionInitializer.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -S %s -typedef struct { - union { - struct { } __attribute((packed)); - }; -} fenv_t; -const fenv_t _FE_DFL_ENV = {{{ 0, 0, 0, 0 }}}; diff --git a/test/FrontendC/2011-03-31-ArrayRefFolding.c b/test/FrontendC/2011-03-31-ArrayRefFolding.c deleted file mode 100644 index 403927931c7f..000000000000 --- a/test/FrontendC/2011-03-31-ArrayRefFolding.c +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %llvmgcc -S -o - -m32 -Os %s | FileCheck %s -// PR9571 - -struct t { - int x; -}; - -extern struct t *cfun; - -int f(void) { - if (!(cfun + 0)) -// CHECK: icmp eq %struct.t* %0, null - return 0; - return cfun->x; -} diff --git a/test/FrontendC/ARM/dg.exp b/test/FrontendC/ARM/dg.exp deleted file mode 100644 index df7d49ebdb13..000000000000 --- a/test/FrontendC/ARM/dg.exp +++ /dev/null @@ -1,5 +0,0 @@ -load_lib llvm.exp - -if { [llvm_supports_target ARM] && [llvm_gcc_supports c] } { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp,s}]] -} diff --git a/test/FrontendC/ARM/inline-asm-multichar.c b/test/FrontendC/ARM/inline-asm-multichar.c deleted file mode 100644 index bd883903262d..000000000000 --- a/test/FrontendC/ARM/inline-asm-multichar.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -S -march=armv7a %s | FileCheck %s - -// XFAIL: * -// XTARGET: arm - -int t1() { - static float k = 1.0f; - // CHECK: "flds s15, $0 \0A", "*^Uv,~{s15}" - __asm__ volatile ("flds s15, %[k] \n" :: [k] "Uv,m" (k) : "s15"); - return 0; -} diff --git a/test/FrontendC/Atomics-no64bit.c b/test/FrontendC/Atomics-no64bit.c deleted file mode 100644 index 6fb610981109..000000000000 --- a/test/FrontendC/Atomics-no64bit.c +++ /dev/null @@ -1,190 +0,0 @@ -// Test frontend handling of __sync builtins. -// Modified from a gcc testcase. -// RUN: %llvmgcc -S %s -o - | grep atomic | count 150 -// RUN: %llvmgcc -S %s -o - | grep p0i8 | count 50 -// RUN: %llvmgcc -S %s -o - | grep p0i16 | count 50 -// RUN: %llvmgcc -S %s -o - | grep p0i32 | count 50 -// RUN: %llvmgcc -S %s -o - | grep volatile | count 6 - -// Currently this is implemented only for Alpha, X86, PowerPC. -// Add your target here if it doesn't work. -// This version of the test does not include long long. -// XFAIL: sparc,arm - -signed char sc; -unsigned char uc; -signed short ss; -unsigned short us; -signed int si; -unsigned int ui; - -void test_op_ignore (void) -{ - (void) __sync_fetch_and_add (&sc, 1); - (void) __sync_fetch_and_add (&uc, 1); - (void) __sync_fetch_and_add (&ss, 1); - (void) __sync_fetch_and_add (&us, 1); - (void) __sync_fetch_and_add (&si, 1); - (void) __sync_fetch_and_add (&ui, 1); - - (void) __sync_fetch_and_sub (&sc, 1); - (void) __sync_fetch_and_sub (&uc, 1); - (void) __sync_fetch_and_sub (&ss, 1); - (void) __sync_fetch_and_sub (&us, 1); - (void) __sync_fetch_and_sub (&si, 1); - (void) __sync_fetch_and_sub (&ui, 1); - - (void) __sync_fetch_and_or (&sc, 1); - (void) __sync_fetch_and_or (&uc, 1); - (void) __sync_fetch_and_or (&ss, 1); - (void) __sync_fetch_and_or (&us, 1); - (void) __sync_fetch_and_or (&si, 1); - (void) __sync_fetch_and_or (&ui, 1); - - (void) __sync_fetch_and_xor (&sc, 1); - (void) __sync_fetch_and_xor (&uc, 1); - (void) __sync_fetch_and_xor (&ss, 1); - (void) __sync_fetch_and_xor (&us, 1); - (void) __sync_fetch_and_xor (&si, 1); - (void) __sync_fetch_and_xor (&ui, 1); - - (void) __sync_fetch_and_and (&sc, 1); - (void) __sync_fetch_and_and (&uc, 1); - (void) __sync_fetch_and_and (&ss, 1); - (void) __sync_fetch_and_and (&us, 1); - (void) __sync_fetch_and_and (&si, 1); - (void) __sync_fetch_and_and (&ui, 1); - - (void) __sync_fetch_and_nand (&sc, 1); - (void) __sync_fetch_and_nand (&uc, 1); - (void) __sync_fetch_and_nand (&ss, 1); - (void) __sync_fetch_and_nand (&us, 1); - (void) __sync_fetch_and_nand (&si, 1); - (void) __sync_fetch_and_nand (&ui, 1); -} - -void test_fetch_and_op (void) -{ - sc = __sync_fetch_and_add (&sc, 11); - uc = __sync_fetch_and_add (&uc, 11); - ss = __sync_fetch_and_add (&ss, 11); - us = __sync_fetch_and_add (&us, 11); - si = __sync_fetch_and_add (&si, 11); - ui = __sync_fetch_and_add (&ui, 11); - - sc = __sync_fetch_and_sub (&sc, 11); - uc = __sync_fetch_and_sub (&uc, 11); - ss = __sync_fetch_and_sub (&ss, 11); - us = __sync_fetch_and_sub (&us, 11); - si = __sync_fetch_and_sub (&si, 11); - ui = __sync_fetch_and_sub (&ui, 11); - - sc = __sync_fetch_and_or (&sc, 11); - uc = __sync_fetch_and_or (&uc, 11); - ss = __sync_fetch_and_or (&ss, 11); - us = __sync_fetch_and_or (&us, 11); - si = __sync_fetch_and_or (&si, 11); - ui = __sync_fetch_and_or (&ui, 11); - - sc = __sync_fetch_and_xor (&sc, 11); - uc = __sync_fetch_and_xor (&uc, 11); - ss = __sync_fetch_and_xor (&ss, 11); - us = __sync_fetch_and_xor (&us, 11); - si = __sync_fetch_and_xor (&si, 11); - ui = __sync_fetch_and_xor (&ui, 11); - - sc = __sync_fetch_and_and (&sc, 11); - uc = __sync_fetch_and_and (&uc, 11); - ss = __sync_fetch_and_and (&ss, 11); - us = __sync_fetch_and_and (&us, 11); - si = __sync_fetch_and_and (&si, 11); - ui = __sync_fetch_and_and (&ui, 11); - - sc = __sync_fetch_and_nand (&sc, 11); - uc = __sync_fetch_and_nand (&uc, 11); - ss = __sync_fetch_and_nand (&ss, 11); - us = __sync_fetch_and_nand (&us, 11); - si = __sync_fetch_and_nand (&si, 11); - ui = __sync_fetch_and_nand (&ui, 11); -} - -void test_op_and_fetch (void) -{ - sc = __sync_add_and_fetch (&sc, uc); - uc = __sync_add_and_fetch (&uc, uc); - ss = __sync_add_and_fetch (&ss, uc); - us = __sync_add_and_fetch (&us, uc); - si = __sync_add_and_fetch (&si, uc); - ui = __sync_add_and_fetch (&ui, uc); - - sc = __sync_sub_and_fetch (&sc, uc); - uc = __sync_sub_and_fetch (&uc, uc); - ss = __sync_sub_and_fetch (&ss, uc); - us = __sync_sub_and_fetch (&us, uc); - si = __sync_sub_and_fetch (&si, uc); - ui = __sync_sub_and_fetch (&ui, uc); - - sc = __sync_or_and_fetch (&sc, uc); - uc = __sync_or_and_fetch (&uc, uc); - ss = __sync_or_and_fetch (&ss, uc); - us = __sync_or_and_fetch (&us, uc); - si = __sync_or_and_fetch (&si, uc); - ui = __sync_or_and_fetch (&ui, uc); - - sc = __sync_xor_and_fetch (&sc, uc); - uc = __sync_xor_and_fetch (&uc, uc); - ss = __sync_xor_and_fetch (&ss, uc); - us = __sync_xor_and_fetch (&us, uc); - si = __sync_xor_and_fetch (&si, uc); - ui = __sync_xor_and_fetch (&ui, uc); - - sc = __sync_and_and_fetch (&sc, uc); - uc = __sync_and_and_fetch (&uc, uc); - ss = __sync_and_and_fetch (&ss, uc); - us = __sync_and_and_fetch (&us, uc); - si = __sync_and_and_fetch (&si, uc); - ui = __sync_and_and_fetch (&ui, uc); - - sc = __sync_nand_and_fetch (&sc, uc); - uc = __sync_nand_and_fetch (&uc, uc); - ss = __sync_nand_and_fetch (&ss, uc); - us = __sync_nand_and_fetch (&us, uc); - si = __sync_nand_and_fetch (&si, uc); - ui = __sync_nand_and_fetch (&ui, uc); -} - -void test_compare_and_swap (void) -{ - sc = __sync_val_compare_and_swap (&sc, uc, sc); - uc = __sync_val_compare_and_swap (&uc, uc, sc); - ss = __sync_val_compare_and_swap (&ss, uc, sc); - us = __sync_val_compare_and_swap (&us, uc, sc); - si = __sync_val_compare_and_swap (&si, uc, sc); - ui = __sync_val_compare_and_swap (&ui, uc, sc); - - ui = __sync_bool_compare_and_swap (&sc, uc, sc); - ui = __sync_bool_compare_and_swap (&uc, uc, sc); - ui = __sync_bool_compare_and_swap (&ss, uc, sc); - ui = __sync_bool_compare_and_swap (&us, uc, sc); - ui = __sync_bool_compare_and_swap (&si, uc, sc); - ui = __sync_bool_compare_and_swap (&ui, uc, sc); -} - -void test_lock (void) -{ - sc = __sync_lock_test_and_set (&sc, 1); - uc = __sync_lock_test_and_set (&uc, 1); - ss = __sync_lock_test_and_set (&ss, 1); - us = __sync_lock_test_and_set (&us, 1); - si = __sync_lock_test_and_set (&si, 1); - ui = __sync_lock_test_and_set (&ui, 1); - - __sync_synchronize (); - - __sync_lock_release (&sc); - __sync_lock_release (&uc); - __sync_lock_release (&ss); - __sync_lock_release (&us); - __sync_lock_release (&si); - __sync_lock_release (&ui); -} diff --git a/test/FrontendC/Atomics.c b/test/FrontendC/Atomics.c deleted file mode 100644 index 2b96ae0f6294..000000000000 --- a/test/FrontendC/Atomics.c +++ /dev/null @@ -1,236 +0,0 @@ -// Test frontend handling of __sync builtins. -// Modified from a gcc testcase. -// RUN: %llvmgcc -S %s -o - | grep atomic | count 200 -// RUN: %llvmgcc -S %s -o - | grep p0i8 | count 50 -// RUN: %llvmgcc -S %s -o - | grep p0i16 | count 50 -// RUN: %llvmgcc -S %s -o - | grep p0i32 | count 50 -// RUN: %llvmgcc -S %s -o - | grep volatile | count 8 - -// Currently this is implemented only for Alpha, X86, PowerPC. -// Add your target here if it doesn't work. -// PPC32 does not translate the long long variants, so fails this test. -// XFAIL: sparc,arm,powerpc - -signed char sc; -unsigned char uc; -signed short ss; -unsigned short us; -signed int si; -unsigned int ui; -signed long long sll; -unsigned long long ull; - -void test_op_ignore (void) -{ - (void) __sync_fetch_and_add (&sc, 1); - (void) __sync_fetch_and_add (&uc, 1); - (void) __sync_fetch_and_add (&ss, 1); - (void) __sync_fetch_and_add (&us, 1); - (void) __sync_fetch_and_add (&si, 1); - (void) __sync_fetch_and_add (&ui, 1); - (void) __sync_fetch_and_add (&sll, 1); - (void) __sync_fetch_and_add (&ull, 1); - - (void) __sync_fetch_and_sub (&sc, 1); - (void) __sync_fetch_and_sub (&uc, 1); - (void) __sync_fetch_and_sub (&ss, 1); - (void) __sync_fetch_and_sub (&us, 1); - (void) __sync_fetch_and_sub (&si, 1); - (void) __sync_fetch_and_sub (&ui, 1); - (void) __sync_fetch_and_sub (&sll, 1); - (void) __sync_fetch_and_sub (&ull, 1); - - (void) __sync_fetch_and_or (&sc, 1); - (void) __sync_fetch_and_or (&uc, 1); - (void) __sync_fetch_and_or (&ss, 1); - (void) __sync_fetch_and_or (&us, 1); - (void) __sync_fetch_and_or (&si, 1); - (void) __sync_fetch_and_or (&ui, 1); - (void) __sync_fetch_and_or (&sll, 1); - (void) __sync_fetch_and_or (&ull, 1); - - (void) __sync_fetch_and_xor (&sc, 1); - (void) __sync_fetch_and_xor (&uc, 1); - (void) __sync_fetch_and_xor (&ss, 1); - (void) __sync_fetch_and_xor (&us, 1); - (void) __sync_fetch_and_xor (&si, 1); - (void) __sync_fetch_and_xor (&ui, 1); - (void) __sync_fetch_and_xor (&sll, 1); - (void) __sync_fetch_and_xor (&ull, 1); - - (void) __sync_fetch_and_and (&sc, 1); - (void) __sync_fetch_and_and (&uc, 1); - (void) __sync_fetch_and_and (&ss, 1); - (void) __sync_fetch_and_and (&us, 1); - (void) __sync_fetch_and_and (&si, 1); - (void) __sync_fetch_and_and (&ui, 1); - (void) __sync_fetch_and_and (&sll, 1); - (void) __sync_fetch_and_and (&ull, 1); - - (void) __sync_fetch_and_nand (&sc, 1); - (void) __sync_fetch_and_nand (&uc, 1); - (void) __sync_fetch_and_nand (&ss, 1); - (void) __sync_fetch_and_nand (&us, 1); - (void) __sync_fetch_and_nand (&si, 1); - (void) __sync_fetch_and_nand (&ui, 1); - (void) __sync_fetch_and_nand (&sll, 1); - (void) __sync_fetch_and_nand (&ull, 1); -} - -void test_fetch_and_op (void) -{ - sc = __sync_fetch_and_add (&sc, 11); - uc = __sync_fetch_and_add (&uc, 11); - ss = __sync_fetch_and_add (&ss, 11); - us = __sync_fetch_and_add (&us, 11); - si = __sync_fetch_and_add (&si, 11); - ui = __sync_fetch_and_add (&ui, 11); - sll = __sync_fetch_and_add (&sll, 11); - ull = __sync_fetch_and_add (&ull, 11); - - sc = __sync_fetch_and_sub (&sc, 11); - uc = __sync_fetch_and_sub (&uc, 11); - ss = __sync_fetch_and_sub (&ss, 11); - us = __sync_fetch_and_sub (&us, 11); - si = __sync_fetch_and_sub (&si, 11); - ui = __sync_fetch_and_sub (&ui, 11); - sll = __sync_fetch_and_sub (&sll, 11); - ull = __sync_fetch_and_sub (&ull, 11); - - sc = __sync_fetch_and_or (&sc, 11); - uc = __sync_fetch_and_or (&uc, 11); - ss = __sync_fetch_and_or (&ss, 11); - us = __sync_fetch_and_or (&us, 11); - si = __sync_fetch_and_or (&si, 11); - ui = __sync_fetch_and_or (&ui, 11); - sll = __sync_fetch_and_or (&sll, 11); - ull = __sync_fetch_and_or (&ull, 11); - - sc = __sync_fetch_and_xor (&sc, 11); - uc = __sync_fetch_and_xor (&uc, 11); - ss = __sync_fetch_and_xor (&ss, 11); - us = __sync_fetch_and_xor (&us, 11); - si = __sync_fetch_and_xor (&si, 11); - ui = __sync_fetch_and_xor (&ui, 11); - sll = __sync_fetch_and_xor (&sll, 11); - ull = __sync_fetch_and_xor (&ull, 11); - - sc = __sync_fetch_and_and (&sc, 11); - uc = __sync_fetch_and_and (&uc, 11); - ss = __sync_fetch_and_and (&ss, 11); - us = __sync_fetch_and_and (&us, 11); - si = __sync_fetch_and_and (&si, 11); - ui = __sync_fetch_and_and (&ui, 11); - sll = __sync_fetch_and_and (&sll, 11); - ull = __sync_fetch_and_and (&ull, 11); - - sc = __sync_fetch_and_nand (&sc, 11); - uc = __sync_fetch_and_nand (&uc, 11); - ss = __sync_fetch_and_nand (&ss, 11); - us = __sync_fetch_and_nand (&us, 11); - si = __sync_fetch_and_nand (&si, 11); - ui = __sync_fetch_and_nand (&ui, 11); - sll = __sync_fetch_and_nand (&sll, 11); - ull = __sync_fetch_and_nand (&ull, 11); -} - -void test_op_and_fetch (void) -{ - sc = __sync_add_and_fetch (&sc, uc); - uc = __sync_add_and_fetch (&uc, uc); - ss = __sync_add_and_fetch (&ss, uc); - us = __sync_add_and_fetch (&us, uc); - si = __sync_add_and_fetch (&si, uc); - ui = __sync_add_and_fetch (&ui, uc); - sll = __sync_add_and_fetch (&sll, uc); - ull = __sync_add_and_fetch (&ull, uc); - - sc = __sync_sub_and_fetch (&sc, uc); - uc = __sync_sub_and_fetch (&uc, uc); - ss = __sync_sub_and_fetch (&ss, uc); - us = __sync_sub_and_fetch (&us, uc); - si = __sync_sub_and_fetch (&si, uc); - ui = __sync_sub_and_fetch (&ui, uc); - sll = __sync_sub_and_fetch (&sll, uc); - ull = __sync_sub_and_fetch (&ull, uc); - - sc = __sync_or_and_fetch (&sc, uc); - uc = __sync_or_and_fetch (&uc, uc); - ss = __sync_or_and_fetch (&ss, uc); - us = __sync_or_and_fetch (&us, uc); - si = __sync_or_and_fetch (&si, uc); - ui = __sync_or_and_fetch (&ui, uc); - sll = __sync_or_and_fetch (&sll, uc); - ull = __sync_or_and_fetch (&ull, uc); - - sc = __sync_xor_and_fetch (&sc, uc); - uc = __sync_xor_and_fetch (&uc, uc); - ss = __sync_xor_and_fetch (&ss, uc); - us = __sync_xor_and_fetch (&us, uc); - si = __sync_xor_and_fetch (&si, uc); - ui = __sync_xor_and_fetch (&ui, uc); - sll = __sync_xor_and_fetch (&sll, uc); - ull = __sync_xor_and_fetch (&ull, uc); - - sc = __sync_and_and_fetch (&sc, uc); - uc = __sync_and_and_fetch (&uc, uc); - ss = __sync_and_and_fetch (&ss, uc); - us = __sync_and_and_fetch (&us, uc); - si = __sync_and_and_fetch (&si, uc); - ui = __sync_and_and_fetch (&ui, uc); - sll = __sync_and_and_fetch (&sll, uc); - ull = __sync_and_and_fetch (&ull, uc); - - sc = __sync_nand_and_fetch (&sc, uc); - uc = __sync_nand_and_fetch (&uc, uc); - ss = __sync_nand_and_fetch (&ss, uc); - us = __sync_nand_and_fetch (&us, uc); - si = __sync_nand_and_fetch (&si, uc); - ui = __sync_nand_and_fetch (&ui, uc); - sll = __sync_nand_and_fetch (&sll, uc); - ull = __sync_nand_and_fetch (&ull, uc); -} - -void test_compare_and_swap (void) -{ - sc = __sync_val_compare_and_swap (&sc, uc, sc); - uc = __sync_val_compare_and_swap (&uc, uc, sc); - ss = __sync_val_compare_and_swap (&ss, uc, sc); - us = __sync_val_compare_and_swap (&us, uc, sc); - si = __sync_val_compare_and_swap (&si, uc, sc); - ui = __sync_val_compare_and_swap (&ui, uc, sc); - sll = __sync_val_compare_and_swap (&sll, uc, sc); - ull = __sync_val_compare_and_swap (&ull, uc, sc); - - ui = __sync_bool_compare_and_swap (&sc, uc, sc); - ui = __sync_bool_compare_and_swap (&uc, uc, sc); - ui = __sync_bool_compare_and_swap (&ss, uc, sc); - ui = __sync_bool_compare_and_swap (&us, uc, sc); - ui = __sync_bool_compare_and_swap (&si, uc, sc); - ui = __sync_bool_compare_and_swap (&ui, uc, sc); - ui = __sync_bool_compare_and_swap (&sll, uc, sc); - ui = __sync_bool_compare_and_swap (&ull, uc, sc); -} - -void test_lock (void) -{ - sc = __sync_lock_test_and_set (&sc, 1); - uc = __sync_lock_test_and_set (&uc, 1); - ss = __sync_lock_test_and_set (&ss, 1); - us = __sync_lock_test_and_set (&us, 1); - si = __sync_lock_test_and_set (&si, 1); - ui = __sync_lock_test_and_set (&ui, 1); - sll = __sync_lock_test_and_set (&sll, 1); - ull = __sync_lock_test_and_set (&ull, 1); - - __sync_synchronize (); - - __sync_lock_release (&sc); - __sync_lock_release (&uc); - __sync_lock_release (&ss); - __sync_lock_release (&us); - __sync_lock_release (&si); - __sync_lock_release (&ui); - __sync_lock_release (&sll); - __sync_lock_release (&ull); -} diff --git a/test/FrontendC/BasicInstrs.c b/test/FrontendC/BasicInstrs.c deleted file mode 100644 index ceed17c2ba9a..000000000000 --- a/test/FrontendC/BasicInstrs.c +++ /dev/null @@ -1,26 +0,0 @@ -// This file can be used to see what a native C compiler is generating for a -// variety of interesting operations. -// -// RUN: %llvmgcc -S %s -o - | llc - -unsigned int udiv(unsigned int X, unsigned int Y) { - return X/Y; -} -int sdiv(int X, int Y) { - return X/Y; -} -unsigned int urem(unsigned int X, unsigned int Y) { - return X%Y; -} -int srem(int X, int Y) { - return X%Y; -} - -_Bool setlt(int X, int Y) { - return X < Y; -} - -_Bool setgt(int X, int Y) { - return X > Y; -} - diff --git a/test/FrontendC/alignstack.c b/test/FrontendC/alignstack.c deleted file mode 100644 index 30c00ff88e44..000000000000 --- a/test/FrontendC/alignstack.c +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: %llvmgcc %s -fasm-blocks -S -o - | FileCheck %s -// Complicated expression as jump target -// XFAIL: * -// XTARGET: x86,i386,i686,darwin - -void Method3() -{ -// CHECK: Method3 -// CHECK-NOT: alignstack - asm("foo:"); -// CHECK: return -} - -void Method4() -{ -// CHECK: Method4 -// CHECK: alignstack - asm { - bar: - } -// CHECK: return -} - diff --git a/test/FrontendC/always-inline.c b/test/FrontendC/always-inline.c deleted file mode 100644 index 22f6c7a20ef2..000000000000 --- a/test/FrontendC/always-inline.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep call | not grep foo - -void bar() { -} - -inline void __attribute__((__always_inline__)) foo() { - bar(); -} - -void i_want_bar() { - foo(); -} diff --git a/test/FrontendC/arrayderef.c b/test/FrontendC/arrayderef.c deleted file mode 100644 index 66c2e0ba4165..000000000000 --- a/test/FrontendC/arrayderef.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc %s -S -O -o - | FileCheck %s -// The load here was getting lost because this code was close -// enough to the traditional (wrong) implementation of offsetof -// to confuse the gcc FE. 8629268. - -struct foo { - int x; - int *y; -}; - -struct foo Foo[1]; - -int * bar(unsigned int ix) { -// CHECK: load - return &Foo->y[ix]; -} - diff --git a/test/FrontendC/asm-reg-var-local.c b/test/FrontendC/asm-reg-var-local.c deleted file mode 100644 index e0be10c8723e..000000000000 --- a/test/FrontendC/asm-reg-var-local.c +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | FileCheck %s -// Exercise various use cases for local asm "register variables". -// XFAIL: * -// XTARGET: x86_64,i686,i386 - -int foo() { -// CHECK: %a = alloca i32 - - register int a asm("rsi")=5; -// CHECK: store i32 5, i32* %a, align 4 - - asm volatile("; %0 This asm defines rsi" : "=r"(a)); -// CHECK: %1 = call i32 asm sideeffect "; $0 This asm defines rsi", "={rsi} -// CHECK: store i32 %1, i32* %a - - a = 42; -// CHECK: store i32 42, i32* %a, align 4 - - asm volatile("; %0 This asm uses rsi" : : "r"(a)); -// CHECK: %2 = load i32* %a, align 4 -// CHECK: call void asm sideeffect "", "{rsi}"(i32 %2) nounwind -// CHECK: %3 = call i32 asm sideeffect "", "={rsi}"() nounwind -// CHECK: call void asm sideeffect "; $0 This asm uses rsi", "{rsi},~{dirflag},~{fpsr},~{flags}"(i32 %3) - - return a; -// CHECK: %4 = load i32* %a, align 4 -// CHECK: call void asm sideeffect "", "{rsi}"(i32 %4) nounwind -// CHECK: %5 = call i32 asm sideeffect "", "={rsi}"() nounwind -// CHECK: store i32 %5, i32* %0, align 4 -// CHECK: %6 = load i32* %0, align 4 -// CHECK: store i32 %6, i32* %retval, align 4 -} diff --git a/test/FrontendC/attribute_constructor.c b/test/FrontendC/attribute_constructor.c deleted file mode 100644 index da17a37e2606..000000000000 --- a/test/FrontendC/attribute_constructor.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | grep llvm.global_ctors - -void foo() __attribute__((constructor)); -void foo() { - bar(); -} diff --git a/test/FrontendC/block-copy.c b/test/FrontendC/block-copy.c deleted file mode 100644 index c088f2dc1955..000000000000 --- a/test/FrontendC/block-copy.c +++ /dev/null @@ -1,20 +0,0 @@ -/* RUN: %llvmgcc %s -S -o - -O3 | grep {call.*memcpy} - - This should compile into a memcpy from a global, not 128 stores. */ - - - -void foo(); - -float bar() { - float lookupTable[] = {-1,-1,-1,0, -1,-1,0,-1, -1,-1,0,1, -1,-1,1,0, - -1,0,-1,-1, -1,0,-1,1, -1,0,1,-1, -1,0,1,1, - -1,1,-1,0, -1,1,0,-1, -1,1,0,1, -1,1,1,0, - 0,-1,-1,-1, 0,-1,-1,1, 0,-1,1,-1, 0,-1,1,1, - 1,-1,-1,0, 1,-1,0,-1, 1,-1,0,1, 1,-1,1,0, - 1,0,-1,-1, 1,0,-1,1, 1,0,1,-1, 1,0,1,1, - 1,1,-1,0, 1,1,0,-1, 1,1,0,1, 1,1,1,0, - 0,1,-1,-1, 0,1,-1,1, 0,1,1,-1, 0,1,1,1}; - foo(lookupTable); -} - diff --git a/test/FrontendC/crash-invalid-array.c b/test/FrontendC/crash-invalid-array.c deleted file mode 100644 index d602f7854585..000000000000 --- a/test/FrontendC/crash-invalid-array.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: not %llvmgcc -O1 %s -S |& grep {error: invalid use of array with unspecified bounds} -// PR6913 - -#include - -int main() -{ - int x[10][10]; - int (*p)[] = x; // <-- this line is what triggered it - - int i; - - for(i = 0; i < 10; ++i) - { - p[i][i] = i; - } -} diff --git a/test/FrontendC/dg.exp b/test/FrontendC/dg.exp deleted file mode 100644 index a9be28a63cf6..000000000000 --- a/test/FrontendC/dg.exp +++ /dev/null @@ -1,5 +0,0 @@ -load_lib llvm.exp - -if [ llvm_gcc_supports c ] then { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] -} diff --git a/test/FrontendC/exact-div-expr.c b/test/FrontendC/exact-div-expr.c deleted file mode 100644 index 9dce922f9532..000000000000 --- a/test/FrontendC/exact-div-expr.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -o - -O1 | grep ashr -// RUN: %llvmgcc -S %s -o - -O1 | not grep sdiv - -long long test(int *A, int *B) { - return A-B; -} diff --git a/test/FrontendC/extern-weak.c b/test/FrontendC/extern-weak.c deleted file mode 100644 index 73b59cc48c40..000000000000 --- a/test/FrontendC/extern-weak.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -O3 -S -o - %s | grep extern_weak -// RUN: %llvmgcc -O3 -S -o - %s | llc - -#if !defined(__linux__) && !defined(__FreeBSD__) && \ - !defined(__OpenBSD__) && !defined(__CYGWIN__) && !defined(__DragonFly__) -void foo() __attribute__((weak_import)); -#else -void foo() __attribute__((weak)); -#endif - -void bar() { foo(); } - diff --git a/test/FrontendC/fp-logical.c b/test/FrontendC/fp-logical.c deleted file mode 100644 index 60404f670226..000000000000 --- a/test/FrontendC/fp-logical.c +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | grep bitcast | count 14 - -typedef float vFloat __attribute__ ((__vector_size__ (16))); -typedef unsigned int vUInt32 __attribute__ ((__vector_size__ (16))); -void foo(vFloat *X) { - vFloat NoSignBit = (vFloat) ~ (vUInt32) (vFloat) { -0.f, -0.f, -0.f, -0.f }; - vFloat ExtremeValue = *X & NoSignBit; - *X = ExtremeValue; -} - -void bar(vFloat *X) { - vFloat NoSignBit = (vFloat) ~ (vUInt32) (vFloat) { -0.f, -0.f, -0.f, -0.f }; - vFloat ExtremeValue = *X & ~NoSignBit; - *X = ExtremeValue; -} diff --git a/test/FrontendC/func-aligned.c b/test/FrontendC/func-aligned.c deleted file mode 100644 index 477e82418aef..000000000000 --- a/test/FrontendC/func-aligned.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | FileCheck %s - -// rdar://7270273 -void foo() __attribute__((aligned (64))); -void foo() { -// CHECK: define void @foo() {{.*}} align 64 -} diff --git a/test/FrontendC/funccall.c b/test/FrontendC/funccall.c deleted file mode 100644 index 9735e3470570..000000000000 --- a/test/FrontendC/funccall.c +++ /dev/null @@ -1,17 +0,0 @@ - -static int q; - -void foo() { - int t = q; - q = t + 1; -} -int main() { - q = 0; - foo(); - q = q - 1; - - return q; -} - -// This is the source that corresponds to funccall.ll -// RUN: echo foo diff --git a/test/FrontendC/hidden-visibility.c b/test/FrontendC/hidden-visibility.c deleted file mode 100644 index 589bb53453f3..000000000000 --- a/test/FrontendC/hidden-visibility.c +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | grep {hidden unnamed_addr global} - -int X __attribute__ ((__visibility__ ("hidden"))) = 123; diff --git a/test/FrontendC/implicit-arg.c b/test/FrontendC/implicit-arg.c deleted file mode 100644 index a6cb8bce7ed6..000000000000 --- a/test/FrontendC/implicit-arg.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc %s -S -O0 -o - -// RUN: %llvmgcc %s -S -O1 -o - -// rdar://6518089 - -static int bar(); -void foo() { - int a = bar(); -} -int bar(unsigned a) { -} diff --git a/test/FrontendC/inline-asm-function.c b/test/FrontendC/inline-asm-function.c deleted file mode 100644 index e5848409865b..000000000000 --- a/test/FrontendC/inline-asm-function.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -fasm-blocks -o - -O | grep naked -// 7533078 (partial). - -asm int f() { - xyz -} diff --git a/test/FrontendC/inline-asm-mrv.c b/test/FrontendC/inline-asm-mrv.c deleted file mode 100644 index 6d1df67af1bd..000000000000 --- a/test/FrontendC/inline-asm-mrv.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -S %s -o - -O | not grep alloca -// PR2094 - -int sad16_sse2(void *v, unsigned char *blk2, unsigned char *blk1, - int stride, int h) { - int ret; - asm volatile( "%0 %1 %2 %3" - : "+r" (h), "+r" (blk1), "+r" (blk2) - : "r" ((long)stride)); - asm volatile("set %0 %1" : "=r"(ret) : "r"(blk1)); - return ret; -} diff --git a/test/FrontendC/libcalls-d.c b/test/FrontendC/libcalls-d.c deleted file mode 100644 index d92208d89edd..000000000000 --- a/test/FrontendC/libcalls-d.c +++ /dev/null @@ -1,14 +0,0 @@ -// llvm-gcc -O1+ should run simplify libcalls, O0 shouldn't -// and -fno-builtins shouldn't. -// -fno-math-errno should emit an llvm intrinsic, -fmath-errno should not. -// RUN: %llvmgcc %s -S -fno-math-errno -O0 -o - | grep {call.*exp2\\.f64} -// RUN: %llvmgcc %s -S -fmath-errno -O0 -o - | grep {call.*exp2} -// RUN: %llvmgcc %s -S -O1 -o - | grep {call.*ldexp} -// RUN: %llvmgcc %s -S -O3 -fno-builtin -o - | grep {call.*exp2} - -double exp2(double); - -double t4(unsigned char x) { - return exp2(x); -} - diff --git a/test/FrontendC/libcalls-ld.c b/test/FrontendC/libcalls-ld.c deleted file mode 100644 index cf71d19eaa35..000000000000 --- a/test/FrontendC/libcalls-ld.c +++ /dev/null @@ -1,17 +0,0 @@ -// llvm-gcc -O1+ should run simplify libcalls, O0 shouldn't -// and -fno-builtins shouldn't. -// -fno-math-errno should emit an llvm intrinsic, -fmath-errno should not. -// RUN: %llvmgcc %s -S -fno-math-errno -O0 -o - | grep {call.*exp2\\..*f} -// RUN: %llvmgcc %s -S -fmath-errno -O0 -o - | grep {call.*exp2l} -// RUN: %llvmgcc %s -S -O1 -o - | grep {call.*ldexp} -// RUN: %llvmgcc %s -S -O3 -fno-builtin -o - | grep {call.*exp2l} - -// If this fails for you because your target doesn't support long double, -// please xfail the test. - -long double exp2l(long double); - -long double t4(unsigned char x) { - return exp2l(x); -} - diff --git a/test/FrontendC/libcalls.c b/test/FrontendC/libcalls.c deleted file mode 100644 index 60e22e7e690a..000000000000 --- a/test/FrontendC/libcalls.c +++ /dev/null @@ -1,14 +0,0 @@ -// llvm-gcc -O1+ should run simplify libcalls, O0 shouldn't -// and -fno-builtins shouldn't. -// -fno-math-errno should emit an llvm intrinsic, -fmath-errno should not. -// RUN: %llvmgcc %s -S -fno-math-errno -O0 -o - | grep {call.*exp2\\.f32} -// RUN: %llvmgcc %s -S -fmath-errno -O0 -o - | grep {call.*exp2f} -// RUN: %llvmgcc %s -S -O1 -o - | grep {call.*ldexp} -// RUN: %llvmgcc %s -S -O3 -fno-builtin -o - | grep {call.*exp2f} - -float exp2f(float); - -float t4(unsigned char x) { - return exp2f(x); -} - diff --git a/test/FrontendC/misaligned-param.c b/test/FrontendC/misaligned-param.c deleted file mode 100644 index b4fcfe312f5a..000000000000 --- a/test/FrontendC/misaligned-param.c +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %llvmgcc %s -m32 -S -o - | FileCheck %s -// Misaligned parameter must be memcpy'd to correctly aligned temporary. -// XFAIL: * -// XTARGET: i386-apple-darwin,i686-apple-darwin,x86_64-apple-darwin - -struct s { int x; long double y; }; -long double foo(struct s x, int i, struct s y) { -// CHECK: foo -// CHECK: %x_addr = alloca %struct.s, align 16 -// CHECK: %y_addr = alloca %struct.s, align 16 -// CHECK: memcpy -// CHECK: memcpy -// CHECK: bar - return bar(&x, &y); -} diff --git a/test/FrontendC/mmx-inline-asm.c b/test/FrontendC/mmx-inline-asm.c deleted file mode 100644 index 5c09a41072b6..000000000000 --- a/test/FrontendC/mmx-inline-asm.c +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %llvmgcc -mmmx -S -o - %s | FileCheck %s -// XFAIL: * -// XTARGET: x86,i386,i686 -// -#include -#include - -// CHECK: { x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx, x86_mmx } - -void foo(__m64 vfill) { - __m64 v1, v2, v3, v4, v5, v6, v7; - - __asm__ __volatile__ ( - "\tmovq %7, %0\n" - "\tmovq %7, %1\n" - "\tmovq %7, %2\n" - "\tmovq %7, %3\n" - "\tmovq %7, %4\n" - "\tmovq %7, %5\n" - "\tmovq %7, %6" - : "=&y" (v1), "=&y" (v2), "=&y" (v3), - "=&y" (v4), "=&y" (v5), "=&y" (v6), "=y" (v7) - : "y" (vfill)); -} diff --git a/test/FrontendC/nested-functions.c b/test/FrontendC/nested-functions.c deleted file mode 100644 index bccbef3dbdd8..000000000000 --- a/test/FrontendC/nested-functions.c +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %llvmgcc -S %s -o - -fnested-functions -// PR1274 - -void Bork() { - void Fork(const int *src, int size) { - int i = 1; - int x; - - while (i < size) - x = src[i]; - } -} - -void foo(void *a){ - inline void foo_bar() { - a += 1; - } -} diff --git a/test/FrontendC/pr2394.c b/test/FrontendC/pr2394.c deleted file mode 100644 index ca8b046f72f7..000000000000 --- a/test/FrontendC/pr2394.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | FileCheck %s -struct __attribute((packed)) x {int a : 24;}; -int a(struct x* g) { - // CHECK: load i24 - return g->a; -} diff --git a/test/FrontendC/pr3518.c b/test/FrontendC/pr3518.c deleted file mode 100644 index 112394a651b4..000000000000 --- a/test/FrontendC/pr3518.c +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %llvmgcc %s -S -O0 -o - | grep {= internal unnamed_addr global} | count 4 -// PR 3518 -// Some of the objects were coming out as unintialized (external) before 3518 -// was fixed. Internal names are different between llvm-gcc and clang so they -// are not tested. - -extern void abort (void); - -struct A { int i; int j; }; -struct B { struct A *a; struct A *b; }; -struct C { struct B *c; struct A *d; }; -struct C e = { &(struct B) { &(struct A) { 1, 2 }, &(struct A) { 3, 4 } }, &(struct A) { 5, 6 } }; - -int -main (void) -{ - if (e.c->a->i != 1 || e.c->a->j != 2) - abort (); - if (e.c->b->i != 3 || e.c->b->j != 4) - abort (); - if (e.d->i != 5 || e.d->j != 6) - abort (); - return 0; -} diff --git a/test/FrontendC/pr4349.c b/test/FrontendC/pr4349.c deleted file mode 100644 index 49c89e25fed4..000000000000 --- a/test/FrontendC/pr4349.c +++ /dev/null @@ -1,38 +0,0 @@ -// RUN: %llvmgcc %s -S -O0 -o - | FileCheck %s -// PR 4349 - -union reg -{ - unsigned char b[2][2]; - unsigned short w[2]; - unsigned int d; -}; -struct cpu -{ - union reg pc; -}; -extern struct cpu cpu; -struct svar -{ - void *ptr; -}; -// CHECK: @svars1 = global [1 x %struct.svar] [%struct.svar { i8* bitcast (%struct.cpu* @cpu to i8*) }] -struct svar svars1[] = -{ - { &((cpu.pc).w[0]) } -}; -// CHECK: @svars2 = global [1 x %struct.svar] [%struct.svar { i8* getelementptr ([2 x i8]* bitcast (%struct.cpu* @cpu to [2 x i8]*), i{{[0-9]+}} 0, i{{[0-9]+}} 1) }] -struct svar svars2[] = -{ - { &((cpu.pc).b[0][1]) } -}; -// CHECK: @svars3 = global [1 x %struct.svar] [%struct.svar { i8* bitcast (i16* getelementptr ([2 x i16]* bitcast (%struct.cpu* @cpu to [2 x i16]*), i{{[0-9]+}} 0, i{{[0-9]+}} 1) to i8*) }] -struct svar svars3[] = -{ - { &((cpu.pc).w[1]) } -}; -// CHECK: @svars4 = global [1 x %struct.svar] [%struct.svar { i8* getelementptr ([2 x [2 x i8]]* bitcast (%struct.cpu* @cpu to [2 x [2 x i8]]*), i{{[0-9]+}} 0, i{{[0-9]+}} 1, i{{[0-9]+}} 1) }] -struct svar svars4[] = -{ - { &((cpu.pc).b[1][1]) } -}; diff --git a/test/FrontendC/pr5406.c b/test/FrontendC/pr5406.c deleted file mode 100644 index 0b1f277592fb..000000000000 --- a/test/FrontendC/pr5406.c +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %llvmgcc %s -S -O0 -o - | FileCheck %s -// PR 5406 - -// XFAIL: * -// XTARGET: arm - -typedef struct { char x[3]; } A0; -void foo (int i, ...); - - -// CHECK: call void (i32, ...)* @foo(i32 1, i32 {{.*}}) nounwind -int main (void) -{ - A0 a3; - a3.x[0] = 0; - a3.x[0] = 0; - a3.x[2] = 26; - foo (1, a3 ); - return 0; -} diff --git a/test/FrontendC/ptr-rotate.c b/test/FrontendC/ptr-rotate.c deleted file mode 100644 index 36d9755dd674..000000000000 --- a/test/FrontendC/ptr-rotate.c +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc %s -S -m32 -o /dev/null -// RUN: %llvmgcc %s -S -O1 -m32 -o - | llc -march=x86 -mtriple=i386-apple-darwin9.7 | FileCheck %s -check-prefix=DARWIN - -unsigned int func(void *A) { - // DARWIN: roll $27 - return ((((unsigned long long) A) >> 5) | (((unsigned long long) A) << 27)); -} diff --git a/test/FrontendC/redef-ext-inline.c b/test/FrontendC/redef-ext-inline.c deleted file mode 100644 index 240beb1f6f67..000000000000 --- a/test/FrontendC/redef-ext-inline.c +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S %s -o - -// rdar://7208839 - -extern inline int f1 (void) {return 1;} -int f3 (void) {return f1();} -int f1 (void) {return 0;} diff --git a/test/FrontendC/sret.c b/test/FrontendC/sret.c deleted file mode 100644 index 42666917a8df..000000000000 --- a/test/FrontendC/sret.c +++ /dev/null @@ -1,15 +0,0 @@ -// RUN: %llvmgcc %s -S -O0 -o - | grep sret | count 5 - -struct abc { - long a; - long b; - long c; -}; - -struct abc foo1(void); -struct abc foo2(); - -void bar() { - struct abc dummy1 = foo1(); - struct abc dummy2 = foo2(); -} diff --git a/test/FrontendC/sret2.c b/test/FrontendC/sret2.c deleted file mode 100644 index 0f35b1c2586f..000000000000 --- a/test/FrontendC/sret2.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc %s -S -O0 -o - | grep sret | count 2 - -struct abc { - long a; - long b; - long c; -}; - -struct abc foo2(){} diff --git a/test/FrontendC/struct-matching-constraint.c b/test/FrontendC/struct-matching-constraint.c deleted file mode 100644 index d002cddeef25..000000000000 --- a/test/FrontendC/struct-matching-constraint.c +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %llvmgcc -S -march=armv7a %s - -// XFAIL: * -// XTARGET: arm - -typedef struct __simd128_uint16_t -{ - __neon_uint16x8_t val; -} uint16x8_t; - -void b(uint16x8_t sat, uint16x8_t luma) -{ - __asm__("vmov.16 %1, %0 \n\t" - "vtrn.16 %0, %1 \n\t" - :"=w"(luma), "=w"(sat) - :"0"(luma) - ); - -} diff --git a/test/FrontendC/unaligned-memcpy.c b/test/FrontendC/unaligned-memcpy.c deleted file mode 100644 index 8fb84e4f5150..000000000000 --- a/test/FrontendC/unaligned-memcpy.c +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %llvmgcc %s -S -o - | llc - -void bork() { - char Qux[33] = {0}; -} diff --git a/test/FrontendC/union-align.c b/test/FrontendC/union-align.c deleted file mode 100644 index f99a76080569..000000000000 --- a/test/FrontendC/union-align.c +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep load | grep "4 x float" | not grep "align 4" -// RUN: %llvmgcc -S %s -o - | grep load | grep "4 x float" | grep "align 16" -// PR3432 -// rdar://6536377 - -typedef float __m128 __attribute__ ((__vector_size__ (16))); - -typedef union -{ - int i[4]; - float f[4]; - __m128 v; -} u_t; - -__m128 t(u_t *a) { - return a->v; -} diff --git a/test/FrontendC/vla-1.c b/test/FrontendC/vla-1.c deleted file mode 100644 index 77f78a5e3af7..000000000000 --- a/test/FrontendC/vla-1.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc_only -std=gnu99 %s -S |& grep {warning: alignment for} -// ppc does not support this feature, and gets a fatal error at runtime. -// XFAIL: powerpc - -int foo(int a) -{ - int var[a] __attribute__((__aligned__(32))); - return 4; -} diff --git a/test/FrontendC/vla-2.c b/test/FrontendC/vla-2.c deleted file mode 100644 index 555cfc789250..000000000000 --- a/test/FrontendC/vla-2.c +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc -std=gnu99 %s -S -o - | grep ".*alloca.*align 16" - -extern void bar(int[]); - -void foo(int a) -{ - int var[a] __attribute__((__aligned__(16))); - bar(var); - return; -} diff --git a/test/FrontendC/vla-3.c b/test/FrontendC/vla-3.c deleted file mode 100644 index eca9675a419f..000000000000 --- a/test/FrontendC/vla-3.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -std=gnu99 %s -S -o - | grep ".*alloca.*align 16" - -void adr(char *); - -void vlaalign(int size) -{ - char __attribute__((aligned(16))) tmp[size+32]; - char tmp2[size+16]; - - adr(tmp); -} diff --git a/test/FrontendC/wchar-const.c b/test/FrontendC/wchar-const.c deleted file mode 100644 index 7cf3322e8cf9..000000000000 --- a/test/FrontendC/wchar-const.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -S %s -o - | grep {constant \\\[18 x} | grep { 84, } -// This should pass for any endianness combination of host and target. -#include -extern void foo(const wchar_t* p); -int main (int argc, const char * argv[]) -{ - foo(L"This is some text"); - return 0; -} diff --git a/test/FrontendC/weak_constant.c b/test/FrontendC/weak_constant.c deleted file mode 100644 index 53379482cb4d..000000000000 --- a/test/FrontendC/weak_constant.c +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %llvmgcc -S %s -O1 -o - | grep {ret.*123} -// Check for bug compatibility with gcc. - -const int x __attribute((weak)) = 123; - -int* f(void) { - return &x; -} - -int g(void) { - return *f(); -} diff --git a/test/FrontendFortran/2008-11-03-OptionOverride.f90 b/test/FrontendFortran/2008-11-03-OptionOverride.f90 deleted file mode 100644 index d65ba9b4736f..000000000000 --- a/test/FrontendFortran/2008-11-03-OptionOverride.f90 +++ /dev/null @@ -1,4 +0,0 @@ -! RUN: %llvmgcc -S %s -march=k8 -! XTARGET: x86 -! Note: this file intentionally left blank, the problem itself is in -! frontend initialization routines and march flag! diff --git a/test/FrontendFortran/2009-02-09-FloorDivExpr.f90 b/test/FrontendFortran/2009-02-09-FloorDivExpr.f90 deleted file mode 100644 index ddd05c549496..000000000000 --- a/test/FrontendFortran/2009-02-09-FloorDivExpr.f90 +++ /dev/null @@ -1,32 +0,0 @@ -! RUN: %llvmgcc -S %s -! PR2437 -program main - implicit none - call build (77) -contains - subroutine build (order) - integer :: order, i, j - - - call test (1, order, 3, (/ (i, i = 1, order, 3) /)) - call test (order, 1, -3, (/ (i, i = order, 1, -3) /)) - - do j = -10, 10 - call test (order + j, order, 5, (/ (i, i = order + j, order, 5) /)) - call test (order + j, order, -5, (/ (i, i = order + j, order, -5) /)) - end do - - end subroutine build - - subroutine test (from, to, step, values) - integer, dimension (:) :: values - integer :: from, to, step, last, i - - last = 0 - do i = from, to, step - last = last + 1 - if (values (last) .ne. i) call abort - end do - if (size (values, dim = 1) .ne. last) call abort - end subroutine test -end program main diff --git a/test/FrontendFortran/cpow.f90 b/test/FrontendFortran/cpow.f90 deleted file mode 100644 index 25156fd58971..000000000000 --- a/test/FrontendFortran/cpow.f90 +++ /dev/null @@ -1,18 +0,0 @@ -! RUN: %llvmgcc -S %s -! PR2443 - -! Program to test the power (**) operator -program testpow - implicit none - real(kind=4) r, s, two - real(kind=8) :: q - complex(kind=4) :: c, z - real, parameter :: del = 0.0001 - integer i, j - - two = 2.0 - - c = (2.0, 3.0) - c = c ** two - if (abs(c - (-5.0, 12.0)) .gt. del) call abort -end program diff --git a/test/FrontendFortran/dg.exp b/test/FrontendFortran/dg.exp deleted file mode 100644 index 45bffc6fdcb8..000000000000 --- a/test/FrontendFortran/dg.exp +++ /dev/null @@ -1,6 +0,0 @@ -load_lib llvm.exp - -if [ llvm_gcc_supports fortran ] then { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{f,f90}]] -} - diff --git a/test/FrontendObjC++/2007-10-03-MetadataPointers.mm b/test/FrontendObjC++/2007-10-03-MetadataPointers.mm deleted file mode 100644 index 2ab76c1db595..000000000000 --- a/test/FrontendObjC++/2007-10-03-MetadataPointers.mm +++ /dev/null @@ -1,7 +0,0 @@ -// RUN: %llvmgcc -w -x objective-c++ -S %s -o /dev/null - -@class NSImage; -void bork() { - NSImage *nsimage; - [nsimage release]; -} diff --git a/test/FrontendObjC++/2010-08-02-NonPODObjectValue.mm b/test/FrontendObjC++/2010-08-02-NonPODObjectValue.mm deleted file mode 100644 index da47ed0c1222..000000000000 --- a/test/FrontendObjC++/2010-08-02-NonPODObjectValue.mm +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: not %llvmgcc %s -S -o - |& FileCheck %s -// This tests for a specific diagnostic in LLVM-GCC. -// Clang compiles this correctly with no diagnostic, -// ergo this test will fail with a Clang-based front-end. -class TFENodeVector { -public: - TFENodeVector(const TFENodeVector& inNodeVector); - TFENodeVector(); -}; - -@interface TWindowHistoryEntry {} -@property (assign, nonatomic) TFENodeVector targetPath; -@end - -@implementation TWindowHistoryEntry -@synthesize targetPath; -- (void) initWithWindowController { - TWindowHistoryEntry* entry; - TFENodeVector newPath; - // CHECK: setting a C++ non-POD object value is not implemented -#ifdef __clang__ -#error setting a C++ non-POD object value is not implemented -#endif - entry.targetPath = newPath; - [entry setTargetPath:newPath]; -} -@end diff --git a/test/FrontendObjC++/2010-08-04-Template.mm b/test/FrontendObjC++/2010-08-04-Template.mm deleted file mode 100644 index 2ebfd3e17cef..000000000000 --- a/test/FrontendObjC++/2010-08-04-Template.mm +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: %llvmgcc %s -S -struct TRunSoon { - template static void Post() {} -}; - -@implementation TPrivsTableViewMainController -- (void) applyToEnclosed { - TRunSoon::Post(); -} -@end diff --git a/test/FrontendObjC++/2010-08-06-X.Y-syntax.mm b/test/FrontendObjC++/2010-08-06-X.Y-syntax.mm deleted file mode 100644 index 986094c07235..000000000000 --- a/test/FrontendObjC++/2010-08-06-X.Y-syntax.mm +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %llvmgcc %s -S -struct TFENode { - TFENode(const TFENode& inNode); -}; - -@interface TIconViewController -- (const TFENode&) target; -@end - -void sortAllChildrenForNode(const TFENode&node); - -@implementation TIconViewController -- (void) setArrangeBy { - sortAllChildrenForNode(self.target); -} -@end diff --git a/test/FrontendObjC++/dg.exp b/test/FrontendObjC++/dg.exp deleted file mode 100644 index 41c3db2af097..000000000000 --- a/test/FrontendObjC++/dg.exp +++ /dev/null @@ -1,5 +0,0 @@ -load_lib llvm.exp - -if [ llvm_gcc_supports obj-c++ ] then { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{mm}]] -} diff --git a/test/FrontendObjC/2007-04-03-ObjcEH.m b/test/FrontendObjC/2007-04-03-ObjcEH.m deleted file mode 100644 index ae744c785009..000000000000 --- a/test/FrontendObjC/2007-04-03-ObjcEH.m +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: %llvmgcc -S %s -o /dev/null - -@interface B --(int)bar; -@end - -@interface A --(void) Foo:(int) state; -@end - -@implementation A -- (void) Foo:(int) state { - - int wasResponded = 0; - @try { - if (state) { - B * b = 0; - @try { } - @finally { - wasResponded = ![b bar]; - } - } - } - @finally { - } -} -@end - - diff --git a/test/FrontendObjC/2007-05-02-Strong.m b/test/FrontendObjC/2007-05-02-Strong.m deleted file mode 100644 index 34b41ad964f5..000000000000 --- a/test/FrontendObjC/2007-05-02-Strong.m +++ /dev/null @@ -1,23 +0,0 @@ -// RUN: %llvmgcc -S %s -fobjc-gc -o /dev/null -typedef int NSInteger; -typedef struct _NSRect { - int origin; - int size; -} NSRect; - -__attribute__((objc_gc(strong))) NSRect *_cachedRectArray; -extern const NSRect NSZeroRect; -@interface A{ -} --(void)bar:(NSInteger *)rectCount; -@end - -@implementation A - --(void)bar:(NSInteger *)rectCount { - NSRect appendRect = NSZeroRect; - - _cachedRectArray[*rectCount - 1] = NSZeroRect; -} - -@end diff --git a/test/FrontendObjC/2007-09-25-EH.m b/test/FrontendObjC/2007-09-25-EH.m deleted file mode 100644 index d625584a6c54..000000000000 --- a/test/FrontendObjC/2007-09-25-EH.m +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %llvmgcc -S -w -m64 -mmacosx-version-min=10.5 %s -o /dev/null -// XFAIL: * -// XTARGET: darwin -@class NSDictionary, DSoBuffer, DSoDirectory, NSMutableArray; -@interface NSException {} -@end -@interface DSoNode { - DSoDirectory *mDirectory; -} -@end -@implementation DSoNode -- (void) _findRecordsOfTypes { - DSoBuffer *dbData; - void *recInfo; - NSMutableArray *results; - @try { - dsGetRecordEntry([dbData dsDataBuffer], (void**)&recInfo); - @try { - [results addObject:37]; - } @finally { - dsDeallocRecordEntry([mDirectory dsDirRef], recInfo); - } - } @catch(NSException * exception) { - } -} - - diff --git a/test/FrontendObjC/2007-10-17-SJLJExceptions.m b/test/FrontendObjC/2007-10-17-SJLJExceptions.m deleted file mode 100644 index 970207e0d8a4..000000000000 --- a/test/FrontendObjC/2007-10-17-SJLJExceptions.m +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %llvmgcc -m32 -x objective-c %s -pipe -std=gnu99 -O2 -fexceptions -S -o - | not grep Unwind_Resume -#import - -@interface Foo { - char c; - short s; - int i; - long l; - float f; - double d; -} --(Foo*)retain; -@end - -struct Foo *bork(Foo *FooArray) { - struct Foo *result = 0; - @try { - result = [FooArray retain]; - } @catch(id any) { - printf("hello world\n"); - } - - return result; -} diff --git a/test/FrontendObjC/2007-10-18-ProDescriptor.m b/test/FrontendObjC/2007-10-18-ProDescriptor.m deleted file mode 100644 index 220fdd2c2329..000000000000 --- a/test/FrontendObjC/2007-10-18-ProDescriptor.m +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %llvmgcc -x objective-c -S %s -o /dev/null -@protocol O -@end -@interface O < O > { -} -@end -struct A { -}; -@protocol AB -- (unsigned) ver; -@end -@interface AGy:O < AB > { -} -@end -@implementation AGy -- (unsigned) ver { -} -@end - diff --git a/test/FrontendObjC/2007-10-23-GC-WriteBarrier.m b/test/FrontendObjC/2007-10-23-GC-WriteBarrier.m deleted file mode 100644 index 4bbe4407bed9..000000000000 --- a/test/FrontendObjC/2007-10-23-GC-WriteBarrier.m +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -x objective-c -S %s -o /dev/null -fobjc-gc -// rdar://5541393 - -typedef unsigned int NSUInteger; -__attribute__((objc_gc(strong))) float *_scores; - -void foo(int i, float f) { - _scores[i] = f; -} diff --git a/test/FrontendObjC/2008-10-3-EhValue.m b/test/FrontendObjC/2008-10-3-EhValue.m deleted file mode 100644 index c7aabe271eeb..000000000000 --- a/test/FrontendObjC/2008-10-3-EhValue.m +++ /dev/null @@ -1,50 +0,0 @@ -// RUN: %llvmgcc -w -x objective-c -S %s -o /dev/null - -@interface Object { -@public - Class isa; -} -+initialize; -+alloc; -+new; -+free; --free; -+(Class)class; --(Class)class; --init; --superclass; --(const char *)name; -@end - -@interface Frob: Object -@end - -@implementation Frob: Object -@end - -static Frob* _connection = ((void *)0); - -extern void abort(void); - -void test (Object* sendPort) -{ - int cleanupPorts = 1; - Frob* receivePort = ((void *)0); - - @try { - receivePort = (Frob *) -1; - _connection = (Frob *) -1; - receivePort = ((void *)0); - sendPort = ((void *)0); - cleanupPorts = 0; - @throw [Object new]; - } - @catch(Frob *obj) { - if(!(0)) abort(); - } - @catch(id exc) { - if(!(!receivePort)) abort(); - if(!(!sendPort)) abort(); - if(!(!cleanupPorts)) abort(); - } -} diff --git a/test/FrontendObjC/2008-11-12-Metadata.m b/test/FrontendObjC/2008-11-12-Metadata.m deleted file mode 100644 index be8ee41e77ad..000000000000 --- a/test/FrontendObjC/2008-11-12-Metadata.m +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -x objective-c -m64 -S %s -o /dev/null - -@interface A -@end -@protocol P -@end -@interface B : A

    -{ -} -@end -@implementation B -- (void)test { -} -@end diff --git a/test/FrontendObjC/2008-11-24-ConstCFStrings.m b/test/FrontendObjC/2008-11-24-ConstCFStrings.m deleted file mode 100644 index 976adc47f12a..000000000000 --- a/test/FrontendObjC/2008-11-24-ConstCFStrings.m +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -x objective-c -m64 -S %s -o - | grep {L_unnamed_cfstring_} - -@class NSString; - -@interface A -- (void)bork:(NSString*)msg; -@end - -void func(A *a) { - [a bork:@"Hello world!"]; -} diff --git a/test/FrontendObjC/2008-11-25-Blocks.m b/test/FrontendObjC/2008-11-25-Blocks.m deleted file mode 100644 index c5cd3d2a0b2f..000000000000 --- a/test/FrontendObjC/2008-11-25-Blocks.m +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc -S %s -o /dev/null -// rdar://6394879 - -@interface bork -- (id)B:(void (^)())blk; -- (void)C; -@end -@implementation bork -- (id)B:(void (^)())blk { - __attribute__((__blocks__(byref))) bork* new = ((void *)0); - blk(); -} -- (void)C { - __attribute__((__blocks__(byref))) id var; - [self B:^() {}]; -} -@end diff --git a/test/FrontendObjC/2009-01-26-WriteBarrier-2.m b/test/FrontendObjC/2009-01-26-WriteBarrier-2.m deleted file mode 100644 index 32833a81e169..000000000000 --- a/test/FrontendObjC/2009-01-26-WriteBarrier-2.m +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -x objective-c -S %s -fobjc-gc -o - | grep objc_assign_strongCast -// rdar://5541393 - -typedef struct { - void (^ivarBlock)(void); -} StructWithBlock_t; - -int main(char *argc, char *argv[]) { - StructWithBlock_t *swbp = (StructWithBlock_t *)malloc(sizeof(StructWithBlock_t*)); - __block int i = 10; - // assigning a Block into an struct slot should elicit a write-barrier under GC - swbp->ivarBlock = ^ { ++i; }; - return 0; -} diff --git a/test/FrontendObjC/2009-02-05-VolatileProp.m b/test/FrontendObjC/2009-02-05-VolatileProp.m deleted file mode 100644 index 1deef739bee2..000000000000 --- a/test/FrontendObjC/2009-02-05-VolatileProp.m +++ /dev/null @@ -1,11 +0,0 @@ -/* RUN: %llvmgcc -w -x objective-c -S %s -o /dev/null -pedantic-errors - rdar://6551276 */ - -void foo(const unsigned short *); -void bar() { - unsigned short *s[3]; - int i; - @try { } @catch (id anException) { } - foo(2+s[i]); -} - diff --git a/test/FrontendObjC/2009-04-14-AsmSection.m b/test/FrontendObjC/2009-04-14-AsmSection.m deleted file mode 100644 index aefe08876716..000000000000 --- a/test/FrontendObjC/2009-04-14-AsmSection.m +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc -S %s -fobjc-abi-version=2 -o %t -// RUN: grep {OBJC_CLASS_\\\$_A.*section.*__DATA, __objc_data.*align} %t -// XTARGET: darwin - -@interface A -@end - -@implementation A -@end diff --git a/test/FrontendObjC/2009-04-27-bitfield-vs-ivar.m b/test/FrontendObjC/2009-04-27-bitfield-vs-ivar.m deleted file mode 100644 index cada8438bc95..000000000000 --- a/test/FrontendObjC/2009-04-27-bitfield-vs-ivar.m +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: %llvmgcc -S -x objective-c -m64 -fobjc-abi-version=2 %s -o %t -// RUN: grep {OBJC_CLASS_RO_\\\$_I4} %t | grep {i32 0, i32 1, i32 2, i32 0} -// RUN: grep {OBJC_CLASS_RO_\\\$_I2} %t | grep {i32 0, i32 1, i32 1, i32 0} -// RUN: grep {OBJC_CLASS_RO_\\\$_I5} %t | grep {i32 0, i32 0, i32 0, i32 0} -// XTARGET: darwin - -// Test instance variable sizing when base class ends in bitfield -@interface I3 { - unsigned int _iv2 :1; -} -@end - -@interface I4 : I3 { - char _iv4; -} -@end - -// Test case with no instance variables in derived class -@interface I1 { - unsigned int _iv2 :1; -} -@end - -@interface I2 : I1 { -} -@end - -// Test case with no instance variables anywhere -@interface I6 { -} -@end - -@interface I5 : I6 { -} -@end - -@implementation I4 -@end - -@implementation I2 -@end - -@implementation I5 -@end diff --git a/test/FrontendObjC/2009-04-28-bitfield-vs-vbc.m b/test/FrontendObjC/2009-04-28-bitfield-vs-vbc.m deleted file mode 100644 index 8306fcc7e07f..000000000000 --- a/test/FrontendObjC/2009-04-28-bitfield-vs-vbc.m +++ /dev/null @@ -1,127 +0,0 @@ -// RUN: %llvmgcc -S -x objective-c -m32 %s -o %t -// This used to crash, 6831493. -#include - -struct s0 { - double x; -}; - -@interface I2 { - struct s0 _iv1; -} -@end - -@interface I3 : I2 { - unsigned int _iv2 :1; - unsigned : 0; - unsigned int _iv3 : 3; -} -@end - -@interface I4 : I3 { - char _iv4; -} -@end - -@interface I5 : I4 { - char _iv5; - int _iv6; - int _iv7; -} - -@property int P1; -@end - -@implementation I2 -@end - -@implementation I3 -@end - -@implementation I4 -@end - -@interface I5 () -@property int P2; -@end - -#if 0 -int g2 = sizeof(I2); -int g3 = sizeof(I3); -int g4 = sizeof(I4); -int g5_0 = sizeof(I5); -#endif - -@implementation I5 -#ifdef __x86_64 -@synthesize P1 = _MadeUpName; -@synthesize P2 = _AnotherMadeUpName; -#else -@synthesize P1 = _iv6; -@synthesize P2 = _iv7; -#endif -@end - -#if 0 -int g5_1 = sizeof(I5); -#endif - -@interface T0_I0 { - double iv_A_0; - char iv_A_1; -} -@end - -@interface T0_I1 : T0_I0 { - char iv_B_0; -} -@end - -@interface T0_I2 : T0_I1 { - char iv_C_0; -} -@end - -#if 0 -int g6 = sizeof(T0_I0); -int g7 = sizeof(T0_I1); -int g8 = sizeof(T0_I2); -#endif - -@implementation T0_I0 @end -@implementation T0_I1 @end -@implementation T0_I2 @end - -void f0(I2*i2,I3*i3,I4*i4,I5*i5,T0_I0*t0_i0,T0_I1*t0_i1,T0_I2*t0_i2) { -} - -// Thomas Wang's ui32 hash. -unsigned hash_ui32_to_ui32(unsigned a) { - a = (a ^ 61) ^ (a >> 16); - a = a + (a << 3); - a = a ^ (a >> 4); - a = a * 0x27d4eb2d; - a = a ^ (a >> 15); - return a; -} - -unsigned char hash_ui32_to_ui8(unsigned ui) { - ui = hash_ui32_to_ui32(ui); - ui ^= ui>>8; - ui ^= ui>>8; - ui ^= ui>>8; - return (unsigned char) ui; -} - -void *init() { - unsigned i, N = 1024; - unsigned char *p = malloc(N); - for (i=0; i != N; ++i) - p[i] = hash_ui32_to_ui8(i); - return p; -} - -int main(){ - void *p = init(); - f0(p,p,p,p,p,p,p); -} diff --git a/test/FrontendObjC/2009-08-05-utf16.m b/test/FrontendObjC/2009-08-05-utf16.m deleted file mode 100644 index df3745c48700..000000000000 --- a/test/FrontendObjC/2009-08-05-utf16.m +++ /dev/null @@ -1,5 +0,0 @@ -/* RUN: %llvmgcc -w -x objective-c -S %s -o - | grep {__utf16_string_1} | grep {internal unnamed_addr constant} | grep {12 x i8} - rdar://7095855 rdar://7115749 */ - -void *P = @"iPodâ„¢"; - diff --git a/test/FrontendObjC/2009-08-17-DebugInfo.m b/test/FrontendObjC/2009-08-17-DebugInfo.m deleted file mode 100644 index 825bbd75358c..000000000000 --- a/test/FrontendObjC/2009-08-17-DebugInfo.m +++ /dev/null @@ -1,28 +0,0 @@ -// This is a regression test on debug info to make sure that we can set a -// breakpoint on a objective message. -// RUN: %llvmgcc -S -O0 -g %s -o - | llc -disable-cfi -o %t.s -O0 -// RUN: %compile_c %t.s -o %t.o -// RUN: %link %t.o -o %t.exe -framework Foundation -// RUN: echo {break randomFunc\n} > %t.in -// RUN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | \ -// RUN: grep {Breakpoint 1 at 0x.*: file .*2009-08-17-DebugInfo.m, line 21} -// XTARGET: darwin -@interface MyClass -{ - int my; -} -+ init; -- randomFunc; -@end - -@implementation MyClass -+ init { -} -- randomFunc { my = 42; } -@end - -int main() { - id o = [MyClass init]; - [o randomFunc]; - return 0; -} diff --git a/test/FrontendObjC/2009-11-30-Objc-ID.m b/test/FrontendObjC/2009-11-30-Objc-ID.m deleted file mode 100644 index 787bf72efe3e..000000000000 --- a/test/FrontendObjC/2009-11-30-Objc-ID.m +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %llvmgcc -S -O0 -g %s -o - | \ -// RUN: llc --disable-fp-elim -o %t.s -O0 -// RUN: grep id %t.s | grep DW_AT_name -@interface A --(id) blah; -@end - -@implementation A --(id)blah { - int i = 1; - i++; - return i; -} -@end diff --git a/test/FrontendObjC/2010-02-01-utf16-with-null.m b/test/FrontendObjC/2010-02-01-utf16-with-null.m deleted file mode 100644 index 86e46376bd25..000000000000 --- a/test/FrontendObjC/2010-02-01-utf16-with-null.m +++ /dev/null @@ -1,5 +0,0 @@ -/* 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 deleted file mode 100644 index bb00f6a1e2c6..000000000000 --- a/test/FrontendObjC/2010-02-11-fwritable-stringsBug.m +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %llvmgcc -x objective-c -fwritable-strings -S %s -o - | FileCheck %s -// CHECK: @.str = private unnamed_addr constant -// CHECK: @.str1 = internal unnamed_addr 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/FrontendObjC/2010-02-23-DbgInheritance.m b/test/FrontendObjC/2010-02-23-DbgInheritance.m deleted file mode 100644 index 7e1cf67b4750..000000000000 --- a/test/FrontendObjC/2010-02-23-DbgInheritance.m +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %llvmgcc %s -S -g -o - | grep -v DW_TAG_member -// Interface P should not be a member of interface I in debug info. -@interface P -@end - -@interface I : P -@end - -void fn(I *iptr) {} diff --git a/test/FrontendObjC/2010-03-17-StructRef.m b/test/FrontendObjC/2010-03-17-StructRef.m deleted file mode 100644 index 3594684a194d..000000000000 --- a/test/FrontendObjC/2010-03-17-StructRef.m +++ /dev/null @@ -1,43 +0,0 @@ -// RUN: %llvmgcc %s -m64 -S -o - | FileCheck %s -// Bitfield references must not touch memory outside of the enclosing -// struct. Radar 7639995 -typedef signed char BOOL; -@protocol NSObject -- (id)init; -@end -@interface NSObject {} -@end -@interface IMAVChatParticipant : NSObject { - int _ardRole; - int _state; - int _avRelayStatus; - int _chatEndedReason; - int _chatError; - unsigned _sendingAudio:1; - unsigned _sendingVideo:1; - unsigned _sendingAuxVideo:1; - unsigned _audioMuted:1; - unsigned _videoPaused:1; - unsigned _networkStalled:1; - unsigned _isInitiator:1; - unsigned _isAOLInterop:1; - unsigned _isRecording:1; - unsigned _isUsingICE:1; -} -@end -@implementation IMAVChatParticipant -- (id) init { - self = [super init]; - if ( self ) { - BOOL blah = (BOOL)1; - // We're expecting these three bitfield assignments will generate i8 stores. - _sendingAudio = (BOOL)1; - _isUsingICE = (BOOL)1; - _isUsingICE = blah; - // CHECK: store i8 - // CHECK: store i8 - // CHECK: store i8 - } - return self; -} -@end diff --git a/test/FrontendObjC/2010-06-04-UnnamedCFString-dbg.m b/test/FrontendObjC/2010-06-04-UnnamedCFString-dbg.m deleted file mode 100644 index bded9ea2a403..000000000000 --- a/test/FrontendObjC/2010-06-04-UnnamedCFString-dbg.m +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: %llvmgcc -S -O0 -g %s -o - | grep DW_TAG_variable | count 1 - -// Do not emit debug info for unnamed builtin CFString variable. -@interface Foo -@end -Foo *FooName = @"FooBar"; diff --git a/test/FrontendObjC/2011-03-02-ConstCFStringLiteralAlign.m b/test/FrontendObjC/2011-03-02-ConstCFStringLiteralAlign.m deleted file mode 100644 index a5bd2b73bf09..000000000000 --- a/test/FrontendObjC/2011-03-02-ConstCFStringLiteralAlign.m +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %llvmgcc -S -w -m64 -mmacosx-version-min=10.5 %s -o - | \ -// RUN: llc --disable-fp-elim -o - | FileCheck %s -// XFAIL: * -// XTARGET: darwin - -@interface Foo -@end -Foo *FooName = @"FooBar"; - -// CHECK: .section __TEXT,__cstring,cstring_literals -// CHECK-NEXT: L_.str: diff --git a/test/FrontendObjC/2011-03-08-IVarLookup.m b/test/FrontendObjC/2011-03-08-IVarLookup.m deleted file mode 100644 index 939f2a7b8f36..000000000000 --- a/test/FrontendObjC/2011-03-08-IVarLookup.m +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: %llvmgcc -x objective-c -S -fobjc-abi-version=2 %s -o /dev/null -// XFAIL: * -// XTARGET: darwin - -typedef unsigned int UInt_t; - -@interface A -{ -@protected - UInt_t _f1; -} -@end - -@interface B : A { } -@end - -@interface A () -@property (assign) UInt_t f1; -@end - -@interface B () -@property (assign) int x; -@end - -@implementation B -@synthesize x; -- (id) init -{ - _f1 = 0; - return self; -} -@end diff --git a/test/FrontendObjC/dg.exp b/test/FrontendObjC/dg.exp deleted file mode 100644 index 18f73a797879..000000000000 --- a/test/FrontendObjC/dg.exp +++ /dev/null @@ -1,5 +0,0 @@ -load_lib llvm.exp - -if [ llvm_gcc_supports objc ] then { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{m}]] -} diff --git a/test/LLVMC/Alias.td b/test/LLVMC/Alias.td deleted file mode 100644 index 5d37889304bd..000000000000 --- a/test/LLVMC/Alias.td +++ /dev/null @@ -1,24 +0,0 @@ -// Test alias generation. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def OptList : OptionList<[ - -(switch_option "dummy1", (help "none")), -// CHECK: cl::alias Alias_dummy2 -(alias_option "dummy2", "dummy1") -]>; - -def dummy_tool : Tool<[ -(command "dummy_cmd"), -(in_language "dummy_lang"), -(out_language "dummy_lang"), -(actions (case - (switch_on "dummy1"), (forward "dummy1"))) -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/AppendCmdHook.td b/test/LLVMC/AppendCmdHook.td deleted file mode 100644 index c85f002e6e8b..000000000000 --- a/test/LLVMC/AppendCmdHook.td +++ /dev/null @@ -1,29 +0,0 @@ -// Check that hooks can be invoked from 'append_cmd'. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -// CHECK: std::string MyHook() - -def OptList : OptionList<[ -(switch_option "dummy1", (help "none")), -(switch_option "dummy2", (help "none")) -]>; - -def dummy_tool : Tool<[ -(command "dummy_cmd"), -(in_language "dummy_lang"), -(out_language "dummy_lang"), -(actions (case - // CHECK: , "-arg1")); - // CHECK: , "-arg2")); - (switch_on "dummy1"), (append_cmd "-arg1 -arg2"), - // CHECK: , "-arg3")); - // CHECK: hooks::MyHook() - (switch_on "dummy2"), (append_cmd "-arg3 $CALL(MyHook)"))) -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/C++/dash-x.cpp b/test/LLVMC/C++/dash-x.cpp deleted file mode 100644 index 7d4cf19fa41d..000000000000 --- a/test/LLVMC/C++/dash-x.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Test that we can compile .c files as C++ and vice versa -// RUN: llvmc %s -x c++ %p/../test_data/false.c -x c %p/../test_data/false.cpp -x lisp -x whatnot -x none %p/../test_data/false2.cpp -o %t -// RUN: %abs_tmp | grep hello -// XFAIL: vg - -extern int test_main(); - -int main() { - test_main(); -} diff --git a/test/LLVMC/C++/dg.exp b/test/LLVMC/C++/dg.exp deleted file mode 100644 index 209345540c11..000000000000 --- a/test/LLVMC/C++/dg.exp +++ /dev/null @@ -1,5 +0,0 @@ -load_lib llvm.exp - -if [ llvm_gcc_supports c++ ] then { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{unk,ll,c,cpp}]] -} diff --git a/test/LLVMC/C++/filelist.cpp b/test/LLVMC/C++/filelist.cpp deleted file mode 100644 index 6f5f6f7ae858..000000000000 --- a/test/LLVMC/C++/filelist.cpp +++ /dev/null @@ -1,3 +0,0 @@ -// Test that the -filelist option works correctly with -linker=c++. -// RUN: llvmc --dry-run -filelist DUMMY -linker c++ |& grep llvm-g++ -// XFAIL: vg diff --git a/test/LLVMC/C++/hello.cpp b/test/LLVMC/C++/hello.cpp deleted file mode 100644 index 8f38306e9e96..000000000000 --- a/test/LLVMC/C++/hello.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// Test that we can compile C++ code. -// RUN: llvmc %s -o %t -// RUN: %abs_tmp | grep hello -// XFAIL: vg -#include - -int main() { - std::cout << "hello" << '\n'; -} diff --git a/test/LLVMC/C++/just-compile.cpp b/test/LLVMC/C++/just-compile.cpp deleted file mode 100644 index 771c9822da69..000000000000 --- a/test/LLVMC/C++/just-compile.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Test that the -c flag works. -// RUN: llvmc -c %s -o %t.o -// RUN: llvmc --linker=c++ %t.o -o %t -// RUN: %abs_tmp | grep hello -// XFAIL: vg -#include - -int main() { - std::cout << "hello" << '\n'; -} diff --git a/test/LLVMC/C++/together.cpp b/test/LLVMC/C++/together.cpp deleted file mode 100644 index 925215a4db51..000000000000 --- a/test/LLVMC/C++/together.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Check that we can compile files of different types together. -// RUN: llvmc %s %p/../test_data/together.c -o %t -// RUN: %abs_tmp | grep hello -// XFAIL: vg - -extern "C" void test(); - -int main() { - test(); -} diff --git a/test/LLVMC/C++/unknown_suffix.unk b/test/LLVMC/C++/unknown_suffix.unk deleted file mode 100644 index bf4aea286247..000000000000 --- a/test/LLVMC/C++/unknown_suffix.unk +++ /dev/null @@ -1,9 +0,0 @@ -// Test that the -x option works for files with unknown suffixes. -// RUN: llvmc -x c++ %s -o %t -// RUN: %abs_tmp | grep hello -// XFAIL: vg -#include - -int main() { - std::cout << "hello" << '\n'; -} diff --git a/test/LLVMC/C/dg.exp b/test/LLVMC/C/dg.exp deleted file mode 100644 index a9be28a63cf6..000000000000 --- a/test/LLVMC/C/dg.exp +++ /dev/null @@ -1,5 +0,0 @@ -load_lib llvm.exp - -if [ llvm_gcc_supports c ] then { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] -} diff --git a/test/LLVMC/C/emit-llvm-opt.c b/test/LLVMC/C/emit-llvm-opt.c deleted file mode 100644 index 50710cf9dba2..000000000000 --- a/test/LLVMC/C/emit-llvm-opt.c +++ /dev/null @@ -1,9 +0,0 @@ -// Check that -emit-llvm [-S] works with -opt. - -// RUN: llvmc -c -opt -emit-llvm -o - %s | llvm-dis | grep "@f0()" | count 1 -// RUN: llvmc -c -opt -emit-llvm -S -o - %s | grep "@f0()" | count 1 -// RUN: llvmc --dry-run -c -opt -emit-llvm %s |& grep "^opt" -// XFAIL: vg_leak - -int f0(void) { -} diff --git a/test/LLVMC/C/emit-llvm.c b/test/LLVMC/C/emit-llvm.c deleted file mode 100644 index 56a1e30b2e42..000000000000 --- a/test/LLVMC/C/emit-llvm.c +++ /dev/null @@ -1,8 +0,0 @@ -// Check that -emit-llvm [-S] works correctly. - -// RUN: llvmc -c -emit-llvm -o - %s | llvm-dis | grep "@f0()" | count 1 -// RUN: llvmc -c -emit-llvm -S -o - %s | grep "@f0()" | count 1 -// XFAIL: vg_leak - -int f0(void) { -} diff --git a/test/LLVMC/C/hello.c b/test/LLVMC/C/hello.c deleted file mode 100644 index 29ad39fd2cb6..000000000000 --- a/test/LLVMC/C/hello.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Check that we can compile helloworld - * RUN: llvmc %s -o %t - * RUN: %abs_tmp | grep hello - * XFAIL: vg_leak - */ - -#include - -int main() { - printf("hello\n"); - return 0; -} diff --git a/test/LLVMC/C/include.c b/test/LLVMC/C/include.c deleted file mode 100644 index 9c9530bfb49f..000000000000 --- a/test/LLVMC/C/include.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Check that the 'include' options work. - * RUN: echo "int x;\n" > %t1.inc - * RUN: llvmc -include %t1.inc -fsyntax-only %s - * XFAIL: vg_leak - */ - -int f0(void) { - return x; -} diff --git a/test/LLVMC/C/opt-test.c b/test/LLVMC/C/opt-test.c deleted file mode 100644 index 7924def203ab..000000000000 --- a/test/LLVMC/C/opt-test.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Check that the -opt switch works. - * RUN: llvmc %s -opt -o %t - * RUN: %abs_tmp | grep hello - * XFAIL: vg_leak - */ - -#include - -int main() { - printf("hello\n"); - return 0; -} diff --git a/test/LLVMC/C/sink.c b/test/LLVMC/C/sink.c deleted file mode 100644 index c4f9beba8c38..000000000000 --- a/test/LLVMC/C/sink.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Check that the 'sink' options work. - * RUN: llvmc -v -Wall %s -o %t |& grep "Wall" - * RUN: %abs_tmp | grep hello - * XFAIL: vg_leak - */ - -#include - -int main() { - printf("hello\n"); - return 0; -} diff --git a/test/LLVMC/C/wall.c b/test/LLVMC/C/wall.c deleted file mode 100644 index 36813ba0f833..000000000000 --- a/test/LLVMC/C/wall.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Check that -Wall works as intended - * RUN: llvmc -Wall %s -o %t - * RUN: %abs_tmp | grep hello - * XFAIL: vg_leak - */ - -#include - -int main() { - printf("hello\n"); - return 0; -} diff --git a/test/LLVMC/EmptyCompilationGraph.td b/test/LLVMC/EmptyCompilationGraph.td deleted file mode 100644 index a52b8a8c1990..000000000000 --- a/test/LLVMC/EmptyCompilationGraph.td +++ /dev/null @@ -1,8 +0,0 @@ -// Check that the compilation graph can be empty. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def Graph : CompilationGraph<[]>; diff --git a/test/LLVMC/EnvParentheses.td b/test/LLVMC/EnvParentheses.td deleted file mode 100644 index ce0cb824604c..000000000000 --- a/test/LLVMC/EnvParentheses.td +++ /dev/null @@ -1,18 +0,0 @@ -// Check the fix for PR4157. -// http://llvm.org/bugs/show_bug.cgi?id=4157 -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: not grep {FOO")));} %t -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def dummy_tool : Tool<[ -(command "gcc $ENV(FOO)/bar"), -(in_language "dummy"), -(out_language "dummy") -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; - -def Graph : CompilationGraph<[]>; diff --git a/test/LLVMC/ForwardAs.td b/test/LLVMC/ForwardAs.td deleted file mode 100644 index 99b240e30fb3..000000000000 --- a/test/LLVMC/ForwardAs.td +++ /dev/null @@ -1,21 +0,0 @@ -// Check the fix for PR4159. -// http://llvm.org/bugs/show_bug.cgi?id=4159 -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def OptList : OptionList<[(parameter_option "dummy", (help "dummmy"))]>; - -def dummy_tool : Tool<[ -(command "dummy_cmd"), -(in_language "dummy"), -(out_language "dummy"), -(actions (case - // CHECK: "unique_name")); - (not_empty "dummy"), (forward_as "dummy", "unique_name"))) -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/ForwardTransformedValue.td b/test/LLVMC/ForwardTransformedValue.td deleted file mode 100644 index 9184ede36101..000000000000 --- a/test/LLVMC/ForwardTransformedValue.td +++ /dev/null @@ -1,27 +0,0 @@ -// Check that forward_transformed_value works. -// The dummy tool and graph are required to silence warnings. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def OptList : OptionList<[(parameter_option "a", (help "dummy")), - (prefix_list_option "b", (help "dummy"))]>; - -// CHECK: std::string HookA -// CHECK: std::string HookB - -def dummy_tool : Tool<[ -(command "dummy_cmd"), -(in_language "dummy"), -(out_language "dummy"), -(actions (case - // CHECK: HookA(autogenerated::Parameter_a - (not_empty "a"), (forward_transformed_value "a", "HookA"), - // CHECK: HookB(autogenerated::List_b - (not_empty "b"), (forward_transformed_value "b", "HookB"))) -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/ForwardValue.td b/test/LLVMC/ForwardValue.td deleted file mode 100644 index a42a3f06ec3d..000000000000 --- a/test/LLVMC/ForwardValue.td +++ /dev/null @@ -1,24 +0,0 @@ -// Check that forward_value works. -// The dummy tool and graph are required to silence warnings. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def OptList : OptionList<[(parameter_option "a", (help "dummy")), - (prefix_list_option "b", (help "dummy"))]>; - -def dummy_tool : Tool<[ -(command "dummy_cmd"), -(in_language "dummy"), -(out_language "dummy"), -(actions (case - // CHECK: , autogenerated::Parameter_a)); - (not_empty "a"), (forward_value "a"), - // CHECK: B = autogenerated::List_b.begin() - (not_empty "b"), (forward_value "b"))) -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/HookWithArguments.td b/test/LLVMC/HookWithArguments.td deleted file mode 100644 index bbba2e984599..000000000000 --- a/test/LLVMC/HookWithArguments.td +++ /dev/null @@ -1,20 +0,0 @@ -// Check that hooks with arguments work. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -// CHECK: Hook(const char* Arg0, const char* Arg1, const char* Arg2); -// CHECK: "/path" -// CHECK: std::getenv("VARIABLE") -// CHECK: "/2path" - -def dummy_tool : Tool<[ -(command "$CALL(Hook, 'Arg1', 'Arg2', 'Arg3 Arg3Cont')/path arg1 $ENV(VARIABLE)/2path arg2"), -(in_language "dummy"), -(out_language "dummy") -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/HookWithInFile.td b/test/LLVMC/HookWithInFile.td deleted file mode 100644 index ed08b5321ccf..000000000000 --- a/test/LLVMC/HookWithInFile.td +++ /dev/null @@ -1,16 +0,0 @@ -// Check that a hook can be given $INFILE as an argument. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def dummy_tool : Tool<[ -// CHECK: Hook(inFile.c_str()) -(command "$CALL(Hook, '$INFILE')/path"), -(in_language "dummy"), -(out_language "dummy") -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/Init.td b/test/LLVMC/Init.td deleted file mode 100644 index c3846797026e..000000000000 --- a/test/LLVMC/Init.td +++ /dev/null @@ -1,25 +0,0 @@ -// Check that (init true/false) and (init "str") work. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def OptList : OptionList<[ -// CHECK: cl::init(true) -(switch_option "dummy1", (help "none"), (init true)), -// CHECK: cl::init("some-string") -(parameter_option "dummy2", (help "none"), (init "some-string")) -]>; - -def dummy_tool : Tool<[ -(command "dummy_cmd"), -(in_language "dummy_lang"), -(out_language "dummy_lang"), -(actions (case - (switch_on "dummy1"), (forward "dummy1"), - (not_empty "dummy2"), (forward "dummy2"))) -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/LanguageMap.td b/test/LLVMC/LanguageMap.td deleted file mode 100644 index a0502142e6d7..000000000000 --- a/test/LLVMC/LanguageMap.td +++ /dev/null @@ -1,29 +0,0 @@ -// Check that LanguageMap is processed properly. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def OptList : OptionList<[ -(switch_option "dummy1", (help "none")) -]>; - -def dummy_tool : Tool<[ -(command "dummy_cmd"), -(in_language "dummy_lang"), -(out_language "dummy_lang"), -(actions (case - (switch_on "dummy1"), (forward "dummy1"))) -]>; - -def lang_map : LanguageMap<[ - // CHECK: langMap["dummy"] = "dummy_lang" - // CHECK: langMap["DUM"] = "dummy_lang" - (lang_to_suffixes "dummy_lang", ["dummy", "DUM"]), - // CHECK: langMap["DUM2"] = "dummy_lang_2" - (lang_to_suffixes "dummy_lang_2", "DUM2") -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/MultiValuedOption.td b/test/LLVMC/MultiValuedOption.td deleted file mode 100644 index 08c753380d47..000000000000 --- a/test/LLVMC/MultiValuedOption.td +++ /dev/null @@ -1,24 +0,0 @@ -// Check that multivalued options work. -// The dummy tool and graph are required to silence warnings. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def OptList : OptionList<[ - // CHECK: cl::multi_val(2) - (prefix_list_option "foo", (multi_val 2)), - (parameter_list_option "baz", (multi_val 2))]>; - -def dummy_tool : Tool<[ -(command "dummy_cmd"), -(in_language "dummy"), -(out_language "dummy"), -(actions (case - (not_empty "foo"), (forward_as "foo", "bar"), - (not_empty "baz"), (forward "baz"))) -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/MultipleCompilationGraphs.td b/test/LLVMC/MultipleCompilationGraphs.td deleted file mode 100644 index b3746c03b6cb..000000000000 --- a/test/LLVMC/MultipleCompilationGraphs.td +++ /dev/null @@ -1,10 +0,0 @@ -// Check that multiple compilation graphs are allowed. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def Graph1 : CompilationGraph<[]>; -def Graph2 : CompilationGraph<[]>; -def Graph3 : CompilationGraph<[]>; diff --git a/test/LLVMC/MultipleOutputLanguages.td b/test/LLVMC/MultipleOutputLanguages.td deleted file mode 100644 index ae0c92eefcf1..000000000000 --- a/test/LLVMC/MultipleOutputLanguages.td +++ /dev/null @@ -1,27 +0,0 @@ -// Check that multiple output languages work. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def dummy_tool : Tool<[ - (command "dummy_cmd"), - (in_language "dummy_lang"), - (out_language "another_dummy_lang", "yet_another_dummy_lang") -]>; - -def another_dummy_tool : Tool<[ - (command "another_dummy_cmd"), - (in_language "another_dummy_lang", "some_other_dummy_lang"), - (out_language "executable"), - (join) -]>; - -// CHECK: new SimpleEdge("dummy_tool") -// CHECK: new SimpleEdge("another_dummy_tool") -def DummyGraph : CompilationGraph<[ - (edge "root", "dummy_tool"), - (edge "dummy_tool", "another_dummy_tool") -]>; diff --git a/test/LLVMC/NoActions.td b/test/LLVMC/NoActions.td deleted file mode 100644 index 34b444066350..000000000000 --- a/test/LLVMC/NoActions.td +++ /dev/null @@ -1,16 +0,0 @@ -// Check that tools without associated actions are accepted. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -// CHECK: class dummy_tool : public Tool { -def dummy_tool : Tool<[ -(command "dummy_cmd"), -(in_language "dummy"), -(out_language "dummy") -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/NoCompilationGraph.td b/test/LLVMC/NoCompilationGraph.td deleted file mode 100644 index 4182882c451f..000000000000 --- a/test/LLVMC/NoCompilationGraph.td +++ /dev/null @@ -1,6 +0,0 @@ -// Check that the compilation graph is not required. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" diff --git a/test/LLVMC/ObjC++/dg.exp b/test/LLVMC/ObjC++/dg.exp deleted file mode 100644 index 41c3db2af097..000000000000 --- a/test/LLVMC/ObjC++/dg.exp +++ /dev/null @@ -1,5 +0,0 @@ -load_lib llvm.exp - -if [ llvm_gcc_supports obj-c++ ] then { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{mm}]] -} diff --git a/test/LLVMC/ObjC++/hello.mm b/test/LLVMC/ObjC++/hello.mm deleted file mode 100644 index 2125dc76b722..000000000000 --- a/test/LLVMC/ObjC++/hello.mm +++ /dev/null @@ -1,8 +0,0 @@ -// Test that we can compile Objective-C++ code. -// RUN: llvmc %s -o %t -// RUN: %abs_tmp | grep hello -#include - -int main() { - std::cout << "hello" << '\n'; -} diff --git a/test/LLVMC/ObjC/dg.exp b/test/LLVMC/ObjC/dg.exp deleted file mode 100644 index 18f73a797879..000000000000 --- a/test/LLVMC/ObjC/dg.exp +++ /dev/null @@ -1,5 +0,0 @@ -load_lib llvm.exp - -if [ llvm_gcc_supports objc ] then { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{m}]] -} diff --git a/test/LLVMC/ObjC/hello.m b/test/LLVMC/ObjC/hello.m deleted file mode 100644 index b2d903f8d53f..000000000000 --- a/test/LLVMC/ObjC/hello.m +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Check that we can compile helloworld - * RUN: llvmc %s -o %t - * RUN: %abs_tmp | grep hello - */ - -#include - -int main() { - printf("hello\n"); - return 0; -} diff --git a/test/LLVMC/OneOrMore.td b/test/LLVMC/OneOrMore.td deleted file mode 100644 index 54fa62d1ff04..000000000000 --- a/test/LLVMC/OneOrMore.td +++ /dev/null @@ -1,25 +0,0 @@ -// Check that (one_or_more) and (zero_or_one) properties work. -// The dummy tool and graph are required to silence warnings. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def OptList : OptionList<[ - // CHECK: cl::OneOrMore - (prefix_list_option "foo", (one_or_more)), - // CHECK: cl::Optional - (parameter_list_option "baz", (optional))]>; - -def dummy_tool : Tool<[ -(command "dummy_cmd"), -(in_language "dummy"), -(out_language "dummy"), -(actions (case - (not_empty "foo"), (forward_as "foo", "bar"), - (not_empty "baz"), (forward "baz"))) -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/OptionPreprocessor.td b/test/LLVMC/OptionPreprocessor.td deleted file mode 100644 index 5fdc35a187eb..000000000000 --- a/test/LLVMC/OptionPreprocessor.td +++ /dev/null @@ -1,67 +0,0 @@ -// Test for the OptionPreprocessor and related functionality. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def OptList : OptionList<[ -(switch_option "foo", (help "dummy")), -(switch_option "bar", (help "dummy")), -(switch_option "baz", (help "dummy")), -(parameter_option "foo_p", (help "dummy")), -(parameter_option "bar_p", (help "dummy")), -(parameter_option "baz_p", (help "dummy")), -(parameter_list_option "foo_l", (help "dummy")) -]>; - -def Preprocess : OptionPreprocessor< -(case - // CHECK: W1 - // CHECK: foo = false; - // CHECK: foo_p = ""; - // CHECK: foo_l.clear(); - (and (switch_on "foo"), (any_switch_on "bar", "baz")), - [(warning "W1"), (unset_option "foo"), - (unset_option "foo_p"), (unset_option "foo_l")], - // CHECK: W2 - // CHECK: foo = true; - // CHECK: bar = true; - // CHECK: baz = false; - // CHECK: foo_p = "asdf"; - // CHECK: foo_l.clear(); - // CHECK: foo_l.push_back("qwert"); - // CHECK: foo_l.push_back("yuiop"); - // CHECK: foo_l.push_back("asdf"); - (and (switch_on "foo", "bar"), (any_empty "foo_p", "bar_p")), - [(warning "W2"), (set_option "foo"), - (set_option "bar", true), - (set_option "baz", false), - (set_option "foo_p", "asdf"), - (set_option "foo_l", ["qwert", "yuiop", "asdf"])], - // CHECK: W3 - // CHECK: foo = true; - // CHECK: bar = true; - // CHECK: baz = true; - (and (empty "foo_p", "bar_p"), (any_not_empty "baz_p")), - [(warning "W3"), (set_option "foo", "bar", "baz")]) ->; - -// Shut up warnings... -def dummy : Tool< -[(in_language "dummy"), - (out_language "dummy"), - (output_suffix "d"), - (command "dummy"), - (actions (case (switch_on "foo"), (error), - (switch_on "bar"), (error), - (switch_on "baz"), (error), - (not_empty "foo_p"), (error), - (not_empty "bar_p"), (error), - (not_empty "baz_p"), (error), - (not_empty "foo_l"), (error))) -]>; - -def Graph : CompilationGraph<[(edge "root", "dummy")]>; - diff --git a/test/LLVMC/OutputSuffixHook.td b/test/LLVMC/OutputSuffixHook.td deleted file mode 100644 index 1f5ecd1237f3..000000000000 --- a/test/LLVMC/OutputSuffixHook.td +++ /dev/null @@ -1,24 +0,0 @@ -// Check that hooks can be invoked from 'output_suffix'. -// RUN: tblgen -I %p/../../include --gen-llvmc %s -o %t -// RUN: FileCheck -input-file %t %s -// RUN: %compile_cxx %t -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -// CHECK: std::string MyHook() - -def OptList : OptionList<[ -(switch_option "dummy1", (help "none")) -]>; - -def dummy_tool : Tool<[ -(command "dummy_cmd"), -(in_language "dummy_lang"), -(out_language "dummy_lang"), -(actions (case - // CHECK: hooks::MyHook() - (switch_on "dummy1"), (output_suffix "$CALL(MyHook)"))) -]>; - -def DummyGraph : CompilationGraph<[(edge "root", "dummy_tool")]>; diff --git a/test/LLVMC/TestWarnings.td b/test/LLVMC/TestWarnings.td deleted file mode 100644 index b0f57e97e0d8..000000000000 --- a/test/LLVMC/TestWarnings.td +++ /dev/null @@ -1,8 +0,0 @@ -// Check that warnings about unused options are really emitted. -// This should fail because the output is printed on stderr. -// RUN: tblgen -I %p/../../include --gen-llvmc %s |& grep "option '-Wall' has no effect!" -// XFAIL: vg_leak - -include "llvm/CompilerDriver/Common.td" - -def OptList : OptionList<[(switch_option "Wall", (help "dummy"))]>; diff --git a/test/LLVMC/dg.exp b/test/LLVMC/dg.exp deleted file mode 100644 index f7d275ad8cb1..000000000000 --- a/test/LLVMC/dg.exp +++ /dev/null @@ -1,3 +0,0 @@ -load_lib llvm.exp - -RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{td}]] diff --git a/test/LLVMC/test_data/false.c b/test/LLVMC/test_data/false.c deleted file mode 100644 index 3e4e8a7e9280..000000000000 --- a/test/LLVMC/test_data/false.c +++ /dev/null @@ -1,10 +0,0 @@ -#include - -extern "C" void test(); -extern std::string test2(); - -int test_main() { - std::cout << "h"; - test(); - std::cout << test2() << '\n'; -} diff --git a/test/LLVMC/test_data/false.cpp b/test/LLVMC/test_data/false.cpp deleted file mode 100644 index 593fcd5805a3..000000000000 --- a/test/LLVMC/test_data/false.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include - -/* Make this invalid C++ */ -typedef struct { - int i; - char c; -} a; - -static a b = { .i = 65, .c = 'r'}; - -void test() { - b.i = 9; - fflush(stdout); - printf("el"); -} - diff --git a/test/LLVMC/test_data/false2.cpp b/test/LLVMC/test_data/false2.cpp deleted file mode 100644 index bba064c8e042..000000000000 --- a/test/LLVMC/test_data/false2.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include - -std::string test2() { - return "lo"; -} diff --git a/test/LLVMC/test_data/together.c b/test/LLVMC/test_data/together.c deleted file mode 100644 index a828c475779b..000000000000 --- a/test/LLVMC/test_data/together.c +++ /dev/null @@ -1,5 +0,0 @@ -#include - -void test() { - printf("hello\n"); -} diff --git a/test/Linker/2003-01-30-LinkerTypeRename.ll b/test/Linker/2003-01-30-LinkerTypeRename.ll index 6cd2406ecd3f..043457da3735 100644 --- a/test/Linker/2003-01-30-LinkerTypeRename.ll +++ b/test/Linker/2003-01-30-LinkerTypeRename.ll @@ -1,9 +1,9 @@ -; This fails because the linker renames the non-opaque type not the opaque +; This fails because the linker renames the non-opaque type not the opaque ; one... -; RUN: echo {%Ty = type opaque @GV = external global %Ty*} | llvm-as > %t.1.bc +; RUN: echo {%%Ty = type opaque @GV = external global %%Ty*} | llvm-as > %t.1.bc ; RUN: llvm-as < %s > %t.2.bc -; RUN: llvm-link %t.1.bc %t.2.bc -S | grep {%Ty } | not grep opaque +; RUN: llvm-link %t.1.bc %t.2.bc -S | grep {%%Ty } | not grep opaque %Ty = type {i32} diff --git a/test/Linker/2003-04-26-NullPtrLinkProblem.ll b/test/Linker/2003-04-26-NullPtrLinkProblem.ll index 54ba05153f49..d23df1bb5912 100644 --- a/test/Linker/2003-04-26-NullPtrLinkProblem.ll +++ b/test/Linker/2003-04-26-NullPtrLinkProblem.ll @@ -1,7 +1,7 @@ ; This one fails because the LLVM runtime is allowing two null pointers of ; the same type to be created! -; RUN: echo {%T = type i32} | llvm-as > %t.2.bc +; RUN: echo {%%T = type i32} | llvm-as > %t.2.bc ; RUN: llvm-as %s -o %t.1.bc ; RUN: llvm-link %t.1.bc %t.2.bc diff --git a/test/Linker/2003-06-02-TypeResolveProblem.ll b/test/Linker/2003-06-02-TypeResolveProblem.ll index 86979f60d172..0b0e9c19087a 100644 --- a/test/Linker/2003-06-02-TypeResolveProblem.ll +++ b/test/Linker/2003-06-02-TypeResolveProblem.ll @@ -1,4 +1,4 @@ -; RUN: echo {%T = type opaque} | llvm-as > %t.2.bc +; RUN: echo {%%T = type opaque} | llvm-as > %t.2.bc ; RUN: llvm-as < %s > %t.1.bc ; RUN: llvm-link %t.1.bc %t.2.bc diff --git a/test/Linker/2003-06-02-TypeResolveProblem2.ll b/test/Linker/2003-06-02-TypeResolveProblem2.ll index 42cc0403ae77..3f9fd04ae340 100644 --- a/test/Linker/2003-06-02-TypeResolveProblem2.ll +++ b/test/Linker/2003-06-02-TypeResolveProblem2.ll @@ -1,4 +1,4 @@ -; RUN: echo {%T = type i32} | llvm-as > %t.1.bc +; RUN: echo {%%T = type i32} | llvm-as > %t.1.bc ; RUN: llvm-as < %s > %t.2.bc ; RUN: llvm-link %t.1.bc %t.2.bc diff --git a/test/Linker/2003-08-23-GlobalVarLinking.ll b/test/Linker/2003-08-23-GlobalVarLinking.ll index 8acbbd2fca2d..255cb88daf43 100644 --- a/test/Linker/2003-08-23-GlobalVarLinking.ll +++ b/test/Linker/2003-08-23-GlobalVarLinking.ll @@ -1,5 +1,5 @@ ; RUN: llvm-as < %s > %t.out1.bc -; RUN: echo {%T1 = type opaque %T2 = type opaque @S = external global \{ i32, %T1* \} declare void @F(%T2*)}\ +; RUN: echo {%%T1 = type opaque %%T2 = type opaque @S = external global \{ i32, %%T1* \} declare void @F(%%T2*)}\ ; RUN: | llvm-as > %t.out2.bc ; RUN: llvm-link %t.out1.bc %t.out2.bc -S | not grep opaque diff --git a/test/Linker/2003-11-18-TypeResolution.ll b/test/Linker/2003-11-18-TypeResolution.ll index d3152eda8e98..e7b15fa6b59f 100644 --- a/test/Linker/2003-11-18-TypeResolution.ll +++ b/test/Linker/2003-11-18-TypeResolution.ll @@ -5,7 +5,7 @@ ; own. ; RUN: llvm-as < %s > %t.out2.bc -; RUN: echo "%T1 = type opaque @GVar = external global %T1*" | llvm-as > %t.out1.bc +; RUN: echo "%%T1 = type opaque @GVar = external global %%T1*" | llvm-as > %t.out1.bc ; RUN: llvm-link %t.out1.bc %t.out2.bc %T1 = type opaque diff --git a/test/Linker/2011-08-04-DebugLoc.ll b/test/Linker/2011-08-04-DebugLoc.ll new file mode 100644 index 000000000000..699f0b535464 --- /dev/null +++ b/test/Linker/2011-08-04-DebugLoc.ll @@ -0,0 +1,26 @@ +; RUN: llvm-link %s %p/2011-08-04-DebugLoc2.ll -o %t.bc +; RUN: llvm-dis < %t.bc | FileCheck %s +; Test if DebugLoc is mapped properly or not. + + +;CHECK-NOT: metadata !{i32 589870, i32 0, metadata !{{[0-9]+}}, metadata !"bar", metadata !"bar", metadata !"", metadata !{{[0-9]+}}, i32 1, metadata !{{[0-9]+}}, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, null, null, null} + + +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-macosx10.7.0" + +define i32 @foo() nounwind ssp { + ret i32 42, !dbg !6 +} + +!llvm.dbg.cu = !{!0} +!llvm.dbg.sp = !{!1} + +!0 = metadata !{i32 589841, i32 0, i32 12, metadata !"a.c", metadata !"/private/tmp", metadata !"Apple clang version 3.0 (tags/Apple/clang-209.11) (based on LLVM 3.0svn)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"", metadata !2, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, i32 ()* @foo, null, null} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 589865, metadata !"a.c", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{metadata !5} +!5 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 2, i32 13, metadata !7, null} +!7 = metadata !{i32 589835, metadata !1, i32 2, i32 11, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] diff --git a/test/Linker/2011-08-04-DebugLoc2.ll b/test/Linker/2011-08-04-DebugLoc2.ll new file mode 100644 index 000000000000..f30e1805f40f --- /dev/null +++ b/test/Linker/2011-08-04-DebugLoc2.ll @@ -0,0 +1,23 @@ +; This file is used by 2011-08-04-DebugLoc.ll, so it doesn't actually do anything itself +; +; RUN: true + + +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-macosx10.7.0" + +define i32 @bar() nounwind ssp { + ret i32 21, !dbg !6 +} + +!llvm.dbg.cu = !{!0} +!llvm.dbg.sp = !{!1} + +!0 = metadata !{i32 589841, i32 0, i32 12, metadata !"b.c", metadata !"/private/tmp", metadata !"Apple clang version 3.0 (tags/Apple/clang-209.11) (based on LLVM 3.0svn)", i1 true, i1 false, metadata !"", i32 0} ; [ DW_TAG_compile_unit ] +!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"bar", metadata !"bar", metadata !"", metadata !2, i32 1, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, i32 ()* @bar, null, null} ; [ DW_TAG_subprogram ] +!2 = metadata !{i32 589865, metadata !"b.c", metadata !"/private/tmp", metadata !0} ; [ DW_TAG_file_type ] +!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!4 = metadata !{metadata !5} +!5 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!6 = metadata !{i32 1, i32 13, metadata !7, null} +!7 = metadata !{i32 589835, metadata !1, i32 1, i32 11, metadata !2, i32 0} ; [ DW_TAG_lexical_block ] diff --git a/test/Linker/2011-08-04-Metadata.ll b/test/Linker/2011-08-04-Metadata.ll new file mode 100644 index 000000000000..952eccc50768 --- /dev/null +++ b/test/Linker/2011-08-04-Metadata.ll @@ -0,0 +1,29 @@ +; RUN: llvm-link %s %p/2011-08-04-Metadata2.ll -o %t.bc +; RUN: llvm-dis < %t.bc | FileCheck %s +; Test if internal global variable's debug info is merged appropriately or not. + +;CHECK: metadata !{i32 589876, i32 0, metadata !{{[0-9]+}}, metadata !"x", metadata !"x", metadata !"", metadata !{{[0-9]+}}, i32 1, metadata !{{[0-9]+}}, i32 1, i32 1, i32* @x1} +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-macosx10.7.0" + +@x = internal global i32 0, align 4 + +define void @foo() nounwind uwtable ssp { +entry: + store i32 1, i32* @x, align 4, !dbg !7 + ret void, !dbg !7 +} + +!llvm.dbg.cu = !{!0} +!llvm.dbg.sp = !{!1} +!llvm.dbg.gv = !{!5} + +!0 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/one.c", metadata !"/Volumes/Lalgate/Slate/D", metadata !"clang version 3.0 ()", i1 true, i1 false, metadata !"", i32 0} +!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"foo", metadata !"foo", metadata !"", metadata !2, i32 3, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, void ()* @foo, null, null} +!2 = metadata !{i32 589865, metadata !"/tmp/one.c", metadata !"/Volumes/Lalgate/Slate/D", metadata !0} +!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} +!4 = metadata !{null} +!5 = metadata !{i32 589876, i32 0, metadata !0, metadata !"x", metadata !"x", metadata !"", metadata !2, i32 2, metadata !6, i32 1, i32 1, i32* @x} +!6 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} +!7 = metadata !{i32 3, i32 14, metadata !8, null} +!8 = metadata !{i32 589835, metadata !1, i32 3, i32 12, metadata !2, i32 0} diff --git a/test/Linker/2011-08-04-Metadata2.ll b/test/Linker/2011-08-04-Metadata2.ll new file mode 100644 index 000000000000..fa5e7c9a3f76 --- /dev/null +++ b/test/Linker/2011-08-04-Metadata2.ll @@ -0,0 +1,29 @@ +; This file is used by 2011-08-04-Metadata.ll, so it doesn't actually do anything itself +; +; RUN: true + + +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-macosx10.7.0" + +@x = internal global i32 0, align 4 + +define void @bar() nounwind uwtable ssp { +entry: + store i32 1, i32* @x, align 4, !dbg !7 + ret void, !dbg !7 +} + +!llvm.dbg.cu = !{!0} +!llvm.dbg.sp = !{!1} +!llvm.dbg.gv = !{!5} + +!0 = metadata !{i32 589841, i32 0, i32 12, metadata !"/tmp/two.c", metadata !"/Volumes/Lalgate/Slate/D", metadata !"clang version 3.0 ()", i1 true, i1 false, metadata !"", i32 0} +!1 = metadata !{i32 589870, i32 0, metadata !2, metadata !"bar", metadata !"bar", metadata !"", metadata !2, i32 2, metadata !3, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, void ()* @bar, null, null} +!2 = metadata !{i32 589865, metadata !"/tmp/two.c", metadata !"/Volumes/Lalgate/Slate/D", metadata !0} +!3 = metadata !{i32 589845, metadata !2, metadata !"", metadata !2, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} +!4 = metadata !{null} +!5 = metadata !{i32 589876, i32 0, metadata !0, metadata !"x", metadata !"x", metadata !"", metadata !2, i32 1, metadata !6, i32 1, i32 1, i32* @x} +!6 = metadata !{i32 589860, metadata !0, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} +!7 = metadata !{i32 2, i32 14, metadata !8, null} +!8 = metadata !{i32 589835, metadata !1, i32 2, i32 12, metadata !2, i32 0} diff --git a/test/Linker/2011-08-18-unique-class-type.ll b/test/Linker/2011-08-18-unique-class-type.ll new file mode 100644 index 000000000000..cae1245522ef --- /dev/null +++ b/test/Linker/2011-08-18-unique-class-type.ll @@ -0,0 +1,35 @@ +; RUN: llvm-link %s %p/2011-08-18-unique-class-type2.ll -S -o - | grep DW_TAG_class_type | count 1 +; Test to check there is only one MDNode for class A after linking. + +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-macosx10.7.0" + +%"class.N1::A" = type { i8 } + +define void @_Z3fooN2N11AE() nounwind uwtable ssp { +entry: + %mya = alloca %"class.N1::A", align 1 + call void @llvm.dbg.declare(metadata !{%"class.N1::A"* %mya}, metadata !9), !dbg !13 + ret void, !dbg !14 +} + +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +!llvm.dbg.cu = !{!0} + +!0 = metadata !{i32 720913, i32 0, i32 4, metadata !"n1.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 137954)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ] +!1 = metadata !{metadata !2} +!2 = metadata !{i32 0} +!3 = metadata !{metadata !4} +!4 = metadata !{metadata !5} +!5 = metadata !{i32 720942, i32 0, metadata !6, metadata !"foo", metadata !"foo", metadata !"_Z3fooN2N11AE", metadata !6, i32 4, metadata !7, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void ()* @_Z3fooN2N11AE, null, null} ; [ DW_TAG_subprogram ] +!6 = metadata !{i32 720937, metadata !"n1.c", metadata !"/private/tmp", null} ; [ DW_TAG_file_type ] +!7 = metadata !{i32 720917, metadata !6, metadata !"", metadata !6, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!8 = metadata !{null} +!9 = metadata !{i32 721153, metadata !5, metadata !"mya", metadata !6, i32 16777220, metadata !10, i32 0, i32 0} ; [ DW_TAG_arg_variable ] +!10 = metadata !{i32 720898, metadata !11, metadata !"A", metadata !12, i32 3, i64 8, i64 8, i32 0, i32 0, null, metadata !2, i32 0, null, null} ; [ DW_TAG_class_type ] +!11 = metadata !{i32 720953, null, metadata !"N1", metadata !12, i32 2} ; [ DW_TAG_namespace ] +!12 = metadata !{i32 720937, metadata !"./n.h", metadata !"/private/tmp", null} ; [ DW_TAG_file_type ] +!13 = metadata !{i32 4, i32 12, metadata !5, null} +!14 = metadata !{i32 4, i32 18, metadata !15, null} +!15 = metadata !{i32 720907, metadata !5, i32 4, i32 17, metadata !6, i32 0} ; [ DW_TAG_lexical_block ] diff --git a/test/Linker/2011-08-18-unique-class-type2.ll b/test/Linker/2011-08-18-unique-class-type2.ll new file mode 100644 index 000000000000..95892a44a5ba --- /dev/null +++ b/test/Linker/2011-08-18-unique-class-type2.ll @@ -0,0 +1,35 @@ +; This file is for use with 2011-08-10-unique-class-type.ll +; RUN: true + +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-macosx10.7.0" + +%"class.N1::A" = type { i8 } + +define void @_Z3barN2N11AE() nounwind uwtable ssp { +entry: + %youra = alloca %"class.N1::A", align 1 + call void @llvm.dbg.declare(metadata !{%"class.N1::A"* %youra}, metadata !9), !dbg !13 + ret void, !dbg !14 +} + +declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone + +!llvm.dbg.cu = !{!0} + +!0 = metadata !{i32 720913, i32 0, i32 4, metadata !"n2.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 137954)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ] +!1 = metadata !{metadata !2} +!2 = metadata !{i32 0} +!3 = metadata !{metadata !4} +!4 = metadata !{metadata !5} +!5 = metadata !{i32 720942, i32 0, metadata !6, metadata !"bar", metadata !"bar", metadata !"_Z3barN2N11AE", metadata !6, i32 4, metadata !7, i1 false, i1 true, i32 0, i32 0, i32 0, i32 256, i1 false, void ()* @_Z3barN2N11AE, null, null} ; [ DW_TAG_subprogram ] +!6 = metadata !{i32 720937, metadata !"n2.c", metadata !"/private/tmp", null} ; [ DW_TAG_file_type ] +!7 = metadata !{i32 720917, metadata !6, metadata !"", metadata !6, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!8 = metadata !{null} +!9 = metadata !{i32 721153, metadata !5, metadata !"youra", metadata !6, i32 16777220, metadata !10, i32 0, i32 0} ; [ DW_TAG_arg_variable ] +!10 = metadata !{i32 720898, metadata !11, metadata !"A", metadata !12, i32 3, i64 8, i64 8, i32 0, i32 0, null, metadata !2, i32 0, null, null} ; [ DW_TAG_class_type ] +!11 = metadata !{i32 720953, null, metadata !"N1", metadata !12, i32 2} ; [ DW_TAG_namespace ] +!12 = metadata !{i32 720937, metadata !"./n.h", metadata !"/private/tmp", null} ; [ DW_TAG_file_type ] +!13 = metadata !{i32 4, i32 12, metadata !5, null} +!14 = metadata !{i32 4, i32 20, metadata !15, null} +!15 = metadata !{i32 720907, metadata !5, i32 4, i32 19, metadata !6, i32 0} ; [ DW_TAG_lexical_block ] diff --git a/test/Linker/2011-08-18-unique-debug-type.ll b/test/Linker/2011-08-18-unique-debug-type.ll new file mode 100644 index 000000000000..4ef0e0e391e1 --- /dev/null +++ b/test/Linker/2011-08-18-unique-debug-type.ll @@ -0,0 +1,26 @@ + +; RUN: llvm-link %s %p/2011-08-18-unique-debug-type2.ll -S -o - | grep "int" | count 1 +; Test to check only one MDNode for "int" after linking. +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-macosx10.7.0" + +define i32 @foo() nounwind uwtable ssp { +entry: + ret i32 1, !dbg !10 +} + +!llvm.dbg.cu = !{!0} + +!0 = metadata !{i32 720913, i32 0, i32 12, metadata !"one.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 137954)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ] +!1 = metadata !{metadata !2} +!2 = metadata !{i32 0} +!3 = metadata !{metadata !4} +!4 = metadata !{metadata !5} +!5 = metadata !{i32 720942, i32 0, metadata !6, metadata !"foo", metadata !"foo", metadata !"", metadata !6, i32 1, metadata !7, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, i32 ()* @foo, null, null} ; [ DW_TAG_subprogram ] +!6 = metadata !{i32 720937, metadata !"one.c", metadata !"/private/tmp", null} ; [ DW_TAG_file_type ] +!7 = metadata !{i32 720917, metadata !6, metadata !"", metadata !6, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!8 = metadata !{metadata !9} +!9 = metadata !{i32 720932, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!10 = metadata !{i32 1, i32 13, metadata !11, null} +!11 = metadata !{i32 720907, metadata !5, i32 1, i32 11, metadata !6, i32 0} ; [ DW_TAG_lexical_block ] + diff --git a/test/Linker/2011-08-18-unique-debug-type2.ll b/test/Linker/2011-08-18-unique-debug-type2.ll new file mode 100644 index 000000000000..986da5b2cffa --- /dev/null +++ b/test/Linker/2011-08-18-unique-debug-type2.ll @@ -0,0 +1,25 @@ +; This file is for use with 2011-08-10-unique-debug-type.ll +; RUN: true + +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-macosx10.7.0" + +define i32 @bar() nounwind uwtable ssp { +entry: + ret i32 2, !dbg !10 +} + +!llvm.dbg.cu = !{!0} + +!0 = metadata !{i32 720913, i32 0, i32 12, metadata !"two.c", metadata !"/private/tmp", metadata !"clang version 3.0 (trunk 137954)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !3, metadata !1} ; [ DW_TAG_compile_unit ] +!1 = metadata !{metadata !2} +!2 = metadata !{i32 0} +!3 = metadata !{metadata !4} +!4 = metadata !{metadata !5} +!5 = metadata !{i32 720942, i32 0, metadata !6, metadata !"bar", metadata !"bar", metadata !"", metadata !6, i32 1, metadata !7, i1 false, i1 true, i32 0, i32 0, i32 0, i32 0, i1 false, i32 ()* @bar, null, null} ; [ DW_TAG_subprogram ] +!6 = metadata !{i32 720937, metadata !"two.c", metadata !"/private/tmp", null} ; [ DW_TAG_file_type ] +!7 = metadata !{i32 720917, metadata !6, metadata !"", metadata !6, i32 0, i64 0, i64 0, i32 0, i32 0, i32 0, metadata !8, i32 0, i32 0} ; [ DW_TAG_subroutine_type ] +!8 = metadata !{metadata !9} +!9 = metadata !{i32 720932, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] +!10 = metadata !{i32 1, i32 13, metadata !11, null} +!11 = metadata !{i32 720907, metadata !5, i32 1, i32 11, metadata !6, i32 0} ; [ DW_TAG_lexical_block ] diff --git a/test/Linker/2011-08-22-ResolveAlias.ll b/test/Linker/2011-08-22-ResolveAlias.ll new file mode 100644 index 000000000000..6b99233dd778 --- /dev/null +++ b/test/Linker/2011-08-22-ResolveAlias.ll @@ -0,0 +1,89 @@ +; PR10663 +; RUN: llvm-link %s %p/2011-08-22-ResolveAlias2.ll + +%union.pthread_attr_t = type { [56 x i8] } +%union.pthread_mutex_t = type { [40 x i8] } +%struct.timespec = type { i64, i64 } +%union.pthread_mutexattr_t = type { [4 x i8] } +%union.pthread_cond_t = type { [48 x i8] } + +@_ZL20__gthrw_pthread_oncePiPFvvE = alias weak i32 (i32*, void ()*)* @pthread_once +@_ZL27__gthrw_pthread_getspecificj = alias weak i8* (i32)* @pthread_getspecific +@_ZL27__gthrw_pthread_setspecificjPKv = alias weak i32 (i32, i8*)* @pthread_setspecific +@_ZL22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_ = alias weak i32 (i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*)* @pthread_create +@_ZL20__gthrw_pthread_joinmPPv = alias weak i32 (i64, i8**)* @pthread_join +@_ZL21__gthrw_pthread_equalmm = alias weak i32 (i64, i64)* @pthread_equal +@_ZL20__gthrw_pthread_selfv = alias weak i64 ()* @pthread_self +@_ZL22__gthrw_pthread_detachm = alias weak i32 (i64)* @pthread_detach +@_ZL22__gthrw_pthread_cancelm = alias weak i32 (i64)* @pthread_cancel +@_ZL19__gthrw_sched_yieldv = alias weak i32 ()* @sched_yield +@_ZL26__gthrw_pthread_mutex_lockP15pthread_mutex_t = alias weak i32 (%union.pthread_mutex_t*)* @pthread_mutex_lock +@_ZL29__gthrw_pthread_mutex_trylockP15pthread_mutex_t = alias weak i32 (%union.pthread_mutex_t*)* @pthread_mutex_trylock +@_ZL31__gthrw_pthread_mutex_timedlockP15pthread_mutex_tPK8timespec = alias weak i32 (%union.pthread_mutex_t*, %struct.timespec*)* @pthread_mutex_timedlock +@_ZL28__gthrw_pthread_mutex_unlockP15pthread_mutex_t = alias weak i32 (%union.pthread_mutex_t*)* @pthread_mutex_unlock +@_ZL26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t = alias weak i32 (%union.pthread_mutex_t*, %union.pthread_mutexattr_t*)* @pthread_mutex_init +@_ZL29__gthrw_pthread_mutex_destroyP15pthread_mutex_t = alias weak i32 (%union.pthread_mutex_t*)* @pthread_mutex_destroy +@_ZL30__gthrw_pthread_cond_broadcastP14pthread_cond_t = alias weak i32 (%union.pthread_cond_t*)* @pthread_cond_broadcast +@_ZL27__gthrw_pthread_cond_signalP14pthread_cond_t = alias weak i32 (%union.pthread_cond_t*)* @pthread_cond_signal +@_ZL25__gthrw_pthread_cond_waitP14pthread_cond_tP15pthread_mutex_t = alias weak i32 (%union.pthread_cond_t*, %union.pthread_mutex_t*)* @pthread_cond_wait +@_ZL30__gthrw_pthread_cond_timedwaitP14pthread_cond_tP15pthread_mutex_tPK8timespec = alias weak i32 (%union.pthread_cond_t*, %union.pthread_mutex_t*, %struct.timespec*)* @pthread_cond_timedwait +@_ZL28__gthrw_pthread_cond_destroyP14pthread_cond_t = alias weak i32 (%union.pthread_cond_t*)* @pthread_cond_destroy +@_ZL26__gthrw_pthread_key_createPjPFvPvE = alias weak i32 (i32*, void (i8*)*)* @pthread_key_create +@_ZL26__gthrw_pthread_key_deletej = alias weak i32 (i32)* @pthread_key_delete +@_ZL30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t = alias weak i32 (%union.pthread_mutexattr_t*)* @pthread_mutexattr_init +@_ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti = alias weak i32 (%union.pthread_mutexattr_t*, i32)* @pthread_mutexattr_settype +@_ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t = alias weak i32 (%union.pthread_mutexattr_t*)* @pthread_mutexattr_destroy + +declare extern_weak i32 @pthread_once(i32*, void ()*) + +declare extern_weak i8* @pthread_getspecific(i32) + +declare extern_weak i32 @pthread_setspecific(i32, i8*) + +declare extern_weak i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*) + +declare extern_weak i32 @pthread_join(i64, i8**) + +declare extern_weak i32 @pthread_equal(i64, i64) + +declare extern_weak i64 @pthread_self() + +declare extern_weak i32 @pthread_detach(i64) + +declare extern_weak i32 @pthread_cancel(i64) + +declare extern_weak i32 @sched_yield() + +declare extern_weak i32 @pthread_mutex_lock(%union.pthread_mutex_t*) + +declare extern_weak i32 @pthread_mutex_trylock(%union.pthread_mutex_t*) + +declare extern_weak i32 @pthread_mutex_timedlock(%union.pthread_mutex_t*, %struct.timespec*) + +declare extern_weak i32 @pthread_mutex_unlock(%union.pthread_mutex_t*) + +declare extern_weak i32 @pthread_mutex_init(%union.pthread_mutex_t*, %union.pthread_mutexattr_t*) + +declare extern_weak i32 @pthread_mutex_destroy(%union.pthread_mutex_t*) + +declare extern_weak i32 @pthread_cond_broadcast(%union.pthread_cond_t*) + +declare extern_weak i32 @pthread_cond_signal(%union.pthread_cond_t*) + +declare extern_weak i32 @pthread_cond_wait(%union.pthread_cond_t*, %union.pthread_mutex_t*) + +declare extern_weak i32 @pthread_cond_timedwait(%union.pthread_cond_t*, %union.pthread_mutex_t*, %struct.timespec*) + +declare extern_weak i32 @pthread_cond_destroy(%union.pthread_cond_t*) + +declare extern_weak i32 @pthread_key_create(i32*, void (i8*)*) + +declare extern_weak i32 @pthread_key_delete(i32) + +declare extern_weak i32 @pthread_mutexattr_init(%union.pthread_mutexattr_t*) + +declare extern_weak i32 @pthread_mutexattr_settype(%union.pthread_mutexattr_t*, i32) + +declare extern_weak i32 @pthread_mutexattr_destroy(%union.pthread_mutexattr_t*) + +declare void @_GLOBAL__sub_I__ZN10BitBoard64coEv() nounwind uwtable diff --git a/test/Linker/2011-08-22-ResolveAlias2.ll b/test/Linker/2011-08-22-ResolveAlias2.ll new file mode 100644 index 000000000000..254904059733 --- /dev/null +++ b/test/Linker/2011-08-22-ResolveAlias2.ll @@ -0,0 +1,92 @@ +; This file is used by 2011-08-22-ResolveAlias.ll +; RUN: true + +%struct.HexxagonBoard = type { %struct.BitBoard64, %struct.BitBoard64 } +%struct.BitBoard64 = type { i32, i32 } +%union.pthread_attr_t = type { [56 x i8] } +%union.pthread_mutex_t = type { [40 x i8] } +%struct.timespec = type { i64, i64 } +%union.pthread_mutexattr_t = type { [4 x i8] } +%union.pthread_cond_t = type { [48 x i8] } + +@_ZN13HexxagonBoardC1ERKS_ = alias void (%struct.HexxagonBoard*, %struct.HexxagonBoard*)* @_ZN13HexxagonBoardC2ERKS_ +@_ZL20__gthrw_pthread_oncePiPFvvE = alias weak i32 (i32*, void ()*)* @pthread_once +@_ZL27__gthrw_pthread_getspecificj = alias weak i8* (i32)* @pthread_getspecific +@_ZL27__gthrw_pthread_setspecificjPKv = alias weak i32 (i32, i8*)* @pthread_setspecific +@_ZL22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_ = alias weak i32 (i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*)* @pthread_create +@_ZL20__gthrw_pthread_joinmPPv = alias weak i32 (i64, i8**)* @pthread_join +@_ZL21__gthrw_pthread_equalmm = alias weak i32 (i64, i64)* @pthread_equal +@_ZL20__gthrw_pthread_selfv = alias weak i64 ()* @pthread_self +@_ZL22__gthrw_pthread_detachm = alias weak i32 (i64)* @pthread_detach +@_ZL22__gthrw_pthread_cancelm = alias weak i32 (i64)* @pthread_cancel +@_ZL19__gthrw_sched_yieldv = alias weak i32 ()* @sched_yield +@_ZL26__gthrw_pthread_mutex_lockP15pthread_mutex_t = alias weak i32 (%union.pthread_mutex_t*)* @pthread_mutex_lock +@_ZL29__gthrw_pthread_mutex_trylockP15pthread_mutex_t = alias weak i32 (%union.pthread_mutex_t*)* @pthread_mutex_trylock +@_ZL31__gthrw_pthread_mutex_timedlockP15pthread_mutex_tPK8timespec = alias weak i32 (%union.pthread_mutex_t*, %struct.timespec*)* @pthread_mutex_timedlock +@_ZL28__gthrw_pthread_mutex_unlockP15pthread_mutex_t = alias weak i32 (%union.pthread_mutex_t*)* @pthread_mutex_unlock +@_ZL26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t = alias weak i32 (%union.pthread_mutex_t*, %union.pthread_mutexattr_t*)* @pthread_mutex_init +@_ZL29__gthrw_pthread_mutex_destroyP15pthread_mutex_t = alias weak i32 (%union.pthread_mutex_t*)* @pthread_mutex_destroy +@_ZL30__gthrw_pthread_cond_broadcastP14pthread_cond_t = alias weak i32 (%union.pthread_cond_t*)* @pthread_cond_broadcast +@_ZL27__gthrw_pthread_cond_signalP14pthread_cond_t = alias weak i32 (%union.pthread_cond_t*)* @pthread_cond_signal +@_ZL25__gthrw_pthread_cond_waitP14pthread_cond_tP15pthread_mutex_t = alias weak i32 (%union.pthread_cond_t*, %union.pthread_mutex_t*)* @pthread_cond_wait +@_ZL30__gthrw_pthread_cond_timedwaitP14pthread_cond_tP15pthread_mutex_tPK8timespec = alias weak i32 (%union.pthread_cond_t*, %union.pthread_mutex_t*, %struct.timespec*)* @pthread_cond_timedwait +@_ZL28__gthrw_pthread_cond_destroyP14pthread_cond_t = alias weak i32 (%union.pthread_cond_t*)* @pthread_cond_destroy +@_ZL26__gthrw_pthread_key_createPjPFvPvE = alias weak i32 (i32*, void (i8*)*)* @pthread_key_create +@_ZL26__gthrw_pthread_key_deletej = alias weak i32 (i32)* @pthread_key_delete +@_ZL30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t = alias weak i32 (%union.pthread_mutexattr_t*)* @pthread_mutexattr_init +@_ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti = alias weak i32 (%union.pthread_mutexattr_t*, i32)* @pthread_mutexattr_settype +@_ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t = alias weak i32 (%union.pthread_mutexattr_t*)* @pthread_mutexattr_destroy + +declare void @_ZN13HexxagonBoardC2ERKS_(%struct.HexxagonBoard*, %struct.HexxagonBoard*) uwtable align 2 + +declare extern_weak i32 @pthread_once(i32*, void ()*) + +declare extern_weak i8* @pthread_getspecific(i32) + +declare extern_weak i32 @pthread_setspecific(i32, i8*) + +declare extern_weak i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*) + +declare extern_weak i32 @pthread_join(i64, i8**) + +declare extern_weak i32 @pthread_equal(i64, i64) + +declare extern_weak i64 @pthread_self() + +declare extern_weak i32 @pthread_detach(i64) + +declare extern_weak i32 @pthread_cancel(i64) + +declare extern_weak i32 @sched_yield() + +declare extern_weak i32 @pthread_mutex_lock(%union.pthread_mutex_t*) + +declare extern_weak i32 @pthread_mutex_trylock(%union.pthread_mutex_t*) + +declare extern_weak i32 @pthread_mutex_timedlock(%union.pthread_mutex_t*, %struct.timespec*) + +declare extern_weak i32 @pthread_mutex_unlock(%union.pthread_mutex_t*) + +declare extern_weak i32 @pthread_mutex_init(%union.pthread_mutex_t*, %union.pthread_mutexattr_t*) + +declare extern_weak i32 @pthread_mutex_destroy(%union.pthread_mutex_t*) + +declare extern_weak i32 @pthread_cond_broadcast(%union.pthread_cond_t*) + +declare extern_weak i32 @pthread_cond_signal(%union.pthread_cond_t*) + +declare extern_weak i32 @pthread_cond_wait(%union.pthread_cond_t*, %union.pthread_mutex_t*) + +declare extern_weak i32 @pthread_cond_timedwait(%union.pthread_cond_t*, %union.pthread_mutex_t*, %struct.timespec*) + +declare extern_weak i32 @pthread_cond_destroy(%union.pthread_cond_t*) + +declare extern_weak i32 @pthread_key_create(i32*, void (i8*)*) + +declare extern_weak i32 @pthread_key_delete(i32) + +declare extern_weak i32 @pthread_mutexattr_init(%union.pthread_mutexattr_t*) + +declare extern_weak i32 @pthread_mutexattr_settype(%union.pthread_mutexattr_t*, i32) + +declare extern_weak i32 @pthread_mutexattr_destroy(%union.pthread_mutexattr_t*) diff --git a/test/MC/ARM/arm-memory-instructions.s b/test/MC/ARM/arm-memory-instructions.s new file mode 100644 index 000000000000..783ac28ced95 --- /dev/null +++ b/test/MC/ARM/arm-memory-instructions.s @@ -0,0 +1,479 @@ +@ RUN: llvm-mc -triple=armv7-apple-darwin -show-encoding < %s | FileCheck %s + .syntax unified + .globl _func + +@ Check that the assembler can handle the documented syntax from the ARM ARM +@ for loads and stores. + +_func: +@ CHECK: _func + +@------------------------------------------------------------------------------ +@ LDR (immediate) +@------------------------------------------------------------------------------ + ldr r5, [r7] + ldr r6, [r3, #63] + ldr r2, [r4, #4095]! + ldr r1, [r2], #30 + ldr r3, [r1], #-30 + +@ CHECK: ldr r5, [r7] @ encoding: [0x00,0x50,0x97,0xe5] +@ CHECK: ldr r6, [r3, #63] @ encoding: [0x3f,0x60,0x93,0xe5] +@ CHECK: ldr r2, [r4, #4095]! @ encoding: [0xff,0x2f,0xb4,0xe5] +@ CHECK: ldr r1, [r2], #30 @ encoding: [0x1e,0x10,0x92,0xe4] +@ CHECK: ldr r3, [r1], #-30 @ encoding: [0x1e,0x30,0x11,0xe4] + +@------------------------------------------------------------------------------ +@ FIXME: LDR (literal) +@------------------------------------------------------------------------------ +@ label operands currently assert the show-encoding asm comment helper due +@ to the use of non-contiguous bit ranges for fixups in ARM. Once that's +@ cleaned up, we can write useful assembly testcases for these sorts of +@ instructions. + +@------------------------------------------------------------------------------ +@ LDR (register) +@------------------------------------------------------------------------------ + ldr r3, [r8, r1] + ldr r2, [r5, -r3] + ldr r1, [r5, r9]! + ldr r6, [r7, -r8]! + ldr r1, [r0, r2, lsr #3]! + ldr r5, [r9], r2 + ldr r4, [r3], -r6 + ldr r3, [r8, -r2, lsl #15] + ldr r1, [r5], r3, asr #15 + +@ CHECK: ldr r3, [r8, r1] @ encoding: [0x01,0x30,0x98,0xe7] +@ CHECK: ldr r2, [r5, -r3] @ encoding: [0x03,0x20,0x15,0xe7] +@ CHECK: ldr r1, [r5, r9]! @ encoding: [0x09,0x10,0xb5,0xe7] +@ CHECK: ldr r6, [r7, -r8]! @ encoding: [0x08,0x60,0x37,0xe7] +@ CHECK: ldr r1, [r0, r2, lsr #3]! @ encoding: [0xa2,0x11,0xb0,0xe7] +@ CHECK: ldr r5, [r9], r2 @ encoding: [0x02,0x50,0x99,0xe6] +@ CHECK: ldr r4, [r3], -r6 @ encoding: [0x06,0x40,0x13,0xe6] +@ CHECK: ldr r3, [r8, -r2, lsl #15] @ encoding: [0x82,0x37,0x18,0xe7] +@ CHECK: ldr r1, [r5], r3, asr #15 @ encoding: [0xc3,0x17,0x95,0xe6] + + +@------------------------------------------------------------------------------ +@ LDRB (immediate) +@------------------------------------------------------------------------------ + ldrb r3, [r8] + ldrb r1, [sp, #63] + ldrb r9, [r3, #4095]! + ldrb r8, [r1], #22 + ldrb r2, [r7], #-19 + +@ CHECK: ldrb r3, [r8] @ encoding: [0x00,0x30,0xd8,0xe5] +@ CHECK: ldrb r1, [sp, #63] @ encoding: [0x3f,0x10,0xdd,0xe5] +@ CHECK: ldrb r9, [r3, #4095]! @ encoding: [0xff,0x9f,0xf3,0xe5] +@ CHECK: ldrb r8, [r1], #22 @ encoding: [0x16,0x80,0xd1,0xe4] +@ CHECK: ldrb r2, [r7], #-19 @ encoding: [0x13,0x20,0x57,0xe4] + + +@------------------------------------------------------------------------------ +@ LDRB (register) +@------------------------------------------------------------------------------ + ldrb r9, [r8, r5] + ldrb r1, [r5, -r1] + ldrb r3, [r5, r2]! + ldrb r6, [r9, -r3]! + ldrb r2, [r1], r4 + ldrb r8, [r4], -r5 + ldrb r7, [r12, -r1, lsl #15] + ldrb r5, [r2], r9, asr #15 + +@ CHECK: ldrb r9, [r8, r5] @ encoding: [0x05,0x90,0xd8,0xe7] +@ CHECK: ldrb r1, [r5, -r1] @ encoding: [0x01,0x10,0x55,0xe7] +@ CHECK: ldrb r3, [r5, r2]! @ encoding: [0x02,0x30,0xf5,0xe7] +@ CHECK: ldrb r6, [r9, -r3]! @ encoding: [0x03,0x60,0x79,0xe7] +@ CHECK: ldrb r2, [r1], r4 @ encoding: [0x04,0x20,0xd1,0xe6] +@ CHECK: ldrb r8, [r4], -r5 @ encoding: [0x05,0x80,0x54,0xe6] +@ CHECK: ldrb r7, [r12, -r1, lsl #15] @ encoding: [0x81,0x77,0x5c,0xe7] +@ CHECK: ldrb r5, [r2], r9, asr #15 @ encoding: [0xc9,0x57,0xd2,0xe6] + + +@------------------------------------------------------------------------------ +@ LDRBT +@------------------------------------------------------------------------------ +@ FIXME: Optional offset operand. + ldrbt r3, [r1], #4 + ldrbt r2, [r8], #-8 + ldrbt r8, [r7], r6 + ldrbt r1, [r2], -r6, lsl #12 + + +@ CHECK: ldrbt r3, [r1], #4 @ encoding: [0x04,0x30,0xf1,0xe4] +@ CHECK: ldrbt r2, [r8], #-8 @ encoding: [0x08,0x20,0x78,0xe4] +@ CHECK: ldrbt r8, [r7], r6 @ encoding: [0x06,0x80,0xf7,0xe6] +@ CHECK: ldrbt r1, [r2], -r6, lsl #12 @ encoding: [0x06,0x16,0x72,0xe6] + + +@------------------------------------------------------------------------------ +@ LDRD (immediate) +@------------------------------------------------------------------------------ + ldrd r3, r4, [r5] + ldrd r7, r8, [r2, #15] + ldrd r1, r2, [r9, #32]! + ldrd r6, r7, [r1], #8 + ldrd r1, r2, [r8], #0 + ldrd r1, r2, [r8], #+0 + ldrd r1, r2, [r8], #-0 + +@ CHECK: ldrd r3, r4, [r5] @ encoding: [0xd0,0x30,0xc5,0xe1] +@ CHECK: ldrd r7, r8, [r2, #15] @ encoding: [0xdf,0x70,0xc2,0xe1] +@ CHECK: ldrd r1, r2, [r9, #32]! @ encoding: [0xd0,0x12,0xe9,0xe1] +@ CHECK: ldrd r6, r7, [r1], #8 @ encoding: [0xd8,0x60,0xc1,0xe0] +@ CHECK: ldrd r1, r2, [r8], #0 @ encoding: [0xd0,0x10,0xc8,0xe0] +@ CHECK: ldrd r1, r2, [r8], #0 @ encoding: [0xd0,0x10,0xc8,0xe0] +@ CHECK: ldrd r1, r2, [r8], #-0 @ encoding: [0xd0,0x10,0x48,0xe0] + + +@------------------------------------------------------------------------------ +@ FIXME: LDRD (label) +@------------------------------------------------------------------------------ + +@------------------------------------------------------------------------------ +@ LDRD (register) +@------------------------------------------------------------------------------ + ldrd r3, r4, [r1, r3] + ldrd r4, r5, [r7, r2]! + ldrd r1, r2, [r8], r12 + ldrd r1, r2, [r8], -r12 + +@ CHECK: ldrd r3, r4, [r1, r3] @ encoding: [0xd3,0x30,0x81,0xe1] +@ CHECK: ldrd r4, r5, [r7, r2]! @ encoding: [0xd2,0x40,0xa7,0xe1] +@ CHECK: ldrd r1, r2, [r8], r12 @ encoding: [0xdc,0x10,0x88,0xe0] +@ CHECK: ldrd r1, r2, [r8], -r12 @ encoding: [0xdc,0x10,0x08,0xe0] + + +@------------------------------------------------------------------------------ +@ LDRH (immediate) +@------------------------------------------------------------------------------ + ldrh r3, [r4] + ldrh r2, [r7, #4] + ldrh r1, [r8, #64]! + ldrh r12, [sp], #4 + +@ CHECK: ldrh r3, [r4] @ encoding: [0xb0,0x30,0xd4,0xe1] +@ CHECK: ldrh r2, [r7, #4] @ encoding: [0xb4,0x20,0xd7,0xe1] +@ CHECK: ldrh r1, [r8, #64]! @ encoding: [0xb0,0x14,0xf8,0xe1] +@ CHECK: ldrh r12, [sp], #4 @ encoding: [0xb4,0xc0,0xdd,0xe0] + + +@------------------------------------------------------------------------------ +@ FIXME: LDRH (label) +@------------------------------------------------------------------------------ + + +@------------------------------------------------------------------------------ +@ LDRH (register) +@------------------------------------------------------------------------------ + ldrh r6, [r5, r4] + ldrh r3, [r8, r11]! + ldrh r1, [r2, -r1]! + ldrh r9, [r7], r2 + ldrh r4, [r3], -r2 + +@ CHECK: ldrh r6, [r5, r4] @ encoding: [0xb4,0x60,0x95,0xe1] +@ CHECK: ldrh r3, [r8, r11]! @ encoding: [0xbb,0x30,0xb8,0xe1] +@ CHECK: ldrh r1, [r2, -r1]! @ encoding: [0xb1,0x10,0x32,0xe1] +@ CHECK: ldrh r9, [r7], r2 @ encoding: [0xb2,0x90,0x97,0xe0] +@ CHECK: ldrh r4, [r3], -r2 @ encoding: [0xb2,0x40,0x13,0xe0] + + +@------------------------------------------------------------------------------ +@ LDRHT +@------------------------------------------------------------------------------ + ldrht r9, [r7], #128 + ldrht r4, [r3], #-75 + ldrht r9, [r7], r2 + ldrht r4, [r3], -r2 + +@ CHECK: ldrht r9, [r7], #128 @ encoding: [0xb0,0x98,0xf7,0xe0] +@ CHECK: ldrht r4, [r3], #-75 @ encoding: [0xbb,0x44,0x73,0xe0] +@ CHECK: ldrht r9, [r7], r2 @ encoding: [0xb2,0x90,0xb7,0xe0] +@ CHECK: ldrht r4, [r3], -r2 @ encoding: [0xb2,0x40,0x33,0xe0] + + +@------------------------------------------------------------------------------ +@ LDRSB (immediate) +@------------------------------------------------------------------------------ + ldrsb r3, [r4] + ldrsb r2, [r7, #17] + ldrsb r1, [r8, #255]! + ldrsb r12, [sp], #9 + +@ CHECK: ldrsb r3, [r4] @ encoding: [0xd0,0x30,0xd4,0xe1] +@ CHECK: ldrsb r2, [r7, #17] @ encoding: [0xd1,0x21,0xd7,0xe1] +@ CHECK: ldrsb r1, [r8, #255]! @ encoding: [0xdf,0x1f,0xf8,0xe1] +@ CHECK: ldrsb r12, [sp], #9 @ encoding: [0xd9,0xc0,0xdd,0xe0] + + +@------------------------------------------------------------------------------ +@ FIXME: LDRSB (label) +@------------------------------------------------------------------------------ + + +@------------------------------------------------------------------------------ +@ LDRSB (register) +@------------------------------------------------------------------------------ + ldrsb r6, [r5, r4] + ldrsb r3, [r8, r11]! + ldrsb r1, [r2, -r1]! + ldrsb r9, [r7], r2 + ldrsb r4, [r3], -r2 + + +@ CHECK: ldrsb r6, [r5, r4] @ encoding: [0xd4,0x60,0x95,0xe1] +@ CHECK: ldrsb r3, [r8, r11]! @ encoding: [0xdb,0x30,0xb8,0xe1] +@ CHECK: ldrsb r1, [r2, -r1]! @ encoding: [0xd1,0x10,0x32,0xe1] +@ CHECK: ldrsb r9, [r7], r2 @ encoding: [0xd2,0x90,0x97,0xe0] +@ CHECK: ldrsb r4, [r3], -r2 @ encoding: [0xd2,0x40,0x13,0xe0] + + +@------------------------------------------------------------------------------ +@ LDRSBT +@------------------------------------------------------------------------------ + ldrsbt r5, [r6], #1 + ldrsbt r3, [r8], #-12 + ldrsbt r8, [r9], r5 + ldrsbt r2, [r1], -r4 + +@ CHECK: ldrsbt r5, [r6], #1 @ encoding: [0xd1,0x50,0xf6,0xe0] +@ CHECK: ldrsbt r3, [r8], #-12 @ encoding: [0xdc,0x30,0x78,0xe0] +@ CHECK: ldrsbt r8, [r9], r5 @ encoding: [0xd5,0x80,0xb9,0xe0] +@ CHECK: ldrsbt r2, [r1], -r4 @ encoding: [0xd4,0x20,0x31,0xe0] + + +@------------------------------------------------------------------------------ +@ LDRSH (immediate) +@------------------------------------------------------------------------------ + ldrsh r5, [r9] + ldrsh r4, [r5, #7] + ldrsh r3, [r6, #55]! + ldrsh r2, [r7], #-9 + +@ CHECK: ldrsh r5, [r9] @ encoding: [0xf0,0x50,0xd9,0xe1] +@ CHECK: ldrsh r4, [r5, #7] @ encoding: [0xf7,0x40,0xd5,0xe1] +@ CHECK: ldrsh r3, [r6, #55]! @ encoding: [0xf7,0x33,0xf6,0xe1] +@ CHECK: ldrsh r2, [r7], #-9 @ encoding: [0xf9,0x20,0x57,0xe0] + + +@------------------------------------------------------------------------------ +@ FIXME: LDRSH (label) +@------------------------------------------------------------------------------ + + +@------------------------------------------------------------------------------ +@ LDRSH (register) +@------------------------------------------------------------------------------ + ldrsh r3, [r1, r5] + ldrsh r4, [r6, r1]! + ldrsh r5, [r3, -r6]! + ldrsh r6, [r9], r8 + ldrsh r7, [r8], -r3 + +@ CHECK: ldrsh r3, [r1, r5] @ encoding: [0xf5,0x30,0x91,0xe1] +@ CHECK: ldrsh r4, [r6, r1]! @ encoding: [0xf1,0x40,0xb6,0xe1] +@ CHECK: ldrsh r5, [r3, -r6]! @ encoding: [0xf6,0x50,0x33,0xe1] +@ CHECK: ldrsh r6, [r9], r8 @ encoding: [0xf8,0x60,0x99,0xe0] +@ CHECK: ldrsh r7, [r8], -r3 @ encoding: [0xf3,0x70,0x18,0xe0] + + +@------------------------------------------------------------------------------ +@ LDRSHT +@------------------------------------------------------------------------------ + ldrsht r5, [r6], #1 + ldrsht r3, [r8], #-12 + ldrsht r8, [r9], r5 + ldrsht r2, [r1], -r4 + +@ CHECK: ldrsht r5, [r6], #1 @ encoding: [0xf1,0x50,0xf6,0xe0] +@ CHECK: ldrsht r3, [r8], #-12 @ encoding: [0xfc,0x30,0x78,0xe0] +@ CHECK: ldrsht r8, [r9], r5 @ encoding: [0xf5,0x80,0xb9,0xe0] +@ CHECK: ldrsht r2, [r1], -r4 @ encoding: [0xf4,0x20,0x31,0xe0] + + +@------------------------------------------------------------------------------ +@ STR (immediate) +@------------------------------------------------------------------------------ + str r8, [r12] + str r7, [r1, #12] + str r3, [r5, #40]! + str r9, [sp], #4095 + str r1, [r7], #-128 + +@ CHECK: str r8, [r12] @ encoding: [0x00,0x80,0x8c,0xe5] +@ CHECK: str r7, [r1, #12] @ encoding: [0x0c,0x70,0x81,0xe5] +@ CHECK: str r3, [r5, #40]! @ encoding: [0x28,0x30,0xa5,0xe5] +@ CHECK: str r9, [sp], #4095 @ encoding: [0xff,0x9f,0x8d,0xe4] +@ CHECK: str r1, [r7], #-128 @ encoding: [0x80,0x10,0x07,0xe4] + + +@------------------------------------------------------------------------------ +@ FIXME: STR (literal) +@------------------------------------------------------------------------------ + +@------------------------------------------------------------------------------ +@ STR (register) +@------------------------------------------------------------------------------ + str r9, [r6, r3] + str r8, [r0, -r2] + str r7, [r1, r6]! + str r6, [sp, -r1]! + str r5, [r3], r9 + str r4, [r2], -r5 + str r3, [r4, -r2, lsl #2] + str r2, [r7], r3, asr #24 + +@ CHECK: str r9, [r6, r3] @ encoding: [0x03,0x90,0x86,0xe7] +@ CHECK: str r8, [r0, -r2] @ encoding: [0x02,0x80,0x00,0xe7] +@ CHECK: str r7, [r1, r6]! @ encoding: [0x06,0x70,0xa1,0xe7] +@ CHECK: str r6, [sp, -r1]! @ encoding: [0x01,0x60,0x2d,0xe7] +@ CHECK: str r5, [r3], r9 @ encoding: [0x09,0x50,0x83,0xe6] +@ CHECK: str r4, [r2], -r5 @ encoding: [0x05,0x40,0x02,0xe6] +@ CHECK: str r3, [r4, -r2, lsl #2] @ encoding: [0x02,0x31,0x04,0xe7] +@ CHECK: str r2, [r7], r3, asr #24 @ encoding: [0x43,0x2c,0x87,0xe6] + + +@------------------------------------------------------------------------------ +@ STRB (immediate) +@------------------------------------------------------------------------------ + strb r9, [r2] + strb r7, [r1, #3] + strb r6, [r4, #405]! + strb r5, [r7], #72 + strb r1, [sp], #-1 + +@ CHECK: strb r9, [r2] @ encoding: [0x00,0x90,0xc2,0xe5] +@ CHECK: strb r7, [r1, #3] @ encoding: [0x03,0x70,0xc1,0xe5] +@ CHECK: strb r6, [r4, #405]! @ encoding: [0x95,0x61,0xe4,0xe5] +@ CHECK: strb r5, [r7], #72 @ encoding: [0x48,0x50,0xc7,0xe4] +@ CHECK: strb r1, [sp], #-1 @ encoding: [0x01,0x10,0x4d,0xe4] + +@------------------------------------------------------------------------------ +@ FIXME: STRB (literal) +@------------------------------------------------------------------------------ + +@------------------------------------------------------------------------------ +@ STRB (register) +@------------------------------------------------------------------------------ + strb r1, [r2, r9] + strb r2, [r3, -r8] + strb r3, [r4, r7]! + strb r4, [r5, -r6]! + strb r5, [r6], r5 + strb r6, [r2], -r4 + strb r7, [r12, -r3, lsl #5] + strb sp, [r7], r2, asr #12 + +@ CHECK: strb r1, [r2, r9] @ encoding: [0x09,0x10,0xc2,0xe7] +@ CHECK: strb r2, [r3, -r8] @ encoding: [0x08,0x20,0x43,0xe7] +@ CHECK: strb r3, [r4, r7]! @ encoding: [0x07,0x30,0xe4,0xe7] +@ CHECK: strb r4, [r5, -r6]! @ encoding: [0x06,0x40,0x65,0xe7] +@ CHECK: strb r5, [r6], r5 @ encoding: [0x05,0x50,0xc6,0xe6] +@ CHECK: strb r6, [r2], -r4 @ encoding: [0x04,0x60,0x42,0xe6] +@ CHECK: strb r7, [r12, -r3, lsl #5] @ encoding: [0x83,0x72,0x4c,0xe7] +@ CHECK: strb sp, [r7], r2, asr #12 @ encoding: [0x42,0xd6,0xc7,0xe6] + + +@------------------------------------------------------------------------------ +@ STRBT +@------------------------------------------------------------------------------ +@ FIXME: Optional offset operand. + strbt r6, [r2], #12 + strbt r5, [r6], #-13 + strbt r4, [r9], r5 + strbt r3, [r8], -r2, lsl #3 + +@ CHECK: strbt r6, [r2], #12 @ encoding: [0x0c,0x60,0xe2,0xe4] +@ CHECK: strbt r5, [r6], #-13 @ encoding: [0x0d,0x50,0x66,0xe4] +@ CHECK: strbt r4, [r9], r5 @ encoding: [0x05,0x40,0xe9,0xe6] +@ CHECK: strbt r3, [r8], -r2, lsl #3 @ encoding: [0x82,0x31,0x68,0xe6] + + +@------------------------------------------------------------------------------ +@ STRD (immediate) +@------------------------------------------------------------------------------ + strd r1, r2, [r4] + strd r2, r3, [r6, #1] + strd r3, r4, [r7, #22]! + strd r4, r5, [r8], #7 + strd r5, r6, [sp], #0 + strd r6, r7, [lr], #+0 + strd r7, r8, [r9], #-0 + +@ CHECK: strd r1, r2, [r4] @ encoding: [0xf0,0x10,0xc4,0xe1] +@ CHECK: strd r2, r3, [r6, #1] @ encoding: [0xf1,0x20,0xc6,0xe1] +@ CHECK: strd r3, r4, [r7, #22]! @ encoding: [0xf6,0x31,0xe7,0xe1] +@ CHECK: strd r4, r5, [r8], #7 @ encoding: [0xf7,0x40,0xc8,0xe0] +@ CHECK: strd r5, r6, [sp], #0 @ encoding: [0xf0,0x50,0xcd,0xe0] +@ CHECK: strd r6, r7, [lr], #0 @ encoding: [0xf0,0x60,0xce,0xe0] +@ CHECK: strd r7, r8, [r9], #-0 @ encoding: [0xf0,0x70,0x49,0xe0] + + +@------------------------------------------------------------------------------ +@ FIXME: STRD (label) +@------------------------------------------------------------------------------ + +@------------------------------------------------------------------------------ +@ STRD (register) +@------------------------------------------------------------------------------ + strd r8, r9, [r4, r1] + strd r7, r8, [r3, r9]! + strd r6, r7, [r5], r8 + strd r5, r6, [r12], -r10 + +@ CHECK: strd r8, r9, [r4, r1] @ encoding: [0xf1,0x80,0x84,0xe1] +@ CHECK: strd r7, r8, [r3, r9]! @ encoding: [0xf9,0x70,0xa3,0xe1] +@ CHECK: strd r6, r7, [r5], r8 @ encoding: [0xf8,0x60,0x85,0xe0] +@ CHECK: strd r5, r6, [r12], -r10 @ encoding: [0xfa,0x50,0x0c,0xe0] + + +@------------------------------------------------------------------------------ +@ STRH (immediate) +@------------------------------------------------------------------------------ + strh r3, [r4] + strh r2, [r7, #4] + strh r1, [r8, #64]! + strh r12, [sp], #4 + +@ CHECK: strh r3, [r4] @ encoding: [0xb0,0x30,0xc4,0xe1] +@ CHECK: strh r2, [r7, #4] @ encoding: [0xb4,0x20,0xc7,0xe1] +@ CHECK: strh r1, [r8, #64]! @ encoding: [0xb0,0x14,0xe8,0xe1] +@ CHECK: strh r12, [sp], #4 @ encoding: [0xb4,0xc0,0xcd,0xe0] + + +@------------------------------------------------------------------------------ +@ FIXME: STRH (label) +@------------------------------------------------------------------------------ + + +@------------------------------------------------------------------------------ +@ STRH (register) +@------------------------------------------------------------------------------ + strh r6, [r5, r4] + strh r3, [r8, r11]! + strh r1, [r2, -r1]! + strh r9, [r7], r2 + strh r4, [r3], -r2 + +@ CHECK: strh r6, [r5, r4] @ encoding: [0xb4,0x60,0x85,0xe1] +@ CHECK: strh r3, [r8, r11]! @ encoding: [0xbb,0x30,0xa8,0xe1] +@ CHECK: strh r1, [r2, -r1]! @ encoding: [0xb1,0x10,0x22,0xe1] +@ CHECK: strh r9, [r7], r2 @ encoding: [0xb2,0x90,0x87,0xe0] +@ CHECK: strh r4, [r3], -r2 @ encoding: [0xb2,0x40,0x03,0xe0] + +@------------------------------------------------------------------------------ +@ STRHT +@------------------------------------------------------------------------------ + strht r2, [r5], #76 + strht r8, [r1], #-25 + strht r5, [r3], r4 + strht r6, [r8], -r0 + +@ CHECK: strht r2, [r5], #76 @ encoding: [0xbc,0x24,0xe5,0xe0] +@ CHECK: strht r8, [r1], #-25 @ encoding: [0xb9,0x81,0x61,0xe0] +@ CHECK: strht r5, [r3], r4 @ encoding: [0xb4,0x50,0xa3,0xe0] +@ CHECK: strht r6, [r8], -r0 @ encoding: [0xb0,0x60,0x28,0xe0] diff --git a/test/MC/ARM/arm_addrmode3.s b/test/MC/ARM/arm_addrmode3.s index 0b9639e32307..e1dc02004181 100644 --- a/test/MC/ARM/arm_addrmode3.s +++ b/test/MC/ARM/arm_addrmode3.s @@ -1,12 +1,12 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | FileCheck %s -@ CHECK: ldrsbt r1, [r0], +r2 @ encoding: [0xd2,0x10,0xb0,0xe0] +@ CHECK: ldrsbt r1, [r0], r2 @ encoding: [0xd2,0x10,0xb0,0xe0] @ CHECK: ldrsbt r1, [r0], #4 @ encoding: [0xd4,0x10,0xf0,0xe0] -@ CHECK: ldrsht r1, [r0], +r2 @ encoding: [0xf2,0x10,0xb0,0xe0] +@ CHECK: ldrsht r1, [r0], r2 @ encoding: [0xf2,0x10,0xb0,0xe0] @ CHECK: ldrsht r1, [r0], #4 @ encoding: [0xf4,0x10,0xf0,0xe0] -@ CHECK: ldrht r1, [r0], +r2 @ encoding: [0xb2,0x10,0xb0,0xe0] +@ CHECK: ldrht r1, [r0], r2 @ encoding: [0xb2,0x10,0xb0,0xe0] @ CHECK: ldrht r1, [r0], #4 @ encoding: [0xb4,0x10,0xf0,0xe0] -@ CHECK: strht r1, [r0], +r2 @ encoding: [0xb2,0x10,0xa0,0xe0] +@ CHECK: strht r1, [r0], r2 @ encoding: [0xb2,0x10,0xa0,0xe0] @ CHECK: strht r1, [r0], #4 @ encoding: [0xb4,0x10,0xe0,0xe0] ldrsbt r1, [r0], r2 ldrsbt r1, [r0], #4 diff --git a/test/MC/ARM/arm_fixups.s b/test/MC/ARM/arm_fixups.s index 0dceb83c24ab..aba0cd824dbc 100644 --- a/test/MC/ARM/arm_fixups.s +++ b/test/MC/ARM/arm_fixups.s @@ -1,7 +1,17 @@ -// RUN: llvm-mc -triple arm-unknown-unknown %s --show-encoding > %t -// RUN: FileCheck < %t %s +@ RUN: llvm-mc -triple armv7-unknown-unknown %s --show-encoding > %t +@ RUN: FileCheck < %t %s -// CHECK: bl _printf @ encoding: [A,A,A,0xeb] -// CHECK: @ fixup A - offset: 0, value: _printf, kind: fixup_arm_uncondbranch -bl _printf - \ No newline at end of file + bl _printf +@ CHECK: bl _printf @ encoding: [A,A,A,0xeb] +@ CHECK: @ fixup A - offset: 0, value: _printf, kind: fixup_arm_uncondbranch + + mov r9, :lower16:(_foo) + movw r9, :lower16:(_foo) + movt r9, :upper16:(_foo) + +@ CHECK: movw r9, :lower16:_foo @ encoding: [A,0x90'A',0b0000AAAA,0xe3] +@ CHECK: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movw_lo16 +@ CHECK: movw r9, :lower16:_foo @ encoding: [A,0x90'A',0b0000AAAA,0xe3] +@ CHECK: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movw_lo16 +@ CHECK: movt r9, :upper16:_foo @ encoding: [A,0x90'A',0b0100AAAA,0xe3] +@ CHECK: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movt_hi16 diff --git a/test/MC/ARM/arm_instructions.s b/test/MC/ARM/arm_instructions.s index 650fcd2374fe..186954cafa56 100644 --- a/test/MC/ARM/arm_instructions.s +++ b/test/MC/ARM/arm_instructions.s @@ -1,13 +1,5 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding %s | FileCheck %s -@ CHECK: nop -@ CHECK: encoding: [0x00,0xf0,0x20,0xe3] - nop - -@ CHECK: nopeq -@ CHECK: encoding: [0x00,0xf0,0x20,0x03] - nopeq - @ CHECK: trap @ CHECK: encoding: [0xfe,0xde,0xff,0xe7] trap @@ -47,15 +39,6 @@ @ CHECK: adc r1, r2, r3 @ encoding: [0x03,0x10,0xa2,0xe0] adc r1,r2,r3 -@ CHECK: sbc r1, r2, r3 @ encoding: [0x03,0x10,0xc2,0xe0] - sbc r1,r2,r3 - -@ CHECK: orr r1, r2, r3 @ encoding: [0x03,0x10,0x82,0xe1] - orr r1,r2,r3 - -@ CHECK: orrs r1, r2, r3 @ encoding: [0x03,0x10,0x92,0xe1] - orrs r1,r2,r3 - @ CHECK: bic r1, r2, r3 @ encoding: [0x03,0x10,0xc2,0xe1] bic r1,r2,r3 @@ -71,135 +54,23 @@ @ CHECK: mvns r1, r2 @ encoding: [0x02,0x10,0xf0,0xe1] mvns r1,r2 -@ CHECK: rsb r1, r2, r3 @ encoding: [0x03,0x10,0x62,0xe0] - rsb r1,r2,r3 - -@ CHECK: rsc r1, r2, r3 @ encoding: [0x03,0x10,0xe2,0xe0] - rsc r1,r2,r3 - @ CHECK: bfi r0, r0, #5, #7 @ encoding: [0x90,0x02,0xcb,0xe7] bfi r0, r0, #5, #7 @ CHECK: bkpt #10 @ encoding: [0x7a,0x00,0x20,0xe1] bkpt #10 -@ CHECK: mrs r8, cpsr @ encoding: [0x00,0x80,0x0f,0xe1] - mrs r8, cpsr - -@ CHECK: mrc p14, #0, r1, c1, c2, #4 @ encoding: [0x92,0x1e,0x11,0xee] - mrc p14, #0, r1, c1, c2, #4 -@ CHECK: mrrc p7, #1, r5, r4, c1 @ encoding: [0x11,0x57,0x54,0xec] - mrrc p7, #1, r5, r4, c1 - -@ CHECK: mrc2 p14, #0, r1, c1, c2, #4 @ encoding: [0x92,0x1e,0x11,0xfe] - mrc2 p14, #0, r1, c1, c2, #4 -@ CHECK: mrrc2 p7, #1, r5, r4, c1 @ encoding: [0x11,0x57,0x54,0xfc] - mrrc2 p7, #1, r5, r4, c1 - @ CHECK: cdp p7, #1, c1, c1, c1, #4 @ encoding: [0x81,0x17,0x11,0xee] cdp p7, #1, c1, c1, c1, #4 @ CHECK: cdp2 p7, #1, c1, c1, c1, #4 @ encoding: [0x81,0x17,0x11,0xfe] cdp2 p7, #1, c1, c1, c1, #4 -@ CHECK: qadd r1, r2, r3 @ encoding: [0x52,0x10,0x03,0xe1] - qadd r1, r2, r3 - -@ CHECK: qsub r1, r2, r3 @ encoding: [0x52,0x10,0x23,0xe1] - qsub r1, r2, r3 - -@ CHECK: qdadd r1, r2, r3 @ encoding: [0x52,0x10,0x43,0xe1] - qdadd r1, r2, r3 - -@ CHECK: qdsub r1, r2, r3 @ encoding: [0x52,0x10,0x63,0xe1] - qdsub r1, r2, r3 - -@ CHECK: wfe @ encoding: [0x02,0xf0,0x20,0xe3] - wfe - -@ CHECK: wfi @ encoding: [0x03,0xf0,0x20,0xe3] - wfi - -@ CHECK: yield @ encoding: [0x01,0xf0,0x20,0xe3] - yield - -@ CHECK: nop @ encoding: [0x00,0xf0,0x20,0xe3] - nop - -@ CHECK: cpsie aif @ encoding: [0xc0,0x01,0x08,0xf1] - cpsie aif - -@ CHECK: cps #15 @ encoding: [0x0f,0x00,0x02,0xf1] - cps #15 - -@ CHECK: cpsie if, #10 @ encoding: [0xca,0x00,0x0a,0xf1] - cpsie if, #10 - -@ CHECK: msr cpsr_fc, r0 @ encoding: [0x00,0xf0,0x29,0xe1] - msr apsr, r0 - -@ CHECK: msr cpsr_s, r0 @ encoding: [0x00,0xf0,0x24,0xe1] - msr apsr_g, r0 - -@ CHECK: msr cpsr_f, r0 @ encoding: [0x00,0xf0,0x28,0xe1] - msr apsr_nzcvq, r0 - -@ CHECK: msr cpsr_fs, r0 @ encoding: [0x00,0xf0,0x2c,0xe1] - msr apsr_nzcvqg, r0 - -@ CHECK: msr cpsr_fc, r0 @ encoding: [0x00,0xf0,0x29,0xe1] - msr cpsr_fc, r0 - -@ CHECK: msr cpsr_c, r0 @ encoding: [0x00,0xf0,0x21,0xe1] - msr cpsr_c, r0 - -@ CHECK: msr cpsr_x, r0 @ encoding: [0x00,0xf0,0x22,0xe1] - msr cpsr_x, r0 - -@ CHECK: msr cpsr_fc, r0 @ encoding: [0x00,0xf0,0x29,0xe1] - msr cpsr_fc, r0 - -@ CHECK: msr cpsr_fc, r0 @ encoding: [0x00,0xf0,0x29,0xe1] - msr cpsr_all, r0 - -@ CHECK: msr cpsr_fsx, r0 @ encoding: [0x00,0xf0,0x2e,0xe1] - msr cpsr_fsx, r0 - -@ CHECK: msr spsr_fc, r0 @ encoding: [0x00,0xf0,0x69,0xe1] - msr spsr_fc, r0 - -@ CHECK: msr spsr_fsxc, r0 @ encoding: [0x00,0xf0,0x6f,0xe1] - msr spsr_fsxc, r0 - -@ CHECK: msr cpsr_fsxc, r0 @ encoding: [0x00,0xf0,0x2f,0xe1] - msr cpsr_fsxc, r0 - @ CHECK: add r1, r2, r3, lsl r4 @ encoding: [0x13,0x14,0x82,0xe0] add r1, r2, r3, lsl r4 -@ CHECK: strexb r0, r1, [r2] @ encoding: [0x91,0x0f,0xc2,0xe1] - strexb r0, r1, [r2] - -@ CHECK: strexh r0, r1, [r2] @ encoding: [0x91,0x0f,0xe2,0xe1] - strexh r0, r1, [r2] - -@ CHECK: strex r0, r1, [r2] @ encoding: [0x91,0x0f,0x82,0xe1] - strex r0, r1, [r2] - -@ CHECK: strexd r0, r2, r3, [r1] @ encoding: [0x92,0x0f,0xa1,0xe1] - strexd r0, r2, r3, [r1] - -@ CHECK: ldrexb r0, [r0] @ encoding: [0x9f,0x0f,0xd0,0xe1] - ldrexb r0, [r0] - -@ CHECK: ldrexh r0, [r0] @ encoding: [0x9f,0x0f,0xf0,0xe1] - ldrexh r0, [r0] - -@ CHECK: ldrex r0, [r0] @ encoding: [0x9f,0x0f,0x90,0xe1] - ldrex r0, [r0] - -@ CHECK: ldrexd r0, r1, [r0] @ encoding: [0x9f,0x0f,0xb0,0xe1] - ldrexd r0, r1, [r0] - @ CHECK: ssat16 r0, #7, r0 @ encoding: [0x30,0x0f,0xa6,0xe6] ssat16 r0, #7, r0 +@ CHECK: cpsie none, #0 @ encoding: [0x00,0x00,0x0a,0xf1] + cpsie none, #0 + diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index 0b728bc2c1be..55d9f0261950 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -14,18 +14,18 @@ _func: @------------------------------------------------------------------------------ @ ADC (immediate) @------------------------------------------------------------------------------ - adc r1, r2, #0xf - adc r1, r2, #0xf0 - adc r1, r2, #0xf00 - adc r1, r2, #0xf000 - adc r1, r2, #0xf0000 - adc r1, r2, #0xf00000 - adc r1, r2, #0xf000000 - adc r1, r2, #0xf0000000 - adc r1, r2, #0xf000000f - adcs r1, r2, #0xf00 - adcseq r1, r2, #0xf00 - adceq r1, r2, #0xf00 + adc r1, r2, #0xf + adc r1, r2, #0xf0 + adc r1, r2, #0xf00 + adc r1, r2, #0xf000 + adc r1, r2, #0xf0000 + adc r1, r2, #0xf00000 + adc r1, r2, #0xf000000 + adc r1, r2, #0xf0000000 + adc r1, r2, #0xf000000f + adcs r1, r2, #0xf00 + adcseq r1, r2, #0xf00 + adceq r1, r2, #0xf00 @ CHECK: adc r1, r2, #15 @ encoding: [0x0f,0x10,0xa2,0xe2] @ CHECK: adc r1, r2, #240 @ encoding: [0xf0,0x10,0xa2,0xe2] @@ -45,44 +45,44 @@ _func: @ ADC (register) @ ADC (shifted register) @------------------------------------------------------------------------------ - adc r4, r5, r6 - @ Constant shifts - adc r4, r5, r6, lsl #1 - adc r4, r5, r6, lsl #31 - adc r4, r5, r6, lsr #1 - adc r4, r5, r6, lsr #31 - adc r4, r5, r6, lsr #32 - adc r4, r5, r6, asr #1 - adc r4, r5, r6, asr #31 - adc r4, r5, r6, asr #32 - adc r4, r5, r6, ror #1 - adc r4, r5, r6, ror #31 + adc r4, r5, r6 + @ Constant shifts + adc r4, r5, r6, lsl #1 + adc r4, r5, r6, lsl #31 + adc r4, r5, r6, lsr #1 + adc r4, r5, r6, lsr #31 + adc r4, r5, r6, lsr #32 + adc r4, r5, r6, asr #1 + adc r4, r5, r6, asr #31 + adc r4, r5, r6, asr #32 + adc r4, r5, r6, ror #1 + adc r4, r5, r6, ror #31 - @ Register shifts - adc r6, r7, r8, lsl r9 - adc r6, r7, r8, lsr r9 - adc r6, r7, r8, asr r9 - adc r6, r7, r8, ror r9 - adc r4, r5, r6, rrx + @ Register shifts + adc r6, r7, r8, lsl r9 + adc r6, r7, r8, lsr r9 + adc r6, r7, r8, asr r9 + adc r6, r7, r8, ror r9 + adc r4, r5, r6, rrx - @ Destination register is optional - adc r5, r6 - adc r4, r5, lsl #1 - adc r4, r5, lsl #31 - adc r4, r5, lsr #1 - adc r4, r5, lsr #31 - adc r4, r5, lsr #32 - adc r4, r5, asr #1 - adc r4, r5, asr #31 - adc r4, r5, asr #32 - adc r4, r5, ror #1 - adc r4, r5, ror #31 - adc r4, r5, rrx - adc r6, r7, lsl r9 - adc r6, r7, lsr r9 - adc r6, r7, asr r9 - adc r6, r7, ror r9 - adc r4, r5, rrx + @ Destination register is optional + adc r5, r6 + adc r4, r5, lsl #1 + adc r4, r5, lsl #31 + adc r4, r5, lsr #1 + adc r4, r5, lsr #31 + adc r4, r5, lsr #32 + adc r4, r5, asr #1 + adc r4, r5, asr #31 + adc r4, r5, asr #32 + adc r4, r5, ror #1 + adc r4, r5, ror #31 + adc r4, r5, rrx + adc r6, r7, lsl r9 + adc r6, r7, lsr r9 + adc r6, r7, asr r9 + adc r6, r7, ror r9 + adc r4, r5, rrx @ CHECK: adc r4, r5, r6 @ encoding: [0x06,0x40,0xa5,0xe0] @@ -123,38 +123,54 @@ _func: @------------------------------------------------------------------------------ -@ FIXME: ADR +@ ADR @------------------------------------------------------------------------------ +Lback: + adr r2, Lback + adr r3, Lforward +Lforward: + adr r2, #3 + adr r2, #-3 + +@ CHECK: Lback: +@ CHECK: adr r2, Lback @ encoding: [0bAAAAAAA0,0x20'A',0x0f'A',0b1110001A] +@ CHECK: @ fixup A - offset: 0, value: Lback, kind: fixup_arm_adr_pcrel_12 +@ CHECK: adr r3, Lforward @ encoding: [0bAAAAAAA0,0x30'A',0x0f'A',0b1110001A] +@ CHECK: @ fixup A - offset: 0, value: Lforward, kind: fixup_arm_adr_pcrel_12 +@ CHECK: Lforward: +@ CHECK: adr r2, #3 @ encoding: [0x03,0x20,0x8f,0xe2] +@ CHECK: adr r2, #-3 @ encoding: [0x03,0x20,0x4f,0xe2] + @------------------------------------------------------------------------------ @ ADD @------------------------------------------------------------------------------ - add r4, r5, #0xf000 - add r4, r5, r6 - add r4, r5, r6, lsl #5 - add r4, r5, r6, lsr #5 - add r4, r5, r6, lsr #5 - add r4, r5, r6, asr #5 - add r4, r5, r6, ror #5 - add r6, r7, r8, lsl r9 - add r6, r7, r8, lsr r9 - add r6, r7, r8, asr r9 - add r6, r7, r8, ror r9 - add r4, r5, r6, rrx + add r4, r5, #0xf000 + add r4, r5, r6 + add r4, r5, r6, lsl #5 + add r4, r5, r6, lsr #5 + add r4, r5, r6, lsr #5 + add r4, r5, r6, asr #5 + add r4, r5, r6, ror #5 + add r6, r7, r8, lsl r9 + add r6, r7, r8, lsr r9 + add r6, r7, r8, asr r9 + add r6, r7, r8, ror r9 + add r4, r5, r6, rrx - @ destination register is optional - add r5, #0xf000 - add r4, r5 - add r4, r5, lsl #5 - add r4, r5, lsr #5 - add r4, r5, lsr #5 - add r4, r5, asr #5 - add r4, r5, ror #5 - add r6, r7, lsl r9 - add r6, r7, lsr r9 - add r6, r7, asr r9 - add r6, r7, ror r9 - add r4, r5, rrx + @ destination register is optional + add r5, #0xf000 + add r4, r5 + add r4, r5, lsl #5 + add r4, r5, lsr #5 + add r4, r5, lsr #5 + add r4, r5, asr #5 + add r4, r5, ror #5 + add r6, r7, lsl r9 + add r6, r7, lsr r9 + add r6, r7, asr r9 + add r6, r7, ror r9 + add r4, r5, rrx @ CHECK: add r4, r5, #61440 @ encoding: [0x0f,0x4a,0x85,0xe2] @ CHECK: add r4, r5, r6 @ encoding: [0x06,0x40,0x85,0xe0] @@ -187,32 +203,32 @@ _func: @------------------------------------------------------------------------------ @ AND @------------------------------------------------------------------------------ - and r10, r1, #0xf - and r10, r1, r6 - and r10, r1, r6, lsl #10 - and r10, r1, r6, lsr #10 - and r10, r1, r6, lsr #10 - and r10, r1, r6, asr #10 - and r10, r1, r6, ror #10 - and r6, r7, r8, lsl r2 - and r6, r7, r8, lsr r2 - and r6, r7, r8, asr r2 - and r6, r7, r8, ror r2 - and r10, r1, r6, rrx + and r10, r1, #0xf + and r10, r1, r6 + and r10, r1, r6, lsl #10 + and r10, r1, r6, lsr #10 + and r10, r1, r6, lsr #10 + and r10, r1, r6, asr #10 + and r10, r1, r6, ror #10 + and r6, r7, r8, lsl r2 + and r6, r7, r8, lsr r2 + and r6, r7, r8, asr r2 + and r6, r7, r8, ror r2 + and r10, r1, r6, rrx - @ destination register is optional - and r1, #0xf - and r10, r1 - and r10, r1, lsl #10 - and r10, r1, lsr #10 - and r10, r1, lsr #10 - and r10, r1, asr #10 - and r10, r1, ror #10 - and r6, r7, lsl r2 - and r6, r7, lsr r2 - and r6, r7, asr r2 - and r6, r7, ror r2 - and r10, r1, rrx + @ destination register is optional + and r1, #0xf + and r10, r1 + and r10, r1, lsl #10 + and r10, r1, lsr #10 + and r10, r1, lsr #10 + and r10, r1, asr #10 + and r10, r1, ror #10 + and r6, r7, lsl r2 + and r6, r7, lsr r2 + and r6, r7, asr r2 + and r6, r7, ror r2 + and r10, r1, rrx @ CHECK: and r10, r1, #15 @ encoding: [0x0f,0xa0,0x01,0xe2] @ CHECK: and r10, r1, r6 @ encoding: [0x06,0xa0,0x01,0xe0] @@ -244,44 +260,66 @@ _func: @ FIXME: ASR @------------------------------------------------------------------------------ @------------------------------------------------------------------------------ -@ FIXME: B +@ B @------------------------------------------------------------------------------ + b _bar + beq _baz + +@ CHECK: b _bar @ encoding: [A,A,A,0xea] + @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbranch +@ CHECK: beq _baz @ encoding: [A,A,A,0x0a] + @ fixup A - offset: 0, value: _baz, kind: fixup_arm_condbranch + + @------------------------------------------------------------------------------ -@ FIXME: BFC +@ BFC @------------------------------------------------------------------------------ + bfc r5, #3, #17 + bfccc r5, #3, #17 + +@ CHECK: bfc r5, #3, #17 @ encoding: [0x9f,0x51,0xd3,0xe7] +@ CHECK: bfclo r5, #3, #17 @ encoding: [0x9f,0x51,0xd3,0x37] + + @------------------------------------------------------------------------------ -@ FIXME: BFI +@ BFI @------------------------------------------------------------------------------ + bfi r5, r2, #3, #17 + bfine r5, r2, #3, #17 + +@ CHECK: bfi r5, r2, #3, #17 @ encoding: [0x92,0x51,0xd3,0xe7] +@ CHECK: bfine r5, r2, #3, #17 @ encoding: [0x92,0x51,0xd3,0x17] + @------------------------------------------------------------------------------ @ BIC @------------------------------------------------------------------------------ - bic r10, r1, #0xf - bic r10, r1, r6 - bic r10, r1, r6, lsl #10 - bic r10, r1, r6, lsr #10 - bic r10, r1, r6, lsr #10 - bic r10, r1, r6, asr #10 - bic r10, r1, r6, ror #10 - bic r6, r7, r8, lsl r2 - bic r6, r7, r8, lsr r2 - bic r6, r7, r8, asr r2 - bic r6, r7, r8, ror r2 - bic r10, r1, r6, rrx + bic r10, r1, #0xf + bic r10, r1, r6 + bic r10, r1, r6, lsl #10 + bic r10, r1, r6, lsr #10 + bic r10, r1, r6, lsr #10 + bic r10, r1, r6, asr #10 + bic r10, r1, r6, ror #10 + bic r6, r7, r8, lsl r2 + bic r6, r7, r8, lsr r2 + bic r6, r7, r8, asr r2 + bic r6, r7, r8, ror r2 + bic r10, r1, r6, rrx - @ destination register is optional - bic r1, #0xf - bic r10, r1 - bic r10, r1, lsl #10 - bic r10, r1, lsr #10 - bic r10, r1, lsr #10 - bic r10, r1, asr #10 - bic r10, r1, ror #10 - bic r6, r7, lsl r2 - bic r6, r7, lsr r2 - bic r6, r7, asr r2 - bic r6, r7, ror r2 - bic r10, r1, rrx + @ destination register is optional + bic r1, #0xf + bic r10, r1 + bic r10, r1, lsl #10 + bic r10, r1, lsr #10 + bic r10, r1, lsr #10 + bic r10, r1, asr #10 + bic r10, r1, ror #10 + bic r6, r7, lsl r2 + bic r6, r7, lsr r2 + bic r6, r7, asr r2 + bic r6, r7, ror r2 + bic r10, r1, rrx @ CHECK: bic r10, r1, #15 @ encoding: [0x0f,0xa0,0xc1,0xe3] @ CHECK: bic r10, r1, r6 @ encoding: [0x06,0xa0,0xc1,0xe1] @@ -313,8 +351,8 @@ _func: @------------------------------------------------------------------------------ @ BKPT @------------------------------------------------------------------------------ - bkpt #10 - bkpt #65535 + bkpt #10 + bkpt #65535 @ CHECK: bkpt #10 @ encoding: [0x7a,0x00,0x20,0xe1] @ CHECK: bkpt #65535 @ encoding: [0x7f,0xff,0x2f,0xe1] @@ -323,17 +361,24 @@ _func: @ BL/BLX (immediate) @------------------------------------------------------------------------------ - bl _bar - @ FIXME: blx _bar + bl _bar + blx _bar + blls #28634268 + blx #32424576 + blx #16212288 @ CHECK: bl _bar @ encoding: [A,A,A,0xeb] @ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbranch - +@ CHECK: blx _bar @ encoding: [A,A,A,0xfa] + @ fixup A - offset: 0, value: _bar, kind: fixup_arm_uncondbranch +@ CHECK: blls #28634268 @ encoding: [0x27,0x3b,0x6d,0x9b] +@ CHECK: blx #32424576 @ encoding: [0xa0,0xb0,0x7b,0xfa] +@ CHECK: blx #16212288 @ encoding: [0x50,0xd8,0x3d,0xfa] @------------------------------------------------------------------------------ @ BLX (register) @------------------------------------------------------------------------------ - blx r2 - blxne r2 + blx r2 + blxne r2 @ CHECK: blx r2 @ encoding: [0x32,0xff,0x2f,0xe1] @ CHECK: blxne r2 @ encoding: [0x32,0xff,0x2f,0x11] @@ -341,9 +386,8 @@ _func: @------------------------------------------------------------------------------ @ BX @------------------------------------------------------------------------------ - - bx r2 - bxne r2 + bx r2 + bxne r2 @ CHECK: bx r2 @ encoding: [0x12,0xff,0x2f,0xe1] @ CHECK: bxne r2 @ encoding: [0x12,0xff,0x2f,0x11] @@ -351,23 +395,18 @@ _func: @------------------------------------------------------------------------------ @ BXJ @------------------------------------------------------------------------------ - - bxj r2 - bxjne r2 + bxj r2 + bxjne r2 @ CHECK: bxj r2 @ encoding: [0x22,0xff,0x2f,0xe1] @ CHECK: bxjne r2 @ encoding: [0x22,0xff,0x2f,0x11] -@------------------------------------------------------------------------------ -@ FIXME: CBNZ/CBZ -@------------------------------------------------------------------------------ - @------------------------------------------------------------------------------ @ CDP/CDP2 @------------------------------------------------------------------------------ - cdp p7, #1, c1, c1, c1, #4 - cdp2 p7, #1, c1, c1, c1, #4 + cdp p7, #1, c1, c1, c1, #4 + cdp2 p7, #1, c1, c1, c1, #4 @ CHECK: cdp p7, #1, c1, c1, c1, #4 @ encoding: [0x81,0x17,0x11,0xee] @ CHECK: cdp2 p7, #1, c1, c1, c1, #4 @ encoding: [0x81,0x17,0x11,0xfe] @@ -376,7 +415,7 @@ _func: @------------------------------------------------------------------------------ @ CLREX @------------------------------------------------------------------------------ - clrex + clrex @ CHECK: clrex @ encoding: [0x1f,0xf0,0x7f,0xf5] @@ -384,8 +423,8 @@ _func: @------------------------------------------------------------------------------ @ CLZ @------------------------------------------------------------------------------ - clz r1, r2 - clzeq r1, r2 + clz r1, r2 + clzeq r1, r2 @ CHECK: clz r1, r2 @ encoding: [0x12,0x1f,0x6f,0xe1] @ CHECK: clzeq r1, r2 @ encoding: [0x12,0x1f,0x6f,0x01] @@ -393,18 +432,18 @@ _func: @------------------------------------------------------------------------------ @ CMN @------------------------------------------------------------------------------ - cmn r1, #0xf - cmn r1, r6 - cmn r1, r6, lsl #10 - cmn r1, r6, lsr #10 - cmn sp, r6, lsr #10 - cmn r1, r6, asr #10 - cmn r1, r6, ror #10 - cmn r7, r8, lsl r2 - cmn sp, r8, lsr r2 - cmn r7, r8, asr r2 - cmn r7, r8, ror r2 - cmn r1, r6, rrx + cmn r1, #0xf + cmn r1, r6 + cmn r1, r6, lsl #10 + cmn r1, r6, lsr #10 + cmn sp, r6, lsr #10 + cmn r1, r6, asr #10 + cmn r1, r6, ror #10 + cmn r7, r8, lsl r2 + cmn sp, r8, lsr r2 + cmn r7, r8, asr r2 + cmn r7, r8, ror r2 + cmn r1, r6, rrx @ CHECK: cmn r1, #15 @ encoding: [0x0f,0x00,0x71,0xe3] @ CHECK: cmn r1, r6 @ encoding: [0x06,0x00,0x71,0xe1] @@ -422,18 +461,18 @@ _func: @------------------------------------------------------------------------------ @ CMP @------------------------------------------------------------------------------ - cmp r1, #0xf - cmp r1, r6 - cmp r1, r6, lsl #10 - cmp r1, r6, lsr #10 - cmp sp, r6, lsr #10 - cmp r1, r6, asr #10 - cmp r1, r6, ror #10 - cmp r7, r8, lsl r2 - cmp sp, r8, lsr r2 - cmp r7, r8, asr r2 - cmp r7, r8, ror r2 - cmp r1, r6, rrx + cmp r1, #0xf + cmp r1, r6 + cmp r1, r6, lsl #10 + cmp r1, r6, lsr #10 + cmp sp, r6, lsr #10 + cmp r1, r6, asr #10 + cmp r1, r6, ror #10 + cmp r7, r8, lsl r2 + cmp sp, r8, lsr r2 + cmp r7, r8, asr r2 + cmp r7, r8, ror r2 + cmp r1, r6, rrx @ CHECK: cmp r1, #15 @ encoding: [0x0f,0x00,0x51,0xe3] @ CHECK: cmp r1, r6 @ encoding: [0x06,0x00,0x51,0xe1] @@ -448,12 +487,25 @@ _func: @ CHECK: cmp r7, r8, ror r2 @ encoding: [0x78,0x02,0x57,0xe1] @ CHECK: cmp r1, r6, rrx @ encoding: [0x66,0x00,0x51,0xe1] + +@------------------------------------------------------------------------------ +@ CPS +@------------------------------------------------------------------------------ + cpsie aif + cps #15 + cpsid if, #10 + +@ CHECK: cpsie aif @ encoding: [0xc0,0x01,0x08,0xf1] +@ CHECK: cps #15 @ encoding: [0x0f,0x00,0x02,0xf1] +@ CHECK: cpsid if, #10 @ encoding: [0xca,0x00,0x0e,0xf1] + + @------------------------------------------------------------------------------ @ DBG @------------------------------------------------------------------------------ - dbg #0 - dbg #5 - dbg #15 + dbg #0 + dbg #5 + dbg #15 @ CHECK: dbg #0 @ encoding: [0xf0,0xf0,0x20,0xe3] @ CHECK: dbg #5 @ encoding: [0xf5,0xf0,0x20,0xe3] @@ -463,19 +515,19 @@ _func: @------------------------------------------------------------------------------ @ DMB @------------------------------------------------------------------------------ - dmb sy - dmb st - dmb sh - dmb ish - dmb shst - dmb ishst - dmb un - dmb nsh - dmb unst - dmb nshst - dmb osh - dmb oshst - dmb + dmb sy + dmb st + dmb sh + dmb ish + dmb shst + dmb ishst + dmb un + dmb nsh + dmb unst + dmb nshst + dmb osh + dmb oshst + dmb @ CHECK: dmb sy @ encoding: [0x5f,0xf0,0x7f,0xf5] @ CHECK: dmb st @ encoding: [0x5e,0xf0,0x7f,0xf5] @@ -494,19 +546,19 @@ _func: @------------------------------------------------------------------------------ @ DSB @------------------------------------------------------------------------------ - dsb sy - dsb st - dsb sh - dsb ish - dsb shst - dsb ishst - dsb un - dsb nsh - dsb unst - dsb nshst - dsb osh - dsb oshst - dsb + dsb sy + dsb st + dsb sh + dsb ish + dsb shst + dsb ishst + dsb un + dsb nsh + dsb unst + dsb nshst + dsb osh + dsb oshst + dsb @ CHECK: dsb sy @ encoding: [0x4f,0xf0,0x7f,0xf5] @ CHECK: dsb st @ encoding: [0x4e,0xf0,0x7f,0xf5] @@ -525,32 +577,32 @@ _func: @------------------------------------------------------------------------------ @ EOR @------------------------------------------------------------------------------ - eor r4, r5, #0xf000 - eor r4, r5, r6 - eor r4, r5, r6, lsl #5 - eor r4, r5, r6, lsr #5 - eor r4, r5, r6, lsr #5 - eor r4, r5, r6, asr #5 - eor r4, r5, r6, ror #5 - eor r6, r7, r8, lsl r9 - eor r6, r7, r8, lsr r9 - eor r6, r7, r8, asr r9 - eor r6, r7, r8, ror r9 - eor r4, r5, r6, rrx + eor r4, r5, #0xf000 + eor r4, r5, r6 + eor r4, r5, r6, lsl #5 + eor r4, r5, r6, lsr #5 + eor r4, r5, r6, lsr #5 + eor r4, r5, r6, asr #5 + eor r4, r5, r6, ror #5 + eor r6, r7, r8, lsl r9 + eor r6, r7, r8, lsr r9 + eor r6, r7, r8, asr r9 + eor r6, r7, r8, ror r9 + eor r4, r5, r6, rrx - @ destination register is optional - eor r5, #0xf000 - eor r4, r5 - eor r4, r5, lsl #5 - eor r4, r5, lsr #5 - eor r4, r5, lsr #5 - eor r4, r5, asr #5 - eor r4, r5, ror #5 - eor r6, r7, lsl r9 - eor r6, r7, lsr r9 - eor r6, r7, asr r9 - eor r6, r7, ror r9 - eor r4, r5, rrx + @ destination register is optional + eor r5, #0xf000 + eor r4, r5 + eor r4, r5, lsl #5 + eor r4, r5, lsr #5 + eor r4, r5, lsr #5 + eor r4, r5, asr #5 + eor r4, r5, ror #5 + eor r6, r7, lsl r9 + eor r6, r7, lsr r9 + eor r6, r7, asr r9 + eor r6, r7, ror r9 + eor r4, r5, rrx @ CHECK: eor r4, r5, #61440 @ encoding: [0x0f,0x4a,0x25,0xe2] @ CHECK: eor r4, r5, r6 @ encoding: [0x06,0x40,0x25,0xe0] @@ -590,6 +642,91 @@ _func: @ CHECK: isb sy @ encoding: [0x6f,0xf0,0x7f,0xf5] +@------------------------------------------------------------------------------ +@ LDC{L}/LDC2{L} +@------------------------------------------------------------------------------ + ldc2 p0, c8, [r1, #4] + ldc2 p1, c7, [r2] + ldc2 p2, c6, [r3, #-224] + ldc2 p3, c5, [r4, #-120]! + ldc2 p4, c4, [r5], #16 + ldc2 p5, c3, [r6], #-72 + ldc2l p6, c2, [r7, #4] + ldc2l p7, c1, [r8] + ldc2l p8, c0, [r9, #-224] + ldc2l p9, c1, [r10, #-120]! + ldc2l p10, c2, [r11], #16 + ldc2l p11, c3, [r12], #-72 + + ldc p12, c4, [r0, #4] + ldc p13, c5, [r1] + ldc p14, c6, [r2, #-224] + ldc p15, c7, [r3, #-120]! + ldc p5, c8, [r4], #16 + ldc p4, c9, [r5], #-72 + ldcl p3, c10, [r6, #4] + ldcl p2, c11, [r7] + ldcl p1, c12, [r8, #-224] + ldcl p0, c13, [r9, #-120]! + ldcl p6, c14, [r10], #16 + ldcl p7, c15, [r11], #-72 + + ldclo p12, c4, [r0, #4] + ldchi p13, c5, [r1] + ldccs p14, c6, [r2, #-224] + ldccc p15, c7, [r3, #-120]! + ldceq p5, c8, [r4], #16 + ldcgt p4, c9, [r5], #-72 + ldcllt p3, c10, [r6, #4] + ldclge p2, c11, [r7] + ldclle p1, c12, [r8, #-224] + ldclne p0, c13, [r9, #-120]! + ldcleq p6, c14, [r10], #16 + ldclhi p7, c15, [r11], #-72 + + ldc2 p2, c8, [r1], { 25 } + +@ CHECK: ldc2 p0, c8, [r1, #4] @ encoding: [0x01,0x80,0x91,0xfd] +@ CHECK: ldc2 p1, c7, [r2] @ encoding: [0x00,0x71,0x92,0xfd] +@ CHECK: ldc2 p2, c6, [r3, #-224] @ encoding: [0x38,0x62,0x13,0xfd] +@ CHECK: ldc2 p3, c5, [r4, #-120]! @ encoding: [0x1e,0x53,0x34,0xfd] +@ CHECK: ldc2 p4, c4, [r5], #16 @ encoding: [0x04,0x44,0xb5,0xfc] +@ CHECK: ldc2 p5, c3, [r6], #-72 @ encoding: [0x12,0x35,0x36,0xfc] +@ CHECK: ldc2l p6, c2, [r7, #4] @ encoding: [0x01,0x26,0xd7,0xfd] +@ CHECK: ldc2l p7, c1, [r8] @ encoding: [0x00,0x17,0xd8,0xfd] +@ CHECK: ldc2l p8, c0, [r9, #-224] @ encoding: [0x38,0x08,0x59,0xfd] +@ CHECK: ldc2l p9, c1, [r10, #-120]! @ encoding: [0x1e,0x19,0x7a,0xfd] +@ CHECK: ldc2l p10, c2, [r11], #16 @ encoding: [0x04,0x2a,0xfb,0xfc] +@ CHECK: ldc2l p11, c3, [r12], #-72 @ encoding: [0x12,0x3b,0x7c,0xfc] + +@ CHECK: ldc p12, c4, [r0, #4] @ encoding: [0x01,0x4c,0x90,0xed] +@ CHECK: ldc p13, c5, [r1] @ encoding: [0x00,0x5d,0x91,0xed] +@ CHECK: ldc p14, c6, [r2, #-224] @ encoding: [0x38,0x6e,0x12,0xed] +@ CHECK: ldc p15, c7, [r3, #-120]! @ encoding: [0x1e,0x7f,0x33,0xed] +@ CHECK: ldc p5, c8, [r4], #16 @ encoding: [0x04,0x85,0xb4,0xec] +@ CHECK: ldc p4, c9, [r5], #-72 @ encoding: [0x12,0x94,0x35,0xec] +@ CHECK: ldcl p3, c10, [r6, #4] @ encoding: [0x01,0xa3,0xd6,0xed] +@ CHECK: ldcl p2, c11, [r7] @ encoding: [0x00,0xb2,0xd7,0xed] +@ CHECK: ldcl p1, c12, [r8, #-224] @ encoding: [0x38,0xc1,0x58,0xed] +@ CHECK: ldcl p0, c13, [r9, #-120]! @ encoding: [0x1e,0xd0,0x79,0xed] +@ CHECK: ldcl p6, c14, [r10], #16 @ encoding: [0x04,0xe6,0xfa,0xec] +@ CHECK: ldcl p7, c15, [r11], #-72 @ encoding: [0x12,0xf7,0x7b,0xec] + +@ CHECK: ldclo p12, c4, [r0, #4] @ encoding: [0x01,0x4c,0x90,0x3d] +@ CHECK: ldchi p13, c5, [r1] @ encoding: [0x00,0x5d,0x91,0x8d] +@ CHECK: ldchs p14, c6, [r2, #-224] @ encoding: [0x38,0x6e,0x12,0x2d] +@ CHECK: ldclo p15, c7, [r3, #-120]! @ encoding: [0x1e,0x7f,0x33,0x3d] +@ CHECK: ldceq p5, c8, [r4], #16 @ encoding: [0x04,0x85,0xb4,0x0c] +@ CHECK: ldcgt p4, c9, [r5], #-72 @ encoding: [0x12,0x94,0x35,0xcc] +@ CHECK: ldcllt p3, c10, [r6, #4] @ encoding: [0x01,0xa3,0xd6,0xbd] +@ CHECK: ldclge p2, c11, [r7] @ encoding: [0x00,0xb2,0xd7,0xad] +@ CHECK: ldclle p1, c12, [r8, #-224] @ encoding: [0x38,0xc1,0x58,0xdd] +@ CHECK: ldclne p0, c13, [r9, #-120]! @ encoding: [0x1e,0xd0,0x79,0x1d] +@ CHECK: ldcleq p6, c14, [r10], #16 @ encoding: [0x04,0xe6,0xfa,0x0c] +@ CHECK: ldclhi p7, c15, [r11], #-72 @ encoding: [0x12,0xf7,0x7b,0x8c] + +@ CHECK: ldc2 p2, c8, [r1], {25} @ encoding: [0x19,0x82,0x91,0xfc] + @------------------------------------------------------------------------------ @ LDM* @@ -619,9 +756,29 @@ _func: @ CHECK: ldmda r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x32,0xe8] @ CHECK: ldmdb r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x32,0xe9] + @------------------------------------------------------------------------------ -@ FIXME: LDR* +@ LDREX/LDREXB/LDREXH/LDREXD @------------------------------------------------------------------------------ + ldrexb r3, [r4] + ldrexh r2, [r5] + ldrex r1, [r7] + ldrexd r6, r7, [r8] + +@ CHECK: ldrexb r3, [r4] @ encoding: [0x9f,0x3f,0xd4,0xe1] +@ CHECK: ldrexh r2, [r5] @ encoding: [0x9f,0x2f,0xf5,0xe1] +@ CHECK: ldrex r1, [r7] @ encoding: [0x9f,0x1f,0x97,0xe1] +@ CHECK: ldrexd r6, r7, [r8] @ encoding: [0x9f,0x6f,0xb8,0xe1] + +@------------------------------------------------------------------------------ +@ LDRHT +@------------------------------------------------------------------------------ + ldrhthi r8, [r11], #-0 + ldrhthi r8, [r11], #0 + +@ CHECK: ldrhthi r8, [r11], #-0 @ encoding: [0xb0,0x80,0x7b,0x80] +@ CHECK: ldrhthi r8, [r11], #0 @ encoding: [0xb0,0x80,0xfb,0x80] + @------------------------------------------------------------------------------ @ FIXME: LSL @------------------------------------------------------------------------------ @@ -635,8 +792,8 @@ _func: mcr p7, #1, r5, c1, c1, #4 mcr2 p7, #1, r5, c1, c1, #4 -@ CHECK: mcr p7, #1, r5, c1, c1, #4 @ encoding: [0x91,0x57,0x21,0xee] -@ CHECK: mcr2 p7, #1, r5, c1, c1, #4 @ encoding: [0x91,0x57,0x21,0xfe] +@ CHECK: mcr p7, #1, r5, c1, c1, #4 @ encoding: [0x91,0x57,0x21,0xee] +@ CHECK: mcr2 p7, #1, r5, c1, c1, #4 @ encoding: [0x91,0x57,0x21,0xfe] @------------------------------------------------------------------------------ @ MCRR/MCRR2 @@ -644,8 +801,8 @@ _func: mcrr p7, #15, r5, r4, c1 mcrr2 p7, #15, r5, r4, c1 -@ CHECK: mcrr p7, #15, r5, r4, c1 @ encoding: [0xf1,0x57,0x44,0xec] -@ CHECK: mcrr2 p7, #15, r5, r4, c1 @ encoding: [0xf1,0x57,0x44,0xfc] +@ CHECK: mcrr p7, #15, r5, r4, c1 @ encoding: [0xf1,0x57,0x44,0xec] +@ CHECK: mcrr2 p7, #15, r5, r4, c1 @ encoding: [0xf1,0x57,0x44,0xfc] @------------------------------------------------------------------------------ @@ -656,10 +813,10 @@ _func: mlane r1,r2,r3,r4 mlasne r1,r2,r3,r4 -@ CHECK: mla r1, r2, r3, r4 @ encoding: [0x92,0x43,0x21,0xe0] -@ CHECK: mlas r1, r2, r3, r4 @ encoding: [0x92,0x43,0x31,0xe0] -@ CHECK: mlane r1, r2, r3, r4 @ encoding: [0x92,0x43,0x21,0x10] -@ CHECK: mlasne r1, r2, r3, r4 @ encoding: [0x92,0x43,0x31,0x10] +@ CHECK: mla r1, r2, r3, r4 @ encoding: [0x92,0x43,0x21,0xe0] +@ CHECK: mlas r1, r2, r3, r4 @ encoding: [0x92,0x43,0x31,0xe0] +@ CHECK: mlane r1, r2, r3, r4 @ encoding: [0x92,0x43,0x21,0x10] +@ CHECK: mlasne r1, r2, r3, r4 @ encoding: [0x92,0x43,0x31,0x10] @------------------------------------------------------------------------------ @ MLS @@ -670,29 +827,1800 @@ _func: @ CHECK: mls r2, r5, r6, r3 @ encoding: [0x95,0x36,0x62,0xe0] @ CHECK: mlsne r2, r5, r6, r3 @ encoding: [0x95,0x36,0x62,0x10] +@------------------------------------------------------------------------------ +@ MOV (immediate) +@------------------------------------------------------------------------------ + mov r3, #7 + mov r4, #0xff0 + mov r5, #0xff0000 + mov r6, #0xffff + movw r9, #0xffff + movs r3, #7 + moveq r4, #0xff0 + movseq r5, #0xff0000 + +@ CHECK: mov r3, #7 @ encoding: [0x07,0x30,0xa0,0xe3] +@ CHECK: mov r4, #4080 @ encoding: [0xff,0x4e,0xa0,0xe3] +@ CHECK: mov r5, #16711680 @ encoding: [0xff,0x58,0xa0,0xe3] +@ CHECK: movw r6, #65535 @ encoding: [0xff,0x6f,0x0f,0xe3] +@ CHECK: movw r9, #65535 @ encoding: [0xff,0x9f,0x0f,0xe3] +@ CHECK: movs r3, #7 @ encoding: [0x07,0x30,0xb0,0xe3] +@ CHECK: moveq r4, #4080 @ encoding: [0xff,0x4e,0xa0,0x03] +@ CHECK: movseq r5, #16711680 @ encoding: [0xff,0x58,0xb0,0x03] + +@------------------------------------------------------------------------------ +@ MOV (register) +@------------------------------------------------------------------------------ + mov r2, r3 + movs r2, r3 + moveq r2, r3 + movseq r2, r3 + +@ CHECK: mov r2, r3 @ encoding: [0x03,0x20,0xa0,0xe1] +@ CHECK: movs r2, r3 @ encoding: [0x03,0x20,0xb0,0xe1] +@ CHECK: moveq r2, r3 @ encoding: [0x03,0x20,0xa0,0x01] +@ CHECK: movseq r2, r3 @ encoding: [0x03,0x20,0xb0,0x01] + +@------------------------------------------------------------------------------ +@ MOVT +@------------------------------------------------------------------------------ + movt r3, #7 + movt r6, #0xffff + movteq r4, #0xff0 + +@ CHECK: movt r3, #7 @ encoding: [0x07,0x30,0x40,0xe3] +@ CHECK: movt r6, #65535 @ encoding: [0xff,0x6f,0x4f,0xe3] +@ CHECK: movteq r4, #4080 @ encoding: [0xf0,0x4f,0x40,0x03] + + +@------------------------------------------------------------------------------ +@ MRC/MRC2 +@------------------------------------------------------------------------------ + mrc p14, #0, r1, c1, c2, #4 + mrc2 p14, #0, r1, c1, c2, #4 + +@ CHECK: mrc p14, #0, r1, c1, c2, #4 @ encoding: [0x92,0x1e,0x11,0xee] +@ CHECK: mrc2 p14, #0, r1, c1, c2, #4 @ encoding: [0x92,0x1e,0x11,0xfe] + +@------------------------------------------------------------------------------ +@ MRRC/MRRC2 +@------------------------------------------------------------------------------ + mrrc p7, #1, r5, r4, c1 + mrrc2 p7, #1, r5, r4, c1 + +@ CHECK: mrrc p7, #1, r5, r4, c1 @ encoding: [0x11,0x57,0x54,0xec] +@ CHECK: mrrc2 p7, #1, r5, r4, c1 @ encoding: [0x11,0x57,0x54,0xfc] + + +@------------------------------------------------------------------------------ +@ MRS +@------------------------------------------------------------------------------ + mrs r8, apsr + mrs r8, cpsr + mrs r8, spsr +@ CHECK: mrs r8, apsr @ encoding: [0x00,0x80,0x0f,0xe1] +@ CHECK: mrs r8, apsr @ encoding: [0x00,0x80,0x0f,0xe1] +@ CHECK: mrs r8, spsr @ encoding: [0x00,0x80,0x4f,0xe1] + + + +@------------------------------------------------------------------------------ +@ MSR +@------------------------------------------------------------------------------ + + msr apsr, #5 + msr apsr_g, #5 + msr apsr_nzcvq, #5 + msr APSR_nzcvq, #5 + msr apsr_nzcvqg, #5 + msr cpsr_fc, #5 + msr cpsr_c, #5 + msr cpsr_x, #5 + msr cpsr_fc, #5 + msr cpsr_all, #5 + msr cpsr_fsx, #5 + msr spsr_fc, #5 + msr SPSR_fsxc, #5 + msr cpsr_fsxc, #5 + +@ CHECK: msr APSR_nzcvq, #5 @ encoding: [0x05,0xf0,0x28,0xe3] +@ CHECK: msr APSR_g, #5 @ encoding: [0x05,0xf0,0x24,0xe3] +@ CHECK: msr APSR_nzcvq, #5 @ encoding: [0x05,0xf0,0x28,0xe3] +@ CHECK: msr APSR_nzcvq, #5 @ encoding: [0x05,0xf0,0x28,0xe3] +@ CHECK: msr APSR_nzcvqg, #5 @ encoding: [0x05,0xf0,0x2c,0xe3] +@ CHECK: msr CPSR_fc, #5 @ encoding: [0x05,0xf0,0x29,0xe3] +@ CHECK: msr CPSR_c, #5 @ encoding: [0x05,0xf0,0x21,0xe3] +@ CHECK: msr CPSR_x, #5 @ encoding: [0x05,0xf0,0x22,0xe3] +@ CHECK: msr CPSR_fc, #5 @ encoding: [0x05,0xf0,0x29,0xe3] +@ CHECK: msr CPSR_fc, #5 @ encoding: [0x05,0xf0,0x29,0xe3] +@ CHECK: msr CPSR_fsx, #5 @ encoding: [0x05,0xf0,0x2e,0xe3] +@ CHECK: msr SPSR_fc, #5 @ encoding: [0x05,0xf0,0x69,0xe3] +@ CHECK: msr SPSR_fsxc, #5 @ encoding: [0x05,0xf0,0x6f,0xe3] +@ CHECK: msr CPSR_fsxc, #5 @ encoding: [0x05,0xf0,0x2f,0xe3] + + msr apsr, r0 + msr apsr_g, r0 + msr apsr_nzcvq, r0 + msr APSR_nzcvq, r0 + msr apsr_nzcvqg, r0 + msr cpsr_fc, r0 + msr cpsr_c, r0 + msr cpsr_x, r0 + msr cpsr_fc, r0 + msr cpsr_all, r0 + msr cpsr_fsx, r0 + msr spsr_fc, r0 + msr SPSR_fsxc, r0 + msr cpsr_fsxc, r0 + +@ CHECK: msr APSR_nzcvq, r0 @ encoding: [0x00,0xf0,0x28,0xe1] +@ CHECK: msr APSR_g, r0 @ encoding: [0x00,0xf0,0x24,0xe1] +@ CHECK: msr APSR_nzcvq, r0 @ encoding: [0x00,0xf0,0x28,0xe1] +@ CHECK: msr APSR_nzcvq, r0 @ encoding: [0x00,0xf0,0x28,0xe1] +@ CHECK: msr APSR_nzcvqg, r0 @ encoding: [0x00,0xf0,0x2c,0xe1] +@ CHECK: msr CPSR_fc, r0 @ encoding: [0x00,0xf0,0x29,0xe1] +@ CHECK: msr CPSR_c, r0 @ encoding: [0x00,0xf0,0x21,0xe1] +@ CHECK: msr CPSR_x, r0 @ encoding: [0x00,0xf0,0x22,0xe1] +@ CHECK: msr CPSR_fc, r0 @ encoding: [0x00,0xf0,0x29,0xe1] +@ CHECK: msr CPSR_fc, r0 @ encoding: [0x00,0xf0,0x29,0xe1] +@ CHECK: msr CPSR_fsx, r0 @ encoding: [0x00,0xf0,0x2e,0xe1] +@ CHECK: msr SPSR_fc, r0 @ encoding: [0x00,0xf0,0x69,0xe1] +@ CHECK: msr SPSR_fsxc, r0 @ encoding: [0x00,0xf0,0x6f,0xe1] +@ CHECK: msr CPSR_fsxc, r0 @ encoding: [0x00,0xf0,0x2f,0xe1] + +@------------------------------------------------------------------------------ +@ MUL +@------------------------------------------------------------------------------ + mul r5, r6, r7 + muls r5, r6, r7 + mulgt r5, r6, r7 + mulsle r5, r6, r7 + +@ CHECK: mul r5, r6, r7 @ encoding: [0x96,0x07,0x05,0xe0] +@ CHECK: muls r5, r6, r7 @ encoding: [0x96,0x07,0x15,0xe0] +@ CHECK: mulgt r5, r6, r7 @ encoding: [0x96,0x07,0x05,0xc0] +@ CHECK: mulsle r5, r6, r7 @ encoding: [0x96,0x07,0x15,0xd0] + + +@------------------------------------------------------------------------------ +@ MVN (immediate) +@------------------------------------------------------------------------------ + mvn r3, #7 + mvn r4, #0xff0 + mvn r5, #0xff0000 + mvns r3, #7 + mvneq r4, #0xff0 + mvnseq r5, #0xff0000 + +@ CHECK: mvn r3, #7 @ encoding: [0x07,0x30,0xe0,0xe3] +@ CHECK: mvn r4, #4080 @ encoding: [0xff,0x4e,0xe0,0xe3] +@ CHECK: mvn r5, #16711680 @ encoding: [0xff,0x58,0xe0,0xe3] +@ CHECK: mvns r3, #7 @ encoding: [0x07,0x30,0xf0,0xe3] +@ CHECK: mvneq r4, #4080 @ encoding: [0xff,0x4e,0xe0,0x03] +@ CHECK: mvnseq r5, #16711680 @ encoding: [0xff,0x58,0xf0,0x03] + + +@------------------------------------------------------------------------------ +@ MVN (register) +@------------------------------------------------------------------------------ + mvn r2, r3 + mvns r2, r3 + mvn r5, r6, lsl #19 + mvn r5, r6, lsr #9 + mvn r5, r6, asr #4 + mvn r5, r6, ror #6 + mvn r5, r6, rrx + mvneq r2, r3 + mvnseq r2, r3, lsl #10 + +@ CHECK: mvn r2, r3 @ encoding: [0x03,0x20,0xe0,0xe1] +@ CHECK: mvns r2, r3 @ encoding: [0x03,0x20,0xf0,0xe1] +@ CHECK: mvn r5, r6, lsl #19 @ encoding: [0x86,0x59,0xe0,0xe1] +@ CHECK: mvn r5, r6, lsr #9 @ encoding: [0xa6,0x54,0xe0,0xe1] +@ CHECK: mvn r5, r6, asr #4 @ encoding: [0x46,0x52,0xe0,0xe1] +@ CHECK: mvn r5, r6, ror #6 @ encoding: [0x66,0x53,0xe0,0xe1] +@ CHECK: mvn r5, r6, rrx @ encoding: [0x66,0x50,0xe0,0xe1] +@ CHECK: mvneq r2, r3 @ encoding: [0x03,0x20,0xe0,0x01] +@ CHECK: mvnseq r2, r3, lsl #10 @ encoding: [0x03,0x25,0xf0,0x01] + + +@------------------------------------------------------------------------------ +@ MVN (shifted register) +@------------------------------------------------------------------------------ + mvn r5, r6, lsl r7 + mvns r5, r6, lsr r7 + mvngt r5, r6, asr r7 + mvnslt r5, r6, ror r7 + +@ CHECK: mvn r5, r6, lsl r7 @ encoding: [0x16,0x57,0xe0,0xe1] +@ CHECK: mvns r5, r6, lsr r7 @ encoding: [0x36,0x57,0xf0,0xe1] +@ CHECK: mvngt r5, r6, asr r7 @ encoding: [0x56,0x57,0xe0,0xc1] +@ CHECK: mvnslt r5, r6, ror r7 @ encoding: [0x76,0x57,0xf0,0xb1] + +@------------------------------------------------------------------------------ +@ NOP +@------------------------------------------------------------------------------ + nop + nopgt + +@ CHECK: nop @ encoding: [0x00,0xf0,0x20,0xe3] +@ CHECK: nopgt @ encoding: [0x00,0xf0,0x20,0xc3] + + +@------------------------------------------------------------------------------ +@ ORR +@------------------------------------------------------------------------------ + orr r4, r5, #0xf000 + orr r4, r5, r6 + orr r4, r5, r6, lsl #5 + orr r4, r5, r6, lsr #5 + orr r4, r5, r6, lsr #5 + orr r4, r5, r6, asr #5 + orr r4, r5, r6, ror #5 + orr r6, r7, r8, lsl r9 + orr r6, r7, r8, lsr r9 + orr r6, r7, r8, asr r9 + orr r6, r7, r8, ror r9 + orr r4, r5, r6, rrx + + @ destination register is optional + orr r5, #0xf000 + orr r4, r5 + orr r4, r5, lsl #5 + orr r4, r5, lsr #5 + orr r4, r5, lsr #5 + orr r4, r5, asr #5 + orr r4, r5, ror #5 + orr r6, r7, lsl r9 + orr r6, r7, lsr r9 + orr r6, r7, asr r9 + orr r6, r7, ror r9 + orr r4, r5, rrx + +@ CHECK: orr r4, r5, #61440 @ encoding: [0x0f,0x4a,0x85,0xe3] +@ CHECK: orr r4, r5, r6 @ encoding: [0x06,0x40,0x85,0xe1] +@ CHECK: orr r4, r5, r6, lsl #5 @ encoding: [0x86,0x42,0x85,0xe1] +@ CHECK: orr r4, r5, r6, lsr #5 @ encoding: [0xa6,0x42,0x85,0xe1] +@ CHECK: orr r4, r5, r6, lsr #5 @ encoding: [0xa6,0x42,0x85,0xe1] +@ CHECK: orr r4, r5, r6, asr #5 @ encoding: [0xc6,0x42,0x85,0xe1] +@ CHECK: orr r4, r5, r6, ror #5 @ encoding: [0xe6,0x42,0x85,0xe1] +@ CHECK: orr r6, r7, r8, lsl r9 @ encoding: [0x18,0x69,0x87,0xe1] +@ CHECK: orr r6, r7, r8, lsr r9 @ encoding: [0x38,0x69,0x87,0xe1] +@ CHECK: orr r6, r7, r8, asr r9 @ encoding: [0x58,0x69,0x87,0xe1] +@ CHECK: orr r6, r7, r8, ror r9 @ encoding: [0x78,0x69,0x87,0xe1] +@ CHECK: orr r4, r5, r6, rrx @ encoding: [0x66,0x40,0x85,0xe1] + +@ CHECK: orr r5, r5, #61440 @ encoding: [0x0f,0x5a,0x85,0xe3] +@ CHECK: orr r4, r4, r5 @ encoding: [0x05,0x40,0x84,0xe1] +@ CHECK: orr r4, r4, r5, lsl #5 @ encoding: [0x85,0x42,0x84,0xe1] +@ CHECK: orr r4, r4, r5, lsr #5 @ encoding: [0xa5,0x42,0x84,0xe1] +@ CHECK: orr r4, r4, r5, lsr #5 @ encoding: [0xa5,0x42,0x84,0xe1] +@ CHECK: orr r4, r4, r5, asr #5 @ encoding: [0xc5,0x42,0x84,0xe1] +@ CHECK: orr r4, r4, r5, ror #5 @ encoding: [0xe5,0x42,0x84,0xe1] +@ CHECK: orr r6, r6, r7, lsl r9 @ encoding: [0x17,0x69,0x86,0xe1] +@ CHECK: orr r6, r6, r7, lsr r9 @ encoding: [0x37,0x69,0x86,0xe1] +@ CHECK: orr r6, r6, r7, asr r9 @ encoding: [0x57,0x69,0x86,0xe1] +@ CHECK: orr r6, r6, r7, ror r9 @ encoding: [0x77,0x69,0x86,0xe1] +@ CHECK: orr r4, r4, r5, rrx @ encoding: [0x65,0x40,0x84,0xe1] + + orrseq r4, r5, #0xf000 + orrne r4, r5, r6 + orrseq r4, r5, r6, lsl #5 + orrlo r6, r7, r8, ror r9 + orrshi r4, r5, r6, rrx + orrcs r5, #0xf000 + orrseq r4, r5 + orrne r6, r7, asr r9 + orrslt r6, r7, ror r9 + orrsgt r4, r5, rrx + +@ CHECK: orrseq r4, r5, #61440 @ encoding: [0x0f,0x4a,0x95,0x03] +@ CHECK: orrne r4, r5, r6 @ encoding: [0x06,0x40,0x85,0x11] +@ CHECK: orrseq r4, r5, r6, lsl #5 @ encoding: [0x86,0x42,0x95,0x01] +@ CHECK: orrlo r6, r7, r8, ror r9 @ encoding: [0x78,0x69,0x87,0x31] +@ CHECK: orrshi r4, r5, r6, rrx @ encoding: [0x66,0x40,0x95,0x81] +@ CHECK: orrhs r5, r5, #61440 @ encoding: [0x0f,0x5a,0x85,0x23] +@ CHECK: orrseq r4, r4, r5 @ encoding: [0x05,0x40,0x94,0x01] +@ CHECK: orrne r6, r6, r7, asr r9 @ encoding: [0x57,0x69,0x86,0x11] +@ CHECK: orrslt r6, r6, r7, ror r9 @ encoding: [0x77,0x69,0x96,0xb1] +@ CHECK: orrsgt r4, r4, r5, rrx @ encoding: [0x65,0x40,0x94,0xc1] + +@------------------------------------------------------------------------------ +@ PKH +@------------------------------------------------------------------------------ + pkhbt r2, r2, r3 + pkhbt r2, r2, r3, lsl #31 + pkhbt r2, r2, r3, lsl #0 + pkhbt r2, r2, r3, lsl #15 + + pkhtb r2, r2, r3 + pkhtb r2, r2, r3, asr #31 + pkhtb r2, r2, r3, asr #15 + +@ CHECK: pkhbt r2, r2, r3 @ encoding: [0x13,0x20,0x82,0xe6] +@ CHECK: pkhbt r2, r2, r3, lsl #31 @ encoding: [0x93,0x2f,0x82,0xe6] +@ CHECK: pkhbt r2, r2, r3 @ encoding: [0x13,0x20,0x82,0xe6] +@ CHECK: pkhbt r2, r2, r3, lsl #15 @ encoding: [0x93,0x27,0x82,0xe6] + +@ CHECK: pkhbt r2, r2, r3 @ encoding: [0x13,0x20,0x82,0xe6] +@ CHECK: pkhtb r2, r2, r3, asr #31 @ encoding: [0xd3,0x2f,0x82,0xe6] +@ CHECK: pkhtb r2, r2, r3, asr #15 @ encoding: [0xd3,0x27,0x82,0xe6] + +@------------------------------------------------------------------------------ +@ FIXME: PLD +@------------------------------------------------------------------------------ +@------------------------------------------------------------------------------ +@ FIXME: PLI +@------------------------------------------------------------------------------ + + +@------------------------------------------------------------------------------ +@ POP +@------------------------------------------------------------------------------ + pop {r7} + pop {r7, r8, r9, r10} + +@ CHECK: pop {r7} @ encoding: [0x04,0x70,0x9d,0xe4] +@ CHECK: pop {r7, r8, r9, r10} @ encoding: [0x80,0x07,0xbd,0xe8] + + +@------------------------------------------------------------------------------ +@ PUSH +@------------------------------------------------------------------------------ + push {r7} + push {r7, r8, r9, r10} + +@ CHECK: push {r7} @ encoding: [0x04,0x70,0x2d,0xe5] +@ CHECK: push {r7, r8, r9, r10} @ encoding: [0x80,0x07,0x2d,0xe9] + + +@------------------------------------------------------------------------------ +@ QADD/QADD16/QADD8 +@------------------------------------------------------------------------------ + qadd r1, r2, r3 + qaddne r1, r2, r3 + qadd16 r1, r2, r3 + qadd16gt r1, r2, r3 + qadd8 r1, r2, r3 + qadd8le r1, r2, r3 + +@ CHECK: qadd r1, r2, r3 @ encoding: [0x52,0x10,0x03,0xe1] +@ CHECK: qaddne r1, r2, r3 @ encoding: [0x52,0x10,0x03,0x11] +@ CHECK: qadd16 r1, r2, r3 @ encoding: [0x13,0x1f,0x22,0xe6] +@ CHECK: qadd16gt r1, r2, r3 @ encoding: [0x13,0x1f,0x22,0xc6] +@ CHECK: qadd8 r1, r2, r3 @ encoding: [0x93,0x1f,0x22,0xe6] +@ CHECK: qadd8le r1, r2, r3 @ encoding: [0x93,0x1f,0x22,0xd6] + + +@------------------------------------------------------------------------------ +@ QDADD/QDSUB +@------------------------------------------------------------------------------ + qdadd r6, r7, r8 + qdaddhi r6, r7, r8 + qdsub r6, r7, r8 + qdsubhi r6, r7, r8 + +@ CHECK: qdadd r6, r7, r8 @ encoding: [0x57,0x60,0x48,0xe1] +@ CHECK: qdaddhi r6, r7, r8 @ encoding: [0x57,0x60,0x48,0x81] +@ CHECK: qdsub r6, r7, r8 @ encoding: [0x57,0x60,0x68,0xe1] +@ CHECK: qdsubhi r6, r7, r8 @ encoding: [0x57,0x60,0x68,0x81] + + +@------------------------------------------------------------------------------ +@ QSAX +@------------------------------------------------------------------------------ + qsax r9, r12, r0 + qsaxeq r9, r12, r0 + +@ CHECK: qsax r9, r12, r0 @ encoding: [0x50,0x9f,0x2c,0xe6] +@ CHECK: qsaxeq r9, r12, r0 @ encoding: [0x50,0x9f,0x2c,0x06] + + +@------------------------------------------------------------------------------ +@ QSUB/QSUB16/QSUB8 +@------------------------------------------------------------------------------ + qsub r1, r2, r3 + qsubne r1, r2, r3 + qsub16 r1, r2, r3 + qsub16gt r1, r2, r3 + qsub8 r1, r2, r3 + qsub8le r1, r2, r3 + +@ CHECK: qsub r1, r2, r3 @ encoding: [0x52,0x10,0x23,0xe1] +@ CHECK: qsubne r1, r2, r3 @ encoding: [0x52,0x10,0x23,0x11] +@ CHECK: qsub16 r1, r2, r3 @ encoding: [0x73,0x1f,0x22,0xe6] +@ CHECK: qsub16gt r1, r2, r3 @ encoding: [0x73,0x1f,0x22,0xc6] +@ CHECK: qsub8 r1, r2, r3 @ encoding: [0xf3,0x1f,0x22,0xe6] +@ CHECK: qsub8le r1, r2, r3 @ encoding: [0xf3,0x1f,0x22,0xd6] + + +@------------------------------------------------------------------------------ +@ RBIT +@------------------------------------------------------------------------------ + rbit r1, r2 + rbitne r1, r2 + +@ CHECK: rbit r1, r2 @ encoding: [0x32,0x1f,0xff,0xe6] +@ CHECK: rbitne r1, r2 @ encoding: [0x32,0x1f,0xff,0x16] + + +@------------------------------------------------------------------------------ +@ REV/REV16/REVSH +@------------------------------------------------------------------------------ + rev r1, r9 + revne r1, r5 + rev16 r8, r3 + rev16ne r12, r4 + revsh r4, r9 + revshne r9, r1 + +@ CHECK: rev r1, r9 @ encoding: [0x39,0x1f,0xbf,0xe6] +@ CHECK: revne r1, r5 @ encoding: [0x35,0x1f,0xbf,0x16] +@ CHECK: rev16 r8, r3 @ encoding: [0xb3,0x8f,0xbf,0xe6] +@ CHECK: rev16ne r12, r4 @ encoding: [0xb4,0xcf,0xbf,0x16] +@ CHECK: revsh r4, r9 @ encoding: [0xb9,0x4f,0xff,0xe6] +@ CHECK: revshne r9, r1 @ encoding: [0xb1,0x9f,0xff,0x16] + + +@------------------------------------------------------------------------------ +@ RFE +@------------------------------------------------------------------------------ + rfeda r2 + rfedb r3 + rfeia r5 + rfeib r6 + + rfeda r4! + rfedb r7! + rfeia r9! + rfeib r8! + + rfefa r2 + rfeea r3 + rfefd r5 + rfeed r6 + + rfefa r4! + rfeea r7! + rfefd r9! + rfeed r8! + + rfe r1 + rfe r1! + +@ CHECK: rfeda r2 @ encoding: [0x00,0x0a,0x12,0xf8] +@ CHECK: rfedb r3 @ encoding: [0x00,0x0a,0x13,0xf9] +@ CHECK: rfeia r5 @ encoding: [0x00,0x0a,0x95,0xf8] +@ CHECK: rfeib r6 @ encoding: [0x00,0x0a,0x96,0xf9] + +@ CHECK: rfeda r4! @ encoding: [0x00,0x0a,0x34,0xf8] +@ CHECK: rfedb r7! @ encoding: [0x00,0x0a,0x37,0xf9] +@ CHECK: rfeia r9! @ encoding: [0x00,0x0a,0xb9,0xf8] +@ CHECK: rfeib r8! @ encoding: [0x00,0x0a,0xb8,0xf9] + +@ CHECK: rfeda r2 @ encoding: [0x00,0x0a,0x12,0xf8] +@ CHECK: rfedb r3 @ encoding: [0x00,0x0a,0x13,0xf9] +@ CHECK: rfeia r5 @ encoding: [0x00,0x0a,0x95,0xf8] +@ CHECK: rfeib r6 @ encoding: [0x00,0x0a,0x96,0xf9] + +@ CHECK: rfeda r4! @ encoding: [0x00,0x0a,0x34,0xf8] +@ CHECK: rfedb r7! @ encoding: [0x00,0x0a,0x37,0xf9] +@ CHECK: rfeia r9! @ encoding: [0x00,0x0a,0xb9,0xf8] +@ CHECK: rfeib r8! @ encoding: [0x00,0x0a,0xb8,0xf9] + +@ CHECK: rfeia r1 @ encoding: [0x00,0x0a,0x91,0xf8] +@ CHECK: rfeia r1! @ encoding: [0x00,0x0a,0xb1,0xf8] + + +@------------------------------------------------------------------------------ +@ RSB +@------------------------------------------------------------------------------ + rsb r4, r5, #0xf000 + rsb r4, r5, r6 + rsb r4, r5, r6, lsl #5 + rsblo r4, r5, r6, lsr #5 + rsb r4, r5, r6, lsr #5 + rsb r4, r5, r6, asr #5 + rsb r4, r5, r6, ror #5 + rsb r6, r7, r8, lsl r9 + rsb r6, r7, r8, lsr r9 + rsb r6, r7, r8, asr r9 + rsble r6, r7, r8, ror r9 + rsb r4, r5, r6, rrx + + @ destination register is optional + rsb r5, #0xf000 + rsb r4, r5 + rsb r4, r5, lsl #5 + rsb r4, r5, lsr #5 + rsbne r4, r5, lsr #5 + rsb r4, r5, asr #5 + rsb r4, r5, ror #5 + rsbgt r6, r7, lsl r9 + rsb r6, r7, lsr r9 + rsb r6, r7, asr r9 + rsb r6, r7, ror r9 + rsb r4, r5, rrx + +@ CHECK: rsb r4, r5, #61440 @ encoding: [0x0f,0x4a,0x65,0xe2] +@ CHECK: rsb r4, r5, r6 @ encoding: [0x06,0x40,0x65,0xe0] +@ CHECK: rsb r4, r5, r6, lsl #5 @ encoding: [0x86,0x42,0x65,0xe0] +@ CHECK: rsblo r4, r5, r6, lsr #5 @ encoding: [0xa6,0x42,0x65,0x30] +@ CHECK: rsb r4, r5, r6, lsr #5 @ encoding: [0xa6,0x42,0x65,0xe0] +@ CHECK: rsb r4, r5, r6, asr #5 @ encoding: [0xc6,0x42,0x65,0xe0] +@ CHECK: rsb r4, r5, r6, ror #5 @ encoding: [0xe6,0x42,0x65,0xe0] +@ CHECK: rsb r6, r7, r8, lsl r9 @ encoding: [0x18,0x69,0x67,0xe0] +@ CHECK: rsb r6, r7, r8, lsr r9 @ encoding: [0x38,0x69,0x67,0xe0] +@ CHECK: rsb r6, r7, r8, asr r9 @ encoding: [0x58,0x69,0x67,0xe0] +@ CHECK: rsble r6, r7, r8, ror r9 @ encoding: [0x78,0x69,0x67,0xd0] +@ CHECK: rsb r4, r5, r6, rrx @ encoding: [0x66,0x40,0x65,0xe0] + +@ CHECK: rsb r5, r5, #61440 @ encoding: [0x0f,0x5a,0x65,0xe2] +@ CHECK: rsb r4, r4, r5 @ encoding: [0x05,0x40,0x64,0xe0] +@ CHECK: rsb r4, r4, r5, lsl #5 @ encoding: [0x85,0x42,0x64,0xe0] +@ CHECK: rsb r4, r4, r5, lsr #5 @ encoding: [0xa5,0x42,0x64,0xe0] +@ CHECK: rsbne r4, r4, r5, lsr #5 @ encoding: [0xa5,0x42,0x64,0x10] +@ CHECK: rsb r4, r4, r5, asr #5 @ encoding: [0xc5,0x42,0x64,0xe0] +@ CHECK: rsb r4, r4, r5, ror #5 @ encoding: [0xe5,0x42,0x64,0xe0] +@ CHECK: rsbgt r6, r6, r7, lsl r9 @ encoding: [0x17,0x69,0x66,0xc0] +@ CHECK: rsb r6, r6, r7, lsr r9 @ encoding: [0x37,0x69,0x66,0xe0] +@ CHECK: rsb r6, r6, r7, asr r9 @ encoding: [0x57,0x69,0x66,0xe0] +@ CHECK: rsb r6, r6, r7, ror r9 @ encoding: [0x77,0x69,0x66,0xe0] +@ CHECK: rsb r4, r4, r5, rrx @ encoding: [0x65,0x40,0x64,0xe0] + +@------------------------------------------------------------------------------ +@ RSC +@------------------------------------------------------------------------------ + rsc r4, r5, #0xf000 + rsc r4, r5, r6 + rsc r4, r5, r6, lsl #5 + rsclo r4, r5, r6, lsr #5 + rsc r4, r5, r6, lsr #5 + rsc r4, r5, r6, asr #5 + rsc r4, r5, r6, ror #5 + rsc r6, r7, r8, lsl r9 + rsc r6, r7, r8, lsr r9 + rsc r6, r7, r8, asr r9 + rscle r6, r7, r8, ror r9 + rscs r1, r8, #4064 + + @ destination register is optional + rsc r5, #0xf000 + rsc r4, r5 + rsc r4, r5, lsl #5 + rsc r4, r5, lsr #5 + rscne r4, r5, lsr #5 + rsc r4, r5, asr #5 + rsc r4, r5, ror #5 + rscgt r6, r7, lsl r9 + rsc r6, r7, lsr r9 + rsc r6, r7, asr r9 + rsc r6, r7, ror r9 + +@ CHECK: rsc r4, r5, #61440 @ encoding: [0x0f,0x4a,0xe5,0xe2] +@ CHECK: rsc r4, r5, r6 @ encoding: [0x06,0x40,0xe5,0xe0] +@ CHECK: rsc r4, r5, r6, lsl #5 @ encoding: [0x86,0x42,0xe5,0xe0] +@ CHECK: rsclo r4, r5, r6, lsr #5 @ encoding: [0xa6,0x42,0xe5,0x30] +@ CHECK: rsc r4, r5, r6, lsr #5 @ encoding: [0xa6,0x42,0xe5,0xe0] +@ CHECK: rsc r4, r5, r6, asr #5 @ encoding: [0xc6,0x42,0xe5,0xe0] +@ CHECK: rsc r4, r5, r6, ror #5 @ encoding: [0xe6,0x42,0xe5,0xe0] +@ CHECK: rsc r6, r7, r8, lsl r9 @ encoding: [0x18,0x69,0xe7,0xe0] +@ CHECK: rsc r6, r7, r8, lsr r9 @ encoding: [0x38,0x69,0xe7,0xe0] +@ CHECK: rsc r6, r7, r8, asr r9 @ encoding: [0x58,0x69,0xe7,0xe0] +@ CHECK: rscle r6, r7, r8, ror r9 @ encoding: [0x78,0x69,0xe7,0xd0] +@ CHECK: rscs r1, r8, #4064 @ encoding: [0xfe,0x1e,0xf8,0xe2] + +@ CHECK: rsc r5, r5, #61440 @ encoding: [0x0f,0x5a,0xe5,0xe2] +@ CHECK: rsc r4, r4, r5 @ encoding: [0x05,0x40,0xe4,0xe0] +@ CHECK: rsc r4, r4, r5, lsl #5 @ encoding: [0x85,0x42,0xe4,0xe0] +@ CHECK: rsc r4, r4, r5, lsr #5 @ encoding: [0xa5,0x42,0xe4,0xe0] +@ CHECK: rscne r4, r4, r5, lsr #5 @ encoding: [0xa5,0x42,0xe4,0x10] +@ CHECK: rsc r4, r4, r5, asr #5 @ encoding: [0xc5,0x42,0xe4,0xe0] +@ CHECK: rsc r4, r4, r5, ror #5 @ encoding: [0xe5,0x42,0xe4,0xe0] +@ CHECK: rscgt r6, r6, r7, lsl r9 @ encoding: [0x17,0x69,0xe6,0xc0] +@ CHECK: rsc r6, r6, r7, lsr r9 @ encoding: [0x37,0x69,0xe6,0xe0] +@ CHECK: rsc r6, r6, r7, asr r9 @ encoding: [0x57,0x69,0xe6,0xe0] +@ CHECK: rsc r6, r6, r7, ror r9 @ encoding: [0x77,0x69,0xe6,0xe0] + +@------------------------------------------------------------------------------ +@ SADD16/SADD8 +@------------------------------------------------------------------------------ + sadd16 r1, r2, r3 + sadd16gt r1, r2, r3 + sadd8 r1, r2, r3 + sadd8le r1, r2, r3 + +@ CHECK: sadd16 r1, r2, r3 @ encoding: [0x13,0x1f,0x12,0xe6] +@ CHECK: sadd16gt r1, r2, r3 @ encoding: [0x13,0x1f,0x12,0xc6] +@ CHECK: sadd8 r1, r2, r3 @ encoding: [0x93,0x1f,0x12,0xe6] +@ CHECK: sadd8le r1, r2, r3 @ encoding: [0x93,0x1f,0x12,0xd6] + + +@------------------------------------------------------------------------------ +@ SASX +@------------------------------------------------------------------------------ + sasx r9, r12, r0 + sasxeq r9, r12, r0 + +@ CHECK: sasx r9, r12, r0 @ encoding: [0x30,0x9f,0x1c,0xe6] +@ CHECK: sasxeq r9, r12, r0 @ encoding: [0x30,0x9f,0x1c,0x06] + + +@------------------------------------------------------------------------------ +@ SBC +@------------------------------------------------------------------------------ + sbc r4, r5, #0xf000 + sbc r4, r5, r6 + sbc r4, r5, r6, lsl #5 + sbc r4, r5, r6, lsr #5 + sbc r4, r5, r6, lsr #5 + sbc r4, r5, r6, asr #5 + sbc r4, r5, r6, ror #5 + sbc r6, r7, r8, lsl r9 + sbc r6, r7, r8, lsr r9 + sbc r6, r7, r8, asr r9 + sbc r6, r7, r8, ror r9 + + @ destination register is optional + sbc r5, #0xf000 + sbc r4, r5 + sbc r4, r5, lsl #5 + sbc r4, r5, lsr #5 + sbc r4, r5, lsr #5 + sbc r4, r5, asr #5 + sbc r4, r5, ror #5 + sbc r6, r7, lsl r9 + sbc r6, r7, lsr r9 + sbc r6, r7, asr r9 + sbc r6, r7, ror r9 + +@ CHECK: sbc r4, r5, #61440 @ encoding: [0x0f,0x4a,0xc5,0xe2] +@ CHECK: sbc r4, r5, r6 @ encoding: [0x06,0x40,0xc5,0xe0] +@ CHECK: sbc r4, r5, r6, lsl #5 @ encoding: [0x86,0x42,0xc5,0xe0] +@ CHECK: sbc r4, r5, r6, lsr #5 @ encoding: [0xa6,0x42,0xc5,0xe0] +@ CHECK: sbc r4, r5, r6, lsr #5 @ encoding: [0xa6,0x42,0xc5,0xe0] +@ CHECK: sbc r4, r5, r6, asr #5 @ encoding: [0xc6,0x42,0xc5,0xe0] +@ CHECK: sbc r4, r5, r6, ror #5 @ encoding: [0xe6,0x42,0xc5,0xe0] +@ CHECK: sbc r6, r7, r8, lsl r9 @ encoding: [0x18,0x69,0xc7,0xe0] +@ CHECK: sbc r6, r7, r8, lsr r9 @ encoding: [0x38,0x69,0xc7,0xe0] +@ CHECK: sbc r6, r7, r8, asr r9 @ encoding: [0x58,0x69,0xc7,0xe0] +@ CHECK: sbc r6, r7, r8, ror r9 @ encoding: [0x78,0x69,0xc7,0xe0] + +@ CHECK: sbc r5, r5, #61440 @ encoding: [0x0f,0x5a,0xc5,0xe2] +@ CHECK: sbc r4, r4, r5 @ encoding: [0x05,0x40,0xc4,0xe0] +@ CHECK: sbc r4, r4, r5, lsl #5 @ encoding: [0x85,0x42,0xc4,0xe0] +@ CHECK: sbc r4, r4, r5, lsr #5 @ encoding: [0xa5,0x42,0xc4,0xe0] +@ CHECK: sbc r4, r4, r5, lsr #5 @ encoding: [0xa5,0x42,0xc4,0xe0] +@ CHECK: sbc r4, r4, r5, asr #5 @ encoding: [0xc5,0x42,0xc4,0xe0] +@ CHECK: sbc r4, r4, r5, ror #5 @ encoding: [0xe5,0x42,0xc4,0xe0] +@ CHECK: sbc r6, r6, r7, lsl r9 @ encoding: [0x17,0x69,0xc6,0xe0] +@ CHECK: sbc r6, r6, r7, lsr r9 @ encoding: [0x37,0x69,0xc6,0xe0] +@ CHECK: sbc r6, r6, r7, asr r9 @ encoding: [0x57,0x69,0xc6,0xe0] +@ CHECK: sbc r6, r6, r7, ror r9 @ encoding: [0x77,0x69,0xc6,0xe0] + + +@------------------------------------------------------------------------------ +@ SBFX +@------------------------------------------------------------------------------ + sbfx r4, r5, #16, #1 + sbfxgt r4, r5, #16, #16 + +@ CHECK: sbfx r4, r5, #16, #1 @ encoding: [0x55,0x48,0xa0,0xe7] +@ CHECK: sbfxgt r4, r5, #16, #16 @ encoding: [0x55,0x48,0xaf,0xc7] + + +@------------------------------------------------------------------------------ +@ SEL +@------------------------------------------------------------------------------ + sel r9, r2, r1 + selne r9, r2, r1 + +@ CHECK: sel r9, r2, r1 @ encoding: [0xb1,0x9f,0x82,0xe6] +@ CHECK: selne r9, r2, r1 @ encoding: [0xb1,0x9f,0x82,0x16] + + +@------------------------------------------------------------------------------ +@ SETEND +@------------------------------------------------------------------------------ + setend be + setend le + +@ CHECK: setend be @ encoding: [0x00,0x02,0x01,0xf1] +@ CHECK: setend le @ encoding: [0x00,0x00,0x01,0xf1] + + +@------------------------------------------------------------------------------ +@ SEV +@------------------------------------------------------------------------------ + sev + seveq + +@ CHECK: sev @ encoding: [0x04,0xf0,0x20,0xe3] +@ CHECK: seveq @ encoding: [0x04,0xf0,0x20,0x03] + + +@------------------------------------------------------------------------------ +@ SHADD16/SHADD8 +@------------------------------------------------------------------------------ + shadd16 r4, r8, r2 + shadd16gt r4, r8, r2 + shadd8 r4, r8, r2 + shadd8gt r4, r8, r2 + +@ CHECK: shadd16 r4, r8, r2 @ encoding: [0x12,0x4f,0x38,0xe6] +@ CHECK: shadd16gt r4, r8, r2 @ encoding: [0x12,0x4f,0x38,0xc6] +@ CHECK: shadd8 r4, r8, r2 @ encoding: [0x92,0x4f,0x38,0xe6] +@ CHECK: shadd8gt r4, r8, r2 @ encoding: [0x92,0x4f,0x38,0xc6] + + +@------------------------------------------------------------------------------ +@ SHASX +@------------------------------------------------------------------------------ + shasx r4, r8, r2 + shasxgt r4, r8, r2 + +@ CHECK: shasx r4, r8, r2 @ encoding: [0x32,0x4f,0x38,0xe6] +@ CHECK: shasxgt r4, r8, r2 @ encoding: [0x32,0x4f,0x38,0xc6] + + +@------------------------------------------------------------------------------ +@ SHSUB16/SHSUB8 +@------------------------------------------------------------------------------ + shsub16 r4, r8, r2 + shsub16gt r4, r8, r2 + shsub8 r4, r8, r2 + shsub8gt r4, r8, r2 + +@ CHECK: shsub16 r4, r8, r2 @ encoding: [0x72,0x4f,0x38,0xe6] +@ CHECK: shsub16gt r4, r8, r2 @ encoding: [0x72,0x4f,0x38,0xc6] +@ CHECK: shsub8 r4, r8, r2 @ encoding: [0xf2,0x4f,0x38,0xe6] +@ CHECK: shsub8gt r4, r8, r2 @ encoding: [0xf2,0x4f,0x38,0xc6] + +@------------------------------------------------------------------------------ +@ SMC +@------------------------------------------------------------------------------ + smc #0xf + smceq #0 + +@ CHECK: smc #15 @ encoding: [0x7f,0x00,0x60,0xe1] +@ CHECK: smceq #0 @ encoding: [0x70,0x00,0x60,0x01] + +@------------------------------------------------------------------------------ +@ SMLABB/SMLABT/SMLATB/SMLATT +@------------------------------------------------------------------------------ + smlabb r3, r1, r9, r0 + smlabt r5, r6, r4, r1 + smlatb r4, r2, r3, r2 + smlatt r8, r3, r8, r4 + smlabbge r3, r1, r9, r0 + smlabtle r5, r6, r4, r1 + smlatbne r4, r2, r3, r2 + smlatteq r8, r3, r8, r4 + +@ CHECK: smlabb r3, r1, r9, r0 @ encoding: [0x81,0x09,0x03,0xe1] +@ CHECK: smlabt r5, r6, r4, r1 @ encoding: [0xc6,0x14,0x05,0xe1] +@ CHECK: smlatb r4, r2, r3, r2 @ encoding: [0xa2,0x23,0x04,0xe1] +@ CHECK: smlatt r8, r3, r8, r4 @ encoding: [0xe3,0x48,0x08,0xe1] +@ CHECK: smlabbge r3, r1, r9, r0 @ encoding: [0x81,0x09,0x03,0xa1] +@ CHECK: smlabtle r5, r6, r4, r1 @ encoding: [0xc6,0x14,0x05,0xd1] +@ CHECK: smlatbne r4, r2, r3, r2 @ encoding: [0xa2,0x23,0x04,0x11] +@ CHECK: smlatteq r8, r3, r8, r4 @ encoding: [0xe3,0x48,0x08,0x01] + +@------------------------------------------------------------------------------ +@ SMLAD/SMLADX +@------------------------------------------------------------------------------ + smlad r2, r3, r5, r8 + smladx r2, r3, r5, r8 + smladeq r2, r3, r5, r8 + smladxhi r2, r3, r5, r8 + +@ CHECK: smlad r2, r3, r5, r8 @ encoding: [0x13,0x85,0x02,0xe7] +@ CHECK: smladx r2, r3, r5, r8 @ encoding: [0x33,0x85,0x02,0xe7] +@ CHECK: smladeq r2, r3, r5, r8 @ encoding: [0x13,0x85,0x02,0x07] +@ CHECK: smladxhi r2, r3, r5, r8 @ encoding: [0x33,0x85,0x02,0x87] + + +@------------------------------------------------------------------------------ +@ SMLAL +@------------------------------------------------------------------------------ + smlal r2, r3, r5, r8 + smlals r2, r3, r5, r8 + smlaleq r2, r3, r5, r8 + smlalshi r2, r3, r5, r8 + +@ CHECK: smlal r2, r3, r5, r8 @ encoding: [0x95,0x28,0xe3,0xe0] +@ CHECK: smlals r2, r3, r5, r8 @ encoding: [0x95,0x28,0xf3,0xe0] +@ CHECK: smlaleq r2, r3, r5, r8 @ encoding: [0x95,0x28,0xe3,0x00] +@ CHECK: smlalshi r2, r3, r5, r8 @ encoding: [0x95,0x28,0xf3,0x80] + + +@------------------------------------------------------------------------------ +@ SMLALBB/SMLALBT/SMLALTB/SMLALTT +@------------------------------------------------------------------------------ + smlalbb r3, r1, r9, r0 + smlalbt r5, r6, r4, r1 + smlaltb r4, r2, r3, r2 + smlaltt r8, r3, r8, r4 + smlalbbge r3, r1, r9, r0 + smlalbtle r5, r6, r4, r1 + smlaltbne r4, r2, r3, r2 + smlaltteq r8, r3, r8, r4 + +@ CHECK: smlalbb r3, r1, r9, r0 @ encoding: [0x89,0x30,0x41,0xe1] +@ CHECK: smlalbt r5, r6, r4, r1 @ encoding: [0xc4,0x51,0x46,0xe1] +@ CHECK: smlaltb r4, r2, r3, r2 @ encoding: [0xa3,0x42,0x42,0xe1] +@ CHECK: smlaltt r8, r3, r8, r4 @ encoding: [0xe8,0x84,0x43,0xe1] +@ CHECK: smlalbbge r3, r1, r9, r0 @ encoding: [0x89,0x30,0x41,0xa1] +@ CHECK: smlalbtle r5, r6, r4, r1 @ encoding: [0xc4,0x51,0x46,0xd1] +@ CHECK: smlaltbne r4, r2, r3, r2 @ encoding: [0xa3,0x42,0x42,0x11] +@ CHECK: smlaltteq r8, r3, r8, r4 @ encoding: [0xe8,0x84,0x43,0x01] + + +@------------------------------------------------------------------------------ +@ SMLALD/SMLALDX +@------------------------------------------------------------------------------ + smlald r2, r3, r5, r8 + smlaldx r2, r3, r5, r8 + smlaldeq r2, r3, r5, r8 + smlaldxhi r2, r3, r5, r8 + +@ CHECK: smlald r2, r3, r5, r8 @ encoding: [0x15,0x28,0x43,0xe7] +@ CHECK: smlaldx r2, r3, r5, r8 @ encoding: [0x35,0x28,0x43,0xe7] +@ CHECK: smlaldeq r2, r3, r5, r8 @ encoding: [0x15,0x28,0x43,0x07] +@ CHECK: smlaldxhi r2, r3, r5, r8 @ encoding: [0x35,0x28,0x43,0x87] + + +@------------------------------------------------------------------------------ +@ SMLAWB/SMLAWT +@------------------------------------------------------------------------------ + smlawb r2, r3, r10, r8 + smlawt r8, r3, r5, r9 + smlawbeq r2, r7, r5, r8 + smlawthi r1, r3, r0, r8 + +@ CHECK: smlawb r2, r3, r10, r8 @ encoding: [0x83,0x8a,0x22,0xe1] +@ CHECK: smlawt r8, r3, r5, r9 @ encoding: [0xc3,0x95,0x28,0xe1] +@ CHECK: smlawbeq r2, r7, r5, r8 @ encoding: [0x87,0x85,0x22,0x01] +@ CHECK: smlawthi r1, r3, r0, r8 @ encoding: [0xc3,0x80,0x21,0x81] + + +@------------------------------------------------------------------------------ +@ SMLSD/SMLSDX +@------------------------------------------------------------------------------ + smlsd r2, r3, r5, r8 + smlsdx r2, r3, r5, r8 + smlsdeq r2, r3, r5, r8 + smlsdxhi r2, r3, r5, r8 + +@ CHECK: smlsd r2, r3, r5, r8 @ encoding: [0x53,0x85,0x02,0xe7] +@ CHECK: smlsdx r2, r3, r5, r8 @ encoding: [0x73,0x85,0x02,0xe7] +@ CHECK: smlsdeq r2, r3, r5, r8 @ encoding: [0x53,0x85,0x02,0x07] +@ CHECK: smlsdxhi r2, r3, r5, r8 @ encoding: [0x73,0x85,0x02,0x87] + + +@------------------------------------------------------------------------------ +@ SMLSLD/SMLSLDX +@------------------------------------------------------------------------------ + smlsld r2, r9, r5, r1 + smlsldx r4, r11, r2, r8 + smlsldeq r8, r2, r5, r6 + smlsldxhi r1, r0, r3, r8 + +@ CHECK: smlsld r2, r9, r5, r1 @ encoding: [0x55,0x21,0x49,0xe7] +@ CHECK: smlsldx r4, r11, r2, r8 @ encoding: [0x72,0x48,0x4b,0xe7] +@ CHECK: smlsldeq r8, r2, r5, r6 @ encoding: [0x55,0x86,0x42,0x07] +@ CHECK: smlsldxhi r1, r0, r3, r8 @ encoding: [0x73,0x18,0x40,0x87] + + +@------------------------------------------------------------------------------ +@ SMMLA/SMMLAR +@------------------------------------------------------------------------------ + smmla r1, r2, r3, r4 + smmlar r4, r3, r2, r1 + smmlalo r1, r2, r3, r4 + smmlarcs r4, r3, r2, r1 + +@ CHECK: smmla r1, r2, r3, r4 @ encoding: [0x12,0x43,0x51,0xe7] +@ CHECK: smmlar r4, r3, r2, r1 @ encoding: [0x33,0x12,0x54,0xe7] +@ CHECK: smmlalo r1, r2, r3, r4 @ encoding: [0x12,0x43,0x51,0x37] +@ CHECK: smmlarhs r4, r3, r2, r1 @ encoding: [0x33,0x12,0x54,0x27] + + +@------------------------------------------------------------------------------ +@ SMMLS/SMMLSR +@------------------------------------------------------------------------------ + smmls r1, r2, r3, r4 + smmlsr r4, r3, r2, r1 + smmlslo r1, r2, r3, r4 + smmlsrcs r4, r3, r2, r1 + +@ CHECK: smmls r1, r2, r3, r4 @ encoding: [0xd2,0x43,0x51,0xe7] +@ CHECK: smmlsr r4, r3, r2, r1 @ encoding: [0xf3,0x12,0x54,0xe7] +@ CHECK: smmlslo r1, r2, r3, r4 @ encoding: [0xd2,0x43,0x51,0x37] +@ CHECK: smmlsrhs r4, r3, r2, r1 @ encoding: [0xf3,0x12,0x54,0x27] + + +@------------------------------------------------------------------------------ +@ SMMUL/SMMULR +@------------------------------------------------------------------------------ + smmul r2, r3, r4 + smmulr r3, r2, r1 + smmulcc r2, r3, r4 + smmulrhs r3, r2, r1 + +@ CHECK: smmul r2, r3, r4 @ encoding: [0x13,0xf4,0x52,0xe7] +@ CHECK: smmulr r3, r2, r1 @ encoding: [0x32,0xf1,0x53,0xe7] +@ CHECK: smmullo r2, r3, r4 @ encoding: [0x13,0xf4,0x52,0x37] +@ CHECK: smmulrhs r3, r2, r1 @ encoding: [0x32,0xf1,0x53,0x27] + + +@------------------------------------------------------------------------------ +@ SMUAD/SMUADX +@------------------------------------------------------------------------------ + smuad r2, r3, r4 + smuadx r3, r2, r1 + smuadlt r2, r3, r4 + smuadxge r3, r2, r1 + +@ CHECK: smuad r2, r3, r4 @ encoding: [0x13,0xf4,0x02,0xe7] +@ CHECK: smuadx r3, r2, r1 @ encoding: [0x32,0xf1,0x03,0xe7] +@ CHECK: smuadlt r2, r3, r4 @ encoding: [0x13,0xf4,0x02,0xb7] +@ CHECK: smuadxge r3, r2, r1 @ encoding: [0x32,0xf1,0x03,0xa7] + + +@------------------------------------------------------------------------------ +@ SMULBB/SMULBT/SMULTB/SMULTT +@------------------------------------------------------------------------------ + smulbb r3, r9, r0 + smulbt r5, r4, r1 + smultb r4, r2, r2 + smultt r8, r3, r4 + smulbbge r1, r9, r0 + smulbtle r5, r6, r4 + smultbne r2, r3, r2 + smultteq r8, r3, r4 + +@ CHECK: smulbb r3, r9, r0 @ encoding: [0x89,0x00,0x63,0xe1] +@ CHECK: smulbt r5, r4, r1 @ encoding: [0xc4,0x01,0x65,0xe1] +@ CHECK: smultb r4, r2, r2 @ encoding: [0xa2,0x02,0x64,0xe1] +@ CHECK: smultt r8, r3, r4 @ encoding: [0xe3,0x04,0x68,0xe1] +@ CHECK: smulbbge r1, r9, r0 @ encoding: [0x89,0x00,0x61,0xa1] +@ CHECK: smulbtle r5, r6, r4 @ encoding: [0xc6,0x04,0x65,0xd1] +@ CHECK: smultbne r2, r3, r2 @ encoding: [0xa3,0x02,0x62,0x11] +@ CHECK: smultteq r8, r3, r4 @ encoding: [0xe3,0x04,0x68,0x01] + + +@------------------------------------------------------------------------------ +@ SMULL +@------------------------------------------------------------------------------ + smull r3, r9, r0, r1 + smulls r3, r9, r0, r2 + smulleq r8, r3, r4, r5 + smullseq r8, r3, r4, r3 + +@ CHECK: smull r3, r9, r0, r1 @ encoding: [0x90,0x31,0xc9,0xe0] +@ CHECK: smulls r3, r9, r0, r2 @ encoding: [0x90,0x32,0xd9,0xe0] +@ CHECK: smulleq r8, r3, r4, r5 @ encoding: [0x94,0x85,0xc3,0x00] +@ CHECK: smullseq r8, r3, r4, r3 @ encoding: [0x94,0x83,0xd3,0x00] + + +@------------------------------------------------------------------------------ +@ SMULWB/SMULWT +@------------------------------------------------------------------------------ + smulwb r3, r9, r0 + smulwt r3, r9, r2 + +@ CHECK: smulwb r3, r9, r0 @ encoding: [0xa9,0x00,0x23,0xe1] +@ CHECK: smulwt r3, r9, r2 @ encoding: [0xe9,0x02,0x23,0xe1] + + +@------------------------------------------------------------------------------ +@ SMUSD/SMUSDX +@------------------------------------------------------------------------------ + smusd r3, r0, r1 + smusdx r3, r9, r2 + smusdeq r8, r3, r2 + smusdxne r7, r4, r3 + +@ CHECK: smusd r3, r0, r1 @ encoding: [0x50,0xf1,0x03,0xe7] +@ CHECK: smusdx r3, r9, r2 @ encoding: [0x79,0xf2,0x03,0xe7] +@ CHECK: smusdeq r8, r3, r2 @ encoding: [0x53,0xf2,0x08,0x07] +@ CHECK: smusdxne r7, r4, r3 @ encoding: [0x74,0xf3,0x07,0x17] + + +@------------------------------------------------------------------------------ +@ SRS +@------------------------------------------------------------------------------ + srsda sp, #5 + srsdb sp, #1 + srsia sp, #0 + srsib sp, #15 + + srsda sp!, #31 + srsdb sp!, #19 + srsia sp!, #2 + srsib sp!, #14 + + srsfa sp, #11 + srsea sp, #10 + srsfd sp, #9 + srsed sp, #5 + + srsfa sp!, #5 + srsea sp!, #5 + srsfd sp!, #5 + srsed sp!, #5 + + srs sp, #5 + srs sp!, #5 + +@ CHECK: srsda sp, #5 @ encoding: [0x05,0x05,0x4d,0xf8] +@ CHECK: srsdb sp, #1 @ encoding: [0x01,0x05,0x4d,0xf9] +@ CHECK: srsia sp, #0 @ encoding: [0x00,0x05,0xcd,0xf8] +@ CHECK: srsib sp, #15 @ encoding: [0x0f,0x05,0xcd,0xf9] + +@ CHECK: srsda sp!, #31 @ encoding: [0x1f,0x05,0x6d,0xf8] +@ CHECK: srsdb sp!, #19 @ encoding: [0x13,0x05,0x6d,0xf9] +@ CHECK: srsia sp!, #2 @ encoding: [0x02,0x05,0xed,0xf8] +@ CHECK: srsib sp!, #14 @ encoding: [0x0e,0x05,0xed,0xf9] + +@ CHECK: srsda sp, #11 @ encoding: [0x0b,0x05,0x4d,0xf8] +@ CHECK: srsdb sp, #10 @ encoding: [0x0a,0x05,0x4d,0xf9] +@ CHECK: srsia sp, #9 @ encoding: [0x09,0x05,0xcd,0xf8] +@ CHECK: srsib sp, #5 @ encoding: [0x05,0x05,0xcd,0xf9] + +@ CHECK: srsda sp!, #5 @ encoding: [0x05,0x05,0x6d,0xf8] +@ CHECK: srsdb sp!, #5 @ encoding: [0x05,0x05,0x6d,0xf9] +@ CHECK: srsia sp!, #5 @ encoding: [0x05,0x05,0xed,0xf8] +@ CHECK: srsib sp!, #5 @ encoding: [0x05,0x05,0xed,0xf9] + +@ CHECK: srsia sp, #5 @ encoding: [0x05,0x05,0xcd,0xf8] +@ CHECK: srsia sp!, #5 @ encoding: [0x05,0x05,0xed,0xf8] + + +@------------------------------------------------------------------------------ +@ SSAT +@------------------------------------------------------------------------------ + ssat r8, #1, r10 + ssat r8, #1, r10, lsl #0 + ssat r8, #1, r10, lsl #31 + ssat r8, #1, r10, asr #32 + ssat r8, #1, r10, asr #1 + +@ CHECK: ssat r8, #1, r10 @ encoding: [0x1a,0x80,0xa0,0xe6] +@ CHECK: ssat r8, #1, r10 @ encoding: [0x1a,0x80,0xa0,0xe6] +@ CHECK: ssat r8, #1, r10, lsl #31 @ encoding: [0x9a,0x8f,0xa0,0xe6] +@ CHECK: ssat r8, #1, r10, asr #32 @ encoding: [0x5a,0x80,0xa0,0xe6] +@ CHECK: ssat r8, #1, r10, asr #1 @ encoding: [0xda,0x80,0xa0,0xe6] + + +@------------------------------------------------------------------------------ +@ SSAT16 +@------------------------------------------------------------------------------ + ssat16 r2, #1, r7 + ssat16 r3, #16, r5 + +@ CHECK: ssat16 r2, #1, r7 @ encoding: [0x37,0x2f,0xa0,0xe6] +@ CHECK: ssat16 r3, #16, r5 @ encoding: [0x35,0x3f,0xaf,0xe6] + + +@------------------------------------------------------------------------------ +@ SSAX +@------------------------------------------------------------------------------ + ssax r2, r3, r4 + ssaxlt r2, r3, r4 + +@ CHECK: ssax r2, r3, r4 @ encoding: [0x54,0x2f,0x13,0xe6] +@ CHECK: ssaxlt r2, r3, r4 @ encoding: [0x54,0x2f,0x13,0xb6] + +@------------------------------------------------------------------------------ +@ SSUB16/SSUB8 +@------------------------------------------------------------------------------ + ssub16 r1, r0, r6 + ssub16ne r5, r3, r2 + ssub8 r9, r2, r4 + ssub8eq r5, r1, r2 + +@ CHECK: ssub16 r1, r0, r6 @ encoding: [0x76,0x1f,0x10,0xe6] +@ CHECK: ssub16ne r5, r3, r2 @ encoding: [0x72,0x5f,0x13,0x16] +@ CHECK: ssub8 r9, r2, r4 @ encoding: [0xf4,0x9f,0x12,0xe6] +@ CHECK: ssub8eq r5, r1, r2 @ encoding: [0xf2,0x5f,0x11,0x06] + +@------------------------------------------------------------------------------ +@ STC{L}/STC2{L} +@------------------------------------------------------------------------------ + stc2 p0, c8, [r1, #4] + stc2 p1, c7, [r2] + stc2 p2, c6, [r3, #-224] + stc2 p3, c5, [r4, #-120]! + stc2 p4, c4, [r5], #16 + stc2 p5, c3, [r6], #-72 + stc2l p6, c2, [r7, #4] + stc2l p7, c1, [r8] + stc2l p8, c0, [r9, #-224] + stc2l p9, c1, [r10, #-120]! + stc2l p10, c2, [r11], #16 + stc2l p11, c3, [r12], #-72 + + stc p12, c4, [r0, #4] + stc p13, c5, [r1] + stc p14, c6, [r2, #-224] + stc p15, c7, [r3, #-120]! + stc p5, c8, [r4], #16 + stc p4, c9, [r5], #-72 + stcl p3, c10, [r6, #4] + stcl p2, c11, [r7] + stcl p1, c12, [r8, #-224] + stcl p0, c13, [r9, #-120]! + stcl p6, c14, [r10], #16 + stcl p7, c15, [r11], #-72 + + stclo p12, c4, [r0, #4] + stchi p13, c5, [r1] + stccs p14, c6, [r2, #-224] + stccc p15, c7, [r3, #-120]! + stceq p5, c8, [r4], #16 + stcgt p4, c9, [r5], #-72 + stcllt p3, c10, [r6, #4] + stclge p2, c11, [r7] + stclle p1, c12, [r8, #-224] + stclne p0, c13, [r9, #-120]! + stcleq p6, c14, [r10], #16 + stclhi p7, c15, [r11], #-72 + + stc2 p2, c8, [r1], { 25 } + +@ CHECK: stc2 p0, c8, [r1, #4] @ encoding: [0x01,0x80,0x81,0xfd] +@ CHECK: stc2 p1, c7, [r2] @ encoding: [0x00,0x71,0x82,0xfd] +@ CHECK: stc2 p2, c6, [r3, #-224] @ encoding: [0x38,0x62,0x03,0xfd] +@ CHECK: stc2 p3, c5, [r4, #-120]! @ encoding: [0x1e,0x53,0x24,0xfd] +@ CHECK: stc2 p4, c4, [r5], #16 @ encoding: [0x04,0x44,0xa5,0xfc] +@ CHECK: stc2 p5, c3, [r6], #-72 @ encoding: [0x12,0x35,0x26,0xfc] +@ CHECK: stc2l p6, c2, [r7, #4] @ encoding: [0x01,0x26,0xc7,0xfd] +@ CHECK: stc2l p7, c1, [r8] @ encoding: [0x00,0x17,0xc8,0xfd] +@ CHECK: stc2l p8, c0, [r9, #-224] @ encoding: [0x38,0x08,0x49,0xfd] +@ CHECK: stc2l p9, c1, [r10, #-120]! @ encoding: [0x1e,0x19,0x6a,0xfd] +@ CHECK: stc2l p10, c2, [r11], #16 @ encoding: [0x04,0x2a,0xeb,0xfc] +@ CHECK: stc2l p11, c3, [r12], #-72 @ encoding: [0x12,0x3b,0x6c,0xfc] + +@ CHECK: stc p12, c4, [r0, #4] @ encoding: [0x01,0x4c,0x80,0xed] +@ CHECK: stc p13, c5, [r1] @ encoding: [0x00,0x5d,0x81,0xed] +@ CHECK: stc p14, c6, [r2, #-224] @ encoding: [0x38,0x6e,0x02,0xed] +@ CHECK: stc p15, c7, [r3, #-120]! @ encoding: [0x1e,0x7f,0x23,0xed] +@ CHECK: stc p5, c8, [r4], #16 @ encoding: [0x04,0x85,0xa4,0xec] +@ CHECK: stc p4, c9, [r5], #-72 @ encoding: [0x12,0x94,0x25,0xec] +@ CHECK: stcl p3, c10, [r6, #4] @ encoding: [0x01,0xa3,0xc6,0xed] +@ CHECK: stcl p2, c11, [r7] @ encoding: [0x00,0xb2,0xc7,0xed] +@ CHECK: stcl p1, c12, [r8, #-224] @ encoding: [0x38,0xc1,0x48,0xed] +@ CHECK: stcl p0, c13, [r9, #-120]! @ encoding: [0x1e,0xd0,0x69,0xed] +@ CHECK: stcl p6, c14, [r10], #16 @ encoding: [0x04,0xe6,0xea,0xec] +@ CHECK: stcl p7, c15, [r11], #-72 @ encoding: [0x12,0xf7,0x6b,0xec] + +@ CHECK: stclo p12, c4, [r0, #4] @ encoding: [0x01,0x4c,0x80,0x3d] +@ CHECK: stchi p13, c5, [r1] @ encoding: [0x00,0x5d,0x81,0x8d] +@ CHECK: stchs p14, c6, [r2, #-224] @ encoding: [0x38,0x6e,0x02,0x2d] +@ CHECK: stclo p15, c7, [r3, #-120]! @ encoding: [0x1e,0x7f,0x23,0x3d] +@ CHECK: stceq p5, c8, [r4], #16 @ encoding: [0x04,0x85,0xa4,0x0c] +@ CHECK: stcgt p4, c9, [r5], #-72 @ encoding: [0x12,0x94,0x25,0xcc] +@ CHECK: stcllt p3, c10, [r6, #4] @ encoding: [0x01,0xa3,0xc6,0xbd] +@ CHECK: stclge p2, c11, [r7] @ encoding: [0x00,0xb2,0xc7,0xad] +@ CHECK: stclle p1, c12, [r8, #-224] @ encoding: [0x38,0xc1,0x48,0xdd] +@ CHECK: stclne p0, c13, [r9, #-120]! @ encoding: [0x1e,0xd0,0x69,0x1d] +@ CHECK: stcleq p6, c14, [r10], #16 @ encoding: [0x04,0xe6,0xea,0x0c] +@ CHECK: stclhi p7, c15, [r11], #-72 @ encoding: [0x12,0xf7,0x6b,0x8c] + +@ CHECK: stc2 p2, c8, [r1], {25} @ encoding: [0x19,0x82,0x81,0xfc] + + @------------------------------------------------------------------------------ @ STM* @------------------------------------------------------------------------------ stm r2, {r1,r3-r6,sp} - stmia r2, {r1,r3-r6,sp} - stmib r2, {r1,r3-r6,sp} - stmda r2, {r1,r3-r6,sp} - stmdb r2, {r1,r3-r6,sp} - stmfd r2, {r1,r3-r6,sp} + stmia r3, {r1,r3-r6,lr} + stmib r4, {r1,r3-r6,sp} + stmda r5, {r1,r3-r6,sp} + stmdb r6, {r1,r3-r6,r8} + stmfd sp, {r1,r3-r6,sp} @ with update - stmia r2!, {r1,r3-r6,sp} - stmib r2!, {r1,r3-r6,sp} - stmda r2!, {r1,r3-r6,sp} - stmdb r2!, {r1,r3-r6,sp} -@ CHECK: stm r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x82,0xe8] -@ CHECK: stm r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x82,0xe8] -@ CHECK: stmib r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x82,0xe9] -@ CHECK: stmda r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x02,0xe8] -@ CHECK: stmdb r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x02,0xe9] -@ CHECK: stmdb r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x02,0xe9] + stm r8!, {r1,r3-r6,sp} + stmib r9!, {r1,r3-r6,sp} + stmda sp!, {r1,r3-r6} + stmdb r0!, {r1,r5,r7,sp} -@ CHECK: stm r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0xa2,0xe8] -@ CHECK: stmib r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0xa2,0xe9] -@ CHECK: stmda r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x22,0xe8] -@ CHECK: stmdb r2!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x22,0xe9] +@ CHECK: stm r2, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x82,0xe8] +@ CHECK: stm r3, {lr, r1, r3, r4, r5, r6} @ encoding: [0x7a,0x40,0x83,0xe8] +@ CHECK: stmib r4, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x84,0xe9] +@ CHECK: stmda r5, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x05,0xe8] +@ CHECK: stmdb r6, {r1, r3, r4, r5, r6, r8} @ encoding: [0x7a,0x01,0x06,0xe9] +@ CHECK: stmdb sp, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0x0d,0xe9] + +@ CHECK: stm r8!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0xa8,0xe8] +@ CHECK: stmib r9!, {r1, r3, r4, r5, r6, sp} @ encoding: [0x7a,0x20,0xa9,0xe9] +@ CHECK: stmda sp!, {r1, r3, r4, r5, r6} @ encoding: [0x7a,0x00,0x2d,0xe8] +@ CHECK: stmdb r0!, {r1, r5, r7, sp} @ encoding: [0xa2,0x20,0x20,0xe9] + + +@------------------------------------------------------------------------------ +@ STREX/STREXB/STREXH/STREXD +@------------------------------------------------------------------------------ + strexb r1, r3, [r4] + strexh r4, r2, [r5] + strex r2, r1, [r7] + strexd r6, r2, r3, [r8] + +@ CHECK: strexb r1, r3, [r4] @ encoding: [0x93,0x1f,0xc4,0xe1] +@ CHECK: strexh r4, r2, [r5] @ encoding: [0x92,0x4f,0xe5,0xe1] +@ CHECK: strex r2, r1, [r7] @ encoding: [0x91,0x2f,0x87,0xe1] +@ CHECK: strexd r6, r2, r3, [r8] @ encoding: [0x92,0x6f,0xa8,0xe1] + +@------------------------------------------------------------------------------ +@ STR +@------------------------------------------------------------------------------ + strpl r3, [r10, #-0]! + strpl r3, [r10, #0]! + +@ CHECK: strpl r3, [r10, #-0]! @ encoding: [0x00,0x30,0x2a,0x55] +@ CHECK: strpl r3, [r10]! @ encoding: [0x00,0x30,0xaa,0x55] + +@------------------------------------------------------------------------------ +@ SUB +@------------------------------------------------------------------------------ + sub r4, r5, #0xf000 + sub r4, r5, r6 + sub r4, r5, r6, lsl #5 + sub r4, r5, r6, lsr #5 + sub r4, r5, r6, lsr #5 + sub r4, r5, r6, asr #5 + sub r4, r5, r6, ror #5 + sub r6, r7, r8, lsl r9 + sub r6, r7, r8, lsr r9 + sub r6, r7, r8, asr r9 + sub r6, r7, r8, ror r9 + + @ destination register is optional + sub r5, #0xf000 + sub r4, r5 + sub r4, r5, lsl #5 + sub r4, r5, lsr #5 + sub r4, r5, lsr #5 + sub r4, r5, asr #5 + sub r4, r5, ror #5 + sub r6, r7, lsl r9 + sub r6, r7, lsr r9 + sub r6, r7, asr r9 + sub r6, r7, ror r9 + +@ CHECK: sub r4, r5, #61440 @ encoding: [0x0f,0x4a,0x45,0xe2] +@ CHECK: sub r4, r5, r6 @ encoding: [0x06,0x40,0x45,0xe0] +@ CHECK: sub r4, r5, r6, lsl #5 @ encoding: [0x86,0x42,0x45,0xe0] +@ CHECK: sub r4, r5, r6, lsr #5 @ encoding: [0xa6,0x42,0x45,0xe0] +@ CHECK: sub r4, r5, r6, lsr #5 @ encoding: [0xa6,0x42,0x45,0xe0] +@ CHECK: sub r4, r5, r6, asr #5 @ encoding: [0xc6,0x42,0x45,0xe0] +@ CHECK: sub r4, r5, r6, ror #5 @ encoding: [0xe6,0x42,0x45,0xe0] +@ CHECK: sub r6, r7, r8, lsl r9 @ encoding: [0x18,0x69,0x47,0xe0] +@ CHECK: sub r6, r7, r8, lsr r9 @ encoding: [0x38,0x69,0x47,0xe0] +@ CHECK: sub r6, r7, r8, asr r9 @ encoding: [0x58,0x69,0x47,0xe0] +@ CHECK: sub r6, r7, r8, ror r9 @ encoding: [0x78,0x69,0x47,0xe0] + + +@ CHECK: sub r5, r5, #61440 @ encoding: [0x0f,0x5a,0x45,0xe2] +@ CHECK: sub r4, r4, r5 @ encoding: [0x05,0x40,0x44,0xe0] +@ CHECK: sub r4, r4, r5, lsl #5 @ encoding: [0x85,0x42,0x44,0xe0] +@ CHECK: sub r4, r4, r5, lsr #5 @ encoding: [0xa5,0x42,0x44,0xe0] +@ CHECK: sub r4, r4, r5, lsr #5 @ encoding: [0xa5,0x42,0x44,0xe0] +@ CHECK: sub r4, r4, r5, asr #5 @ encoding: [0xc5,0x42,0x44,0xe0] +@ CHECK: sub r4, r4, r5, ror #5 @ encoding: [0xe5,0x42,0x44,0xe0] +@ CHECK: sub r6, r6, r7, lsl r9 @ encoding: [0x17,0x69,0x46,0xe0] +@ CHECK: sub r6, r6, r7, lsr r9 @ encoding: [0x37,0x69,0x46,0xe0] +@ CHECK: sub r6, r6, r7, asr r9 @ encoding: [0x57,0x69,0x46,0xe0] +@ CHECK: sub r6, r6, r7, ror r9 @ encoding: [0x77,0x69,0x46,0xe0] + + +@------------------------------------------------------------------------------ +@ SVC +@------------------------------------------------------------------------------ + svc #16 + svc #0 + svc #0xffffff + +@ CHECK: svc #16 @ encoding: [0x10,0x00,0x00,0xef] +@ CHECK: svc #0 @ encoding: [0x00,0x00,0x00,0xef] +@ CHECK: svc #16777215 @ encoding: [0xff,0xff,0xff,0xef] + + +@------------------------------------------------------------------------------ +@ SWP/SWPB +@------------------------------------------------------------------------------ + swp r1, r2, [r3] + swp r4, r4, [r6] + swpb r5, r1, [r9] + +@ CHECK: swp r1, r2, [r3] @ encoding: [0x92,0x10,0x03,0xe1] +@ CHECK: swp r4, r4, [r6] @ encoding: [0x94,0x40,0x06,0xe1] +@ CHECK: swpb r5, r1, [r9] @ encoding: [0x91,0x50,0x49,0xe1] + + +@------------------------------------------------------------------------------ +@ SXTAB +@------------------------------------------------------------------------------ + sxtab r2, r3, r4 + sxtab r4, r5, r6, ror #0 + sxtablt r6, r2, r9, ror #8 + sxtab r5, r1, r4, ror #16 + sxtab r7, r8, r3, ror #24 + +@ CHECK: sxtab r2, r3, r4 @ encoding: [0x74,0x20,0xa3,0xe6] +@ CHECK: sxtab r4, r5, r6 @ encoding: [0x76,0x40,0xa5,0xe6] +@ CHECK: sxtablt r6, r2, r9, ror #8 @ encoding: [0x79,0x64,0xa2,0xb6] +@ CHECK: sxtab r5, r1, r4, ror #16 @ encoding: [0x74,0x58,0xa1,0xe6] +@ CHECK: sxtab r7, r8, r3, ror #24 @ encoding: [0x73,0x7c,0xa8,0xe6] + + +@------------------------------------------------------------------------------ +@ SXTAB16 +@------------------------------------------------------------------------------ + sxtab16ge r0, r1, r4 + sxtab16 r6, r2, r7, ror #0 + sxtab16 r3, r5, r8, ror #8 + sxtab16 r3, r2, r1, ror #16 + sxtab16eq r1, r2, r3, ror #24 + +@ CHECK: sxtab16ge r0, r1, r4 @ encoding: [0x74,0x00,0x81,0xa6] +@ CHECK: sxtab16 r6, r2, r7 @ encoding: [0x77,0x60,0x82,0xe6] +@ CHECK: sxtab16 r3, r5, r8, ror #8 @ encoding: [0x78,0x34,0x85,0xe6] +@ CHECK: sxtab16 r3, r2, r1, ror #16 @ encoding: [0x71,0x38,0x82,0xe6] +@ CHECK: sxtab16eq r1, r2, r3, ror #24 @ encoding: [0x73,0x1c,0x82,0x06] + +@------------------------------------------------------------------------------ +@ SXTAH +@------------------------------------------------------------------------------ + sxtah r1, r3, r9 + sxtahhi r6, r1, r6, ror #0 + sxtah r3, r8, r3, ror #8 + sxtahlo r2, r2, r4, ror #16 + sxtah r9, r3, r3, ror #24 + +@ CHECK: sxtah r1, r3, r9 @ encoding: [0x79,0x10,0xb3,0xe6] +@ CHECK: sxtahhi r6, r1, r6 @ encoding: [0x76,0x60,0xb1,0x86] +@ CHECK: sxtah r3, r8, r3, ror #8 @ encoding: [0x73,0x34,0xb8,0xe6] +@ CHECK: sxtahlo r2, r2, r4, ror #16 @ encoding: [0x74,0x28,0xb2,0x36] +@ CHECK: sxtah r9, r3, r3, ror #24 @ encoding: [0x73,0x9c,0xb3,0xe6] + +@------------------------------------------------------------------------------ +@ SXTB +@------------------------------------------------------------------------------ + sxtbge r2, r4 + sxtb r5, r6, ror #0 + sxtb r6, r9, ror #8 + sxtbcc r5, r1, ror #16 + sxtb r8, r3, ror #24 + +@ CHECK: sxtbge r2, r4 @ encoding: [0x74,0x20,0xaf,0xa6] +@ CHECK: sxtb r5, r6 @ encoding: [0x76,0x50,0xaf,0xe6] +@ CHECK: sxtb r6, r9, ror #8 @ encoding: [0x79,0x64,0xaf,0xe6] +@ CHECK: sxtblo r5, r1, ror #16 @ encoding: [0x71,0x58,0xaf,0x36] +@ CHECK: sxtb r8, r3, ror #24 @ encoding: [0x73,0x8c,0xaf,0xe6] + + +@------------------------------------------------------------------------------ +@ SXTB16 +@------------------------------------------------------------------------------ + sxtb16 r1, r4 + sxtb16 r6, r7, ror #0 + sxtb16cs r3, r5, ror #8 + sxtb16 r3, r1, ror #16 + sxtb16ge r2, r3, ror #24 + +@ CHECK: sxtb16 r1, r4 @ encoding: [0x74,0x10,0x8f,0xe6] +@ CHECK: sxtb16 r6, r7 @ encoding: [0x77,0x60,0x8f,0xe6] +@ CHECK: sxtb16hs r3, r5, ror #8 @ encoding: [0x75,0x34,0x8f,0x26] +@ CHECK: sxtb16 r3, r1, ror #16 @ encoding: [0x71,0x38,0x8f,0xe6] +@ CHECK: sxtb16ge r2, r3, ror #24 @ encoding: [0x73,0x2c,0x8f,0xa6] + + +@------------------------------------------------------------------------------ +@ SXTH +@------------------------------------------------------------------------------ + sxthne r3, r9 + sxth r1, r6, ror #0 + sxth r3, r8, ror #8 + sxthle r2, r2, ror #16 + sxth r9, r3, ror #24 + +@ CHECK: sxthne r3, r9 @ encoding: [0x79,0x30,0xbf,0x16] +@ CHECK: sxth r1, r6 @ encoding: [0x76,0x10,0xbf,0xe6] +@ CHECK: sxth r3, r8, ror #8 @ encoding: [0x78,0x34,0xbf,0xe6] +@ CHECK: sxthle r2, r2, ror #16 @ encoding: [0x72,0x28,0xbf,0xd6] +@ CHECK: sxth r9, r3, ror #24 @ encoding: [0x73,0x9c,0xbf,0xe6] + + +@------------------------------------------------------------------------------ +@ TEQ +@------------------------------------------------------------------------------ + teq r5, #0xf000 + teq r4, r5 + teq r4, r5, lsl #5 + teq r4, r5, lsr #5 + teq r4, r5, lsr #5 + teq r4, r5, asr #5 + teq r4, r5, ror #5 + teq r6, r7, lsl r9 + teq r6, r7, lsr r9 + teq r6, r7, asr r9 + teq r6, r7, ror r9 + +@ CHECK: teq r5, #61440 @ encoding: [0x0f,0x0a,0x35,0xe3] +@ CHECK: teq r4, r5 @ encoding: [0x05,0x00,0x34,0xe1] +@ CHECK: teq r4, r5, lsl #5 @ encoding: [0x85,0x02,0x34,0xe1] +@ CHECK: teq r4, r5, lsr #5 @ encoding: [0xa5,0x02,0x34,0xe1] +@ CHECK: teq r4, r5, lsr #5 @ encoding: [0xa5,0x02,0x34,0xe1] +@ CHECK: teq r4, r5, asr #5 @ encoding: [0xc5,0x02,0x34,0xe1] +@ CHECK: teq r4, r5, ror #5 @ encoding: [0xe5,0x02,0x34,0xe1] +@ CHECK: teq r6, r7, lsl r9 @ encoding: [0x17,0x09,0x36,0xe1] +@ CHECK: teq r6, r7, lsr r9 @ encoding: [0x37,0x09,0x36,0xe1] +@ CHECK: teq r6, r7, asr r9 @ encoding: [0x57,0x09,0x36,0xe1] +@ CHECK: teq r6, r7, ror r9 @ encoding: [0x77,0x09,0x36,0xe1] + + +@------------------------------------------------------------------------------ +@ TST +@------------------------------------------------------------------------------ + tst r5, #0xf000 + tst r4, r5 + tst r4, r5, lsl #5 + tst r4, r5, lsr #5 + tst r4, r5, lsr #5 + tst r4, r5, asr #5 + tst r4, r5, ror #5 + tst r6, r7, lsl r9 + tst r6, r7, lsr r9 + tst r6, r7, asr r9 + tst r6, r7, ror r9 + +@ CHECK: tst r5, #61440 @ encoding: [0x0f,0x0a,0x15,0xe3] +@ CHECK: tst r4, r5 @ encoding: [0x05,0x00,0x14,0xe1] +@ CHECK: tst r4, r5, lsl #5 @ encoding: [0x85,0x02,0x14,0xe1] +@ CHECK: tst r4, r5, lsr #5 @ encoding: [0xa5,0x02,0x14,0xe1] +@ CHECK: tst r4, r5, lsr #5 @ encoding: [0xa5,0x02,0x14,0xe1] +@ CHECK: tst r4, r5, asr #5 @ encoding: [0xc5,0x02,0x14,0xe1] +@ CHECK: tst r4, r5, ror #5 @ encoding: [0xe5,0x02,0x14,0xe1] +@ CHECK: tst r6, r7, lsl r9 @ encoding: [0x17,0x09,0x16,0xe1] +@ CHECK: tst r6, r7, lsr r9 @ encoding: [0x37,0x09,0x16,0xe1] +@ CHECK: tst r6, r7, asr r9 @ encoding: [0x57,0x09,0x16,0xe1] +@ CHECK: tst r6, r7, ror r9 @ encoding: [0x77,0x09,0x16,0xe1] + + +@------------------------------------------------------------------------------ +@ UADD16/UADD8 +@------------------------------------------------------------------------------ + uadd16 r1, r2, r3 + uadd16gt r1, r2, r3 + uadd8 r1, r2, r3 + uadd8le r1, r2, r3 + +@ CHECK: uadd16 r1, r2, r3 @ encoding: [0x13,0x1f,0x52,0xe6] +@ CHECK: uadd16gt r1, r2, r3 @ encoding: [0x13,0x1f,0x52,0xc6] +@ CHECK: uadd8 r1, r2, r3 @ encoding: [0x93,0x1f,0x52,0xe6] +@ CHECK: uadd8le r1, r2, r3 @ encoding: [0x93,0x1f,0x52,0xd6] + + +@------------------------------------------------------------------------------ +@ UASX +@------------------------------------------------------------------------------ + uasx r9, r12, r0 + uasxeq r9, r12, r0 + +@ CHECK: uasx r9, r12, r0 @ encoding: [0x30,0x9f,0x5c,0xe6] +@ CHECK: uasxeq r9, r12, r0 @ encoding: [0x30,0x9f,0x5c,0x06] + + +@------------------------------------------------------------------------------ +@ UBFX +@------------------------------------------------------------------------------ + ubfx r4, r5, #16, #1 + ubfxgt r4, r5, #16, #16 + +@ CHECK: ubfx r4, r5, #16, #1 @ encoding: [0x55,0x48,0xe0,0xe7] +@ CHECK: ubfxgt r4, r5, #16, #16 @ encoding: [0x55,0x48,0xef,0xc7] + + +@------------------------------------------------------------------------------ +@ UHADD16/UHADD8 +@------------------------------------------------------------------------------ + uhadd16 r4, r8, r2 + uhadd16gt r4, r8, r2 + uhadd8 r4, r8, r2 + uhadd8gt r4, r8, r2 + +@ CHECK: uhadd16 r4, r8, r2 @ encoding: [0x12,0x4f,0x78,0xe6] +@ CHECK: uhadd16gt r4, r8, r2 @ encoding: [0x12,0x4f,0x78,0xc6] +@ CHECK: uhadd8 r4, r8, r2 @ encoding: [0x92,0x4f,0x78,0xe6] +@ CHECK: uhadd8gt r4, r8, r2 @ encoding: [0x92,0x4f,0x78,0xc6] + + +@------------------------------------------------------------------------------ +@ UHASX +@------------------------------------------------------------------------------ + uhasx r4, r8, r2 + uhasxgt r4, r8, r2 + +@ CHECK: uhasx r4, r8, r2 @ encoding: [0x32,0x4f,0x78,0xe6] +@ CHECK: uhasxgt r4, r8, r2 @ encoding: [0x32,0x4f,0x78,0xc6] + + +@------------------------------------------------------------------------------ +@ UHSUB16/UHSUB8 +@------------------------------------------------------------------------------ + uhsub16 r4, r8, r2 + uhsub16gt r4, r8, r2 + uhsub8 r4, r8, r2 + uhsub8gt r4, r8, r2 + +@ CHECK: uhsub16 r4, r8, r2 @ encoding: [0x72,0x4f,0x78,0xe6] +@ CHECK: uhsub16gt r4, r8, r2 @ encoding: [0x72,0x4f,0x78,0xc6] +@ CHECK: uhsub8 r4, r8, r2 @ encoding: [0xf2,0x4f,0x78,0xe6] +@ CHECK: uhsub8gt r4, r8, r2 @ encoding: [0xf2,0x4f,0x78,0xc6] + + +@------------------------------------------------------------------------------ +@ UMAAL +@------------------------------------------------------------------------------ + umaal r3, r4, r5, r6 + umaallt r3, r4, r5, r6 + +@ CHECK: umaal r3, r4, r5, r6 @ encoding: [0x95,0x36,0x44,0xe0] +@ CHECK: umaallt r3, r4, r5, r6 @ encoding: [0x95,0x36,0x44,0xb0] + + +@------------------------------------------------------------------------------ +@ UMLAL +@------------------------------------------------------------------------------ + umlal r2, r4, r6, r8 + umlalgt r6, r1, r2, r6 + umlals r2, r9, r2, r3 + umlalseq r3, r5, r1, r2 + +@ CHECK: umlal r2, r4, r6, r8 @ encoding: [0x96,0x28,0xa4,0xe0] +@ CHECK: umlalgt r6, r1, r2, r6 @ encoding: [0x92,0x66,0xa1,0xc0] +@ CHECK: umlals r2, r9, r2, r3 @ encoding: [0x92,0x23,0xb9,0xe0] +@ CHECK: umlalseq r3, r5, r1, r2 @ encoding: [0x91,0x32,0xb5,0x00] + + +@------------------------------------------------------------------------------ +@ UMULL +@------------------------------------------------------------------------------ + umull r2, r4, r6, r8 + umullgt r6, r1, r2, r6 + umulls r2, r9, r2, r3 + umullseq r3, r5, r1, r2 + +@ CHECK: umull r2, r4, r6, r8 @ encoding: [0x96,0x28,0x84,0xe0] +@ CHECK: umullgt r6, r1, r2, r6 @ encoding: [0x92,0x66,0x81,0xc0] +@ CHECK: umulls r2, r9, r2, r3 @ encoding: [0x92,0x23,0x99,0xe0] +@ CHECK: umullseq r3, r5, r1, r2 @ encoding: [0x91,0x32,0x95,0x00] + + +@------------------------------------------------------------------------------ +@ UQADD16/UQADD8 +@------------------------------------------------------------------------------ + uqadd16 r1, r2, r3 + uqadd16gt r4, r7, r9 + uqadd8 r3, r4, r8 + uqadd8le r8, r1, r2 + + +@ CHECK: uqadd16 r1, r2, r3 @ encoding: [0x13,0x1f,0x62,0xe6] +@ CHECK: uqadd16gt r4, r7, r9 @ encoding: [0x19,0x4f,0x67,0xc6] +@ CHECK: uqadd8 r3, r4, r8 @ encoding: [0x98,0x3f,0x64,0xe6] +@ CHECK: uqadd8le r8, r1, r2 @ encoding: [0x92,0x8f,0x61,0xd6] + + +@------------------------------------------------------------------------------ +@ UQASX +@------------------------------------------------------------------------------ + uqasx r2, r4, r1 + uqasxhi r5, r2, r9 + +@ CHECK: uqasx r2, r4, r1 @ encoding: [0x31,0x2f,0x64,0xe6] +@ CHECK: uqasxhi r5, r2, r9 @ encoding: [0x39,0x5f,0x62,0x86] + + +@------------------------------------------------------------------------------ +@ UQSAX +@------------------------------------------------------------------------------ + uqsax r1, r3, r7 + uqsaxal r3, r6, r2 + +@ CHECK: uqsax r1, r3, r7 @ encoding: [0x57,0x1f,0x63,0xe6] +@ CHECK: uqsax r3, r6, r2 @ encoding: [0x52,0x3f,0x66,0xe6] + + +@------------------------------------------------------------------------------ +@ UQSUB16/UQSUB8 +@------------------------------------------------------------------------------ + uqsub16 r1, r5, r3 + uqsub16gt r3, r2, r5 + uqsub8 r2, r1, r4 + uqsub8le r4, r6, r9 + +@ CHECK: uqsub16 r1, r5, r3 @ encoding: [0x73,0x1f,0x65,0xe6] +@ CHECK: uqsub16gt r3, r2, r5 @ encoding: [0x75,0x3f,0x62,0xc6] +@ CHECK: uqsub8 r2, r1, r4 @ encoding: [0xf4,0x2f,0x61,0xe6] +@ CHECK: uqsub8le r4, r6, r9 @ encoding: [0xf9,0x4f,0x66,0xd6] + + +@------------------------------------------------------------------------------ +@ USADA8/USAD8 +@------------------------------------------------------------------------------ + usad8 r2, r1, r4 + usad8le r4, r6, r9 + usada8 r1, r5, r3, r7 + usada8gt r3, r2, r5, r1 + +@ CHECK: usad8 r2, r1, r4 @ encoding: [0x11,0xf4,0x82,0xe7] +@ CHECK: usad8le r4, r6, r9 @ encoding: [0x16,0xf9,0x84,0xd7] +@ CHECK: usada8 r1, r5, r3, r7 @ encoding: [0x15,0x73,0x81,0xe7] +@ CHECK: usada8gt r3, r2, r5, r1 @ encoding: [0x12,0x15,0x83,0xc7] + + +@------------------------------------------------------------------------------ +@ USAT +@------------------------------------------------------------------------------ + usat r8, #1, r10 + usat r8, #4, r10, lsl #0 + usat r8, #5, r10, lsl #31 + usat r8, #31, r10, asr #32 + usat r8, #16, r10, asr #1 + +@ CHECK: usat r8, #1, r10 @ encoding: [0x1a,0x80,0xe1,0xe6] +@ CHECK: usat r8, #4, r10 @ encoding: [0x1a,0x80,0xe4,0xe6] +@ CHECK: usat r8, #5, r10, lsl #31 @ encoding: [0x9a,0x8f,0xe5,0xe6] +@ CHECK: usat r8, #31, r10, asr #32 @ encoding: [0x5a,0x80,0xff,0xe6] +@ CHECK: usat r8, #16, r10, asr #1 @ encoding: [0xda,0x80,0xf0,0xe6] + + +@------------------------------------------------------------------------------ +@ USAT16 +@------------------------------------------------------------------------------ + usat16 r2, #2, r7 + usat16 r3, #15, r5 + +@ CHECK: usat16 r2, #2, r7 @ encoding: [0x37,0x2f,0xe2,0xe6] +@ CHECK: usat16 r3, #15, r5 @ encoding: [0x35,0x3f,0xef,0xe6] + + +@------------------------------------------------------------------------------ +@ USAX +@------------------------------------------------------------------------------ + usax r2, r3, r4 + usaxne r2, r3, r4 + +@ CHECK: usax r2, r3, r4 @ encoding: [0x54,0x2f,0x53,0xe6] +@ CHECK: usaxne r2, r3, r4 @ encoding: [0x54,0x2f,0x53,0x16] + +@------------------------------------------------------------------------------ +@ USUB16/USUB8 +@------------------------------------------------------------------------------ + usub16 r4, r2, r7 + usub16hi r1, r1, r3 + usub8 r1, r8, r5 + usub8le r9, r2, r3 + +@ CHECK: usub16 r4, r2, r7 @ encoding: [0x77,0x4f,0x52,0xe6] +@ CHECK: usub16hi r1, r1, r3 @ encoding: [0x73,0x1f,0x51,0x86] +@ CHECK: usub8 r1, r8, r5 @ encoding: [0xf5,0x1f,0x58,0xe6] +@ CHECK: usub8le r9, r2, r3 @ encoding: [0xf3,0x9f,0x52,0xd6] + + +@------------------------------------------------------------------------------ +@ UXTAB +@------------------------------------------------------------------------------ + uxtab r2, r3, r4 + uxtab r4, r5, r6, ror #0 + uxtablt r6, r2, r9, ror #8 + uxtab r5, r1, r4, ror #16 + uxtab r7, r8, r3, ror #24 + +@ CHECK: uxtab r2, r3, r4 @ encoding: [0x74,0x20,0xe3,0xe6] +@ CHECK: uxtab r4, r5, r6 @ encoding: [0x76,0x40,0xe5,0xe6] +@ CHECK: uxtablt r6, r2, r9, ror #8 @ encoding: [0x79,0x64,0xe2,0xb6] +@ CHECK: uxtab r5, r1, r4, ror #16 @ encoding: [0x74,0x58,0xe1,0xe6] +@ CHECK: uxtab r7, r8, r3, ror #24 @ encoding: [0x73,0x7c,0xe8,0xe6] + + +@------------------------------------------------------------------------------ +@ UXTAB16 +@------------------------------------------------------------------------------ + uxtab16ge r0, r1, r4 + uxtab16 r6, r2, r7, ror #0 + uxtab16 r3, r5, r8, ror #8 + uxtab16 r3, r2, r1, ror #16 + uxtab16eq r1, r2, r3, ror #24 + +@ CHECK: uxtab16ge r0, r1, r4 @ encoding: [0x74,0x00,0xc1,0xa6] +@ CHECK: uxtab16 r6, r2, r7 @ encoding: [0x77,0x60,0xc2,0xe6] +@ CHECK: uxtab16 r3, r5, r8, ror #8 @ encoding: [0x78,0x34,0xc5,0xe6] +@ CHECK: uxtab16 r3, r2, r1, ror #16 @ encoding: [0x71,0x38,0xc2,0xe6] +@ CHECK: uxtab16eq r1, r2, r3, ror #24 @ encoding: [0x73,0x1c,0xc2,0x06] + + +@------------------------------------------------------------------------------ +@ UXTAH +@------------------------------------------------------------------------------ + uxtah r1, r3, r9 + uxtahhi r6, r1, r6, ror #0 + uxtah r3, r8, r3, ror #8 + uxtahlo r2, r2, r4, ror #16 + uxtah r9, r3, r3, ror #24 + +@ CHECK: uxtah r1, r3, r9 @ encoding: [0x79,0x10,0xf3,0xe6] +@ CHECK: uxtahhi r6, r1, r6 @ encoding: [0x76,0x60,0xf1,0x86] +@ CHECK: uxtah r3, r8, r3, ror #8 @ encoding: [0x73,0x34,0xf8,0xe6] +@ CHECK: uxtahlo r2, r2, r4, ror #16 @ encoding: [0x74,0x28,0xf2,0x36] +@ CHECK: uxtah r9, r3, r3, ror #24 @ encoding: [0x73,0x9c,0xf3,0xe6] + +@------------------------------------------------------------------------------ +@ UXTB +@------------------------------------------------------------------------------ + uxtbge r2, r4 + uxtb r5, r6, ror #0 + uxtb r6, r9, ror #8 + uxtbcc r5, r1, ror #16 + uxtb r8, r3, ror #24 + +@ CHECK: uxtbge r2, r4 @ encoding: [0x74,0x20,0xef,0xa6] +@ CHECK: uxtb r5, r6 @ encoding: [0x76,0x50,0xef,0xe6] +@ CHECK: uxtb r6, r9, ror #8 @ encoding: [0x79,0x64,0xef,0xe6] +@ CHECK: uxtblo r5, r1, ror #16 @ encoding: [0x71,0x58,0xef,0x36] +@ CHECK: uxtb r8, r3, ror #24 @ encoding: [0x73,0x8c,0xef,0xe6] + + +@------------------------------------------------------------------------------ +@ UXTB16 +@------------------------------------------------------------------------------ + uxtb16 r1, r4 + uxtb16 r6, r7, ror #0 + uxtb16cs r3, r5, ror #8 + uxtb16 r3, r1, ror #16 + uxtb16ge r2, r3, ror #24 + +@ CHECK: uxtb16 r1, r4 @ encoding: [0x74,0x10,0xcf,0xe6] +@ CHECK: uxtb16 r6, r7 @ encoding: [0x77,0x60,0xcf,0xe6] +@ CHECK: uxtb16hs r3, r5, ror #8 @ encoding: [0x75,0x34,0xcf,0x26] +@ CHECK: uxtb16 r3, r1, ror #16 @ encoding: [0x71,0x38,0xcf,0xe6] +@ CHECK: uxtb16ge r2, r3, ror #24 @ encoding: [0x73,0x2c,0xcf,0xa6] + + +@------------------------------------------------------------------------------ +@ UXTH +@------------------------------------------------------------------------------ + uxthne r3, r9 + uxth r1, r6, ror #0 + uxth r3, r8, ror #8 + uxthle r2, r2, ror #16 + uxth r9, r3, ror #24 + +@ CHECK: uxthne r3, r9 @ encoding: [0x79,0x30,0xff,0x16] +@ CHECK: uxth r1, r6 @ encoding: [0x76,0x10,0xff,0xe6] +@ CHECK: uxth r3, r8, ror #8 @ encoding: [0x78,0x34,0xff,0xe6] +@ CHECK: uxthle r2, r2, ror #16 @ encoding: [0x72,0x28,0xff,0xd6] +@ CHECK: uxth r9, r3, ror #24 @ encoding: [0x73,0x9c,0xff,0xe6] + + +@------------------------------------------------------------------------------ +@ WFE/WFI/YIELD +@------------------------------------------------------------------------------ + wfe + wfehi + wfi + wfilt + yield + yieldne + +@ CHECK: wfe @ encoding: [0x02,0xf0,0x20,0xe3] +@ CHECK: wfehi @ encoding: [0x02,0xf0,0x20,0x83] +@ CHECK: wfi @ encoding: [0x03,0xf0,0x20,0xe3] +@ CHECK: wfilt @ encoding: [0x03,0xf0,0x20,0xb3] +@ CHECK: yield @ encoding: [0x01,0xf0,0x20,0xe3] +@ CHECK: yieldne @ encoding: [0x01,0xf0,0x20,0x13] diff --git a/test/MC/ARM/basic-thumb-instructions.s b/test/MC/ARM/basic-thumb-instructions.s new file mode 100644 index 000000000000..0fa52b098746 --- /dev/null +++ b/test/MC/ARM/basic-thumb-instructions.s @@ -0,0 +1,623 @@ +@--- +@ Run these test in both Thumb1 and Thumb2 modes, as all of the encodings +@ should be valid, and parse the same, in both. +@--- +@ RUN: llvm-mc -triple=thumbv6-apple-darwin -show-encoding < %s | FileCheck %s +@ RUN: llvm-mc -triple=thumbv7-apple-darwin -show-encoding < %s | FileCheck %s + .syntax unified + .globl _func + +@ Check that the assembler can handle the documented syntax from the ARM ARM. +@ For complex constructs like shifter operands, check more thoroughly for them +@ once then spot check that following instructions accept the form generally. +@ This gives us good coverage while keeping the overall size of the test +@ more reasonable. + + +@ FIXME: Some 3-operand instructions have a 2-operand assembly syntax. + +_func: +@ CHECK: _func + +@------------------------------------------------------------------------------ +@ ADC (register) +@------------------------------------------------------------------------------ + adcs r4, r6 + +@ CHECK: adcs r4, r6 @ encoding: [0x74,0x41] + + +@------------------------------------------------------------------------------ +@ ADD (immediate) +@------------------------------------------------------------------------------ + adds r1, r2, #3 +@ When Rd is not explicitly specified, encoding T2 is preferred even though +@ the literal is in the range [0,7] which would allow encoding T1. + adds r2, #3 + adds r2, #8 + +@ CHECK: adds r1, r2, #3 @ encoding: [0xd1,0x1c] +@ CHECK: adds r2, #3 @ encoding: [0x03,0x32] +@ CHECK: adds r2, #8 @ encoding: [0x08,0x32] + + +@------------------------------------------------------------------------------ +@ ADD (register) +@------------------------------------------------------------------------------ + adds r1, r2, r3 + add r2, r8 + +@ CHECK: adds r1, r2, r3 @ encoding: [0xd1,0x18] +@ CHECK: add r2, r8 @ encoding: [0x42,0x44] + + +@------------------------------------------------------------------------------ +@ ADD (SP plus immediate) +@------------------------------------------------------------------------------ + add sp, #4 + add sp, #508 + add sp, sp, #4 + add r2, sp, #8 + add r2, sp, #1020 + +@ CHECK: add sp, #4 @ encoding: [0x01,0xb0] +@ CHECK: add sp, #508 @ encoding: [0x7f,0xb0] +@ CHECK: add sp, #4 @ encoding: [0x01,0xb0] +@ CHECK: add r2, sp, #8 @ encoding: [0x02,0xaa] +@ CHECK: add r2, sp, #1020 @ encoding: [0xff,0xaa] + + +@------------------------------------------------------------------------------ +@ ADD (SP plus register) +@------------------------------------------------------------------------------ + add sp, r3 + add r2, sp, r2 + +@ CHECK: add sp, r3 @ encoding: [0x9d,0x44] +@ CHECK: add r2, sp, r2 @ encoding: [0x6a,0x44] + + +@------------------------------------------------------------------------------ +@ ADR +@------------------------------------------------------------------------------ + adr r2, _baz + adr r2, #3 + +@ CHECK: adr r2, _baz @ encoding: [A,0xa2] + @ fixup A - offset: 0, value: _baz, kind: fixup_thumb_adr_pcrel_10 +@ CHECK: adr r2, #3 @ encoding: [0x03,0xa2] + +@------------------------------------------------------------------------------ +@ ASR (immediate) +@------------------------------------------------------------------------------ + asrs r2, r3, #32 + asrs r2, r3, #5 + asrs r2, r3, #1 + +@ CHECK: asrs r2, r3, #32 @ encoding: [0x1a,0x10] +@ CHECK: asrs r2, r3, #5 @ encoding: [0x5a,0x11] +@ CHECK: asrs r2, r3, #1 @ encoding: [0x5a,0x10] + + +@------------------------------------------------------------------------------ +@ ASR (register) +@------------------------------------------------------------------------------ + asrs r5, r2 + +@ CHECK: asrs r5, r2 @ encoding: [0x15,0x41] + + +@------------------------------------------------------------------------------ +@ B +@------------------------------------------------------------------------------ + b _baz + beq _bar + b #1838 + b #-420 + beq #336 + beq #160 + +@ CHECK: b _baz @ encoding: [A,0xe0'A'] + @ fixup A - offset: 0, value: _baz, kind: fixup_arm_thumb_br +@ CHECK: beq _bar @ encoding: [A,0xd0] + @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_bcc +@ CHECK: b #1838 @ encoding: [0x97,0xe3] +@ CHECK: b #-420 @ encoding: [0x2e,0xe7] +@ CHECK: beq #336 @ encoding: [0xa8,0xd0] +@ CHECK: beq #160 @ encoding: [0x50,0xd0] + +@------------------------------------------------------------------------------ +@ BL/BLX +@------------------------------------------------------------------------------ + blx #884800 + blx #1769600 + +@ CHECK: blx #884800 @ encoding: [0xd8,0xf0,0x20,0xe8] +@ CHECK: blx #1769600 @ encoding: [0xb0,0xf1,0x40,0xe8] + +@------------------------------------------------------------------------------ +@ BICS +@------------------------------------------------------------------------------ + bics r1, r6 + +@ CHECK: bics r1, r6 @ encoding: [0xb1,0x43] + + +@------------------------------------------------------------------------------ +@ BKPT +@------------------------------------------------------------------------------ + bkpt #0 + bkpt #255 + +@ CHECK: bkpt #0 @ encoding: [0x00,0xbe] +@ CHECK: bkpt #255 @ encoding: [0xff,0xbe] + + +@------------------------------------------------------------------------------ +@ BL/BLX (immediate) +@------------------------------------------------------------------------------ + bl _bar + blx _baz + +@ CHECK: bl _bar @ encoding: [A,0xf0'A',A,0xf8'A'] + @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_bl +@ CHECK: blx _baz @ encoding: [A,0xf0'A',A,0xe8'A'] + @ fixup A - offset: 0, value: _baz, kind: fixup_arm_thumb_blx + + +@------------------------------------------------------------------------------ +@ BLX (register) +@------------------------------------------------------------------------------ + blx r4 + +@ CHECK: blx r4 @ encoding: [0xa0,0x47] + + +@------------------------------------------------------------------------------ +@ BX +@------------------------------------------------------------------------------ + bx r2 + +@ CHECK: bx r2 @ encoding: [0x10,0x47] + + +@------------------------------------------------------------------------------ +@ CMN +@------------------------------------------------------------------------------ + + cmn r5, r1 + +@ CHECK: cmn r5, r1 @ encoding: [0xcd,0x42] + + +@------------------------------------------------------------------------------ +@ CMP +@------------------------------------------------------------------------------ + cmp r6, #32 + cmp r3, r4 + cmp r8, r1 + +@ CHECK: cmp r6, #32 @ encoding: [0x20,0x2e] +@ CHECK: cmp r3, r4 @ encoding: [0xa3,0x42] +@ CHECK: cmp r8, r1 @ encoding: [0x88,0x45] + +@------------------------------------------------------------------------------ +@ EOR +@------------------------------------------------------------------------------ + eors r4, r5 + +@ CHECK: eors r4, r5 @ encoding: [0x6c,0x40] + + +@------------------------------------------------------------------------------ +@ LDM +@------------------------------------------------------------------------------ + ldm r3, {r0, r1, r2, r3, r4, r5, r6, r7} + ldm r2!, {r1, r3, r4, r5, r7} + ldm r1, {r1} + +@ CHECK: ldm r3, {r0, r1, r2, r3, r4, r5, r6, r7} @ encoding: [0xff,0xcb] +@ CHECK: ldm r2!, {r1, r3, r4, r5, r7} @ encoding: [0xba,0xca] +@ CHECK: ldm r1, {r1} @ encoding: [0x02,0xc9] + + +@------------------------------------------------------------------------------ +@ LDR (immediate) +@------------------------------------------------------------------------------ + ldr r1, [r5] + ldr r2, [r6, #32] + ldr r3, [r7, #124] + ldr r1, [sp] + ldr r2, [sp, #24] + ldr r3, [sp, #1020] + + +@ CHECK: ldr r1, [r5] @ encoding: [0x29,0x68] +@ CHECK: ldr r2, [r6, #32] @ encoding: [0x32,0x6a] +@ CHECK: ldr r3, [r7, #124] @ encoding: [0xfb,0x6f] +@ CHECK: ldr r1, [sp] @ encoding: [0x00,0x99] +@ CHECK: ldr r2, [sp, #24] @ encoding: [0x06,0x9a] +@ CHECK: ldr r3, [sp, #1020] @ encoding: [0xff,0x9b] + + +@------------------------------------------------------------------------------ +@ LDR (literal) +@------------------------------------------------------------------------------ + ldr r1, _foo + ldr r3, #604 + ldr r3, #368 + +@ CHECK: ldr r1, _foo @ encoding: [A,0x49] + @ fixup A - offset: 0, value: _foo, kind: fixup_arm_thumb_cp +@ CHECK: ldr r3, #604 @ encoding: [0x97,0x4b] +@ CHECK: ldr r3, #368 @ encoding: [0x5c,0x4b] + +@------------------------------------------------------------------------------ +@ LDR (register) +@------------------------------------------------------------------------------ + ldr r1, [r2, r3] + +@ CHECK: ldr r1, [r2, r3] @ encoding: [0xd1,0x58] + + +@------------------------------------------------------------------------------ +@ LDRB (immediate) +@------------------------------------------------------------------------------ + ldrb r4, [r3] + ldrb r5, [r6, #0] + ldrb r6, [r7, #31] + +@ CHECK: ldrb r4, [r3] @ encoding: [0x1c,0x78] +@ CHECK: ldrb r5, [r6] @ encoding: [0x35,0x78] +@ CHECK: ldrb r6, [r7, #31] @ encoding: [0xfe,0x7f] + + +@------------------------------------------------------------------------------ +@ LDRB (register) +@------------------------------------------------------------------------------ + ldrb r6, [r4, r5] + +@ CHECK: ldrb r6, [r4, r5] @ encoding: [0x66,0x5d] + + +@------------------------------------------------------------------------------ +@ LDRH (immediate) +@------------------------------------------------------------------------------ + ldrh r3, [r3] + ldrh r4, [r6, #2] + ldrh r5, [r7, #62] + +@ CHECK: ldrh r3, [r3] @ encoding: [0x1b,0x88] +@ CHECK: ldrh r4, [r6, #2] @ encoding: [0x74,0x88] +@ CHECK: ldrh r5, [r7, #62] @ encoding: [0xfd,0x8f] + + +@------------------------------------------------------------------------------ +@ LDRH (register) +@------------------------------------------------------------------------------ + ldrh r6, [r2, r6] + +@ CHECK: ldrh r6, [r2, r6] @ encoding: [0x96,0x5b] + + +@------------------------------------------------------------------------------ +@ LDRSB/LDRSH +@------------------------------------------------------------------------------ + ldrsb r6, [r2, r6] + ldrsh r3, [r7, r1] + +@ CHECK: ldrsb r6, [r2, r6] @ encoding: [0x96,0x57] +@ CHECK: ldrsh r3, [r7, r1] @ encoding: [0x7b,0x5e] + + +@------------------------------------------------------------------------------ +@ LSL (immediate) +@------------------------------------------------------------------------------ + lsls r4, r5, #0 + lsls r4, r5, #4 + +@ CHECK: lsls r4, r5, #0 @ encoding: [0x2c,0x00] +@ CHECK: lsls r4, r5, #4 @ encoding: [0x2c,0x01] + + +@------------------------------------------------------------------------------ +@ LSL (register) +@------------------------------------------------------------------------------ + lsls r2, r6 + +@ CHECK: lsls r2, r6 @ encoding: [0xb2,0x40] + + +@------------------------------------------------------------------------------ +@ LSR (immediate) +@------------------------------------------------------------------------------ + lsrs r1, r3, #1 + lsrs r1, r3, #32 + +@ CHECK: lsrs r1, r3, #1 @ encoding: [0x59,0x08] +@ CHECK: lsrs r1, r3, #32 @ encoding: [0x19,0x08] + + +@------------------------------------------------------------------------------ +@ LSR (register) +@------------------------------------------------------------------------------ + lsrs r2, r6 + +@ CHECK: lsrs r2, r6 @ encoding: [0xf2,0x40] + + +@------------------------------------------------------------------------------ +@ MOV (immediate) +@------------------------------------------------------------------------------ + movs r2, #0 + movs r2, #255 + movs r2, #23 + +@ CHECK: movs r2, #0 @ encoding: [0x00,0x22] +@ CHECK: movs r2, #255 @ encoding: [0xff,0x22] +@ CHECK: movs r2, #23 @ encoding: [0x17,0x22] + + +@------------------------------------------------------------------------------ +@ MOV (register) +@------------------------------------------------------------------------------ + mov r3, r4 + movs r1, r3 + +@ CHECK: mov r3, r4 @ encoding: [0x23,0x46] +@ CHECK: movs r1, r3 @ encoding: [0x19,0x00] + + +@------------------------------------------------------------------------------ +@ MUL +@------------------------------------------------------------------------------ + muls r1, r2, r1 + muls r3, r4 + +@ CHECK: muls r1, r2, r1 @ encoding: [0x51,0x43] +@ CHECK: muls r3, r4, r3 @ encoding: [0x63,0x43] + + +@------------------------------------------------------------------------------ +@ MVN +@------------------------------------------------------------------------------ + mvns r6, r3 + +@ CHECK: mvns r6, r3 @ encoding: [0xde,0x43] + + +@------------------------------------------------------------------------------ +@ NEG +@------------------------------------------------------------------------------ + negs r3, r4 + +@ CHECK: rsbs r3, r4, #0 @ encoding: [0x63,0x42] + +@------------------------------------------------------------------------------ +@ ORR +@------------------------------------------------------------------------------ + orrs r3, r4 + +@ CHECK-ERRORS: orrs r3, r4 @ encoding: [0x23,0x43] + + +@------------------------------------------------------------------------------ +@ POP +@------------------------------------------------------------------------------ + pop {r2, r3, r6} + +@ CHECK: pop {r2, r3, r6} @ encoding: [0x4c,0xbc] + + +@------------------------------------------------------------------------------ +@ PUSH +@------------------------------------------------------------------------------ + push {r1, r2, r7} + +@ CHECK: push {r1, r2, r7} @ encoding: [0x86,0xb4] + + +@------------------------------------------------------------------------------ +@ REV/REV16/REVSH +@------------------------------------------------------------------------------ + rev r6, r3 + rev16 r7, r2 + revsh r5, r1 + +@ CHECK: rev r6, r3 @ encoding: [0x1e,0xba] +@ CHECK: rev16 r7, r2 @ encoding: [0x57,0xba] +@ CHECK: revsh r5, r1 @ encoding: [0xcd,0xba] + + +@------------------------------------------------------------------------------ +@ ROR +@------------------------------------------------------------------------------ + rors r2, r7 + +@ CHECK: rors r2, r7 @ encoding: [0xfa,0x41] + + +@------------------------------------------------------------------------------ +@ RSB +@------------------------------------------------------------------------------ + rsbs r1, r3, #0 + +@ CHECK: rsbs r1, r3, #0 @ encoding: [0x59,0x42] + + +@------------------------------------------------------------------------------ +@ SBC +@------------------------------------------------------------------------------ + sbcs r4, r3 + +@ CHECK: sbcs r4, r3 @ encoding: [0x9c,0x41] + + +@------------------------------------------------------------------------------ +@ SETEND +@------------------------------------------------------------------------------ + setend be + setend le + +@ CHECK: setend be @ encoding: [0x58,0xb6] +@ CHECK: setend le @ encoding: [0x50,0xb6] + + +@------------------------------------------------------------------------------ +@ STM +@------------------------------------------------------------------------------ + stm r1!, {r2, r6} + stm r1!, {r1, r2, r3, r7} + +@ CHECK: stm r1!, {r2, r6} @ encoding: [0x44,0xc1] +@ CHECK: stm r1!, {r1, r2, r3, r7} @ encoding: [0x8e,0xc1] + + +@------------------------------------------------------------------------------ +@ STR (immediate) +@------------------------------------------------------------------------------ + str r2, [r7] + str r2, [r7, #0] + str r5, [r1, #4] + str r3, [r7, #124] + str r2, [sp] + str r3, [sp, #0] + str r4, [sp, #20] + str r5, [sp, #1020] + +@ CHECK: str r2, [r7] @ encoding: [0x3a,0x60] +@ CHECK: str r2, [r7] @ encoding: [0x3a,0x60] +@ CHECK: str r5, [r1, #4] @ encoding: [0x4d,0x60] +@ CHECK: str r3, [r7, #124] @ encoding: [0xfb,0x67] +@ CHECK: str r2, [sp] @ encoding: [0x00,0x92] +@ CHECK: str r3, [sp] @ encoding: [0x00,0x93] +@ CHECK: str r4, [sp, #20] @ encoding: [0x05,0x94] +@ CHECK: str r5, [sp, #1020] @ encoding: [0xff,0x95] + + +@------------------------------------------------------------------------------ +@ STR (register) +@------------------------------------------------------------------------------ + str r2, [r7, r3] + +@ CHECK: str r2, [r7, r3] @ encoding: [0xfa,0x50] + + +@------------------------------------------------------------------------------ +@ STRB (immediate) +@------------------------------------------------------------------------------ + strb r4, [r3] + strb r5, [r6, #0] + strb r6, [r7, #31] + +@ CHECK: strb r4, [r3] @ encoding: [0x1c,0x70] +@ CHECK: strb r5, [r6] @ encoding: [0x35,0x70] +@ CHECK: strb r6, [r7, #31] @ encoding: [0xfe,0x77] + + +@------------------------------------------------------------------------------ +@ STRB (register) +@------------------------------------------------------------------------------ + strb r6, [r4, r5] + +@ CHECK: strb r6, [r4, r5] @ encoding: [0x66,0x55] + + +@------------------------------------------------------------------------------ +@ STRH (immediate) +@------------------------------------------------------------------------------ + strh r3, [r3] + strh r4, [r6, #2] + strh r5, [r7, #62] + +@ CHECK: strh r3, [r3] @ encoding: [0x1b,0x80] +@ CHECK: strh r4, [r6, #2] @ encoding: [0x74,0x80] +@ CHECK: strh r5, [r7, #62] @ encoding: [0xfd,0x87] + + +@------------------------------------------------------------------------------ +@ STRH (register) +@------------------------------------------------------------------------------ + strh r6, [r2, r6] + +@ CHECK: strh r6, [r2, r6] @ encoding: [0x96,0x53] + + +@------------------------------------------------------------------------------ +@ SUB (immediate) +@------------------------------------------------------------------------------ + subs r1, r2, #3 + subs r2, #3 + subs r2, #8 + +@ CHECK: subs r1, r2, #3 @ encoding: [0xd1,0x1e] +@ CHECK: subs r2, #3 @ encoding: [0x03,0x3a] +@ CHECK: subs r2, #8 @ encoding: [0x08,0x3a] + + +@------------------------------------------------------------------------------ +@ SUB (SP minus immediate) +@------------------------------------------------------------------------------ + sub sp, #12 + sub sp, sp, #508 + +@ CHECK: sub sp, #12 @ encoding: [0x83,0xb0] +@ CHECK: sub sp, #508 @ encoding: [0xff,0xb0] + + +@------------------------------------------------------------------------------ +@ SUB (register) +@------------------------------------------------------------------------------ + subs r1, r2, r3 + +@ CHECK: subs r1, r2, r3 @ encoding: [0xd1,0x1a] + + +@------------------------------------------------------------------------------ +@ SVC +@------------------------------------------------------------------------------ + svc #0 + svc #255 + +@ CHECK: svc #0 @ encoding: [0x00,0xdf] +@ CHECK: svc #255 @ encoding: [0xff,0xdf] + + +@------------------------------------------------------------------------------ +@ SXTB/SXTH +@------------------------------------------------------------------------------ + sxtb r3, r5 + sxth r3, r5 + +@ CHECK: sxtb r3, r5 @ encoding: [0x6b,0xb2] +@ CHECK: sxth r3, r5 @ encoding: [0x2b,0xb2] + + +@------------------------------------------------------------------------------ +@ TST +@------------------------------------------------------------------------------ + tst r6, r1 + +@ CHECK: tst r6, r1 @ encoding: [0x0e,0x42] + + +@------------------------------------------------------------------------------ +@ UXTB/UXTH +@------------------------------------------------------------------------------ + uxtb r7, r2 + uxth r1, r4 + +@ CHECK: uxtb r7, r2 @ encoding: [0xd7,0xb2] +@ CHECK: uxth r1, r4 @ encoding: [0xa1,0xb2] + + +@------------------------------------------------------------------------------ +@ WFE/WFI/YIELD +@------------------------------------------------------------------------------ + wfe + wfi + yield + +@ CHECK: wfe @ encoding: [0x20,0xbf] +@ CHECK: wfi @ encoding: [0x30,0xbf] +@ CHECK: yield @ encoding: [0x10,0xbf] diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s new file mode 100644 index 000000000000..68815dab016f --- /dev/null +++ b/test/MC/ARM/basic-thumb2-instructions.s @@ -0,0 +1,3213 @@ +@ RUN: llvm-mc -triple=thumbv7-apple-darwin -show-encoding < %s | FileCheck %s + .syntax unified + .globl _func + +@ Check that the assembler can handle the documented syntax from the ARM ARM. +@ For complex constructs like shifter operands, check more thoroughly for them +@ once then spot check that following instructions accept the form generally. +@ This gives us good coverage while keeping the overall size of the test +@ more reasonable. + + +@ FIXME: Some 3-operand instructions have a 2-operand assembly syntax. + +_func: +@ CHECK: _func + +@------------------------------------------------------------------------------ +@ ADC (immediate) +@------------------------------------------------------------------------------ + adc r0, r1, #4 + adcs r0, r1, #0 + adc r1, r2, #255 + adc r3, r7, #0x00550055 + adc r8, r12, #0xaa00aa00 + adc r9, r7, #0xa5a5a5a5 + adc r5, r3, #0x87000000 + adc r4, r2, #0x7f800000 + adc r4, r2, #0x00000680 + +@ CHECK: adc r0, r1, #4 @ encoding: [0x41,0xf1,0x04,0x00] +@ CHECK: adcs r0, r1, #0 @ encoding: [0x51,0xf1,0x00,0x00] +@ CHECK: adc r1, r2, #255 @ encoding: [0x42,0xf1,0xff,0x01] +@ CHECK: adc r3, r7, #5570645 @ encoding: [0x47,0xf1,0x55,0x13] +@ CHECK: adc r8, r12, #2852170240 @ encoding: [0x4c,0xf1,0xaa,0x28] +@ CHECK: adc r9, r7, #2779096485 @ encoding: [0x47,0xf1,0xa5,0x39] +@ CHECK: adc r5, r3, #2264924160 @ encoding: [0x43,0xf1,0x07,0x45] +@ CHECK: adc r4, r2, #2139095040 @ encoding: [0x42,0xf1,0xff,0x44] +@ CHECK: adc r4, r2, #1664 @ encoding: [0x42,0xf5,0xd0,0x64] + +@------------------------------------------------------------------------------ +@ ADC (register) +@------------------------------------------------------------------------------ + adc r4, r5, r6 + adcs r4, r5, r6 + adc.w r9, r1, r3 + adcs.w r9, r1, r3 + adc r0, r1, r3, ror #4 + adcs r0, r1, r3, lsl #7 + adc.w r0, r1, r3, lsr #31 + adcs.w r0, r1, r3, asr #32 + +@ CHECK: adc.w r4, r5, r6 @ encoding: [0x45,0xeb,0x06,0x04] +@ CHECK: adcs.w r4, r5, r6 @ encoding: [0x55,0xeb,0x06,0x04] +@ CHECK: adc.w r9, r1, r3 @ encoding: [0x41,0xeb,0x03,0x09] +@ CHECK: adcs.w r9, r1, r3 @ encoding: [0x51,0xeb,0x03,0x09] +@ CHECK: adc.w r0, r1, r3, ror #4 @ encoding: [0x41,0xeb,0x33,0x10] +@ CHECK: adcs.w r0, r1, r3, lsl #7 @ encoding: [0x51,0xeb,0xc3,0x10] +@ CHECK: adc.w r0, r1, r3, lsr #31 @ encoding: [0x41,0xeb,0xd3,0x70] +@ CHECK: adcs.w r0, r1, r3, asr #32 @ encoding: [0x51,0xeb,0x23,0x00] + + +@------------------------------------------------------------------------------ +@ ADD (immediate) +@------------------------------------------------------------------------------ + itet eq + addeq r1, r2, #4 + addwne r5, r3, #1023 + addeq r4, r5, #293 + add r2, sp, #1024 + add r2, r8, #0xff00 + add r2, r3, #257 + addw r2, r3, #257 + add r12, r6, #0x100 + addw r12, r6, #0x100 + adds r1, r2, #0x1f0 + +@ CHECK: itet eq @ encoding: [0x0a,0xbf] +@ CHECK: addeq r1, r2, #4 @ encoding: [0x11,0x1d] +@ CHECK: addwne r5, r3, #1023 @ encoding: [0x03,0xf2,0xff,0x35] +@ CHECK: addweq r4, r5, #293 @ encoding: [0x05,0xf2,0x25,0x14] +@ CHECK: add.w r2, sp, #1024 @ encoding: [0x0d,0xf5,0x80,0x62] +@ CHECK: add.w r2, r8, #65280 @ encoding: [0x08,0xf5,0x7f,0x42] +@ CHECK: addw r2, r3, #257 @ encoding: [0x03,0xf2,0x01,0x12] +@ CHECK: addw r2, r3, #257 @ encoding: [0x03,0xf2,0x01,0x12] +@ CHECK: add.w r12, r6, #256 @ encoding: [0x06,0xf5,0x80,0x7c] +@ CHECK: addw r12, r6, #256 @ encoding: [0x06,0xf2,0x00,0x1c] +@ CHECK: adds.w r1, r2, #496 @ encoding: [0x12,0xf5,0xf8,0x71] + + +@------------------------------------------------------------------------------ +@ ADD (register) +@------------------------------------------------------------------------------ + add r1, r2, r8 + add r5, r9, r2, asr #32 + adds r7, r3, r1, lsl #31 + adds.w r0, r3, r6, lsr #25 + add.w r4, r8, r1, ror #12 + +@ CHECK: add.w r1, r2, r8 @ encoding: [0x02,0xeb,0x08,0x01] +@ CHECK: add.w r5, r9, r2, asr #32 @ encoding: [0x09,0xeb,0x22,0x05] +@ CHECK: adds.w r7, r3, r1, lsl #31 @ encoding: [0x13,0xeb,0xc1,0x77] +@ CHECK: adds.w r0, r3, r6, lsr #25 @ encoding: [0x13,0xeb,0x56,0x60] +@ CHECK: add.w r4, r8, r1, ror #12 @ encoding: [0x08,0xeb,0x31,0x34] + + +@------------------------------------------------------------------------------ +@ FIXME: ADR +@------------------------------------------------------------------------------ + + subw r11, pc, #3270 + adr.w r11, #-826 + +@ CHECK: subw r11, pc, #3270 @ encoding: [0xaf,0xf6,0xc6,0x4b] +@ CHECK: adr.w r11, #-826 @ encoding: [0xaf,0xf2,0x3a,0x3b] + +@------------------------------------------------------------------------------ +@ AND (immediate) +@------------------------------------------------------------------------------ + and r2, r5, #0xff000 + ands r3, r12, #0xf + and r1, #0xff + and r1, r1, #0xff + +@ CHECK: and r2, r5, #1044480 @ encoding: [0x05,0xf4,0x7f,0x22] +@ CHECK: ands r3, r12, #15 @ encoding: [0x1c,0xf0,0x0f,0x03] +@ CHECK: and r1, r1, #255 @ encoding: [0x01,0xf0,0xff,0x01] +@ CHECK: and r1, r1, #255 @ encoding: [0x01,0xf0,0xff,0x01] + + +@------------------------------------------------------------------------------ +@ AND (register) +@------------------------------------------------------------------------------ + and r4, r9, r8 + and r1, r4, r8, asr #3 + ands r2, r1, r7, lsl #1 + ands.w r4, r5, r2, lsr #20 + and.w r9, r12, r1, ror #17 + +@ CHECK: and.w r4, r9, r8 @ encoding: [0x09,0xea,0x08,0x04] +@ CHECK: and.w r1, r4, r8, asr #3 @ encoding: [0x04,0xea,0xe8,0x01] +@ CHECK: ands.w r2, r1, r7, lsl #1 @ encoding: [0x11,0xea,0x47,0x02] +@ CHECK: ands.w r4, r5, r2, lsr #20 @ encoding: [0x15,0xea,0x12,0x54] +@ CHECK: and.w r9, r12, r1, ror #17 @ encoding: [0x0c,0xea,0x71,0x49] + +@------------------------------------------------------------------------------ +@ ASR (immediate) +@------------------------------------------------------------------------------ + asr r2, r3, #12 + asrs r8, r3, #32 + asrs.w r2, r3, #1 + asr r2, r3, #4 + asrs r2, r12, #15 + + asr r3, #19 + asrs r8, #2 + asrs.w r7, #5 + asr.w r12, #21 + +@ CHECK: asr.w r2, r3, #12 @ encoding: [0x4f,0xea,0x23,0x32] +@ CHECK: asrs.w r8, r3, #32 @ encoding: [0x5f,0xea,0x23,0x08] +@ CHECK: asrs.w r2, r3, #1 @ encoding: [0x5f,0xea,0x63,0x02] +@ CHECK: asr.w r2, r3, #4 @ encoding: [0x4f,0xea,0x23,0x12] +@ CHECK: asrs.w r2, r12, #15 @ encoding: [0x5f,0xea,0xec,0x32] + +@ CHECK: asr.w r3, r3, #19 @ encoding: [0x4f,0xea,0xe3,0x43] +@ CHECK: asrs.w r8, r8, #2 @ encoding: [0x5f,0xea,0xa8,0x08] +@ CHECK: asrs.w r7, r7, #5 @ encoding: [0x5f,0xea,0x67,0x17] +@ CHECK: asr.w r12, r12, #21 @ encoding: [0x4f,0xea,0x6c,0x5c] + + +@------------------------------------------------------------------------------ +@ ASR (register) +@------------------------------------------------------------------------------ + asr r3, r4, r2 + asr.w r1, r2 + asrs r3, r4, r8 + +@ CHECK: asr.w r3, r4, r2 @ encoding: [0x44,0xfa,0x02,0xf3] +@ CHECK: asr.w r1, r1, r2 @ encoding: [0x41,0xfa,0x02,0xf1] +@ CHECK: asrs.w r3, r4, r8 @ encoding: [0x54,0xfa,0x08,0xf3] + + +@------------------------------------------------------------------------------ +@ B +@------------------------------------------------------------------------------ + b.w _bar + beq.w _bar + it eq + beq.w _bar + bmi.w #-183396 + +@ CHECK: b.w _bar @ encoding: [A,0xf0'A',A,0x90'A'] + @ fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch +@ CHECK: beq.w _bar @ encoding: [A,0xf0'A',A,0x80'A'] + @ fixup A - offset: 0, value: _bar, kind: fixup_t2_condbranch +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: beq.w _bar @ encoding: [A,0xf0'A',A,0x90'A'] + @ fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch +@ CHECK: bmi.w #-183396 @ encoding: [0x13,0xf5,0xce,0xa9] + + +@------------------------------------------------------------------------------ +@ BFC +@------------------------------------------------------------------------------ + bfc r5, #3, #17 + it lo + bfccc r5, #3, #17 + +@ CHECK: bfc r5, #3, #17 @ encoding: [0x6f,0xf3,0xd3,0x05] +@ CHECK: it lo @ encoding: [0x38,0xbf] +@ CHECK: bfclo r5, #3, #17 @ encoding: [0x6f,0xf3,0xd3,0x05] + + +@------------------------------------------------------------------------------ +@ BFI +@------------------------------------------------------------------------------ + bfi r5, r2, #3, #17 + it ne + bfine r5, r2, #3, #17 + +@ CHECK: bfi r5, r2, #3, #17 @ encoding: [0x62,0xf3,0xd3,0x05] +@ CHECK: it ne @ encoding: [0x18,0xbf] +@ CHECK: bfine r5, r2, #3, #17 @ encoding: [0x62,0xf3,0xd3,0x05] + + +@------------------------------------------------------------------------------ +@ BIC +@------------------------------------------------------------------------------ + bic r10, r1, #0xf + bic r12, r3, r6 + bic r11, r2, r6, lsl #12 + bic r8, r4, r1, lsr #11 + bic r7, r5, r7, lsr #15 + bic r6, r7, r9, asr #32 + bic r5, r6, r8, ror #1 + + @ destination register is optional + bic r1, #0xf + bic r1, r1 + bic r4, r2, lsl #31 + bic r6, r3, lsr #12 + bic r7, r4, lsr #7 + bic r8, r5, asr #15 + bic r12, r6, ror #29 + +@ CHECK: bic r10, r1, #15 @ encoding: [0x21,0xf0,0x0f,0x0a] +@ CHECK: bic.w r12, r3, r6 @ encoding: [0x23,0xea,0x06,0x0c] +@ CHECK: bic.w r11, r2, r6, lsl #12 @ encoding: [0x22,0xea,0x06,0x3b] +@ CHECK: bic.w r8, r4, r1, lsr #11 @ encoding: [0x24,0xea,0xd1,0x28] +@ CHECK: bic.w r7, r5, r7, lsr #15 @ encoding: [0x25,0xea,0xd7,0x37] +@ CHECK: bic.w r6, r7, r9, asr #32 @ encoding: [0x27,0xea,0x29,0x06] +@ CHECK: bic.w r5, r6, r8, ror #1 @ encoding: [0x26,0xea,0x78,0x05] + +@ CHECK: bic r1, r1, #15 @ encoding: [0x21,0xf0,0x0f,0x01] +@ CHECK: bic.w r1, r1, r1 @ encoding: [0x21,0xea,0x01,0x01] +@ CHECK: bic.w r4, r4, r2, lsl #31 @ encoding: [0x24,0xea,0xc2,0x74] +@ CHECK: bic.w r6, r6, r3, lsr #12 @ encoding: [0x26,0xea,0x13,0x36] +@ CHECK: bic.w r7, r7, r4, lsr #7 @ encoding: [0x27,0xea,0xd4,0x17] +@ CHECK: bic.w r8, r8, r5, asr #15 @ encoding: [0x28,0xea,0xe5,0x38] +@ CHECK: bic.w r12, r12, r6, ror #29 @ encoding: [0x2c,0xea,0x76,0x7c] + +@------------------------------------------------------------------------------ +@ BKPT +@------------------------------------------------------------------------------ + it pl + bkpt #234 + +@ CHECK: it pl @ encoding: [0x58,0xbf] +@ CHECK: bkpt #234 @ encoding: [0xea,0xbe] + +@------------------------------------------------------------------------------ +@ BXJ +@------------------------------------------------------------------------------ + bxj r5 + it ne + bxjne r7 + +@ CHECK: bxj r5 @ encoding: [0xc5,0xf3,0x00,0x8f] +@ CHECK: it ne @ encoding: [0x18,0xbf] +@ CHECK: bxjne r7 @ encoding: [0xc7,0xf3,0x00,0x8f] + + +@------------------------------------------------------------------------------ +@ CBZ/CBNZ +@------------------------------------------------------------------------------ + cbnz r7, #6 + cbnz r7, #12 + cbz r6, _bar + cbnz r6, _bar + +@ CHECK: cbnz r7, #6 @ encoding: [0x1f,0xb9] +@ CHECK: cbnz r7, #12 @ encoding: [0x37,0xb9] +@ CHECK: cbz r6, _bar @ encoding: [0x06'A',0xb1'A'] + @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_cb +@ CHECK: cbnz r6, _bar @ encoding: [0x06'A',0xb9'A'] + @ fixup A - offset: 0, value: _bar, kind: fixup_arm_thumb_cb + + +@------------------------------------------------------------------------------ +@ CDP/CDP2 +@------------------------------------------------------------------------------ + cdp p7, #1, c1, c1, c1, #4 + cdp2 p7, #1, c1, c1, c1, #4 + +@ CHECK: cdp p7, #1, c1, c1, c1, #4 @ encoding: [0x11,0xee,0x81,0x17] +@ CHECK: cdp2 p7, #1, c1, c1, c1, #4 @ encoding: [0x11,0xfe,0x81,0x17] + + +@------------------------------------------------------------------------------ +@ CLREX +@------------------------------------------------------------------------------ + clrex + it ne + clrexne + +@ CHECK: clrex @ encoding: [0xbf,0xf3,0x2f,0x8f] +@ CHECK: it ne @ encoding: [0x18,0xbf] +@ CHECK: clrexne @ encoding: [0xbf,0xf3,0x2f,0x8f] + + +@------------------------------------------------------------------------------ +@ CLZ +@------------------------------------------------------------------------------ + clz r1, r2 + it eq + clzeq r1, r2 + +@ CHECK: clz r1, r2 @ encoding: [0xb2,0xfa,0x82,0xf1] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: clzeq r1, r2 @ encoding: [0xb2,0xfa,0x82,0xf1] + + +@------------------------------------------------------------------------------ +@ CMN +@------------------------------------------------------------------------------ + cmn r1, #0xf + cmn r8, r6 + cmn r1, r6, lsl #10 + cmn r1, r6, lsr #10 + cmn sp, r6, lsr #10 + cmn r1, r6, asr #10 + cmn r1, r6, ror #10 + +@ CHECK: cmn.w r1, #15 @ encoding: [0x11,0xf1,0x0f,0x0f] +@ CHECK: cmn.w r8, r6 @ encoding: [0x18,0xeb,0x06,0x0f] +@ CHECK: cmn.w r1, r6, lsl #10 @ encoding: [0x11,0xeb,0x86,0x2f] +@ CHECK: cmn.w r1, r6, lsr #10 @ encoding: [0x11,0xeb,0x96,0x2f] +@ CHECK: cmn.w sp, r6, lsr #10 @ encoding: [0x1d,0xeb,0x96,0x2f] +@ CHECK: cmn.w r1, r6, asr #10 @ encoding: [0x11,0xeb,0xa6,0x2f] +@ CHECK: cmn.w r1, r6, ror #10 @ encoding: [0x11,0xeb,0xb6,0x2f] + + +@------------------------------------------------------------------------------ +@ CMP +@------------------------------------------------------------------------------ + cmp r5, #0xff00 + cmp.w r4, r12 + cmp r9, r6, lsl #12 + cmp r3, r7, lsr #31 + cmp sp, r6, lsr #1 + cmp r2, r5, asr #24 + cmp r1, r4, ror #15 + +@ CHECK: cmp.w r5, #65280 @ encoding: [0xb5,0xf5,0x7f,0x4f] +@ CHECK: cmp.w r4, r12 @ encoding: [0xb4,0xeb,0x0c,0x0f] +@ CHECK: cmp.w r9, r6, lsl #12 @ encoding: [0xb9,0xeb,0x06,0x3f] +@ CHECK: cmp.w r3, r7, lsr #31 @ encoding: [0xb3,0xeb,0xd7,0x7f] +@ CHECK: cmp.w sp, r6, lsr #1 @ encoding: [0xbd,0xeb,0x56,0x0f] +@ CHECK: cmp.w r2, r5, asr #24 @ encoding: [0xb2,0xeb,0x25,0x6f] +@ CHECK: cmp.w r1, r4, ror #15 @ encoding: [0xb1,0xeb,0xf4,0x3f] + + +@------------------------------------------------------------------------------ +@ DBG +@------------------------------------------------------------------------------ + dbg #5 + dbg #0 + dbg #15 + +@ CHECK: dbg #5 @ encoding: [0xaf,0xf3,0xf5,0x80] +@ CHECK: dbg #0 @ encoding: [0xaf,0xf3,0xf0,0x80] +@ CHECK: dbg #15 @ encoding: [0xaf,0xf3,0xff,0x80] + + +@------------------------------------------------------------------------------ +@ DMB +@------------------------------------------------------------------------------ + dmb sy + dmb st + dmb sh + dmb ish + dmb shst + dmb ishst + dmb un + dmb nsh + dmb unst + dmb nshst + dmb osh + dmb oshst + dmb + +@ CHECK: dmb sy @ encoding: [0xbf,0xf3,0x5f,0x8f] +@ CHECK: dmb st @ encoding: [0xbf,0xf3,0x5e,0x8f] +@ CHECK: dmb ish @ encoding: [0xbf,0xf3,0x5b,0x8f] +@ CHECK: dmb ish @ encoding: [0xbf,0xf3,0x5b,0x8f] +@ CHECK: dmb ishst @ encoding: [0xbf,0xf3,0x5a,0x8f] +@ CHECK: dmb ishst @ encoding: [0xbf,0xf3,0x5a,0x8f] +@ CHECK: dmb nsh @ encoding: [0xbf,0xf3,0x57,0x8f] +@ CHECK: dmb nsh @ encoding: [0xbf,0xf3,0x57,0x8f] +@ CHECK: dmb nshst @ encoding: [0xbf,0xf3,0x56,0x8f] +@ CHECK: dmb nshst @ encoding: [0xbf,0xf3,0x56,0x8f] +@ CHECK: dmb osh @ encoding: [0xbf,0xf3,0x53,0x8f] +@ CHECK: dmb oshst @ encoding: [0xbf,0xf3,0x52,0x8f] +@ CHECK: dmb sy @ encoding: [0xbf,0xf3,0x5f,0x8f] + + +@------------------------------------------------------------------------------ +@ DSB +@------------------------------------------------------------------------------ + dsb sy + dsb st + dsb sh + dsb ish + dsb shst + dsb ishst + dsb un + dsb nsh + dsb unst + dsb nshst + dsb osh + dsb oshst + dsb + +@ CHECK: dsb sy @ encoding: [0xbf,0xf3,0x4f,0x8f] +@ CHECK: dsb st @ encoding: [0xbf,0xf3,0x4e,0x8f] +@ CHECK: dsb ish @ encoding: [0xbf,0xf3,0x4b,0x8f] +@ CHECK: dsb ish @ encoding: [0xbf,0xf3,0x4b,0x8f] +@ CHECK: dsb ishst @ encoding: [0xbf,0xf3,0x4a,0x8f] +@ CHECK: dsb ishst @ encoding: [0xbf,0xf3,0x4a,0x8f] +@ CHECK: dsb nsh @ encoding: [0xbf,0xf3,0x47,0x8f] +@ CHECK: dsb nsh @ encoding: [0xbf,0xf3,0x47,0x8f] +@ CHECK: dsb nshst @ encoding: [0xbf,0xf3,0x46,0x8f] +@ CHECK: dsb nshst @ encoding: [0xbf,0xf3,0x46,0x8f] +@ CHECK: dsb osh @ encoding: [0xbf,0xf3,0x43,0x8f] +@ CHECK: dsb oshst @ encoding: [0xbf,0xf3,0x42,0x8f] +@ CHECK: dsb sy @ encoding: [0xbf,0xf3,0x4f,0x8f] + + +@------------------------------------------------------------------------------ +@ EOR +@------------------------------------------------------------------------------ + eor r4, r5, #0xf000 + eor r4, r5, r6 + eor r4, r5, r6, lsl #5 + eor r4, r5, r6, lsr #5 + eor r4, r5, r6, lsr #5 + eor r4, r5, r6, asr #5 + eor r4, r5, r6, ror #5 + +@ CHECK: eor r4, r5, #61440 @ encoding: [0x85,0xf4,0x70,0x44] +@ CHECK: eor.w r4, r5, r6 @ encoding: [0x85,0xea,0x06,0x04] +@ CHECK: eor.w r4, r5, r6, lsl #5 @ encoding: [0x85,0xea,0x46,0x14] +@ CHECK: eor.w r4, r5, r6, lsr #5 @ encoding: [0x85,0xea,0x56,0x14] +@ CHECK: eor.w r4, r5, r6, lsr #5 @ encoding: [0x85,0xea,0x56,0x14] +@ CHECK: eor.w r4, r5, r6, asr #5 @ encoding: [0x85,0xea,0x66,0x14] +@ CHECK: eor.w r4, r5, r6, ror #5 @ encoding: [0x85,0xea,0x76,0x14] + + +@------------------------------------------------------------------------------ +@ ISB +@------------------------------------------------------------------------------ + isb sy + isb + +@ CHECK: isb sy @ encoding: [0xbf,0xf3,0x6f,0x8f] +@ CHECK: isb sy @ encoding: [0xbf,0xf3,0x6f,0x8f] + + +@------------------------------------------------------------------------------ +@ IT +@------------------------------------------------------------------------------ +@ Test encodings of a few full IT blocks, not just the IT instruction + + iteet eq + addeq r0, r1, r2 + nopne + subne r5, r6, r7 + addeq r1, r2, #4 + +@ CHECK: iteet eq @ encoding: [0x0d,0xbf] +@ CHECK: addeq r0, r1, r2 @ encoding: [0x88,0x18] +@ CHECK: nopne @ encoding: [0x00,0xbf] +@ CHECK: subne r5, r6, r7 @ encoding: [0xf5,0x1b] +@ CHECK: addeq r1, r2, #4 @ encoding: [0x11,0x1d] + + +@------------------------------------------------------------------------------ +@ LDC{L}/LDC2{L} +@------------------------------------------------------------------------------ + ldc2 p0, c8, [r1, #4] + ldc2 p1, c7, [r2] + ldc2 p2, c6, [r3, #-224] + ldc2 p3, c5, [r4, #-120]! + ldc2 p4, c4, [r5], #16 + ldc2 p5, c3, [r6], #-72 + ldc2l p6, c2, [r7, #4] + ldc2l p7, c1, [r8] + ldc2l p8, c0, [r9, #-224] + ldc2l p9, c1, [r10, #-120]! + ldc2l p10, c2, [r11], #16 + ldc2l p11, c3, [r12], #-72 + + ldc p12, c4, [r0, #4] + ldc p13, c5, [r1] + ldc p14, c6, [r2, #-224] + ldc p15, c7, [r3, #-120]! + ldc p5, c8, [r4], #16 + ldc p4, c9, [r5], #-72 + ldcl p3, c10, [r6, #4] + ldcl p2, c11, [r7] + ldcl p1, c12, [r8, #-224] + ldcl p0, c13, [r9, #-120]! + ldcl p6, c14, [r10], #16 + ldcl p7, c15, [r11], #-72 + + ldc2 p2, c8, [r1], { 25 } + +@ CHECK: ldc2 p0, c8, [r1, #4] @ encoding: [0x91,0xfd,0x01,0x80] +@ CHECK: ldc2 p1, c7, [r2] @ encoding: [0x92,0xfd,0x00,0x71] +@ CHECK: ldc2 p2, c6, [r3, #-224] @ encoding: [0x13,0xfd,0x38,0x62] +@ CHECK: ldc2 p3, c5, [r4, #-120]! @ encoding: [0x34,0xfd,0x1e,0x53] +@ CHECK: ldc2 p4, c4, [r5], #16 @ encoding: [0xb5,0xfc,0x04,0x44] +@ CHECK: ldc2 p5, c3, [r6], #-72 @ encoding: [0x36,0xfc,0x12,0x35] +@ CHECK: ldc2l p6, c2, [r7, #4] @ encoding: [0xd7,0xfd,0x01,0x26] +@ CHECK: ldc2l p7, c1, [r8] @ encoding: [0xd8,0xfd,0x00,0x17] +@ CHECK: ldc2l p8, c0, [r9, #-224] @ encoding: [0x59,0xfd,0x38,0x08] +@ CHECK: ldc2l p9, c1, [r10, #-120]! @ encoding: [0x7a,0xfd,0x1e,0x19] +@ CHECK: ldc2l p10, c2, [r11], #16 @ encoding: [0xfb,0xfc,0x04,0x2a] +@ CHECK: ldc2l p11, c3, [r12], #-72 @ encoding: [0x7c,0xfc,0x12,0x3b] + +@ CHECK: ldc p12, c4, [r0, #4] @ encoding: [0x90,0xed,0x01,0x4c] +@ CHECK: ldc p13, c5, [r1] @ encoding: [0x91,0xed,0x00,0x5d] +@ CHECK: ldc p14, c6, [r2, #-224] @ encoding: [0x12,0xed,0x38,0x6e] +@ CHECK: ldc p15, c7, [r3, #-120]! @ encoding: [0x33,0xed,0x1e,0x7f] +@ CHECK: ldc p5, c8, [r4], #16 @ encoding: [0xb4,0xec,0x04,0x85] +@ CHECK: ldc p4, c9, [r5], #-72 @ encoding: [0x35,0xec,0x12,0x94] +@ CHECK: ldcl p3, c10, [r6, #4] @ encoding: [0xd6,0xed,0x01,0xa3] +@ CHECK: ldcl p2, c11, [r7] @ encoding: [0xd7,0xed,0x00,0xb2] +@ CHECK: ldcl p1, c12, [r8, #-224] @ encoding: [0x58,0xed,0x38,0xc1] +@ CHECK: ldcl p0, c13, [r9, #-120]! @ encoding: [0x79,0xed,0x1e,0xd0] +@ CHECK: ldcl p6, c14, [r10], #16 @ encoding: [0xfa,0xec,0x04,0xe6] +@ CHECK: ldcl p7, c15, [r11], #-72 @ encoding: [0x7b,0xec,0x12,0xf7] + +@ CHECK: ldc2 p2, c8, [r1], {25} @ encoding: [0x91,0xfc,0x19,0x82] + + +@------------------------------------------------------------------------------ +@ LDMIA +@------------------------------------------------------------------------------ + ldmia.w r4, {r4, r5, r8, r9} + ldmia.w r4, {r5, r6} + ldmia.w r5!, {r3, r8} + ldm.w r4, {r4, r5, r8, r9} + ldm.w r4, {r5, r6} + ldm.w r5!, {r3, r8} + ldm.w r5!, {r1, r2} + ldm.w r2, {r1, r2} + + ldmia r4, {r4, r5, r8, r9} + ldmia r4, {r5, r6} + ldmia r5!, {r3, r8} + ldm r4, {r4, r5, r8, r9} + ldm r4, {r5, r6} + ldm r5!, {r3, r8} + ldmfd r5!, {r3, r8} + +@ CHECK: ldm.w r4, {r4, r5, r8, r9} @ encoding: [0x94,0xe8,0x30,0x03] +@ CHECK: ldm.w r4, {r5, r6} @ encoding: [0x94,0xe8,0x60,0x00] +@ CHECK: ldm.w r5!, {r3, r8} @ encoding: [0xb5,0xe8,0x08,0x01] +@ CHECK: ldm.w r4, {r4, r5, r8, r9} @ encoding: [0x94,0xe8,0x30,0x03] +@ CHECK: ldm.w r4, {r5, r6} @ encoding: [0x94,0xe8,0x60,0x00] +@ CHECK: ldm.w r5!, {r3, r8} @ encoding: [0xb5,0xe8,0x08,0x01] +@ CHECK: ldm.w r5!, {r1, r2} @ encoding: [0xb5,0xe8,0x06,0x00] +@ CHECK: ldm.w r2, {r1, r2} @ encoding: [0x92,0xe8,0x06,0x00] + +@ CHECK: ldm.w r4, {r4, r5, r8, r9} @ encoding: [0x94,0xe8,0x30,0x03] +@ CHECK: ldm.w r4, {r5, r6} @ encoding: [0x94,0xe8,0x60,0x00] +@ CHECK: ldm.w r5!, {r3, r8} @ encoding: [0xb5,0xe8,0x08,0x01] +@ CHECK: ldm.w r4, {r4, r5, r8, r9} @ encoding: [0x94,0xe8,0x30,0x03] +@ CHECK: ldm.w r4, {r5, r6} @ encoding: [0x94,0xe8,0x60,0x00] +@ CHECK: ldm.w r5!, {r3, r8} @ encoding: [0xb5,0xe8,0x08,0x01] +@ CHECK: ldm.w r5!, {r3, r8} @ encoding: [0xb5,0xe8,0x08,0x01] + + +@------------------------------------------------------------------------------ +@ LDMDB +@------------------------------------------------------------------------------ + ldmdb r4, {r4, r5, r8, r9} + ldmdb r4, {r5, r6} + ldmdb r5!, {r3, r8} + ldmea r5!, {r3, r8} + +@ CHECK: ldmdb r4, {r4, r5, r8, r9} @ encoding: [0x14,0xe9,0x30,0x03] +@ CHECK: ldmdb r4, {r5, r6} @ encoding: [0x14,0xe9,0x60,0x00] +@ CHECK: ldmdb r5!, {r3, r8} @ encoding: [0x35,0xe9,0x08,0x01] +@ CHECK: ldmdb r5!, {r3, r8} @ encoding: [0x35,0xe9,0x08,0x01] + + +@------------------------------------------------------------------------------ +@ LDR(immediate) +@------------------------------------------------------------------------------ + ldr r5, [r5, #-4] + ldr r5, [r6, #32] + ldr r5, [r6, #33] + ldr r5, [r6, #257] + ldr.w pc, [r7, #257] + ldr r2, [r4, #255]! + ldr r8, [sp, #4]! + ldr lr, [sp, #-4]! + ldr r2, [r4], #255 + ldr r8, [sp], #4 + ldr lr, [sp], #-4 + +@ CHECK: ldr r5, [r5, #-4] @ encoding: [0x55,0xf8,0x04,0x5c] +@ CHECK: ldr r5, [r6, #32] @ encoding: [0x35,0x6a] +@ CHECK: ldr.w r5, [r6, #33] @ encoding: [0xd6,0xf8,0x21,0x50] +@ CHECK: ldr.w r5, [r6, #257] @ encoding: [0xd6,0xf8,0x01,0x51] +@ CHECK: ldr.w pc, [r7, #257] @ encoding: [0xd7,0xf8,0x01,0xf1] +@ CHECK: ldr r2, [r4, #255]! @ encoding: [0x54,0xf8,0xff,0x2f] +@ CHECK: ldr r8, [sp, #4]! @ encoding: [0x5d,0xf8,0x04,0x8f] +@ CHECK: ldr lr, [sp, #-4]! @ encoding: [0x5d,0xf8,0x04,0xed] +@ CHECK: ldr r2, [r4], #255 @ encoding: [0x54,0xf8,0xff,0x2b] +@ CHECK: ldr r8, [sp], #4 @ encoding: [0x5d,0xf8,0x04,0x8b] +@ CHECK: ldr lr, [sp], #-4 @ encoding: [0x5d,0xf8,0x04,0xe9] + + +@------------------------------------------------------------------------------ +@ LDR(literal) +@------------------------------------------------------------------------------ + ldr.w r5, _foo + +@ CHECK: ldr.w r5, _foo @ encoding: [0x5f'A',0xf8'A',A,0x50'A'] + @ fixup A - offset: 0, value: _foo, kind: fixup_t2_ldst_pcrel_12 + + +@------------------------------------------------------------------------------ +@ LDR(register) +@------------------------------------------------------------------------------ + ldr r1, [r8, r1] + ldr.w r4, [r5, r2] + ldr r6, [r0, r2, lsl #3] + ldr r8, [r8, r2, lsl #2] + ldr r7, [sp, r2, lsl #1] + ldr r7, [sp, r2, lsl #0] + +@ CHECK: ldr.w r1, [r8, r1] @ encoding: [0x58,0xf8,0x01,0x10] +@ CHECK: ldr.w r4, [r5, r2] @ encoding: [0x55,0xf8,0x02,0x40] +@ CHECK: ldr.w r6, [r0, r2, lsl #3] @ encoding: [0x50,0xf8,0x32,0x60] +@ CHECK: ldr.w r8, [r8, r2, lsl #2] @ encoding: [0x58,0xf8,0x22,0x80] +@ CHECK: ldr.w r7, [sp, r2, lsl #1] @ encoding: [0x5d,0xf8,0x12,0x70] +@ CHECK: ldr.w r7, [sp, r2] @ encoding: [0x5d,0xf8,0x02,0x70] + + +@------------------------------------------------------------------------------ +@ LDRB(immediate) +@------------------------------------------------------------------------------ + ldrb r5, [r5, #-4] + ldrb r5, [r6, #32] + ldrb r5, [r6, #33] + ldrb r5, [r6, #257] + ldrb.w lr, [r7, #257] + ldrb r5, [r8, #255]! + ldrb r2, [r5, #4]! + ldrb r1, [r4, #-4]! + ldrb lr, [r3], #255 + ldrb r9, [r2], #4 + ldrb r3, [sp], #-4 + +@ CHECK: ldrb r5, [r5, #-4] @ encoding: [0x15,0xf8,0x04,0x5c] +@ CHECK: ldrb.w r5, [r6, #32] @ encoding: [0x96,0xf8,0x20,0x50] +@ CHECK: ldrb.w r5, [r6, #33] @ encoding: [0x96,0xf8,0x21,0x50] +@ CHECK: ldrb.w r5, [r6, #257] @ encoding: [0x96,0xf8,0x01,0x51] +@ CHECK: ldrb.w lr, [r7, #257] @ encoding: [0x97,0xf8,0x01,0xe1] +@ CHECK: ldrb r5, [r8, #255]! @ encoding: [0x18,0xf8,0xff,0x5f] +@ CHECK: ldrb r2, [r5, #4]! @ encoding: [0x15,0xf8,0x04,0x2f] +@ CHECK: ldrb r1, [r4, #-4]! @ encoding: [0x14,0xf8,0x04,0x1d] +@ CHECK: ldrb lr, [r3], #255 @ encoding: [0x13,0xf8,0xff,0xeb] +@ CHECK: ldrb r9, [r2], #4 @ encoding: [0x12,0xf8,0x04,0x9b] +@ CHECK: ldrb r3, [sp], #-4 @ encoding: [0x1d,0xf8,0x04,0x39] + + +@------------------------------------------------------------------------------ +@ LDRB(register) +@------------------------------------------------------------------------------ + ldrb r1, [r8, r1] + ldrb.w r4, [r5, r2] + ldrb r6, [r0, r2, lsl #3] + ldrb r8, [r8, r2, lsl #2] + ldrb r7, [sp, r2, lsl #1] + ldrb r7, [sp, r2, lsl #0] + +@ CHECK: ldrb.w r1, [r8, r1] @ encoding: [0x18,0xf8,0x01,0x10] +@ CHECK: ldrb.w r4, [r5, r2] @ encoding: [0x15,0xf8,0x02,0x40] +@ CHECK: ldrb.w r6, [r0, r2, lsl #3] @ encoding: [0x10,0xf8,0x32,0x60] +@ CHECK: ldrb.w r8, [r8, r2, lsl #2] @ encoding: [0x18,0xf8,0x22,0x80] +@ CHECK: ldrb.w r7, [sp, r2, lsl #1] @ encoding: [0x1d,0xf8,0x12,0x70] +@ CHECK: ldrb.w r7, [sp, r2] @ encoding: [0x1d,0xf8,0x02,0x70] + + +@------------------------------------------------------------------------------ +@ LDRBT +@------------------------------------------------------------------------------ + ldrbt r1, [r2] + ldrbt r1, [r8, #0] + ldrbt r1, [r8, #3] + ldrbt r1, [r8, #255] + +@ CHECK: ldrbt r1, [r2] @ encoding: [0x12,0xf8,0x00,0x1e] +@ CHECK: ldrbt r1, [r8] @ encoding: [0x18,0xf8,0x00,0x1e] +@ CHECK: ldrbt r1, [r8, #3] @ encoding: [0x18,0xf8,0x03,0x1e] +@ CHECK: ldrbt r1, [r8, #255] @ encoding: [0x18,0xf8,0xff,0x1e] + + +@------------------------------------------------------------------------------ +@ LDRD +@------------------------------------------------------------------------------ + ldrd r3, r5, [r6, #24] + ldrd r3, r5, [r6, #24]! + ldrd r3, r5, [r6], #4 + ldrd r3, r5, [r6], #-8 + ldrd r3, r5, [r6] + ldrd r8, r1, [r3, #0] + +@ CHECK: ldrd r3, r5, [r6, #24] @ encoding: [0xd6,0xe9,0x06,0x35] +@ CHECK: ldrd r3, r5, [r6, #24]! @ encoding: [0xf6,0xe9,0x06,0x35] +@ CHECK: ldrd r3, r5, [r6], #4 @ encoding: [0xf6,0xe8,0x01,0x35] +@ CHECK: ldrd r3, r5, [r6], #-8 @ encoding: [0x76,0xe8,0x02,0x35] +@ CHECK: ldrd r3, r5, [r6] @ encoding: [0xd6,0xe9,0x00,0x35] +@ CHECK: ldrd r8, r1, [r3] @ encoding: [0xd3,0xe9,0x00,0x81] + + +@------------------------------------------------------------------------------ +@ FIXME: LDRD(literal) +@------------------------------------------------------------------------------ + + +@------------------------------------------------------------------------------ +@ LDREX/LDREXB/LDREXH/LDREXD +@------------------------------------------------------------------------------ + ldrex r1, [r4] + ldrex r8, [r4, #0] + ldrex r2, [sp, #128] + ldrexb r5, [r7] + ldrexh r9, [r12] + ldrexd r9, r3, [r4] + +@ CHECK: ldrex r1, [r4] @ encoding: [0x54,0xe8,0x00,0x1f] +@ CHECK: ldrex r8, [r4] @ encoding: [0x54,0xe8,0x00,0x8f] +@ CHECK: ldrex r2, [sp, #128] @ encoding: [0x5d,0xe8,0x20,0x2f] +@ CHECK: ldrexb r5, [r7] @ encoding: [0xd7,0xe8,0x4f,0x5f] +@ CHECK: ldrexh r9, [r12] @ encoding: [0xdc,0xe8,0x5f,0x9f] +@ CHECK: ldrexd r9, r3, [r4] @ encoding: [0xd4,0xe8,0x7f,0x93] + + +@------------------------------------------------------------------------------ +@ LDRH(immediate) +@------------------------------------------------------------------------------ + ldrh r5, [r5, #-4] + ldrh r5, [r6, #32] + ldrh r5, [r6, #33] + ldrh r5, [r6, #257] + ldrh.w lr, [r7, #257] + ldrh r5, [r8, #255]! + ldrh r2, [r5, #4]! + ldrh r1, [r4, #-4]! + ldrh lr, [r3], #255 + ldrh r9, [r2], #4 + ldrh r3, [sp], #-4 + +@ CHECK: ldrh r5, [r5, #-4] @ encoding: [0x35,0xf8,0x04,0x5c] +@ CHECK: ldrh r5, [r6, #32] @ encoding: [0x35,0x8c] +@ CHECK: ldrh.w r5, [r6, #33] @ encoding: [0xb6,0xf8,0x21,0x50] +@ CHECK: ldrh.w r5, [r6, #257] @ encoding: [0xb6,0xf8,0x01,0x51] +@ CHECK: ldrh.w lr, [r7, #257] @ encoding: [0xb7,0xf8,0x01,0xe1] +@ CHECK: ldrh r5, [r8, #255]! @ encoding: [0x38,0xf8,0xff,0x5f] +@ CHECK: ldrh r2, [r5, #4]! @ encoding: [0x35,0xf8,0x04,0x2f] +@ CHECK: ldrh r1, [r4, #-4]! @ encoding: [0x34,0xf8,0x04,0x1d] +@ CHECK: ldrh lr, [r3], #255 @ encoding: [0x33,0xf8,0xff,0xeb] +@ CHECK: ldrh r9, [r2], #4 @ encoding: [0x32,0xf8,0x04,0x9b] +@ CHECK: ldrh r3, [sp], #-4 @ encoding: [0x3d,0xf8,0x04,0x39] + + +@------------------------------------------------------------------------------ +@ LDRH(register) +@------------------------------------------------------------------------------ + ldrh r1, [r8, r1] + ldrh.w r4, [r5, r2] + ldrh r6, [r0, r2, lsl #3] + ldrh r8, [r8, r2, lsl #2] + ldrh r7, [sp, r2, lsl #1] + ldrh r7, [sp, r2, lsl #0] + +@ CHECK: ldrh.w r1, [r8, r1] @ encoding: [0x38,0xf8,0x01,0x10] +@ CHECK: ldrh.w r4, [r5, r2] @ encoding: [0x35,0xf8,0x02,0x40] +@ CHECK: ldrh.w r6, [r0, r2, lsl #3] @ encoding: [0x30,0xf8,0x32,0x60] +@ CHECK: ldrh.w r8, [r8, r2, lsl #2] @ encoding: [0x38,0xf8,0x22,0x80] +@ CHECK: ldrh.w r7, [sp, r2, lsl #1] @ encoding: [0x3d,0xf8,0x12,0x70] +@ CHECK: ldrh.w r7, [sp, r2] @ encoding: [0x3d,0xf8,0x02,0x70] + + +@------------------------------------------------------------------------------ +@ LDRH(literal) +@------------------------------------------------------------------------------ + ldrh r5, _bar + +@ CHECK: ldrh.w r5, _bar @ encoding: [0xbf'A',0xf8'A',A,0x50'A'] +@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_ldst_pcrel_12 + + +@------------------------------------------------------------------------------ +@ LDRHT +@------------------------------------------------------------------------------ + ldrht r1, [r2] + ldrht r1, [r8, #0] + ldrht r1, [r8, #3] + ldrht r1, [r8, #255] + +@ CHECK: ldrht r1, [r2] @ encoding: [0x32,0xf8,0x00,0x1e] +@ CHECK: ldrht r1, [r8] @ encoding: [0x38,0xf8,0x00,0x1e] +@ CHECK: ldrht r1, [r8, #3] @ encoding: [0x38,0xf8,0x03,0x1e] +@ CHECK: ldrht r1, [r8, #255] @ encoding: [0x38,0xf8,0xff,0x1e] + + +@------------------------------------------------------------------------------ +@ LDRSB(immediate) +@------------------------------------------------------------------------------ + ldrsb r5, [r5, #-4] + ldrsb r5, [r6, #32] + ldrsb r5, [r6, #33] + ldrsb r5, [r6, #257] + ldrsb.w lr, [r7, #257] + +@ CHECK: ldrsb r5, [r5, #-4] @ encoding: [0x15,0xf9,0x04,0x5c] +@ CHECK: ldrsb.w r5, [r6, #32] @ encoding: [0x96,0xf9,0x20,0x50] +@ CHECK: ldrsb.w r5, [r6, #33] @ encoding: [0x96,0xf9,0x21,0x50] +@ CHECK: ldrsb.w r5, [r6, #257] @ encoding: [0x96,0xf9,0x01,0x51] +@ CHECK: ldrsb.w lr, [r7, #257] @ encoding: [0x97,0xf9,0x01,0xe1] + + +@------------------------------------------------------------------------------ +@ LDRSB(register) +@------------------------------------------------------------------------------ + ldrsb r1, [r8, r1] + ldrsb.w r4, [r5, r2] + ldrsb r6, [r0, r2, lsl #3] + ldrsb r8, [r8, r2, lsl #2] + ldrsb r7, [sp, r2, lsl #1] + ldrsb r7, [sp, r2, lsl #0] + ldrsb r5, [r8, #255]! + ldrsb r2, [r5, #4]! + ldrsb r1, [r4, #-4]! + ldrsb lr, [r3], #255 + ldrsb r9, [r2], #4 + ldrsb r3, [sp], #-4 + +@ CHECK: ldrsb.w r1, [r8, r1] @ encoding: [0x18,0xf9,0x01,0x10] +@ CHECK: ldrsb.w r4, [r5, r2] @ encoding: [0x15,0xf9,0x02,0x40] +@ CHECK: ldrsb.w r6, [r0, r2, lsl #3] @ encoding: [0x10,0xf9,0x32,0x60] +@ CHECK: ldrsb.w r8, [r8, r2, lsl #2] @ encoding: [0x18,0xf9,0x22,0x80] +@ CHECK: ldrsb.w r7, [sp, r2, lsl #1] @ encoding: [0x1d,0xf9,0x12,0x70] +@ CHECK: ldrsb.w r7, [sp, r2] @ encoding: [0x1d,0xf9,0x02,0x70] +@ CHECK: ldrsb r5, [r8, #255]! @ encoding: [0x18,0xf9,0xff,0x5f] +@ CHECK: ldrsb r2, [r5, #4]! @ encoding: [0x15,0xf9,0x04,0x2f] +@ CHECK: ldrsb r1, [r4, #-4]! @ encoding: [0x14,0xf9,0x04,0x1d] +@ CHECK: ldrsb lr, [r3], #255 @ encoding: [0x13,0xf9,0xff,0xeb] +@ CHECK: ldrsb r9, [r2], #4 @ encoding: [0x12,0xf9,0x04,0x9b] +@ CHECK: ldrsb r3, [sp], #-4 @ encoding: [0x1d,0xf9,0x04,0x39] + + +@------------------------------------------------------------------------------ +@ LDRSB(literal) +@------------------------------------------------------------------------------ + ldrsb r5, _bar + +@ CHECK: ldrsb.w r5, _bar @ encoding: [0x9f'A',0xf9'A',A,0x50'A'] +@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_ldst_pcrel_12 + + +@------------------------------------------------------------------------------ +@ LDRSBT +@------------------------------------------------------------------------------ + ldrsbt r1, [r2] + ldrsbt r1, [r8, #0] + ldrsbt r1, [r8, #3] + ldrsbt r1, [r8, #255] + +@ CHECK: ldrsbt r1, [r2] @ encoding: [0x12,0xf9,0x00,0x1e] +@ CHECK: ldrsbt r1, [r8] @ encoding: [0x18,0xf9,0x00,0x1e] +@ CHECK: ldrsbt r1, [r8, #3] @ encoding: [0x18,0xf9,0x03,0x1e] +@ CHECK: ldrsbt r1, [r8, #255] @ encoding: [0x18,0xf9,0xff,0x1e] + + +@------------------------------------------------------------------------------ +@ LDRSH(immediate) +@------------------------------------------------------------------------------ + ldrsh r5, [r5, #-4] + ldrsh r5, [r6, #32] + ldrsh r5, [r6, #33] + ldrsh r5, [r6, #257] + ldrsh.w lr, [r7, #257] + +@ CHECK: ldrsh r5, [r5, #-4] @ encoding: [0x35,0xf9,0x04,0x5c] +@ CHECK: ldrsh.w r5, [r6, #32] @ encoding: [0xb6,0xf9,0x20,0x50] +@ CHECK: ldrsh.w r5, [r6, #33] @ encoding: [0xb6,0xf9,0x21,0x50] +@ CHECK: ldrsh.w r5, [r6, #257] @ encoding: [0xb6,0xf9,0x01,0x51] +@ CHECK: ldrsh.w lr, [r7, #257] @ encoding: [0xb7,0xf9,0x01,0xe1] + + +@------------------------------------------------------------------------------ +@ LDRSH(register) +@------------------------------------------------------------------------------ + ldrsh r1, [r8, r1] + ldrsh.w r4, [r5, r2] + ldrsh r6, [r0, r2, lsl #3] + ldrsh r8, [r8, r2, lsl #2] + ldrsh r7, [sp, r2, lsl #1] + ldrsh r7, [sp, r2, lsl #0] + ldrsh r5, [r8, #255]! + ldrsh r2, [r5, #4]! + ldrsh r1, [r4, #-4]! + ldrsh lr, [r3], #255 + ldrsh r9, [r2], #4 + ldrsh r3, [sp], #-4 + +@ CHECK: ldrsh.w r1, [r8, r1] @ encoding: [0x38,0xf9,0x01,0x10] +@ CHECK: ldrsh.w r4, [r5, r2] @ encoding: [0x35,0xf9,0x02,0x40] +@ CHECK: ldrsh.w r6, [r0, r2, lsl #3] @ encoding: [0x30,0xf9,0x32,0x60] +@ CHECK: ldrsh.w r8, [r8, r2, lsl #2] @ encoding: [0x38,0xf9,0x22,0x80] +@ CHECK: ldrsh.w r7, [sp, r2, lsl #1] @ encoding: [0x3d,0xf9,0x12,0x70] +@ CHECK: ldrsh.w r7, [sp, r2] @ encoding: [0x3d,0xf9,0x02,0x70] +@ CHECK: ldrsh r5, [r8, #255]! @ encoding: [0x38,0xf9,0xff,0x5f] +@ CHECK: ldrsh r2, [r5, #4]! @ encoding: [0x35,0xf9,0x04,0x2f] +@ CHECK: ldrsh r1, [r4, #-4]! @ encoding: [0x34,0xf9,0x04,0x1d] +@ CHECK: ldrsh lr, [r3], #255 @ encoding: [0x33,0xf9,0xff,0xeb] +@ CHECK: ldrsh r9, [r2], #4 @ encoding: [0x32,0xf9,0x04,0x9b] +@ CHECK: ldrsh r3, [sp], #-4 @ encoding: [0x3d,0xf9,0x04,0x39] + + +@------------------------------------------------------------------------------ +@ LDRSH(literal) +@------------------------------------------------------------------------------ + ldrsh r5, _bar + +@ CHECK: ldrsh.w r5, _bar @ encoding: [0xbf'A',0xf9'A',A,0x50'A'] +@ CHECK: @ fixup A - offset: 0, value: _bar, kind: fixup_t2_ldst_pcrel_12 + +@ TEMPORARILY DISABLED: +@ ldrsh.w r4, [pc, #1435] +@ : ldrsh.w r4, [pc, #1435] @ encoding: [0x3f,0xf9,0x9b,0x45] + +@------------------------------------------------------------------------------ +@ LDRSHT +@------------------------------------------------------------------------------ + ldrsht r1, [r2] + ldrsht r1, [r8, #0] + ldrsht r1, [r8, #3] + ldrsht r1, [r8, #255] + +@ CHECK: ldrsht r1, [r2] @ encoding: [0x32,0xf9,0x00,0x1e] +@ CHECK: ldrsht r1, [r8] @ encoding: [0x38,0xf9,0x00,0x1e] +@ CHECK: ldrsht r1, [r8, #3] @ encoding: [0x38,0xf9,0x03,0x1e] +@ CHECK: ldrsht r1, [r8, #255] @ encoding: [0x38,0xf9,0xff,0x1e] + + +@------------------------------------------------------------------------------ +@ LDRT +@------------------------------------------------------------------------------ + ldrt r1, [r2] + ldrt r2, [r6, #0] + ldrt r3, [r7, #3] + ldrt r4, [r9, #255] + +@ CHECK: ldrt r1, [r2] @ encoding: [0x52,0xf8,0x00,0x1e] +@ CHECK: ldrt r2, [r6] @ encoding: [0x56,0xf8,0x00,0x2e] +@ CHECK: ldrt r3, [r7, #3] @ encoding: [0x57,0xf8,0x03,0x3e] +@ CHECK: ldrt r4, [r9, #255] @ encoding: [0x59,0xf8,0xff,0x4e] + + +@------------------------------------------------------------------------------ +@ LSL (immediate) +@------------------------------------------------------------------------------ + lsl r2, r3, #12 + lsls r8, r3, #31 + lsls.w r2, r3, #1 + lsl r2, r3, #4 + lsls r2, r12, #15 + + lsl r3, #19 + lsls r8, #2 + lsls.w r7, #5 + lsl.w r12, #21 + +@ CHECK: lsl.w r2, r3, #12 @ encoding: [0x4f,0xea,0x03,0x32] +@ CHECK: lsls.w r8, r3, #31 @ encoding: [0x5f,0xea,0xc3,0x78] +@ CHECK: lsls.w r2, r3, #1 @ encoding: [0x5f,0xea,0x43,0x02] +@ CHECK: lsl.w r2, r3, #4 @ encoding: [0x4f,0xea,0x03,0x12] +@ CHECK: lsls.w r2, r12, #15 @ encoding: [0x5f,0xea,0xcc,0x32] + +@ CHECK: lsl.w r3, r3, #19 @ encoding: [0x4f,0xea,0xc3,0x43] +@ CHECK: lsls.w r8, r8, #2 @ encoding: [0x5f,0xea,0x88,0x08] +@ CHECK: lsls.w r7, r7, #5 @ encoding: [0x5f,0xea,0x47,0x17] +@ CHECK: lsl.w r12, r12, #21 @ encoding: [0x4f,0xea,0x4c,0x5c] + + +@------------------------------------------------------------------------------ +@ LSL (register) +@------------------------------------------------------------------------------ + lsl r3, r4, r2 + lsl.w r1, r2 + lsls r3, r4, r8 + +@ CHECK: lsl.w r3, r4, r2 @ encoding: [0x04,0xfa,0x02,0xf3] +@ CHECK: lsl.w r1, r1, r2 @ encoding: [0x01,0xfa,0x02,0xf1] +@ CHECK: lsls.w r3, r4, r8 @ encoding: [0x14,0xfa,0x08,0xf3] + + +@------------------------------------------------------------------------------ +@ LSR (immediate) +@------------------------------------------------------------------------------ + lsr r2, r3, #12 + lsrs r8, r3, #32 + lsrs.w r2, r3, #1 + lsr r2, r3, #4 + lsrs r2, r12, #15 + + lsr r3, #19 + lsrs r8, #2 + lsrs.w r7, #5 + lsr.w r12, #21 + +@ CHECK: lsr.w r2, r3, #12 @ encoding: [0x4f,0xea,0x13,0x32] +@ CHECK: lsrs.w r8, r3, #32 @ encoding: [0x5f,0xea,0x13,0x08] +@ CHECK: lsrs.w r2, r3, #1 @ encoding: [0x5f,0xea,0x53,0x02] +@ CHECK: lsr.w r2, r3, #4 @ encoding: [0x4f,0xea,0x13,0x12] +@ CHECK: lsrs.w r2, r12, #15 @ encoding: [0x5f,0xea,0xdc,0x32] + +@ CHECK: lsr.w r3, r3, #19 @ encoding: [0x4f,0xea,0xd3,0x43] +@ CHECK: lsrs.w r8, r8, #2 @ encoding: [0x5f,0xea,0x98,0x08] +@ CHECK: lsrs.w r7, r7, #5 @ encoding: [0x5f,0xea,0x57,0x17] +@ CHECK: lsr.w r12, r12, #21 @ encoding: [0x4f,0xea,0x5c,0x5c] + + +@------------------------------------------------------------------------------ +@ LSR (register) +@------------------------------------------------------------------------------ + lsr r3, r4, r2 + lsr.w r1, r2 + lsrs r3, r4, r8 + +@ CHECK: lsr.w r3, r4, r2 @ encoding: [0x24,0xfa,0x02,0xf3] +@ CHECK: lsr.w r1, r1, r2 @ encoding: [0x21,0xfa,0x02,0xf1] +@ CHECK: lsrs.w r3, r4, r8 @ encoding: [0x34,0xfa,0x08,0xf3] + +@------------------------------------------------------------------------------ +@ MCR/MCR2 +@------------------------------------------------------------------------------ + mcr p7, #1, r5, c1, c1, #4 + mcr2 p7, #1, r5, c1, c1, #4 + +@ CHECK: mcr p7, #1, r5, c1, c1, #4 @ encoding: [0x21,0xee,0x91,0x57] +@ CHECK: mcr2 p7, #1, r5, c1, c1, #4 @ encoding: [0x21,0xfe,0x91,0x57] + + +@------------------------------------------------------------------------------ +@ MCRR/MCRR2 +@------------------------------------------------------------------------------ + mcrr p7, #15, r5, r4, c1 + mcrr2 p7, #15, r5, r4, c1 + +@ CHECK: mcrr p7, #15, r5, r4, c1 @ encoding: [0x44,0xec,0xf1,0x57] +@ CHECK: mcrr2 p7, #15, r5, r4, c1 @ encoding: [0x44,0xfc,0xf1,0x57] + + +@------------------------------------------------------------------------------ +@ MLA/MLS +@------------------------------------------------------------------------------ + mla r1,r2,r3,r4 + mls r1,r2,r3,r4 + +@ CHECK: mla r1, r2, r3, r4 @ encoding: [0x02,0xfb,0x03,0x41] +@ CHECK: mls r1, r2, r3, r4 @ encoding: [0x02,0xfb,0x13,0x41] + + +@------------------------------------------------------------------------------ +@ MOV(immediate) +@------------------------------------------------------------------------------ + movs r1, #21 + movs.w r1, #21 + movs r8, #21 + movw r0, #65535 + movw r1, #43777 + movw r1, #43792 + mov.w r0, #0x3fc0000 + mov r0, #0x3fc0000 + movs.w r0, #0x3fc0000 + itte eq + movseq r1, #12 + moveq r1, #12 + movne.w r1, #12 + mov.w r6, #450 + +@ CHECK: movs r1, #21 @ encoding: [0x15,0x21] +@ CHECK: movs.w r1, #21 @ encoding: [0x5f,0xf0,0x15,0x01] +@ CHECK: movs.w r8, #21 @ encoding: [0x5f,0xf0,0x15,0x08] +@ CHECK: movw r0, #65535 @ encoding: [0x4f,0xf6,0xff,0x70] +@ CHECK: movw r1, #43777 @ encoding: [0x4a,0xf6,0x01,0x31] +@ CHECK: movw r1, #43792 @ encoding: [0x4a,0xf6,0x10,0x31] +@ CHECK: mov.w r0, #66846720 @ encoding: [0x4f,0xf0,0x7f,0x70] +@ CHECK: mov.w r0, #66846720 @ encoding: [0x4f,0xf0,0x7f,0x70] +@ CHECK: movs.w r0, #66846720 @ encoding: [0x5f,0xf0,0x7f,0x70] +@ CHECK: itte eq @ encoding: [0x06,0xbf] +@ CHECK: movseq.w r1, #12 @ encoding: [0x5f,0xf0,0x0c,0x01] +@ CHECK: moveq r1, #12 @ encoding: [0x0c,0x21] +@ CHECK: movne.w r1, #12 @ encoding: [0x4f,0xf0,0x0c,0x01] +@ CHECK: mov.w r6, #450 @ encoding: [0x4f,0xf4,0xe1,0x76] + + +@------------------------------------------------------------------------------ +@ MOVT +@------------------------------------------------------------------------------ + movt r3, #7 + movt r6, #0xffff + it eq + movteq r4, #0xff0 + +@ CHECK: movt r3, #7 @ encoding: [0xc0,0xf2,0x07,0x03] +@ CHECK: movt r6, #65535 @ encoding: [0xcf,0xf6,0xff,0x76] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: movteq r4, #4080 @ encoding: [0xc0,0xf6,0xf0,0x74] + +@------------------------------------------------------------------------------ +@ MRC/MRC2 +@------------------------------------------------------------------------------ + mrc p14, #0, r1, c1, c2, #4 + mrc2 p14, #0, r1, c1, c2, #4 + +@ CHECK: mrc p14, #0, r1, c1, c2, #4 @ encoding: [0x11,0xee,0x92,0x1e] +@ CHECK: mrc2 p14, #0, r1, c1, c2, #4 @ encoding: [0x11,0xfe,0x92,0x1e] + + +@------------------------------------------------------------------------------ +@ MRRC/MRRC2 +@------------------------------------------------------------------------------ + mrrc p7, #1, r5, r4, c1 + mrrc2 p7, #1, r5, r4, c1 + +@ CHECK: mrrc p7, #1, r5, r4, c1 @ encoding: [0x54,0xec,0x11,0x57] +@ CHECK: mrrc2 p7, #1, r5, r4, c1 @ encoding: [0x54,0xfc,0x11,0x57] + + +@------------------------------------------------------------------------------ +@ MRS +@------------------------------------------------------------------------------ + mrs r8, apsr + mrs r8, cpsr + mrs r8, spsr + +@ CHECK: mrs r8, apsr @ encoding: [0xef,0xf3,0x00,0x88] +@ CHECK: mrs r8, apsr @ encoding: [0xef,0xf3,0x00,0x88] +@ CHECK: mrs r8, spsr @ encoding: [0xff,0xf3,0x00,0x88] + + +@------------------------------------------------------------------------------ +@ MSR +@------------------------------------------------------------------------------ + msr apsr, r1 + msr apsr_g, r2 + msr apsr_nzcvq, r3 + msr APSR_nzcvq, r4 + msr apsr_nzcvqg, r5 + msr cpsr_fc, r6 + msr cpsr_c, r7 + msr cpsr_x, r8 + msr cpsr_fc, r9 + msr cpsr_all, r11 + msr cpsr_fsx, r12 + msr spsr_fc, r0 + msr SPSR_fsxc, r5 + msr cpsr_fsxc, r8 + +@ CHECK: msr APSR_nzcvq, r1 @ encoding: [0x81,0xf3,0x00,0x88] +@ CHECK: msr APSR_g, r2 @ encoding: [0x82,0xf3,0x00,0x84] +@ CHECK: msr APSR_nzcvq, r3 @ encoding: [0x83,0xf3,0x00,0x88] +@ CHECK: msr APSR_nzcvq, r4 @ encoding: [0x84,0xf3,0x00,0x88] +@ CHECK: msr APSR_nzcvqg, r5 @ encoding: [0x85,0xf3,0x00,0x8c] +@ CHECK: msr CPSR_fc, r6 @ encoding: [0x86,0xf3,0x00,0x89] +@ CHECK: msr CPSR_c, r7 @ encoding: [0x87,0xf3,0x00,0x81] +@ CHECK: msr CPSR_x, r8 @ encoding: [0x88,0xf3,0x00,0x82] +@ CHECK: msr CPSR_fc, r9 @ encoding: [0x89,0xf3,0x00,0x89] +@ CHECK: msr CPSR_fc, r11 @ encoding: [0x8b,0xf3,0x00,0x89] +@ CHECK: msr CPSR_fsx, r12 @ encoding: [0x8c,0xf3,0x00,0x8e] +@ CHECK: msr SPSR_fc, r0 @ encoding: [0x90,0xf3,0x00,0x89] +@ CHECK: msr SPSR_fsxc, r5 @ encoding: [0x95,0xf3,0x00,0x8f] +@ CHECK: msr CPSR_fsxc, r8 @ encoding: [0x88,0xf3,0x00,0x8f] + + +@------------------------------------------------------------------------------ +@ MUL +@------------------------------------------------------------------------------ + muls r3, r4, r3 + mul r3, r4, r3 + mul r3, r4, r6 + it eq + muleq r3, r4, r5 + +@ CHECK: muls r3, r4, r3 @ encoding: [0x63,0x43] +@ CHECK: mul r3, r4, r3 @ encoding: [0x04,0xfb,0x03,0xf3] +@ CHECK: mul r3, r4, r6 @ encoding: [0x04,0xfb,0x06,0xf3] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: muleq r3, r4, r5 @ encoding: [0x04,0xfb,0x05,0xf3] + + +@------------------------------------------------------------------------------ +@ MVN(immediate) +@------------------------------------------------------------------------------ + mvns r8, #21 + mvn r0, #0x3fc0000 + mvns r0, #0x3fc0000 + itte eq + mvnseq r1, #12 + mvneq r1, #12 + mvnne r1, #12 + +@ CHECK: mvns r8, #21 @ encoding: [0x7f,0xf0,0x15,0x08] +@ CHECK: mvn r0, #66846720 @ encoding: [0x6f,0xf0,0x7f,0x70] +@ CHECK: mvns r0, #66846720 @ encoding: [0x7f,0xf0,0x7f,0x70] +@ CHECK: itte eq @ encoding: [0x06,0xbf] +@ CHECK: mvnseq r1, #12 @ encoding: [0x7f,0xf0,0x0c,0x01] +@ CHECK: mvneq r1, #12 @ encoding: [0x6f,0xf0,0x0c,0x01] +@ CHECK: mvnne r1, #12 @ encoding: [0x6f,0xf0,0x0c,0x01] + + +@------------------------------------------------------------------------------ +@ MVN(register) +@------------------------------------------------------------------------------ + mvn r2, r3 + mvns r2, r3 + mvn r5, r6, lsl #19 + mvn r5, r6, lsr #9 + mvn r5, r6, asr #4 + mvn r5, r6, ror #6 + mvn r5, r6, rrx + it eq + mvneq r2, r3 + +@ CHECK: mvn.w r2, r3 @ encoding: [0x6f,0xea,0x03,0x02] +@ CHECK: mvns r2, r3 @ encoding: [0xda,0x43] +@ CHECK: mvn.w r5, r6, lsl #19 @ encoding: [0x6f,0xea,0xc6,0x45] +@ CHECK: mvn.w r5, r6, lsr #9 @ encoding: [0x6f,0xea,0x56,0x25] +@ CHECK: mvn.w r5, r6, asr #4 @ encoding: [0x6f,0xea,0x26,0x15] +@ CHECK: mvn.w r5, r6, ror #6 @ encoding: [0x6f,0xea,0xb6,0x15] +@ CHECK: mvn.w r5, r6, rrx @ encoding: [0x6f,0xea,0x36,0x05] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: mvneq r2, r3 @ encoding: [0xda,0x43] + +@------------------------------------------------------------------------------ +@ NOP +@------------------------------------------------------------------------------ + nop.w + +@ CHECK: nop.w @ encoding: [0xaf,0xf3,0x00,0x80] + + +@------------------------------------------------------------------------------ +@ ORN +@------------------------------------------------------------------------------ + orn r4, r5, #0xf000 + orn r4, r5, r6 + orns r4, r5, r6 + orn r4, r5, r6, lsl #5 + orns r4, r5, r6, lsr #5 + orn r4, r5, r6, lsr #5 + orns r4, r5, r6, asr #5 + orn r4, r5, r6, ror #5 + +@ CHECK: orn r4, r5, #61440 @ encoding: [0x65,0xf4,0x70,0x44] +@ CHECK: orn r4, r5, r6 @ encoding: [0x65,0xea,0x06,0x04] +@ CHECK: orns r4, r5, r6 @ encoding: [0x75,0xea,0x06,0x04] +@ CHECK: orn r4, r5, r6, lsl #5 @ encoding: [0x65,0xea,0x46,0x14] +@ CHECK: orns r4, r5, r6, lsr #5 @ encoding: [0x75,0xea,0x56,0x14] +@ CHECK: orn r4, r5, r6, lsr #5 @ encoding: [0x65,0xea,0x56,0x14] +@ CHECK: orns r4, r5, r6, asr #5 @ encoding: [0x75,0xea,0x66,0x14] +@ CHECK: orn r4, r5, r6, ror #5 @ encoding: [0x65,0xea,0x76,0x14] + + +@------------------------------------------------------------------------------ +@ ORR +@------------------------------------------------------------------------------ + orr r4, r5, #0xf000 + orr r4, r5, r6 + orr r4, r5, r6, lsl #5 + orrs r4, r5, r6, lsr #5 + orr r4, r5, r6, lsr #5 + orrs r4, r5, r6, asr #5 + orr r4, r5, r6, ror #5 + +@ CHECK: orr r4, r5, #61440 @ encoding: [0x45,0xf4,0x70,0x44] +@ CHECK: orr.w r4, r5, r6 @ encoding: [0x45,0xea,0x06,0x04] +@ CHECK: orr.w r4, r5, r6, lsl #5 @ encoding: [0x45,0xea,0x46,0x14] +@ CHECK: orrs.w r4, r5, r6, lsr #5 @ encoding: [0x55,0xea,0x56,0x14] +@ CHECK: orr.w r4, r5, r6, lsr #5 @ encoding: [0x45,0xea,0x56,0x14] +@ CHECK: orrs.w r4, r5, r6, asr #5 @ encoding: [0x55,0xea,0x66,0x14] +@ CHECK: orr.w r4, r5, r6, ror #5 @ encoding: [0x45,0xea,0x76,0x14] + + +@------------------------------------------------------------------------------ +@ PKH +@------------------------------------------------------------------------------ + pkhbt r2, r2, r3 + pkhbt r2, r2, r3, lsl #31 + pkhbt r2, r2, r3, lsl #0 + pkhbt r2, r2, r3, lsl #15 + + pkhtb r2, r2, r3 + pkhtb r2, r2, r3, asr #31 + pkhtb r2, r2, r3, asr #15 + +@ CHECK: pkhbt r2, r2, r3 @ encoding: [0xc2,0xea,0x03,0x02] +@ CHECK: pkhbt r2, r2, r3, lsl #31 @ encoding: [0xc2,0xea,0xc3,0x72] +@ CHECK: pkhbt r2, r2, r3 @ encoding: [0xc2,0xea,0x03,0x02] +@ CHECK: pkhbt r2, r2, r3, lsl #15 @ encoding: [0xc2,0xea,0xc3,0x32] + +@ CHECK: pkhbt r2, r2, r3 @ encoding: [0xc2,0xea,0x03,0x02] +@ CHECK: pkhtb r2, r2, r3, asr #31 @ encoding: [0xc2,0xea,0xe3,0x72] +@ CHECK: pkhtb r2, r2, r3, asr #15 @ encoding: [0xc2,0xea,0xe3,0x32] + + +@------------------------------------------------------------------------------ +@ PLD(immediate) +@------------------------------------------------------------------------------ + pld [r5, #-4] + pld [r6, #32] + pld [r6, #33] + pld [r6, #257] + pld [r7, #257] + +@ CHECK: pld [r5, #-4] @ encoding: [0x15,0xf8,0x04,0xfc] +@ CHECK: pld [r6, #32] @ encoding: [0x96,0xf8,0x20,0xf0] +@ CHECK: pld [r6, #33] @ encoding: [0x96,0xf8,0x21,0xf0] +@ CHECK: pld [r6, #257] @ encoding: [0x96,0xf8,0x01,0xf1] +@ CHECK: pld [r7, #257] @ encoding: [0x97,0xf8,0x01,0xf1] + + +@------------------------------------------------------------------------------ +@ PLD(literal) +@------------------------------------------------------------------------------ + pld _foo + +@ CHECK: pld _foo @ encoding: [0x9f'A',0xf8'A',A,0xf0'A'] + @ fixup A - offset: 0, value: _foo, kind: fixup_t2_ldst_pcrel_12 + + +@------------------------------------------------------------------------------ +@ PLD(register) +@------------------------------------------------------------------------------ + pld [r8, r1] + pld [r5, r2] + pld [r0, r2, lsl #3] + pld [r8, r2, lsl #2] + pld [sp, r2, lsl #1] + pld [sp, r2, lsl #0] + +@ CHECK: pld [r8, r1] @ encoding: [0x18,0xf8,0x01,0xf0] +@ CHECK: pld [r5, r2] @ encoding: [0x15,0xf8,0x02,0xf0] +@ CHECK: pld [r0, r2, lsl #3] @ encoding: [0x10,0xf8,0x32,0xf0] +@ CHECK: pld [r8, r2, lsl #2] @ encoding: [0x18,0xf8,0x22,0xf0] +@ CHECK: pld [sp, r2, lsl #1] @ encoding: [0x1d,0xf8,0x12,0xf0] +@ CHECK: pld [sp, r2] @ encoding: [0x1d,0xf8,0x02,0xf0] + +@------------------------------------------------------------------------------ +@ PLI(immediate) +@------------------------------------------------------------------------------ + pli [r5, #-4] + pli [r6, #32] + pli [r6, #33] + pli [r6, #257] + pli [r7, #257] + +@ CHECK: pli [r5, #-4] @ encoding: [0x15,0xf9,0x04,0xfc] +@ CHECK: pli [r6, #32] @ encoding: [0x96,0xf9,0x20,0xf0] +@ CHECK: pli [r6, #33] @ encoding: [0x96,0xf9,0x21,0xf0] +@ CHECK: pli [r6, #257] @ encoding: [0x96,0xf9,0x01,0xf1] +@ CHECK: pli [r7, #257] @ encoding: [0x97,0xf9,0x01,0xf1] + + +@------------------------------------------------------------------------------ +@ PLI(literal) +@------------------------------------------------------------------------------ + pli _foo + + +@ CHECK: pli _foo @ encoding: [0x9f'A',0xf9'A',A,0xf0'A'] + @ fixup A - offset: 0, value: _foo, kind: fixup_t2_ldst_pcrel_12 + + +@------------------------------------------------------------------------------ +@ PLI(register) +@------------------------------------------------------------------------------ + pli [r8, r1] + pli [r5, r2] + pli [r0, r2, lsl #3] + pli [r8, r2, lsl #2] + pli [sp, r2, lsl #1] + pli [sp, r2, lsl #0] + +@ CHECK: pli [r8, r1] @ encoding: [0x18,0xf9,0x01,0xf0] +@ CHECK: pli [r5, r2] @ encoding: [0x15,0xf9,0x02,0xf0] +@ CHECK: pli [r0, r2, lsl #3] @ encoding: [0x10,0xf9,0x32,0xf0] +@ CHECK: pli [r8, r2, lsl #2] @ encoding: [0x18,0xf9,0x22,0xf0] +@ CHECK: pli [sp, r2, lsl #1] @ encoding: [0x1d,0xf9,0x12,0xf0] +@ CHECK: pli [sp, r2] @ encoding: [0x1d,0xf9,0x02,0xf0] + + +@------------------------------------------------------------------------------ +@ QADD/QADD16/QADD8 +@------------------------------------------------------------------------------ + qadd r1, r2, r3 + qadd16 r1, r2, r3 + qadd8 r1, r2, r3 + itte gt + qaddgt r1, r2, r3 + qadd16gt r1, r2, r3 + qadd8le r1, r2, r3 + +@ CHECK: qadd r1, r2, r3 @ encoding: [0x83,0xfa,0x82,0xf1] +@ CHECK: qadd16 r1, r2, r3 @ encoding: [0x92,0xfa,0x13,0xf1] +@ CHECK: qadd8 r1, r2, r3 @ encoding: [0x82,0xfa,0x13,0xf1] +@ CHECK: itte gt @ encoding: [0xc6,0xbf] +@ CHECK: qaddgt r1, r2, r3 @ encoding: [0x83,0xfa,0x82,0xf1] +@ CHECK: qadd16gt r1, r2, r3 @ encoding: [0x92,0xfa,0x13,0xf1] +@ CHECK: qadd8le r1, r2, r3 @ encoding: [0x82,0xfa,0x13,0xf1] + + +@------------------------------------------------------------------------------ +@ QDADD/QDSUB +@------------------------------------------------------------------------------ + qdadd r6, r7, r8 + qdsub r6, r7, r8 + itt hi + qdaddhi r6, r7, r8 + qdsubhi r6, r7, r8 + +@ CHECK: qdadd r6, r7, r8 @ encoding: [0x88,0xfa,0x97,0xf6] +@ CHECK: qdsub r6, r7, r8 @ encoding: [0x88,0xfa,0xb7,0xf6] +@ CHECK: itt hi @ encoding: [0x84,0xbf] +@ CHECK: qdaddhi r6, r7, r8 @ encoding: [0x88,0xfa,0x97,0xf6] +@ CHECK: qdsubhi r6, r7, r8 @ encoding: [0x88,0xfa,0xb7,0xf6] + + +@------------------------------------------------------------------------------ +@ QSAX +@------------------------------------------------------------------------------ + qsax r9, r12, r0 + it eq + qsaxeq r9, r12, r0 + +@ CHECK: qsax r9, r12, r0 @ encoding: [0xec,0xfa,0x10,0xf9] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: qsaxeq r9, r12, r0 @ encoding: [0xec,0xfa,0x10,0xf9] + + +@------------------------------------------------------------------------------ +@ QSUB/QSUB16/QSUB8 +@------------------------------------------------------------------------------ + qsub r1, r2, r3 + qsub16 r1, r2, r3 + qsub8 r1, r2, r3 + itet le + qsuble r1, r2, r3 + qsub16gt r1, r2, r3 + qsub8le r1, r2, r3 + +@ CHECK: qsub r1, r2, r3 @ encoding: [0x83,0xfa,0xa2,0xf1] +@ CHECK: qsub16 r1, r2, r3 @ encoding: [0xd2,0xfa,0x13,0xf1] +@ CHECK: qsub8 r1, r2, r3 @ encoding: [0xc2,0xfa,0x13,0xf1] +@ CHECK: itet le @ encoding: [0xd6,0xbf] +@ CHECK: qsuble r1, r2, r3 @ encoding: [0x83,0xfa,0xa2,0xf1] +@ CHECK: qsub16gt r1, r2, r3 @ encoding: [0xd2,0xfa,0x13,0xf1] +@ CHECK: qsub8le r1, r2, r3 @ encoding: [0xc2,0xfa,0x13,0xf1] + + +@------------------------------------------------------------------------------ +@ RBIT +@------------------------------------------------------------------------------ + rbit r1, r2 + it ne + rbitne r1, r2 + +@ CHECK: rbit r1, r2 @ encoding: [0x92,0xfa,0xa2,0xf1] +@ CHECK: it ne @ encoding: [0x18,0xbf] +@ CHECK: rbitne r1, r2 @ encoding: [0x92,0xfa,0xa2,0xf1] + + +@------------------------------------------------------------------------------ +@ REV +@------------------------------------------------------------------------------ + rev.w r1, r2 + rev r2, r8 + itt ne + revne r1, r2 + revne r1, r8 + +@ CHECK: rev.w r1, r2 @ encoding: [0x92,0xfa,0x82,0xf1] +@ CHECK: rev.w r2, r8 @ encoding: [0x98,0xfa,0x88,0xf2] +@ CHECK: itt ne @ encoding: [0x1c,0xbf] +@ CHECK: revne r1, r2 @ encoding: [0x11,0xba] +@ CHECK: revne.w r1, r8 @ encoding: [0x98,0xfa,0x88,0xf1] + + +@------------------------------------------------------------------------------ +@ REV16 +@------------------------------------------------------------------------------ + rev16.w r1, r2 + rev16 r2, r8 + itt ne + rev16ne r1, r2 + rev16ne r1, r8 + +@ CHECK: rev16.w r1, r2 @ encoding: [0x92,0xfa,0x92,0xf1] +@ CHECK: rev16.w r2, r8 @ encoding: [0x98,0xfa,0x98,0xf2] +@ CHECK: itt ne @ encoding: [0x1c,0xbf] +@ CHECK: rev16ne r1, r2 @ encoding: [0x51,0xba] +@ CHECK: rev16ne.w r1, r8 @ encoding: [0x98,0xfa,0x98,0xf1] + + +@------------------------------------------------------------------------------ +@ REVSH +@------------------------------------------------------------------------------ + revsh.w r1, r2 + revsh r2, r8 + itt ne + revshne r1, r2 + revshne r1, r8 + +@ CHECK: revsh.w r1, r2 @ encoding: [0x92,0xfa,0xb2,0xf1] +@ CHECK: revsh.w r2, r8 @ encoding: [0x98,0xfa,0xb8,0xf2] +@ CHECK: itt ne @ encoding: [0x1c,0xbf] +@ CHECK: revshne r1, r2 @ encoding: [0xd1,0xba] +@ CHECK: revshne.w r1, r8 @ encoding: [0x98,0xfa,0xb8,0xf1] + + +@------------------------------------------------------------------------------ +@ ROR (immediate) +@------------------------------------------------------------------------------ + ror r2, r3, #12 + rors r8, r3, #31 + rors.w r2, r3, #1 + ror r2, r3, #4 + rors r2, r12, #15 + + ror r3, #19 + rors r8, #2 + rors.w r7, #5 + ror.w r12, #21 + +@ CHECK: ror.w r2, r3, #12 @ encoding: [0x4f,0xea,0x33,0x32] +@ CHECK: rors.w r8, r3, #31 @ encoding: [0x5f,0xea,0xf3,0x78] +@ CHECK: rors.w r2, r3, #1 @ encoding: [0x5f,0xea,0x73,0x02] +@ CHECK: ror.w r2, r3, #4 @ encoding: [0x4f,0xea,0x33,0x12] +@ CHECK: rors.w r2, r12, #15 @ encoding: [0x5f,0xea,0xfc,0x32] + +@ CHECK: ror.w r3, r3, #19 @ encoding: [0x4f,0xea,0xf3,0x43] +@ CHECK: rors.w r8, r8, #2 @ encoding: [0x5f,0xea,0xb8,0x08] +@ CHECK: rors.w r7, r7, #5 @ encoding: [0x5f,0xea,0x77,0x17] +@ CHECK: ror.w r12, r12, #21 @ encoding: [0x4f,0xea,0x7c,0x5c] + + +@------------------------------------------------------------------------------ +@ ROR (register) +@------------------------------------------------------------------------------ + ror r3, r4, r2 + ror.w r1, r2 + rors r3, r4, r8 + +@ CHECK: ror.w r3, r4, r2 @ encoding: [0x64,0xfa,0x02,0xf3] +@ CHECK: ror.w r1, r1, r2 @ encoding: [0x61,0xfa,0x02,0xf1] +@ CHECK: rors.w r3, r4, r8 @ encoding: [0x74,0xfa,0x08,0xf3] + + +@------------------------------------------------------------------------------ +@ RRX +@------------------------------------------------------------------------------ + rrx r1, r2 + rrxs r1, r2 + ite lt + rrxlt r9, r12 + rrxsge r8, r3 + +@ CHECK: rrx r1, r2 @ encoding: [0x4f,0xea,0x32,0x01] +@ CHECK: rrxs r1, r2 @ encoding: [0x5f,0xea,0x32,0x01] +@ CHECK: ite lt @ encoding: [0xb4,0xbf] +@ CHECK: rrxlt r9, r12 @ encoding: [0x4f,0xea,0x3c,0x09] +@ CHECK: rrxsge r8, r3 @ encoding: [0x5f,0xea,0x33,0x08] + +@------------------------------------------------------------------------------ +@ RSB (immediate) +@------------------------------------------------------------------------------ + rsb r2, r5, #0xff000 + rsbs r3, r12, #0xf + rsb r1, #0xff + rsb r1, r1, #0xff + +@ CHECK: rsb.w r2, r5, #1044480 @ encoding: [0xc5,0xf5,0x7f,0x22] +@ CHECK: rsbs.w r3, r12, #15 @ encoding: [0xdc,0xf1,0x0f,0x03] +@ CHECK: rsb.w r1, r1, #255 @ encoding: [0xc1,0xf1,0xff,0x01] +@ CHECK: rsb.w r1, r1, #255 @ encoding: [0xc1,0xf1,0xff,0x01] + + +@------------------------------------------------------------------------------ +@ RSB (register) +@------------------------------------------------------------------------------ + rsb r4, r8 + rsb r4, r9, r8 + rsb r1, r4, r8, asr #3 + rsbs r2, r1, r7, lsl #1 + +@ CHECK: rsb r4, r4, r8 @ encoding: [0xc4,0xeb,0x08,0x04] +@ CHECK: rsb r4, r9, r8 @ encoding: [0xc9,0xeb,0x08,0x04] +@ CHECK: rsb r1, r4, r8, asr #3 @ encoding: [0xc4,0xeb,0xe8,0x01] +@ CHECK: rsbs r2, r1, r7, lsl #1 @ encoding: [0xd1,0xeb,0x47,0x02] + + +@------------------------------------------------------------------------------ +@ SADD16 +@------------------------------------------------------------------------------ + sadd16 r3, r4, r8 + it ne + sadd16ne r3, r4, r8 + +@ CHECK: sadd16 r3, r4, r8 @ encoding: [0x94,0xfa,0x08,0xf3] +@ CHECK: it ne @ encoding: [0x18,0xbf] +@ CHECK: sadd16ne r3, r4, r8 @ encoding: [0x94,0xfa,0x08,0xf3] + + +@------------------------------------------------------------------------------ +@ SADD8 +@------------------------------------------------------------------------------ + sadd8 r3, r4, r8 + it ne + sadd8ne r3, r4, r8 + +@ CHECK: sadd8 r3, r4, r8 @ encoding: [0x84,0xfa,0x08,0xf3] +@ CHECK: it ne @ encoding: [0x18,0xbf] +@ CHECK: sadd8ne r3, r4, r8 @ encoding: [0x84,0xfa,0x08,0xf3] + + +@------------------------------------------------------------------------------ +@ SASX +@------------------------------------------------------------------------------ + saddsubx r9, r2, r7 + it ne + saddsubxne r2, r5, r6 + sasx r9, r2, r7 + it ne + sasxne r2, r5, r6 + +@ CHECK: sasx r9, r2, r7 @ encoding: [0xa2,0xfa,0x07,0xf9] +@ CHECK: it ne @ encoding: [0x18,0xbf] +@ CHECK: sasxne r2, r5, r6 @ encoding: [0xa5,0xfa,0x06,0xf2] +@ CHECK: sasx r9, r2, r7 @ encoding: [0xa2,0xfa,0x07,0xf9] +@ CHECK: it ne @ encoding: [0x18,0xbf] +@ CHECK: sasxne r2, r5, r6 @ encoding: [0xa5,0xfa,0x06,0xf2] + + +@------------------------------------------------------------------------------ +@ SBC (immediate) +@------------------------------------------------------------------------------ + sbc r0, r1, #4 + sbcs r0, r1, #0 + sbc r1, r2, #255 + sbc r3, r7, #0x00550055 + sbc r8, r12, #0xaa00aa00 + sbc r9, r7, #0xa5a5a5a5 + sbc r5, r3, #0x87000000 + sbc r4, r2, #0x7f800000 + sbc r4, r2, #0x00000680 + +@ CHECK: sbc r0, r1, #4 @ encoding: [0x61,0xf1,0x04,0x00] +@ CHECK: sbcs r0, r1, #0 @ encoding: [0x71,0xf1,0x00,0x00] +@ CHECK: sbc r1, r2, #255 @ encoding: [0x62,0xf1,0xff,0x01] +@ CHECK: sbc r3, r7, #5570645 @ encoding: [0x67,0xf1,0x55,0x13] +@ CHECK: sbc r8, r12, #2852170240 @ encoding: [0x6c,0xf1,0xaa,0x28] +@ CHECK: sbc r9, r7, #2779096485 @ encoding: [0x67,0xf1,0xa5,0x39] +@ CHECK: sbc r5, r3, #2264924160 @ encoding: [0x63,0xf1,0x07,0x45] +@ CHECK: sbc r4, r2, #2139095040 @ encoding: [0x62,0xf1,0xff,0x44] +@ CHECK: sbc r4, r2, #1664 @ encoding: [0x62,0xf5,0xd0,0x64] + + +@------------------------------------------------------------------------------ +@ SBC (register) +@------------------------------------------------------------------------------ + sbc r4, r5, r6 + sbcs r4, r5, r6 + sbc.w r9, r1, r3 + sbcs.w r9, r1, r3 + sbc r0, r1, r3, ror #4 + sbcs r0, r1, r3, lsl #7 + sbc.w r0, r1, r3, lsr #31 + sbcs.w r0, r1, r3, asr #32 + +@ CHECK: sbc.w r4, r5, r6 @ encoding: [0x65,0xeb,0x06,0x04] +@ CHECK: sbcs.w r4, r5, r6 @ encoding: [0x75,0xeb,0x06,0x04] +@ CHECK: sbc.w r9, r1, r3 @ encoding: [0x61,0xeb,0x03,0x09] +@ CHECK: sbcs.w r9, r1, r3 @ encoding: [0x71,0xeb,0x03,0x09] +@ CHECK: sbc.w r0, r1, r3, ror #4 @ encoding: [0x61,0xeb,0x33,0x10] +@ CHECK: sbcs.w r0, r1, r3, lsl #7 @ encoding: [0x71,0xeb,0xc3,0x10] +@ CHECK: sbc.w r0, r1, r3, lsr #31 @ encoding: [0x61,0xeb,0xd3,0x70] +@ CHECK: sbcs.w r0, r1, r3, asr #32 @ encoding: [0x71,0xeb,0x23,0x00] + + +@------------------------------------------------------------------------------ +@ SBFX +@------------------------------------------------------------------------------ + sbfx r4, r5, #16, #1 + it gt + sbfxgt r4, r5, #16, #16 + +@ CHECK: sbfx r4, r5, #16, #1 @ encoding: [0x45,0xf3,0x00,0x44] +@ CHECK: it gt @ encoding: [0xc8,0xbf] +@ CHECK: sbfxgt r4, r5, #16, #16 @ encoding: [0x45,0xf3,0x0f,0x44] + + +@------------------------------------------------------------------------------ +@ SEL +@------------------------------------------------------------------------------ + sel r5, r9, r2 + it le + selle r5, r9, r2 + +@ CHECK: sel r5, r9, r2 @ encoding: [0xa9,0xfa,0x82,0xf5] +@ CHECK: it le @ encoding: [0xd8,0xbf] +@ CHECK: selle r5, r9, r2 @ encoding: [0xa9,0xfa,0x82,0xf5] + + +@------------------------------------------------------------------------------ +@ SEV +@------------------------------------------------------------------------------ + sev.w + it eq + seveq.w + +@ CHECK: sev.w @ encoding: [0xaf,0xf3,0x04,0x80] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: seveq.w @ encoding: [0xaf,0xf3,0x04,0x80] + + +@------------------------------------------------------------------------------ +@ SADD16/SADD8 +@------------------------------------------------------------------------------ + sadd16 r1, r2, r3 + sadd8 r1, r2, r3 + ite gt + sadd16gt r1, r2, r3 + sadd8le r1, r2, r3 + +@ CHECK: sadd16 r1, r2, r3 @ encoding: [0x92,0xfa,0x03,0xf1] +@ CHECK: sadd8 r1, r2, r3 @ encoding: [0x82,0xfa,0x03,0xf1] +@ CHECK: ite gt @ encoding: [0xcc,0xbf] +@ CHECK: sadd16gt r1, r2, r3 @ encoding: [0x92,0xfa,0x03,0xf1] +@ CHECK: sadd8le r1, r2, r3 @ encoding: [0x82,0xfa,0x03,0xf1] + + +@------------------------------------------------------------------------------ +@ SHASX +@------------------------------------------------------------------------------ + shasx r4, r8, r2 + it gt + shasxgt r4, r8, r2 + shaddsubx r4, r8, r2 + it gt + shaddsubxgt r4, r8, r2 + +@ CHECK: shasx r4, r8, r2 @ encoding: [0xa8,0xfa,0x22,0xf4] +@ CHECK: it gt @ encoding: [0xc8,0xbf] +@ CHECK: shasxgt r4, r8, r2 @ encoding: [0xa8,0xfa,0x22,0xf4] +@ CHECK: shasx r4, r8, r2 @ encoding: [0xa8,0xfa,0x22,0xf4] +@ CHECK: it gt @ encoding: [0xc8,0xbf] +@ CHECK: shasxgt r4, r8, r2 @ encoding: [0xa8,0xfa,0x22,0xf4] + + +@------------------------------------------------------------------------------ +@ SHASX +@------------------------------------------------------------------------------ + shsax r4, r8, r2 + it gt + shsaxgt r4, r8, r2 + shsubaddx r4, r8, r2 + it gt + shsubaddxgt r4, r8, r2 + +@ CHECK: shsax r4, r8, r2 @ encoding: [0xe8,0xfa,0x22,0xf4] +@ CHECK: it gt @ encoding: [0xc8,0xbf] +@ CHECK: shsaxgt r4, r8, r2 @ encoding: [0xe8,0xfa,0x22,0xf4] +@ CHECK: shsax r4, r8, r2 @ encoding: [0xe8,0xfa,0x22,0xf4] +@ CHECK: it gt @ encoding: [0xc8,0xbf] +@ CHECK: shsaxgt r4, r8, r2 @ encoding: [0xe8,0xfa,0x22,0xf4] + + +@------------------------------------------------------------------------------ +@ SHSUB16/SHSUB8 +@------------------------------------------------------------------------------ + shsub16 r4, r8, r2 + shsub8 r4, r8, r2 + itt gt + shsub16gt r4, r8, r2 + shsub8gt r4, r8, r2 + +@ CHECK: shsub16 r4, r8, r2 @ encoding: [0xd8,0xfa,0x22,0xf4] +@ CHECK: shsub8 r4, r8, r2 @ encoding: [0xc8,0xfa,0x22,0xf4] +@ CHECK: itt gt @ encoding: [0xc4,0xbf] +@ CHECK: shsub16gt r4, r8, r2 @ encoding: [0xd8,0xfa,0x22,0xf4] +@ CHECK: shsub8gt r4, r8, r2 @ encoding: [0xc8,0xfa,0x22,0xf4] + + +@------------------------------------------------------------------------------ +@ SMLABB/SMLABT/SMLATB/SMLATT +@------------------------------------------------------------------------------ + smlabb r3, r1, r9, r0 + smlabt r5, r6, r4, r1 + smlatb r4, r2, r3, r2 + smlatt r8, r3, r8, r4 + itete gt + smlabbgt r3, r1, r9, r0 + smlabtle r5, r6, r4, r1 + smlatbgt r4, r2, r3, r2 + smlattle r8, r3, r8, r4 + +@ CHECK: smlabb r3, r1, r9, r0 @ encoding: [0x11,0xfb,0x09,0x03] +@ CHECK: smlabt r5, r6, r4, r1 @ encoding: [0x16,0xfb,0x14,0x15] +@ CHECK: smlatb r4, r2, r3, r2 @ encoding: [0x12,0xfb,0x23,0x24] +@ CHECK: smlatt r8, r3, r8, r4 @ encoding: [0x13,0xfb,0x38,0x48] +@ CHECK: itete gt @ encoding: [0xcb,0xbf] +@ CHECK: smlabbgt r3, r1, r9, r0 @ encoding: [0x11,0xfb,0x09,0x03] +@ CHECK: smlabtle r5, r6, r4, r1 @ encoding: [0x16,0xfb,0x14,0x15] +@ CHECK: smlatbgt r4, r2, r3, r2 @ encoding: [0x12,0xfb,0x23,0x24] +@ CHECK: smlattle r8, r3, r8, r4 @ encoding: [0x13,0xfb,0x38,0x48] + + +@------------------------------------------------------------------------------ +@ SMLAD/SMLADX +@------------------------------------------------------------------------------ + smlad r2, r3, r5, r8 + smladx r2, r3, r5, r8 + itt hi + smladhi r2, r3, r5, r8 + smladxhi r2, r3, r5, r8 + +@ CHECK: smlad r2, r3, r5, r8 @ encoding: [0x23,0xfb,0x05,0x82] +@ CHECK: smladx r2, r3, r5, r8 @ encoding: [0x23,0xfb,0x15,0x82] +@ CHECK: itt hi @ encoding: [0x84,0xbf] +@ CHECK: smladhi r2, r3, r5, r8 @ encoding: [0x23,0xfb,0x05,0x82] +@ CHECK: smladxhi r2, r3, r5, r8 @ encoding: [0x23,0xfb,0x15,0x82] + + +@------------------------------------------------------------------------------ +@ SMLAL +@------------------------------------------------------------------------------ + smlal r2, r3, r5, r8 + it eq + smlaleq r2, r3, r5, r8 + +@ CHECK: smlal r2, r3, r5, r8 @ encoding: [0xc5,0xfb,0x08,0x23] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: smlaleq r2, r3, r5, r8 @ encoding: [0xc5,0xfb,0x08,0x23] + + +@------------------------------------------------------------------------------ +@ SMLALBB/SMLALBT/SMLALTB/SMLALTT +@------------------------------------------------------------------------------ + smlalbb r3, r1, r9, r0 + smlalbt r5, r6, r4, r1 + smlaltb r4, r2, r3, r2 + smlaltt r8, r3, r8, r4 + iteet ge + smlalbbge r3, r1, r9, r0 + smlalbtlt r5, r6, r4, r1 + smlaltblt r4, r2, r3, r2 + smlalttge r8, r3, r8, r4 + +@ CHECK: smlalbb r3, r1, r9, r0 @ encoding: [0xc9,0xfb,0x80,0x31] +@ CHECK: smlalbt r5, r6, r4, r1 @ encoding: [0xc4,0xfb,0x91,0x56] +@ CHECK: smlaltb r4, r2, r3, r2 @ encoding: [0xc3,0xfb,0xa2,0x42] +@ CHECK: smlaltt r8, r3, r8, r4 @ encoding: [0xc8,0xfb,0xb4,0x83] +@ CHECK: iteet ge @ encoding: [0xad,0xbf] +@ CHECK: smlalbbge r3, r1, r9, r0 @ encoding: [0xc9,0xfb,0x80,0x31] +@ CHECK: smlalbtlt r5, r6, r4, r1 @ encoding: [0xc4,0xfb,0x91,0x56] +@ CHECK: smlaltblt r4, r2, r3, r2 @ encoding: [0xc3,0xfb,0xa2,0x42] +@ CHECK: smlalttge r8, r3, r8, r4 @ encoding: [0xc8,0xfb,0xb4,0x83] + + +@------------------------------------------------------------------------------ +@ SMLALD/SMLALDX +@------------------------------------------------------------------------------ + smlald r2, r3, r5, r8 + smlaldx r2, r3, r5, r8 + ite eq + smlaldeq r2, r3, r5, r8 + smlaldxne r2, r3, r5, r8 + +@ CHECK: smlald r2, r3, r5, r8 @ encoding: [0xc5,0xfb,0xc8,0x23] +@ CHECK: smlaldx r2, r3, r5, r8 @ encoding: [0xc5,0xfb,0xd8,0x23] +@ CHECK: ite eq @ encoding: [0x0c,0xbf] +@ CHECK: smlaldeq r2, r3, r5, r8 @ encoding: [0xc5,0xfb,0xc8,0x23] +@ CHECK: smlaldxne r2, r3, r5, r8 @ encoding: [0xc5,0xfb,0xd8,0x23] + + +@------------------------------------------------------------------------------ +@ SMLAWB/SMLAWT +@------------------------------------------------------------------------------ + smlawb r2, r3, r10, r8 + smlawt r8, r3, r5, r9 + ite eq + smlawbeq r2, r7, r5, r8 + smlawtne r1, r3, r0, r8 + +@ CHECK: smlawb r2, r3, r10, r8 @ encoding: [0x33,0xfb,0x0a,0x82] +@ CHECK: smlawt r8, r3, r5, r9 @ encoding: [0x33,0xfb,0x15,0x98] +@ CHECK: ite eq @ encoding: [0x0c,0xbf] +@ CHECK: smlawbeq r2, r7, r5, r8 @ encoding: [0x37,0xfb,0x05,0x82] +@ CHECK: smlawtne r1, r3, r0, r8 @ encoding: [0x33,0xfb,0x10,0x81] + + +@------------------------------------------------------------------------------ +@ SMLSD/SMLSDX +@------------------------------------------------------------------------------ + smlsd r2, r3, r5, r8 + smlsdx r2, r3, r5, r8 + ite le + smlsdle r2, r3, r5, r8 + smlsdxgt r2, r3, r5, r8 + +@ CHECK: smlsd r2, r3, r5, r8 @ encoding: [0x43,0xfb,0x05,0x82] +@ CHECK: smlsdx r2, r3, r5, r8 @ encoding: [0x43,0xfb,0x15,0x82] +@ CHECK: ite le @ encoding: [0xd4,0xbf] +@ CHECK: smlsdle r2, r3, r5, r8 @ encoding: [0x43,0xfb,0x05,0x82] +@ CHECK: smlsdxgt r2, r3, r5, r8 @ encoding: [0x43,0xfb,0x15,0x82] + + +@------------------------------------------------------------------------------ +@ SMLSLD/SMLSLDX +@------------------------------------------------------------------------------ + smlsld r2, r9, r5, r1 + smlsldx r4, r11, r2, r8 + ite ge + smlsldge r8, r2, r5, r6 + smlsldxlt r1, r0, r3, r8 + +@ CHECK: smlsld r2, r9, r5, r1 @ encoding: [0xd5,0xfb,0xc1,0x29] +@ CHECK: smlsldx r4, r11, r2, r8 @ encoding: [0xd2,0xfb,0xd8,0x4b] +@ CHECK: ite ge @ encoding: [0xac,0xbf] +@ CHECK: smlsldge r8, r2, r5, r6 @ encoding: [0xd5,0xfb,0xc6,0x82] +@ CHECK: smlsldxlt r1, r0, r3, r8 @ encoding: [0xd3,0xfb,0xd8,0x10] + + +@------------------------------------------------------------------------------ +@ SMMLA/SMMLAR +@------------------------------------------------------------------------------ + smmla r1, r2, r3, r4 + smmlar r4, r3, r2, r1 + ite lo + smmlalo r1, r2, r3, r4 + smmlarcs r4, r3, r2, r1 + +@ CHECK: smmla r1, r2, r3, r4 @ encoding: [0x52,0xfb,0x03,0x41] +@ CHECK: smmlar r4, r3, r2, r1 @ encoding: [0x53,0xfb,0x12,0x14] +@ CHECK: ite lo @ encoding: [0x34,0xbf] +@ CHECK: smmlalo r1, r2, r3, r4 @ encoding: [0x52,0xfb,0x03,0x41] +@ CHECK: smmlarhs r4, r3, r2, r1 @ encoding: [0x53,0xfb,0x12,0x14] + + +@------------------------------------------------------------------------------ +@ SMMLS/SMMLSR +@------------------------------------------------------------------------------ + smmls r1, r2, r3, r4 + smmlsr r4, r3, r2, r1 + ite lo + smmlslo r1, r2, r3, r4 + smmlsrcs r4, r3, r2, r1 + +@ CHECK: smmls r1, r2, r3, r4 @ encoding: [0x62,0xfb,0x03,0x41] +@ CHECK: smmlsr r4, r3, r2, r1 @ encoding: [0x63,0xfb,0x12,0x14] +@ CHECK: ite lo @ encoding: [0x34,0xbf] +@ CHECK: smmlslo r1, r2, r3, r4 @ encoding: [0x62,0xfb,0x03,0x41] +@ CHECK: smmlsrhs r4, r3, r2, r1 @ encoding: [0x63,0xfb,0x12,0x14] + + +@------------------------------------------------------------------------------ +@ SMMUL/SMMULR +@------------------------------------------------------------------------------ + smmul r2, r3, r4 + smmulr r3, r2, r1 + ite cc + smmulcc r2, r3, r4 + smmulrhs r3, r2, r1 + +@ CHECK: smmul r2, r3, r4 @ encoding: [0x53,0xfb,0x04,0xf2] +@ CHECK: smmulr r3, r2, r1 @ encoding: [0x52,0xfb,0x11,0xf3] +@ CHECK: ite lo @ encoding: [0x34,0xbf] +@ CHECK: smmullo r2, r3, r4 @ encoding: [0x53,0xfb,0x04,0xf2] +@ CHECK: smmulrhs r3, r2, r1 @ encoding: [0x52,0xfb,0x11,0xf3] + + +@------------------------------------------------------------------------------ +@ SMUAD/SMUADX +@------------------------------------------------------------------------------ + smuad r2, r3, r4 + smuadx r3, r2, r1 + ite lt + smuadlt r2, r3, r4 + smuadxge r3, r2, r1 + +@ CHECK: smuad r2, r3, r4 @ encoding: [0x23,0xfb,0x04,0xf2] +@ CHECK: smuadx r3, r2, r1 @ encoding: [0x22,0xfb,0x11,0xf3] +@ CHECK: ite lt @ encoding: [0xb4,0xbf] +@ CHECK: smuadlt r2, r3, r4 @ encoding: [0x23,0xfb,0x04,0xf2] +@ CHECK: smuadxge r3, r2, r1 @ encoding: [0x22,0xfb,0x11,0xf3] + + +@------------------------------------------------------------------------------ +@ SMULBB/SMULBT/SMULTB/SMULTT +@------------------------------------------------------------------------------ + smulbb r3, r9, r0 + smulbt r5, r4, r1 + smultb r4, r2, r2 + smultt r8, r3, r4 + itete ge + smulbbge r1, r9, r0 + smulbtlt r5, r6, r4 + smultbge r2, r3, r2 + smulttlt r8, r3, r4 + +@ CHECK: smulbb r3, r9, r0 @ encoding: [0x19,0xfb,0x00,0xf3] +@ CHECK: smulbt r5, r4, r1 @ encoding: [0x14,0xfb,0x11,0xf5] +@ CHECK: smultb r4, r2, r2 @ encoding: [0x12,0xfb,0x22,0xf4] +@ CHECK: smultt r8, r3, r4 @ encoding: [0x13,0xfb,0x34,0xf8] +@ CHECK: itete ge @ encoding: [0xab,0xbf] +@ CHECK: smulbbge r1, r9, r0 @ encoding: [0x19,0xfb,0x00,0xf1] +@ CHECK: smulbtlt r5, r6, r4 @ encoding: [0x16,0xfb,0x14,0xf5] +@ CHECK: smultbge r2, r3, r2 @ encoding: [0x13,0xfb,0x22,0xf2] +@ CHECK: smulttlt r8, r3, r4 @ encoding: [0x13,0xfb,0x34,0xf8] + + +@------------------------------------------------------------------------------ +@ SMULL +@------------------------------------------------------------------------------ + smull r3, r9, r0, r1 + it eq + smulleq r8, r3, r4, r5 + +@ CHECK: smull r3, r9, r0, r1 @ encoding: [0x80,0xfb,0x01,0x39] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: smulleq r8, r3, r4, r5 @ encoding: [0x84,0xfb,0x05,0x83] + + +@------------------------------------------------------------------------------ +@ SMULWB/SMULWT +@------------------------------------------------------------------------------ + smulwb r3, r9, r0 + smulwt r3, r9, r2 + ite gt + smulwbgt r3, r9, r0 + smulwtle r3, r9, r2 + +@ CHECK: smulwb r3, r9, r0 @ encoding: [0x39,0xfb,0x00,0xf3] +@ CHECK: smulwt r3, r9, r2 @ encoding: [0x39,0xfb,0x12,0xf3] +@ CHECK: ite gt @ encoding: [0xcc,0xbf] +@ CHECK: smulwbgt r3, r9, r0 @ encoding: [0x39,0xfb,0x00,0xf3] +@ CHECK: smulwtle r3, r9, r2 @ encoding: [0x39,0xfb,0x12,0xf3] + + +@------------------------------------------------------------------------------ +@ SMUSD/SMUSDX +@------------------------------------------------------------------------------ + smusd r3, r0, r1 + smusdx r3, r9, r2 + ite eq + smusdeq r8, r3, r2 + smusdxne r7, r4, r3 + +@ CHECK: smusd r3, r0, r1 @ encoding: [0x40,0xfb,0x01,0xf3] +@ CHECK: smusdx r3, r9, r2 @ encoding: [0x49,0xfb,0x12,0xf3] +@ CHECK: ite eq @ encoding: [0x0c,0xbf] +@ CHECK: smusdeq r8, r3, r2 @ encoding: [0x43,0xfb,0x02,0xf8] +@ CHECK: smusdxne r7, r4, r3 @ encoding: [0x44,0xfb,0x13,0xf7] + + +@------------------------------------------------------------------------------ +@ SRS +@------------------------------------------------------------------------------ + srsdb sp, #1 + srsia sp, #0 + + srsdb sp!, #19 + srsia sp!, #2 + + srsea sp, #10 + srsfd sp, #9 + + srsea sp!, #5 + srsfd sp!, #5 + + srs sp, #5 + srs sp!, #5 + +@ CHECK: srsdb sp, #1 @ encoding: [0x0d,0xe8,0x01,0xc0] +@ CHECK: srsia sp, #0 @ encoding: [0x8d,0xe9,0x00,0xc0] +@ CHECK: srsdb sp!, #19 @ encoding: [0x2d,0xe8,0x13,0xc0] +@ CHECK: srsia sp!, #2 @ encoding: [0xad,0xe9,0x02,0xc0] +@ CHECK: srsdb sp, #10 @ encoding: [0x0d,0xe8,0x0a,0xc0] +@ CHECK: srsia sp, #9 @ encoding: [0x8d,0xe9,0x09,0xc0] +@ CHECK: srsdb sp!, #5 @ encoding: [0x2d,0xe8,0x05,0xc0] +@ CHECK: srsia sp!, #5 @ encoding: [0xad,0xe9,0x05,0xc0] +@ CHECK: srsia sp, #5 @ encoding: [0x8d,0xe9,0x05,0xc0] +@ CHECK: srsia sp!, #5 @ encoding: [0xad,0xe9,0x05,0xc0] + + +@------------------------------------------------------------------------------ +@ SSAT +@------------------------------------------------------------------------------ + ssat r8, #1, r10 + ssat r8, #1, r10, lsl #0 + ssat r8, #1, r10, lsl #31 + ssat r8, #1, r10, asr #1 + +@ CHECK: ssat r8, #1, r10 @ encoding: [0x0a,0xf3,0x00,0x08] +@ CHECK: ssat r8, #1, r10 @ encoding: [0x0a,0xf3,0x00,0x08] +@ CHECK: ssat r8, #1, r10, lsl #31 @ encoding: [0x0a,0xf3,0xc0,0x78] +@ CHECK: ssat r8, #1, r10, asr #1 @ encoding: [0x2a,0xf3,0x40,0x08] + + +@------------------------------------------------------------------------------ +@ SSAT16 +@------------------------------------------------------------------------------ + ssat16 r2, #1, r7 + ssat16 r3, #16, r5 + +@ CHECK: ssat16 r2, #1, r7 @ encoding: [0x27,0xf3,0x00,0x02] +@ CHECK: ssat16 r3, #16, r5 @ encoding: [0x25,0xf3,0x0f,0x03] + + +@------------------------------------------------------------------------------ +@ SSAX +@------------------------------------------------------------------------------ + ssubaddx r2, r3, r4 + it lt + ssubaddxlt r2, r3, r4 + ssax r2, r3, r4 + it lt + ssaxlt r2, r3, r4 + +@ CHECK: ssax r2, r3, r4 @ encoding: [0xe3,0xfa,0x04,0xf2] +@ CHECK: it lt @ encoding: [0xb8,0xbf] +@ CHECK: ssaxlt r2, r3, r4 @ encoding: [0xe3,0xfa,0x04,0xf2] +@ CHECK: ssax r2, r3, r4 @ encoding: [0xe3,0xfa,0x04,0xf2] +@ CHECK: it lt @ encoding: [0xb8,0xbf] +@ CHECK: ssaxlt r2, r3, r4 @ encoding: [0xe3,0xfa,0x04,0xf2] + + +@------------------------------------------------------------------------------ +@ SSUB16/SSUB8 +@------------------------------------------------------------------------------ + ssub16 r1, r0, r6 + ssub8 r9, r2, r4 + ite ne + ssub16ne r5, r3, r2 + ssub8eq r5, r1, r2 + +@ CHECK: ssub16 r1, r0, r6 @ encoding: [0xd0,0xfa,0x06,0xf1] +@ CHECK: ssub8 r9, r2, r4 @ encoding: [0xc2,0xfa,0x04,0xf9] +@ CHECK: ite ne @ encoding: [0x14,0xbf] +@ CHECK: ssub16ne r5, r3, r2 @ encoding: [0xd3,0xfa,0x02,0xf5] +@ CHECK: ssub8eq r5, r1, r2 @ encoding: [0xc1,0xfa,0x02,0xf5] + + +@------------------------------------------------------------------------------ +@ STC{L}/STC2{L} +@------------------------------------------------------------------------------ + stc2 p0, c8, [r1, #4] + stc2 p1, c7, [r2] + stc2 p2, c6, [r3, #-224] + stc2 p3, c5, [r4, #-120]! + stc2 p4, c4, [r5], #16 + stc2 p5, c3, [r6], #-72 + stc2l p6, c2, [r7, #4] + stc2l p7, c1, [r8] + stc2l p8, c0, [r9, #-224] + stc2l p9, c1, [r10, #-120]! + stc2l p10, c2, [r11], #16 + stc2l p11, c3, [r12], #-72 + + stc p12, c4, [r0, #4] + stc p13, c5, [r1] + stc p14, c6, [r2, #-224] + stc p15, c7, [r3, #-120]! + stc p5, c8, [r4], #16 + stc p4, c9, [r5], #-72 + stcl p3, c10, [r6, #4] + stcl p2, c11, [r7] + stcl p1, c12, [r8, #-224] + stcl p0, c13, [r9, #-120]! + stcl p6, c14, [r10], #16 + stcl p7, c15, [r11], #-72 + + stc2 p2, c8, [r1], { 25 } + +@ CHECK: stc2 p0, c8, [r1, #4] @ encoding: [0x81,0xfd,0x01,0x80] +@ CHECK: stc2 p1, c7, [r2] @ encoding: [0x82,0xfd,0x00,0x71] +@ CHECK: stc2 p2, c6, [r3, #-224] @ encoding: [0x03,0xfd,0x38,0x62] +@ CHECK: stc2 p3, c5, [r4, #-120]! @ encoding: [0x24,0xfd,0x1e,0x53] +@ CHECK: stc2 p4, c4, [r5], #16 @ encoding: [0xa5,0xfc,0x04,0x44] +@ CHECK: stc2 p5, c3, [r6], #-72 @ encoding: [0x26,0xfc,0x12,0x35] +@ CHECK: stc2l p6, c2, [r7, #4] @ encoding: [0xc7,0xfd,0x01,0x26] +@ CHECK: stc2l p7, c1, [r8] @ encoding: [0xc8,0xfd,0x00,0x17] +@ CHECK: stc2l p8, c0, [r9, #-224] @ encoding: [0x49,0xfd,0x38,0x08] +@ CHECK: stc2l p9, c1, [r10, #-120]! @ encoding: [0x6a,0xfd,0x1e,0x19] +@ CHECK: stc2l p10, c2, [r11], #16 @ encoding: [0xeb,0xfc,0x04,0x2a] +@ CHECK: stc2l p11, c3, [r12], #-72 @ encoding: [0x6c,0xfc,0x12,0x3b] + +@ CHECK: stc p12, c4, [r0, #4] @ encoding: [0x80,0xed,0x01,0x4c] +@ CHECK: stc p13, c5, [r1] @ encoding: [0x81,0xed,0x00,0x5d] +@ CHECK: stc p14, c6, [r2, #-224] @ encoding: [0x02,0xed,0x38,0x6e] +@ CHECK: stc p15, c7, [r3, #-120]! @ encoding: [0x23,0xed,0x1e,0x7f] +@ CHECK: stc p5, c8, [r4], #16 @ encoding: [0xa4,0xec,0x04,0x85] +@ CHECK: stc p4, c9, [r5], #-72 @ encoding: [0x25,0xec,0x12,0x94] +@ CHECK: stcl p3, c10, [r6, #4] @ encoding: [0xc6,0xed,0x01,0xa3] +@ CHECK: stcl p2, c11, [r7] @ encoding: [0xc7,0xed,0x00,0xb2] +@ CHECK: stcl p1, c12, [r8, #-224] @ encoding: [0x48,0xed,0x38,0xc1] +@ CHECK: stcl p0, c13, [r9, #-120]! @ encoding: [0x69,0xed,0x1e,0xd0] +@ CHECK: stcl p6, c14, [r10], #16 @ encoding: [0xea,0xec,0x04,0xe6] +@ CHECK: stcl p7, c15, [r11], #-72 @ encoding: [0x6b,0xec,0x12,0xf7] + +@ CHECK: stc2 p2, c8, [r1], {25} @ encoding: [0x81,0xfc,0x19,0x82] + + +@------------------------------------------------------------------------------ +@ STMIA +@------------------------------------------------------------------------------ + stmia.w r4, {r4, r5, r8, r9} + stmia.w r4, {r5, r6} + stmia.w r5!, {r3, r8} + stm.w r4, {r4, r5, r8, r9} + stm.w r4, {r5, r6} + stm.w r5!, {r3, r8} + stm.w r5!, {r1, r2} + stm.w r2, {r1, r2} + + stmia r4, {r4, r5, r8, r9} + stmia r4, {r5, r6} + stmia r5!, {r3, r8} + stm r4, {r4, r5, r8, r9} + stm r4, {r5, r6} + stm r5!, {r3, r8} + stmea r5!, {r3, r8} + +@ CHECK: stm.w r4, {r4, r5, r8, r9} @ encoding: [0x84,0xe8,0x30,0x03] +@ CHECK: stm.w r4, {r5, r6} @ encoding: [0x84,0xe8,0x60,0x00] +@ CHECK: stm.w r5!, {r3, r8} @ encoding: [0xa5,0xe8,0x08,0x01] +@ CHECK: stm.w r4, {r4, r5, r8, r9} @ encoding: [0x84,0xe8,0x30,0x03] +@ CHECK: stm.w r4, {r5, r6} @ encoding: [0x84,0xe8,0x60,0x00] +@ CHECK: stm.w r5!, {r3, r8} @ encoding: [0xa5,0xe8,0x08,0x01] +@ CHECK: stm.w r5!, {r1, r2} @ encoding: [0xa5,0xe8,0x06,0x00] +@ CHECK: stm.w r2, {r1, r2} @ encoding: [0x82,0xe8,0x06,0x00] + +@ CHECK: stm.w r4, {r4, r5, r8, r9} @ encoding: [0x84,0xe8,0x30,0x03] +@ CHECK: stm.w r4, {r5, r6} @ encoding: [0x84,0xe8,0x60,0x00] +@ CHECK: stm.w r5!, {r3, r8} @ encoding: [0xa5,0xe8,0x08,0x01] +@ CHECK: stm.w r4, {r4, r5, r8, r9} @ encoding: [0x84,0xe8,0x30,0x03] +@ CHECK: stm.w r4, {r5, r6} @ encoding: [0x84,0xe8,0x60,0x00] +@ CHECK: stm.w r5!, {r3, r8} @ encoding: [0xa5,0xe8,0x08,0x01] +@ CHECK: stm.w r5!, {r3, r8} @ encoding: [0xa5,0xe8,0x08,0x01] + + +@------------------------------------------------------------------------------ +@ STMDB +@------------------------------------------------------------------------------ + stmdb r4, {r4, r5, r8, r9} + stmdb r4, {r5, r6} + stmdb r5!, {r3, r8} + stmea r5!, {r3, r8} + +@ CHECK: stmdb r4, {r4, r5, r8, r9} @ encoding: [0x04,0xe9,0x30,0x03] +@ CHECK: stmdb r4, {r5, r6} @ encoding: [0x04,0xe9,0x60,0x00] +@ CHECK: stmdb r5!, {r3, r8} @ encoding: [0x25,0xe9,0x08,0x01] +@ CHECK: stm.w r5!, {r3, r8} @ encoding: [0xa5,0xe8,0x08,0x01] + + +@------------------------------------------------------------------------------ +@ STR(immediate) +@------------------------------------------------------------------------------ + str r5, [r5, #-4] + str r5, [r6, #32] + str r5, [r6, #33] + str r5, [r6, #257] + str.w pc, [r7, #257] + str r2, [r4, #255]! + str r8, [sp, #4]! + str lr, [sp, #-4]! + str r2, [r4], #255 + str r8, [sp], #4 + str lr, [sp], #-4 + +@ CHECK: str r5, [r5, #-4] @ encoding: [0x45,0xf8,0x04,0x5c] +@ CHECK: str r5, [r6, #32] @ encoding: [0x35,0x62] +@ CHECK: str.w r5, [r6, #33] @ encoding: [0xc6,0xf8,0x21,0x50] +@ CHECK: str.w r5, [r6, #257] @ encoding: [0xc6,0xf8,0x01,0x51] +@ CHECK: str.w pc, [r7, #257] @ encoding: [0xc7,0xf8,0x01,0xf1] +@ CHECK: str r2, [r4, #255]! @ encoding: [0x44,0xf8,0xff,0x2f] +@ CHECK: str r8, [sp, #4]! @ encoding: [0x4d,0xf8,0x04,0x8f] +@ CHECK: str lr, [sp, #-4]! @ encoding: [0x4d,0xf8,0x04,0xed] +@ CHECK: str r2, [r4], #255 @ encoding: [0x44,0xf8,0xff,0x2b] +@ CHECK: str r8, [sp], #4 @ encoding: [0x4d,0xf8,0x04,0x8b] +@ CHECK: str lr, [sp], #-4 @ encoding: [0x4d,0xf8,0x04,0xe9] + + +@------------------------------------------------------------------------------ +@ STR(register) +@------------------------------------------------------------------------------ + str r1, [r8, r1] + str.w r4, [r5, r2] + str r6, [r0, r2, lsl #3] + str r8, [r8, r2, lsl #2] + str r7, [sp, r2, lsl #1] + str r7, [sp, r2, lsl #0] + +@ CHECK: str.w r1, [r8, r1] @ encoding: [0x48,0xf8,0x01,0x10] +@ CHECK: str.w r4, [r5, r2] @ encoding: [0x45,0xf8,0x02,0x40] +@ CHECK: str.w r6, [r0, r2, lsl #3] @ encoding: [0x40,0xf8,0x32,0x60] +@ CHECK: str.w r8, [r8, r2, lsl #2] @ encoding: [0x48,0xf8,0x22,0x80] +@ CHECK: str.w r7, [sp, r2, lsl #1] @ encoding: [0x4d,0xf8,0x12,0x70] +@ CHECK: str.w r7, [sp, r2] @ encoding: [0x4d,0xf8,0x02,0x70] + + +@------------------------------------------------------------------------------ +@ STRB(immediate) +@------------------------------------------------------------------------------ + strb r5, [r5, #-4] + strb r5, [r6, #32] + strb r5, [r6, #33] + strb r5, [r6, #257] + strb.w lr, [r7, #257] + strb r5, [r8, #255]! + strb r2, [r5, #4]! + strb r1, [r4, #-4]! + strb lr, [r3], #255 + strb r9, [r2], #4 + strb r3, [sp], #-4 + strb r4, [r8, #-0]! + +@ CHECK: strb r5, [r5, #-4] @ encoding: [0x05,0xf8,0x04,0x5c] +@ CHECK: strb.w r5, [r6, #32] @ encoding: [0x86,0xf8,0x20,0x50] +@ CHECK: strb.w r5, [r6, #33] @ encoding: [0x86,0xf8,0x21,0x50] +@ CHECK: strb.w r5, [r6, #257] @ encoding: [0x86,0xf8,0x01,0x51] +@ CHECK: strb.w lr, [r7, #257] @ encoding: [0x87,0xf8,0x01,0xe1] +@ CHECK: strb r5, [r8, #255]! @ encoding: [0x08,0xf8,0xff,0x5f] +@ CHECK: strb r2, [r5, #4]! @ encoding: [0x05,0xf8,0x04,0x2f] +@ CHECK: strb r1, [r4, #-4]! @ encoding: [0x04,0xf8,0x04,0x1d] +@ CHECK: strb lr, [r3], #255 @ encoding: [0x03,0xf8,0xff,0xeb] +@ CHECK: strb r9, [r2], #4 @ encoding: [0x02,0xf8,0x04,0x9b] +@ CHECK: strb r3, [sp], #-4 @ encoding: [0x0d,0xf8,0x04,0x39] +@ CHECK: strb r4, [r8, #-0]! @ encoding: [0x08,0xf8,0x00,0x4d] + + +@------------------------------------------------------------------------------ +@ STRB(register) +@------------------------------------------------------------------------------ + strb r1, [r8, r1] + strb.w r4, [r5, r2] + strb r6, [r0, r2, lsl #3] + strb r8, [r8, r2, lsl #2] + strb r7, [sp, r2, lsl #1] + strb r7, [sp, r2, lsl #0] + +@ CHECK: strb.w r1, [r8, r1] @ encoding: [0x08,0xf8,0x01,0x10] +@ CHECK: strb.w r4, [r5, r2] @ encoding: [0x05,0xf8,0x02,0x40] +@ CHECK: strb.w r6, [r0, r2, lsl #3] @ encoding: [0x00,0xf8,0x32,0x60] +@ CHECK: strb.w r8, [r8, r2, lsl #2] @ encoding: [0x08,0xf8,0x22,0x80] +@ CHECK: strb.w r7, [sp, r2, lsl #1] @ encoding: [0x0d,0xf8,0x12,0x70] +@ CHECK: strb.w r7, [sp, r2] @ encoding: [0x0d,0xf8,0x02,0x70] + + +@------------------------------------------------------------------------------ +@ STRBT +@------------------------------------------------------------------------------ + strbt r1, [r2] + strbt r1, [r8, #0] + strbt r1, [r8, #3] + strbt r1, [r8, #255] + +@ CHECK: strbt r1, [r2] @ encoding: [0x02,0xf8,0x00,0x1e] +@ CHECK: strbt r1, [r8] @ encoding: [0x08,0xf8,0x00,0x1e] +@ CHECK: strbt r1, [r8, #3] @ encoding: [0x08,0xf8,0x03,0x1e] +@ CHECK: strbt r1, [r8, #255] @ encoding: [0x08,0xf8,0xff,0x1e] + + +@------------------------------------------------------------------------------ +@ STRD +@------------------------------------------------------------------------------ + strd r3, r5, [r6, #24] + strd r3, r5, [r6, #24]! + strd r3, r5, [r6], #4 + strd r3, r5, [r6], #-8 + strd r3, r5, [r6] + strd r8, r1, [r3, #0] + +@ CHECK: strd r3, r5, [r6, #24] @ encoding: [0xc6,0xe9,0x06,0x35] +@ CHECK: strd r3, r5, [r6, #24]! @ encoding: [0xe6,0xe9,0x06,0x35] +@ CHECK: strd r3, r5, [r6], #4 @ encoding: [0xe6,0xe8,0x01,0x35] +@ CHECK: strd r3, r5, [r6], #-8 @ encoding: [0x66,0xe8,0x02,0x35] +@ CHECK: strd r3, r5, [r6] @ encoding: [0xc6,0xe9,0x00,0x35] +@ CHECK: strd r8, r1, [r3] @ encoding: [0xc3,0xe9,0x00,0x81] + + +@------------------------------------------------------------------------------ +@ STREX/STREXB/STREXH/STREXD +@------------------------------------------------------------------------------ + strex r1, r8, [r4] + strex r8, r2, [r4, #0] + strex r2, r12, [sp, #128] + strexb r5, r1, [r7] + strexh r9, r7, [r12] + strexd r9, r3, r6, [r4] + +@ CHECK: strex r1, r8, [r4] @ encoding: [0x44,0xe8,0x00,0x81] +@ CHECK: strex r8, r2, [r4] @ encoding: [0x44,0xe8,0x00,0x28] +@ CHECK: strex r2, r12, [sp, #128] @ encoding: [0x4d,0xe8,0x20,0xc2] +@ CHECK: strexb r5, r1, [r7] @ encoding: [0xc7,0xe8,0x45,0x1f] +@ CHECK: strexh r9, r7, [r12] @ encoding: [0xcc,0xe8,0x59,0x7f] +@ CHECK: strexd r9, r3, r6, [r4] @ encoding: [0xc4,0xe8,0x79,0x36] + + +@------------------------------------------------------------------------------ +@ STRH(immediate) +@------------------------------------------------------------------------------ + strh r5, [r5, #-4] + strh r5, [r6, #32] + strh r5, [r6, #33] + strh r5, [r6, #257] + strh.w lr, [r7, #257] + strh r5, [r8, #255]! + strh r2, [r5, #4]! + strh r1, [r4, #-4]! + strh lr, [r3], #255 + strh r9, [r2], #4 + strh r3, [sp], #-4 + +@ CHECK: strh r5, [r5, #-4] @ encoding: [0x25,0xf8,0x04,0x5c] +@ CHECK: strh r5, [r6, #32] @ encoding: [0x35,0x84] +@ CHECK: strh.w r5, [r6, #33] @ encoding: [0xa6,0xf8,0x21,0x50] +@ CHECK: strh.w r5, [r6, #257] @ encoding: [0xa6,0xf8,0x01,0x51] +@ CHECK: strh.w lr, [r7, #257] @ encoding: [0xa7,0xf8,0x01,0xe1] +@ CHECK: strh r5, [r8, #255]! @ encoding: [0x28,0xf8,0xff,0x5f] +@ CHECK: strh r2, [r5, #4]! @ encoding: [0x25,0xf8,0x04,0x2f] +@ CHECK: strh r1, [r4, #-4]! @ encoding: [0x24,0xf8,0x04,0x1d] +@ CHECK: strh lr, [r3], #255 @ encoding: [0x23,0xf8,0xff,0xeb] +@ CHECK: strh r9, [r2], #4 @ encoding: [0x22,0xf8,0x04,0x9b] +@ CHECK: strh r3, [sp], #-4 @ encoding: [0x2d,0xf8,0x04,0x39] + + +@------------------------------------------------------------------------------ +@ STRH(register) +@------------------------------------------------------------------------------ + strh r1, [r8, r1] + strh.w r4, [r5, r2] + strh r6, [r0, r2, lsl #3] + strh r8, [r8, r2, lsl #2] + strh r7, [sp, r2, lsl #1] + strh r7, [sp, r2, lsl #0] + +@ CHECK: strh.w r1, [r8, r1] @ encoding: [0x28,0xf8,0x01,0x10] +@ CHECK: strh.w r4, [r5, r2] @ encoding: [0x25,0xf8,0x02,0x40] +@ CHECK: strh.w r6, [r0, r2, lsl #3] @ encoding: [0x20,0xf8,0x32,0x60] +@ CHECK: strh.w r8, [r8, r2, lsl #2] @ encoding: [0x28,0xf8,0x22,0x80] +@ CHECK: strh.w r7, [sp, r2, lsl #1] @ encoding: [0x2d,0xf8,0x12,0x70] +@ CHECK: strh.w r7, [sp, r2] @ encoding: [0x2d,0xf8,0x02,0x70] + + +@------------------------------------------------------------------------------ +@ STRHT +@------------------------------------------------------------------------------ + strht r1, [r2] + strht r1, [r8, #0] + strht r1, [r8, #3] + strht r1, [r8, #255] + +@ CHECK: strht r1, [r2] @ encoding: [0x22,0xf8,0x00,0x1e] +@ CHECK: strht r1, [r8] @ encoding: [0x28,0xf8,0x00,0x1e] +@ CHECK: strht r1, [r8, #3] @ encoding: [0x28,0xf8,0x03,0x1e] +@ CHECK: strht r1, [r8, #255] @ encoding: [0x28,0xf8,0xff,0x1e] + + +@------------------------------------------------------------------------------ +@ STRT +@------------------------------------------------------------------------------ + strt r1, [r2] + strt r1, [r8, #0] + strt r1, [r8, #3] + strt r1, [r8, #255] + +@ CHECK: strt r1, [r2] @ encoding: [0x42,0xf8,0x00,0x1e] +@ CHECK: strt r1, [r8] @ encoding: [0x48,0xf8,0x00,0x1e] +@ CHECK: strt r1, [r8, #3] @ encoding: [0x48,0xf8,0x03,0x1e] +@ CHECK: strt r1, [r8, #255] @ encoding: [0x48,0xf8,0xff,0x1e] + + +@------------------------------------------------------------------------------ +@ SUB (immediate) +@------------------------------------------------------------------------------ + itet eq + subeq r1, r2, #4 + subwne r5, r3, #1023 + subeq r4, r5, #293 + sub r2, sp, #1024 + sub r2, r8, #0xff00 + sub r2, r3, #257 + subw r2, r3, #257 + sub r12, r6, #0x100 + subw r12, r6, #0x100 + subs r1, r2, #0x1f0 + +@ CHECK: itet eq @ encoding: [0x0a,0xbf] +@ CHECK: subeq r1, r2, #4 @ encoding: [0x11,0x1f] +@ CHECK: subwne r5, r3, #1023 @ encoding: [0xa3,0xf2,0xff,0x35] +@ CHECK: subweq r4, r5, #293 @ encoding: [0xa5,0xf2,0x25,0x14] +@ CHECK: sub.w r2, sp, #1024 @ encoding: [0xad,0xf5,0x80,0x62] +@ CHECK: sub.w r2, r8, #65280 @ encoding: [0xa8,0xf5,0x7f,0x42] +@ CHECK: subw r2, r3, #257 @ encoding: [0xa3,0xf2,0x01,0x12] +@ CHECK: subw r2, r3, #257 @ encoding: [0xa3,0xf2,0x01,0x12] +@ CHECK: sub.w r12, r6, #256 @ encoding: [0xa6,0xf5,0x80,0x7c] +@ CHECK: subw r12, r6, #256 @ encoding: [0xa6,0xf2,0x00,0x1c] +@ CHECK: subs.w r1, r2, #496 @ encoding: [0xb2,0xf5,0xf8,0x71] + + +@------------------------------------------------------------------------------ +@ SUB (register) +@------------------------------------------------------------------------------ + sub r4, r5, r6 + sub r4, r5, r6, lsl #5 + sub r4, r5, r6, lsr #5 + sub.w r4, r5, r6, lsr #5 + sub r4, r5, r6, asr #5 + sub r4, r5, r6, ror #5 + sub.w r5, r2, r12, rrx + +@ CHECK: sub.w r4, r5, r6 @ encoding: [0xa5,0xeb,0x06,0x04] +@ CHECK: sub.w r4, r5, r6, lsl #5 @ encoding: [0xa5,0xeb,0x46,0x14] +@ CHECK: sub.w r4, r5, r6, lsr #5 @ encoding: [0xa5,0xeb,0x56,0x14] +@ CHECK: sub.w r4, r5, r6, lsr #5 @ encoding: [0xa5,0xeb,0x56,0x14] +@ CHECK: sub.w r4, r5, r6, asr #5 @ encoding: [0xa5,0xeb,0x66,0x14] +@ CHECK: sub.w r4, r5, r6, ror #5 @ encoding: [0xa5,0xeb,0x76,0x14] +@ CHECK: sub.w r5, r2, r12, rrx @ encoding: [0xa2,0xeb,0x3c,0x05] + + +@------------------------------------------------------------------------------ +@ SVC +@------------------------------------------------------------------------------ + svc #0 + ite eq + svceq #255 + swine #33 + +@ CHECK: svc #0 @ encoding: [0x00,0xdf] +@ CHECK: ite eq @ encoding: [0x0c,0xbf] +@ CHECK: svceq #255 @ encoding: [0xff,0xdf] +@ CHECK: svcne #33 @ encoding: [0x21,0xdf] + + +@------------------------------------------------------------------------------ +@ SXTAB +@------------------------------------------------------------------------------ + sxtab r2, r3, r4 + sxtab r4, r5, r6, ror #0 + it lt + sxtablt r6, r2, r9, ror #8 + sxtab r5, r1, r4, ror #16 + sxtab r7, r8, r3, ror #24 + +@ CHECK: sxtab r2, r3, r4 @ encoding: [0x43,0xfa,0x84,0xf2] +@ CHECK: sxtab r4, r5, r6 @ encoding: [0x45,0xfa,0x86,0xf4] +@ CHECK: it lt @ encoding: [0xb8,0xbf] +@ CHECK: sxtablt r6, r2, r9, ror #8 @ encoding: [0x42,0xfa,0x99,0xf6] +@ CHECK: sxtab r5, r1, r4, ror #16 @ encoding: [0x41,0xfa,0xa4,0xf5] +@ CHECK: sxtab r7, r8, r3, ror #24 @ encoding: [0x48,0xfa,0xb3,0xf7] + + +@------------------------------------------------------------------------------ +@ SXTAB16 +@------------------------------------------------------------------------------ + sxtab16 r6, r2, r7, ror #0 + sxtab16 r3, r5, r8, ror #8 + sxtab16 r3, r2, r1, ror #16 + ite ne + sxtab16ne r0, r1, r4 + sxtab16eq r1, r2, r3, ror #24 + +@ CHECK: sxtab16 r6, r2, r7 @ encoding: [0x22,0xfa,0x87,0xf6] +@ CHECK: sxtab16 r3, r5, r8, ror #8 @ encoding: [0x25,0xfa,0x98,0xf3] +@ CHECK: sxtab16 r3, r2, r1, ror #16 @ encoding: [0x22,0xfa,0xa1,0xf3] +@ CHECK: ite ne @ encoding: [0x14,0xbf] +@ CHECK: sxtab16ne r0, r1, r4 @ encoding: [0x21,0xfa,0x84,0xf0] +@ CHECK: sxtab16eq r1, r2, r3, ror #24 @ encoding: [0x22,0xfa,0xb3,0xf1] + + +@------------------------------------------------------------------------------ +@ SXTAH +@------------------------------------------------------------------------------ + sxtah r1, r3, r9 + sxtah r3, r8, r3, ror #8 + sxtah r9, r3, r3, ror #24 + ite hi + sxtahhi r6, r1, r6, ror #0 + sxtahls r2, r2, r4, ror #16 + +@ CHECK: sxtah r1, r3, r9 @ encoding: [0x03,0xfa,0x89,0xf1] +@ CHECK: sxtah r3, r8, r3, ror #8 @ encoding: [0x08,0xfa,0x93,0xf3] +@ CHECK: sxtah r9, r3, r3, ror #24 @ encoding: [0x03,0xfa,0xb3,0xf9] +@ CHECK: ite hi @ encoding: [0x8c,0xbf] +@ CHECK: sxtahhi r6, r1, r6 @ encoding: [0x01,0xfa,0x86,0xf6] +@ CHECK: sxtahls r2, r2, r4, ror #16 @ encoding: [0x02,0xfa,0xa4,0xf2] + + +@------------------------------------------------------------------------------ +@ SXTB +@------------------------------------------------------------------------------ + sxtb r5, r6, ror #0 + sxtb r6, r9, ror #8 + sxtb r8, r3, ror #24 + ite ge + sxtbge r2, r4 + sxtblt r5, r1, ror #16 + sxtb.w r7, r8 + +@ CHECK: sxtb r5, r6 @ encoding: [0x75,0xb2] +@ CHECK: sxtb.w r6, r9, ror #8 @ encoding: [0x4f,0xfa,0x99,0xf6] +@ CHECK: sxtb.w r8, r3, ror #24 @ encoding: [0x4f,0xfa,0xb3,0xf8] +@ CHECK: ite ge @ encoding: [0xac,0xbf] +@ CHECK: sxtbge r2, r4 @ encoding: [0x62,0xb2] +@ CHECK: sxtblt.w r5, r1, ror #16 @ encoding: [0x4f,0xfa,0xa1,0xf5] +@ CHECK: sxtb.w r7, r8 @ encoding: [0x4f,0xfa,0x88,0xf7] + + +@------------------------------------------------------------------------------ +@ SXTB16 +@------------------------------------------------------------------------------ + sxtb16 r1, r4 + sxtb16 r6, r7, ror #0 + sxtb16 r3, r1, ror #16 + ite cs + sxtb16cs r3, r5, ror #8 + sxtb16lo r2, r3, ror #24 + +@ CHECK: sxtb16 r1, r4 @ encoding: [0x2f,0xfa,0x84,0xf1] +@ CHECK: sxtb16 r6, r7 @ encoding: [0x2f,0xfa,0x87,0xf6] +@ CHECK: sxtb16 r3, r1, ror #16 @ encoding: [0x2f,0xfa,0xa1,0xf3] +@ CHECK: ite hs @ encoding: [0x2c,0xbf] +@ CHECK: sxtb16hs r3, r5, ror #8 @ encoding: [0x2f,0xfa,0x95,0xf3] +@ CHECK: sxtb16lo r2, r3, ror #24 @ encoding: [0x2f,0xfa,0xb3,0xf2] + + +@------------------------------------------------------------------------------ +@ SXTH +@------------------------------------------------------------------------------ + sxth r1, r6, ror #0 + sxth r3, r8, ror #8 + sxth r9, r3, ror #24 + itt ne + sxthne r3, r9 + sxthne r2, r2, ror #16 + sxth.w r7, r8 + +@ CHECK: sxth r1, r6 @ encoding: [0x31,0xb2] +@ CHECK: sxth.w r3, r8, ror #8 @ encoding: [0x0f,0xfa,0x98,0xf3] +@ CHECK: sxth.w r9, r3, ror #24 @ encoding: [0x0f,0xfa,0xb3,0xf9] +@ CHECK: itt ne @ encoding: [0x1c,0xbf] +@ CHECK: sxthne.w r3, r9 @ encoding: [0x0f,0xfa,0x89,0xf3] +@ CHECK: sxthne.w r2, r2, ror #16 @ encoding: [0x0f,0xfa,0xa2,0xf2] +@ CHECK: sxth.w r7, r8 @ encoding: [0x0f,0xfa,0x88,0xf7] + + +@------------------------------------------------------------------------------ +@ SXTB +@------------------------------------------------------------------------------ + sxtb r5, r6, ror #0 + sxtb.w r6, r9, ror #8 + sxtb r8, r3, ror #24 + ite ge + sxtbge r2, r4 + sxtblt r5, r1, ror #16 + +@ CHECK: sxtb r5, r6 @ encoding: [0x75,0xb2] +@ CHECK: sxtb.w r6, r9, ror #8 @ encoding: [0x4f,0xfa,0x99,0xf6] +@ CHECK: sxtb.w r8, r3, ror #24 @ encoding: [0x4f,0xfa,0xb3,0xf8] +@ CHECK: ite ge @ encoding: [0xac,0xbf] +@ CHECK: sxtbge r2, r4 @ encoding: [0x62,0xb2] +@ CHECK: sxtblt.w r5, r1, ror #16 @ encoding: [0x4f,0xfa,0xa1,0xf5] + + +@------------------------------------------------------------------------------ +@ SXTB16 +@------------------------------------------------------------------------------ + sxtb16 r1, r4 + sxtb16 r6, r7, ror #0 + sxtb16 r3, r1, ror #16 + ite cs + sxtb16cs r3, r5, ror #8 + sxtb16lo r2, r3, ror #24 + +@ CHECK: sxtb16 r1, r4 @ encoding: [0x2f,0xfa,0x84,0xf1] +@ CHECK: sxtb16 r6, r7 @ encoding: [0x2f,0xfa,0x87,0xf6] +@ CHECK: sxtb16 r3, r1, ror #16 @ encoding: [0x2f,0xfa,0xa1,0xf3] +@ CHECK: ite hs @ encoding: [0x2c,0xbf] +@ CHECK: sxtb16hs r3, r5, ror #8 @ encoding: [0x2f,0xfa,0x95,0xf3] +@ CHECK: sxtb16lo r2, r3, ror #24 @ encoding: [0x2f,0xfa,0xb3,0xf2] + + +@------------------------------------------------------------------------------ +@ SXTH +@------------------------------------------------------------------------------ + sxth r1, r6, ror #0 + sxth.w r3, r8, ror #8 + sxth r9, r3, ror #24 + itt ne + sxthne r3, r9 + sxthne r2, r2, ror #16 + +@ CHECK: sxth r1, r6 @ encoding: [0x31,0xb2] +@ CHECK: sxth.w r3, r8, ror #8 @ encoding: [0x0f,0xfa,0x98,0xf3] +@ CHECK: sxth.w r9, r3, ror #24 @ encoding: [0x0f,0xfa,0xb3,0xf9] +@ CHECK: itt ne @ encoding: [0x1c,0xbf] +@ CHECK: sxthne.w r3, r9 @ encoding: [0x0f,0xfa,0x89,0xf3] +@ CHECK: sxthne.w r2, r2, ror #16 @ encoding: [0x0f,0xfa,0xa2,0xf2] + + +@------------------------------------------------------------------------------ +@ TBB/TBH +@------------------------------------------------------------------------------ + tbb [r3, r8] + tbh [r3, r8, lsl #1] + it eq + tbbeq [r3, r8] + it cs + tbhcs [r3, r8, lsl #1] + +@ CHECK: tbb [r3, r8] @ encoding: [0xd3,0xe8,0x08,0xf0] +@ CHECK: tbh [r3, r8, lsl #1] @ encoding: [0xd3,0xe8,0x18,0xf0] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: tbbeq [r3, r8] @ encoding: [0xd3,0xe8,0x08,0xf0] +@ CHECK: it hs @ encoding: [0x28,0xbf] +@ CHECK: tbhhs [r3, r8, lsl #1] @ encoding: [0xd3,0xe8,0x18,0xf0] + + +@------------------------------------------------------------------------------ +@ TEQ +@------------------------------------------------------------------------------ + teq r5, #0xf000 + teq r4, r5 + teq r4, r5, lsl #5 + teq r4, r5, lsr #5 + teq r4, r5, lsr #5 + teq r4, r5, asr #5 + teq r4, r5, ror #5 + +@ CHECK: teq.w r5, #61440 @ encoding: [0x95,0xf4,0x70,0x4f] +@ CHECK: teq.w r4, r5 @ encoding: [0x94,0xea,0x05,0x0f] +@ CHECK: teq.w r4, r5, lsl #5 @ encoding: [0x94,0xea,0x45,0x1f] +@ CHECK: teq.w r4, r5, lsr #5 @ encoding: [0x94,0xea,0x55,0x1f] +@ CHECK: teq.w r4, r5, lsr #5 @ encoding: [0x94,0xea,0x55,0x1f] +@ CHECK: teq.w r4, r5, asr #5 @ encoding: [0x94,0xea,0x65,0x1f] +@ CHECK: teq.w r4, r5, ror #5 @ encoding: [0x94,0xea,0x75,0x1f] + + +@------------------------------------------------------------------------------ +@ TST +@------------------------------------------------------------------------------ + tst r5, #0xf000 + tst r2, r5 + tst r3, r12, lsl #5 + tst r4, r11, lsr #4 + tst r5, r10, lsr #12 + tst r6, r9, asr #30 + tst r7, r8, ror #2 + +@ CHECK: tst.w r5, #61440 @ encoding: [0x15,0xf4,0x70,0x4f] +@ CHECK: tst r2, r5 @ encoding: [0x2a,0x42] +@ CHECK: tst.w r3, r12, lsl #5 @ encoding: [0x13,0xea,0x4c,0x1f] +@ CHECK: tst.w r4, r11, lsr #4 @ encoding: [0x14,0xea,0x1b,0x1f] +@ CHECK: tst.w r5, r10, lsr #12 @ encoding: [0x15,0xea,0x1a,0x3f] +@ CHECK: tst.w r6, r9, asr #30 @ encoding: [0x16,0xea,0xa9,0x7f] +@ CHECK: tst.w r7, r8, ror #2 @ encoding: [0x17,0xea,0xb8,0x0f] + + +@------------------------------------------------------------------------------ +@ UADD16/UADD8 +@------------------------------------------------------------------------------ + uadd16 r1, r2, r3 + uadd8 r1, r2, r3 + ite gt + uadd16gt r1, r2, r3 + uadd8le r1, r2, r3 + +@ CHECK: uadd16 r1, r2, r3 @ encoding: [0x92,0xfa,0x43,0xf1] +@ CHECK: uadd8 r1, r2, r3 @ encoding: [0x82,0xfa,0x43,0xf1] +@ CHECK: ite gt @ encoding: [0xcc,0xbf] +@ CHECK: uadd16gt r1, r2, r3 @ encoding: [0x92,0xfa,0x43,0xf1] +@ CHECK: uadd8le r1, r2, r3 @ encoding: [0x82,0xfa,0x43,0xf1] + + +@------------------------------------------------------------------------------ +@ UASX +@------------------------------------------------------------------------------ + uasx r9, r12, r0 + it eq + uasxeq r9, r12, r0 + uaddsubx r9, r12, r0 + it eq + uaddsubxeq r9, r12, r0 + +@ CHECK: uasx r9, r12, r0 @ encoding: [0xac,0xfa,0x40,0xf9] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: uasxeq r9, r12, r0 @ encoding: [0xac,0xfa,0x40,0xf9] +@ CHECK: uasx r9, r12, r0 @ encoding: [0xac,0xfa,0x40,0xf9] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: uasxeq r9, r12, r0 @ encoding: [0xac,0xfa,0x40,0xf9] + + +@------------------------------------------------------------------------------ +@ UBFX +@------------------------------------------------------------------------------ + ubfx r4, r5, #16, #1 + it gt + ubfxgt r4, r5, #16, #16 + +@ CHECK: ubfx r4, r5, #16, #1 @ encoding: [0xc5,0xf3,0x00,0x44] +@ CHECK: it gt @ encoding: [0xc8,0xbf] +@ CHECK: ubfxgt r4, r5, #16, #16 @ encoding: [0xc5,0xf3,0x0f,0x44] + + +@------------------------------------------------------------------------------ +@ UHADD16/UHADD8 +@------------------------------------------------------------------------------ + uhadd16 r4, r8, r2 + uhadd8 r4, r8, r2 + itt gt + uhadd16gt r4, r8, r2 + uhadd8gt r4, r8, r2 + +@ CHECK: uhadd16 r4, r8, r2 @ encoding: [0x98,0xfa,0x62,0xf4] +@ CHECK: uhadd8 r4, r8, r2 @ encoding: [0x88,0xfa,0x62,0xf4] +@ CHECK: itt gt @ encoding: [0xc4,0xbf] +@ CHECK: uhadd16gt r4, r8, r2 @ encoding: [0x98,0xfa,0x62,0xf4] +@ CHECK: uhadd8gt r4, r8, r2 @ encoding: [0x88,0xfa,0x62,0xf4] + + +@------------------------------------------------------------------------------ +@ UHASX/UHSAX +@------------------------------------------------------------------------------ + uhasx r4, r1, r5 + uhsax r5, r6, r6 + itt gt + uhasxgt r6, r9, r8 + uhsaxgt r7, r8, r12 + uhaddsubx r4, r1, r5 + uhsubaddx r5, r6, r6 + itt gt + uhaddsubxgt r6, r9, r8 + uhsubaddxgt r7, r8, r12 + +@ CHECK: uhasx r4, r1, r5 @ encoding: [0xa1,0xfa,0x65,0xf4] +@ CHECK: uhsax r5, r6, r6 @ encoding: [0xe6,0xfa,0x66,0xf5] +@ CHECK: itt gt @ encoding: [0xc4,0xbf] +@ CHECK: uhasxgt r6, r9, r8 @ encoding: [0xa9,0xfa,0x68,0xf6] +@ CHECK: uhsaxgt r7, r8, r12 @ encoding: [0xe8,0xfa,0x6c,0xf7] +@ CHECK: uhasx r4, r1, r5 @ encoding: [0xa1,0xfa,0x65,0xf4] +@ CHECK: uhsax r5, r6, r6 @ encoding: [0xe6,0xfa,0x66,0xf5] +@ CHECK: itt gt @ encoding: [0xc4,0xbf] +@ CHECK: uhasxgt r6, r9, r8 @ encoding: [0xa9,0xfa,0x68,0xf6] +@ CHECK: uhsaxgt r7, r8, r12 @ encoding: [0xe8,0xfa,0x6c,0xf7] + + +@------------------------------------------------------------------------------ +@ UHSUB16/UHSUB8 +@------------------------------------------------------------------------------ + uhsub16 r5, r8, r3 + uhsub8 r1, r7, r6 + itt lt + uhsub16lt r4, r9, r12 + uhsub8lt r3, r1, r5 + +@ CHECK: uhsub16 r5, r8, r3 @ encoding: [0xd8,0xfa,0x63,0xf5] +@ CHECK: uhsub8 r1, r7, r6 @ encoding: [0xc7,0xfa,0x66,0xf1] +@ CHECK: itt lt @ encoding: [0xbc,0xbf] +@ CHECK: uhsub16lt r4, r9, r12 @ encoding: [0xd9,0xfa,0x6c,0xf4] +@ CHECK: uhsub8lt r3, r1, r5 @ encoding: [0xc1,0xfa,0x65,0xf3] + + +@------------------------------------------------------------------------------ +@ UMAAL +@------------------------------------------------------------------------------ + umaal r3, r4, r5, r6 + it lt + umaallt r3, r4, r5, r6 + +@ CHECK: umaal r3, r4, r5, r6 @ encoding: [0xe5,0xfb,0x66,0x34] +@ CHECK: it lt @ encoding: [0xb8,0xbf] +@ CHECK: umaallt r3, r4, r5, r6 @ encoding: [0xe5,0xfb,0x66,0x34] + + +@------------------------------------------------------------------------------ +@ UMLAL +@------------------------------------------------------------------------------ + umlal r2, r4, r6, r8 + it gt + umlalgt r6, r1, r2, r6 + +@ CHECK: umlal r2, r4, r6, r8 @ encoding: [0xe6,0xfb,0x08,0x24] +@ CHECK: it gt @ encoding: [0xc8,0xbf] +@ CHECK: umlalgt r6, r1, r2, r6 @ encoding: [0xe2,0xfb,0x06,0x61] + + +@------------------------------------------------------------------------------ +@ UMULL +@------------------------------------------------------------------------------ + umull r2, r4, r6, r8 + it gt + umullgt r6, r1, r2, r6 + +@ CHECK: umull r2, r4, r6, r8 @ encoding: [0xa6,0xfb,0x08,0x24] +@ CHECK: it gt @ encoding: [0xc8,0xbf] +@ CHECK: umullgt r6, r1, r2, r6 @ encoding: [0xa2,0xfb,0x06,0x61] + + +@------------------------------------------------------------------------------ +@ UQADD16/UQADD8 +@------------------------------------------------------------------------------ + uqadd16 r1, r2, r3 + uqadd8 r3, r4, r8 + ite gt + uqadd16gt r4, r7, r9 + uqadd8le r8, r1, r2 + +@ CHECK: uqadd16 r1, r2, r3 @ encoding: [0x92,0xfa,0x53,0xf1] +@ CHECK: uqadd8 r3, r4, r8 @ encoding: [0x84,0xfa,0x58,0xf3] +@ CHECK: ite gt @ encoding: [0xcc,0xbf] +@ CHECK: uqadd16gt r4, r7, r9 @ encoding: [0x97,0xfa,0x59,0xf4] +@ CHECK: uqadd8le r8, r1, r2 @ encoding: [0x81,0xfa,0x52,0xf8] + + +@------------------------------------------------------------------------------ +@ UQASX/UQSAX +@------------------------------------------------------------------------------ + uqasx r1, r2, r3 + uqsax r3, r4, r8 + ite gt + uqasxgt r4, r7, r9 + uqsaxle r8, r1, r2 + + uqaddsubx r1, r2, r3 + uqsubaddx r3, r4, r8 + ite gt + uqaddsubxgt r4, r7, r9 + uqsubaddxle r8, r1, r2 + +@ CHECK: uqasx r1, r2, r3 @ encoding: [0xa2,0xfa,0x53,0xf1] +@ CHECK: uqsax r3, r4, r8 @ encoding: [0xe4,0xfa,0x58,0xf3] +@ CHECK: ite gt @ encoding: [0xcc,0xbf] +@ CHECK: uqasxgt r4, r7, r9 @ encoding: [0xa7,0xfa,0x59,0xf4] +@ CHECK: uqsaxle r8, r1, r2 @ encoding: [0xe1,0xfa,0x52,0xf8] + +@ CHECK: uqasx r1, r2, r3 @ encoding: [0xa2,0xfa,0x53,0xf1] +@ CHECK: uqsax r3, r4, r8 @ encoding: [0xe4,0xfa,0x58,0xf3] +@ CHECK: ite gt @ encoding: [0xcc,0xbf] +@ CHECK: uqasxgt r4, r7, r9 @ encoding: [0xa7,0xfa,0x59,0xf4] +@ CHECK: uqsaxle r8, r1, r2 @ encoding: [0xe1,0xfa,0x52,0xf8] + + +@------------------------------------------------------------------------------ +@ UQSUB16/UQSUB8 +@------------------------------------------------------------------------------ + uqsub8 r8, r2, r9 + uqsub16 r1, r9, r7 + ite gt + uqsub8gt r3, r1, r6 + uqsub16le r4, r6, r4 + +@ CHECK: uqsub8 r8, r2, r9 @ encoding: [0xc2,0xfa,0x59,0xf8] +@ CHECK: uqsub16 r1, r9, r7 @ encoding: [0xd9,0xfa,0x57,0xf1] +@ CHECK: ite gt @ encoding: [0xcc,0xbf] +@ CHECK: uqsub8gt r3, r1, r6 @ encoding: [0xc1,0xfa,0x56,0xf3] +@ CHECK: uqsub16le r4, r6, r4 @ encoding: [0xd6,0xfa,0x54,0xf4] + + +@------------------------------------------------------------------------------ +@ UQSUB16/UQSUB8 +@------------------------------------------------------------------------------ + usad8 r1, r9, r7 + usada8 r8, r2, r9, r12 + ite gt + usada8gt r3, r1, r6, r9 + usad8le r4, r6, r4 + +@ CHECK: usad8 r1, r9, r7 @ encoding: [0x79,0xfb,0x07,0xf1] +@ CHECK: usada8 r8, r2, r9, r12 @ encoding: [0x72,0xfb,0x09,0xc8] +@ CHECK: ite gt @ encoding: [0xcc,0xbf] +@ CHECK: usada8gt r3, r1, r6, r9 @ encoding: [0x71,0xfb,0x06,0x93] +@ CHECK: usad8le r4, r6, r4 @ encoding: [0x76,0xfb,0x04,0xf4] + + +@------------------------------------------------------------------------------ +@ USAT +@------------------------------------------------------------------------------ + usat r8, #1, r10 + usat r8, #4, r10, lsl #0 + usat r8, #5, r10, lsl #31 + usat r8, #16, r10, asr #1 + +@ CHECK: usat r8, #1, r10 @ encoding: [0x8a,0xf3,0x01,0x08] +@ CHECK: usat r8, #4, r10 @ encoding: [0x8a,0xf3,0x04,0x08] +@ CHECK: usat r8, #5, r10, lsl #31 @ encoding: [0x8a,0xf3,0xc5,0x78] +@ CHECK: usat r8, #16, r10, asr #1 @ encoding: [0xaa,0xf3,0x50,0x08] + + +@------------------------------------------------------------------------------ +@ USAT16 +@------------------------------------------------------------------------------ + usat16 r2, #2, r7 + usat16 r3, #15, r5 + +@ CHECK: usat16 r2, #2, r7 @ encoding: [0xa7,0xf3,0x02,0x02] +@ CHECK: usat16 r3, #15, r5 @ encoding: [0xa5,0xf3,0x0f,0x03] + + +@------------------------------------------------------------------------------ +@ USAX +@------------------------------------------------------------------------------ + usax r2, r3, r4 + it ne + usaxne r6, r1, r9 + usubaddx r2, r3, r4 + it ne + usubaddxne r6, r1, r9 + +@ CHECK: usax r2, r3, r4 @ encoding: [0xe3,0xfa,0x44,0xf2] +@ CHECK: it ne @ encoding: [0x18,0xbf] +@ CHECK: usaxne r6, r1, r9 @ encoding: [0xe1,0xfa,0x49,0xf6] +@ CHECK: usax r2, r3, r4 @ encoding: [0xe3,0xfa,0x44,0xf2] +@ CHECK: it ne @ encoding: [0x18,0xbf] +@ CHECK: usaxne r6, r1, r9 @ encoding: [0xe1,0xfa,0x49,0xf6] + + +@------------------------------------------------------------------------------ +@ USUB16/USUB8 +@------------------------------------------------------------------------------ + usub16 r4, r2, r7 + usub8 r1, r8, r5 + ite hi + usub16hi r1, r1, r3 + usub8ls r9, r2, r3 + +@ CHECK: usub16 r4, r2, r7 @ encoding: [0xd2,0xfa,0x47,0xf4] +@ CHECK: usub8 r1, r8, r5 @ encoding: [0xc8,0xfa,0x45,0xf1] +@ CHECK: ite hi @ encoding: [0x8c,0xbf] +@ CHECK: usub16hi r1, r1, r3 @ encoding: [0xd1,0xfa,0x43,0xf1] +@ CHECK: usub8ls r9, r2, r3 @ encoding: [0xc2,0xfa,0x43,0xf9] + + +@------------------------------------------------------------------------------ +@ UXTAB +@------------------------------------------------------------------------------ + uxtab r2, r3, r4 + uxtab r4, r5, r6, ror #0 + it lt + uxtablt r6, r2, r9, ror #8 + uxtab r5, r1, r4, ror #16 + uxtab r7, r8, r3, ror #24 + +@ CHECK: uxtab r2, r3, r4 @ encoding: [0x53,0xfa,0x84,0xf2] +@ CHECK: uxtab r4, r5, r6 @ encoding: [0x55,0xfa,0x86,0xf4] +@ CHECK: it lt @ encoding: [0xb8,0xbf] +@ CHECK: uxtablt r6, r2, r9, ror #8 @ encoding: [0x52,0xfa,0x99,0xf6] +@ CHECK: uxtab r5, r1, r4, ror #16 @ encoding: [0x51,0xfa,0xa4,0xf5] +@ CHECK: uxtab r7, r8, r3, ror #24 @ encoding: [0x58,0xfa,0xb3,0xf7] + + +@------------------------------------------------------------------------------ +@ UXTAB16 +@------------------------------------------------------------------------------ + it ge + uxtab16ge r0, r1, r4 + uxtab16 r6, r2, r7, ror #0 + uxtab16 r3, r5, r8, ror #8 + uxtab16 r3, r2, r1, ror #16 + it eq + uxtab16eq r1, r2, r3, ror #24 + +@ CHECK: it ge @ encoding: [0xa8,0xbf] +@ CHECK: uxtab16ge r0, r1, r4 @ encoding: [0x31,0xfa,0x84,0xf0] +@ CHECK: uxtab16 r6, r2, r7 @ encoding: [0x32,0xfa,0x87,0xf6] +@ CHECK: uxtab16 r3, r5, r8, ror #8 @ encoding: [0x35,0xfa,0x98,0xf3] +@ CHECK: uxtab16 r3, r2, r1, ror #16 @ encoding: [0x32,0xfa,0xa1,0xf3] +@ CHECK: it eq @ encoding: [0x08,0xbf] +@ CHECK: uxtab16eq r1, r2, r3, ror #24 @ encoding: [0x32,0xfa,0xb3,0xf1] + + +@------------------------------------------------------------------------------ +@ UXTAH +@------------------------------------------------------------------------------ + uxtah r1, r3, r9 + it hi + uxtahhi r6, r1, r6, ror #0 + uxtah r3, r8, r3, ror #8 + it lo + uxtahlo r2, r2, r4, ror #16 + uxtah r9, r3, r3, ror #24 + +@ CHECK: uxtah r1, r3, r9 @ encoding: [0x13,0xfa,0x89,0xf1] +@ CHECK: it hi @ encoding: [0x88,0xbf] +@ CHECK: uxtahhi r6, r1, r6 @ encoding: [0x11,0xfa,0x86,0xf6] +@ CHECK: uxtah r3, r8, r3, ror #8 @ encoding: [0x18,0xfa,0x93,0xf3] +@ CHECK: it lo @ encoding: [0x38,0xbf] +@ CHECK: uxtahlo r2, r2, r4, ror #16 @ encoding: [0x12,0xfa,0xa4,0xf2] +@ CHECK: uxtah r9, r3, r3, ror #24 @ encoding: [0x13,0xfa,0xb3,0xf9] + + +@------------------------------------------------------------------------------ +@ UXTB +@------------------------------------------------------------------------------ + it ge + uxtbge r2, r4 + uxtb r5, r6, ror #0 + uxtb r6, r9, ror #8 + it cc + uxtbcc r5, r1, ror #16 + uxtb r8, r3, ror #24 + uxtb.w r7, r8 + +@ CHECK: it ge @ encoding: [0xa8,0xbf] +@ CHECK: uxtbge r2, r4 @ encoding: [0xe2,0xb2] +@ CHECK: uxtb r5, r6 @ encoding: [0xf5,0xb2] +@ CHECK: uxtb.w r6, r9, ror #8 @ encoding: [0x5f,0xfa,0x99,0xf6] +@ CHECK: it lo @ encoding: [0x38,0xbf] +@ CHECK: uxtblo.w r5, r1, ror #16 @ encoding: [0x5f,0xfa,0xa1,0xf5] +@ CHECK: uxtb.w r8, r3, ror #24 @ encoding: [0x5f,0xfa,0xb3,0xf8] +@ CHECK: uxtb.w r7, r8 @ encoding: [0x5f,0xfa,0x88,0xf7] + + +@------------------------------------------------------------------------------ +@ UXTB16 +@------------------------------------------------------------------------------ + uxtb16 r1, r4 + uxtb16 r6, r7, ror #0 + it cs + uxtb16cs r3, r5, ror #8 + uxtb16 r3, r1, ror #16 + it ge + uxtb16ge r2, r3, ror #24 + +@ CHECK: uxtb16 r1, r4 @ encoding: [0x3f,0xfa,0x84,0xf1] +@ CHECK: uxtb16 r6, r7 @ encoding: [0x3f,0xfa,0x87,0xf6] +@ CHECK: it hs @ encoding: [0x28,0xbf] +@ CHECK: uxtb16hs r3, r5, ror #8 @ encoding: [0x3f,0xfa,0x95,0xf3] +@ CHECK: uxtb16 r3, r1, ror #16 @ encoding: [0x3f,0xfa,0xa1,0xf3] +@ CHECK: it ge @ encoding: [0xa8,0xbf] +@ CHECK: uxtb16ge r2, r3, ror #24 @ encoding: [0x3f,0xfa,0xb3,0xf2] + + +@------------------------------------------------------------------------------ +@ UXTH +@------------------------------------------------------------------------------ + it ne + uxthne r3, r9 + uxth r1, r6, ror #0 + uxth r3, r8, ror #8 + it le + uxthle r2, r2, ror #16 + uxth r9, r3, ror #24 + uxth.w r7, r8 + +@ CHECK: it ne @ encoding: [0x18,0xbf] +@ CHECK: uxthne.w r3, r9 @ encoding: [0x1f,0xfa,0x89,0xf3] +@ CHECK: uxth r1, r6 @ encoding: [0xb1,0xb2] +@ CHECK: uxth.w r3, r8, ror #8 @ encoding: [0x1f,0xfa,0x98,0xf3] +@ CHECK: it le @ encoding: [0xd8,0xbf] +@ CHECK: uxthle.w r2, r2, ror #16 @ encoding: [0x1f,0xfa,0xa2,0xf2] +@ CHECK: uxth.w r9, r3, ror #24 @ encoding: [0x1f,0xfa,0xb3,0xf9] +@ CHECK: uxth.w r7, r8 @ encoding: [0x1f,0xfa,0x88,0xf7] + +@------------------------------------------------------------------------------ +@ WFE/WFI/YIELD +@------------------------------------------------------------------------------ + wfe + wfi + yield + itet lt + wfelt + wfige + yieldlt + +@ CHECK: wfe @ encoding: [0x20,0xbf] +@ CHECK: wfi @ encoding: [0x30,0xbf] +@ CHECK: yield @ encoding: [0x10,0xbf] +@ CHECK: itet lt @ encoding: [0xb6,0xbf] +@ CHECK: wfelt @ encoding: [0x20,0xbf] +@ CHECK: wfige @ encoding: [0x30,0xbf] +@ CHECK: yieldlt @ encoding: [0x10,0xbf] diff --git a/test/MC/ARM/diagnostics.s b/test/MC/ARM/diagnostics.s index 4537a0ff6dff..f722dd7c070e 100644 --- a/test/MC/ARM/diagnostics.s +++ b/test/MC/ARM/diagnostics.s @@ -88,3 +88,230 @@ @ CHECK-ERRORS: error: invalid operand for instruction @ CHECK-ERRORS: error: invalid operand for instruction @ CHECK-ERRORS: error: invalid operand for instruction + + + @ Out of range immediate for MOV + movw r9, 0x10000 +@ CHECK-ERRORS: error: invalid operand for instruction + + @ Invalid 's' bit usage for MOVW + movs r6, #0xffff + movwseq r9, #0xffff +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: instruction 'movw' can not set flags, but 's' suffix specified + + @ Out of range immediate for MOVT + movt r9, 0x10000 +@ CHECK-ERRORS: error: invalid operand for instruction + + @ Out of range immediates for MRC/MRC2/MRRC/MRRC2 + mrc p14, #8, r1, c1, c2, #4 + mrc p14, #1, r1, c1, c2, #8 + mrc2 p14, #8, r1, c1, c2, #4 + mrc2 p14, #0, r1, c1, c2, #9 + mrrc p7, #16, r5, r4, c1 + mrrc2 p7, #17, r5, r4, c1 +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: invalid operand for instruction + + @ Shifter operand validation for PKH instructions. + pkhbt r2, r2, r3, lsl #-1 + pkhbt r2, r2, r3, lsl #32 + pkhtb r2, r2, r3, asr #0 + pkhtb r2, r2, r3, asr #33 + pkhbt r2, r2, r3, asr #3 + pkhtb r2, r2, r3, lsl #3 + +@ CHECK-ERRORS: error: immediate value out of range +@ CHECK-ERRORS: pkhbt r2, r2, r3, lsl #-1 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: immediate value out of range +@ CHECK-ERRORS: pkhbt r2, r2, r3, lsl #32 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: immediate value out of range +@ CHECK-ERRORS: pkhtb r2, r2, r3, asr #0 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: immediate value out of range +@ CHECK-ERRORS: pkhtb r2, r2, r3, asr #33 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: lsl operand expected. +@ CHECK-ERRORS: pkhbt r2, r2, r3, asr #3 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: asr operand expected. +@ CHECK-ERRORS: pkhtb r2, r2, r3, lsl #3 +@ CHECK-ERRORS: ^ + + + @ bad values for SETEND + setendne be + setend me + setend 1 + +@ CHECK-ERRORS: error: instruction 'setend' is not predicable, but condition code specified +@ CHECK-ERRORS: setendne be +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: 'be' or 'le' operand expected +@ CHECK-ERRORS: setend me +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: 'be' or 'le' operand expected +@ CHECK-ERRORS: setend 1 +@ CHECK-ERRORS: ^ + + + @ Out of range immediates and bad shift types for SSAT + ssat r8, #0, r10, lsl #8 + ssat r8, #33, r10, lsl #8 + ssat r8, #1, r10, lsl #-1 + ssat r8, #1, r10, lsl #32 + ssat r8, #1, r10, asr #0 + ssat r8, #1, r10, asr #33 + ssat r8, #1, r10, lsr #5 + ssat r8, #1, r10, lsl fred + ssat r8, #1, r10, lsl #fred + +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: ssat r8, #0, r10, lsl #8 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: ssat r8, #33, r10, lsl #8 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: 'lsr' shift amount must be in range [0,31] +@ CHECK-ERRORS: ssat r8, #1, r10, lsl #-1 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: 'lsr' shift amount must be in range [0,31] +@ CHECK-ERRORS: ssat r8, #1, r10, lsl #32 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: 'asr' shift amount must be in range [1,32] +@ CHECK-ERRORS: ssat r8, #1, r10, asr #0 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: 'asr' shift amount must be in range [1,32] +@ CHECK-ERRORS: ssat r8, #1, r10, asr #33 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: shift operator 'asr' or 'lsl' expected +@ CHECK-ERRORS: ssat r8, #1, r10, lsr #5 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: '#' expected +@ CHECK-ERRORS: ssat r8, #1, r10, lsl fred +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: shift amount must be an immediate +@ CHECK-ERRORS: ssat r8, #1, r10, lsl #fred +@ CHECK-ERRORS: ^ + + @ Out of range immediates for SSAT16 + ssat16 r2, #0, r7 + ssat16 r3, #17, r5 + +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: ssat16 r2, #0, r7 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: ssat16 r3, #17, r5 +@ CHECK-ERRORS: ^ + + + @ Out of order STM registers + stmda sp!, {r5, r2} + +@ CHECK-ERRORS: error: register list not in ascending order +@ CHECK-ERRORS: stmda sp!, {r5, r2} +@ CHECK-ERRORS: ^ + + + @ Out of range immediate on SVC + svc #0x1000000 +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: svc #0x1000000 +@ CHECK-ERRORS: ^ + + + @ Out of order Rt/Rt2 operands for ldrexd/strexd + ldrexd r4, r3, [r8] + strexd r6, r5, r3, [r8] + +@ CHECK-ERRORS: error: destination operands must be sequential +@ CHECK-ERRORS: ldrexd r4, r3, [r8] +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: source operands must be sequential +@ CHECK-ERRORS: strexd r6, r5, r3, [r8] +@ CHECK-ERRORS: ^ + + @ Illegal rotate operators for extend instructions + sxtb r8, r3, #8 + sxtb r8, r3, ror 24 + sxtb r8, r3, ror #8 - + sxtab r3, r8, r3, ror #(fred - wilma) + sxtab r7, r8, r3, ror #25 + sxtah r9, r3, r3, ror #-8 + sxtb16ge r2, r3, lsr #24 + +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: sxtb r8, r3, #8 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: '#' expected +@ CHECK-ERRORS: sxtb r8, r3, ror 24 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: unknown token in expression +@ CHECK-ERRORS: sxtb r8, r3, ror #8 - +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: malformed rotate expression +@ CHECK-ERRORS: sxtb r8, r3, ror #8 - +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: rotate amount must be an immediate +@ CHECK-ERRORS: sxtab r3, r8, r3, ror #(fred - wilma) +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: 'ror' rotate amount must be 8, 16, or 24 +@ CHECK-ERRORS: sxtab r7, r8, r3, ror #25 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: 'ror' rotate amount must be 8, 16, or 24 +@ CHECK-ERRORS: sxtah r9, r3, r3, ror #-8 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: sxtb16ge r2, r3, lsr #24 +@ CHECK-ERRORS: ^ + + @ Out of range width for SBFX/UBFX + sbfx r4, r5, #31, #2 + ubfxgt r4, r5, #16, #17 + +@ CHECK-ERRORS: error: bitfield width must be in range [1,32-lsb] +@ CHECK-ERRORS: sbfx r4, r5, #31, #2 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: bitfield width must be in range [1,32-lsb] +@ CHECK-ERRORS: ubfxgt r4, r5, #16, #17 +@ CHECK-ERRORS: ^ + + @ Out of order Rt/Rt2 operands for ldrd + ldrd r4, r3, [r8] + ldrd r4, r3, [r8, #8]! + ldrd r4, r3, [r8], #8 +@ CHECK-ERRORS: error: destination operands must be sequential +@ CHECK-ERRORS: ldrd r4, r3, [r8] +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: destination operands must be sequential +@ CHECK-ERRORS: ldrd r4, r3, [r8, #8]! +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: destination operands must be sequential +@ CHECK-ERRORS: ldrd r4, r3, [r8], #8 +@ CHECK-ERRORS: ^ + + + @ Bad register lists for VFP. + vpush {s0, s3} +@ CHECK-ERRORS: error: non-contiguous register range +@ CHECK-ERRORS: vpush {s0, s3} +@ CHECK-ERRORS: ^ + + @ Out of range coprocessor option immediate. + ldc2 p2, c8, [r1], { 256 } + ldc2 p2, c8, [r1], { -1 } + +@ CHECK-ERRORS: error: coprocessor option must be an immediate in range [0, 255] +@ CHECK-ERRORS: ldc2 p2, c8, [r1], { 256 } +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: coprocessor option must be an immediate in range [0, 255] +@ CHECK-ERRORS: ldc2 p2, c8, [r1], { -1 } +@ CHECK-ERRORS: ^ diff --git a/test/MC/ARM/elf-movt.s b/test/MC/ARM/elf-movt.s index 18061f57f519..02bb5a6907de 100644 --- a/test/MC/ARM/elf-movt.s +++ b/test/MC/ARM/elf-movt.s @@ -27,13 +27,13 @@ barf: @ @barf @ OBJ-NEXT: 'sh_entsize', 0x00000000 @ OBJ-NEXT: '_section_data', 'f00f0fe3 f40f4fe3' -@ OBJ: Relocation 0x00000000 +@ OBJ: Relocation 0 @ OBJ-NEXT: 'r_offset', 0x00000000 @ OBJ-NEXT: 'r_sym' -@ OBJ-NEXT: 'r_type', 0x0000002d +@ OBJ-NEXT: 'r_type', 0x2d -@ OBJ: Relocation 0x00000001 +@ OBJ: Relocation 1 @ OBJ-NEXT: 'r_offset', 0x00000004 @ OBJ-NEXT: 'r_sym' -@ OBJ-NEXT: 'r_type', 0x0000002e +@ OBJ-NEXT: 'r_type', 0x2e diff --git a/test/MC/ARM/elf-reloc-01.ll b/test/MC/ARM/elf-reloc-01.ll index eb6e2436af33..e6efe7eb94c5 100644 --- a/test/MC/ARM/elf-reloc-01.ll +++ b/test/MC/ARM/elf-reloc-01.ll @@ -60,11 +60,11 @@ bb3: ; preds = %bb, %entry declare void @exit(i32) noreturn nounwind -;; OBJ: Relocation 0x00000001 +;; OBJ: Relocation 1 ;; OBJ-NEXT: 'r_offset', -;; OBJ-NEXT: 'r_sym', 0x00000002 -;; OBJ-NEXT: 'r_type', 0x0000002b +;; OBJ-NEXT: 'r_sym', 0x000002 +;; OBJ-NEXT: 'r_type', 0x2b -;; OBJ: Symbol 0x00000002 +;; OBJ: Symbol 2 ;; OBJ-NEXT: '_MergedGlobals' ;; OBJ-NEXT: 'st_value', 0x00000010 diff --git a/test/MC/ARM/elf-reloc-02.ll b/test/MC/ARM/elf-reloc-02.ll index 091e89f57643..e51bac30ca8a 100644 --- a/test/MC/ARM/elf-reloc-02.ll +++ b/test/MC/ARM/elf-reloc-02.ll @@ -41,10 +41,10 @@ declare i32 @write(...) declare void @exit(i32) noreturn nounwind -;; OBJ: Relocation 0x00000000 +;; OBJ: Relocation 0 ;; OBJ-NEXT: 'r_offset', -;; OBJ-NEXT: 'r_sym', 0x00000002 -;; OBJ-NEXT: 'r_type', 0x0000002b +;; OBJ-NEXT: 'r_sym', 0x000002 +;; OBJ-NEXT: 'r_type', 0x2b -;; OBJ: Symbol 0x00000002 +;; OBJ: Symbol 2 ;; OBJ-NEXT: '.L.str' diff --git a/test/MC/ARM/elf-reloc-03.ll b/test/MC/ARM/elf-reloc-03.ll index 91dba554ab63..922242f9d3d6 100644 --- a/test/MC/ARM/elf-reloc-03.ll +++ b/test/MC/ARM/elf-reloc-03.ll @@ -88,10 +88,10 @@ entry: declare void @exit(i32) noreturn nounwind -;; OBJ: Relocation 0x00000001 +;; OBJ: Relocation 1 ;; OBJ-NEXT: 'r_offset', -;; OBJ-NEXT: 'r_sym', 0x0000000c -;; OBJ-NEXT: 'r_type', 0x0000002b +;; OBJ-NEXT: 'r_sym', 0x00000c +;; OBJ-NEXT: 'r_type', 0x2b -;; OBJ: Symbol 0x0000000c +;; OBJ: Symbol 12 ;; OBJ-NEXT: 'vtable' diff --git a/test/MC/ARM/elf-thumbfunc-reloc.ll b/test/MC/ARM/elf-thumbfunc-reloc.ll index 6fce40388ed8..e7cb01ee409e 100644 --- a/test/MC/ARM/elf-thumbfunc-reloc.ll +++ b/test/MC/ARM/elf-thumbfunc-reloc.ll @@ -22,16 +22,16 @@ entry: ; make sure that bl 0 (fff7feff) is correctly encoded -; CHECK: '_section_data', '70470000 2de90048 fff7feff bde80088' +; CHECK: '_section_data', '704700bf 2de90048 fff7feff bde80008' ; Offset Info Type Sym.Value Sym. Name ; 00000008 0000070a R_ARM_THM_CALL 00000001 foo -; CHECK: Relocation 0x00000000 +; CHECK: Relocation 0 ; CHECK-NEXT: 'r_offset', 0x00000008 -; CHECK-NEXT: 'r_sym', 0x00000007 -; CHECK-NEXT: 'r_type', 0x0000000a +; CHECK-NEXT: 'r_sym', 0x000007 +; CHECK-NEXT: 'r_type', 0x0a ; make sure foo is thumb function: bit 0 = 1 -; CHECK: Symbol 0x00000007 +; CHECK: Symbol 7 ; CHECK-NEXT: 'foo' ; CHECK-NEXT: 'st_value', 0x00000001 diff --git a/test/MC/ARM/elf-thumbfunc.s b/test/MC/ARM/elf-thumbfunc.s index a1b3c311e8c1..0aa7f41cc4be 100644 --- a/test/MC/ARM/elf-thumbfunc.s +++ b/test/MC/ARM/elf-thumbfunc.s @@ -12,9 +12,9 @@ foo: bx lr @@ make sure foo is thumb function: bit 0 = 1 (st_value) -@CHECK: Symbol 0x00000004 +@CHECK: Symbol 4 @CHECK-NEXT: 'st_name', 0x00000001 @CHECK-NEXT: 'st_value', 0x00000001 @CHECK-NEXT: 'st_size', 0x00000000 -@CHECK-NEXT: 'st_bind', 0x00000001 -@CHECK-NEXT: 'st_type', 0x00000002 +@CHECK-NEXT: 'st_bind', 0x1 +@CHECK-NEXT: 'st_type', 0x2 diff --git a/test/MC/ARM/mode-switch.s b/test/MC/ARM/mode-switch.s index 4cc986a3e173..9d4995439e82 100644 --- a/test/MC/ARM/mode-switch.s +++ b/test/MC/ARM/mode-switch.s @@ -1,17 +1,15 @@ @ Test ARM / Thumb mode switching with .code -@ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding < %s | FileCheck %s -@ RUN: llvm-mc -mcpu=cortex-a8 -triple thumb-unknown-unknown -show-encoding < %s | FileCheck %s +@ RUN: llvm-mc -triple armv7-unknown-unknown -show-encoding < %s | FileCheck %s +@ RUN: llvm-mc -triple thumbv7-unknown-unknown -show-encoding <%s | FileCheck %s .code 16 - -@ CHECK: add.w r0, r0, r1 @ encoding: [0x00,0xeb,0x01,0x00] add.w r0, r0, r1 +@ CHECK: add.w r0, r0, r1 @ encoding: [0x00,0xeb,0x01,0x00] .code 32 -@ CHECK: add r0, r0, r1 @ encoding: [0x01,0x00,0x80,0xe0] add r0, r0, r1 +@ CHECK: add r0, r0, r1 @ encoding: [0x01,0x00,0x80,0xe0] .code 16 -@ CHECK: add r0, r0, r1 @ encoding: [0x40,0x18] - - add r0, r0, r1 + adds r0, r0, r1 +@ CHECK: adds r0, r0, r1 @ encoding: [0x40,0x18] diff --git a/test/MC/ARM/neon-bitwise-encoding.s b/test/MC/ARM/neon-bitwise-encoding.s index 8710923c670d..81e2c4d099bf 100644 --- a/test/MC/ARM/neon-bitwise-encoding.s +++ b/test/MC/ARM/neon-bitwise-encoding.s @@ -1,47 +1,55 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding < %s | FileCheck %s -@ XFAIL: * -@ CHECK: vand d16, d17, d16 @ encoding: [0xb0,0x01,0x41,0xf2] vand d16, d17, d16 -@ CHECK: vand q8, q8, q9 @ encoding: [0xf2,0x01,0x40,0xf2] vand q8, q8, q9 -@ CHECK: veor d16, d17, d16 @ encoding: [0xb0,0x01,0x41,0xf3] +@ CHECK: vand d16, d17, d16 @ encoding: [0xb0,0x01,0x41,0xf2] +@ CHECK: vand q8, q8, q9 @ encoding: [0xf2,0x01,0x40,0xf2] + veor d16, d17, d16 -@ CHECK: veor q8, q8, q9 @ encoding: [0xf2,0x01,0x40,0xf3] veor q8, q8, q9 -@ CHECK: vorr d16, d17, d16 @ encoding: [0xb0,0x01,0x61,0xf2] +@ CHECK: veor d16, d17, d16 @ encoding: [0xb0,0x01,0x41,0xf3] +@ CHECK: veor q8, q8, q9 @ encoding: [0xf2,0x01,0x40,0xf3] + vorr d16, d17, d16 -@ CHECK: vorr q8, q8, q9 @ encoding: [0xf2,0x01,0x60,0xf2] vorr q8, q8, q9 -@ CHECK: vorr.i32 d16, #0x1000000 @ encoding: [0x11,0x07,0xc0,0xf2] - vorr.i32 d16, #0x1000000 -@ CHECK: vorr.i32 q8, #0x1000000 @ encoding: [0x51,0x07,0xc0,0xf2] - vorr.i32 q8, #0x1000000 -@ CHECK: vorr.i32 q8, #0x0 @ encoding: [0x50,0x01,0xc0,0xf2] - vorr.i32 q8, #0x0 + +@ CHECK: vorr d16, d17, d16 @ encoding: [0xb0,0x01,0x61,0xf2] +@ CHECK: vorr q8, q8, q9 @ encoding: [0xf2,0x01,0x60,0xf2] + + vorr.i32 d16, #0x1000000 + vorr.i32 q8, #0x1000000 + vorr.i32 q8, #0x0 + +@ FIXME: vorr.i32 d16, #0x1000000 @ encoding: [0x11,0x07,0xc0,0xf2] +@ FIXME: vorr.i32 q8, #0x1000000 @ encoding: [0x51,0x07,0xc0,0xf2] +@ FIXME: vorr.i32 q8, #0x0 @ encoding: [0x50,0x01,0xc0,0xf2] + + vbic d16, d17, d16 + vbic q8, q8, q9 + vbic.i32 d16, #0xFF000000 + vbic.i32 q8, #0xFF000000 @ CHECK: vbic d16, d17, d16 @ encoding: [0xb0,0x01,0x51,0xf2] - vbic d16, d17, d16 @ CHECK: vbic q8, q8, q9 @ encoding: [0xf2,0x01,0x50,0xf2] - vbic q8, q8, q9 -@ CHECK: vbic.i32 d16, #0xFF000000 @ encoding: [0x3f,0x07,0xc7,0xf3] - vbic.i32 d16, #0xFF000000 -@ CHECK: vbic.i32 q8, #0xFF000000 @ encoding: [0x7f,0x07,0xc7,0xf3] - vbic.i32 q8, #0xFF000000 +@ FIXME: vbic.i32 d16, #0xFF000000 @ encoding: [0x3f,0x07,0xc7,0xf3] +@ FIXME: vbic.i32 q8, #0xFF000000 @ encoding: [0x7f,0x07,0xc7,0xf3] -@ CHECK: vorn d16, d17, d16 @ encoding: [0xb0,0x01,0x71,0xf2] vorn d16, d17, d16 -@ CHECK: vorn q8, q8, q9 @ encoding: [0xf2,0x01,0x70,0xf2] vorn q8, q8, q9 -@ CHECK: vmvn d16, d16 @ encoding: [0xa0,0x05,0xf0,0xf3] +@ CHECK: vorn d16, d17, d16 @ encoding: [0xb0,0x01,0x71,0xf2] +@ CHECK: vorn q8, q8, q9 @ encoding: [0xf2,0x01,0x70,0xf2] + vmvn d16, d16 -@ CHECK: vmvn q8, q8 @ encoding: [0xe0,0x05,0xf0,0xf3] vmvn q8, q8 -@ CHECK: vbsl d18, d17, d16 @ encoding: [0xb0,0x21,0x51,0xf3] +@ CHECK: vmvn d16, d16 @ encoding: [0xa0,0x05,0xf0,0xf3] +@ CHECK: vmvn q8, q8 @ encoding: [0xe0,0x05,0xf0,0xf3] + vbsl d18, d17, d16 -@ CHECK: vbsl q8, q10, q9 @ encoding: [0xf2,0x01,0x54,0xf3] vbsl q8, q10, q9 + +@ CHECK: vbsl d18, d17, d16 @ encoding: [0xb0,0x21,0x51,0xf3] +@ CHECK: vbsl q8, q10, q9 @ encoding: [0xf2,0x01,0x54,0xf3] diff --git a/test/MC/ARM/neon-cmp-encoding.s b/test/MC/ARM/neon-cmp-encoding.s index 6bfc549e9474..d94e2f72079f 100644 --- a/test/MC/ARM/neon-cmp-encoding.s +++ b/test/MC/ARM/neon-cmp-encoding.s @@ -1,115 +1,113 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding < %s | FileCheck %s -@ XFAIL: * -@ FIXME: We cannot currently test the following instructions, which are -@ currently marked as for-disassembly only in the .td files: -@ - VCEQz -@ - VCGEz, VCLEz -@ - VCGTz, VCLTz - -@ CHECK: vceq.i8 d16, d16, d17 @ encoding: [0xb1,0x08,0x40,0xf3] vceq.i8 d16, d16, d17 -@ CHECK: vceq.i16 d16, d16, d17 @ encoding: [0xb1,0x08,0x50,0xf3] vceq.i16 d16, d16, d17 -@ CHECK: vceq.i32 d16, d16, d17 @ encoding: [0xb1,0x08,0x60,0xf3] vceq.i32 d16, d16, d17 -@ CHECK: vceq.f32 d16, d16, d17 @ encoding: [0xa1,0x0e,0x40,0xf2] vceq.f32 d16, d16, d17 -@ CHECK: vceq.i8 q8, q8, q9 @ encoding: [0xf2,0x08,0x40,0xf3] vceq.i8 q8, q8, q9 -@ CHECK: vceq.i16 q8, q8, q9 @ encoding: [0xf2,0x08,0x50,0xf3] vceq.i16 q8, q8, q9 -@ CHECK: vceq.i32 q8, q8, q9 @ encoding: [0xf2,0x08,0x60,0xf3] vceq.i32 q8, q8, q9 -@ CHECK: vceq.f32 q8, q8, q9 @ encoding: [0xe2,0x0e,0x40,0xf2] vceq.f32 q8, q8, q9 -@ CHECK: vcge.s8 d16, d16, d17 @ encoding: [0xb1,0x03,0x40,0xf2] +@ CHECK: vceq.i8 d16, d16, d17 @ encoding: [0xb1,0x08,0x40,0xf3] +@ CHECK: vceq.i16 d16, d16, d17 @ encoding: [0xb1,0x08,0x50,0xf3] +@ CHECK: vceq.i32 d16, d16, d17 @ encoding: [0xb1,0x08,0x60,0xf3] +@ CHECK: vceq.f32 d16, d16, d17 @ encoding: [0xa1,0x0e,0x40,0xf2] +@ CHECK: vceq.i8 q8, q8, q9 @ encoding: [0xf2,0x08,0x40,0xf3] +@ CHECK: vceq.i16 q8, q8, q9 @ encoding: [0xf2,0x08,0x50,0xf3] +@ CHECK: vceq.i32 q8, q8, q9 @ encoding: [0xf2,0x08,0x60,0xf3] +@ CHECK: vceq.f32 q8, q8, q9 @ encoding: [0xe2,0x0e,0x40,0xf2] + vcge.s8 d16, d16, d17 -@ CHECK: vcge.s16 d16, d16, d17 @ encoding: [0xb1,0x03,0x50,0xf2] vcge.s16 d16, d16, d17 -@ CHECK: vcge.s32 d16, d16, d17 @ encoding: [0xb1,0x03,0x60,0xf2] vcge.s32 d16, d16, d17 -@ CHECK: vcge.u8 d16, d16, d17 @ encoding: [0xb1,0x03,0x40,0xf3] vcge.u8 d16, d16, d17 -@ CHECK: vcge.u16 d16, d16, d17 @ encoding: [0xb1,0x03,0x50,0xf3] vcge.u16 d16, d16, d17 -@ CHECK: vcge.u32 d16, d16, d17 @ encoding: [0xb1,0x03,0x60,0xf3] vcge.u32 d16, d16, d17 -@ CHECK: vcge.f32 d16, d16, d17 @ encoding: [0xa1,0x0e,0x40,0xf3] vcge.f32 d16, d16, d17 -@ CHECK: vcge.s8 q8, q8, q9 @ encoding: [0xf2,0x03,0x40,0xf2] vcge.s8 q8, q8, q9 -@ CHECK: vcge.s16 q8, q8, q9 @ encoding: [0xf2,0x03,0x50,0xf2] vcge.s16 q8, q8, q9 -@ CHECK: vcge.s32 q8, q8, q9 @ encoding: [0xf2,0x03,0x60,0xf2] vcge.s32 q8, q8, q9 -@ CHECK: vcge.u8 q8, q8, q9 @ encoding: [0xf2,0x03,0x40,0xf3] vcge.u8 q8, q8, q9 -@ CHECK: vcge.u16 q8, q8, q9 @ encoding: [0xf2,0x03,0x50,0xf3] vcge.u16 q8, q8, q9 -@ CHECK: vcge.u32 q8, q8, q9 @ encoding: [0xf2,0x03,0x60,0xf3] vcge.u32 q8, q8, q9 -@ CHECK: vcge.f32 q8, q8, q9 @ encoding: [0xe2,0x0e,0x40,0xf3] vcge.f32 q8, q8, q9 -@ CHECK: vacge.f32 d16, d16, d17 @ encoding: [0xb1,0x0e,0x40,0xf3] vacge.f32 d16, d16, d17 -@ CHECK: vacge.f32 q8, q8, q9 @ encoding: [0xf2,0x0e,0x40,0xf3] vacge.f32 q8, q8, q9 -@ CHECK: vcgt.s8 d16, d16, d17 @ encoding: [0xa1,0x03,0x40,0xf2] +@ CHECK: vcge.s8 d16, d16, d17 @ encoding: [0xb1,0x03,0x40,0xf2] +@ CHECK: vcge.s16 d16, d16, d17 @ encoding: [0xb1,0x03,0x50,0xf2] +@ CHECK: vcge.s32 d16, d16, d17 @ encoding: [0xb1,0x03,0x60,0xf2] +@ CHECK: vcge.u8 d16, d16, d17 @ encoding: [0xb1,0x03,0x40,0xf3] +@ CHECK: vcge.u16 d16, d16, d17 @ encoding: [0xb1,0x03,0x50,0xf3] +@ CHECK: vcge.u32 d16, d16, d17 @ encoding: [0xb1,0x03,0x60,0xf3] +@ CHECK: vcge.f32 d16, d16, d17 @ encoding: [0xa1,0x0e,0x40,0xf3] +@ CHECK: vcge.s8 q8, q8, q9 @ encoding: [0xf2,0x03,0x40,0xf2] +@ CHECK: vcge.s16 q8, q8, q9 @ encoding: [0xf2,0x03,0x50,0xf2] +@ CHECK: vcge.s32 q8, q8, q9 @ encoding: [0xf2,0x03,0x60,0xf2] +@ CHECK: vcge.u8 q8, q8, q9 @ encoding: [0xf2,0x03,0x40,0xf3] +@ CHECK: vcge.u16 q8, q8, q9 @ encoding: [0xf2,0x03,0x50,0xf3] +@ CHECK: vcge.u32 q8, q8, q9 @ encoding: [0xf2,0x03,0x60,0xf3] +@ CHECK: vcge.f32 q8, q8, q9 @ encoding: [0xe2,0x0e,0x40,0xf3] +@ CHECK: vacge.f32 d16, d16, d17 @ encoding: [0xb1,0x0e,0x40,0xf3] +@ CHECK: vacge.f32 q8, q8, q9 @ encoding: [0xf2,0x0e,0x40,0xf3] + vcgt.s8 d16, d16, d17 -@ CHECK: vcgt.s16 d16, d16, d17 @ encoding: [0xa1,0x03,0x50,0xf2] vcgt.s16 d16, d16, d17 -@ CHECK: vcgt.s32 d16, d16, d17 @ encoding: [0xa1,0x03,0x60,0xf2] vcgt.s32 d16, d16, d17 -@ CHECK: vcgt.u8 d16, d16, d17 @ encoding: [0xa1,0x03,0x40,0xf3] vcgt.u8 d16, d16, d17 -@ CHECK: vcgt.u16 d16, d16, d17 @ encoding: [0xa1,0x03,0x50,0xf3] vcgt.u16 d16, d16, d17 -@ CHECK: vcgt.u32 d16, d16, d17 @ encoding: [0xa1,0x03,0x60,0xf3] vcgt.u32 d16, d16, d17 -@ CHECK: vcgt.f32 d16, d16, d17 @ encoding: [0xa1,0x0e,0x60,0xf3] vcgt.f32 d16, d16, d17 -@ CHECK: vcgt.s8 q8, q8, q9 @ encoding: [0xe2,0x03,0x40,0xf2] vcgt.s8 q8, q8, q9 -@ CHECK: vcgt.s16 q8, q8, q9 @ encoding: [0xe2,0x03,0x50,0xf2] vcgt.s16 q8, q8, q9 -@ CHECK: vcgt.s32 q8, q8, q9 @ encoding: [0xe2,0x03,0x60,0xf2] vcgt.s32 q8, q8, q9 -@ CHECK: vcgt.u8 q8, q8, q9 @ encoding: [0xe2,0x03,0x40,0xf3] vcgt.u8 q8, q8, q9 -@ CHECK: vcgt.u16 q8, q8, q9 @ encoding: [0xe2,0x03,0x50,0xf3] vcgt.u16 q8, q8, q9 -@ CHECK: vcgt.u32 q8, q8, q9 @ encoding: [0xe2,0x03,0x60,0xf3] vcgt.u32 q8, q8, q9 -@ CHECK: vcgt.f32 q8, q8, q9 @ encoding: [0xe2,0x0e,0x60,0xf3] vcgt.f32 q8, q8, q9 -@ CHECK: vacgt.f32 d16, d16, d17 @ encoding: [0xb1,0x0e,0x60,0xf3] vacgt.f32 d16, d16, d17 -@ CHECK: vacgt.f32 q8, q8, q9 @ encoding: [0xf2,0x0e,0x60,0xf3] vacgt.f32 q8, q8, q9 -@ CHECK: vtst.8 d16, d16, d17 @ encoding: [0xb1,0x08,0x40,0xf2] +@ CHECK: vcgt.s8 d16, d16, d17 @ encoding: [0xa1,0x03,0x40,0xf2] +@ CHECK: vcgt.s16 d16, d16, d17 @ encoding: [0xa1,0x03,0x50,0xf2] +@ CHECK: vcgt.s32 d16, d16, d17 @ encoding: [0xa1,0x03,0x60,0xf2] +@ CHECK: vcgt.u8 d16, d16, d17 @ encoding: [0xa1,0x03,0x40,0xf3] +@ CHECK: vcgt.u16 d16, d16, d17 @ encoding: [0xa1,0x03,0x50,0xf3] +@ CHECK: vcgt.u32 d16, d16, d17 @ encoding: [0xa1,0x03,0x60,0xf3] +@ CHECK: vcgt.f32 d16, d16, d17 @ encoding: [0xa1,0x0e,0x60,0xf3] +@ CHECK: vcgt.s8 q8, q8, q9 @ encoding: [0xe2,0x03,0x40,0xf2] +@ CHECK: vcgt.s16 q8, q8, q9 @ encoding: [0xe2,0x03,0x50,0xf2] +@ CHECK: vcgt.s32 q8, q8, q9 @ encoding: [0xe2,0x03,0x60,0xf2] +@ CHECK: vcgt.u8 q8, q8, q9 @ encoding: [0xe2,0x03,0x40,0xf3] +@ CHECK: vcgt.u16 q8, q8, q9 @ encoding: [0xe2,0x03,0x50,0xf3] +@ CHECK: vcgt.u32 q8, q8, q9 @ encoding: [0xe2,0x03,0x60,0xf3] +@ CHECK: vcgt.f32 q8, q8, q9 @ encoding: [0xe2,0x0e,0x60,0xf3] +@ CHECK: vacgt.f32 d16, d16, d17 @ encoding: [0xb1,0x0e,0x60,0xf3] +@ CHECK: vacgt.f32 q8, q8, q9 @ encoding: [0xf2,0x0e,0x60,0xf3] + vtst.8 d16, d16, d17 -@ CHECK: vtst.16 d16, d16, d17 @ encoding: [0xb1,0x08,0x50,0xf2] vtst.16 d16, d16, d17 -@ CHECK: vtst.32 d16, d16, d17 @ encoding: [0xb1,0x08,0x60,0xf2] vtst.32 d16, d16, d17 -@ CHECK: vtst.8 q8, q8, q9 @ encoding: [0xf2,0x08,0x40,0xf2] vtst.8 q8, q8, q9 -@ CHECK: vtst.16 q8, q8, q9 @ encoding: [0xf2,0x08,0x50,0xf2] vtst.16 q8, q8, q9 -@ CHECK: vtst.32 q8, q8, q9 @ encoding: [0xf2,0x08,0x60,0xf2] vtst.32 q8, q8, q9 -@ CHECK: vceq.i8 d16, d16, #0 @ encoding: [0x20,0x01,0xf1,0xf3] - vceq.i8 d16, d16, #0 -@ CHECK: vcge.s8 d16, d16, #0 @ encoding: [0xa0,0x00,0xf1,0xf3] - vcge.s8 d16, d16, #0 -@ CHECK: vcle.s8 d16, d16, #0 @ encoding: [0xa0,0x01,0xf1,0xf3] - vcle.s8 d16, d16, #0 -@ CHECK: vcgt.s8 d16, d16, #0 @ encoding: [0x20,0x00,0xf1,0xf3] - vcgt.s8 d16, d16, #0 -@ CHECK: vclt.s8 d16, d16, #0 @ encoding: [0x20,0x02,0xf1,0xf3] - vclt.s8 d16, d16, #0 +@ CHECK: vtst.8 d16, d16, d17 @ encoding: [0xb1,0x08,0x40,0xf2] +@ CHECK: vtst.16 d16, d16, d17 @ encoding: [0xb1,0x08,0x50,0xf2] +@ CHECK: vtst.32 d16, d16, d17 @ encoding: [0xb1,0x08,0x60,0xf2] +@ CHECK: vtst.8 q8, q8, q9 @ encoding: [0xf2,0x08,0x40,0xf2] +@ CHECK: vtst.16 q8, q8, q9 @ encoding: [0xf2,0x08,0x50,0xf2] +@ CHECK: vtst.32 q8, q8, q9 @ encoding: [0xf2,0x08,0x60,0xf2] + + vceq.i8 d16, d16, #0 + vcge.s8 d16, d16, #0 + vcle.s8 d16, d16, #0 + vcgt.s8 d16, d16, #0 + vclt.s8 d16, d16, #0 + +@ CHECK: vceq.i8 d16, d16, #0 @ encoding: [0x20,0x01,0xf1,0xf3] +@ CHECK: vcge.s8 d16, d16, #0 @ encoding: [0xa0,0x00,0xf1,0xf3] +@ CHECK: vcle.s8 d16, d16, #0 @ encoding: [0xa0,0x01,0xf1,0xf3] +@ CHECK: vcgt.s8 d16, d16, #0 @ encoding: [0x20,0x00,0xf1,0xf3] +@ CHECK: vclt.s8 d16, d16, #0 @ encoding: [0x20,0x02,0xf1,0xf3] diff --git a/test/MC/ARM/neon-dup-encoding.s b/test/MC/ARM/neon-dup-encoding.s index 0aebdce304a4..31dcf0b31ed5 100644 --- a/test/MC/ARM/neon-dup-encoding.s +++ b/test/MC/ARM/neon-dup-encoding.s @@ -1,27 +1,33 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding < %s | FileCheck %s -@ XFAIL: * + + vdup.8 d16, r0 + vdup.16 d16, r0 + vdup.32 d16, r0 @ CHECK: vdup.8 d16, r0 @ encoding: [0x90,0x0b,0xc0,0xee] - vdup.8 d16, r0 -@ CHECK: vdup.16 d16, r0 @ encoding: [0xb0,0x0b,0x80,0xee] - vdup.16 d16, r0 -@ CHECK: vdup.32 d16, r0 @ encoding: [0x90,0x0b,0x80,0xee] - vdup.32 d16, r0 -@ CHECK: vdup.8 q8, r0 @ encoding: [0x90,0x0b,0xe0,0xee] +@ CHECK: vdup.16 d16, r0 @ encoding: [0xb0,0x0b,0x80,0xee] +@ CHECK: vdup.32 d16, r0 @ encoding: [0x90,0x0b,0x80,0xee] + vdup.8 q8, r0 -@ CHECK: vdup.16 q8, r0 @ encoding: [0xb0,0x0b,0xa0,0xee] vdup.16 q8, r0 -@ CHECK: vdup.32 q8, r0 @ encoding: [0x90,0x0b,0xa0,0xee] vdup.32 q8, r0 -@ CHECK: vdup.8 d16, d16[1] @ encoding: [0x20,0x0c,0xf3,0xf3] + +@ CHECK: vdup.8 q8, r0 @ encoding: [0x90,0x0b,0xe0,0xee] +@ CHECK: vdup.16 q8, r0 @ encoding: [0xb0,0x0b,0xa0,0xee] +@ CHECK: vdup.32 q8, r0 @ encoding: [0x90,0x0b,0xa0,0xee] + vdup.8 d16, d16[1] -@ CHECK: vdup.16 d16, d16[1] @ encoding: [0x20,0x0c,0xf6,0xf3] vdup.16 d16, d16[1] -@ CHECK: vdup.32 d16, d16[1] @ encoding: [0x20,0x0c,0xfc,0xf3] vdup.32 d16, d16[1] -@ CHECK: vdup.8 q8, d16[1] @ encoding: [0x60,0x0c,0xf3,0xf3] + +@ CHECK: vdup.8 d16, d16[1] @ encoding: [0x20,0x0c,0xf3,0xf3] +@ CHECK: vdup.16 d16, d16[1] @ encoding: [0x20,0x0c,0xf6,0xf3] +@ CHECK: vdup.32 d16, d16[1] @ encoding: [0x20,0x0c,0xfc,0xf3] + vdup.8 q8, d16[1] -@ CHECK: vdup.16 q8, d16[1] @ encoding: [0x60,0x0c,0xf6,0xf3] vdup.16 q8, d16[1] -@ CHECK: vdup.32 q8, d16[1] @ encoding: [0x60,0x0c,0xfc,0xf3] vdup.32 q8, d16[1] + +@ CHECK: vdup.8 q8, d16[1] @ encoding: [0x60,0x0c,0xf3,0xf3] +@ CHECK: vdup.16 q8, d16[1] @ encoding: [0x60,0x0c,0xf6,0xf3] +@ CHECK: vdup.32 q8, d16[1] @ encoding: [0x60,0x0c,0xfc,0xf3] diff --git a/test/MC/ARM/neon-mov-encoding.s b/test/MC/ARM/neon-mov-encoding.s index ca678d022df8..02eec1215ab7 100644 --- a/test/MC/ARM/neon-mov-encoding.s +++ b/test/MC/ARM/neon-mov-encoding.s @@ -1,117 +1,131 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding < %s | FileCheck %s @ XFAIL: * -@ CHECK: vmov.i8 d16, #0x8 @ encoding: [0x18,0x0e,0xc0,0xf2] - vmov.i8 d16, #0x8 -@ CHECK: vmov.i16 d16, #0x10 @ encoding: [0x10,0x08,0xc1,0xf2] + vmov.i8 d16, #0x8 vmov.i16 d16, #0x10 -@ CHECK: vmov.i16 d16, #0x1000 @ encoding: [0x10,0x0a,0xc1,0xf2] vmov.i16 d16, #0x1000 -@ CHECK: vmov.i32 d16, #0x20 @ encoding: [0x10,0x00,0xc2,0xf2] vmov.i32 d16, #0x20 -@ CHECK: vmov.i32 d16, #0x2000 @ encoding: [0x10,0x02,0xc2,0xf2] vmov.i32 d16, #0x2000 -@ CHECK: vmov.i32 d16, #0x200000 @ encoding: [0x10,0x04,0xc2,0xf2] vmov.i32 d16, #0x200000 -@ CHECK: vmov.i32 d16, #0x20000000 @ encoding: [0x10,0x06,0xc2,0xf2] vmov.i32 d16, #0x20000000 -@ CHECK: vmov.i32 d16, #0x20FF @ encoding: [0x10,0x0c,0xc2,0xf2] vmov.i32 d16, #0x20FF -@ CHECK: vmov.i32 d16, #0x20FFFF @ encoding: [0x10,0x0d,0xc2,0xf2] vmov.i32 d16, #0x20FFFF -@ CHECK: vmov.i64 d16, #0xFF0000FF0000FFFF @ encoding: [0x33,0x0e,0xc1,0xf3] vmov.i64 d16, #0xFF0000FF0000FFFF -@ CHECK: vmov.i8 q8, #0x8 @ encoding: [0x58,0x0e,0xc0,0xf2] - vmov.i8 q8, #0x8 -@ CHECK: vmov.i16 q8, #0x10 @ encoding: [0x50,0x08,0xc1,0xf2] + +@ CHECK: vmov.i8 d16, #0x8 @ encoding: [0x18,0x0e,0xc0,0xf2] +@ CHECK: vmov.i16 d16, #0x10 @ encoding: [0x10,0x08,0xc1,0xf2] +@ CHECK: vmov.i16 d16, #0x1000 @ encoding: [0x10,0x0a,0xc1,0xf2] +@ CHECK: vmov.i32 d16, #0x20 @ encoding: [0x10,0x00,0xc2,0xf2] +@ CHECK: vmov.i32 d16, #0x2000 @ encoding: [0x10,0x02,0xc2,0xf2] +@ CHECK: vmov.i32 d16, #0x200000 @ encoding: [0x10,0x04,0xc2,0xf2] +@ CHECK: vmov.i32 d16, #0x20000000 @ encoding: [0x10,0x06,0xc2,0xf2] +@ CHECK: vmov.i32 d16, #0x20FF @ encoding: [0x10,0x0c,0xc2,0xf2] +@ CHECK: vmov.i32 d16, #0x20FFFF @ encoding: [0x10,0x0d,0xc2,0xf2] +@ CHECK: vmov.i64 d16, #0xFF0000FF0000FFFF @ encoding: [0x33,0x0e,0xc1,0xf3] + + + + vmov.i8 q8, #0x8 vmov.i16 q8, #0x10 -@ CHECK: vmov.i16 q8, #0x1000 @ encoding: [0x50,0x0a,0xc1,0xf2] vmov.i16 q8, #0x1000 -@ CHECK: vmov.i32 q8, #0x20 @ encoding: [0x50,0x00,0xc2,0xf2] vmov.i32 q8, #0x20 -@ CHECK: vmov.i32 q8, #0x2000 @ encoding: [0x50,0x02,0xc2,0xf2] vmov.i32 q8, #0x2000 -@ CHECK: vmov.i32 q8, #0x200000 @ encoding: [0x50,0x04,0xc2,0xf2] vmov.i32 q8, #0x200000 -@ CHECK: vmov.i32 q8, #0x20000000 @ encoding: [0x50,0x06,0xc2,0xf2] vmov.i32 q8, #0x20000000 -@ CHECK: vmov.i32 q8, #0x20FF @ encoding: [0x50,0x0c,0xc2,0xf2] vmov.i32 q8, #0x20FF -@ CHECK: vmov.i32 q8, #0x20FFFF @ encoding: [0x50,0x0d,0xc2,0xf2] vmov.i32 q8, #0x20FFFF -@ CHECK: vmov.i64 q8, #0xFF0000FF0000FFFF @ encoding: [0x73,0x0e,0xc1,0xf3] vmov.i64 q8, #0xFF0000FF0000FFFF -@ CHECK: vmvn.i16 d16, #0x10 @ encoding: [0x30,0x08,0xc1,0xf2] + +@ CHECK: vmov.i8 q8, #0x8 @ encoding: [0x58,0x0e,0xc0,0xf2] +@ CHECK: vmov.i16 q8, #0x10 @ encoding: [0x50,0x08,0xc1,0xf2] +@ CHECK: vmov.i16 q8, #0x1000 @ encoding: [0x50,0x0a,0xc1,0xf2] +@ CHECK: vmov.i32 q8, #0x20 @ encoding: [0x50,0x00,0xc2,0xf2] +@ CHECK: vmov.i32 q8, #0x2000 @ encoding: [0x50,0x02,0xc2,0xf2] +@ CHECK: vmov.i32 q8, #0x200000 @ encoding: [0x50,0x04,0xc2,0xf2] +@ CHECK: vmov.i32 q8, #0x20000000 @ encoding: [0x50,0x06,0xc2,0xf2] +@ CHECK: vmov.i32 q8, #0x20FF @ encoding: [0x50,0x0c,0xc2,0xf2] +@ CHECK: vmov.i32 q8, #0x20FFFF @ encoding: [0x50,0x0d,0xc2,0xf2] +@ CHECK: vmov.i64 q8, #0xFF0000FF0000FFFF @ encoding: [0x73,0x0e,0xc1,0xf3] + vmvn.i16 d16, #0x10 -@ CHECK: vmvn.i16 d16, #0x1000 @ encoding: [0x30,0x0a,0xc1,0xf2] vmvn.i16 d16, #0x1000 -@ CHECK: vmvn.i32 d16, #0x20 @ encoding: [0x30,0x00,0xc2,0xf2] vmvn.i32 d16, #0x20 -@ CHECK: vmvn.i32 d16, #0x2000 @ encoding: [0x30,0x02,0xc2,0xf2] vmvn.i32 d16, #0x2000 -@ CHECK: vmvn.i32 d16, #0x200000 @ encoding: [0x30,0x04,0xc2,0xf2] vmvn.i32 d16, #0x200000 -@ CHECK: vmvn.i32 d16, #0x20000000 @ encoding: [0x30,0x06,0xc2,0xf2] vmvn.i32 d16, #0x20000000 -@ CHECK: vmvn.i32 d16, #0x20FF @ encoding: [0x30,0x0c,0xc2,0xf2] vmvn.i32 d16, #0x20FF -@ CHECK: vmvn.i32 d16, #0x20FFFF @ encoding: [0x30,0x0d,0xc2,0xf2] vmvn.i32 d16, #0x20FFFF -@ CHECK: vmovl.s8 q8, d16 @ encoding: [0x30,0x0a,0xc8,0xf2] + +@ CHECK: vmvn.i16 d16, #0x10 @ encoding: [0x30,0x08,0xc1,0xf2] +@ CHECK: vmvn.i16 d16, #0x1000 @ encoding: [0x30,0x0a,0xc1,0xf2] +@ CHECK: vmvn.i32 d16, #0x20 @ encoding: [0x30,0x00,0xc2,0xf2] +@ CHECK: vmvn.i32 d16, #0x2000 @ encoding: [0x30,0x02,0xc2,0xf2] +@ CHECK: vmvn.i32 d16, #0x200000 @ encoding: [0x30,0x04,0xc2,0xf2] +@ CHECK: vmvn.i32 d16, #0x20000000 @ encoding: [0x30,0x06,0xc2,0xf2] +@ CHECK: vmvn.i32 d16, #0x20FF @ encoding: [0x30,0x0c,0xc2,0xf2] +@ CHECK: vmvn.i32 d16, #0x20FFFF @ encoding: [0x30,0x0d,0xc2,0xf2] + vmovl.s8 q8, d16 -@ CHECK: vmovl.s16 q8, d16 @ encoding: [0x30,0x0a,0xd0,0xf2] vmovl.s16 q8, d16 -@ CHECK: vmovl.s32 q8, d16 @ encoding: [0x30,0x0a,0xe0,0xf2] vmovl.s32 q8, d16 -@ CHECK: vmovl.u8 q8, d16 @ encoding: [0x30,0x0a,0xc8,0xf3] vmovl.u8 q8, d16 -@ CHECK: vmovl.u16 q8, d16 @ encoding: [0x30,0x0a,0xd0,0xf3] vmovl.u16 q8, d16 -@ CHECK: vmovl.u32 q8, d16 @ encoding: [0x30,0x0a,0xe0,0xf3] vmovl.u32 q8, d16 -@ CHECK: vmovn.i16 d16, q8 @ encoding: [0x20,0x02,0xf2,0xf3] + +@ CHECK: vmovl.s8 q8, d16 @ encoding: [0x30,0x0a,0xc8,0xf2] +@ CHECK: vmovl.s16 q8, d16 @ encoding: [0x30,0x0a,0xd0,0xf2] +@ CHECK: vmovl.s32 q8, d16 @ encoding: [0x30,0x0a,0xe0,0xf2] +@ CHECK: vmovl.u8 q8, d16 @ encoding: [0x30,0x0a,0xc8,0xf3] +@ CHECK: vmovl.u16 q8, d16 @ encoding: [0x30,0x0a,0xd0,0xf3] +@ CHECK: vmovl.u32 q8, d16 @ encoding: [0x30,0x0a,0xe0,0xf3] + + vmovn.i16 d16, q8 -@ CHECK: vmovn.i32 d16, q8 @ encoding: [0x20,0x02,0xf6,0xf3] vmovn.i32 d16, q8 -@ CHECK: vmovn.i64 d16, q8 @ encoding: [0x20,0x02,0xfa,0xf3] vmovn.i64 d16, q8 -@ CHECK: vqmovn.s16 d16, q8 @ encoding: [0xa0,0x02,0xf2,0xf3] vqmovn.s16 d16, q8 -@ CHECK: vqmovn.s32 d16, q8 @ encoding: [0xa0,0x02,0xf6,0xf3] vqmovn.s32 d16, q8 -@ CHECK: vqmovn.s64 d16, q8 @ encoding: [0xa0,0x02,0xfa,0xf3] vqmovn.s64 d16, q8 -@ CHECK: vqmovn.u16 d16, q8 @ encoding: [0xe0,0x02,0xf2,0xf3] vqmovn.u16 d16, q8 -@ CHECK: vqmovn.u32 d16, q8 @ encoding: [0xe0,0x02,0xf6,0xf3] vqmovn.u32 d16, q8 -@ CHECK: vqmovn.u64 d16, q8 @ encoding: [0xe0,0x02,0xfa,0xf3] vqmovn.u64 d16, q8 -@ CHECK: vqmovun.s16 d16, q8 @ encoding: [0x60,0x02,0xf2,0xf3] vqmovun.s16 d16, q8 -@ CHECK: vqmovun.s32 d16, q8 @ encoding: [0x60,0x02,0xf6,0xf3] vqmovun.s32 d16, q8 -@ CHECK: vqmovun.s64 d16, q8 @ encoding: [0x60,0x02,0xfa,0xf3] vqmovun.s64 d16, q8 -@ CHECK: vmov.s8 r0, d16[1] @ encoding: [0xb0,0x0b,0x50,0xee] - vmov.s8 r0, d16[1] -@ CHECK: vmov.s16 r0, d16[1] @ encoding: [0xf0,0x0b,0x10,0xee] + +@ CHECK: vmovn.i16 d16, q8 @ encoding: [0x20,0x02,0xf2,0xf3] +@ CHECK: vmovn.i32 d16, q8 @ encoding: [0x20,0x02,0xf6,0xf3] +@ CHECK: vmovn.i64 d16, q8 @ encoding: [0x20,0x02,0xfa,0xf3] +@ CHECK: vqmovn.s16 d16, q8 @ encoding: [0xa0,0x02,0xf2,0xf3] +@ CHECK: vqmovn.s32 d16, q8 @ encoding: [0xa0,0x02,0xf6,0xf3] +@ CHECK: vqmovn.s64 d16, q8 @ encoding: [0xa0,0x02,0xfa,0xf3] +@ CHECK: vqmovn.u16 d16, q8 @ encoding: [0xe0,0x02,0xf2,0xf3] +@ CHECK: vqmovn.u32 d16, q8 @ encoding: [0xe0,0x02,0xf6,0xf3] +@ CHECK: vqmovn.u64 d16, q8 @ encoding: [0xe0,0x02,0xfa,0xf3] +@ CHECK: vqmovun.s16 d16, q8 @ encoding: [0x60,0x02,0xf2,0xf3] +@ CHECK: vqmovun.s32 d16, q8 @ encoding: [0x60,0x02,0xf6,0xf3] +@ CHECK: vqmovun.s64 d16, q8 @ encoding: [0x60,0x02,0xfa,0xf3] + + vmov.s8 r0, d16[1] vmov.s16 r0, d16[1] -@ CHECK: vmov.u8 r0, d16[1] @ encoding: [0xb0,0x0b,0xd0,0xee] - vmov.u8 r0, d16[1] -@ CHECK: vmov.u16 r0, d16[1] @ encoding: [0xf0,0x0b,0x90,0xee] + vmov.u8 r0, d16[1] vmov.u16 r0, d16[1] -@ CHECK: vmov.32 r0, d16[1] @ encoding: [0x90,0x0b,0x30,0xee] - vmov.32 r0, d16[1] -@ CHECK: vmov.8 d16[1], r1 @ encoding: [0xb0,0x1b,0x40,0xee] + vmov.32 r0, d16[1] vmov.8 d16[1], r1 -@ CHECK: vmov.16 d16[1], r1 @ encoding: [0xf0,0x1b,0x00,0xee] vmov.16 d16[1], r1 -@ CHECK: vmov.32 d16[1], r1 @ encoding: [0x90,0x1b,0x20,0xee] vmov.32 d16[1], r1 -@ CHECK: vmov.8 d18[1], r1 @ encoding: [0xb0,0x1b,0x42,0xee] vmov.8 d18[1], r1 -@ CHECK: vmov.16 d18[1], r1 @ encoding: [0xf0,0x1b,0x02,0xee] vmov.16 d18[1], r1 -@ CHECK: vmov.32 d18[1], r1 @ encoding: [0x90,0x1b,0x22,0xee] vmov.32 d18[1], r1 + +@ CHECK: vmov.s8 r0, d16[1] @ encoding: [0xb0,0x0b,0x50,0xee] +@ CHECK: vmov.s16 r0, d16[1] @ encoding: [0xf0,0x0b,0x10,0xee] +@ CHECK: vmov.u8 r0, d16[1] @ encoding: [0xb0,0x0b,0xd0,0xee] +@ CHECK: vmov.u16 r0, d16[1] @ encoding: [0xf0,0x0b,0x90,0xee] +@ CHECK: vmov.32 r0, d16[1] @ encoding: [0x90,0x0b,0x30,0xee] +@ CHECK: vmov.8 d16[1], r1 @ encoding: [0xb0,0x1b,0x40,0xee] +@ CHECK: vmov.16 d16[1], r1 @ encoding: [0xf0,0x1b,0x00,0xee] +@ CHECK: vmov.32 d16[1], r1 @ encoding: [0x90,0x1b,0x20,0xee] +@ CHECK: vmov.8 d18[1], r1 @ encoding: [0xb0,0x1b,0x42,0xee] +@ CHECK: vmov.16 d18[1], r1 @ encoding: [0xf0,0x1b,0x02,0xee] +@ CHECK: vmov.32 d18[1], r1 @ encoding: [0x90,0x1b,0x22,0xee] diff --git a/test/MC/ARM/neon-mul-accum-encoding.s b/test/MC/ARM/neon-mul-accum-encoding.s index e269dea360f4..ed9ceb3ecb00 100644 --- a/test/MC/ARM/neon-mul-accum-encoding.s +++ b/test/MC/ARM/neon-mul-accum-encoding.s @@ -1,11 +1,10 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding < %s | FileCheck %s -@ XFAIL: * @ CHECK: vmla.i8 d16, d18, d17 @ encoding: [0xa1,0x09,0x42,0xf2] vmla.i8 d16, d18, d17 @ CHECK: vmla.i16 d16, d18, d17 @ encoding: [0xa1,0x09,0x52,0xf2] vmla.i16 d16, d18, d17 -@ CHECK: vmla.i16 d16, d18, d17 @ encoding: [0xa1,0x09,0x52,0xf2] +@ CHECK: vmla.i32 d16, d18, d17 @ encoding: [0xa1,0x09,0x62,0xf2] vmla.i32 d16, d18, d17 @ CHECK: vmla.f32 d16, d18, d17 @ encoding: [0xb1,0x0d,0x42,0xf2] vmla.f32 d16, d18, d17 diff --git a/test/MC/ARM/neon-mul-encoding.s b/test/MC/ARM/neon-mul-encoding.s index 4ff192f6e557..4dc78036c025 100644 --- a/test/MC/ARM/neon-mul-encoding.s +++ b/test/MC/ARM/neon-mul-encoding.s @@ -1,56 +1,82 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple arm-unknown-unknown -show-encoding < %s | FileCheck %s -@ CHECK: vmul.i8 d16, d16, d17 @ encoding: [0xb1,0x09,0x40,0xf2] - vmul.i8 d16, d16, d17 -@ CHECK: vmul.i16 d16, d16, d17 @ encoding: [0xb1,0x09,0x50,0xf2] - vmul.i16 d16, d16, d17 -@ CHECK: vmul.i32 d16, d16, d17 @ encoding: [0xb1,0x09,0x60,0xf2] - vmul.i32 d16, d16, d17 -@ CHECK: vmul.f32 d16, d16, d17 @ encoding: [0xb1,0x0d,0x40,0xf3] - vmul.f32 d16, d16, d17 -@ CHECK: vmul.i8 q8, q8, q9 @ encoding: [0xf2,0x09,0x40,0xf2] - vmul.i8 q8, q8, q9 -@ CHECK: vmul.i16 q8, q8, q9 @ encoding: [0xf2,0x09,0x50,0xf2] - vmul.i16 q8, q8, q9 -@ CHECK: vmul.i32 q8, q8, q9 @ encoding: [0xf2,0x09,0x60,0xf2] - vmul.i32 q8, q8, q9 -@ CHECK: vmul.f32 q8, q8, q9 @ encoding: [0xf2,0x0d,0x40,0xf3] - vmul.f32 q8, q8, q9 -@ CHECK: vmul.p8 d16, d16, d17 @ encoding: [0xb1,0x09,0x40,0xf3] - vmul.p8 d16, d16, d17 -@ CHECK: vmul.p8 q8, q8, q9 @ encoding: [0xf2,0x09,0x40,0xf3] - vmul.p8 q8, q8, q9 -@ CHECK: vqdmulh.s16 d16, d16, d17 @ encoding: [0xa1,0x0b,0x50,0xf2] - vqdmulh.s16 d16, d16, d17 -@ CHECK: vqdmulh.s32 d16, d16, d17 @ encoding: [0xa1,0x0b,0x60,0xf2] - vqdmulh.s32 d16, d16, d17 -@ CHECK: vqdmulh.s16 q8, q8, q9 @ encoding: [0xe2,0x0b,0x50,0xf2] - vqdmulh.s16 q8, q8, q9 -@ CHECK: vqdmulh.s32 q8, q8, q9 @ encoding: [0xe2,0x0b,0x60,0xf2] - vqdmulh.s32 q8, q8, q9 -@ CHECK: vqrdmulh.s16 d16, d16, d17 @ encoding: [0xa1,0x0b,0x50,0xf3] - vqrdmulh.s16 d16, d16, d17 -@ CHECK: vqrdmulh.s32 d16, d16, d17 @ encoding: [0xa1,0x0b,0x60,0xf3] - vqrdmulh.s32 d16, d16, d17 -@ CHECK: vqrdmulh.s16 q8, q8, q9 @ encoding: [0xe2,0x0b,0x50,0xf3] - vqrdmulh.s16 q8, q8, q9 -@ CHECK: vqrdmulh.s32 q8, q8, q9 @ encoding: [0xe2,0x0b,0x60,0xf3] - vqrdmulh.s32 q8, q8, q9 -@ CHECK: vmull.s8 q8, d16, d17 @ encoding: [0xa1,0x0c,0xc0,0xf2] - vmull.s8 q8, d16, d17 -@ CHECK: vmull.s16 q8, d16, d17 @ encoding: [0xa1,0x0c,0xd0,0xf2] - vmull.s16 q8, d16, d17 -@ CHECK: vmull.s32 q8, d16, d17 @ encoding: [0xa1,0x0c,0xe0,0xf2] - vmull.s32 q8, d16, d17 -@ CHECK: vmull.u8 q8, d16, d17 @ encoding: [0xa1,0x0c,0xc0,0xf3] - vmull.u8 q8, d16, d17 -@ CHECK: vmull.u16 q8, d16, d17 @ encoding: [0xa1,0x0c,0xd0,0xf3] - vmull.u16 q8, d16, d17 -@ CHECK: vmull.u32 q8, d16, d17 @ encoding: [0xa1,0x0c,0xe0,0xf3] - vmull.u32 q8, d16, d17 -@ CHECK: vmull.p8 q8, d16, d17 @ encoding: [0xa1,0x0e,0xc0,0xf2] - vmull.p8 q8, d16, d17 -@ CHECK: vqdmull.s16 q8, d16, d17 @ encoding: [0xa1,0x0d,0xd0,0xf2] - vqdmull.s16 q8, d16, d17 -@ CHECK: vqdmull.s32 q8, d16, d17 @ encoding: [0xa1,0x0d,0xe0,0xf2] - vqdmull.s32 q8, d16, d17 + vmla.i8 d16, d18, d17 + vmla.i16 d16, d18, d17 + vmla.i32 d16, d18, d17 + vmla.f32 d16, d18, d17 + vmla.i8 q9, q8, q10 + vmla.i16 q9, q8, q10 + vmla.i32 q9, q8, q10 + vmla.f32 q9, q8, q10 + +@ CHECK: vmla.i8 d16, d18, d17 @ encoding: [0xa1,0x09,0x42,0xf2] +@ CHECK: vmla.i16 d16, d18, d17 @ encoding: [0xa1,0x09,0x52,0xf2] +@ CHECK: vmla.i32 d16, d18, d17 @ encoding: [0xa1,0x09,0x62,0xf2] +@ CHECK: vmla.f32 d16, d18, d17 @ encoding: [0xb1,0x0d,0x42,0xf2] +@ CHECK: vmla.i8 q9, q8, q10 @ encoding: [0xe4,0x29,0x40,0xf2] +@ CHECK: vmla.i16 q9, q8, q10 @ encoding: [0xe4,0x29,0x50,0xf2] +@ CHECK: vmla.i32 q9, q8, q10 @ encoding: [0xe4,0x29,0x60,0xf2] +@ CHECK: vmla.f32 q9, q8, q10 @ encoding: [0xf4,0x2d,0x40,0xf2] + + + vmlal.s8 q8, d19, d18 + vmlal.s16 q8, d19, d18 + vmlal.s32 q8, d19, d18 + vmlal.u8 q8, d19, d18 + vmlal.u16 q8, d19, d18 + vmlal.u32 q8, d19, d18 + +@ CHECK: vmlal.s8 q8, d19, d18 @ encoding: [0xa2,0x08,0xc3,0xf2] +@ CHECK: vmlal.s16 q8, d19, d18 @ encoding: [0xa2,0x08,0xd3,0xf2] +@ CHECK: vmlal.s32 q8, d19, d18 @ encoding: [0xa2,0x08,0xe3,0xf2] +@ CHECK: vmlal.u8 q8, d19, d18 @ encoding: [0xa2,0x08,0xc3,0xf3] +@ CHECK: vmlal.u16 q8, d19, d18 @ encoding: [0xa2,0x08,0xd3,0xf3] +@ CHECK: vmlal.u32 q8, d19, d18 @ encoding: [0xa2,0x08,0xe3,0xf3] + + + vqdmlal.s16 q8, d19, d18 + vqdmlal.s32 q8, d19, d18 + +@ CHECK: vqdmlal.s16 q8, d19, d18 @ encoding: [0xa2,0x09,0xd3,0xf2] +@ CHECK: vqdmlal.s32 q8, d19, d18 @ encoding: [0xa2,0x09,0xe3,0xf2] + + + vmls.i8 d16, d18, d17 + vmls.i16 d16, d18, d17 + vmls.i32 d16, d18, d17 + vmls.f32 d16, d18, d17 + vmls.i8 q9, q8, q10 + vmls.i16 q9, q8, q10 + vmls.i32 q9, q8, q10 + vmls.f32 q9, q8, q10 + +@ CHECK: vmls.i8 d16, d18, d17 @ encoding: [0xa1,0x09,0x42,0xf3] +@ CHECK: vmls.i16 d16, d18, d17 @ encoding: [0xa1,0x09,0x52,0xf3] +@ CHECK: vmls.i32 d16, d18, d17 @ encoding: [0xa1,0x09,0x62,0xf3] +@ CHECK: vmls.f32 d16, d18, d17 @ encoding: [0xb1,0x0d,0x62,0xf2] +@ CHECK: vmls.i8 q9, q8, q10 @ encoding: [0xe4,0x29,0x40,0xf3] +@ CHECK: vmls.i16 q9, q8, q10 @ encoding: [0xe4,0x29,0x50,0xf3] +@ CHECK: vmls.i32 q9, q8, q10 @ encoding: [0xe4,0x29,0x60,0xf3] +@ CHECK: vmls.f32 q9, q8, q10 @ encoding: [0xf4,0x2d,0x60,0xf2] + + + vmlsl.s8 q8, d19, d18 + vmlsl.s16 q8, d19, d18 + vmlsl.s32 q8, d19, d18 + vmlsl.u8 q8, d19, d18 + vmlsl.u16 q8, d19, d18 + vmlsl.u32 q8, d19, d18 + +@ CHECK: vmlsl.s8 q8, d19, d18 @ encoding: [0xa2,0x0a,0xc3,0xf2] +@ CHECK: vmlsl.s16 q8, d19, d18 @ encoding: [0xa2,0x0a,0xd3,0xf2] +@ CHECK: vmlsl.s32 q8, d19, d18 @ encoding: [0xa2,0x0a,0xe3,0xf2] +@ CHECK: vmlsl.u8 q8, d19, d18 @ encoding: [0xa2,0x0a,0xc3,0xf3] +@ CHECK: vmlsl.u16 q8, d19, d18 @ encoding: [0xa2,0x0a,0xd3,0xf3] +@ CHECK: vmlsl.u32 q8, d19, d18 @ encoding: [0xa2,0x0a,0xe3,0xf3] + + + vqdmlsl.s16 q8, d19, d18 + vqdmlsl.s32 q8, d19, d18 + +@ CHECK: vqdmlsl.s16 q8, d19, d18 @ encoding: [0xa2,0x0b,0xd3,0xf2] +@ CHECK: vqdmlsl.s32 q8, d19, d18 @ encoding: [0xa2,0x0b,0xe3,0xf2] diff --git a/test/MC/ARM/neon-vld-encoding.s b/test/MC/ARM/neon-vld-encoding.s index be55f47900c6..55c88686e003 100644 --- a/test/MC/ARM/neon-vld-encoding.s +++ b/test/MC/ARM/neon-vld-encoding.s @@ -1,110 +1,125 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple armv7-apple-darwin -show-encoding < %s | FileCheck %s @ XFAIL: * -@ CHECK: vld1.8 {d16}, [r0, :64] @ encoding: [0x1f,0x07,0x60,0xf4] vld1.8 {d16}, [r0, :64] -@ CHECK: vld1.16 {d16}, [r0] @ encoding: [0x4f,0x07,0x60,0xf4] - vld1.16 {d16}, [r0] -@ CHECK: vld1.32 {d16}, [r0] @ encoding: [0x8f,0x07,0x60,0xf4] - vld1.32 {d16}, [r0] -@ CHECK: vld1.64 {d16}, [r0] @ encoding: [0xcf,0x07,0x60,0xf4] - vld1.64 {d16}, [r0] + vld1.16 {d16}, [r0] + vld1.32 {d16}, [r0] + vld1.64 {d16}, [r0] + vld1.8 {d16, d17}, [r0, :64] + vld1.16 {d16, d17}, [r0, :128] + vld1.32 {d16, d17}, [r0] + vld1.64 {d16, d17}, [r0] + +@ CHECK: vld1.8 {d16}, [r0, :64] @ encoding: [0x1f,0x07,0x60,0xf4] +@ CHECK: vld1.16 {d16}, [r0] @ encoding: [0x4f,0x07,0x60,0xf4] +@ CHECK: vld1.32 {d16}, [r0] @ encoding: [0x8f,0x07,0x60,0xf4] +@ CHECK: vld1.64 {d16}, [r0] @ encoding: [0xcf,0x07,0x60,0xf4] @ CHECK: vld1.8 {d16, d17}, [r0, :64] @ encoding: [0x1f,0x0a,0x60,0xf4] - vld1.8 {d16, d17}, [r0, :64] -@ CHECK: vld1.16 {d16, d17}, [r0, :128] @ encoding: [0x6f,0x0a,0x60,0xf4] - vld1.16 {d16, d17}, [r0, :128] -@ CHECK: vld1.32 {d16, d17}, [r0] @ encoding: [0x8f,0x0a,0x60,0xf4] - vld1.32 {d16, d17}, [r0] -@ CHECK: vld1.64 {d16, d17}, [r0] @ encoding: [0xcf,0x0a,0x60,0xf4] - vld1.64 {d16, d17}, [r0] +@ CHECK: vld1.16 {d16, d17}, [r0, :128] @ encoding: [0x6f,0x0a,0x60,0xf4] +@ CHECK: vld1.32 {d16, d17}, [r0]@ encoding: [0x8f,0x0a,0x60,0xf4] +@ CHECK: vld1.64 {d16, d17}, [r0]@ encoding: [0xcf,0x0a,0x60,0xf4] + + + vld2.8 {d16, d17}, [r0, :64] + vld2.16 {d16, d17}, [r0, :128] + vld2.32 {d16, d17}, [r0] + vld2.8 {d16, d17, d18, d19}, [r0, :64] + vld2.16 {d16, d17, d18, d19}, [r0, :128] + vld2.32 {d16, d17, d18, d19}, [r0, :256] @ CHECK: vld2.8 {d16, d17}, [r0, :64] @ encoding: [0x1f,0x08,0x60,0xf4] - vld2.8 {d16, d17}, [r0, :64] -@ CHECK: vld2.16 {d16, d17}, [r0, :128] @ encoding: [0x6f,0x08,0x60,0xf4] - vld2.16 {d16, d17}, [r0, :128] -@ CHECK: vld2.32 {d16, d17}, [r0] @ encoding: [0x8f,0x08,0x60,0xf4] - vld2.32 {d16, d17}, [r0] -@ CHECK: vld2.8 {d16, d17, d18, d19}, [r0, :64] @ encoding: [0x1f,0x03,0x60,0xf4] - vld2.8 {d16, d17, d18, d19}, [r0, :64] -@ CHECK: vld2.16 {d16, d17, d18, d19}, [r0, :128] @ encoding: [0x6f,0x03,0x60,0xf4] - vld2.16 {d16, d17, d18, d19}, [r0, :128] -@ CHECK: vld2.32 {d16, d17, d18, d19}, [r0, :256] @ encoding: [0xbf,0x03,0x60,0xf4] - vld2.32 {d16, d17, d18, d19}, [r0, :256] +@ CHECK: vld2.16 {d16, d17}, [r0, :128] @ encoding: [0x6f,0x08,0x60,0xf4] +@ CHECK: vld2.32 {d16, d17}, [r0]@ encoding: [0x8f,0x08,0x60,0xf4] +@ CHECK: vld2.8 {d16, d17, d18, d19}, [r0, :64]@ encoding: [0x1f,0x03,0x60,0xf4] +@ CHECK: vld2.16 {d16, d17, d18, d19}, [r0, :128] @ encoding: [0x6f,0x03,0x60,0xf4] +@ CHECK: vld2.32 {d16, d17, d18, d19}, [r0, :256] @ encoding: [0xbf,0x03,0x60,0xf4] + + + vld3.8 {d16, d17, d18}, [r0, :64] + vld3.16 {d16, d17, d18}, [r0] + vld3.32 {d16, d17, d18}, [r0] + vld3.8 {d16, d18, d20}, [r0, :64]! + vld3.8 {d17, d19, d21}, [r0, :64]! + vld3.16 {d16, d18, d20}, [r0]! + vld3.16 {d17, d19, d21}, [r0]! + vld3.32 {d16, d18, d20}, [r0]! + vld3.32 {d17, d19, d21}, [r0]! @ CHECK: vld3.8 {d16, d17, d18}, [r0, :64] @ encoding: [0x1f,0x04,0x60,0xf4] - vld3.8 {d16, d17, d18}, [r0, :64] -@ CHECK: vld3.16 {d16, d17, d18}, [r0] @ encoding: [0x4f,0x04,0x60,0xf4] - vld3.16 {d16, d17, d18}, [r0] -@ CHECK: vld3.32 {d16, d17, d18}, [r0] @ encoding: [0x8f,0x04,0x60,0xf4] - vld3.32 {d16, d17, d18}, [r0] +@ CHECK: vld3.16 {d16, d17, d18}, [r0] @ encoding: [0x4f,0x04,0x60,0xf4] +@ CHECK: vld3.32 {d16, d17, d18}, [r0] @ encoding: [0x8f,0x04,0x60,0xf4] @ CHECK: vld3.8 {d16, d18, d20}, [r0, :64]! @ encoding: [0x1d,0x05,0x60,0xf4] - vld3.8 {d16, d18, d20}, [r0, :64]! @ CHECK: vld3.8 {d17, d19, d21}, [r0, :64]! @ encoding: [0x1d,0x15,0x60,0xf4] - vld3.8 {d17, d19, d21}, [r0, :64]! -@ CHECK: vld3.16 {d16, d18, d20}, [r0]! @ encoding: [0x4d,0x05,0x60,0xf4] - vld3.16 {d16, d18, d20}, [r0]! -@ CHECK: vld3.16 {d17, d19, d21}, [r0]! @ encoding: [0x4d,0x15,0x60,0xf4] - vld3.16 {d17, d19, d21}, [r0]! -@ CHECK: vld3.32 {d16, d18, d20}, [r0]! @ encoding: [0x8d,0x05,0x60,0xf4] - vld3.32 {d16, d18, d20}, [r0]! -@ CHECK: vld3.32 {d17, d19, d21}, [r0]! @ encoding: [0x8d,0x15,0x60,0xf4] - vld3.32 {d17, d19, d21}, [r0]! +@ CHECK: vld3.16 {d16, d18, d20}, [r0]! @ encoding: [0x4d,0x05,0x60,0xf4] +@ CHECK: vld3.16 {d17, d19, d21}, [r0]! @ encoding: [0x4d,0x15,0x60,0xf4] +@ CHECK: vld3.32 {d16, d18, d20}, [r0]! @ encoding: [0x8d,0x05,0x60,0xf4] +@ CHECK: vld3.32 {d17, d19, d21}, [r0]! @ encoding: [0x8d,0x15,0x60,0xf4] -@ CHECK: vld4.8 {d16, d17, d18, d19}, [r0, :64] @ encoding: [0x1f,0x00,0x60,0xf4] - vld4.8 {d16, d17, d18, d19}, [r0, :64] -@ CHECK: vld4.16 {d16, d17, d18, d19}, [r0, :128] @ encoding: [0x6f,0x00,0x60,0xf4] - vld4.16 {d16, d17, d18, d19}, [r0, :128] -@ CHECK: vld4.32 {d16, d17, d18, d19}, [r0, :256] @ encoding: [0xbf,0x00,0x60,0xf4] - vld4.32 {d16, d17, d18, d19}, [r0, :256] -@ CHECK: vld4.8 {d16, d18, d20, d22}, [r0, :256]! @ encoding: [0x3d,0x01,0x60,0xf4] - vld4.8 {d16, d18, d20, d22}, [r0, :256]! -@ CHECK: vld4.8 {d17, d19, d21, d23}, [r0, :256]! @ encoding: [0x3d,0x11,0x60,0xf4] - vld4.8 {d17, d19, d21, d23}, [r0, :256]! -@ CHECK: vld4.16 {d16, d18, d20, d22}, [r0]! @ encoding: [0x4d,0x01,0x60,0xf4] - vld4.16 {d16, d18, d20, d22}, [r0]! -@ CHECK: vld4.16 {d17, d19, d21, d23}, [r0]! @ encoding: [0x4d,0x11,0x60,0xf4] - vld4.16 {d17, d19, d21, d23}, [r0]! -@ CHECK: vld4.32 {d16, d18, d20, d22}, [r0]! @ encoding: [0x8d,0x01,0x60,0xf4] - vld4.32 {d16, d18, d20, d22}, [r0]! -@ CHECK: vld4.32 {d17, d19, d21, d23}, [r0]! @ encoding: [0x8d,0x11,0x60,0xf4] - vld4.32 {d17, d19, d21, d23}, [r0]! + + vld4.8 {d16, d17, d18, d19}, [r0, :64] + vld4.16 {d16, d17, d18, d19}, [r0, :128] + vld4.32 {d16, d17, d18, d19}, [r0, :256] + vld4.8 {d16, d18, d20, d22}, [r0, :256]! + vld4.8 {d17, d19, d21, d23}, [r0, :256]! + vld4.16 {d16, d18, d20, d22}, [r0]! + vld4.16 {d17, d19, d21, d23}, [r0]! + vld4.32 {d16, d18, d20, d22}, [r0]! + vld4.32 {d17, d19, d21, d23}, [r0]! + +@ CHECK: vld4.8 {d16, d17, d18, d19}, [r0, :64]@ encoding: [0x1f,0x00,0x60,0xf4] +@ CHECK: vld4.16 {d16, d17, d18, d19}, [r0,:128]@ encoding:[0x6f,0x00,0x60,0xf4] +@ CHECK: vld4.32 {d16, d17, d18, d19}, [r0,:256]@ encoding:[0xbf,0x00,0x60,0xf4] +@ CHECK: vld4.8 {d16, d18, d20, d22}, [r0,:256]!@ encoding:[0x3d,0x01,0x60,0xf4] +@ CHECK: vld4.8 {d17, d19, d21, d23}, [r0,:256]!@ encoding:[0x3d,0x11,0x60,0xf4] +@ CHECK: vld4.16 {d16, d18, d20, d22}, [r0]! @ encoding: [0x4d,0x01,0x60,0xf4] +@ CHECK: vld4.16 {d17, d19, d21, d23}, [r0]! @ encoding: [0x4d,0x11,0x60,0xf4] +@ CHECK: vld4.32 {d16, d18, d20, d22}, [r0]! @ encoding: [0x8d,0x01,0x60,0xf4] +@ CHECK: vld4.32 {d17, d19, d21, d23}, [r0]! @ encoding: [0x8d,0x11,0x60,0xf4] + + + vld1.8 {d16[3]}, [r0] + vld1.16 {d16[2]}, [r0, :16] + vld1.32 {d16[1]}, [r0, :32] @ CHECK: vld1.8 {d16[3]}, [r0] @ encoding: [0x6f,0x00,0xe0,0xf4] - vld1.8 {d16[3]}, [r0] -@ CHECK: vld1.16 {d16[2]}, [r0, :16] @ encoding: [0x9f,0x04,0xe0,0xf4] - vld1.16 {d16[2]}, [r0, :16] -@ CHECK: vld1.32 {d16[1]}, [r0, :32] @ encoding: [0xbf,0x08,0xe0,0xf4] - vld1.32 {d16[1]}, [r0, :32] +@ CHECK: vld1.16 {d16[2]}, [r0, :16] @ encoding: [0x9f,0x04,0xe0,0xf4] +@ CHECK: vld1.32 {d16[1]}, [r0, :32] @ encoding: [0xbf,0x08,0xe0,0xf4] + + + vld2.8 {d16[1], d17[1]}, [r0, :16] + vld2.16 {d16[1], d17[1]}, [r0, :32] + vld2.32 {d16[1], d17[1]}, [r0] + vld2.16 {d17[1], d19[1]}, [r0] + vld2.32 {d17[0], d19[0]}, [r0, :64] @ CHECK: vld2.8 {d16[1], d17[1]}, [r0, :16] @ encoding: [0x3f,0x01,0xe0,0xf4] - vld2.8 {d16[1], d17[1]}, [r0, :16] -@ CHECK: vld2.16 {d16[1], d17[1]}, [r0, :32] @ encoding: [0x5f,0x05,0xe0,0xf4] - vld2.16 {d16[1], d17[1]}, [r0, :32] -@ CHECK: vld2.32 {d16[1], d17[1]}, [r0] @ encoding: [0x8f,0x09,0xe0,0xf4] - vld2.32 {d16[1], d17[1]}, [r0] -@ CHECK: vld2.16 {d17[1], d19[1]}, [r0] @ encoding: [0x6f,0x15,0xe0,0xf4] - vld2.16 {d17[1], d19[1]}, [r0] -@ CHECK: vld2.32 {d17[0], d19[0]}, [r0, :64] @ encoding: [0x5f,0x19,0xe0,0xf4] - vld2.32 {d17[0], d19[0]}, [r0, :64] +@ CHECK: vld2.16 {d16[1], d17[1]}, [r0, :32] @ encoding: [0x5f,0x05,0xe0,0xf4] +@ CHECK: vld2.32 {d16[1], d17[1]}, [r0] @ encoding: [0x8f,0x09,0xe0,0xf4] +@ CHECK: vld2.16 {d17[1], d19[1]}, [r0] @ encoding: [0x6f,0x15,0xe0,0xf4] +@ CHECK: vld2.32 {d17[0], d19[0]}, [r0, :64] @ encoding: [0x5f,0x19,0xe0,0xf4] + + + vld3.8 {d16[1], d17[1], d18[1]}, [r0] + vld3.16 {d16[1], d17[1], d18[1]}, [r0] + vld3.32 {d16[1], d17[1], d18[1]}, [r0] + vld3.16 {d16[1], d18[1], d20[1]}, [r0] + vld3.32 {d17[1], d19[1], d21[1]}, [r0] @ CHECK: vld3.8 {d16[1], d17[1], d18[1]}, [r0] @ encoding: [0x2f,0x02,0xe0,0xf4] - vld3.8 {d16[1], d17[1], d18[1]}, [r0] -@ CHECK: vld3.16 {d16[1], d17[1], d18[1]}, [r0] @ encoding: [0x4f,0x06,0xe0,0xf4] - vld3.16 {d16[1], d17[1], d18[1]}, [r0] -@ CHECK: vld3.32 {d16[1], d17[1], d18[1]}, [r0] @ encoding: [0x8f,0x0a,0xe0,0xf4] - vld3.32 {d16[1], d17[1], d18[1]}, [r0] -@ CHECK: vld3.16 {d16[1], d18[1], d20[1]}, [r0] @ encoding: [0x6f,0x06,0xe0,0xf4] - vld3.16 {d16[1], d18[1], d20[1]}, [r0] -@ CHECK: vld3.32 {d17[1], d19[1], d21[1]}, [r0] @ encoding: [0xcf,0x1a,0xe0,0xf4] - vld3.32 {d17[1], d19[1], d21[1]}, [r0] +@ CHECK: vld3.16 {d16[1], d17[1], d18[1]}, [r0]@ encoding: [0x4f,0x06,0xe0,0xf4] +@ CHECK: vld3.32 {d16[1], d17[1], d18[1]}, [r0]@ encoding: [0x8f,0x0a,0xe0,0xf4] +@ CHECK: vld3.16 {d16[1], d18[1], d20[1]}, [r0]@ encoding: [0x6f,0x06,0xe0,0xf4] +@ CHECK: vld3.32 {d17[1], d19[1], d21[1]}, [r0]@ encoding: [0xcf,0x1a,0xe0,0xf4] + + + vld4.8 {d16[1], d17[1], d18[1], d19[1]}, [r0, :32] + vld4.16 {d16[1], d17[1], d18[1], d19[1]}, [r0] + vld4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0, :128] + vld4.16 {d16[1], d18[1], d20[1], d22[1]}, [r0, :64] + vld4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0] @ CHECK: vld4.8 {d16[1], d17[1], d18[1], d19[1]}, [r0, :32] @ encoding: [0x3f,0x03,0xe0,0xf4] - vld4.8 {d16[1], d17[1], d18[1], d19[1]}, [r0, :32] -@ CHECK: vld4.16 {d16[1], d17[1], d18[1], d19[1]}, [r0] @ encoding: [0x4f,0x07,0xe0,0xf4] - vld4.16 {d16[1], d17[1], d18[1], d19[1]}, [r0] -@ CHECK: vld4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0, :128] @ encoding: [0xaf,0x0b,0xe0,0xf4] - vld4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0, :128] -@ CHECK: vld4.16 {d16[1], d18[1], d20[1], d22[1]}, [r0, :64] @ encoding: [0x7f,0x07,0xe0,0xf4] - vld4.16 {d16[1], d18[1], d20[1], d22[1]}, [r0, :64] -@ CHECK: vld4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0] @ encoding: [0x4f,0x1b,0xe0,0xf4] - vld4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0] +@ CHECK: vld4.16 {d16[1], d17[1], d18[1], d19[1]}, [r0] @ encoding: [0x4f,0x07,0xe0,0xf4] +@ CHECK: vld4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0, :128] @ encoding: [0xaf,0x0b,0xe0,0xf4] +@ CHECK: vld4.16 {d16[1], d18[1], d20[1], d22[1]}, [r0, :64] @ encoding: [0x7f,0x07,0xe0,0xf4] +@ CHECK: vld4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0] @ encoding: [0x4f,0x1b,0xe0,0xf4] diff --git a/test/MC/ARM/neont2-absdiff-encoding.s b/test/MC/ARM/neont2-absdiff-encoding.s index 2096357ce8ff..431348392f48 100644 --- a/test/MC/ARM/neont2-absdiff-encoding.s +++ b/test/MC/ARM/neont2-absdiff-encoding.s @@ -1,86 +1,91 @@ -@ RUN: llvm-mc -mcpu=cortex-a8 -triple thumb-unknown-unknown -show-encoding < %s | FileCheck %s -@ XFAIL: * -@ NOTE: This currently fails because the ASM parser doesn't parse vabal. +@RUN: llvm-mc -triple thumbv7-unknown-unknown -show-encoding < %s | FileCheck %s .code 16 -@ CHECK: vabd.s8 d16, d16, d17 @ encoding: [0xa1,0x07,0x40,0xef] vabd.s8 d16, d16, d17 -@ CHECK: vabd.s16 d16, d16, d17 @ encoding: [0xa1,0x07,0x50,0xef] vabd.s16 d16, d16, d17 -@ CHECK: vabd.s32 d16, d16, d17 @ encoding: [0xa1,0x07,0x60,0xef] vabd.s32 d16, d16, d17 -@ CHECK: vabd.u8 d16, d16, d17 @ encoding: [0xa1,0x07,0x40,0xff] vabd.u8 d16, d16, d17 -@ CHECK: vabd.u16 d16, d16, d17 @ encoding: [0xa1,0x07,0x50,0xff] vabd.u16 d16, d16, d17 - @ CHECK: vabd.u32 d16, d16, d17 @ encoding: [0xa1,0x07,0x60,0xff] vabd.u32 d16, d16, d17 -@ CHECK: vabd.f32 d16, d16, d17 @ encoding: [0xa1,0x0d,0x60,0xff] vabd.f32 d16, d16, d17 -@ CHECK: vabd.s8 q8, q8, q9 @ encoding: [0xe2,0x07,0x40,0xef] vabd.s8 q8, q8, q9 -@ CHECK: vabd.s16 q8, q8, q9 @ encoding: [0xe2,0x07,0x50,0xef] vabd.s16 q8, q8, q9 -@ CHECK: vabd.s32 q8, q8, q9 @ encoding: [0xe2,0x07,0x60,0xef] vabd.s32 q8, q8, q9 -@ CHECK: vabd.u8 q8, q8, q9 @ encoding: [0xe2,0x07,0x40,0xff] vabd.u8 q8, q8, q9 -@ CHECK: vabd.u16 q8, q8, q9 @ encoding: [0xe2,0x07,0x50,0xff] vabd.u16 q8, q8, q9 -@ CHECK: vabd.u32 q8, q8, q9 @ encoding: [0xe2,0x07,0x60,0xff] vabd.u32 q8, q8, q9 -@ CHECK: vabd.f32 q8, q8, q9 @ encoding: [0xe2,0x0d,0x60,0xff] vabd.f32 q8, q8, q9 -@ CHECK: vabdl.s8 q8, d16, d17 @ encoding: [0xa1,0x07,0xc0,0xef] +@ CHECK: vabd.s8 d16, d16, d17 @ encoding: [0x40,0xef,0xa1,0x07] +@ CHECK: vabd.s16 d16, d16, d17 @ encoding: [0x50,0xef,0xa1,0x07] +@ CHECK: vabd.s32 d16, d16, d17 @ encoding: [0x60,0xef,0xa1,0x07] +@ CHECK: vabd.u8 d16, d16, d17 @ encoding: [0x40,0xff,0xa1,0x07] +@ CHECK: vabd.u16 d16, d16, d17 @ encoding: [0x50,0xff,0xa1,0x07] +@ CHECK: vabd.u32 d16, d16, d17 @ encoding: [0x60,0xff,0xa1,0x07] +@ CHECK: vabd.f32 d16, d16, d17 @ encoding: [0x60,0xff,0xa1,0x0d] +@ CHECK: vabd.s8 q8, q8, q9 @ encoding: [0x40,0xef,0xe2,0x07] +@ CHECK: vabd.s16 q8, q8, q9 @ encoding: [0x50,0xef,0xe2,0x07] +@ CHECK: vabd.s32 q8, q8, q9 @ encoding: [0x60,0xef,0xe2,0x07] +@ CHECK: vabd.u8 q8, q8, q9 @ encoding: [0x40,0xff,0xe2,0x07] +@ CHECK: vabd.u16 q8, q8, q9 @ encoding: [0x50,0xff,0xe2,0x07] +@ CHECK: vabd.u32 q8, q8, q9 @ encoding: [0x60,0xff,0xe2,0x07] +@ CHECK: vabd.f32 q8, q8, q9 @ encoding: [0x60,0xff,0xe2,0x0d] + + vabdl.s8 q8, d16, d17 -@ CHECK: vabdl.s16 q8, d16, d17 @ encoding: [0xa1,0x07,0xd0,0xef] vabdl.s16 q8, d16, d17 -@ CHECK: vabdl.s32 q8, d16, d17 @ encoding: [0xa1,0x07,0xe0,0xef] vabdl.s32 q8, d16, d17 -@ CHECK: vabdl.u8 q8, d16, d17 @ encoding: [0xa1,0x07,0xc0,0xff] vabdl.u8 q8, d16, d17 -@ CHECK: vabdl.u16 q8, d16, d17 @ encoding: [0xa1,0x07,0xd0,0xff] vabdl.u16 q8, d16, d17 -@ CHECK: vabdl.u32 q8, d16, d17 @ encoding: [0xa1,0x07,0xe0,0xff] vabdl.u32 q8, d16, d17 -@ CHECK: vaba.s8 d16, d18, d17 @ encoding: [0xb1,0x07,0x42,0xef] +@ CHECK: vabdl.s8 q8, d16, d17 @ encoding: [0xc0,0xef,0xa1,0x07] +@ CHECK: vabdl.s16 q8, d16, d17 @ encoding: [0xd0,0xef,0xa1,0x07] +@ CHECK: vabdl.s32 q8, d16, d17 @ encoding: [0xe0,0xef,0xa1,0x07] +@ CHECK: vabdl.u8 q8, d16, d17 @ encoding: [0xc0,0xff,0xa1,0x07] +@ CHECK: vabdl.u16 q8, d16, d17 @ encoding: [0xd0,0xff,0xa1,0x07] +@ CHECK: vabdl.u32 q8, d16, d17 @ encoding: [0xe0,0xff,0xa1,0x07] + + vaba.s8 d16, d18, d17 -@ CHECK: vaba.s16 d16, d18, d17 @ encoding: [0xb1,0x07,0x52,0xef] vaba.s16 d16, d18, d17 -@ CHECK: vaba.s32 d16, d18, d17 @ encoding: [0xb1,0x07,0x62,0xef] vaba.s32 d16, d18, d17 -@ CHECK: vaba.u8 d16, d18, d17 @ encoding: [0xb1,0x07,0x42,0xff] vaba.u8 d16, d18, d17 -@ CHECK: vaba.u16 d16, d18, d17 @ encoding: [0xb1,0x07,0x52,0xff] vaba.u16 d16, d18, d17 -@ CHECK: vaba.u32 d16, d18, d17 @ encoding: [0xb1,0x07,0x62,0xff] vaba.u32 d16, d18, d17 -@ CHECK: vaba.s8 q9, q8, q10 @ encoding: [0xf4,0x27,0x40,0xef] vaba.s8 q9, q8, q10 -@ CHECK: vaba.s16 q9, q8, q10 @ encoding: [0xf4,0x27,0x50,0xef] vaba.s16 q9, q8, q10 -@ CHECK: vaba.s32 q9, q8, q10 @ encoding: [0xf4,0x27,0x60,0xef] vaba.s32 q9, q8, q10 -@ CHECK: vaba.u8 q9, q8, q10 @ encoding: [0xf4,0x27,0x40,0xff] vaba.u8 q9, q8, q10 -@ CHECK: vaba.u16 q9, q8, q10 @ encoding: [0xf4,0x27,0x50,0xff] vaba.u16 q9, q8, q10 -@ CHECK: vaba.u32 q9, q8, q10 @ encoding: [0xf4,0x27,0x60,0xff] vaba.u32 q9, q8, q10 -@ CHECK: vabal.s8 q8, d19, d18 @ encoding: [0xa2,0x05,0xc3,0xef] +@ CHECK: vaba.s8 d16, d18, d17 @ encoding: [0x42,0xef,0xb1,0x07] +@ CHECK: vaba.s16 d16, d18, d17 @ encoding: [0x52,0xef,0xb1,0x07] +@ CHECK: vaba.s32 d16, d18, d17 @ encoding: [0x62,0xef,0xb1,0x07] +@ CHECK: vaba.u8 d16, d18, d17 @ encoding: [0x42,0xff,0xb1,0x07] +@ CHECK: vaba.u16 d16, d18, d17 @ encoding: [0x52,0xff,0xb1,0x07] +@ CHECK: vaba.u32 d16, d18, d17 @ encoding: [0x62,0xff,0xb1,0x07] +@ CHECK: vaba.s8 q9, q8, q10 @ encoding: [0x40,0xef,0xf4,0x27] +@ CHECK: vaba.s16 q9, q8, q10 @ encoding: [0x50,0xef,0xf4,0x27] +@ CHECK: vaba.s32 q9, q8, q10 @ encoding: [0x60,0xef,0xf4,0x27] +@ CHECK: vaba.u8 q9, q8, q10 @ encoding: [0x40,0xff,0xf4,0x27] +@ CHECK: vaba.u16 q9, q8, q10 @ encoding: [0x50,0xff,0xf4,0x27] +@ CHECK: vaba.u32 q9, q8, q10 @ encoding: [0x60,0xff,0xf4,0x27] + + vabal.s8 q8, d19, d18 -@ CHECK: vabal.s16 q8, d19, d18 @ encoding: [0xa2,0x05,0xd3,0xef] vabal.s16 q8, d19, d18 -@ CHECK: vabal.s32 q8, d19, d18 @ encoding: [0xa2,0x05,0xe3,0xef] vabal.s32 q8, d19, d18 -@ CHECK: vabal.u8 q8, d19, d18 @ encoding: [0xa2,0x05,0xc3,0xff] vabal.u8 q8, d19, d18 -@ CHECK: vabal.u16 q8, d19, d18 @ encoding: [0xa2,0x05,0xd3,0xff] vabal.u16 q8, d19, d18 -@ CHECK: vabal.u32 q8, d19, d18 @ encoding: [0xa2,0x05,0xe3,0xff] vabal.u32 q8, d19, d18 +@ CHECK: vabal.s8 q8, d19, d18 @ encoding: [0xc3,0xef,0xa2,0x05] +@ CHECK: vabal.s16 q8, d19, d18 @ encoding: [0xd3,0xef,0xa2,0x05] +@ CHECK: vabal.s32 q8, d19, d18 @ encoding: [0xe3,0xef,0xa2,0x05] +@ CHECK: vabal.u8 q8, d19, d18 @ encoding: [0xc3,0xff,0xa2,0x05] +@ CHECK: vabal.u16 q8, d19, d18 @ encoding: [0xd3,0xff,0xa2,0x05] +@ CHECK: vabal.u32 q8, d19, d18 @ encoding: [0xe3,0xff,0xa2,0x05] + diff --git a/test/MC/ARM/neont2-bitcount-encoding.s b/test/MC/ARM/neont2-bitcount-encoding.s index 4280cbd4a44f..bd525f13e29d 100644 --- a/test/MC/ARM/neont2-bitcount-encoding.s +++ b/test/MC/ARM/neont2-bitcount-encoding.s @@ -1,34 +1,38 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple thumb-unknown-unknown -show-encoding < %s | FileCheck %s -@ XFAIL: * .code 16 -@ CHECK: vcnt.8 d16, d16 @ encoding: [0x20,0x05,0xf0,0xff] vcnt.8 d16, d16 -@ CHECK: vcnt.8 q8, q8 @ encoding: [0x60,0x05,0xf0,0xff] vcnt.8 q8, q8 -@ CHECK: vclz.i8 d16, d16 @ encoding: [0xa0,0x04,0xf0,0xff] + +@ CHECK: vcnt.8 d16, d16 @ encoding: [0xf0,0xff,0x20,0x05] +@ CHECK: vcnt.8 q8, q8 @ encoding: [0xf0,0xff,0x60,0x05] + vclz.i8 d16, d16 -@ CHECK: vclz.i16 d16, d16 @ encoding: [0xa0,0x04,0xf4,0xff] vclz.i16 d16, d16 -@ CHECK: vclz.i32 d16, d16 @ encoding: [0xa0,0x04,0xf8,0xff] vclz.i32 d16, d16 -@ CHECK: vclz.i8 q8, q8 @ encoding: [0xe0,0x04,0xf0,0xff] vclz.i8 q8, q8 -@ CHECK: vclz.i16 q8, q8 @ encoding: [0xe0,0x04,0xf4,0xff] vclz.i16 q8, q8 -@ CHECK: vclz.i32 q8, q8 @ encoding: [0xe0,0x04,0xf8,0xff] vclz.i32 q8, q8 -@ CHECK: vcls.s8 d16, d16 @ encoding: [0x20,0x04,0xf0,0xff] + +@ CHECK: vclz.i8 d16, d16 @ encoding: [0xf0,0xff,0xa0,0x04] +@ CHECK: vclz.i16 d16, d16 @ encoding: [0xf4,0xff,0xa0,0x04] +@ CHECK: vclz.i32 d16, d16 @ encoding: [0xf8,0xff,0xa0,0x04] +@ CHECK: vclz.i8 q8, q8 @ encoding: [0xf0,0xff,0xe0,0x04] +@ CHECK: vclz.i16 q8, q8 @ encoding: [0xf4,0xff,0xe0,0x04] +@ CHECK: vclz.i32 q8, q8 @ encoding: [0xf8,0xff,0xe0,0x04] + vcls.s8 d16, d16 -@ CHECK: vcls.s16 d16, d16 @ encoding: [0x20,0x04,0xf4,0xff] vcls.s16 d16, d16 -@ CHECK: vcls.s32 d16, d16 @ encoding: [0x20,0x04,0xf8,0xff] vcls.s32 d16, d16 -@ CHECK: vcls.s8 q8, q8 @ encoding: [0x60,0x04,0xf0,0xff] vcls.s8 q8, q8 -@ CHECK: vcls.s16 q8, q8 @ encoding: [0x60,0x04,0xf4,0xff] vcls.s16 q8, q8 -@ CHECK: vcls.s32 q8, q8 @ encoding: [0x60,0x04,0xf8,0xff] vcls.s32 q8, q8 +@ CHECK: vcls.s8 d16, d16 @ encoding: [0xf0,0xff,0x20,0x04] +@ CHECK: vcls.s16 d16, d16 @ encoding: [0xf4,0xff,0x20,0x04] +@ CHECK: vcls.s32 d16, d16 @ encoding: [0xf8,0xff,0x20,0x04] +@ CHECK: vcls.s8 q8, q8 @ encoding: [0xf0,0xff,0x60,0x04] +@ CHECK: vcls.s16 q8, q8 @ encoding: [0xf4,0xff,0x60,0x04] +@ CHECK: vcls.s32 q8, q8 @ encoding: [0xf8,0xff,0x60,0x04] + diff --git a/test/MC/ARM/neont2-bitwise-encoding.s b/test/MC/ARM/neont2-bitwise-encoding.s index 3acd7a8c9911..175873b69718 100644 --- a/test/MC/ARM/neont2-bitwise-encoding.s +++ b/test/MC/ARM/neont2-bitwise-encoding.s @@ -1,49 +1,55 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple thumb-unknown-unknown -show-encoding < %s | FileCheck %s -@ XFAIL: * .code 16 -@ CHECK: vand d16, d17, d16 @ encoding: [0xb0,0x01,0x41,0xef] vand d16, d17, d16 -@ CHECK: vand q8, q8, q9 @ encoding: [0xf2,0x01,0x40,0xef] vand q8, q8, q9 -@ CHECK: veor d16, d17, d16 @ encoding: [0xb0,0x01,0x41,0xff] +@ CHECK: vand d16, d17, d16 @ encoding: [0x41,0xef,0xb0,0x01] +@ CHECK: vand q8, q8, q9 @ encoding: [0x40,0xef,0xf2,0x01] + veor d16, d17, d16 -@ CHECK: veor q8, q8, q9 @ encoding: [0xf2,0x01,0x40,0xff] veor q8, q8, q9 -@ CHECK: vorr d16, d17, d16 @ encoding: [0xb0,0x01,0x61,0xef] +@ CHECK: veor d16, d17, d16 @ encoding: [0x41,0xff,0xb0,0x01] +@ CHECK: veor q8, q8, q9 @ encoding: [0x40,0xff,0xf2,0x01] + + vorr d16, d17, d16 -@ CHECK: vorr q8, q8, q9 @ encoding: [0xf2,0x01,0x60,0xef] vorr q8, q8, q9 -@ CHECK: vorr.i32 d16, #0x1000000 @ encoding: [0x11,0x07,0xc0,0xef] - vorr.i32 d16, #0x1000000 -@ CHECK: vorr.i32 q8, #0x1000000 @ encoding: [0x51,0x07,0xc0,0xef] - vorr.i32 q8, #0x1000000 -@ CHECK: vorr.i32 q8, #0x0 @ encoding: [0x50,0x01,0xc0,0xef] - vorr.i32 q8, #0x0 +@ vorr.i32 d16, #0x1000000 +@ vorr.i32 q8, #0x1000000 +@ vorr.i32 q8, #0x0 + +@ CHECK: vorr d16, d17, d16 @ encoding: [0x61,0xef,0xb0,0x01] +@ CHECK: vorr q8, q8, q9 @ encoding: [0x60,0xef,0xf2,0x01] + -@ CHECK: vbic d16, d17, d16 @ encoding: [0xb0,0x01,0x51,0xef] vbic d16, d17, d16 -@ CHECK: vbic q8, q8, q9 @ encoding: [0xf2,0x01,0x50,0xef] vbic q8, q8, q9 -@ CHECK: vbic.i32 d16, #0xFF000000 @ encoding: [0x3f,0x07,0xc7,0xff] - vbic.i32 d16, #0xFF000000 -@ CHECK: vbic.i32 q8, #0xFF000000 @ encoding: [0x7f,0x07,0xc7,0xff] - vbic.i32 q8, #0xFF000000 +@ vbic.i32 d16, #0xFF000000 +@ vbic.i32 q8, #0xFF000000 + +@ CHECK: vbic d16, d17, d16 @ encoding: [0x51,0xef,0xb0,0x01] +@ CHECK: vbic q8, q8, q9 @ encoding: [0x50,0xef,0xf2,0x01] + -@ CHECK: vorn d16, d17, d16 @ encoding: [0xb0,0x01,0x71,0xef] vorn d16, d17, d16 -@ CHECK: vorn q8, q8, q9 @ encoding: [0xf2,0x01,0x70,0xef] vorn q8, q8, q9 -@ CHECK: vmvn d16, d16 @ encoding: [0xa0,0x05,0xf0,0xff] +@ CHECK: vorn d16, d17, d16 @ encoding: [0x71,0xef,0xb0,0x01] +@ CHECK: vorn q8, q8, q9 @ encoding: [0x70,0xef,0xf2,0x01] + + vmvn d16, d16 -@ CHECK: vmvn q8, q8 @ encoding: [0xe0,0x05,0xf0,0xff] vmvn q8, q8 -@ CHECK: vbsl d18, d17, d16 @ encoding: [0xb0,0x21,0x51,0xff] +@ CHECK: vmvn d16, d16 @ encoding: [0xf0,0xff,0xa0,0x05] +@ CHECK: vmvn q8, q8 @ encoding: [0xf0,0xff,0xe0,0x05] + + vbsl d18, d17, d16 -@ CHECK: vbsl q8, q10, q9 @ encoding: [0xf2,0x01,0x54,0xff] vbsl q8, q10, q9 + +@ CHECK: vbsl d18, d17, d16 @ encoding: [0x51,0xff,0xb0,0x21] +@ CHECK: vbsl q8, q10, q9 @ encoding: [0x54,0xff,0xf2,0x01] diff --git a/test/MC/ARM/neont2-dup-encoding.s b/test/MC/ARM/neont2-dup-encoding.s index da6e78f56012..bf25d70b5cf4 100644 --- a/test/MC/ARM/neont2-dup-encoding.s +++ b/test/MC/ARM/neont2-dup-encoding.s @@ -1,29 +1,43 @@ -@ RUN: llvm-mc -mcpu=cortex-a8 -triple thumb-unknown-unknown -show-encoding < %s | FileCheck %s -@ XFAIL: * +@RUN: llvm-mc -triple thumbv7-unknown-unknown -show-encoding < %s | FileCheck %s .code 16 -@ CHECK: vdup.8 d16, r0 @ encoding: [0x90,0x0b,0xc0,0xee] - vdup.8 d16, r0 -@ CHECK: vdup.16 d16, r0 @ encoding: [0xb0,0x0b,0x80,0xee] - vdup.16 d16, r0 -@ CHECK: vdup.32 d16, r0 @ encoding: [0x90,0x0b,0x80,0xee] - vdup.32 d16, r0 -@ CHECK: vdup.8 q8, r0 @ encoding: [0x90,0x0b,0xe0,0xee] - vdup.8 q8, r0 -@ CHECK: vdup.16 q8, r0 @ encoding: [0xb0,0x0b,0xa0,0xee] - vdup.16 q8, r0 -@ CHECK: vdup.32 q8, r0 @ encoding: [0x90,0x0b,0xa0,0xee] - vdup.32 q8, r0 -@ CHECK: vdup.8 d16, d16[1] @ encoding: [0x20,0x0c,0xf3,0xff] - vdup.8 d16, d16[1] -@ CHECK: vdup.16 d16, d16[1] @ encoding: [0x20,0x0c,0xf6,0xff] - vdup.16 d16, d16[1] -@ CHECK: vdup.32 d16, d16[1] @ encoding: [0x20,0x0c,0xfc,0xff] - vdup.32 d16, d16[1] -@ CHECK: vdup.8 q8, d16[1] @ encoding: [0x60,0x0c,0xf3,0xff] - vdup.8 q8, d16[1] -@ CHECK: vdup.16 q8, d16[1] @ encoding: [0x60,0x0c,0xf6,0xff] - vdup.16 q8, d16[1] -@ CHECK: vdup.32 q8, d16[1] @ encoding: [0x60,0x0c,0xfc,0xff] - vdup.32 q8, d16[1] + vdup.8 d16, r1 + vdup.16 d15, r2 + vdup.32 d14, r3 + vdup.8 q9, r4 + vdup.16 q8, r5 + vdup.32 q7, r6 + +@ CHECK: vdup.8 d16, r1 @ encoding: [0xc0,0xee,0x90,0x1b] +@ CHECK: vdup.16 d15, r2 @ encoding: [0x8f,0xee,0x30,0x2b] +@ CHECK: vdup.32 d14, r3 @ encoding: [0x8e,0xee,0x10,0x3b] +@ CHECK: vdup.8 q9, r4 @ encoding: [0xe2,0xee,0x90,0x4b] +@ CHECK: vdup.16 q8, r5 @ encoding: [0xa0,0xee,0xb0,0x5b] +@ CHECK: vdup.32 q7, r6 @ encoding: [0xae,0xee,0x10,0x6b] + + vdup.8 d16, d11[0] + vdup.16 d17, d12[0] + vdup.32 d18, d13[0] + vdup.8 q3, d10[0] + vdup.16 q9, d9[0] + vdup.32 q8, d8[0] + vdup.8 d16, d11[1] + vdup.16 d17, d12[1] + vdup.32 d18, d13[1] + vdup.8 q3, d10[1] + vdup.16 q9, d9[1] + vdup.32 q8, d8[1] + +@ CHECK: vdup.8 d16, d11[0] @ encoding: [0xf1,0xff,0x0b,0x0c] +@ CHECK: vdup.16 d17, d12[0] @ encoding: [0xf2,0xff,0x0c,0x1c] +@ CHECK: vdup.32 d18, d13[0] @ encoding: [0xf4,0xff,0x0d,0x2c] +@ CHECK: vdup.8 q3, d10[0] @ encoding: [0xb1,0xff,0x4a,0x6c] +@ CHECK: vdup.16 q9, d9[0] @ encoding: [0xf2,0xff,0x49,0x2c] +@ CHECK: vdup.32 q8, d8[0] @ encoding: [0xf4,0xff,0x48,0x0c] +@ CHECK: vdup.8 d16, d11[1] @ encoding: [0xf3,0xff,0x0b,0x0c] +@ CHECK: vdup.16 d17, d12[1] @ encoding: [0xf6,0xff,0x0c,0x1c] +@ CHECK: vdup.32 d18, d13[1] @ encoding: [0xfc,0xff,0x0d,0x2c] +@ CHECK: vdup.8 q3, d10[1] @ encoding: [0xb3,0xff,0x4a,0x6c] +@ CHECK: vdup.16 q9, d9[1] @ encoding: [0xf6,0xff,0x49,0x2c] +@ CHECK: vdup.32 q8, d8[1] @ encoding: [0xfc,0xff,0x48,0x0c] diff --git a/test/MC/ARM/neont2-mul-accum-encoding.s b/test/MC/ARM/neont2-mul-accum-encoding.s index e21c67d2e8d6..be4bf79bca58 100644 --- a/test/MC/ARM/neont2-mul-accum-encoding.s +++ b/test/MC/ARM/neont2-mul-accum-encoding.s @@ -1,69 +1,84 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple thumb-unknown-unknown -show-encoding < %s | FileCheck %s -@ XFAIL: * .code 16 -@ CHECK: vmla.i8 d16, d18, d17 @ encoding: [0xa1,0x09,0x42,0xef] vmla.i8 d16, d18, d17 -@ CHECK: vmla.i16 d16, d18, d17 @ encoding: [0xa1,0x09,0x52,0xef] vmla.i16 d16, d18, d17 -@ CHECK: vmla.i16 d16, d18, d17 @ encoding: [0xa1,0x09,0x52,0xef] vmla.i32 d16, d18, d17 -@ CHECK: vmla.f32 d16, d18, d17 @ encoding: [0xb1,0x0d,0x42,0xef] vmla.f32 d16, d18, d17 -@ CHECK: vmla.i8 q9, q8, q10 @ encoding: [0xe4,0x29,0x40,0xef] vmla.i8 q9, q8, q10 -@ CHECK: vmla.i16 q9, q8, q10 @ encoding: [0xe4,0x29,0x50,0xef] vmla.i16 q9, q8, q10 -@ CHECK: vmla.i32 q9, q8, q10 @ encoding: [0xe4,0x29,0x60,0xef] vmla.i32 q9, q8, q10 -@ CHECK: vmla.f32 q9, q8, q10 @ encoding: [0xf4,0x2d,0x40,0xef] vmla.f32 q9, q8, q10 -@ CHECK: vmlal.s8 q8, d19, d18 @ encoding: [0xa2,0x08,0xc3,0xef] + +@ CHECK: vmla.i8 d16, d18, d17 @ encoding: [0x42,0xef,0xa1,0x09] +@ CHECK: vmla.i16 d16, d18, d17 @ encoding: [0x52,0xef,0xa1,0x09] +@ CHECK: vmla.i32 d16, d18, d17 @ encoding: [0x62,0xef,0xa1,0x09] +@ CHECK: vmla.f32 d16, d18, d17 @ encoding: [0x42,0xef,0xb1,0x0d] +@ CHECK: vmla.i8 q9, q8, q10 @ encoding: [0x40,0xef,0xe4,0x29] +@ CHECK: vmla.i16 q9, q8, q10 @ encoding: [0x50,0xef,0xe4,0x29] +@ CHECK: vmla.i32 q9, q8, q10 @ encoding: [0x60,0xef,0xe4,0x29] +@ CHECK: vmla.f32 q9, q8, q10 @ encoding: [0x40,0xef,0xf4,0x2d] + + vmlal.s8 q8, d19, d18 -@ CHECK: vmlal.s16 q8, d19, d18 @ encoding: [0xa2,0x08,0xd3,0xef] vmlal.s16 q8, d19, d18 -@ CHECK: vmlal.s32 q8, d19, d18 @ encoding: [0xa2,0x08,0xe3,0xef] vmlal.s32 q8, d19, d18 -@ CHECK: vmlal.u8 q8, d19, d18 @ encoding: [0xa2,0x08,0xc3,0xff] vmlal.u8 q8, d19, d18 -@ CHECK: vmlal.u16 q8, d19, d18 @ encoding: [0xa2,0x08,0xd3,0xff] vmlal.u16 q8, d19, d18 -@ CHECK: vmlal.u32 q8, d19, d18 @ encoding: [0xa2,0x08,0xe3,0xff] vmlal.u32 q8, d19, d18 -@ CHECK: vqdmlal.s16 q8, d19, d18 @ encoding: [0xa2,0x09,0xd3,0xef] + +@ CHECK: vmlal.s8 q8, d19, d18 @ encoding: [0xc3,0xef,0xa2,0x08] +@ CHECK: vmlal.s16 q8, d19, d18 @ encoding: [0xd3,0xef,0xa2,0x08] +@ CHECK: vmlal.s32 q8, d19, d18 @ encoding: [0xe3,0xef,0xa2,0x08] +@ CHECK: vmlal.u8 q8, d19, d18 @ encoding: [0xc3,0xff,0xa2,0x08] +@ CHECK: vmlal.u16 q8, d19, d18 @ encoding: [0xd3,0xff,0xa2,0x08] +@ CHECK: vmlal.u32 q8, d19, d18 @ encoding: [0xe3,0xff,0xa2,0x08] + + vqdmlal.s16 q8, d19, d18 -@ CHECK: vqdmlal.s32 q8, d19, d18 @ encoding: [0xa2,0x09,0xe3,0xef] vqdmlal.s32 q8, d19, d18 -@ CHECK: vmls.i8 d16, d18, d17 @ encoding: [0xa1,0x09,0x42,0xff] + +@ CHECK: vqdmlal.s16 q8, d19, d18 @ encoding: [0xd3,0xef,0xa2,0x09] +@ CHECK: vqdmlal.s32 q8, d19, d18 @ encoding: [0xe3,0xef,0xa2,0x09] + + vmls.i8 d16, d18, d17 -@ CHECK: vmls.i16 d16, d18, d17 @ encoding: [0xa1,0x09,0x52,0xff] vmls.i16 d16, d18, d17 -@ CHECK: vmls.i32 d16, d18, d17 @ encoding: [0xa1,0x09,0x62,0xff] vmls.i32 d16, d18, d17 -@ CHECK: vmls.f32 d16, d18, d17 @ encoding: [0xb1,0x0d,0x62,0xef] vmls.f32 d16, d18, d17 -@ CHECK: vmls.i8 q9, q8, q10 @ encoding: [0xe4,0x29,0x40,0xff] vmls.i8 q9, q8, q10 -@ CHECK: vmls.i16 q9, q8, q10 @ encoding: [0xe4,0x29,0x50,0xff] vmls.i16 q9, q8, q10 -@ CHECK: vmls.i32 q9, q8, q10 @ encoding: [0xe4,0x29,0x60,0xff] vmls.i32 q9, q8, q10 -@ CHECK: vmls.f32 q9, q8, q10 @ encoding: [0xf4,0x2d,0x60,0xef] vmls.f32 q9, q8, q10 -@ CHECK: vmlsl.s8 q8, d19, d18 @ encoding: [0xa2,0x0a,0xc3,0xef] + +@ CHECK: vmls.i8 d16, d18, d17 @ encoding: [0x42,0xff,0xa1,0x09] +@ CHECK: vmls.i16 d16, d18, d17 @ encoding: [0x52,0xff,0xa1,0x09] +@ CHECK: vmls.i32 d16, d18, d17 @ encoding: [0x62,0xff,0xa1,0x09] +@ CHECK: vmls.f32 d16, d18, d17 @ encoding: [0x62,0xef,0xb1,0x0d] +@ CHECK: vmls.i8 q9, q8, q10 @ encoding: [0x40,0xff,0xe4,0x29] +@ CHECK: vmls.i16 q9, q8, q10 @ encoding: [0x50,0xff,0xe4,0x29] +@ CHECK: vmls.i32 q9, q8, q10 @ encoding: [0x60,0xff,0xe4,0x29] +@ CHECK: vmls.f32 q9, q8, q10 @ encoding: [0x60,0xef,0xf4,0x2d] + + vmlsl.s8 q8, d19, d18 -@ CHECK: vmlsl.s16 q8, d19, d18 @ encoding: [0xa2,0x0a,0xd3,0xef] vmlsl.s16 q8, d19, d18 -@ CHECK: vmlsl.s32 q8, d19, d18 @ encoding: [0xa2,0x0a,0xe3,0xef] vmlsl.s32 q8, d19, d18 -@ CHECK: vmlsl.u8 q8, d19, d18 @ encoding: [0xa2,0x0a,0xc3,0xff] vmlsl.u8 q8, d19, d18 -@ CHECK: vmlsl.u16 q8, d19, d18 @ encoding: [0xa2,0x0a,0xd3,0xff] vmlsl.u16 q8, d19, d18 -@ CHECK: vmlsl.u32 q8, d19, d18 @ encoding: [0xa2,0x0a,0xe3,0xff] vmlsl.u32 q8, d19, d18 -@ CHECK: vqdmlsl.s16 q8, d19, d18 @ encoding: [0xa2,0x0b,0xd3,0xef] + +@ CHECK: vmlsl.s8 q8, d19, d18 @ encoding: [0xc3,0xef,0xa2,0x0a] +@ CHECK: vmlsl.s16 q8, d19, d18 @ encoding: [0xd3,0xef,0xa2,0x0a] +@ CHECK: vmlsl.s32 q8, d19, d18 @ encoding: [0xe3,0xef,0xa2,0x0a] +@ CHECK: vmlsl.u8 q8, d19, d18 @ encoding: [0xc3,0xff,0xa2,0x0a] +@ CHECK: vmlsl.u16 q8, d19, d18 @ encoding: [0xd3,0xff,0xa2,0x0a] +@ CHECK: vmlsl.u32 q8, d19, d18 @ encoding: [0xe3,0xff,0xa2,0x0a] + + vqdmlsl.s16 q8, d19, d18 -@ CHECK: vqdmlsl.s32 q8, d19, d18 @ encoding: [0xa2,0x0b,0xe3,0xef] vqdmlsl.s32 q8, d19, d18 + +@ CHECK: vqdmlsl.s16 q8, d19, d18 @ encoding: [0xd3,0xef,0xa2,0x0b] +@ CHECK: vqdmlsl.s32 q8, d19, d18 @ encoding: [0xe3,0xef,0xa2,0x0b] diff --git a/test/MC/ARM/neont2-pairwise-encoding.s b/test/MC/ARM/neont2-pairwise-encoding.s index ef9092214cf2..29aac36392e8 100644 --- a/test/MC/ARM/neont2-pairwise-encoding.s +++ b/test/MC/ARM/neont2-pairwise-encoding.s @@ -1,89 +1,100 @@ @ RUN: llvm-mc -mcpu=cortex-a8 -triple thumb-unknown-unknown -show-encoding < %s | FileCheck %s -@ XFAIL: * .code 16 + vpadd.i8 d1, d5, d11 + vpadd.i16 d13, d2, d12 + vpadd.i32 d14, d1, d13 + vpadd.f32 d19, d16, d14 -@ CHECK: vpadd.i8 d16, d17, d16 @ encoding: [0xb0,0x0b,0x41,0xef] - vpadd.i8 d16, d17, d16 -@ CHECK: vpadd.i16 d16, d17, d16 @ encoding: [0xb0,0x0b,0x51,0xef] - vpadd.i16 d16, d17, d16 -@ CHECK: vpadd.i32 d16, d17, d16 @ encoding: [0xb0,0x0b,0x61,0xef] - vpadd.i32 d16, d17, d16 -@ CHECK: vpadd.f32 d16, d16, d17 @ encoding: [0xa1,0x0d,0x40,0xff] - vpadd.f32 d16, d16, d17 -@ CHECK: vpaddl.s8 d16, d16 @ encoding: [0x20,0x02,0xf0,0xff] - vpaddl.s8 d16, d16 -@ CHECK: vpaddl.s16 d16, d16 @ encoding: [0x20,0x02,0xf4,0xff] - vpaddl.s16 d16, d16 -@ CHECK: vpaddl.s32 d16, d16 @ encoding: [0x20,0x02,0xf8,0xff] - vpaddl.s32 d16, d16 -@ CHECK: vpaddl.u8 d16, d16 @ encoding: [0xa0,0x02,0xf0,0xff] - vpaddl.u8 d16, d16 -@ CHECK: vpaddl.u16 d16, d16 @ encoding: [0xa0,0x02,0xf4,0xff] - vpaddl.u16 d16, d16 -@ CHECK: vpaddl.u32 d16, d16 @ encoding: [0xa0,0x02,0xf8,0xff] - vpaddl.u32 d16, d16 -@ CHECK: vpaddl.s8 q8, q8 @ encoding: [0x60,0x02,0xf0,0xff] - vpaddl.s8 q8, q8 -@ CHECK: vpaddl.s16 q8, q8 @ encoding: [0x60,0x02,0xf4,0xff] - vpaddl.s16 q8, q8 -@ CHECK: vpaddl.s32 q8, q8 @ encoding: [0x60,0x02,0xf8,0xff] - vpaddl.s32 q8, q8 -@ CHECK: vpaddl.u8 q8, q8 @ encoding: [0xe0,0x02,0xf0,0xff] - vpaddl.u8 q8, q8 -@ CHECK: vpaddl.u16 q8, q8 @ encoding: [0xe0,0x02,0xf4,0xff] - vpaddl.u16 q8, q8 -@ CHECK: vpaddl.u32 q8, q8 @ encoding: [0xe0,0x02,0xf8,0xff] - vpaddl.u32 q8, q8 -@ CHECK: vpadal.s8 d16, d17 @ encoding: [0x21,0x06,0xf0,0xff] - vpadal.s8 d16, d17 -@ CHECK: vpadal.s16 d16, d17 @ encoding: [0x21,0x06,0xf4,0xff] - vpadal.s16 d16, d17 -@ CHECK: vpadal.s32 d16, d17 @ encoding: [0x21,0x06,0xf8,0xff] - vpadal.s32 d16, d17 -@ CHECK: vpadal.u8 d16, d17 @ encoding: [0xa1,0x06,0xf0,0xff] - vpadal.u8 d16, d17 -@ CHECK: vpadal.u16 d16, d17 @ encoding: [0xa1,0x06,0xf4,0xff] - vpadal.u16 d16, d17 -@ CHECK: vpadal.u32 d16, d17 @ encoding: [0xa1,0x06,0xf8,0xff] - vpadal.u32 d16, d17 -@ CHECK: vpadal.s8 q9, q8 @ encoding: [0x60,0x26,0xf0,0xff] - vpadal.s8 q9, q8 -@ CHECK: vpadal.s16 q9, q8 @ encoding: [0x60,0x26,0xf4,0xff] - vpadal.s16 q9, q8 -@ CHECK: vpadal.s32 q9, q8 @ encoding: [0x60,0x26,0xf8,0xff] - vpadal.s32 q9, q8 -@ CHECK: vpadal.u8 q9, q8 @ encoding: [0xe0,0x26,0xf0,0xff] - vpadal.u8 q9, q8 -@ CHECK: vpadal.u16 q9, q8 @ encoding: [0xe0,0x26,0xf4,0xff] - vpadal.u16 q9, q8 -@ CHECK: vpadal.u32 q9, q8 @ encoding: [0xe0,0x26,0xf8,0xff] - vpadal.u32 q9, q8 -@ CHECK: vpmin.s8 d16, d16, d17 @ encoding: [0xb1,0x0a,0x40,0xef] - vpmin.s8 d16, d16, d17 -@ CHECK: vpmin.s16 d16, d16, d17 @ encoding: [0xb1,0x0a,0x50,0xef] - vpmin.s16 d16, d16, d17 -@ CHECK: vpmin.s32 d16, d16, d17 @ encoding: [0xb1,0x0a,0x60,0xef] - vpmin.s32 d16, d16, d17 -@ CHECK: vpmin.u8 d16, d16, d17 @ encoding: [0xb1,0x0a,0x40,0xff] - vpmin.u8 d16, d16, d17 -@ CHECK: vpmin.u16 d16, d16, d17 @ encoding: [0xb1,0x0a,0x50,0xff] - vpmin.u16 d16, d16, d17 -@ CHECK: vpmin.u32 d16, d16, d17 @ encoding: [0xb1,0x0a,0x60,0xff] - vpmin.u32 d16, d16, d17 -@ CHECK: vpmin.f32 d16, d16, d17 @ encoding: [0xa1,0x0f,0x60,0xff] - vpmin.f32 d16, d16, d17 -@ CHECK: vpmax.s8 d16, d16, d17 @ encoding: [0xa1,0x0a,0x40,0xef] - vpmax.s8 d16, d16, d17 -@ CHECK: vpmax.s16 d16, d16, d17 @ encoding: [0xa1,0x0a,0x50,0xef] - vpmax.s16 d16, d16, d17 -@ CHECK: vpmax.s32 d16, d16, d17 @ encoding: [0xa1,0x0a,0x60,0xef] - vpmax.s32 d16, d16, d17 -@ CHECK: vpmax.u8 d16, d16, d17 @ encoding: [0xa1,0x0a,0x40,0xff] - vpmax.u8 d16, d16, d17 -@ CHECK: vpmax.u16 d16, d16, d17 @ encoding: [0xa1,0x0a,0x50,0xff] - vpmax.u16 d16, d16, d17 -@ CHECK: vpmax.u32 d16, d16, d17 @ encoding: [0xa1,0x0a,0x60,0xff] - vpmax.u32 d16, d16, d17 -@ CHECK: vpmax.f32 d16, d16, d17 @ encoding: [0xa1,0x0f,0x40,0xff] - vpmax.f32 d16, d16, d17 +@ CHECK: vpadd.i8 d1, d5, d11 @ encoding: [0x05,0xef,0x1b,0x1b] +@ CHECK: vpadd.i16 d13, d2, d12 @ encoding: [0x12,0xef,0x1c,0xdb] +@ CHECK: vpadd.i32 d14, d1, d13 @ encoding: [0x21,0xef,0x1d,0xeb] +@ CHECK: vpadd.f32 d19, d16, d14 @ encoding: [0x40,0xff,0x8e,0x3d] + + + vpaddl.s8 d7, d10 + vpaddl.s16 d8, d11 + vpaddl.s32 d9, d12 + vpaddl.u8 d0, d13 + vpaddl.u16 d5, d14 + vpaddl.u32 d6, d15 + vpaddl.s8 q4, q7 + vpaddl.s16 q5, q6 + vpaddl.s32 q6, q5 + vpaddl.u8 q7, q4 + vpaddl.u16 q8, q3 + vpaddl.u32 q9, q2 + +@ CHECK: vpaddl.s8 d7, d10 @ encoding: [0xb0,0xff,0x0a,0x72] +@ CHECK: vpaddl.s16 d8, d11 @ encoding: [0xb4,0xff,0x0b,0x82] +@ CHECK: vpaddl.s32 d9, d12 @ encoding: [0xb8,0xff,0x0c,0x92] +@ CHECK: vpaddl.u8 d0, d13 @ encoding: [0xb0,0xff,0x8d,0x02] +@ CHECK: vpaddl.u16 d5, d14 @ encoding: [0xb4,0xff,0x8e,0x52] +@ CHECK: vpaddl.u32 d6, d15 @ encoding: [0xb8,0xff,0x8f,0x62] +@ CHECK: vpaddl.s8 q4, q7 @ encoding: [0xb0,0xff,0x4e,0x82] +@ CHECK: vpaddl.s16 q5, q6 @ encoding: [0xb4,0xff,0x4c,0xa2] +@ CHECK: vpaddl.s32 q6, q5 @ encoding: [0xb8,0xff,0x4a,0xc2] +@ CHECK: vpaddl.u8 q7, q4 @ encoding: [0xb0,0xff,0xc8,0xe2] +@ CHECK: vpaddl.u16 q8, q3 @ encoding: [0xf4,0xff,0xc6,0x02] +@ CHECK: vpaddl.u32 q9, q2 @ encoding: [0xf8,0xff,0xc4,0x22] + + + vpadal.s8 d16, d4 + vpadal.s16 d20, d9 + vpadal.s32 d18, d1 + vpadal.u8 d14, d25 + vpadal.u16 d12, d6 + vpadal.u32 d11, d7 + vpadal.s8 q4, q10 + vpadal.s16 q5, q11 + vpadal.s32 q6, q12 + vpadal.u8 q7, q13 + vpadal.u16 q8, q14 + vpadal.u32 q9, q15 + +@ CHECK: vpadal.s8 d16, d4 @ encoding: [0xf0,0xff,0x04,0x06] +@ CHECK: vpadal.s16 d20, d9 @ encoding: [0xf4,0xff,0x09,0x46] +@ CHECK: vpadal.s32 d18, d1 @ encoding: [0xf8,0xff,0x01,0x26] +@ CHECK: vpadal.u8 d14, d25 @ encoding: [0xb0,0xff,0xa9,0xe6] +@ CHECK: vpadal.u16 d12, d6 @ encoding: [0xb4,0xff,0x86,0xc6] +@ CHECK: vpadal.u32 d11, d7 @ encoding: [0xb8,0xff,0x87,0xb6] +@ CHECK: vpadal.s8 q4, q10 @ encoding: [0xb0,0xff,0x64,0x86] +@ CHECK: vpadal.s16 q5, q11 @ encoding: [0xb4,0xff,0x66,0xa6] +@ CHECK: vpadal.s32 q6, q12 @ encoding: [0xb8,0xff,0x68,0xc6] +@ CHECK: vpadal.u8 q7, q13 @ encoding: [0xb0,0xff,0xea,0xe6] +@ CHECK: vpadal.u16 q8, q14 @ encoding: [0xf4,0xff,0xec,0x06] +@ CHECK: vpadal.u32 q9, q15 @ encoding: [0xf8,0xff,0xee,0x26] + + + vpmin.s8 d16, d29, d10 + vpmin.s16 d17, d28, d11 + vpmin.s32 d18, d27, d12 + vpmin.u8 d19, d26, d13 + vpmin.u16 d20, d25, d14 + vpmin.u32 d21, d24, d15 + vpmin.f32 d22, d23, d16 + +@ CHECK: vpmin.s8 d16, d29, d10 @ encoding: [0x4d,0xef,0x9a,0x0a] +@ CHECK: vpmin.s16 d17, d28, d11 @ encoding: [0x5c,0xef,0x9b,0x1a] +@ CHECK: vpmin.s32 d18, d27, d12 @ encoding: [0x6b,0xef,0x9c,0x2a] +@ CHECK: vpmin.u8 d19, d26, d13 @ encoding: [0x4a,0xff,0x9d,0x3a] +@ CHECK: vpmin.u16 d20, d25, d14 @ encoding: [0x59,0xff,0x9e,0x4a] +@ CHECK: vpmin.u32 d21, d24, d15 @ encoding: [0x68,0xff,0x9f,0x5a] +@ CHECK: vpmin.f32 d22, d23, d16 @ encoding: [0x67,0xff,0xa0,0x6f] + + + vpmax.s8 d3, d20, d17 + vpmax.s16 d4, d21, d16 + vpmax.s32 d5, d22, d15 + vpmax.u8 d6, d23, d14 + vpmax.u16 d7, d24, d13 + vpmax.u32 d8, d25, d12 + vpmax.f32 d9, d26, d11 + +@ CHECK: vpmax.s8 d3, d20, d17 @ encoding: [0x04,0xef,0xa1,0x3a] +@ CHECK: vpmax.s16 d4, d21, d16 @ encoding: [0x15,0xef,0xa0,0x4a] +@ CHECK: vpmax.s32 d5, d22, d15 @ encoding: [0x26,0xef,0x8f,0x5a] +@ CHECK: vpmax.u8 d6, d23, d14 @ encoding: [0x07,0xff,0x8e,0x6a] +@ CHECK: vpmax.u16 d7, d24, d13 @ encoding: [0x18,0xff,0x8d,0x7a] +@ CHECK: vpmax.u32 d8, d25, d12 @ encoding: [0x29,0xff,0x8c,0x8a] +@ CHECK: vpmax.f32 d9, d26, d11 @ encoding: [0x0a,0xff,0x8b,0x9f] diff --git a/test/MC/ARM/nop-armv4-padding.s b/test/MC/ARM/nop-armv4-padding.s new file mode 100644 index 000000000000..8f646dbb396a --- /dev/null +++ b/test/MC/ARM/nop-armv4-padding.s @@ -0,0 +1,10 @@ +@ RUN: llvm-mc -triple armv4-apple-darwin %s -filetype=obj -o %t.obj +@ RUN: macho-dump --dump-section-data < %t.obj > %t.dump +@ RUN: FileCheck %s < %t.dump + +x: + add r0, r1, r2 + .align 4 + add r0, r1, r2 + +@ CHECK: ('_section_data', '020081e0 00001a0e 00001a0e 00001a0e 020081e0') diff --git a/test/MC/ARM/nop-armv6t2-padding.s b/test/MC/ARM/nop-armv6t2-padding.s new file mode 100644 index 000000000000..0e257186caa3 --- /dev/null +++ b/test/MC/ARM/nop-armv6t2-padding.s @@ -0,0 +1,10 @@ +@ RUN: llvm-mc -triple armv6t2-apple-darwin %s -filetype=obj -o %t.obj +@ RUN: macho-dump --dump-section-data < %t.obj > %t.dump +@ RUN: FileCheck %s < %t.dump + +x: + add r0, r1, r2 + .align 4 + add r0, r1, r2 + +@ CHECK: ('_section_data', '020081e0 007820e3 007820e3 007820e3 020081e0') diff --git a/test/MC/ARM/nop-thumb-padding.s b/test/MC/ARM/nop-thumb-padding.s new file mode 100644 index 000000000000..1e173f1a42d9 --- /dev/null +++ b/test/MC/ARM/nop-thumb-padding.s @@ -0,0 +1,12 @@ +@ RUN: llvm-mc -triple armv6-apple-darwin %s -filetype=obj -o %t.obj +@ RUN: macho-dump --dump-section-data < %t.obj > %t.dump +@ RUN: FileCheck %s < %t.dump + +.thumb_func x +.code 16 +x: + adds r0, r1, r2 + .align 4 + adds r0, r1, r2 + +@ CHECK: ('_section_data', '8818c046 c046c046 c046c046 c046c046 8818') diff --git a/test/MC/ARM/nop-thumb2-padding.s b/test/MC/ARM/nop-thumb2-padding.s new file mode 100644 index 000000000000..a8aa3a1168ef --- /dev/null +++ b/test/MC/ARM/nop-thumb2-padding.s @@ -0,0 +1,12 @@ +@ RUN: llvm-mc -triple armv7-apple-darwin %s -filetype=obj -o %t.obj +@ RUN: macho-dump --dump-section-data < %t.obj > %t.dump +@ RUN: FileCheck %s < %t.dump + +.thumb_func x +.code 16 +x: + adds r0, r1, r2 + .align 4 + adds r0, r1, r2 + +@ CHECK: ('_section_data', '881800bf 00bf00bf 00bf00bf 00bf00bf 8818') diff --git a/test/MC/ARM/reg-list.s b/test/MC/ARM/reg-list.s deleted file mode 100644 index 4dd392e83791..000000000000 --- a/test/MC/ARM/reg-list.s +++ /dev/null @@ -1,8 +0,0 @@ -@ RUN: llvm-mc -triple thumb-apple-darwin10 -show-encoding < %s 2> %t | FileCheck %s -@ RUN: FileCheck --check-prefix=CHECK-WARNINGS < %t %s - - push {r7, lr} -@ CHECK-WARNINGS: register not in ascending order in register list - - push {lr, r7} -@ CHECK: push {lr, r7} diff --git a/test/MC/ARM/simple-encoding.ll b/test/MC/ARM/simple-encoding.ll deleted file mode 100644 index 14ed945fa2db..000000000000 --- a/test/MC/ARM/simple-encoding.ll +++ /dev/null @@ -1,236 +0,0 @@ -;RUN: llc -mtriple=armv7-apple-darwin -show-mc-encoding -disable-cgp-branch-opts -join-physregs < %s | FileCheck %s - - -;FIXME: Once the ARM integrated assembler is up and going, these sorts of tests -; should run on .s source files rather than using llc to generate the -; assembly. There's also a large number of instruction encodings the -; compiler never generates, so we need the integrated assembler to be -; able to test those at all. - -declare void @llvm.trap() nounwind -declare i32 @llvm.ctlz.i32(i32) - -define i32 @foo(i32 %a, i32 %b) { -; CHECK: foo -; CHECK: trap @ encoding: [0xfe,0xde,0xff,0xe7] -; CHECK: bx lr @ encoding: [0x1e,0xff,0x2f,0xe1] - - tail call void @llvm.trap() - ret i32 undef -} - -define i32 @f2(i32 %a, i32 %b) { -; CHECK: f2 -; CHECK: add r0, r1, r0 @ encoding: [0x00,0x00,0x81,0xe0] -; CHECK: bx lr @ encoding: [0x1e,0xff,0x2f,0xe1] - %add = add nsw i32 %b, %a - ret i32 %add -} - - -define i32 @f3(i32 %a, i32 %b) { -; CHECK: f3 -; CHECK: add r0, r0, r1, lsl #3 @ encoding: [0x81,0x01,0x80,0xe0] -; CHECK: bx lr @ encoding: [0x1e,0xff,0x2f,0xe1] - %mul = shl i32 %b, 3 - %add = add nsw i32 %mul, %a - ret i32 %add -} - -define i32 @f4(i32 %a, i32 %b) { -; CHECK: f4 -; CHECK: add r0, r0, #4064 @ encoding: [0xfe,0x0e,0x80,0xe2] -; CHECK: bx lr @ encoding: [0x1e,0xff,0x2f,0xe1] - %add = add nsw i32 %a, 4064 - ret i32 %add -} - -define i32 @f5(i32 %a, i32 %b, i32 %c) { -; CHECK: f5 -; CHECK: cmp r0, r1 @ encoding: [0x01,0x00,0x50,0xe1] -; CHECK: mov r0, r2 @ encoding: [0x02,0x00,0xa0,0xe1] -; CHECK: movgt r0, r1 @ encoding: [0x01,0x00,0xa0,0xc1] - %cmp = icmp sgt i32 %a, %b - %retval.0 = select i1 %cmp, i32 %b, i32 %c - ret i32 %retval.0 -} - -define i64 @f6(i64 %a, i64 %b, i64 %c) { -; CHECK: f6 -; CHECK: adds r0, r2, r0 @ encoding: [0x00,0x00,0x92,0xe0] -; CHECK: adc r1, r3, r1 @ encoding: [0x01,0x10,0xa3,0xe0] - %add = add nsw i64 %b, %a - ret i64 %add -} - -define i32 @f7(i32 %a, i32 %b) { -; CHECK: f7 -; CHECK: uxtab r0, r0, r1 @ encoding: [0x71,0x00,0xe0,0xe6] - %and = and i32 %b, 255 - %add = add i32 %and, %a - ret i32 %add -} - -define i32 @f8(i32 %a) { -; CHECK: f8 -; CHECK: movt r0, #42405 @ encoding: [0xa5,0x05,0x4a,0xe3] - %and = and i32 %a, 65535 - %or = or i32 %and, -1515913216 - ret i32 %or -} - -define i32 @f9() { -; CHECK: f9 -; CHECK: movw r0, #42405 @ encoding: [0xa5,0x05,0x0a,0xe3] - ret i32 42405 -} - -define i64 @f10(i64 %a) { -; CHECK: f10 -; CHECK: asrs r1, r1, #1 @ encoding: [0xc1,0x10,0xb0,0xe1] -; CHECK: rrx r0, r0 @ encoding: [0x60,0x00,0xa0,0xe1] - %shr = ashr i64 %a, 1 - ret i64 %shr -} - -define i32 @f11([1 x i32] %A.coerce0, [1 x i32] %B.coerce0) { -; CHECK: f11 -; CHECK: ubfx r1, r1, #8, #5 @ encoding: [0x51,0x14,0xe4,0xe7] -; CHECK: sbfx r0, r0, #13, #7 @ encoding: [0xd0,0x06,0xa6,0xe7] - %tmp1 = extractvalue [1 x i32] %A.coerce0, 0 - %tmp2 = extractvalue [1 x i32] %B.coerce0, 0 - %tmp3 = shl i32 %tmp1, 12 - %bf.val.sext = ashr i32 %tmp3, 25 - %tmp4 = lshr i32 %tmp2, 8 - %bf.clear2 = and i32 %tmp4, 31 - %mul = mul nsw i32 %bf.val.sext, %bf.clear2 - ret i32 %mul -} - -define i32 @f12(i32 %a) { -; CHECK: f12: -; CHECK: bfc r0, #4, #20 @ encoding: [0x1f,0x02,0xd7,0xe7] - %tmp = and i32 %a, 4278190095 - ret i32 %tmp -} - -define i64 @f13() { -; CHECK: f13: -; CHECK: mvn r0, #0 @ encoding: [0x00,0x00,0xe0,0xe3] -; CHECK: mvn r1, #-2147483648 @ encoding: [0x02,0x11,0xe0,0xe3] - ret i64 9223372036854775807 -} - -define i32 @f14(i32 %x, i32 %y) { -; CHECK: f14: -; CHECK: smmul r0, r1, r0 @ encoding: [0x11,0xf0,0x50,0xe7] - %tmp = sext i32 %x to i64 - %tmp1 = sext i32 %y to i64 - %tmp2 = mul i64 %tmp1, %tmp - %tmp3 = lshr i64 %tmp2, 32 - %tmp3.upgrd.1 = trunc i64 %tmp3 to i32 - ret i32 %tmp3.upgrd.1 -} - -define i32 @f15(i32 %x, i32 %y) { -; CHECK: f15: -; CHECK: umull r1, r0, r1, r0 @ encoding: [0x91,0x10,0x80,0xe0] - %tmp = zext i32 %x to i64 - %tmp1 = zext i32 %y to i64 - %tmp2 = mul i64 %tmp1, %tmp - %tmp3 = lshr i64 %tmp2, 32 - %tmp3.upgrd.2 = trunc i64 %tmp3 to i32 - ret i32 %tmp3.upgrd.2 -} - -define i32 @f16(i16 %x, i32 %y) { -; CHECK: f16: -; CHECK: smulbt r0, r0, r1 @ encoding: [0xc0,0x01,0x60,0xe1] - %tmp1 = add i16 %x, 2 - %tmp2 = sext i16 %tmp1 to i32 - %tmp3 = ashr i32 %y, 16 - %tmp4 = mul i32 %tmp2, %tmp3 - ret i32 %tmp4 -} - -define i32 @f17(i32 %x, i32 %y) { -; CHECK: f17: -; CHECK: smultt r0, r1, r0 @ encoding: [0xe1,0x00,0x60,0xe1] - %tmp1 = ashr i32 %x, 16 - %tmp3 = ashr i32 %y, 16 - %tmp4 = mul i32 %tmp3, %tmp1 - ret i32 %tmp4 -} - -define i32 @f18(i32 %a, i16 %x, i32 %y) { -; CHECK: f18: -; CHECK: smlabt r0, r1, r2, r0 @ encoding: [0xc1,0x02,0x00,0xe1] - %tmp = sext i16 %x to i32 - %tmp2 = ashr i32 %y, 16 - %tmp3 = mul i32 %tmp2, %tmp - %tmp5 = add i32 %tmp3, %a - ret i32 %tmp5 -} - -define i32 @f19(i32 %x) { -; CHECK: f19 -; CHECK: clz r0, r0 @ encoding: [0x10,0x0f,0x6f,0xe1] - %tmp.1 = call i32 @llvm.ctlz.i32( i32 %x ) - ret i32 %tmp.1 -} - -define i32 @f20(i32 %X) { -; CHECK: f20 -; CHECK: rev16 r0, r0 @ encoding: [0xb0,0x0f,0xbf,0xe6] - %tmp1 = lshr i32 %X, 8 - %X15 = bitcast i32 %X to i32 - %tmp4 = shl i32 %X15, 8 - %tmp2 = and i32 %tmp1, 16711680 - %tmp5 = and i32 %tmp4, -16777216 - %tmp9 = and i32 %tmp1, 255 - %tmp13 = and i32 %tmp4, 65280 - %tmp6 = or i32 %tmp5, %tmp2 - %tmp10 = or i32 %tmp6, %tmp13 - %tmp14 = or i32 %tmp10, %tmp9 - ret i32 %tmp14 -} - -define i32 @f21(i32 %X) { -; CHECK: f21 -; CHECK: revsh r0, r0 @ encoding: [0xb0,0x0f,0xff,0xe6] - %tmp1 = lshr i32 %X, 8 - %tmp1.upgrd.1 = trunc i32 %tmp1 to i16 - %tmp3 = trunc i32 %X to i16 - %tmp2 = and i16 %tmp1.upgrd.1, 255 - %tmp4 = shl i16 %tmp3, 8 - %tmp5 = or i16 %tmp2, %tmp4 - %tmp5.upgrd.2 = sext i16 %tmp5 to i32 - ret i32 %tmp5.upgrd.2 -} - -define i32 @f22(i32 %X, i32 %Y) { -; CHECK: f22 -; CHECK: pkhtb r0, r0, r1, asr #22 @ encoding: [0x51,0x0b,0x80,0xe6] - %tmp1 = and i32 %X, -65536 - %tmp2 = lshr i32 %Y, 22 - %tmp3 = or i32 %tmp2, %tmp1 - ret i32 %tmp3 -} - -define i32 @f23(i32 %X, i32 %Y) { -; CHECK: f23 -; CHECK: pkhbt r0, r0, r1, lsl #18 @ encoding: [0x11,0x09,0x80,0xe6] - %tmp1 = and i32 %X, 65535 - %tmp2 = shl i32 %Y, 18 - %tmp3 = or i32 %tmp1, %tmp2 - ret i32 %tmp3 -} - -define void @f24(i32 %a) { -; CHECK: f24 -; CHECK: cmp r0, #65536 @ encoding: [0x01,0x08,0x50,0xe3] - %b = icmp ugt i32 %a, 65536 - br i1 %b, label %r, label %r -r: - ret void -} diff --git a/test/MC/ARM/simple-fp-encoding.s b/test/MC/ARM/simple-fp-encoding.s index 891738085a2d..e7d452a28495 100644 --- a/test/MC/ARM/simple-fp-encoding.s +++ b/test/MC/ARM/simple-fp-encoding.s @@ -2,7 +2,7 @@ @ CHECK: vadd.f64 d16, d17, d16 @ encoding: [0xa0,0x0b,0x71,0xee] vadd.f64 d16, d17, d16 - + @ CHECK: vadd.f32 s0, s1, s0 @ encoding: [0x80,0x0a,0x30,0xee] vadd.f32 s0, s1, s0 @@ -36,18 +36,18 @@ @ CHECK: vcmpe.f32 s1, s0 @ encoding: [0xc0,0x0a,0xf4,0xee] vcmpe.f32 s1, s0 -@ FIXME: vcmpe.f64 d16, #0 @ encoding: [0xc0,0x0b,0xf5,0xee] -@ vcmpe.f64 d16, #0 +@ CHECK: vcmpe.f64 d16, #0 @ encoding: [0xc0,0x0b,0xf5,0xee] + vcmpe.f64 d16, #0 -@ FIXME: vcmpe.f32 s0, #0 @ encoding: [0xc0,0x0a,0xb5,0xee] -@ vcmpe.f32 s0, #0 +@ CHECK: vcmpe.f32 s0, #0 @ encoding: [0xc0,0x0a,0xb5,0xee] + vcmpe.f32 s0, #0 @ CHECK: vabs.f64 d16, d16 @ encoding: [0xe0,0x0b,0xf0,0xee] vabs.f64 d16, d16 @ CHECK: vabs.f32 s0, s0 @ encoding: [0xc0,0x0a,0xb0,0xee] vabs.f32 s0, s0 - + @ CHECK: vcvt.f32.f64 s0, d16 @ encoding: [0xe0,0x0b,0xb7,0xee] vcvt.f32.f64 s0, d16 @@ -114,9 +114,11 @@ @ CHECK: vnmls.f32 s1, s2, s0 @ encoding: [0x00,0x0a,0x51,0xee] vnmls.f32 s1, s2, s0 -@ FIXME: vmrs apsr_nzcv, fpscr @ encoding: [0x10,0xfa,0xf1,0xee] -@ vmrs apsr_nzcv, fpscr - +@ CHECK: vmrs apsr_nzcv, fpscr @ encoding: [0x10,0xfa,0xf1,0xee] +@ CHECK: vmrs apsr_nzcv, fpscr @ encoding: [0x10,0xfa,0xf1,0xee] + vmrs apsr_nzcv, fpscr + fmstat + @ CHECK: vnegne.f64 d16, d16 @ encoding: [0x60,0x0b,0xf1,0x1e] vnegne.f64 d16, d16 @@ -139,11 +141,15 @@ @ CHECK: vmsr fpsid, r0 @ encoding: [0x10,0x0a,0xe0,0xee] vmsr fpsid, r0 -@ FIXME: vmov.f64 d16, #3.000000e+00 @ encoding: [0x08,0x0b,0xf0,0xee] -@ vmov.f64 d16, #3.000000e+00 + vmov.f64 d16, #3.000000e+00 + vmov.f32 s0, #3.000000e+00 + vmov.f64 d16, #-3.000000e+00 + vmov.f32 s0, #-3.000000e+00 -@ FIXME: vmov.f32 s0, #3.000000e+00 @ encoding: [0x08,0x0a,0xb0,0xee] -@ vmov.f32 s0, #3.000000e+00 +@ CHECK: vmov.f64 d16, #3.000000e+00 @ encoding: [0x08,0x0b,0xf0,0xee] +@ CHECK: vmov.f32 s0, #3.000000e+00 @ encoding: [0x08,0x0a,0xb0,0xee] +@ CHECK: vmov.f64 d16, #-3.000000e+00 @ encoding: [0x08,0x0b,0xf8,0xee] +@ CHECK: vmov.f32 s0, #-3.000000e+00 @ encoding: [0x08,0x0a,0xb8,0xee] @ CHECK: vmov s0, r0 @ encoding: [0x10,0x0a,0x00,0xee] @ CHECK: vmov s1, r1 @ encoding: [0x90,0x1a,0x00,0xee] @@ -173,13 +179,13 @@ @ CHECK: vldr.64 d1, [r2, #-32] @ encoding: [0x08,0x1b,0x12,0xed] vldr.64 d1, [r2, #32] vldr.64 d1, [r2, #-32] - + @ CHECK: vldr.64 d2, [r3] @ encoding: [0x00,0x2b,0x93,0xed] vldr.64 d2, [r3] @ CHECK: vldr.64 d3, [pc] @ encoding: [0x00,0x3b,0x9f,0xed] @ CHECK: vldr.64 d3, [pc] @ encoding: [0x00,0x3b,0x9f,0xed] -@ CHECK: vldr.64 d3, [pc] @ encoding: [0x00,0x3b,0x9f,0xed] +@ CHECK: vldr.64 d3, [pc, #-0] @ encoding: [0x00,0x3b,0x1f,0xed] vldr.64 d3, [pc] vldr.64 d3, [pc,#0] vldr.64 d3, [pc,#-0] @@ -191,13 +197,13 @@ @ CHECK: vldr.32 s1, [r2, #-32] @ encoding: [0x08,0x0a,0x52,0xed] vldr.32 s1, [r2, #32] vldr.32 s1, [r2, #-32] - + @ CHECK: vldr.32 s2, [r3] @ encoding: [0x00,0x1a,0x93,0xed] vldr.32 s2, [r3] @ CHECK: vldr.32 s5, [pc] @ encoding: [0x00,0x2a,0xdf,0xed] @ CHECK: vldr.32 s5, [pc] @ encoding: [0x00,0x2a,0xdf,0xed] -@ CHECK: vldr.32 s5, [pc] @ encoding: [0x00,0x2a,0xdf,0xed] +@ CHECK: vldr.32 s5, [pc, #-0] @ encoding: [0x00,0x2a,0x5f,0xed] vldr.32 s5, [pc] vldr.32 s5, [pc,#0] vldr.32 s5, [pc,#-0] @@ -234,3 +240,6 @@ vcvtr.s32.f32 s0, s1 vcvtr.u32.f64 s0, d0 vcvtr.u32.f32 s0, s1 + +@ CHECK: vmovne s25, s26, r2, r5 + vmovne s25, s26, r2, r5 @ encoding: [0x39,0x2a,0x45,0x1c] diff --git a/test/MC/ARM/thumb-diagnostics.s b/test/MC/ARM/thumb-diagnostics.s new file mode 100644 index 000000000000..d02c27e1ae02 --- /dev/null +++ b/test/MC/ARM/thumb-diagnostics.s @@ -0,0 +1,139 @@ +@ RUN: not llvm-mc -triple=thumbv6-apple-darwin < %s 2> %t +@ RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s +@ RUN: not llvm-mc -triple=thumbv5-apple-darwin < %s 2> %t +@ RUN: FileCheck --check-prefix=CHECK-ERRORS-V5 < %t %s + +@ Check for various assembly diagnostic messages on invalid input. + +@ ADD instruction w/o 'S' suffix. + add r1, r2, r3 +@ CHECK-ERRORS: error: invalid instruction +@ CHECK-ERRORS: add r1, r2, r3 +@ CHECK-ERRORS: ^ + +@ Instructions which require v6+ for both registers to be low regs. + add r2, r3 + mov r2, r3 +@ CHECK-ERRORS: error: instruction variant requires Thumb2 +@ CHECK-ERRORS: add r2, r3 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS-V5: error: instruction variant requires ARMv6 or later +@ CHECK-ERRORS-V5: mov r2, r3 +@ CHECK-ERRORS-V5: ^ + + +@ Out of range immediates for ASR instruction. + asrs r2, r3, #33 + asrs r2, r3, #0 +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: asrs r2, r3, #33 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: asrs r2, r3, #0 +@ CHECK-ERRORS: ^ + +@ Out of range immediates for BKPT instruction. + bkpt #256 + bkpt #-1 +error: invalid operand for instruction + bkpt #256 + ^ +error: invalid operand for instruction + bkpt #-1 + ^ + +@ Invalid writeback and register lists for LDM + ldm r2!, {r5, r8} + ldm r2, {r5, r7} + ldm r2!, {r2, r3, r4} +@ CHECK-ERRORS: error: registers must be in range r0-r7 +@ CHECK-ERRORS: ldm r2!, {r5, r8} +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: writeback operator '!' expected +@ CHECK-ERRORS: ldm r2, {r5, r7} +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: writeback operator '!' not allowed when base register in register list +@ CHECK-ERRORS: ldm r2!, {r2, r3, r4} +@ CHECK-ERRORS: ^ + + +@ Invalid writeback and register lists for PUSH/POP + pop {r1, r2, r10} + push {r8, r9} +@ CHECK-ERRORS: error: registers must be in range r0-r7 or pc +@ CHECK-ERRORS: pop {r1, r2, r10} +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: registers must be in range r0-r7 or lr +@ CHECK-ERRORS: push {r8, r9} +@ CHECK-ERRORS: ^ + + +@ Invalid writeback and register lists for STM + stm r1, {r2, r6} + stm r1!, {r2, r9} +@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled +@ CHECK-ERRORS: stm r1, {r2, r6} +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: registers must be in range r0-r7 +@ CHECK-ERRORS: stm r1!, {r2, r9} +@ CHECK-ERRORS: ^ + +@ Out of range immediates for LSL instruction. + lsls r4, r5, #-1 + lsls r4, r5, #32 +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: lsls r4, r5, #-1 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: lsls r4, r5, #32 +@ CHECK-ERRORS: ^ + +@ Mismatched source/destination operands for MUL instruction. + muls r1, r2, r3 +@ CHECK-ERRORS: error: destination register must match source register +@ CHECK-ERRORS: muls r1, r2, r3 +@ CHECK-ERRORS: ^ + + +@ Out of range immediates for STR instruction. + str r2, [r7, #-1] + str r5, [r1, #3] + str r3, [r7, #128] +@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled +@ CHECK-ERRORS: str r2, [r7, #-1] +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled +@ CHECK-ERRORS: str r5, [r1, #3] +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled +@ CHECK-ERRORS: str r3, [r7, #128] +@ CHECK-ERRORS: ^ + +@ Out of range immediate for SVC instruction. + svc #-1 + svc #256 +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: svc #-1 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled +@ CHECK-ERRORS: svc #256 +@ CHECK-ERRORS: ^ + + +@ Out of range immediate for ADD SP instructions + add sp, #-1 + add sp, #3 + add sp, sp, #512 + add r2, sp, #1024 +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: add sp, #-1 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: add sp, #3 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled +@ CHECK-ERRORS: add sp, sp, #512 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: instruction requires a CPU feature not currently enabled +@ CHECK-ERRORS: add r2, sp, #1024 +@ CHECK-ERRORS: ^ diff --git a/test/MC/ARM/thumb-nop.s b/test/MC/ARM/thumb-nop.s new file mode 100644 index 000000000000..0b580ea14a93 --- /dev/null +++ b/test/MC/ARM/thumb-nop.s @@ -0,0 +1,9 @@ +@ RUN: llvm-mc -triple=thumbv6-apple-darwin -show-encoding < %s | FileCheck %s -check-prefix=CHECK-V6 +@ RUN: llvm-mc -triple=thumbv7-apple-darwin -show-encoding < %s | FileCheck %s -check-prefix=CHECK-V7 + + .syntax unified + + nop + +@ CHECK-V6: nop @ encoding: [0xc0,0x46] +@ CHECK-V7: nop @ encoding: [0x00,0xbf] diff --git a/test/MC/ARM/thumb.s b/test/MC/ARM/thumb.s index 79ea2e412bb4..625882c737fb 100644 --- a/test/MC/ARM/thumb.s +++ b/test/MC/ARM/thumb.s @@ -1,60 +1,58 @@ @ RUN: llvm-mc -triple thumbv6-apple-darwin -show-encoding < %s | FileCheck %s .code 16 -@ CHECK: cmp r1, r2 @ encoding: [0x91,0x42] cmp r1, r2 +@ CHECK: cmp r1, r2 @ encoding: [0x91,0x42] -@ CHECK: pop {r1, r2, r4} @ encoding: [0x16,0xbc] pop {r1, r2, r4} +@ CHECK: pop {r1, r2, r4} @ encoding: [0x16,0xbc] -@ CHECK: trap @ encoding: [0xfe,0xde] trap +@ CHECK: trap @ encoding: [0xfe,0xde] -@ CHECK: blx r9 @ encoding: [0xc8,0x47] blx r9 + blx r10 +@ CHECK: blx r9 @ encoding: [0xc8,0x47] @ CHECK: blx r10 @ encoding: [0xd0,0x47] - blx r10 -@ CHECK: rev r2, r3 @ encoding: [0x1a,0xba] -@ CHECK: rev16 r3, r4 @ encoding: [0x63,0xba] -@ CHECK: revsh r5, r6 @ encoding: [0xf5,0xba] rev r2, r3 rev16 r3, r4 revsh r5, r6 +@ CHECK: rev r2, r3 @ encoding: [0x1a,0xba] +@ CHECK: rev16 r3, r4 @ encoding: [0x63,0xba] +@ CHECK: revsh r5, r6 @ encoding: [0xf5,0xba] -@ CHECK: sxtb r2, r3 @ encoding: [0x5a,0xb2] -@ CHECK: sxth r2, r3 @ encoding: [0x1a,0xb2] sxtb r2, r3 sxth r2, r3 +@ CHECK: sxtb r2, r3 @ encoding: [0x5a,0xb2] +@ CHECK: sxth r2, r3 @ encoding: [0x1a,0xb2] -@ CHECK: tst r4, r5 @ encoding: [0x2c,0x42] tst r4, r5 +@ CHECK: tst r4, r5 @ encoding: [0x2c,0x42] -@ CHECK: uxtb r3, r6 @ encoding: [0xf3,0xb2] -@ CHECK: uxth r3, r6 @ encoding: [0xb3,0xb2] uxtb r3, r6 uxth r3, r6 +@ CHECK: uxtb r3, r6 @ encoding: [0xf3,0xb2] +@ CHECK: uxth r3, r6 @ encoding: [0xb3,0xb2] -@ CHECK: ldr r3, [r1, r2] @ encoding: [0x8b,0x58] ldr r3, [r1, r2] +@ CHECK: ldr r3, [r1, r2] @ encoding: [0x8b,0x58] -@ CHECK: bkpt #2 @ encoding: [0x02,0xbe] - bkpt #2 + bkpt #2 +@ CHECK: bkpt #2 @ encoding: [0x02,0xbe] -@ CHECK: nop @ encoding: [0x00,0xbf] nop +@ CHECK: nop @ encoding: [0xc0,0x46] -@ CHECK: yield @ encoding: [0x10,0xbf] - yield - -@ CHECK: wfe @ encoding: [0x20,0xbf] wfe - -@ CHECK: wfi @ encoding: [0x30,0xbf] wfi + yield +@ CHECK: wfe @ encoding: [0x20,0xbf] +@ CHECK: wfi @ encoding: [0x30,0xbf] +@ CHECK: yield @ encoding: [0x10,0xbf] -@ CHECK: cpsie aif @ encoding: [0x67,0xb6] cpsie aif +@ CHECK: cpsie aif @ encoding: [0x67,0xb6] -@ CHECK: mov r0, pc @ encoding: [0x78,0x46] mov r0, pc +@ CHECK: mov r0, pc @ encoding: [0x78,0x46] diff --git a/test/MC/ARM/thumb2-diagnostics.s b/test/MC/ARM/thumb2-diagnostics.s new file mode 100644 index 000000000000..e38f53c6cfdc --- /dev/null +++ b/test/MC/ARM/thumb2-diagnostics.s @@ -0,0 +1,44 @@ +@ RUN: not llvm-mc -triple=thumbv7-apple-darwin < %s 2> %t +@ RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s + +@ Ill-formed IT block instructions. + itet eq + addle r0, r1, r2 + nop + it le + iteeee gt + ittfe le + nopeq + +@ CHECK-ERRORS: error: incorrect condition in IT block; got 'le', but expected 'eq' +@ CHECK-ERRORS: addle r0, r1, r2 +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: incorrect condition in IT block; got 'al', but expected 'ne' +@ CHECK-ERRORS: nop +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: instructions in IT block must be predicable +@ CHECK-ERRORS: it le +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: too many conditions on IT instruction +@ CHECK-ERRORS: iteeee gt +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: illegal IT block condition mask 'tfe' +@ CHECK-ERRORS: ittfe le +@ CHECK-ERRORS: ^ +@ CHECK-ERRORS: error: predicated instructions must be in IT block +@ CHECK-ERRORS: nopeq +@ CHECK-ERRORS: ^ + + @ Out of range immediates for MRC/MRC2/MRRC/MRRC2 + mrc p14, #8, r1, c1, c2, #4 + mrc p14, #1, r1, c1, c2, #8 + mrc2 p14, #8, r1, c1, c2, #4 + mrc2 p14, #0, r1, c1, c2, #9 + mrrc p7, #16, r5, r4, c1 + mrrc2 p7, #17, r5, r4, c1 +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-ERRORS: error: invalid operand for instruction diff --git a/test/MC/ARM/thumb2-mclass.s b/test/MC/ARM/thumb2-mclass.s new file mode 100644 index 000000000000..10460f914509 --- /dev/null +++ b/test/MC/ARM/thumb2-mclass.s @@ -0,0 +1,74 @@ +@ RUN: llvm-mc -triple=thumbv7m-apple-darwin -show-encoding < %s | FileCheck %s + .syntax unified + .globl _func + +@ Check that the assembler can handle the documented syntax from the ARM ARM. +@ These tests test instruction encodings specific to v7m & v7m (FeatureMClass). + +@------------------------------------------------------------------------------ +@ MRS +@------------------------------------------------------------------------------ + + mrs r0, apsr + mrs r0, iapsr + mrs r0, eapsr + mrs r0, xpsr + mrs r0, ipsr + mrs r0, epsr + mrs r0, iepsr + mrs r0, msp + mrs r0, psp + mrs r0, primask + mrs r0, basepri + mrs r0, basepri_max + mrs r0, faultmask + mrs r0, control + +@ CHECK: mrs r0, apsr @ encoding: [0xef,0xf3,0x00,0x80] +@ CHECK: mrs r0, iapsr @ encoding: [0xef,0xf3,0x01,0x80] +@ CHECK: mrs r0, eapsr @ encoding: [0xef,0xf3,0x02,0x80] +@ CHECK: mrs r0, xpsr @ encoding: [0xef,0xf3,0x03,0x80] +@ CHECK: mrs r0, ipsr @ encoding: [0xef,0xf3,0x05,0x80] +@ CHECK: mrs r0, epsr @ encoding: [0xef,0xf3,0x06,0x80] +@ CHECK: mrs r0, iepsr @ encoding: [0xef,0xf3,0x07,0x80] +@ CHECK: mrs r0, msp @ encoding: [0xef,0xf3,0x08,0x80] +@ CHECK: mrs r0, psp @ encoding: [0xef,0xf3,0x09,0x80] +@ CHECK: mrs r0, primask @ encoding: [0xef,0xf3,0x10,0x80] +@ CHECK: mrs r0, basepri @ encoding: [0xef,0xf3,0x11,0x80] +@ CHECK: mrs r0, basepri_max @ encoding: [0xef,0xf3,0x12,0x80] +@ CHECK: mrs r0, faultmask @ encoding: [0xef,0xf3,0x13,0x80] +@ CHECK: mrs r0, control @ encoding: [0xef,0xf3,0x14,0x80] + +@------------------------------------------------------------------------------ +@ MSR +@------------------------------------------------------------------------------ + + msr apsr, r0 + msr iapsr, r0 + msr eapsr, r0 + msr xpsr, r0 + msr ipsr, r0 + msr epsr, r0 + msr iepsr, r0 + msr msp, r0 + msr psp, r0 + msr primask, r0 + msr basepri, r0 + msr basepri_max, r0 + msr faultmask, r0 + msr control, r0 + +@ CHECK: msr apsr, r0 @ encoding: [0x80,0xf3,0x00,0x80] +@ CHECK: msr iapsr, r0 @ encoding: [0x80,0xf3,0x01,0x80] +@ CHECK: msr eapsr, r0 @ encoding: [0x80,0xf3,0x02,0x80] +@ CHECK: msr xpsr, r0 @ encoding: [0x80,0xf3,0x03,0x80] +@ CHECK: msr ipsr, r0 @ encoding: [0x80,0xf3,0x05,0x80] +@ CHECK: msr epsr, r0 @ encoding: [0x80,0xf3,0x06,0x80] +@ CHECK: msr iepsr, r0 @ encoding: [0x80,0xf3,0x07,0x80] +@ CHECK: msr msp, r0 @ encoding: [0x80,0xf3,0x08,0x80] +@ CHECK: msr psp, r0 @ encoding: [0x80,0xf3,0x09,0x80] +@ CHECK: msr primask, r0 @ encoding: [0x80,0xf3,0x10,0x80] +@ CHECK: msr basepri, r0 @ encoding: [0x80,0xf3,0x11,0x80] +@ CHECK: msr basepri_max, r0 @ encoding: [0x80,0xf3,0x12,0x80] +@ CHECK: msr faultmask, r0 @ encoding: [0x80,0xf3,0x13,0x80] +@ CHECK: msr control, r0 @ encoding: [0x80,0xf3,0x14,0x80] diff --git a/test/MC/ARM/thumb2.s b/test/MC/ARM/thumb2.s deleted file mode 100644 index 7d632dbb15ed..000000000000 --- a/test/MC/ARM/thumb2.s +++ /dev/null @@ -1,355 +0,0 @@ -@ RUN: llvm-mc -mcpu=cortex-a8 -triple thumb-unknown-unknown -show-encoding < %s | FileCheck %s -@ XFAIL: * -.code 16 - -@ CHECK: adc r1, r1, #171 @ encoding: [0xab,0x01,0x41,0xf1] - adc r1, r1, #171 -@ CHECK: adc r1, r1, #1179666 @ encoding: [0x12,0x11,0x41,0xf1] - adc r1, r1, #1179666 -@ CHECK: adc r1, r1, #872428544 @ encoding: [0x34,0x21,0x41,0xf1] - adc r1, r1, #872428544 -@ CHECK: adc r1, r1, #1448498774 @ encoding: [0x56,0x31,0x41,0xf1] - adc r1, r1, #1448498774 -@ CHECK: adc r1, r1, #66846720 @ encoding: [0x7f,0x71,0x41,0xf1] - adc r1, r1, #66846720 - -@ CHECK: mvn r0, #187 @ encoding: [0xbb,0x00,0x6f,0xf0] - mvn r0, #187 -@ CHECK: mvn r0, #11141290 @ encoding: [0xaa,0x10,0x6f,0xf0] - mvn r0, #11141290 -@ CHECK: mvn r0, #-872363008 @ encoding: [0xcc,0x20,0x6f,0xf0] - mvn r0, #-872363008 -@ CHECK: mvn r0, #1114112 @ encoding: [0x88,0x10,0x6f,0xf4] - mvn r0, #1114112 - -@ CHECK: cmp.w r0, #11141290 @ encoding: [0xaa,0x1f,0xb0,0xf1] - cmp.w r0, #11141290 -@ CHECK: cmp.w r0, #-872363008 @ encoding: [0xcc,0x2f,0xb0,0xf1] - cmp.w r0, #-872363008 -@ CHECK: cmp.w r0, #-572662307 @ encoding: [0xdd,0x3f,0xb0,0xf1] - cmp.w r0, #-572662307 -@ CHECK: cmp.w r0, #1114112 @ encoding: [0x88,0x1f,0xb0,0xf5] - cmp.w r0, #1114112 -@ CHECK: cmp.w r0, r1, lsl #5 @ encoding: [0x41,0x1f,0xb0,0xeb] - cmp.w r0, r1, lsl #5 - -@ CHECK: sxtab r0, r1, r0 @ encoding: [0x80,0xf0,0x41,0xfa] - sxtab r0, r1, r0 @ encoding: [0x80,0xf0,0x41,0xfa] - -@ CHECK: movw r0, #65535 @ encoding: [0xff,0x70,0x4f,0xf6] - movw r0, #65535 -@ CHECK: movw r1, #43777 @ encoding: [0x01,0x31,0x4a,0xf6] - movw r1, #43777 -@ CHECK: movt r1, #427 @ encoding: [0xab,0x11,0xc0,0xf2] - movt r1, #427 -@ CHECK: movw r1, #43792 @ encoding: [0x10,0x31,0x4a,0xf6] - movw r1, #43792 -@ CHECK: movt r1, #4267 @ encoding: [0xab,0x01,0xc0,0xf2] - movt r1, #4267 -@ CHECK: mov.w r0, #66846720 @ encoding: [0x7f,0x70,0x4f,0xf0] - mov.w r0, #66846720 - -@ Aliases w/ the vanilla 'mov' mnemonic, and explicit alternative selection. - mov r2, #0xbf000000 - mov r1, #0x100 - mov r3, #32 - mov.w r3, #32 - movw r3, #32 - -@ CHECK: mov.w r2, #3204448256 @ encoding: [0x4f,0xf0,0x3f,0x42] -@ CHECK: mov.w r1, #256 @ encoding: [0x4f,0xf4,0x80,0x71] -@ CHECK: mov r3, #32 @ encoding: [0x20,0x23] -@ CHECK: mov.w r3, #32 @ encoding: [0x4f,0xf0,0x20,0x03] -@ CHECK: movw r3, #32 @ encoding: [0x40,0xf2,0x20,0x03] - - - - -@ CHECK: rrx r0, r0 @ encoding: [0x30,0x00,0x4f,0xea] - rrx r0, r0 - -@ CHECK: bfc r0, #4, #20 @ encoding: [0x17,0x10,0x6f,0xf3] - bfc r0, #4, #20 -@ CHECK: bfc r0, #0, #23 @ encoding: [0x16,0x00,0x6f,0xf3] - bfc r0, #0, #23 -@ CHECK: bfc r0, #12, #20 @ encoding: [0x1f,0x30,0x6f,0xf3] - bfc r0, #12, #20 - -@ CHECK: sbfx r0, r0, #7, #11 @ encoding: [0xca,0x10,0x40,0xf3] - sbfx r0, r0, #7, #11 -@ CHECK: ubfx r0, r0, #7, #11 @ encoding: [0xca,0x10,0xc0,0xf3] - ubfx r0, r0, #7, #11 - -@ CHECK: mla r0, r0, r1, r2 @ encoding: [0x01,0x20,0x00,0xfb] - mla r0, r0, r1, r2 -@ CHECK: mls r0, r0, r1, r2 @ encoding: [0x11,0x20,0x00,0xfb] - mls r0, r0, r1, r2 - -@ CHECK: smlabt r0, r1, r2, r0 @ encoding: [0x12,0x00,0x11,0xfb] - smlabt r0, r1, r2, r0 - -@ CHECK: clz r0, r0 @ encoding: [0x80,0xf0,0xb0,0xfa] - clz r0, r0 - -@ CHECK: pkhbt r0, r0, r1, lsl #16 @ encoding: [0x01,0x40,0xc0,0xea] - pkhbt r0, r0, r1, lsl #16 -@ CHECK: pkhbt r0, r0, r1, lsl #12 @ encoding: [0x01,0x30,0xc0,0xea] - pkhbt r0, r0, r1, lsl #16 -@ CHECK: pkhbt r0, r0, r1, lsl #18 @ encoding: [0x81,0x40,0xc0,0xea] - pkhbt r0, r0, r1, lsl #18 -@ CHECK: pkhbt r0, r0, r1 @ encoding: [0x01,0x00,0xc0,0xea] - pkhbt r0, r0, r1 -@ CHECK: pkhtb r0, r0, r1, asr #16 @ encoding: [0x21,0x40,0xc0,0xea] - pkhtb r0, r0, r1, asr #16 -@ CHECK: pkhtb r0, r0, r1, asr #12 @ encoding: [0x21,0x30,0xc0,0xea] - pkhtb r0, r0, r1, asr #12 -@ CHECK: pkhtb r0, r0, r1, asr #18 @ encoding: [0xa1,0x40,0xc0,0xea] - pkhtb r0, r0, r1, asr #18 -@ CHECK: pkhtb r0, r0, r1, asr #22 @ encoding: [0xa1,0x50,0xc0,0xea] - pkhtb r0, r0, r1, asr #22 - -@ CHECK: str.w r0, [r1, #4092] @ encoding: [0xfc,0x0f,0xc1,0xf8] - str.w r0, [r1, #4092] -@ CHECK: str r0, [r1, #-128] @ encoding: [0x80,0x0c,0x41,0xf8] - str r0, [r1, #-128] -@ CHECK: str.w r0, [r1, r2, lsl #2] @ encoding: [0x22,0x00,0x41,0xf8 - str.w r0, [r1, r2, lsl #2] - -@ CHECK: ldr.w r0, [r0, #4092] @ encoding: [0xfc,0x0f,0xd0,0xf8] - ldr.w r0, [r0, #4092] -@ CHECK: ldr r0, [r0, #-128] @ encoding: [0x80,0x0c,0x50,0xf8] - ldr r0, [r0, #-128] -@ CHECK: ldr.w r0, [r0, r1, lsl #2] @ encoding: [0x21,0x00,0x50,0xf8] - ldr.w r0, [r0, r1, lsl #2] - -@ CHECK: str r1, [r0, #16]! @ encoding: [0x10,0x1f,0x40,0xf8] - str r1, [r0, #16]! -@ CHECK: strh r1, [r0, #8]! @ encoding: [0x08,0x1f,0x20,0xf8] - strh r1, [r0, #8]! -@ CHECK: strh r2, [r0], #-4 @ encoding: [0x04,0x29,0x20,0xf8] - strh r2, [r0], #-4 -@ CHECK: str r2, [r0], #-4 @ encoding: [0x04,0x29,0x40,0xf8] - str r2, [r0], #-4 - -@ CHECK: ldr r2, [r0, #16]! @ encoding: [0x10,0x2f,0x50,0xf8] - ldr r2, [r0, #16]! -@ CHECK: ldr r2, [r0, #-64]! @ encoding: [0x40,0x2d,0x50,0xf8] - ldr r2, [r0, #-64]! -@ CHECK: ldrsb r2, [r0, #4]! @ encoding: [0x04,0x2f,0x10,0xf9] - ldrsb r2, [r0, #4]! - -@ CHECK: strb.w r0, [r1, #4092] @ encoding: [0xfc,0x0f,0x81,0xf8] - strb.w r0, [r1, #4092] -@ CHECK: strb r0, [r1, #-128] @ encoding: [0x80,0x0c,0x01,0xf8] - strb r0, [r1, #-128] -@ CHECK: strb.w r0, [r1, r2, lsl #2] @ encoding: [0x22,0x00,0x01,0xf8] - strb.w r0, [r1, r2, lsl #2] -@ CHECK: strh.w r0, [r1, #4092] @ encoding: [0xfc,0x0f,0xa1,0xf8] - strh.w r0, [r1, #4092] -@ CHECK: strh r0, [r1, #-128] @ encoding: [0x80,0x0c,0x21,0xf8] - strh r0, [r1, #-128] -@ CHECK: strh r0, [r1, #-128] @ encoding: [0x80,0x0c,0x21,0xf8] - strh r0, [r1, #-128] -@ CHECK: strh.w r0, [r1, r2, lsl #2] @ encoding: [0x22,0x00,0x21,0xf8] - strh.w r0, [r1, r2, lsl #2] - -@ CHECK: ldrb r0, [r0, #-1] @ encoding: [0x01,0x0c,0x10,0xf8] - ldrb r0, [r0, #-1] -@ CHECK: ldrb r0, [r0, #-128] @ encoding: [0x80,0x0c,0x10,0xf8] - ldrb r0, [r0, #-128] -@ CHECK: ldrb.w r0, [r0, r1, lsl #2] @ encoding: [0x21,0x00,0x10,0xf8] - ldrb.w r0, [r0, r1, lsl #2] -@ CHECK: ldrh.w r0, [r0, #2046] @ encoding: [0xfe,0x07,0xb0,0xf8] - ldrh.w r0, [r0, #2046] -@ CHECK: ldrh r0, [r0, #-128] @ encoding: [0x80,0x0c,0x30,0xf8] - ldrh r0, [r0, #-128] -@ CHECK: ldrh.w r0, [r0, r1, lsl #2] @ encoding: [0x21,0x00,0x30,0xf8] - ldrh.w r0, [r0, r1, lsl #2] -@ CHECK: ldrsb.w r0, [r0] @ encoding: [0x00,0x00,0x90,0xf9] - ldrsb.w r0, [r0] -@ CHECK: ldrsh.w r0, [r0] @ encoding: [0x00,0x00,0xb0,0xf9] - ldrsh.w r0, [r0] -@ CHECK: bfi r0, r0, #5, #7 @ encoding: [0x60,0xf3,0x4b,0x10] - bfi r0, r0, #5, #7 -@ CHECK: isb @ encoding: [0xbf,0xf3,0x6f,0x8f] - isb -@ CHECK: mrs r0, cpsr @ encoding: [0xef,0xf3,0x00,0x80] - mrs r0, cpsr -@ CHECK: vmrs r0, fpscr @ encoding: [0xf1,0xee,0x10,0x0a] - vmrs r0, fpscr -@ CHECK: vmrs r0, fpexc @ encoding: [0xf8,0xee,0x10,0x0a] - vmrs r0, fpexc -@ CHECK: vmrs r0, fpsid @ encoding: [0xf0,0xee,0x10,0x0a] - vmrs r0, fpsid - -@ CHECK: vmsr fpscr, r0 @ encoding: [0xe1,0xee,0x10,0x0a] - vmsr fpscr, r0 -@ CHECK: vmsr fpexc, r0 @ encoding: [0xe8,0xee,0x10,0x0a] - vmsr fpexc, r0 -@ CHECK: vmsr fpsid, r0 @ encoding: [0xe0,0xee,0x10,0x0a] - vmsr fpsid, r0 - -@ CHECK: mcr p7, #1, r5, c1, c1, #4 @ encoding: [0x21,0xee,0x91,0x57] - mcr p7, #1, r5, c1, c1, #4 - -@ CHECK: mrc p14, #0, r1, c1, c2, #4 @ encoding: [0x11,0xee,0x92,0x1e] - mrc p14, #0, r1, c1, c2, #4 - -@ CHECK: mcrr p7, #1, r5, r4, c1 @ encoding: [0x44,0xec,0x11,0x57] - mcrr p7, #1, r5, r4, c1 - -@ CHECK: mrrc p7, #1, r5, r4, c1 @ encoding: [0x54,0xec,0x11,0x57] - mrrc p7, #1, r5, r4, c1 - -@ CHECK: mcr2 p7, #1, r5, c1, c1, #4 @ encoding: [0x21,0xfe,0x91,0x57] - mcr2 p7, #1, r5, c1, c1, #4 - -@ CHECK: mrc2 p14, #0, r1, c1, c2, #4 @ encoding: [0x11,0xfe,0x92,0x1e] - mrc2 p14, #0, r1, c1, c2, #4 - -@ CHECK: mcrr2 p7, #1, r5, r4, c1 @ encoding: [0x44,0xfc,0x11,0x57] - mcrr2 p7, #1, r5, r4, c1 - -@ CHECK: mrrc2 p7, #1, r5, r4, c1 @ encoding: [0x54,0xfc,0x11,0x57] - mrrc2 p7, #1, r5, r4, c1 - -@ CHECK: cdp p7, #1, c1, c1, c1, #4 @ encoding: [0x11,0xee,0x81,0x17] - cdp p7, #1, c1, c1, c1, #4 - -@ CHECK: cdp2 p7, #1, c1, c1, c1, #4 @ encoding: [0x11,0xfe,0x81,0x17] - cdp2 p7, #1, c1, c1, c1, #4 - -@ CHECK: clrex @ encoding: [0xbf,0xf3,0x2f,0x8f] - clrex - -@ CHECK: clz r9, r0 @ encoding: [0xb0,0xfa,0x80,0xf9] - clz r9, r0 - -@ CHECK: qadd r1, r2, r3 @ encoding: [0x83,0xfa,0x82,0xf1] - qadd r1, r2, r3 - -@ CHECK: qsub r1, r2, r3 @ encoding: [0x83,0xfa,0xa2,0xf1] - qsub r1, r2, r3 - -@ CHECK: qdadd r1, r2, r3 @ encoding: [0x83,0xfa,0x92,0xf1] - qdadd r1, r2, r3 - -@ CHECK: qdsub r1, r2, r3 @ encoding: [0x83,0xfa,0xb2,0xf1] - qdsub r1, r2, r3 - -@ CHECK: nop.w @ encoding: [0xaf,0xf3,0x00,0x80] - nop.w - -@ CHECK: yield.w @ encoding: [0xaf,0xf3,0x01,0x80] - yield.w - -@ CHECK: wfe.w @ encoding: [0xaf,0xf3,0x02,0x80] - wfe.w - -@ CHECK: wfi.w @ encoding: [0xaf,0xf3,0x03,0x80] - wfi.w - -@ CHECK: dmb sy @ encoding: [0xbf,0xf3,0x5f,0x8f] - dmb sy -@ CHECK: dmb st @ encoding: [0xbf,0xf3,0x5e,0x8f] - dmb st -@ CHECK: dmb ish @ encoding: [0xbf,0xf3,0x5b,0x8f] - dmb ish -@ CHECK: dmb ishst @ encoding: [0xbf,0xf3,0x5a,0x8f] - dmb ishst -@ CHECK: dmb nsh @ encoding: [0xbf,0xf3,0x57,0x8f] - dmb nsh -@ CHECK: dmb nshst @ encoding: [0xbf,0xf3,0x56,0x8f] - dmb nshst -@ CHECK: dmb osh @ encoding: [0xbf,0xf3,0x53,0x8f] - dmb osh -@ CHECK: dmb oshst @ encoding: [0xbf,0xf3,0x52,0x8f] - dmb oshst - -@ CHECK: dsb sy @ encoding: [0xbf,0xf3,0x4f,0x8f] - dsb sy -@ CHECK: dsb st @ encoding: [0xbf,0xf3,0x4e,0x8f] - dsb st -@ CHECK: dsb ish @ encoding: [0xbf,0xf3,0x4b,0x8f] - dsb ish -@ CHECK: dsb ishst @ encoding: [0xbf,0xf3,0x4a,0x8f] - dsb ishst -@ CHECK: dsb nsh @ encoding: [0xbf,0xf3,0x47,0x8f] - dsb nsh -@ CHECK: dsb nshst @ encoding: [0xbf,0xf3,0x46,0x8f] - dsb nshst -@ CHECK: dsb osh @ encoding: [0xbf,0xf3,0x43,0x8f] - dsb osh -@ CHECK: dsb oshst @ encoding: [0xbf,0xf3,0x42,0x8f] - dsb oshst - -@ CHECK: cpsie.w aif @ encoding: [0xaf,0xf3,0xe0,0x84] - cpsie.w aif -@ CHECK: cps #15 @ encoding: [0xaf,0xf3,0x0f,0x81] - cps #15 -@ CHECK: cpsie.w if, #10 @ encoding: [0xaf,0xf3,0x6a,0x85] - cpsie.w if, #10 - -@ CHECK: msr cpsr_fc, r0 @ encoding: [0x80,0xf3,0x00,0x89] - msr apsr, r0 -@ CHECK: msr cpsr_s, r0 @ encoding: [0x80,0xf3,0x00,0x84] - msr apsr_g, r0 -@ CHECK: msr cpsr_f, r0 @ encoding: [0x80,0xf3,0x00,0x88] - msr apsr_nzcvq, r0 -@ CHECK: msr cpsr_fs, r0 @ encoding: [0x80,0xf3,0x00,0x8c] - msr apsr_nzcvqg, r0 -@ CHECK: msr cpsr_fc, r0 @ encoding: [0x80,0xf3,0x00,0x89] - msr cpsr_fc, r0 -@ CHECK: msr cpsr_c, r0 @ encoding: [0x80,0xf3,0x00,0x81] - msr cpsr_c, r0 -@ CHECK: msr cpsr_x, r0 @ encoding: [0x80,0xf3,0x00,0x82] - msr cpsr_x, r0 -@ CHECK: msr cpsr_fc, r0 @ encoding: [0x80,0xf3,0x00,0x89] - msr cpsr_fc, r0 -@ CHECK: msr cpsr_fsx, r0 @ encoding: [0x80,0xf3,0x00,0x8e] - msr cpsr_fsx, r0 -@ CHECK: msr spsr_fc, r0 @ encoding: [0x90,0xf3,0x00,0x89] - msr spsr_fc, r0 -@ CHECK: msr spsr_fsxc, r0 @ encoding: [0x90,0xf3,0x00,0x8f] - msr spsr_fsxc, r0 -@ CHECK: msr cpsr_fsxc, r0 @ encoding: [0x80,0xf3,0x00,0x8f] - msr cpsr_fsxc, r0 - -@ CHECK: strexb r0, r1, [r2] @ encoding: [0xc2,0xe8,0x40,0x1f] - strexb r0, r1, [r2] -@ CHECK: strexh r0, r1, [r2] @ encoding: [0xc2,0xe8,0x50,0x1f] - strexh r0, r1, [r2] -@ CHECK: strex r0, r1, [r2] @ encoding: [0x42,0xe8,0x00,0x10] - strex r0, r1, [r2] -@ CHECK: strexd r0, r2, r3, [r1] @ encoding: [0xc1,0xe8,0x70,0x23] - strexd r0, r2, r3, [r1] -@ CHECK: ldrexb r0, [r0] @ encoding: [0xd0,0xe8,0x4f,0x0f] - ldrexb r0, [r0] -@ CHECK: ldrexh r0, [r0] @ encoding: [0xd0,0xe8,0x5f,0x0f] - ldrexh r0, [r0] -@ CHECK: ldrex r0, [r0] @ encoding: [0x50,0xe8,0x00,0x0f] - ldrex r0, [r0] -@ CHECK: ldrexd r0, r1, [r0] @ encoding: [0xd0,0xe8,0x7f,0x01] - ldrexd r0, r1, [r0] -@ CHECK: ssat16 r0, #7, r0 @ encoding: [0x20,0xf3,0x06,0x00] - ssat16 r0, #7, r0 - - and r1, #0xff - and r1, r1, #0xff - orr r1, 0x100 - orr r1, r1, 0x100 - eor r1, 0x100 - eor r1, r1, 0x100 - bic r1, 0x100 - bic r1, r1, 0x100 - -@ CHECK: and r1, r1, #255 @ encoding: [0x01,0xf0,0xff,0x01] -@ CHECK: and r1, r1, #255 @ encoding: [0x01,0xf0,0xff,0x01] -@ CHECK: orr r1, r1, #256 @ encoding: [0x41,0xf4,0x80,0x71] -@ CHECK: orr r1, r1, #256 @ encoding: [0x41,0xf4,0x80,0x71] -@ CHECK: eor r1, r1, #256 @ encoding: [0x81,0xf4,0x80,0x71] -@ CHECK: eor r1, r1, #256 @ encoding: [0x81,0xf4,0x80,0x71] -@ CHECK: bic r1, r1, #256 @ encoding: [0x21,0xf4,0x80,0x71] -@ CHECK: bic r1, r1, #256 @ encoding: [0x21,0xf4,0x80,0x71] - - diff --git a/test/MC/ARM/thumb2_instructions.s b/test/MC/ARM/thumb2_instructions.s deleted file mode 100644 index 71cd4aea2f85..000000000000 --- a/test/MC/ARM/thumb2_instructions.s +++ /dev/null @@ -1,12 +0,0 @@ -@ RUN: llvm-mc -triple thumbv7-unknown-unknown -show-encoding %s > %t -@ RUN: FileCheck < %t %s - - .syntax unified - .text - -@ FIXME: This is not the correct instruction representation, but at least we are -@ parsing the ldr to something. -@ -@ CHECK: ldr r0, [r7, #258] - ldr r0, [r7, #-8] - diff --git a/test/MC/ARM/xscale-attributes.ll b/test/MC/ARM/xscale-attributes.ll index e576278c3dcf..3ccf02b95e2c 100644 --- a/test/MC/ARM/xscale-attributes.ll +++ b/test/MC/ARM/xscale-attributes.ll @@ -17,7 +17,7 @@ entry: ; ASM-NEXT: .eabi_attribute 8, 1 ; ASM-NEXT: .eabi_attribute 9, 1 -; OBJ: Section 0x00000004 +; OBJ: Section 4 ; OBJ-NEXT: 'sh_name', 0x0000000c ; OBJ-NEXT: 'sh_type', 0x70000003 ; OBJ-NEXT: 'sh_flags', 0x00000000 diff --git a/test/MC/AsmParser/2011-09-06-NoNewline.s b/test/MC/AsmParser/2011-09-06-NoNewline.s new file mode 100644 index 000000000000..7ecaf688ea07 --- /dev/null +++ b/test/MC/AsmParser/2011-09-06-NoNewline.s @@ -0,0 +1,6 @@ +// RUN: llvm-mc %s +movl %gs:8, %eax +// RUN: llvm-mc %s +movl %gs:8, %eax +// RUN: llvm-mc %s +movl %gs:8, %eax \ No newline at end of file diff --git a/test/MC/AsmParser/exprs.s b/test/MC/AsmParser/exprs.s index 153701d6852a..df075f85ecf5 100644 --- a/test/MC/AsmParser/exprs.s +++ b/test/MC/AsmParser/exprs.s @@ -5,12 +5,12 @@ .abort Unexpected $0 != $1. .endif .endmacro - + .text g: h: j: -k: +k: .data check_expr !1 + 2, 2 check_expr !0, 1 @@ -44,7 +44,8 @@ k: check_expr 0 || 1, 1 check_expr 0 || 0, 0 check_expr 1 + 2 < 3 + 4, 1 - + check_expr 1 << 8 - 1, 128 + .set c, 10 check_expr c + 1, 11 @@ -56,15 +57,15 @@ k: i = (j + 10) - (k + 2) .long i - + l = m - n + 4 - + .text m: n: nop - - + + movw $8, (42)+66(%eax) // "." support: diff --git a/test/MC/AsmParser/labels.s b/test/MC/AsmParser/labels.s index 3bc7e630ce47..56091755d966 100644 --- a/test/MC/AsmParser/labels.s +++ b/test/MC/AsmParser/labels.s @@ -35,9 +35,6 @@ foo: // CHECK: .globl "a 3" .globl "a 3" -// CHECK: .weak "a 4" - .weak "a 4" - // CHECK: .desc "a 5",1 .desc "a 5", 1 diff --git a/test/MC/AsmParser/line_with_hash.s b/test/MC/AsmParser/line_with_hash.s new file mode 100644 index 000000000000..6fdab400f37b --- /dev/null +++ b/test/MC/AsmParser/line_with_hash.s @@ -0,0 +1,15 @@ +# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s + +// We used to incorrectly parse a line with only a # in it + +.zero 42 +# +.ifndef FOO +.zero 2 +.else +.endif +.zero 24 + +// CHECK: .zero 42 +// CHECK-NEXT: .zero 2 +// CHECK-NEXT: .zero 24 diff --git a/test/MC/Disassembler/ARM/arm-tests.txt b/test/MC/Disassembler/ARM/arm-tests.txt index 0536eebb3171..69a094dd681c 100644 --- a/test/MC/Disassembler/ARM/arm-tests.txt +++ b/test/MC/Disassembler/ARM/arm-tests.txt @@ -1,4 +1,4 @@ -# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 | FileCheck %s +# RUN: llvm-mc --disassemble %s -triple=armv7-apple-darwin9 -mattr +mp | FileCheck %s # CHECK: addpl r4, pc, #318767104 0x4c 0x45 0x8f 0x52 @@ -45,8 +45,11 @@ # CHECK: isb 0x6f 0xf0 0x7f 0xf5 -# CHECK: ldclvc p5, cr15, [r8], #-0 -0x00 0xf5 0x78 0x7c +# FIXME: LDC encoding information is incorrect. Re-enable this along with more +# robust testing for other values when we get it fleshed out and working +# properly. +# CHECKx: ldclvc p5, cr15, [r8], #-0 +#0x00 0xf5 0x78 0x7c # CHECK: ldr r0, [r2], #15 0x0f 0x00 0x92 0xe4 @@ -57,11 +60,14 @@ # CHECK: ldrh r0, [r2], #0 0xb0 0x00 0xd2 0xe0 +# CHECK: ldrh r0, [r2] +0xb0 0x00 0xd2 0xe1 + # CHECK: ldrht r0, [r2], #15 0xbf 0x00 0xf2 0xe0 # CHECK: ldrsbtvs lr, [r2], -r9 -0xd9 0xe9 0x32 0x60 +0xd9 0xe0 0x32 0x60 # CHECK: lsls r0, r2, #31 0x82 0x0f 0xb0 0xe1 @@ -101,6 +107,12 @@ # CHECK: rfedb r0! 0x00 0x0a 0x30 0xf9 +# CHECK: srsdb sp!, #19 +0x13 0x05 0x6d 0xf9 + +# CHECK: srsia sp, #9 +0x09 0x05 0xcd 0xf8 + # CHECK-NOT: rsbeq r0, r2, r0, lsl #0 # CHECK: rsbeq r0, r2, r0 0x00 0x00 0x62 0x00 @@ -149,10 +161,10 @@ # CHECK: cpsie if, #10 0xca 0x00 0x0a 0xf1 -# CHECK: msr cpsr_fc, r0 +# CHECK: msr CPSR_fc, r0 0x00 0xf0 0x29 0xe1 -# CHECK: msrmi cpsr_c, #4043309056 +# CHECK: msrmi CPSR_c, #4043309056 0xf1 0xf4 0x21 0x43 # CHECK: rsbs r6, r7, r8 @@ -168,7 +180,7 @@ 0x15 0xff 0x2f 0x01 # CHECK: uqadd16mi r6, r11, r8 -0x18 0x60 0x6b 0x46 +0x18 0x6F 0x6b 0x46 # CHECK: str r0, [sp, #4] 0x04 0x00 0x8d 0xe5 @@ -221,7 +233,7 @@ # CHECK: umull r1, r2, r3, r4 0x93 0x14 0x82 0xe0 -# CHECK: pld [pc, #-0] +# CHECK: pldw [pc, #-0] 0x00 0xf0 0x1f 0xf5 # CHECK: pli [pc, #-0] @@ -230,12 +242,15 @@ # CHECK: pli [r3, r1, lsl #2] 0x01 0xf1 0xd3 0xf6 -# CHECK: stc p2, cr4, [r9], {157} +# CHECK: stc p2, c4, [r9], {157} 0x9d 0x42 0x89 0xec -# CHECK: stc2 p2, cr4, [r9], {157} +# CHECK: stc2 p2, c4, [r9], {157} 0x9d 0x42 0x89 0xfc +# CHECK: bne #-24 +0xfa 0xff 0xff 0x1a + # CHECK: blx #60 0x0f 0x00 0x00 0xfa @@ -287,3 +302,18 @@ # CHECK: nop 0x00 0xf0 0x20 0xe3 + +# CHECK: andeq r0, r0, r0, lsr #32 +0x20 0x00 0x00 0x00 + +# CHECK: strb r3, [r2], #1 +0x01 0x30 0xc2 0xe4 + +# CHECK: strheq r0, [r0, -r0] +0xb0 0x00 0x00 0x01 + +# CHECK: rfedb #4! +0x14 0x0 0x32 0xf9 + +# CHECK: stc2l p0, c0, [r2], #-96 +0x18 0x0 0x62 0xfc diff --git a/test/MC/Disassembler/ARM/basic-arm-instructions.txt b/test/MC/Disassembler/ARM/basic-arm-instructions.txt new file mode 100644 index 000000000000..fc7eda537aba --- /dev/null +++ b/test/MC/Disassembler/ARM/basic-arm-instructions.txt @@ -0,0 +1,2362 @@ +# RUN: llvm-mc -triple=armv7-apple-darwin -disassemble < %s | FileCheck %s + +#------------------------------------------------------------------------------ +# ADC (immediate) +#------------------------------------------------------------------------------ +# CHECK: adc r1, r2, #15 +# CHECK: adc r1, r2, #240 +# CHECK: adc r1, r2, #3840 +# CHECK: adc r1, r2, #61440 +# CHECK: adc r1, r2, #983040 +# CHECK: adc r1, r2, #15728640 +# CHECK: adc r1, r2, #251658240 +# CHECK: adc r1, r2, #4026531840 +# CHECK: adc r1, r2, #4026531855 +# CHECK: adcs r1, r2, #3840 +# CHECK: adcseq r1, r2, #3840 +# CHECK: adceq r1, r2, #3840 + +0x0f 0x10 0xa2 0xe2 +0xf0 0x10 0xa2 0xe2 +0x0f 0x1c 0xa2 0xe2 +0x0f 0x1a 0xa2 0xe2 +0x0f 0x18 0xa2 0xe2 +0x0f 0x16 0xa2 0xe2 +0x0f 0x14 0xa2 0xe2 +0x0f 0x12 0xa2 0xe2 +0xff 0x12 0xa2 0xe2 + +0x0f 0x1c 0xb2 0xe2 +0x0f 0x1c 0xb2 0x02 +0x0f 0x1c 0xa2 0x02 + +#------------------------------------------------------------------------------ +# ADC (register) +# ADC (shifted register) +#------------------------------------------------------------------------------ +# CHECK: adc r4, r5, r6 + +# CHECK: adc r4, r5, r6, lsl #1 +# CHECK: adc r4, r5, r6, lsl #31 +# CHECK: adc r4, r5, r6, lsr #1 +# CHECK: adc r4, r5, r6, lsr #31 +# CHECK: adc r4, r5, r6, lsr #32 +# CHECK: adc r4, r5, r6, asr #1 +# CHECK: adc r4, r5, r6, asr #31 +# CHECK: adc r4, r5, r6, asr #32 +# CHECK: adc r4, r5, r6, ror #1 +# CHECK: adc r4, r5, r6, ror #31 + +# CHECK: adc r6, r7, r8, lsl r9 +# CHECK: adc r6, r7, r8, lsr r9 +# CHECK: adc r6, r7, r8, asr r9 +# CHECK: adc r6, r7, r8, ror r9 +# CHECK: adc r4, r5, r6, rrx + +# CHECK: adc r5, r5, r6 +# CHECK: adc r4, r4, r5, lsl #1 +# CHECK: adc r4, r4, r5, lsl #31 +# CHECK: adc r4, r4, r5, lsr #1 +# CHECK: adc r4, r4, r5, lsr #31 +# CHECK: adc r4, r4, r5, lsr #32 +# CHECK: adc r4, r4, r5, asr #1 +# CHECK: adc r4, r4, r5, asr #31 +# CHECK: adc r4, r4, r5, asr #32 +# CHECK: adc r4, r4, r5, ror #1 +# CHECK: adc r4, r4, r5, ror #31 +# CHECK: adc r4, r4, r5, rrx +# CHECK: adc r6, r6, r7, lsl r9 +# CHECK: adc r6, r6, r7, lsr r9 +# CHECK: adc r6, r6, r7, asr r9 +# CHECK: adc r6, r6, r7, ror r9 +# CHECK: adc r4, r4, r5, rrx + +0x06 0x40 0xa5 0xe0 + +0x86 0x40 0xa5 0xe0 +0x86 0x4f 0xa5 0xe0 +0xa6 0x40 0xa5 0xe0 +0xa6 0x4f 0xa5 0xe0 +0x26 0x40 0xa5 0xe0 +0xc6 0x40 0xa5 0xe0 +0xc6 0x4f 0xa5 0xe0 +0x46 0x40 0xa5 0xe0 +0xe6 0x40 0xa5 0xe0 +0xe6 0x4f 0xa5 0xe0 + +0x18 0x69 0xa7 0xe0 +0x38 0x69 0xa7 0xe0 +0x58 0x69 0xa7 0xe0 +0x78 0x69 0xa7 0xe0 +0x66 0x40 0xa5 0xe0 + +0x06 0x50 0xa5 0xe0 +0x85 0x40 0xa4 0xe0 +0x85 0x4f 0xa4 0xe0 +0xa5 0x40 0xa4 0xe0 +0xa5 0x4f 0xa4 0xe0 +0x25 0x40 0xa4 0xe0 +0xc5 0x40 0xa4 0xe0 +0xc5 0x4f 0xa4 0xe0 +0x45 0x40 0xa4 0xe0 +0xe5 0x40 0xa4 0xe0 +0xe5 0x4f 0xa4 0xe0 +0x65 0x40 0xa4 0xe0 +0x17 0x69 0xa6 0xe0 +0x37 0x69 0xa6 0xe0 +0x57 0x69 0xa6 0xe0 +0x77 0x69 0xa6 0xe0 +0x65 0x40 0xa4 0xe0 + +#------------------------------------------------------------------------------ +# ADD +#------------------------------------------------------------------------------ +# CHECK: add r4, r5, #61440 +# CHECK: add r4, r5, r6 +# CHECK: add r4, r5, r6, lsl #5 +# CHECK: add r4, r5, r6, lsr #5 +# CHECK: add r4, r5, r6, lsr #5 +# CHECK: add r4, r5, r6, asr #5 +# CHECK: add r4, r5, r6, ror #5 +# CHECK: add r6, r7, r8, lsl r9 +# CHECK: add r6, r7, r8, lsr r9 +# CHECK: add r6, r7, r8, asr r9 +# CHECK: add r6, r7, r8, ror r9 +# CHECK: add r4, r5, r6, rrx + +# CHECK: add r5, r5, #61440 +# CHECK: add r4, r4, r5 +# CHECK: add r4, r4, r5, lsl #5 +# CHECK: add r4, r4, r5, lsr #5 +# CHECK: add r4, r4, r5, lsr #5 +# CHECK: add r4, r4, r5, asr #5 +# CHECK: add r4, r4, r5, ror #5 +# CHECK: add r6, r6, r7, lsl r9 +# CHECK: add r6, r6, r7, lsr r9 +# CHECK: add r6, r6, r7, asr r9 +# CHECK: add r6, r6, r7, ror r9 +# CHECK: add r4, r4, r5, rrx + +0x0f 0x4a 0x85 0xe2 +0x06 0x40 0x85 0xe0 +0x86 0x42 0x85 0xe0 +0xa6 0x42 0x85 0xe0 +0xa6 0x42 0x85 0xe0 +0xc6 0x42 0x85 0xe0 +0xe6 0x42 0x85 0xe0 +0x18 0x69 0x87 0xe0 +0x38 0x69 0x87 0xe0 +0x58 0x69 0x87 0xe0 +0x78 0x69 0x87 0xe0 +0x66 0x40 0x85 0xe0 + + +0x0f 0x5a 0x85 0xe2 +0x05 0x40 0x84 0xe0 +0x85 0x42 0x84 0xe0 +0xa5 0x42 0x84 0xe0 +0xa5 0x42 0x84 0xe0 +0xc5 0x42 0x84 0xe0 +0xe5 0x42 0x84 0xe0 +0x17 0x69 0x86 0xe0 +0x37 0x69 0x86 0xe0 +0x57 0x69 0x86 0xe0 +0x77 0x69 0x86 0xe0 +0x65 0x40 0x84 0xe0 + +#------------------------------------------------------------------------------ +# ADR +#------------------------------------------------------------------------------ +# CHECK: add r2, pc, #3 +# CHECK: sub r2, pc, #3 + +0x03 0x20 0x8f 0xe2 +0x03 0x20 0x4f 0xe2 + +#------------------------------------------------------------------------------ +# AND +#------------------------------------------------------------------------------ +# CHECK: and r10, r1, #15 +# CHECK: and r10, r1, r6 +# CHECK: and r10, r1, r6, lsl #10 +# CHECK: and r10, r1, r6, lsr #10 +# CHECK: and r10, r1, r6, lsr #10 +# CHECK: and r10, r1, r6, asr #10 +# CHECK: and r10, r1, r6, ror #10 +# CHECK: and r6, r7, r8, lsl r2 +# CHECK: and r6, r7, r8, lsr r2 +# CHECK: and r6, r7, r8, asr r2 +# CHECK: and r6, r7, r8, ror r2 +# CHECK: and r10, r1, r6, rrx + +# CHECK: and r1, r1, #15 +# CHECK: and r10, r10, r1 +# CHECK: and r10, r10, r1, lsl #10 +# CHECK: and r10, r10, r1, lsr #10 +# CHECK: and r10, r10, r1, lsr #10 +# CHECK: and r10, r10, r1, asr #10 +# CHECK: and r10, r10, r1, ror #10 +# CHECK: and r6, r6, r7, lsl r2 +# CHECK: and r6, r6, r7, lsr r2 +# CHECK: and r6, r6, r7, asr r2 +# CHECK: and r6, r6, r7, ror r2 +# CHECK: and r10, r10, r1, rrx + +0x0f 0xa0 0x01 0xe2 +0x06 0xa0 0x01 0xe0 +0x06 0xa5 0x01 0xe0 +0x26 0xa5 0x01 0xe0 +0x26 0xa5 0x01 0xe0 +0x46 0xa5 0x01 0xe0 +0x66 0xa5 0x01 0xe0 +0x18 0x62 0x07 0xe0 +0x38 0x62 0x07 0xe0 +0x58 0x62 0x07 0xe0 +0x78 0x62 0x07 0xe0 +0x66 0xa0 0x01 0xe0 + +0x0f 0x10 0x01 0xe2 +0x01 0xa0 0x0a 0xe0 +0x01 0xa5 0x0a 0xe0 +0x21 0xa5 0x0a 0xe0 +0x21 0xa5 0x0a 0xe0 +0x41 0xa5 0x0a 0xe0 +0x61 0xa5 0x0a 0xe0 +0x17 0x62 0x06 0xe0 +0x37 0x62 0x06 0xe0 +0x57 0x62 0x06 0xe0 +0x77 0x62 0x06 0xe0 +0x61 0xa0 0x0a 0xe0 + +#------------------------------------------------------------------------------ +# FIXME: ASR +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# BFC +#------------------------------------------------------------------------------ +# CHECK: bfc r5, #3, #17 +# CHECK: bfclo r5, #3, #17 + +0x9f 0x51 0xd3 0xe7 +0x9f 0x51 0xd3 0x37 + + +#------------------------------------------------------------------------------ +# BFI +#------------------------------------------------------------------------------ +# CHECK: bfi r5, r2, #3, #17 +# CHECK: bfine r5, r2, #3, #17 + +0x92 0x51 0xd3 0xe7 +0x92 0x51 0xd3 0x17 + + +#------------------------------------------------------------------------------ +# BIC +#------------------------------------------------------------------------------ +# CHECK: bic r10, r1, #15 +# CHECK: bic r10, r1, r6 +# CHECK: bic r10, r1, r6, lsl #10 +# CHECK: bic r10, r1, r6, lsr #10 +# CHECK: bic r10, r1, r6, lsr #10 +# CHECK: bic r10, r1, r6, asr #10 +# CHECK: bic r10, r1, r6, ror #10 +# CHECK: bic r6, r7, r8, lsl r2 +# CHECK: bic r6, r7, r8, lsr r2 +# CHECK: bic r6, r7, r8, asr r2 +# CHECK: bic r6, r7, r8, ror r2 +# CHECK: bic r10, r1, r6, rrx + +# CHECK: bic r1, r1, #15 +# CHECK: bic r10, r10, r1 +# CHECK: bic r10, r10, r1, lsl #10 +# CHECK: bic r10, r10, r1, lsr #10 +# CHECK: bic r10, r10, r1, lsr #10 +# CHECK: bic r10, r10, r1, asr #10 +# CHECK: bic r10, r10, r1, ror #10 +# CHECK: bic r6, r6, r7, lsl r2 +# CHECK: bic r6, r6, r7, lsr r2 +# CHECK: bic r6, r6, r7, asr r2 +# CHECK: bic r6, r6, r7, ror r2 +# CHECK: bic r10, r10, r1, rrx + +0x0f 0xa0 0xc1 0xe3 +0x06 0xa0 0xc1 0xe1 +0x06 0xa5 0xc1 0xe1 +0x26 0xa5 0xc1 0xe1 +0x26 0xa5 0xc1 0xe1 +0x46 0xa5 0xc1 0xe1 +0x66 0xa5 0xc1 0xe1 +0x18 0x62 0xc7 0xe1 +0x38 0x62 0xc7 0xe1 +0x58 0x62 0xc7 0xe1 +0x78 0x62 0xc7 0xe1 +0x66 0xa0 0xc1 0xe1 + + +0x0f 0x10 0xc1 0xe3 +0x01 0xa0 0xca 0xe1 +0x01 0xa5 0xca 0xe1 +0x21 0xa5 0xca 0xe1 +0x21 0xa5 0xca 0xe1 +0x41 0xa5 0xca 0xe1 +0x61 0xa5 0xca 0xe1 +0x17 0x62 0xc6 0xe1 +0x37 0x62 0xc6 0xe1 +0x57 0x62 0xc6 0xe1 +0x77 0x62 0xc6 0xe1 +0x61 0xa0 0xca 0xe1 + +#------------------------------------------------------------------------------ +# BKPT +#------------------------------------------------------------------------------ +# CHECK: bkpt #10 +# CHECK: bkpt #65535 + +0x7a 0x00 0x20 0xe1 +0x7f 0xff 0x2f 0xe1 + +#------------------------------------------------------------------------------ +# BLX (register) +#------------------------------------------------------------------------------ +# CHECK: blx r2 +# CHECK: blxne r2 + +0x32 0xff 0x2f 0xe1 +0x32 0xff 0x2f 0x11 + +#------------------------------------------------------------------------------ +# BLX (immediate) +#------------------------------------------------------------------------------ +# CHECK: blx #32424576 +# CHECK: blx #16212288 + +0xa0 0xb0 0x7b 0xfa +0x50 0xd8 0x3d 0xfa + +#------------------------------------------------------------------------------ +# BX +#------------------------------------------------------------------------------ + +# CHECK: bx r2 +# CHECK: bxne r2 + +0x12 0xff 0x2f 0xe1 +0x12 0xff 0x2f 0x11 + +#------------------------------------------------------------------------------ +# BXJ +#------------------------------------------------------------------------------ + +# CHECK: bxj r2 +# CHECK: bxjne r2 + +0x22 0xff 0x2f 0xe1 +0x22 0xff 0x2f 0x11 + + +#------------------------------------------------------------------------------ +# CDP/CDP2 +#------------------------------------------------------------------------------ +# CHECK: cdp p7, #1, c1, c1, c1, #4 +# CHECK: cdp2 p7, #1, c1, c1, c1, #4 + +0x81 0x17 0x11 0xee +0x81 0x17 0x11 0xfe + + +#------------------------------------------------------------------------------ +# CLREX +#------------------------------------------------------------------------------ +# CHECK: clrex + +0x1f 0xf0 0x7f 0xf5 + + +#------------------------------------------------------------------------------ +# CLZ +#------------------------------------------------------------------------------ +# CHECK: clz r1, r2 +# CHECK: clzeq r1, r2 + +0x12 0x1f 0x6f 0xe1 +0x12 0x1f 0x6f 0x01 + +#------------------------------------------------------------------------------ +# CMN +#------------------------------------------------------------------------------ +# CHECK: cmn r1, #15 +# CHECK: cmn r1, r6 +# CHECK: cmn r1, r6, lsl #10 +# CHECK: cmn r1, r6, lsr #10 +# CHECK: cmn sp, r6, lsr #10 +# CHECK: cmn r1, r6, asr #10 +# CHECK: cmn r1, r6, ror #10 +# CHECK: cmn r7, r8, lsl r2 +# CHECK: cmn sp, r8, lsr r2 +# CHECK: cmn r7, r8, asr r2 +# CHECK: cmn r7, r8, ror r2 +# CHECK: cmn r1, r6, rrx + +0x0f 0x00 0x71 0xe3 +0x06 0x00 0x71 0xe1 +0x06 0x05 0x71 0xe1 +0x26 0x05 0x71 0xe1 +0x26 0x05 0x7d 0xe1 +0x46 0x05 0x71 0xe1 +0x66 0x05 0x71 0xe1 +0x18 0x02 0x77 0xe1 +0x38 0x02 0x7d 0xe1 +0x58 0x02 0x77 0xe1 +0x78 0x02 0x77 0xe1 +0x66 0x00 0x71 0xe1 + +#------------------------------------------------------------------------------ +# CMP +#------------------------------------------------------------------------------ +# CHECK: cmp r1, #15 +# CHECK: cmp r1, r6 +# CHECK: cmp r1, r6, lsl #10 +# CHECK: cmp r1, r6, lsr #10 +# CHECK: cmp sp, r6, lsr #10 +# CHECK: cmp r1, r6, asr #10 +# CHECK: cmp r1, r6, ror #10 +# CHECK: cmp r7, r8, lsl r2 +# CHECK: cmp sp, r8, lsr r2 +# CHECK: cmp r7, r8, asr r2 +# CHECK: cmp r7, r8, ror r2 +# CHECK: cmp r1, r6, rrx + +0x0f 0x00 0x51 0xe3 +0x06 0x00 0x51 0xe1 +0x06 0x05 0x51 0xe1 +0x26 0x05 0x51 0xe1 +0x26 0x05 0x5d 0xe1 +0x46 0x05 0x51 0xe1 +0x66 0x05 0x51 0xe1 +0x18 0x02 0x57 0xe1 +0x38 0x02 0x5d 0xe1 +0x58 0x02 0x57 0xe1 +0x78 0x02 0x57 0xe1 +0x66 0x00 0x51 0xe1 + + +#------------------------------------------------------------------------------ +# CPS +#------------------------------------------------------------------------------ +# CHECK: cpsie aif +# CHECK: cps #15 +# CHECK: cpsid if, #10 + +0xc0 0x01 0x08 0xf1 +0x0f 0x00 0x02 0xf1 +0xca 0x00 0x0e 0xf1 + + +#------------------------------------------------------------------------------ +# DBG +#------------------------------------------------------------------------------ +# CHECK: dbg #0 +# CHECK: dbg #5 +# CHECK: dbg #15 + +0xf0 0xf0 0x20 0xe3 +0xf5 0xf0 0x20 0xe3 +0xff 0xf0 0x20 0xe3 + + +#------------------------------------------------------------------------------ +# DMB +#------------------------------------------------------------------------------ +# CHECK: dmb sy +# CHECK: dmb st +# CHECK: dmb ish +# CHECK: dmb ishst +# CHECK: dmb nsh +# CHECK: dmb nshst +# CHECK: dmb osh +# CHECK: dmb oshst +# CHECK: dmb + +0x5f 0xf0 0x7f 0xf5 +0x5e 0xf0 0x7f 0xf5 +0x5b 0xf0 0x7f 0xf5 +0x5a 0xf0 0x7f 0xf5 +0x57 0xf0 0x7f 0xf5 +0x56 0xf0 0x7f 0xf5 +0x53 0xf0 0x7f 0xf5 +0x52 0xf0 0x7f 0xf5 +0x5f 0xf0 0x7f 0xf5 + +#------------------------------------------------------------------------------ +# DSB +#------------------------------------------------------------------------------ +# CHECK: dsb sy +# CHECK: dsb st +# CHECK: dsb ish +# CHECK: dsb ishst +# CHECK: dsb nsh +# CHECK: dsb nshst +# CHECK: dsb osh +# CHECK: dsb oshst +# CHECK: dsb + +0x4f 0xf0 0x7f 0xf5 +0x4e 0xf0 0x7f 0xf5 +0x4b 0xf0 0x7f 0xf5 +0x4a 0xf0 0x7f 0xf5 +0x47 0xf0 0x7f 0xf5 +0x46 0xf0 0x7f 0xf5 +0x43 0xf0 0x7f 0xf5 +0x42 0xf0 0x7f 0xf5 +0x4f 0xf0 0x7f 0xf5 + +#------------------------------------------------------------------------------ +# EOR +#------------------------------------------------------------------------------ +# CHECK: eor r4, r5, #61440 +# CHECK: eor r4, r5, r6 +# CHECK: eor r4, r5, r6, lsl #5 +# CHECK: eor r4, r5, r6, lsr #5 +# CHECK: eor r4, r5, r6, lsr #5 +# CHECK: eor r4, r5, r6, asr #5 +# CHECK: eor r4, r5, r6, ror #5 +# CHECK: eor r6, r7, r8, lsl r9 +# CHECK: eor r6, r7, r8, lsr r9 +# CHECK: eor r6, r7, r8, asr r9 +# CHECK: eor r6, r7, r8, ror r9 +# CHECK: eor r4, r5, r6, rrx + +# CHECK: eor r5, r5, #61440 +# CHECK: eor r4, r4, r5 +# CHECK: eor r4, r4, r5, lsl #5 +# CHECK: eor r4, r4, r5, lsr #5 +# CHECK: eor r4, r4, r5, lsr #5 +# CHECK: eor r4, r4, r5, asr #5 +# CHECK: eor r4, r4, r5, ror #5 +# CHECK: eor r6, r6, r7, lsl r9 +# CHECK: eor r6, r6, r7, lsr r9 +# CHECK: eor r6, r6, r7, asr r9 +# CHECK: eor r6, r6, r7, ror r9 +# CHECK: eor r4, r4, r5, rrx + +0x0f 0x4a 0x25 0xe2 +0x06 0x40 0x25 0xe0 +0x86 0x42 0x25 0xe0 +0xa6 0x42 0x25 0xe0 +0xa6 0x42 0x25 0xe0 +0xc6 0x42 0x25 0xe0 +0xe6 0x42 0x25 0xe0 +0x18 0x69 0x27 0xe0 +0x38 0x69 0x27 0xe0 +0x58 0x69 0x27 0xe0 +0x78 0x69 0x27 0xe0 +0x66 0x40 0x25 0xe0 + + +0x0f 0x5a 0x25 0xe2 +0x05 0x40 0x24 0xe0 +0x85 0x42 0x24 0xe0 +0xa5 0x42 0x24 0xe0 +0xa5 0x42 0x24 0xe0 +0xc5 0x42 0x24 0xe0 +0xe5 0x42 0x24 0xe0 +0x17 0x69 0x26 0xe0 +0x37 0x69 0x26 0xe0 +0x57 0x69 0x26 0xe0 +0x77 0x69 0x26 0xe0 +0x65 0x40 0x24 0xe0 + + +#------------------------------------------------------------------------------ +# ISB +#------------------------------------------------------------------------------ +# CHECK: isb sy + +0x6f 0xf0 0x7f 0xf5 + + + +#------------------------------------------------------------------------------ +# LDM* +#------------------------------------------------------------------------------ +# CHECK: ldm r2, {r1, r3, r4, r5, r6, sp} +# CHECK: ldmib r2, {r1, r3, r4, r5, r6, sp} +# CHECK: ldmda r2, {r1, r3, r4, r5, r6, sp} +# CHECK: ldmdb r2, {r1, r3, r4, r5, r6, sp} + + +# CHECK: ldm r2!, {r1, r3, r4, r5, r6, sp} +# CHECK: ldmib r2!, {r1, r3, r4, r5, r6, sp} +# CHECK: ldmda r2!, {r1, r3, r4, r5, r6, sp} +# CHECK: ldmdb r2!, {r1, r3, r4, r5, r6, sp} + +0x7a 0x20 0x92 0xe8 +0x7a 0x20 0x92 0xe9 +0x7a 0x20 0x12 0xe8 +0x7a 0x20 0x12 0xe9 + +0x7a 0x20 0xb2 0xe8 +0x7a 0x20 0xb2 0xe9 +0x7a 0x20 0x32 0xe8 +0x7a 0x20 0x32 0xe9 + + +#------------------------------------------------------------------------------ +# LDREX/LDREXB/LDREXH/LDREXD +#------------------------------------------------------------------------------ +# CHECK: ldrexb r3, [r4] +# CHECK: ldrexh r2, [r5] +# CHECK: ldrex r1, [r7] +# CHECK: ldrexd r6, r7, [r8] + +0x9f 0x3f 0xd4 0xe1 +0x9f 0x2f 0xf5 0xe1 +0x9f 0x1f 0x97 0xe1 +0x9f 0x6f 0xb8 0xe1 + + +#------------------------------------------------------------------------------ +# FIXME: LSL +#------------------------------------------------------------------------------ +#------------------------------------------------------------------------------ +# FIXME: LSR +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# MCR/MCR2 +#------------------------------------------------------------------------------ +# CHECK: mcr p7, #1, r5, c1, c1, #4 +# CHECK: mcr2 p7, #1, r5, c1, c1, #4 + +0x91 0x57 0x21 0xee +0x91 0x57 0x21 0xfe + +#------------------------------------------------------------------------------ +# MCRR/MCRR2 +#------------------------------------------------------------------------------ +# CHECK: mcrr p7, #15, r5, r4, c1 +# CHECK: mcrr2 p7, #15, r5, r4, c1 + +0xf1 0x57 0x44 0xec +0xf1 0x57 0x44 0xfc + + +#------------------------------------------------------------------------------ +# MLA +#------------------------------------------------------------------------------ +# CHECK: mla r1, r2, r3, r4 +# CHECK: mlas r1, r2, r3, r4 +# CHECK: mlane r1, r2, r3, r4 +# CHECK: mlasne r1, r2, r3, r4 + +0x92 0x43 0x21 0xe0 +0x92 0x43 0x31 0xe0 +0x92 0x43 0x21 0x10 +0x92 0x43 0x31 0x10 + +#------------------------------------------------------------------------------ +# MLS +#------------------------------------------------------------------------------ +# CHECK: mls r2, r5, r6, r3 +# CHECK: mlsne r2, r5, r6, r3 + +0x95 0x36 0x62 0xe0 +0x95 0x36 0x62 0x10 + +#------------------------------------------------------------------------------ +# MOV (immediate) +#------------------------------------------------------------------------------ +# CHECK: mov r3, #7 +# CHECK: mov r4, #4080 +# CHECK: mov r5, #16711680 +# CHECK: movw r6, #65535 +# CHECK: movw r9, #65535 +# CHECK: movs r3, #7 +# CHECK: moveq r4, #4080 +# CHECK: movseq r5, #16711680 + +0x07 0x30 0xa0 0xe3 +0xff 0x4e 0xa0 0xe3 +0xff 0x58 0xa0 0xe3 +0xff 0x6f 0x0f 0xe3 +0xff 0x9f 0x0f 0xe3 +0x07 0x30 0xb0 0xe3 +0xff 0x4e 0xa0 0x03 +0xff 0x58 0xb0 0x03 + +#------------------------------------------------------------------------------ +# MOV (register) +#------------------------------------------------------------------------------ +# CHECK: mov r2, r3 +# CHECK: movs r2, r3 +# CHECK: moveq r2, r3 +# CHECK: movseq r2, r3 + +0x03 0x20 0xa0 0xe1 +0x03 0x20 0xb0 0xe1 +0x03 0x20 0xa0 0x01 +0x03 0x20 0xb0 0x01 + +#------------------------------------------------------------------------------ +# MOVT +#------------------------------------------------------------------------------ +# CHECK: movt r3, #7 +# CHECK: movt r6, #65535 +# CHECK: movteq r4, #4080 + +0x07 0x30 0x40 0xe3 +0xff 0x6f 0x4f 0xe3 +0xf0 0x4f 0x40 0x03 + + +#------------------------------------------------------------------------------ +# MRC/MRC2 +#------------------------------------------------------------------------------ +# CHECK: mrc p14, #0, r1, c1, c2, #4 +# CHECK: mrc2 p14, #0, r1, c1, c2, #4 + +0x92 0x1e 0x11 0xee +0x92 0x1e 0x11 0xfe + +#------------------------------------------------------------------------------ +# MRRC/MRRC2 +#------------------------------------------------------------------------------ +# CHECK: mrrc p7, #1, r5, r4, c1 +# CHECK: mrrc2 p7, #1, r5, r4, c1 + +0x11 0x57 0x54 0xec +0x11 0x57 0x54 0xfc + + +#------------------------------------------------------------------------------ +# MRS +#------------------------------------------------------------------------------ +# CHECK: mrs r8, apsr +# CHECK: mrs r8, spsr +0x00 0x80 0x0f 0xe1 +0x00 0x80 0x4f 0xe1 + + + +#------------------------------------------------------------------------------ +# MSR +#------------------------------------------------------------------------------ + +# CHECK: msr CPSR_fc, #5 +# CHECK: msr APSR_g, #5 +# CHECK: msr APSR_nzcvq, #5 +# CHECK: msr APSR_nzcvq, #5 +# CHECK: msr APSR_nzcvqg, #5 +# CHECK: msr CPSR_fc, #5 +# CHECK: msr CPSR_c, #5 +# CHECK: msr CPSR_x, #5 +# CHECK: msr CPSR_fc, #5 +# CHECK: msr CPSR_fc, #5 +# CHECK: msr CPSR_fsx, #5 +# CHECK: msr SPSR_fc, #5 +# CHECK: msr SPSR_fsxc, #5 +# CHECK: msr CPSR_fsxc, #5 + +0x05 0xf0 0x29 0xe3 +0x05 0xf0 0x24 0xe3 +0x05 0xf0 0x28 0xe3 +0x05 0xf0 0x28 0xe3 +0x05 0xf0 0x2c 0xe3 +0x05 0xf0 0x29 0xe3 +0x05 0xf0 0x21 0xe3 +0x05 0xf0 0x22 0xe3 +0x05 0xf0 0x29 0xe3 +0x05 0xf0 0x29 0xe3 +0x05 0xf0 0x2e 0xe3 +0x05 0xf0 0x69 0xe3 +0x05 0xf0 0x6f 0xe3 +0x05 0xf0 0x2f 0xe3 + +# CHECK: msr CPSR_fc, r0 +# CHECK: msr APSR_g, r0 +# CHECK: msr APSR_nzcvq, r0 +# CHECK: msr APSR_nzcvq, r0 +# CHECK: msr APSR_nzcvqg, r0 +# CHECK: msr CPSR_fc, r0 +# CHECK: msr CPSR_c, r0 +# CHECK: msr CPSR_x, r0 +# CHECK: msr CPSR_fc, r0 +# CHECK: msr CPSR_fc, r0 +# CHECK: msr CPSR_fsx, r0 +# CHECK: msr SPSR_fc, r0 +# CHECK: msr SPSR_fsxc, r0 +# CHECK: msr CPSR_fsxc, r0 + +0x00 0xf0 0x29 0xe1 +0x00 0xf0 0x24 0xe1 +0x00 0xf0 0x28 0xe1 +0x00 0xf0 0x28 0xe1 +0x00 0xf0 0x2c 0xe1 +0x00 0xf0 0x29 0xe1 +0x00 0xf0 0x21 0xe1 +0x00 0xf0 0x22 0xe1 +0x00 0xf0 0x29 0xe1 +0x00 0xf0 0x29 0xe1 +0x00 0xf0 0x2e 0xe1 +0x00 0xf0 0x69 0xe1 +0x00 0xf0 0x6f 0xe1 +0x00 0xf0 0x2f 0xe1 + +#------------------------------------------------------------------------------ +# MUL +#------------------------------------------------------------------------------ + +# CHECK: mul r5, r6, r7 +# CHECK: muls r5, r6, r7 +# CHECK: mulgt r5, r6, r7 +# CHECK: mulsle r5, r6, r7 + +0x96 0x07 0x05 0xe0 +0x96 0x07 0x15 0xe0 +0x96 0x07 0x05 0xc0 +0x96 0x07 0x15 0xd0 + + +#------------------------------------------------------------------------------ +# MVN (immediate) +#------------------------------------------------------------------------------ +# CHECK: mvn r3, #7 +# CHECK: mvn r4, #4080 +# CHECK: mvn r5, #16711680 +# CHECK: mvns r3, #7 +# CHECK: mvneq r4, #4080 +# CHECK: mvnseq r5, #16711680 + +0x07 0x30 0xe0 0xe3 +0xff 0x4e 0xe0 0xe3 +0xff 0x58 0xe0 0xe3 +0x07 0x30 0xf0 0xe3 +0xff 0x4e 0xe0 0x03 +0xff 0x58 0xf0 0x03 + + +#------------------------------------------------------------------------------ +# MVN (register) +#------------------------------------------------------------------------------ +# CHECK: mvn r2, r3 +# CHECK: mvns r2, r3 +# CHECK: mvn r5, r6, lsl #19 +# CHECK: mvn r5, r6, lsr #9 +# CHECK: mvn r5, r6, asr #4 +# CHECK: mvn r5, r6, ror #6 +# CHECK: mvn r5, r6, rrx +# CHECK: mvneq r2, r3 +# CHECK: mvnseq r2, r3, lsl #10 + +0x03 0x20 0xe0 0xe1 +0x03 0x20 0xf0 0xe1 +0x86 0x59 0xe0 0xe1 +0xa6 0x54 0xe0 0xe1 +0x46 0x52 0xe0 0xe1 +0x66 0x53 0xe0 0xe1 +0x66 0x50 0xe0 0xe1 +0x03 0x20 0xe0 0x01 +0x03 0x25 0xf0 0x01 + + +#------------------------------------------------------------------------------ +# MVN (shifted register) +#------------------------------------------------------------------------------ +# CHECK: mvn r5, r6, lsl r7 +# CHECK: mvns r5, r6, lsr r7 +# CHECK: mvngt r5, r6, asr r7 +# CHECK: mvnslt r5, r6, ror r7 + +0x16 0x57 0xe0 0xe1 +0x36 0x57 0xf0 0xe1 +0x56 0x57 0xe0 0xc1 +0x76 0x57 0xf0 0xb1 + +#------------------------------------------------------------------------------ +# NOP +#------------------------------------------------------------------------------ +# CHECK: nop +# CHECK: nopgt + +0x00 0xf0 0x20 0xe3 +0x00 0xf0 0x20 0xc3 + + +#------------------------------------------------------------------------------ +# ORR +#------------------------------------------------------------------------------ +# CHECK: orr r4, r5, #61440 +# CHECK: orr r4, r5, r6 +# CHECK: orr r4, r5, r6, lsl #5 +# CHECK: orr r4, r5, r6, lsr #5 +# CHECK: orr r4, r5, r6, lsr #5 +# CHECK: orr r4, r5, r6, asr #5 +# CHECK: orr r4, r5, r6, ror #5 +# CHECK: orr r6, r7, r8, lsl r9 +# CHECK: orr r6, r7, r8, lsr r9 +# CHECK: orr r6, r7, r8, asr r9 +# CHECK: orr r6, r7, r8, ror r9 +# CHECK: orr r4, r5, r6, rrx + +# CHECK: orr r5, r5, #61440 +# CHECK: orr r4, r4, r5 +# CHECK: orr r4, r4, r5, lsl #5 +# CHECK: orr r4, r4, r5, lsr #5 +# CHECK: orr r4, r4, r5, lsr #5 +# CHECK: orr r4, r4, r5, asr #5 +# CHECK: orr r4, r4, r5, ror #5 +# CHECK: orr r6, r6, r7, lsl r9 +# CHECK: orr r6, r6, r7, lsr r9 +# CHECK: orr r6, r6, r7, asr r9 +# CHECK: orr r6, r6, r7, ror r9 +# CHECK: orr r4, r4, r5, rrx + +0x0f 0x4a 0x85 0xe3 +0x06 0x40 0x85 0xe1 +0x86 0x42 0x85 0xe1 +0xa6 0x42 0x85 0xe1 +0xa6 0x42 0x85 0xe1 +0xc6 0x42 0x85 0xe1 +0xe6 0x42 0x85 0xe1 +0x18 0x69 0x87 0xe1 +0x38 0x69 0x87 0xe1 +0x58 0x69 0x87 0xe1 +0x78 0x69 0x87 0xe1 +0x66 0x40 0x85 0xe1 + +0x0f 0x5a 0x85 0xe3 +0x05 0x40 0x84 0xe1 +0x85 0x42 0x84 0xe1 +0xa5 0x42 0x84 0xe1 +0xa5 0x42 0x84 0xe1 +0xc5 0x42 0x84 0xe1 +0xe5 0x42 0x84 0xe1 +0x17 0x69 0x86 0xe1 +0x37 0x69 0x86 0xe1 +0x57 0x69 0x86 0xe1 +0x77 0x69 0x86 0xe1 +0x65 0x40 0x84 0xe1 + +# CHECK: orrseq r4, r5, #61440 +# CHECK: orrne r4, r5, r6 +# CHECK: orrseq r4, r5, r6, lsl #5 +# CHECK: orrlo r6, r7, r8, ror r9 +# CHECK: orrshi r4, r5, r6, rrx +# CHECK: orrhs r5, r5, #61440 +# CHECK: orrseq r4, r4, r5 +# CHECK: orrne r6, r6, r7, asr r9 +# CHECK: orrslt r6, r6, r7, ror r9 +# CHECK: orrsgt r4, r4, r5, rrx + +0x0f 0x4a 0x95 0x03 +0x06 0x40 0x85 0x11 +0x86 0x42 0x95 0x01 +0x78 0x69 0x87 0x31 +0x66 0x40 0x95 0x81 +0x0f 0x5a 0x85 0x23 +0x05 0x40 0x94 0x01 +0x57 0x69 0x86 0x11 +0x77 0x69 0x96 0xb1 +0x65 0x40 0x94 0xc1 + +#------------------------------------------------------------------------------ +# PKH +#------------------------------------------------------------------------------ +# CHECK: pkhbt r2, r2, r3 +# CHECK: pkhbt r2, r2, r3, lsl #31 +# CHECK: pkhbt r2, r2, r3 +# CHECK: pkhbt r2, r2, r3, lsl #15 + +# CHECK: pkhbt r2, r2, r3 +# CHECK: pkhtb r2, r2, r3, asr #31 +# CHECK: pkhtb r2, r2, r3, asr #15 + +0x13 0x20 0x82 0xe6 +0x93 0x2f 0x82 0xe6 +0x13 0x20 0x82 0xe6 +0x93 0x27 0x82 0xe6 + +0x13 0x20 0x82 0xe6 +0xd3 0x2f 0x82 0xe6 +0xd3 0x27 0x82 0xe6 + +#------------------------------------------------------------------------------ +# FIXME: PLD +#------------------------------------------------------------------------------ +#------------------------------------------------------------------------------ +# FIXME: PLI +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# POP +#------------------------------------------------------------------------------ +# CHECK: ldr r7, [sp], #4 +# CHECK: pop {r7, r8, r9, r10} + +0x04 0x70 0x9d 0xe4 +0x80 0x07 0xbd 0xe8 + + +#------------------------------------------------------------------------------ +# PUSH +#------------------------------------------------------------------------------ +# CHECK: str r7, [sp, #-4]! +# CHECK: push {r7, r8, r9, r10} + +0x04 0x70 0x2d 0xe5 +0x80 0x07 0x2d 0xe9 + + +#------------------------------------------------------------------------------ +# QADD/QADD16/QADD8 +#------------------------------------------------------------------------------ +# CHECK: qadd r1, r2, r3 +# CHECK: qaddne r1, r2, r3 +# CHECK: qadd16 r1, r2, r3 +# CHECK: qadd16gt r1, r2, r3 +# CHECK: qadd8 r1, r2, r3 +# CHECK: qadd8le r1, r2, r3 + +0x52 0x10 0x03 0xe1 +0x52 0x10 0x03 0x11 +0x13 0x1f 0x22 0xe6 +0x13 0x1f 0x22 0xc6 +0x93 0x1f 0x22 0xe6 +0x93 0x1f 0x22 0xd6 + + +#------------------------------------------------------------------------------ +# QDADD/QDSUB +#------------------------------------------------------------------------------ +# CHECK: qdadd r6, r7, r8 +# CHECK: qdaddhi r6, r7, r8 +# CHECK: qdsub r6, r7, r8 +# CHECK: qdsubhi r6, r7, r8 + +0x57 0x60 0x48 0xe1 +0x57 0x60 0x48 0x81 +0x57 0x60 0x68 0xe1 +0x57 0x60 0x68 0x81 + + +#------------------------------------------------------------------------------ +# QSAX +#------------------------------------------------------------------------------ +# CHECK: qsax r9, r12, r0 +# CHECK: qsaxeq r9, r12, r0 + +0x50 0x9f 0x2c 0xe6 +0x50 0x9f 0x2c 0x06 + + +#------------------------------------------------------------------------------ +# QSUB/QSUB16/QSUB8 +#------------------------------------------------------------------------------ +# CHECK: qsub r1, r2, r3 +# CHECK: qsubne r1, r2, r3 +# CHECK: qsub16 r1, r2, r3 +# CHECK: qsub16gt r1, r2, r3 +# CHECK: qsub8 r1, r2, r3 +# CHECK: qsub8le r1, r2, r3 + +0x52 0x10 0x23 0xe1 +0x52 0x10 0x23 0x11 +0x73 0x1f 0x22 0xe6 +0x73 0x1f 0x22 0xc6 +0xf3 0x1f 0x22 0xe6 +0xf3 0x1f 0x22 0xd6 + + +#------------------------------------------------------------------------------ +# RBIT +#------------------------------------------------------------------------------ +# CHECK: rbit r1, r2 +# CHECK: rbitne r1, r2 + +0x32 0x1f 0xff 0xe6 +0x32 0x1f 0xff 0x16 + + +#------------------------------------------------------------------------------ +# REV/REV16/REVSH +#------------------------------------------------------------------------------ +# CHECK: rev r1, r9 +# CHECK: revne r1, r5 +# CHECK: rev16 r8, r3 +# CHECK: rev16ne r12, r4 +# CHECK: revsh r4, r9 +# CHECK: revshne r9, r1 + +0x39 0x1f 0xbf 0xe6 +0x35 0x1f 0xbf 0x16 +0xb3 0x8f 0xbf 0xe6 +0xb4 0xcf 0xbf 0x16 +0xb9 0x4f 0xff 0xe6 +0xb1 0x9f 0xff 0x16 + + +#------------------------------------------------------------------------------ +# RFE +#------------------------------------------------------------------------------ +# CHECK: rfeda r2 +# CHECK: rfedb r3 +# CHECK: rfeia r5 +# CHECK: rfeib r6 + +# CHECK: rfeda r4! +# CHECK: rfedb r7! +# CHECK: rfeia r9! +# CHECK: rfeib r8! + +# CHECK: rfeda r2 +# CHECK: rfedb r3 +# CHECK: rfeia r5 +# CHECK: rfeib r6 + +# CHECK: rfeda r4! +# CHECK: rfedb r7! +# CHECK: rfeia r9! +# CHECK: rfeib r8! + +# CHECK: rfeia r1 +# CHECK: rfeia r1! + +0x00 0x0a 0x12 0xf8 +0x00 0x0a 0x13 0xf9 +0x00 0x0a 0x95 0xf8 +0x00 0x0a 0x96 0xf9 + +0x00 0x0a 0x34 0xf8 +0x00 0x0a 0x37 0xf9 +0x00 0x0a 0xb9 0xf8 +0x00 0x0a 0xb8 0xf9 + +0x00 0x0a 0x12 0xf8 +0x00 0x0a 0x13 0xf9 +0x00 0x0a 0x95 0xf8 +0x00 0x0a 0x96 0xf9 + +0x00 0x0a 0x34 0xf8 +0x00 0x0a 0x37 0xf9 +0x00 0x0a 0xb9 0xf8 +0x00 0x0a 0xb8 0xf9 + +0x00 0x0a 0x91 0xf8 +0x00 0x0a 0xb1 0xf8 + + +#------------------------------------------------------------------------------ +# RSB +#------------------------------------------------------------------------------ +# CHECK: rsb r4, r5, #61440 +# CHECK: rsb r4, r5, r6 +# CHECK: rsb r4, r5, r6, lsl #5 +# CHECK: rsblo r4, r5, r6, lsr #5 +# CHECK: rsb r4, r5, r6, lsr #5 +# CHECK: rsb r4, r5, r6, asr #5 +# CHECK: rsb r4, r5, r6, ror #5 +# CHECK: rsb r6, r7, r8, lsl r9 +# CHECK: rsb r6, r7, r8, lsr r9 +# CHECK: rsb r6, r7, r8, asr r9 +# CHECK: rsble r6, r7, r8, ror r9 +# CHECK: rsb r4, r5, r6, rrx + +# CHECK: rsb r5, r5, #61440 +# CHECK: rsb r4, r4, r5 +# CHECK: rsb r4, r4, r5, lsl #5 +# CHECK: rsb r4, r4, r5, lsr #5 +# CHECK: rsbne r4, r4, r5, lsr #5 +# CHECK: rsb r4, r4, r5, asr #5 +# CHECK: rsb r4, r4, r5, ror #5 +# CHECK: rsbgt r6, r6, r7, lsl r9 +# CHECK: rsb r6, r6, r7, lsr r9 +# CHECK: rsb r6, r6, r7, asr r9 +# CHECK: rsb r6, r6, r7, ror r9 +# CHECK: rsb r4, r4, r5, rrx + +0x0f 0x4a 0x65 0xe2 +0x06 0x40 0x65 0xe0 +0x86 0x42 0x65 0xe0 +0xa6 0x42 0x65 0x30 +0xa6 0x42 0x65 0xe0 +0xc6 0x42 0x65 0xe0 +0xe6 0x42 0x65 0xe0 +0x18 0x69 0x67 0xe0 +0x38 0x69 0x67 0xe0 +0x58 0x69 0x67 0xe0 +0x78 0x69 0x67 0xd0 +0x66 0x40 0x65 0xe0 + +0x0f 0x5a 0x65 0xe2 +0x05 0x40 0x64 0xe0 +0x85 0x42 0x64 0xe0 +0xa5 0x42 0x64 0xe0 +0xa5 0x42 0x64 0x10 +0xc5 0x42 0x64 0xe0 +0xe5 0x42 0x64 0xe0 +0x17 0x69 0x66 0xc0 +0x37 0x69 0x66 0xe0 +0x57 0x69 0x66 0xe0 +0x77 0x69 0x66 0xe0 +0x65 0x40 0x64 0xe0 + +#------------------------------------------------------------------------------ +# RSC +#------------------------------------------------------------------------------ +# CHECK: rsc r4, r5, #61440 +# CHECK: rsc r4, r5, r6 +# CHECK: rsc r4, r5, r6, lsl #5 +# CHECK: rsclo r4, r5, r6, lsr #5 +# CHECK: rsc r4, r5, r6, lsr #5 +# CHECK: rsc r4, r5, r6, asr #5 +# CHECK: rsc r4, r5, r6, ror #5 +# CHECK: rsc r6, r7, r8, lsl r9 +# CHECK: rsc r6, r7, r8, lsr r9 +# CHECK: rsc r6, r7, r8, asr r9 +# CHECK: rscle r6, r7, r8, ror r9 + +# CHECK: rsc r5, r5, #61440 +# CHECK: rsc r4, r4, r5 +# CHECK: rsc r4, r4, r5, lsl #5 +# CHECK: rsc r4, r4, r5, lsr #5 +# CHECK: rscne r4, r4, r5, lsr #5 +# CHECK: rsc r4, r4, r5, asr #5 +# CHECK: rsc r4, r4, r5, ror #5 +# CHECK: rscgt r6, r6, r7, lsl r9 +# CHECK: rsc r6, r6, r7, lsr r9 +# CHECK: rsc r6, r6, r7, asr r9 +# CHECK: rsc r6, r6, r7, ror r9 + +0x0f 0x4a 0xe5 0xe2 +0x06 0x40 0xe5 0xe0 +0x86 0x42 0xe5 0xe0 +0xa6 0x42 0xe5 0x30 +0xa6 0x42 0xe5 0xe0 +0xc6 0x42 0xe5 0xe0 +0xe6 0x42 0xe5 0xe0 +0x18 0x69 0xe7 0xe0 +0x38 0x69 0xe7 0xe0 +0x58 0x69 0xe7 0xe0 +0x78 0x69 0xe7 0xd0 + +0x0f 0x5a 0xe5 0xe2 +0x05 0x40 0xe4 0xe0 +0x85 0x42 0xe4 0xe0 +0xa5 0x42 0xe4 0xe0 +0xa5 0x42 0xe4 0x10 +0xc5 0x42 0xe4 0xe0 +0xe5 0x42 0xe4 0xe0 +0x17 0x69 0xe6 0xc0 +0x37 0x69 0xe6 0xe0 +0x57 0x69 0xe6 0xe0 +0x77 0x69 0xe6 0xe0 + +#------------------------------------------------------------------------------ +# SADD16/SADD8 +#------------------------------------------------------------------------------ +# CHECK: sadd16 r1, r2, r3 +# CHECK: sadd16gt r1, r2, r3 +# CHECK: sadd8 r1, r2, r3 +# CHECK: sadd8le r1, r2, r3 + +0x13 0x1f 0x12 0xe6 +0x13 0x1f 0x12 0xc6 +0x93 0x1f 0x12 0xe6 +0x93 0x1f 0x12 0xd6 + + +#------------------------------------------------------------------------------ +# SASX +#------------------------------------------------------------------------------ +# CHECK: sasx r9, r12, r0 +# CHECK: sasxeq r9, r12, r0 + +0x30 0x9f 0x1c 0xe6 +0x30 0x9f 0x1c 0x06 + + +#------------------------------------------------------------------------------ +# SBC +#------------------------------------------------------------------------------ +# CHECK: sbc r4, r5, #61440 +# CHECK: sbc r4, r5, r6 +# CHECK: sbc r4, r5, r6, lsl #5 +# CHECK: sbc r4, r5, r6, lsr #5 +# CHECK: sbc r4, r5, r6, lsr #5 +# CHECK: sbc r4, r5, r6, asr #5 +# CHECK: sbc r4, r5, r6, ror #5 +# CHECK: sbc r6, r7, r8, lsl r9 +# CHECK: sbc r6, r7, r8, lsr r9 +# CHECK: sbc r6, r7, r8, asr r9 +# CHECK: sbc r6, r7, r8, ror r9 + +# CHECK: sbc r5, r5, #61440 +# CHECK: sbc r4, r4, r5 +# CHECK: sbc r4, r4, r5, lsl #5 +# CHECK: sbc r4, r4, r5, lsr #5 +# CHECK: sbc r4, r4, r5, lsr #5 +# CHECK: sbc r4, r4, r5, asr #5 +# CHECK: sbc r4, r4, r5, ror #5 +# CHECK: sbc r6, r6, r7, lsl r9 +# CHECK: sbc r6, r6, r7, lsr r9 +# CHECK: sbc r6, r6, r7, asr r9 +# CHECK: sbc r6, r6, r7, ror r9 + +0x0f 0x4a 0xc5 0xe2 +0x06 0x40 0xc5 0xe0 +0x86 0x42 0xc5 0xe0 +0xa6 0x42 0xc5 0xe0 +0xa6 0x42 0xc5 0xe0 +0xc6 0x42 0xc5 0xe0 +0xe6 0x42 0xc5 0xe0 +0x18 0x69 0xc7 0xe0 +0x38 0x69 0xc7 0xe0 +0x58 0x69 0xc7 0xe0 +0x78 0x69 0xc7 0xe0 + +0x0f 0x5a 0xc5 0xe2 +0x05 0x40 0xc4 0xe0 +0x85 0x42 0xc4 0xe0 +0xa5 0x42 0xc4 0xe0 +0xa5 0x42 0xc4 0xe0 +0xc5 0x42 0xc4 0xe0 +0xe5 0x42 0xc4 0xe0 +0x17 0x69 0xc6 0xe0 +0x37 0x69 0xc6 0xe0 +0x57 0x69 0xc6 0xe0 +0x77 0x69 0xc6 0xe0 + + +#------------------------------------------------------------------------------ +# SBFX +#------------------------------------------------------------------------------ +# CHECK: sbfx r4, r5, #16, #1 +# CHECK: sbfxgt r4, r5, #16, #16 + +0x55 0x48 0xa0 0xe7 +0x55 0x48 0xaf 0xc7 + + +#------------------------------------------------------------------------------ +# SEL +#------------------------------------------------------------------------------ +# CHECK: sel r9, r2, r1 +# CHECK: selne r9, r2, r1 + +0xb1 0x9f 0x82 0xe6 +0xb1 0x9f 0x82 0x16 + + +#------------------------------------------------------------------------------ +# SETEND +#------------------------------------------------------------------------------ +# CHECK: setend be +# CHECK: setend le + +0x00 0x02 0x01 0xf1 +0x00 0x00 0x01 0xf1 + +#------------------------------------------------------------------------------ +# SEV +#------------------------------------------------------------------------------ +# CHECK: sev +# CHECK: seveq + +0x04 0xf0 0x20 0xe3 +0x04 0xf0 0x20 0x03 + +#------------------------------------------------------------------------------ +# SHADD16/SHADD8 +#------------------------------------------------------------------------------ +# CHECK: shadd16 r4, r8, r2 +# CHECK: shadd16gt r4, r8, r2 +# CHECK: shadd8 r4, r8, r2 +# CHECK: shadd8gt r4, r8, r2 + +0x12 0x4f 0x38 0xe6 +0x12 0x4f 0x38 0xc6 +0x92 0x4f 0x38 0xe6 +0x92 0x4f 0x38 0xc6 + + +#------------------------------------------------------------------------------ +# SHASX +#------------------------------------------------------------------------------ +# CHECK: shasx r4, r8, r2 +# CHECK: shasxgt r4, r8, r2 + +0x32 0x4f 0x38 0xe6 +0x32 0x4f 0x38 0xc6 + + +#------------------------------------------------------------------------------ +# SHSUB16/SHSUB8 +#------------------------------------------------------------------------------ +# CHECK: shsub16 r4, r8, r2 +# CHECK: shsub16gt r4, r8, r2 +# CHECK: shsub8 r4, r8, r2 +# CHECK: shsub8gt r4, r8, r2 + +0x72 0x4f 0x38 0xe6 +0x72 0x4f 0x38 0xc6 +0xf2 0x4f 0x38 0xe6 +0xf2 0x4f 0x38 0xc6 + +#------------------------------------------------------------------------------ +# SMC +#------------------------------------------------------------------------------ +# CHECK: smc #15 +# CHECK: smceq #0 + +0x7f 0x00 0x60 0xe1 +0x70 0x00 0x60 0x01 + +#------------------------------------------------------------------------------ +# SMLABB/SMLABT/SMLATB/SMLATT +#------------------------------------------------------------------------------ +# CHECK: smlabb r3, r1, r9, r0 +# CHECK: smlabt r5, r6, r4, r1 +# CHECK: smlatb r4, r2, r3, r2 +# CHECK: smlatt r8, r3, r8, r4 +# CHECK: smlabbge r3, r1, r9, r0 +# CHECK: smlabtle r5, r6, r4, r1 +# CHECK: smlatbne r4, r2, r3, r2 +# CHECK: smlatteq r8, r3, r8, r4 + +0x81 0x09 0x03 0xe1 +0xc6 0x14 0x05 0xe1 +0xa2 0x23 0x04 0xe1 +0xe3 0x48 0x08 0xe1 +0x81 0x09 0x03 0xa1 +0xc6 0x14 0x05 0xd1 +0xa2 0x23 0x04 0x11 +0xe3 0x48 0x08 0x01 + +#------------------------------------------------------------------------------ +# SMLAD/SMLADX +#------------------------------------------------------------------------------ +# CHECK: smlad r2, r3, r5, r8 +# CHECK: smladx r2, r3, r5, r8 +# CHECK: smladeq r2, r3, r5, r8 +# CHECK: smladxhi r2, r3, r5, r8 + +0x13 0x85 0x02 0xe7 +0x33 0x85 0x02 0xe7 +0x13 0x85 0x02 0x07 +0x33 0x85 0x02 0x87 + + +#------------------------------------------------------------------------------ +# SMLAL +#------------------------------------------------------------------------------ +# CHECK: smlal r2, r3, r5, r8 +# CHECK: smlals r2, r3, r5, r8 +# CHECK: smlaleq r2, r3, r5, r8 +# CHECK: smlalshi r2, r3, r5, r8 + +0x95 0x28 0xe3 0xe0 +0x95 0x28 0xf3 0xe0 +0x95 0x28 0xe3 0x00 +0x95 0x28 0xf3 0x80 + + +#------------------------------------------------------------------------------ +# SMLALBB/SMLALBT/SMLALTB/SMLALTT +#------------------------------------------------------------------------------ +# CHECK: smlalbb r3, r1, r9, r0 +# CHECK: smlalbt r5, r6, r4, r1 +# CHECK: smlaltb r4, r2, r3, r2 +# CHECK: smlaltt r8, r3, r8, r4 +# CHECK: smlalbbge r3, r1, r9, r0 +# CHECK: smlalbtle r5, r6, r4, r1 +# CHECK: smlaltbne r4, r2, r3, r2 +# CHECK: smlaltteq r8, r3, r8, r4 + +0x89 0x30 0x41 0xe1 +0xc4 0x51 0x46 0xe1 +0xa3 0x42 0x42 0xe1 +0xe8 0x84 0x43 0xe1 +0x89 0x30 0x41 0xa1 +0xc4 0x51 0x46 0xd1 +0xa3 0x42 0x42 0x11 +0xe8 0x84 0x43 0x01 + + +#------------------------------------------------------------------------------ +# SMLALD/SMLALDX +#------------------------------------------------------------------------------ +# CHECK: smlald r2, r3, r5, r8 +# CHECK: smlaldx r2, r3, r5, r8 +# CHECK: smlaldeq r2, r3, r5, r8 +# CHECK: smlaldxhi r2, r3, r5, r8 + +0x15 0x28 0x43 0xe7 +0x35 0x28 0x43 0xe7 +0x15 0x28 0x43 0x07 +0x35 0x28 0x43 0x87 + + +#------------------------------------------------------------------------------ +# SMLAWB/SMLAWT +#------------------------------------------------------------------------------ +# CHECK: smlawb r2, r3, r10, r8 +# CHECK: smlawt r8, r3, r5, r9 +# CHECK: smlawbeq r2, r7, r5, r8 +# CHECK: smlawthi r1, r3, r0, r8 + +0x83 0x8a 0x22 0xe1 +0xc3 0x95 0x28 0xe1 +0x87 0x85 0x22 0x01 +0xc3 0x80 0x21 0x81 + + +#------------------------------------------------------------------------------ +# SMLSD/SMLSDX +#------------------------------------------------------------------------------ +# CHECK: smlsd r2, r3, r5, r8 +# CHECK: smlsdx r2, r3, r5, r8 +# CHECK: smlsdeq r2, r3, r5, r8 +# CHECK: smlsdxhi r2, r3, r5, r8 + +0x53 0x85 0x02 0xe7 +0x73 0x85 0x02 0xe7 +0x53 0x85 0x02 0x07 +0x73 0x85 0x02 0x87 + + +#------------------------------------------------------------------------------ +# SMLSLD/SMLSLDX +#------------------------------------------------------------------------------ +# CHECK: smlsld r2, r9, r5, r1 +# CHECK: smlsldx r4, r11, r2, r8 +# CHECK: smlsldeq r8, r2, r5, r6 +# CHECK: smlsldxhi r1, r0, r3, r8 + +0x55 0x21 0x49 0xe7 +0x72 0x48 0x4b 0xe7 +0x55 0x86 0x42 0x07 +0x73 0x18 0x40 0x87 + + +#------------------------------------------------------------------------------ +# SMMLA/SMMLAR +#------------------------------------------------------------------------------ +# CHECK: smmla r1, r2, r3, r4 +# CHECK: smmlar r4, r3, r2, r1 +# CHECK: smmlalo r1, r2, r3, r4 +# CHECK: smmlarhs r4, r3, r2, r1 + +0x12 0x43 0x51 0xe7 +0x33 0x12 0x54 0xe7 +0x12 0x43 0x51 0x37 +0x33 0x12 0x54 0x27 + + +#------------------------------------------------------------------------------ +# SMMLS/SMMLSR +#------------------------------------------------------------------------------ +# CHECK: smmls r1, r2, r3, r4 +# CHECK: smmlsr r4, r3, r2, r1 +# CHECK: smmlslo r1, r2, r3, r4 +# CHECK: smmlsrhs r4, r3, r2, r1 + +0xd2 0x43 0x51 0xe7 +0xf3 0x12 0x54 0xe7 +0xd2 0x43 0x51 0x37 +0xf3 0x12 0x54 0x27 + + +#------------------------------------------------------------------------------ +# SMMUL/SMMULR +#------------------------------------------------------------------------------ +# CHECK: smmul r2, r3, r4 +# CHECK: smmulr r3, r2, r1 +# CHECK: smmullo r2, r3, r4 +# CHECK: smmulrhs r3, r2, r1 + +0x13 0xf4 0x52 0xe7 +0x32 0xf1 0x53 0xe7 +0x13 0xf4 0x52 0x37 +0x32 0xf1 0x53 0x27 + + +#------------------------------------------------------------------------------ +# SMUAD/SMUADX +#------------------------------------------------------------------------------ +# CHECK: smuad r2, r3, r4 +# CHECK: smuadx r3, r2, r1 +# CHECK: smuadlt r2, r3, r4 +# CHECK: smuadxge r3, r2, r1 + +0x13 0xf4 0x02 0xe7 +0x32 0xf1 0x03 0xe7 +0x13 0xf4 0x02 0xb7 +0x32 0xf1 0x03 0xa7 + + +#------------------------------------------------------------------------------ +# SMULBB/SMLALBT/SMLALTB/SMLALTT +#------------------------------------------------------------------------------ +# CHECK: smulbb r3, r9, r0 +# CHECK: smulbt r5, r4, r1 +# CHECK: smultb r4, r2, r2 +# CHECK: smultt r8, r3, r4 +# CHECK: smulbbge r1, r9, r0 +# CHECK: smulbtle r5, r6, r4 +# CHECK: smultbne r2, r3, r2 +# CHECK: smultteq r8, r3, r4 + +0x89 0x00 0x63 0xe1 +0xc4 0x01 0x65 0xe1 +0xa2 0x02 0x64 0xe1 +0xe3 0x04 0x68 0xe1 +0x89 0x00 0x61 0xa1 +0xc6 0x04 0x65 0xd1 +0xa3 0x02 0x62 0x11 +0xe3 0x04 0x68 0x01 + + +#------------------------------------------------------------------------------ +# SMULL +#------------------------------------------------------------------------------ +# CHECK: smull r3, r9, r0, r1 +# CHECK: smulls r3, r9, r0, r2 +# CHECK: smulleq r8, r3, r4, r5 +# CHECK: smullseq r8, r3, r4, r3 + +0x90 0x31 0xc9 0xe0 +0x90 0x32 0xd9 0xe0 +0x94 0x85 0xc3 0x00 +0x94 0x83 0xd3 0x00 + + +#------------------------------------------------------------------------------ +# SMULWB/SMULWT +#------------------------------------------------------------------------------ +# CHECK: smulwb r3, r9, r0 +# CHECK: smulwt r3, r9, r2 + +0xa9 0x00 0x23 0xe1 +0xe9 0x02 0x23 0xe1 + + +#------------------------------------------------------------------------------ +# SMUSD/SMUSDX +#------------------------------------------------------------------------------ +# CHECK: smusd r3, r0, r1 +# CHECK: smusdx r3, r9, r2 +# CHECK: smusdeq r8, r3, r2 +# CHECK: smusdxne r7, r4, r3 + +0x50 0xf1 0x03 0xe7 +0x79 0xf2 0x03 0xe7 +0x53 0xf2 0x08 0x07 +0x74 0xf3 0x07 0x17 + + +#------------------------------------------------------------------------------ +# SRS +#------------------------------------------------------------------------------ +# CHECK: srsda sp, #5 +# CHECK: srsdb sp, #1 +# CHECK: srsia sp, #0 +# CHECK: srsib sp, #15 + +# CHECK: srsda sp!, #31 +# CHECK: srsdb sp!, #19 +# CHECK: srsia sp!, #2 +# CHECK: srsib sp!, #14 + +# CHECK: srsda sp, #11 +# CHECK: srsdb sp, #10 +# CHECK: srsia sp, #9 +# CHECK: srsib sp, #5 + +# CHECK: srsda sp!, #5 +# CHECK: srsdb sp!, #5 +# CHECK: srsia sp!, #5 +# CHECK: srsib sp!, #5 + +# CHECK: srsia sp, #5 +# CHECK: srsia sp!, #5 + +0x05 0x05 0x4d 0xf8 +0x01 0x05 0x4d 0xf9 +0x00 0x05 0xcd 0xf8 +0x0f 0x05 0xcd 0xf9 + +0x1f 0x05 0x6d 0xf8 +0x13 0x05 0x6d 0xf9 +0x02 0x05 0xed 0xf8 +0x0e 0x05 0xed 0xf9 + +0x0b 0x05 0x4d 0xf8 +0x0a 0x05 0x4d 0xf9 +0x09 0x05 0xcd 0xf8 +0x05 0x05 0xcd 0xf9 + +0x05 0x05 0x6d 0xf8 +0x05 0x05 0x6d 0xf9 +0x05 0x05 0xed 0xf8 +0x05 0x05 0xed 0xf9 + +0x05 0x05 0xcd 0xf8 +0x05 0x05 0xed 0xf8 + + +#------------------------------------------------------------------------------ +# SSAT +#------------------------------------------------------------------------------ +# CHECK: ssat r8, #1, r10 +# CHECK: ssat r8, #1, r10, lsl #31 +# CHECK: ssat r8, #1, r10, asr #32 +# CHECK: ssat r8, #1, r10, asr #1 + +0x1a 0x80 0xa0 0xe6 +0x9a 0x8f 0xa0 0xe6 +0x5a 0x80 0xa0 0xe6 +0xda 0x80 0xa0 0xe6 + + +#------------------------------------------------------------------------------ +# SSAT16 +#------------------------------------------------------------------------------ +# CHECK: ssat16 r2, #1, r7 +# CHECK: ssat16 r3, #16, r5 + +0x37 0x2f 0xa0 0xe6 +0x35 0x3f 0xaf 0xe6 + + +#------------------------------------------------------------------------------ +# SSAX +#------------------------------------------------------------------------------ +# CHECK: ssax r2, r3, r4 +# CHECK: ssaxlt r2, r3, r4 + +0x54 0x2f 0x13 0xe6 +0x54 0x2f 0x13 0xb6 + +#------------------------------------------------------------------------------ +# SSUB16/SSUB8 +#------------------------------------------------------------------------------ +# CHECK: ssub16 r1, r0, r6 +# CHECK: ssub16ne r5, r3, r2 +# CHECK: ssub8 r9, r2, r4 +# CHECK: ssub8eq r5, r1, r2 + +0x76 0x1f 0x10 0xe6 +0x72 0x5f 0x13 0x16 +0xf4 0x9f 0x12 0xe6 +0xf2 0x5f 0x11 0x06 + + +#------------------------------------------------------------------------------ +# STM* +#------------------------------------------------------------------------------ +# CHECK: stm r2, {r1, r3, r4, r5, r6, sp} +# CHECK: stm r3, {r1, r3, r4, r5, r6, lr} +# CHECK: stmib r4, {r1, r3, r4, r5, r6, sp} +# CHECK: stmda r5, {r1, r3, r4, r5, r6, sp} +# CHECK: stmdb r6, {r1, r3, r4, r5, r6, r8} +# CHECK: stmdb sp, {r1, r3, r4, r5, r6, sp} + + +# CHECK: stm r8!, {r1, r3, r4, r5, r6, sp} +# CHECK: stmib r9!, {r1, r3, r4, r5, r6, sp} +# CHECK: stmda sp!, {r1, r3, r4, r5, r6} +# CHECK: stmdb r0!, {r1, r5, r7, sp} + +0x7a 0x20 0x82 0xe8 +0x7a 0x40 0x83 0xe8 +0x7a 0x20 0x84 0xe9 +0x7a 0x20 0x05 0xe8 +0x7a 0x01 0x06 0xe9 +0x7a 0x20 0x0d 0xe9 + +0x7a 0x20 0xa8 0xe8 +0x7a 0x20 0xa9 0xe9 +0x7a 0x00 0x2d 0xe8 +0xa2 0x20 0x20 0xe9 + + +#------------------------------------------------------------------------------ +# STREX/STREXB/STREXH/STREXD +#------------------------------------------------------------------------------ +# CHECK: strexb r1, r3, [r4 +# CHECK: strexh r4, r2, [r5 +# CHECK: strex r2, r1, [r7 +# CHECK: strexd r6, r2, r3, [r8 + +0x93 0x1f 0xc4 0xe1 +0x92 0x4f 0xe5 0xe1 +0x91 0x2f 0x87 0xe1 +0x92 0x6f 0xa8 0xe1 + + +#------------------------------------------------------------------------------ +# SUB +#------------------------------------------------------------------------------ +# CHECK: sub r4, r5, #61440 +# CHECK: sub r4, r5, r6 +# CHECK: sub r4, r5, r6, lsl #5 +# CHECK: sub r4, r5, r6, lsr #5 +# CHECK: sub r4, r5, r6, lsr #5 +# CHECK: sub r4, r5, r6, asr #5 +# CHECK: sub r4, r5, r6, ror #5 +# CHECK: sub r6, r7, r8, lsl r9 +# CHECK: sub r6, r7, r8, lsr r9 +# CHECK: sub r6, r7, r8, asr r9 +# CHECK: sub r6, r7, r8, ror r9 + +# CHECK: sub r5, r5, #61440 +# CHECK: sub r4, r4, r5 +# CHECK: sub r4, r4, r5, lsl #5 +# CHECK: sub r4, r4, r5, lsr #5 +# CHECK: sub r4, r4, r5, lsr #5 +# CHECK: sub r4, r4, r5, asr #5 +# CHECK: sub r4, r4, r5, ror #5 +# CHECK: sub r6, r6, r7, lsl r9 +# CHECK: sub r6, r6, r7, lsr r9 +# CHECK: sub r6, r6, r7, asr r9 +# CHECK: sub r6, r6, r7, ror r9 + +0x0f 0x4a 0x45 0xe2 +0x06 0x40 0x45 0xe0 +0x86 0x42 0x45 0xe0 +0xa6 0x42 0x45 0xe0 +0xa6 0x42 0x45 0xe0 +0xc6 0x42 0x45 0xe0 +0xe6 0x42 0x45 0xe0 +0x18 0x69 0x47 0xe0 +0x38 0x69 0x47 0xe0 +0x58 0x69 0x47 0xe0 +0x78 0x69 0x47 0xe0 + + +0x0f 0x5a 0x45 0xe2 +0x05 0x40 0x44 0xe0 +0x85 0x42 0x44 0xe0 +0xa5 0x42 0x44 0xe0 +0xa5 0x42 0x44 0xe0 +0xc5 0x42 0x44 0xe0 +0xe5 0x42 0x44 0xe0 +0x17 0x69 0x46 0xe0 +0x37 0x69 0x46 0xe0 +0x57 0x69 0x46 0xe0 +0x77 0x69 0x46 0xe0 + + +#------------------------------------------------------------------------------ +# SVC +#------------------------------------------------------------------------------ +# CHECK: svc #16 +# CHECK: svc #0 +# CHECK: svc #16777215 + +0x10 0x00 0x00 0xef +0x00 0x00 0x00 0xef +0xff 0xff 0xff 0xef + + +#------------------------------------------------------------------------------ +# SWP/SWPB +#------------------------------------------------------------------------------ +# CHECK: swp r1, r2, [r3 +# CHECK: swp r4, r4, [r6 +# CHECK: swpb r5, r1, [r9 + +0x92 0x10 0x03 0xe1 +0x94 0x40 0x06 0xe1 +0x91 0x50 0x49 0xe1 + + +#------------------------------------------------------------------------------ +# SXTAB +#------------------------------------------------------------------------------ +# CHECK: sxtab r2, r3, r4 +# CHECK: sxtab r4, r5, r6 +# CHECK: sxtablt r6, r2, r9, ror #8 +# CHECK: sxtab r5, r1, r4, ror #16 +# CHECK: sxtab r7, r8, r3, ror #24 + +0x74 0x20 0xa3 0xe6 +0x76 0x40 0xa5 0xe6 +0x79 0x64 0xa2 0xb6 +0x74 0x58 0xa1 0xe6 +0x73 0x7c 0xa8 0xe6 + + +#------------------------------------------------------------------------------ +# SXTAB16 +#------------------------------------------------------------------------------ +# CHECK: sxtab16ge r0, r1, r4 +# CHECK: sxtab16 r6, r2, r7 +# CHECK: sxtab16 r3, r5, r8, ror #8 +# CHECK: sxtab16 r3, r2, r1, ror #16 +# CHECK: sxtab16eq r1, r2, r3, ror #24 + +0x74 0x00 0x81 0xa6 +0x77 0x60 0x82 0xe6 +0x78 0x34 0x85 0xe6 +0x71 0x38 0x82 0xe6 +0x73 0x1c 0x82 0x06 + +#------------------------------------------------------------------------------ +# SXTAH +#------------------------------------------------------------------------------ +# CHECK: sxtah r1, r3, r9 +# CHECK: sxtahhi r6, r1, r6 +# CHECK: sxtah r3, r8, r3, ror #8 +# CHECK: sxtahlo r2, r2, r4, ror #16 +# CHECK: sxtah r9, r3, r3, ror #24 + +0x79 0x10 0xb3 0xe6 +0x76 0x60 0xb1 0x86 +0x73 0x34 0xb8 0xe6 +0x74 0x28 0xb2 0x36 +0x73 0x9c 0xb3 0xe6 + +#------------------------------------------------------------------------------ +# SXTB +#------------------------------------------------------------------------------ +# CHECK: sxtbge r2, r4 +# CHECK: sxtb r5, r6 +# CHECK: sxtb r6, r9, ror #8 +# CHECK: sxtblo r5, r1, ror #16 +# CHECK: sxtb r8, r3, ror #24 + +0x74 0x20 0xaf 0xa6 +0x76 0x50 0xaf 0xe6 +0x79 0x64 0xaf 0xe6 +0x71 0x58 0xaf 0x36 +0x73 0x8c 0xaf 0xe6 + + +#------------------------------------------------------------------------------ +# SXTB16 +#------------------------------------------------------------------------------ +# CHECK: sxtb16 r1, r4 +# CHECK: sxtb16 r6, r7 +# CHECK: sxtb16hs r3, r5, ror #8 +# CHECK: sxtb16 r3, r1, ror #16 +# CHECK: sxtb16ge r2, r3, ror #24 + +0x74 0x10 0x8f 0xe6 +0x77 0x60 0x8f 0xe6 +0x75 0x34 0x8f 0x26 +0x71 0x38 0x8f 0xe6 +0x73 0x2c 0x8f 0xa6 + + +#------------------------------------------------------------------------------ +# SXTH +#------------------------------------------------------------------------------ +# CHECK: sxthne r3, r9 +# CHECK: sxth r1, r6 +# CHECK: sxth r3, r8, ror #8 +# CHECK: sxthle r2, r2, ror #16 +# CHECK: sxth r9, r3, ror #24 + +0x79 0x30 0xbf 0x16 +0x76 0x10 0xbf 0xe6 +0x78 0x34 0xbf 0xe6 +0x72 0x28 0xbf 0xd6 +0x73 0x9c 0xbf 0xe6 + + +#------------------------------------------------------------------------------ +# FIXME: TBB/TBH +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# TEQ +#------------------------------------------------------------------------------ +# CHECK: teq r5, #61440 +# CHECK: teq r4, r5 +# CHECK: teq r4, r5, lsl #5 +# CHECK: teq r4, r5, lsr #5 +# CHECK: teq r4, r5, lsr #5 +# CHECK: teq r4, r5, asr #5 +# CHECK: teq r4, r5, ror #5 +# CHECK: teq r6, r7, lsl r9 +# CHECK: teq r6, r7, lsr r9 +# CHECK: teq r6, r7, asr r9 +# CHECK: teq r6, r7, ror r9 + +0x0f 0x0a 0x35 0xe3 +0x05 0x00 0x34 0xe1 +0x85 0x02 0x34 0xe1 +0xa5 0x02 0x34 0xe1 +0xa5 0x02 0x34 0xe1 +0xc5 0x02 0x34 0xe1 +0xe5 0x02 0x34 0xe1 +0x17 0x09 0x36 0xe1 +0x37 0x09 0x36 0xe1 +0x57 0x09 0x36 0xe1 +0x77 0x09 0x36 0xe1 + + +#------------------------------------------------------------------------------ +# TST +#------------------------------------------------------------------------------ +# CHECK: tst r5, #61440 +# CHECK: tst r4, r5 +# CHECK: tst r4, r5, lsl #5 +# CHECK: tst r4, r5, lsr #5 +# CHECK: tst r4, r5, lsr #5 +# CHECK: tst r4, r5, asr #5 +# CHECK: tst r4, r5, ror #5 +# CHECK: tst r6, r7, lsl r9 +# CHECK: tst r6, r7, lsr r9 +# CHECK: tst r6, r7, asr r9 +# CHECK: tst r6, r7, ror r9 + +0x0f 0x0a 0x15 0xe3 +0x05 0x00 0x14 0xe1 +0x85 0x02 0x14 0xe1 +0xa5 0x02 0x14 0xe1 +0xa5 0x02 0x14 0xe1 +0xc5 0x02 0x14 0xe1 +0xe5 0x02 0x14 0xe1 +0x17 0x09 0x16 0xe1 +0x37 0x09 0x16 0xe1 +0x57 0x09 0x16 0xe1 +0x77 0x09 0x16 0xe1 + + +#------------------------------------------------------------------------------ +# UADD16/UADD8 +#------------------------------------------------------------------------------ +# CHECK: uadd16 r1, r2, r3 +# CHECK: uadd16gt r1, r2, r3 +# CHECK: uadd8 r1, r2, r3 +# CHECK: uadd8le r1, r2, r3 + +0x13 0x1f 0x52 0xe6 +0x13 0x1f 0x52 0xc6 +0x93 0x1f 0x52 0xe6 +0x93 0x1f 0x52 0xd6 + + +#------------------------------------------------------------------------------ +# UASX +#------------------------------------------------------------------------------ +# CHECK: uasx r9, r12, r0 +# CHECK: uasxeq r9, r12, r0 + +0x30 0x9f 0x5c 0xe6 +0x30 0x9f 0x5c 0x06 + + +#------------------------------------------------------------------------------ +# UBFX +#------------------------------------------------------------------------------ +# CHECK: ubfx r4, r5, #16, #1 +# CHECK: ubfxgt r4, r5, #16, #16 + +0x55 0x48 0xe0 0xe7 +0x55 0x48 0xef 0xc7 + + +#------------------------------------------------------------------------------ +# UHADD16/UHADD8 +#------------------------------------------------------------------------------ +# CHECK: uhadd16 r4, r8, r2 +# CHECK: uhadd16gt r4, r8, r2 +# CHECK: uhadd8 r4, r8, r2 +# CHECK: uhadd8gt r4, r8, r2 + +0x12 0x4f 0x78 0xe6 +0x12 0x4f 0x78 0xc6 +0x92 0x4f 0x78 0xe6 +0x92 0x4f 0x78 0xc6 + + +#------------------------------------------------------------------------------ +# UHASX +#------------------------------------------------------------------------------ +# CHECK: uhasx r4, r8, r2 +# CHECK: uhasxgt r4, r8, r2 + +0x32 0x4f 0x78 0xe6 +0x32 0x4f 0x78 0xc6 + + +#------------------------------------------------------------------------------ +# UHSUB16/UHSUB8 +#------------------------------------------------------------------------------ +# CHECK: uhsub16 r4, r8, r2 +# CHECK: uhsub16gt r4, r8, r2 +# CHECK: uhsub8 r4, r8, r2 +# CHECK: uhsub8gt r4, r8, r2 + +0x72 0x4f 0x78 0xe6 +0x72 0x4f 0x78 0xc6 +0xf2 0x4f 0x78 0xe6 +0xf2 0x4f 0x78 0xc6 + + +#------------------------------------------------------------------------------ +# UMAAL +#------------------------------------------------------------------------------ +# CHECK: umaal r3, r4, r5, r6 +# CHECK: umaallt r3, r4, r5, r6 + +0x95 0x36 0x44 0xe0 +0x95 0x36 0x44 0xb0 + + +#------------------------------------------------------------------------------ +# UMLAL +#------------------------------------------------------------------------------ +# CHECK: umlal r2, r4, r6, r8 +# CHECK: umlalgt r6, r1, r2, r6 +# CHECK: umlals r2, r9, r2, r3 +# CHECK: umlalseq r3, r5, r1, r2 + +0x96 0x28 0xa4 0xe0 +0x92 0x66 0xa1 0xc0 +0x92 0x23 0xb9 0xe0 +0x91 0x32 0xb5 0x00 + + +#------------------------------------------------------------------------------ +# UMULL +#------------------------------------------------------------------------------ +# CHECK: umull r2, r4, r6, r8 +# CHECK: umullgt r6, r1, r2, r6 +# CHECK: umulls r2, r9, r2, r3 +# CHECK: umullseq r3, r5, r1, r2 + +0x96 0x28 0x84 0xe0 +0x92 0x66 0x81 0xc0 +0x92 0x23 0x99 0xe0 +0x91 0x32 0x95 0x00 + + +#------------------------------------------------------------------------------ +# UQADD16/UQADD8 +#------------------------------------------------------------------------------ +# CHECK: uqadd16 r1, r2, r3 +# CHECK: uqadd16gt r4, r7, r9 +# CHECK: uqadd8 r3, r4, r8 +# CHECK: uqadd8le r8, r1, r2 + + +0x13 0x1f 0x62 0xe6 +0x19 0x4f 0x67 0xc6 +0x98 0x3f 0x64 0xe6 +0x92 0x8f 0x61 0xd6 + + +#------------------------------------------------------------------------------ +# UQASX +#------------------------------------------------------------------------------ +# CHECK: uqasx r2, r4, r1 +# CHECK: uqasxhi r5, r2, r9 + +0x31 0x2f 0x64 0xe6 +0x39 0x5f 0x62 0x86 + + +#------------------------------------------------------------------------------ +# UQSAX +#------------------------------------------------------------------------------ +# CHECK: uqsax r1, r3, r7 +# CHECK: uqsax r3, r6, r2 + +0x57 0x1f 0x63 0xe6 +0x52 0x3f 0x66 0xe6 + + +#------------------------------------------------------------------------------ +# UQSUB16/UQSUB8 +#------------------------------------------------------------------------------ +# CHECK: uqsub16 r1, r5, r3 +# CHECK: uqsub16gt r3, r2, r5 +# CHECK: uqsub8 r2, r1, r4 +# CHECK: uqsub8le r4, r6, r9 + +0x73 0x1f 0x65 0xe6 +0x75 0x3f 0x62 0xc6 +0xf4 0x2f 0x61 0xe6 +0xf9 0x4f 0x66 0xd6 + + +#------------------------------------------------------------------------------ +# USADA8/USAD8 +#------------------------------------------------------------------------------ +# CHECK: usad8 r2, r1, r4 +# CHECK: usad8le r4, r6, r9 +# CHECK: usada8 r1, r5, r3, r7 +# CHECK: usada8gt r3, r2, r5, r1 + +0x11 0xf4 0x82 0xe7 +0x16 0xf9 0x84 0xd7 +0x15 0x73 0x81 0xe7 +0x12 0x15 0x83 0xc7 + + +#------------------------------------------------------------------------------ +# USAT +#------------------------------------------------------------------------------ + +# CHECK: usat r8, #1, r10 +# CHECK: usat r8, #4, r10 +# CHECK: usat r8, #5, r10, lsl #31 +# CHECK: usat r8, #31, r10, asr #32 +# CHECK: usat r8, #16, r10, asr #1 + +0x1a 0x80 0xe1 0xe6 +0x1a 0x80 0xe4 0xe6 +0x9a 0x8f 0xe5 0xe6 +0x5a 0x80 0xff 0xe6 +0xda 0x80 0xf0 0xe6 + +#------------------------------------------------------------------------------ +# USAT16 +#------------------------------------------------------------------------------ +# CHECK: usat16 r2, #2, r7 +# CHECK: usat16 r3, #15, r5 + +0x37 0x2f 0xe2 0xe6 +0x35 0x3f 0xef 0xe6 + + +#------------------------------------------------------------------------------ +# USAX +#------------------------------------------------------------------------------ +# CHECK: usax r2, r3, r4 +# CHECK: usaxne r2, r3, r4 + +0x54 0x2f 0x53 0xe6 +0x54 0x2f 0x53 0x16 + +#------------------------------------------------------------------------------ +# USUB16/USUB8 +#------------------------------------------------------------------------------ +# CHECK: usub16 r4, r2, r7 +# CHECK: usub16hi r1, r1, r3 +# CHECK: usub8 r1, r8, r5 +# CHECK: usub8le r9, r2, r3 + +0x77 0x4f 0x52 0xe6 +0x73 0x1f 0x51 0x86 +0xf5 0x1f 0x58 0xe6 +0xf3 0x9f 0x52 0xd6 + + +#------------------------------------------------------------------------------ +# UXTAB +#------------------------------------------------------------------------------ +# CHECK: uxtab r2, r3, r4 +# CHECK: uxtab r4, r5, r6 +# CHECK: uxtablt r6, r2, r9, ror #8 +# CHECK: uxtab r5, r1, r4, ror #16 +# CHECK: uxtab r7, r8, r3, ror #24 + +0x74 0x20 0xe3 0xe6 +0x76 0x40 0xe5 0xe6 +0x79 0x64 0xe2 0xb6 +0x74 0x58 0xe1 0xe6 +0x73 0x7c 0xe8 0xe6 + + +#------------------------------------------------------------------------------ +# UXTAB16 +#------------------------------------------------------------------------------ +# CHECK: uxtab16ge r0, r1, r4 +# CHECK: uxtab16 r6, r2, r7 +# CHECK: uxtab16 r3, r5, r8, ror #8 +# CHECK: uxtab16 r3, r2, r1, ror #16 +# CHECK: uxtab16eq r1, r2, r3, ror #24 + +0x74 0x00 0xc1 0xa6 +0x77 0x60 0xc2 0xe6 +0x78 0x34 0xc5 0xe6 +0x71 0x38 0xc2 0xe6 +0x73 0x1c 0xc2 0x06 + +#------------------------------------------------------------------------------ +# UXTAH +#------------------------------------------------------------------------------ +# CHECK: uxtah r1, r3, r9 +# CHECK: uxtahhi r6, r1, r6 +# CHECK: uxtah r3, r8, r3, ror #8 +# CHECK: uxtahlo r2, r2, r4, ror #16 +# CHECK: uxtah r9, r3, r3, ror #24 + +0x79 0x10 0xf3 0xe6 +0x76 0x60 0xf1 0x86 +0x73 0x34 0xf8 0xe6 +0x74 0x28 0xf2 0x36 +0x73 0x9c 0xf3 0xe6 + +#------------------------------------------------------------------------------ +# UXTB +#------------------------------------------------------------------------------ +# CHECK: uxtbge r2, r4 +# CHECK: uxtb r5, r6 +# CHECK: uxtb r6, r9, ror #8 +# CHECK: uxtblo r5, r1, ror #16 +# CHECK: uxtb r8, r3, ror #24 + +0x74 0x20 0xef 0xa6 +0x76 0x50 0xef 0xe6 +0x79 0x64 0xef 0xe6 +0x71 0x58 0xef 0x36 +0x73 0x8c 0xef 0xe6 + + +#------------------------------------------------------------------------------ +# UXTB16 +#------------------------------------------------------------------------------ +# CHECK: uxtb16 r1, r4 +# CHECK: uxtb16 r6, r7 +# CHECK: uxtb16hs r3, r5, ror #8 +# CHECK: uxtb16 r3, r1, ror #16 +# CHECK: uxtb16ge r2, r3, ror #24 + +0x74 0x10 0xcf 0xe6 +0x77 0x60 0xcf 0xe6 +0x75 0x34 0xcf 0x26 +0x71 0x38 0xcf 0xe6 +0x73 0x2c 0xcf 0xa6 + + +#------------------------------------------------------------------------------ +# UXTH +#------------------------------------------------------------------------------ +# CHECK: uxthne r3, r9 +# CHECK: uxth r1, r6 +# CHECK: uxth r3, r8, ror #8 +# CHECK: uxthle r2, r2, ror #16 +# CHECK: uxth r9, r3, ror #24 + +0x79 0x30 0xff 0x16 +0x76 0x10 0xff 0xe6 +0x78 0x34 0xff 0xe6 +0x72 0x28 0xff 0xd6 +0x73 0x9c 0xff 0xe6 + +#------------------------------------------------------------------------------ +# WFE/WFI/YIELD +#------------------------------------------------------------------------------ +# CHECK: wfe +# CHECK: wfehi +# CHECK: wfi +# CHECK: wfilt +# CHECK: yield +# CHECK: yieldne + +0x02 0xf0 0x20 0xe3 +0x02 0xf0 0x20 0x83 +0x03 0xf0 0x20 0xe3 +0x03 0xf0 0x20 0xb3 +0x01 0xf0 0x20 0xe3 +0x01 0xf0 0x20 0x13 diff --git a/test/MC/Disassembler/ARM/fp-encoding.txt b/test/MC/Disassembler/ARM/fp-encoding.txt new file mode 100644 index 000000000000..f3e026138a0a --- /dev/null +++ b/test/MC/Disassembler/ARM/fp-encoding.txt @@ -0,0 +1,213 @@ +# RUN: llvm-mc -triple armv7-apple-darwin -disassemble < %s | FileCheck %s + +0xa0 0x0b 0x71 0xee +# CHECK: vadd.f64 d16, d17, d16 + +0x80 0x0a 0x30 0xee +# CHECK: vadd.f32 s0, s1, s0 + +0xe0 0x0b 0x71 0xee +# CHECK: vsub.f64 d16, d17, d16 + +0xc0 0x0a 0x30 0xee +# CHECK: vsub.f32 s0, s1, s0 + +0xa0 0x0b 0xc1 0xee +# CHECK: vdiv.f64 d16, d17, d16 + +0x80 0x0a 0x80 0xee +# CHECK: vdiv.f32 s0, s1, s0 + +0xa0 0x0b 0x61 0xee +# CHECK: vmul.f64 d16, d17, d16 + +0x80 0x0a 0x20 0xee +# CHECK: vmul.f32 s0, s1, s0 + +0xe0 0x0b 0x61 0xee +# CHECK: vnmul.f64 d16, d17, d16 + +0xc0 0x0a 0x20 0xee +# CHECK: vnmul.f32 s0, s1, s0 + +0xe0 0x1b 0xf4 0xee +# CHECK: vcmpe.f64 d17, d16 + +0xc0 0x0a 0xf4 0xee +# CHECK: vcmpe.f32 s1, s0 + +0xe0 0x0b 0xf0 0xee +# CHECK: vabs.f64 d16, d16 + +0xc0 0x0a 0xb0 0xee +# CHECK: vabs.f32 s0, s0 + +0xe0 0x0b 0xb7 0xee +# CHECK: vcvt.f32.f64 s0, d16 + +0xc0 0x0a 0xf7 0xee +# CHECK: vcvt.f64.f32 d16, s0 + +0x60 0x0b 0xf1 0xee +# CHECK: vneg.f64 d16, d16 + +0x40 0x0a 0xb1 0xee +# CHECK: vneg.f32 s0, s0 + +0xe0 0x0b 0xf1 0xee +# CHECK: vsqrt.f64 d16, d16 + +0xc0 0x0a 0xb1 0xee +# CHECK: vsqrt.f32 s0, s0 + +0xc0 0x0b 0xf8 0xee +# CHECK: vcvt.f64.s32 d16, s0 + +0xc0 0x0a 0xb8 0xee +# CHECK: vcvt.f32.s32 s0, s0 + +0x40 0x0b 0xf8 0xee +# CHECK: vcvt.f64.u32 d16, s0 + +0x40 0x0a 0xb8 0xee +# CHECK: vcvt.f32.u32 s0, s0 + +0xe0 0x0b 0xbd 0xee +# CHECK: vcvt.s32.f64 s0, d16 + +0xc0 0x0a 0xbd 0xee +# CHECK: vcvt.s32.f32 s0, s0 + +0xe0 0x0b 0xbc 0xee +# CHECK: vcvt.u32.f64 s0, d16 + +0xc0 0x0a 0xbc 0xee +# CHECK: vcvt.u32.f32 s0, s0 + +0xa1 0x0b 0x42 0xee +# CHECK: vmla.f64 d16, d18, d17 + +0x00 0x0a 0x41 0xee +# CHECK: vmla.f32 s1, s2, s0 + +0xe1 0x0b 0x42 0xee +# CHECK: vmls.f64 d16, d18, d17 + +0x40 0x0a 0x41 0xee +# CHECK: vmls.f32 s1, s2, s0 + +0xe1 0x0b 0x52 0xee +# CHECK: vnmla.f64 d16, d18, d17 + +0x40 0x0a 0x51 0xee +# CHECK: vnmla.f32 s1, s2, s0 + +0xa1 0x0b 0x52 0xee +# CHECK: vnmls.f64 d16, d18, d17 + +0x00 0x0a 0x51 0xee +# CHECK: vnmls.f32 s1, s2, s0 + +0x60 0x0b 0xf1 0x1e +# CHECK: vnegne.f64 d16, d16 + +0x10 0x0a 0x00 0x1e +0x10 0x1a 0x00 0x0e +# CHECK: vmovne s0, r0 +# CHECK: vmoveq s0, r1 + +0x10 0x0a 0xf1 0xee +# CHECK: vmrs r0, fpscr +0x10 0x0a 0xf8 0xee +# CHECK: vmrs r0, fpexc +0x10 0x0a 0xf0 0xee +# CHECK: vmrs r0, fpsid + +0x10 0x0a 0xe1 0xee +# CHECK: vmsr fpscr, r0 +0x10 0x0a 0xe8 0xee +# CHECK: vmsr fpexc, r0 +0x10 0x0a 0xe0 0xee +# CHECK: vmsr fpsid, r0 + +0x10 0x0a 0x00 0xee +0x90 0x1a 0x00 0xee +0x10 0x2a 0x01 0xee +0x90 0x3a 0x01 0xee +# CHECK: vmov s0, r0 +# CHECK: vmov s1, r1 +# CHECK: vmov s2, r2 +# CHECK: vmov s3, r3 + +0x10 0x0a 0x10 0xee +0x90 0x1a 0x10 0xee +0x10 0x2a 0x11 0xee +0x90 0x3a 0x11 0xee +# CHECK: vmov r0, s0 +# CHECK: vmov r1, s1 +# CHECK: vmov r2, s2 +# CHECK: vmov r3, s3 + +0x30 0x0b 0x51 0xec +# CHECK: vmov r0, r1, d16 + +0x00 0x1b 0xd0 0xed +# CHECK: vldr.64 d17, [r0] + +0x08 0x1b 0x92 0xed +0x08 0x1b 0x12 0xed +# CHECK: vldr.64 d1, [r2, #32] +# CHECK: vldr.64 d1, [r2, #-32] + +0x00 0x2b 0x93 0xed +# CHECK: vldr.64 d2, [r3] + +0x00 0x3b 0x9f 0xed +# CHECK: vldr.64 d3, [pc] + +0x00 0x6a 0xd0 0xed +# CHECK: vldr.32 s13, [r0] + +0x08 0x0a 0xd2 0xed +0x08 0x0a 0x52 0xed +# CHECK: vldr.32 s1, [r2, #32] +# CHECK: vldr.32 s1, [r2, #-32] + +0x00 0x1a 0x93 0xed +# CHECK: vldr.32 s2, [r3] + +0x00 0x2a 0xdf 0xed +# CHECK: vldr.32 s5, [pc] + +0x00 0x4b 0x81 0xed +0x06 0x4b 0x81 0xed +0x06 0x4b 0x01 0xed +# CHECK: vstr.64 d4, [r1] +# CHECK: vstr.64 d4, [r1, #24] +# CHECK: vstr.64 d4, [r1, #-24] + +0x00 0x2a 0x81 0xed +0x06 0x2a 0x81 0xed +0x06 0x2a 0x01 0xed +# CHECK: vstr.32 s4, [r1] +# CHECK: vstr.32 s4, [r1, #24] +# CHECK: vstr.32 s4, [r1, #-24] + +0x0c 0x2b 0x91 0xec +0x06 0x1a 0x91 0xec +# CHECK: vldmia r1, {d2, d3, d4, d5, d6, d7} +# CHECK: vldmia r1, {s2, s3, s4, s5, s6, s7} + +0x0c 0x2b 0x81 0xec +0x06 0x1a 0x81 0xec +# CHECK: vstmia r1, {d2, d3, d4, d5, d6, d7} +# CHECK: vstmia r1, {s2, s3, s4, s5, s6, s7} + +0x40 0x0b 0xbd 0xee +0x60 0x0a 0xbd 0xee +0x40 0x0b 0xbc 0xee +0x60 0x0a 0xbc 0xee +# CHECK: vcvtr.s32.f64 s0, d0 +# CHECK: vcvtr.s32.f32 s0, s1 +# CHECK: vcvtr.u32.f64 s0, d0 +# CHECK: vcvtr.u32.f32 s0, s1 diff --git a/test/MC/Disassembler/ARM/invalid-BFI-arm.txt b/test/MC/Disassembler/ARM/invalid-BFI-arm.txt index ca0c1abb77b7..a0d5944a053f 100644 --- a/test/MC/Disassembler/ARM/invalid-BFI-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-BFI-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=60 Name=BFI Format=ARM_FORMAT_DPFRM(4) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 0: 1: 1: 1| 1: 1: 0: 0| 1: 1: 1: 1| 1: 1: 1: 1| 0: 0: 0: 0| 0: 0: 0: 1| 0: 1: 1: 0| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-Bcc-thumb.txt b/test/MC/Disassembler/ARM/invalid-Bcc-thumb.txt index 66c43c219780..d2d424c1de49 100644 --- a/test/MC/Disassembler/ARM/invalid-Bcc-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-Bcc-thumb.txt @@ -1,10 +1,10 @@ # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=2249 Name=tBcc Format=ARM_FORMAT_THUMBFRM(25) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 1: 0: 1| 1: 1: 1: 0| 0: 1: 1: 0| 1: 1: 1: 1| # ------------------------------------------------------------------------------------------------- -# +# # if cond = '1110' then UNDEFINED 0x6f 0xde diff --git a/test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt b/test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt index 5202217b6a71..6fdb55e691d4 100644 --- a/test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-CPS3p-arm.txt @@ -1,4 +1,4 @@ -# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {potentially undefined instruction encoding} # invalid (imod, M, iflags) combination 0x93 0x1c 0x02 0xf1 diff --git a/test/MC/Disassembler/ARM/invalid-DMB-thumb.txt b/test/MC/Disassembler/ARM/invalid-DMB-thumb.txt index 0a4be6826ccd..b4414859c91f 100644 --- a/test/MC/Disassembler/ARM/invalid-DMB-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-DMB-thumb.txt @@ -1,11 +1,11 @@ # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=1908 Name=t2DMB Format=ARM_FORMAT_THUMBFRM(25) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 0: 0: 1: 1| 1: 0: 1: 1| 1: 1: 1: 1| 1: 0: 0: 0| 1: 1: 1: 1| 0: 1: 0: 1| 0: 0: 0: 1| # ------------------------------------------------------------------------------------------------- -# +# # Inst{3-0} encodes the option: SY, ST, ISH, ISHST, NSH, NSHST, OSH, OSHST. # Reject invalid encodings. # diff --git a/test/MC/Disassembler/ARM/invalid-DSB-arm.txt b/test/MC/Disassembler/ARM/invalid-DSB-arm.txt index afa2baff615d..de042a97c6ef 100644 --- a/test/MC/Disassembler/ARM/invalid-DSB-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-DSB-arm.txt @@ -1,11 +1,11 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=102 Name=DSB Format=ARM_FORMAT_MISCFRM(26) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 0: 1: 0: 1| 0: 1: 1: 1| 1: 1: 1: 1| 1: 1: 1: 1| 0: 0: 0: 0| 0: 1: 0: 0| 0: 0: 0: 0| # ------------------------------------------------------------------------------------------------- -# +# # Inst{3-0} encodes the option: SY, ST, ISH, ISHST, NSH, NSHST, OSH, OSHST. # Reject invalid encodings. # diff --git a/test/MC/Disassembler/ARM/invalid-IT-CBNZ-thumb.txt b/test/MC/Disassembler/ARM/invalid-IT-CBNZ-thumb.txt new file mode 100644 index 000000000000..6174e92c4726 --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-IT-CBNZ-thumb.txt @@ -0,0 +1,5 @@ +# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 |& grep {potentially undefined instruction encoding} + +# CBZ / CBNZ not allowed in IT block. + +0xdb 0xbf 0x42 0xbb diff --git a/test/MC/Disassembler/ARM/invalid-IT-thumb.txt b/test/MC/Disassembler/ARM/invalid-IT-thumb.txt new file mode 100644 index 000000000000..9b571b33f5fc --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-IT-thumb.txt @@ -0,0 +1,3 @@ +# RUN: llvm-mc --disassemble %s -triple=thumbv7-unknown-unknown |& grep {potentially undefined instruction encoding} + +0xff 0xbf 0x6b 0x80 0x00 0x75 diff --git a/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt b/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt index b966a9d773c2..0b0426b2dabe 100644 --- a/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-LDC-form-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=0 Name=PHI Format=(42) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 0: 1| 1: 1: 0: 0| 0: 0: 0: 1| 1: 1: 1: 1| 1: 0: 1: 1| 0: 1: 0: 0| 1: 0: 0: 1| 0: 0: 1: 0| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-LDM-thumb.txt b/test/MC/Disassembler/ARM/invalid-LDM-thumb.txt new file mode 100644 index 000000000000..a42b24880e56 --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-LDM-thumb.txt @@ -0,0 +1,5 @@ +# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 |& grep {potentially undefined instruction encoding} + +# Writeback is not allowed is Rn is in the target register list. + +0xb4 0xe8 0x34 0x04 diff --git a/test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt b/test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt index 7a35c2d6ce0f..6b695b95b2b3 100644 --- a/test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-LDRB_POST-arm.txt @@ -1,10 +1,10 @@ -# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {potentially undefined instruction encoding} # Opcode=140 Name=LDRB_POST Format=ARM_FORMAT_LDFRM(6) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 0: 1: 1: 0| 1: 1: 0: 1| 0: 1: 1: 1| 0: 1: 1: 1| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 1| # ------------------------------------------------------------------------------------------------- -# +# # if wback && (n == 15 || n == t) then UNPREDICTABLE 0x05 0x70 0xd7 0xe6 diff --git a/test/MC/Disassembler/ARM/invalid-LDRD-arm.txt b/test/MC/Disassembler/ARM/invalid-LDRD-arm.txt new file mode 100644 index 000000000000..f8f23ed02b88 --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-LDRD-arm.txt @@ -0,0 +1,10 @@ +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} + +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# ------------------------------------------------------------------------------------------------- +# | 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| X: X: X: 1| X: X: X: X| 1: 1: X: 1| X: X: X: X| +# ------------------------------------------------------------------------------------------------- +# +# A8.6.68 LDRD (register) +# if Rt{0} = 1 then UNDEFINED; +0xd0 0x10 0x00 0x00 diff --git a/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt b/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt index da2e6bed8615..7ea1b4679570 100644 --- a/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-LDRD_PRE-thumb.txt @@ -1,4 +1,4 @@ -# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} +# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=1930 Name=t2LDRD_PRE Format=ARM_FORMAT_THUMBFRM(25) # 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 diff --git a/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt b/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt index fb2ce20d2c91..067dcb36a7ef 100644 --- a/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-LDRT-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=0 Name=PHI Format=(42) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 0: 1: 1: 0| 0: 0: 1: 1| 0: 1: 1: 1| 0: 1: 0: 1| 0: 0: 0: 1| 0: 0: 0: 1| 0: 0: 0: 0| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt b/test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt index ad79986b2549..eef2c45db522 100644 --- a/test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-LDR_POST-arm.txt @@ -1,4 +1,5 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} +# XFAIL: * # LDR_PRE/POST has encoding Inst{4} = 0. 0xde 0x69 0x18 0x46 diff --git a/test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt b/test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt index 36c1124bced5..e42e0de9b9d1 100644 --- a/test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-LDR_PRE-arm.txt @@ -1,10 +1,10 @@ -# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} +# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {potentially undefined instruction encoding} # Opcode=165 Name=LDR_PRE Format=ARM_FORMAT_LDFRM(6) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 0: 1: 1: 1| 1: 0: 1: 1| 0: 1: 1: 1| 0: 1: 1: 0| 0: 0: 0: 0| 1: 0: 0: 0| 1: 1: 1: 1| # ------------------------------------------------------------------------------------------------- -# +# # if m == 15 then UNPREDICTABLE 0x8f 0x60 0xb7 0xe7 diff --git a/test/MC/Disassembler/ARM/invalid-LSL-regform.txt b/test/MC/Disassembler/ARM/invalid-LSL-regform.txt index 20293ada7983..6a1f11faf232 100644 --- a/test/MC/Disassembler/ARM/invalid-LSL-regform.txt +++ b/test/MC/Disassembler/ARM/invalid-LSL-regform.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=196 Name=MOVs Format=ARM_FORMAT_DPSOREGFRM(5) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 0: 0: 0: 1| 1: 0: 1: 0| 0: 0: 0: 0| 1: 1: 1: 1| 0: 0: 0: 1| 0: 0: 0: 1| 0: 0: 1: 0| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-MCR-arm.txt b/test/MC/Disassembler/ARM/invalid-MCR-arm.txt index d39b9c1d608e..8343d549e1b0 100644 --- a/test/MC/Disassembler/ARM/invalid-MCR-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-MCR-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=171 Name=MCR Format=ARM_FORMAT_BRFRM(2) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 0: 0: 1: 0| 1: 1: 1: 0| 1: 0: 1: 0| 0: 0: 0: 0| 0: 0: 0: 1| 1: 0: 1: 1| 0: 0: 0: 1| 1: 0: 1: 1| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-MOVTi16-arm.txt b/test/MC/Disassembler/ARM/invalid-MOVTi16-arm.txt index 0b8a0776cc41..235952fc3588 100644 --- a/test/MC/Disassembler/ARM/invalid-MOVTi16-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-MOVTi16-arm.txt @@ -1,10 +1,10 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=185 Name=MOVTi16 Format=ARM_FORMAT_DPFRM(4) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 0: 0: 1: 1| 0: 1: 0: 0| 0: 0: 0: 1| 1: 1: 1: 1| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| # ------------------------------------------------------------------------------------------------- -# +# # if d == 15 then UNPREDICTABLE 0x00 0xf0 0x41 0xe3 diff --git a/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt b/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt index f82d3cb0b10f..01c1466a280d 100644 --- a/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-MOVr-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=0 Name=PHI Format=(42) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 0: 0: 0: 1| 1: 0: 1: 1| 1: 1: 0: 0| 1: 1: 0: 1| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 1: 0| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-MOVs-LSL-arm.txt b/test/MC/Disassembler/ARM/invalid-MOVs-LSL-arm.txt index 3165ff794f97..757d16759447 100644 --- a/test/MC/Disassembler/ARM/invalid-MOVs-LSL-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-MOVs-LSL-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=196 Name=MOVs Format=ARM_FORMAT_DPSOREGFRM(5) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 0: 1| 0: 0: 0: 1| 1: 0: 1: 0| 0: 0: 0: 0| 0: 1: 0: 0| 0: 0: 1: 0| 1: 0: 0: 1| 0: 0: 1: 1| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt b/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt index cfbba43fd514..ba488776c0d6 100644 --- a/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-MOVs-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=0 Name=PHI Format=(42) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 0: 0: 0: 1| 1: 0: 1: 1| 1: 1: 0: 0| 1: 1: 0: 1| 0: 0: 0: 1| 0: 0: 0: 0| 0: 0: 1: 0| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt b/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt index e9d5deb04349..3765b1f5c025 100644 --- a/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-MSRi-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=206 Name=MSRi Format=ARM_FORMAT_BRFRM(2) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 0: 0: 0: 0| 0: 0: 1: 1| 0: 0: 1: 0| 0: 0: 0: 0| 1: 1: 1: 1| 0: 0: 0: 1| 1: 0: 1: 0| 0: 1: 1: 1| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-RFEorLDMIA-arm.txt b/test/MC/Disassembler/ARM/invalid-RFEorLDMIA-arm.txt index 1fdfa8299c78..cffd86dc1ad8 100644 --- a/test/MC/Disassembler/ARM/invalid-RFEorLDMIA-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-RFEorLDMIA-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=134 Name=LDMIA Format=ARM_FORMAT_LDSTMULFRM(10) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 1: 0: 0: 0| 1: 0: 0: 1| 1: 0: 0: 1| 1: 0: 1: 1| 0: 0: 0: 1| 0: 0: 1: 1| 0: 0: 1: 0| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-RSC-arm.txt b/test/MC/Disassembler/ARM/invalid-RSC-arm.txt index e7992ae6342e..096b909bc6d1 100644 --- a/test/MC/Disassembler/ARM/invalid-RSC-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-RSC-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=261 Name=RSCrs Format=ARM_FORMAT_DPSOREGFRM(5) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 0: 0: 1: 1| 0: 0: 0: 0| 1: 1: 1: 0| 0: 1: 0: 0| 1: 1: 1: 1| 1: 0: 0: 0| 0: 1: 0: 1| 1: 1: 1: 1| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-SBFX-arm.txt b/test/MC/Disassembler/ARM/invalid-SBFX-arm.txt index 1ecd87df07c2..9e1653605256 100644 --- a/test/MC/Disassembler/ARM/invalid-SBFX-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-SBFX-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=271 Name=SBFX Format=ARM_FORMAT_DPFRM(4) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 0: 1: 1: 1| 1: 0: 1: 0| 0: 1: 1: 1| 0: 1: 0: 1| 0: 1: 0: 0| 0: 1: 0: 1| 1: 1: 1: 1| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-SMLAD-arm.txt b/test/MC/Disassembler/ARM/invalid-SMLAD-arm.txt index c3dcf83fbd21..91f3d58b4c4a 100644 --- a/test/MC/Disassembler/ARM/invalid-SMLAD-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-SMLAD-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=284 Name=SMLAD Format=ARM_FORMAT_MULFRM(1) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 0: 0: 1| 0: 1: 1: 1| 0: 0: 0: 0| 1: 1: 1: 1| 0: 1: 1: 0| 1: 0: 0: 0| 0: 0: 0: 1| 1: 0: 1: 1| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-SRS-arm.txt b/test/MC/Disassembler/ARM/invalid-SRS-arm.txt index fdca9f9eaec6..fc5c711a2300 100644 --- a/test/MC/Disassembler/ARM/invalid-SRS-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-SRS-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=0 Name=PHI Format=(42) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 1: 0: 0: 0| 1: 1: 0: 0| 0: 1: 0: 1| 0: 0: 0: 1| 1: 1: 0: 0| 1: 0: 0: 0| 0: 0: 1: 1| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-SSAT-arm.txt b/test/MC/Disassembler/ARM/invalid-SSAT-arm.txt index 9cc8351b781f..b236f8ef4d25 100644 --- a/test/MC/Disassembler/ARM/invalid-SSAT-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-SSAT-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=322 Name=SSAT Format=ARM_FORMAT_SATFRM(13) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 0: 1: 1: 0| 1: 0: 1: 0| 0: 0: 0: 0| 1: 1: 1: 1| 0: 1: 0: 0| 0: 0: 0: 1| 1: 0: 1: 0| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt b/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt index 0000c60ce4b8..ca16724c7ad5 100644 --- a/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-STMIA_UPD-thumb.txt @@ -1,10 +1,10 @@ # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=2313 Name=tSTMIA_UPD Format=ARM_FORMAT_THUMBFRM(25) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 1: 0: 0| 0: 1: 1: 1| 0: 0: 0: 0| 0: 0: 0: 0| # ------------------------------------------------------------------------------------------------- -# +# # if BitCount(registers) < 1 then UNPREDICTABLE 0x00 0xc7 diff --git a/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt b/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt index 5209323fa847..d3998bdc09a8 100644 --- a/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-STRBrs-arm.txt @@ -1,10 +1,10 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=355 Name=STRBrs Format=ARM_FORMAT_STFRM(7) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 0: 1: 1: 1| 1: 1: 0: 0| 1: 1: 1: 1| 1: 1: 1: 1| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| # ------------------------------------------------------------------------------------------------- -# +# # if t == 15 then UNPREDICTABLE 0x00 0xf0 0xcf 0xe7 diff --git a/test/MC/Disassembler/ARM/invalid-SXTB-arm.txt b/test/MC/Disassembler/ARM/invalid-SXTB-arm.txt index 4ec681daf954..400d44ce8c38 100644 --- a/test/MC/Disassembler/ARM/invalid-SXTB-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-SXTB-arm.txt @@ -1,7 +1,7 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=390 Name=SXTBr_rot Format=ARM_FORMAT_EXTFRM(14) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 0: 1: 1: 0| 1: 0: 1: 0| 1: 1: 1: 1| 1: 1: 1: 1| 0: 1: 0: 0| 0: 1: 1: 1| 0: 1: 0: 1| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-UMAAL-arm.txt b/test/MC/Disassembler/ARM/invalid-UMAAL-arm.txt index 7a3ef3328aa6..c7cbd844871a 100644 --- a/test/MC/Disassembler/ARM/invalid-UMAAL-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-UMAAL-arm.txt @@ -1,11 +1,11 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=419 Name=UMAAL Format=ARM_FORMAT_MULFRM(1) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 0: 0: 0: 0| 0: 1: 0: 0| 1: 1: 1: 1| 1: 0: 1: 1| 1: 1: 1: 1| 1: 0: 0: 1| 1: 0: 0: 0| # ------------------------------------------------------------------------------------------------- # # A8.6.244 UMAAL # if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; -0x98 0xbf 0x4f 0xf0 +0x98 0xbf 0x4f 0xf0 diff --git a/test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt b/test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt index d3f508a1dabd..fb3e71106c9d 100644 --- a/test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-UQADD8-arm.txt @@ -1,11 +1,11 @@ # RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=426 Name=UQADD8 Format=ARM_FORMAT_DPFRM(4) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 0: 1: 1: 0| 0: 1: 1: 0| 0: 1: 1: 0| 0: 1: 0: 1| 1: 1: 1: 1| 1: 0: 0: 1| 1: 1: 1: 1| # ------------------------------------------------------------------------------------------------- -# +# # DPFrm with bad reg specifier(s) # # if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; diff --git a/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt b/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt index 56d9ad704a01..12da8690f160 100644 --- a/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-VLD1DUPq8_UPD-arm.txt @@ -1,4 +1,5 @@ -# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} +# RUN: llvm-mc --disassemble %s -triple=armv7-apple-darwin9 |& grep {invalid instruction encoding} +# XFAIL: * # Opcode=737 Name=VLD1DUPq8_UPD Format=ARM_FORMAT_NLdSt(30) # 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 diff --git a/test/MC/Disassembler/ARM/invalid-VLD3DUPd32_UPD-thumb.txt b/test/MC/Disassembler/ARM/invalid-VLD3DUPd32_UPD-thumb.txt index 5fd02517991a..bab32ca1711f 100644 --- a/test/MC/Disassembler/ARM/invalid-VLD3DUPd32_UPD-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-VLD3DUPd32_UPD-thumb.txt @@ -1,11 +1,11 @@ # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=871 Name=VLD3DUPd32_UPD Format=ARM_FORMAT_NLdSt(30) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 0: 1: 0: 0| 1: 0: 1: 0| 0: 0: 1: 0| 0: 0: 1: 0| 1: 1: 1: 0| 1: 0: 0: 1| 0: 0: 1: 0| # ------------------------------------------------------------------------------------------------- -# +# # A8.6.315 VLD3 (single 3-element structure to all lanes) # The a bit must be encoded as 0. 0xa2 0xf9 0x92 0x2e diff --git a/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt b/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt index eed012b0be60..a53f9405025f 100644 --- a/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-VQADD-arm.txt @@ -1,4 +1,5 @@ -# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} +# RUN: llvm-mc --disassemble %s -triple=armv7-apple-darwin9 |& grep {invalid instruction encoding} +# XFAIL: * # Opcode=1225 Name=VQADDsv16i8 Format=ARM_FORMAT_N3Reg(37) # 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 diff --git a/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt b/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt index 506250c3bc2a..a12ca9548a52 100644 --- a/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt +++ b/test/MC/Disassembler/ARM/invalid-VST2b32_UPD-arm.txt @@ -1,7 +1,8 @@ -# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 |& grep {invalid instruction encoding} +# RUN: llvm-mc --disassemble %s -triple=armv7-apple-darwin9 |& grep {invalid instruction encoding} +# XFAIL: * # Opcode=1641 Name=VST2b32_UPD Format=ARM_FORMAT_NLdSt(30) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 0: 1: 0: 0| 0: 0: 0: 0| 0: 0: 1: 1| 0: 0: 0: 0| 1: 0: 0: 1| 1: 0: 1: 1| 0: 0: 1: 1| # ------------------------------------------------------------------------------------------------- diff --git a/test/MC/Disassembler/ARM/invalid-t2Bcc-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2Bcc-thumb.txt index d0bc51ebaf39..df0a642f440c 100644 --- a/test/MC/Disassembler/ARM/invalid-t2Bcc-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-t2Bcc-thumb.txt @@ -1,11 +1,11 @@ # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=1894 Name=t2Bcc Format=ARM_FORMAT_THUMBFRM(25) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 0: 1: 1: 1| 1: 0: 1: 0| 1: 1: 1: 1| 1: 0: 0: 0| 1: 0: 1: 1| 0: 1: 0: 0| 0: 1: 0: 0| # ------------------------------------------------------------------------------------------------- -# +# # A8.6.16 B # if cond<3:1> == '111' then SEE "Related Encodings" 0xaf 0xf7 0x44 0x8b diff --git a/test/MC/Disassembler/ARM/invalid-t2LDRBT-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2LDRBT-thumb.txt index 9befbd6b6fba..e1f841b86de3 100644 --- a/test/MC/Disassembler/ARM/invalid-t2LDRBT-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-t2LDRBT-thumb.txt @@ -1,10 +1,10 @@ # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=1922 Name=t2LDRBT Format=ARM_FORMAT_THUMBFRM(25) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 1: 0: 0: 0| 0: 0: 0: 1| 0: 0: 0: 0| 1: 1: 1: 1| 1: 1: 1: 0| 0: 0: 0: 0| 0: 0: 1: 1| # ------------------------------------------------------------------------------------------------- -# +# # The unpriviledged Load/Store cannot have SP or PC as Rt. 0x10 0xf8 0x3 0xfe diff --git a/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt index 598efd1bc7c6..7c0efab3834d 100644 --- a/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-t2LDREXD-thumb.txt @@ -1,4 +1,5 @@ -# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} +# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 |& grep {invalid instruction encoding} +# XFAIL: * # Opcode=1934 Name=t2LDREXD Format=ARM_FORMAT_THUMBFRM(25) # 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 diff --git a/test/MC/Disassembler/ARM/invalid-t2LDRSHi12-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2LDRSHi12-thumb.txt index a501eb9cd541..a63d1214f27c 100644 --- a/test/MC/Disassembler/ARM/invalid-t2LDRSHi12-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-t2LDRSHi12-thumb.txt @@ -1,10 +1,10 @@ # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=1953 Name=t2LDRSHi12 Format=ARM_FORMAT_THUMBFRM(25) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 1: 0: 0: 1| 1: 0: 1: 1| 0: 0: 1: 1| 1: 1: 1: 1| 1: 0: 0: 0| 1: 1: 0: 1| 1: 1: 1: 1| # ------------------------------------------------------------------------------------------------- -# +# # if Rt = '1111' then SEE "Unallocated memory hints" 0xb3 0xf9 0xdf 0xf8 diff --git a/test/MC/Disassembler/ARM/invalid-t2LDRSHi8-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2LDRSHi8-thumb.txt index f886a6f074b1..f126ff04fb1c 100644 --- a/test/MC/Disassembler/ARM/invalid-t2LDRSHi8-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-t2LDRSHi8-thumb.txt @@ -1,10 +1,10 @@ # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=1954 Name=t2LDRSHi8 Format=ARM_FORMAT_THUMBFRM(25) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 1: 0: 0: 1| 0: 0: 1: 1| 0: 1: 0: 1| 1: 1: 1: 1| 1: 1: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| # ------------------------------------------------------------------------------------------------- -# +# # if Rt == '1111' and PUW == '100' then SEE "Unallocated memory hints" 0x35 0xf9 0x00 0xfc diff --git a/test/MC/Disassembler/ARM/invalid-t2PUSH-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2PUSH-thumb.txt new file mode 100644 index 000000000000..b3daa9a429f4 --- /dev/null +++ b/test/MC/Disassembler/ARM/invalid-t2PUSH-thumb.txt @@ -0,0 +1,5 @@ +# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 |& grep {invalid instruction encoding} + +# SP and PC are not allowed in the register list on STM instructions in Thumb2. + +0x2d 0xe9 0xf7 0xb6 diff --git a/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt index c8f8ec294ec1..2198efc2d257 100644 --- a/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-t2STRD_PRE-thumb.txt @@ -1,4 +1,5 @@ -# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} +# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 |& grep {invalid instruction encoding} +# XFAIL: * # Opcode=2124 Name=t2STRD_PRE Format=ARM_FORMAT_THUMBFRM(25) # 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 diff --git a/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt index 35ea6511647f..3f406d49487b 100644 --- a/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-t2STREXB-thumb.txt @@ -1,4 +1,5 @@ -# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} +# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 |& grep {invalid instruction encoding} +# XFAIL: * # Opcode=2127 Name=t2STREXB Format=ARM_FORMAT_THUMBFRM(25) # 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 diff --git a/test/MC/Disassembler/ARM/invalid-t2STREXD-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2STREXD-thumb.txt index 9b0cf24ffb16..0f9a16ee54dd 100644 --- a/test/MC/Disassembler/ARM/invalid-t2STREXD-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-t2STREXD-thumb.txt @@ -1,10 +1,10 @@ # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=2128 Name=t2STREXD Format=ARM_FORMAT_THUMBFRM(25) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 0| 1: 0: 0: 0| 1: 1: 0: 0| 0: 0: 1: 0| 0: 1: 1: 1| 1: 0: 0: 0| 0: 1: 1: 1| 1: 0: 0: 0| # ------------------------------------------------------------------------------------------------- -# +# # if d == n || d == t || d == t2 then UNPREDICTABLE mc-input.txt:1:1: warning: invalid instruction encoding diff --git a/test/MC/Disassembler/ARM/invalid-t2STR_POST-thumb.txt b/test/MC/Disassembler/ARM/invalid-t2STR_POST-thumb.txt index 129a2704d5c5..548ad056e6c0 100644 --- a/test/MC/Disassembler/ARM/invalid-t2STR_POST-thumb.txt +++ b/test/MC/Disassembler/ARM/invalid-t2STR_POST-thumb.txt @@ -1,10 +1,10 @@ # RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 |& grep {invalid instruction encoding} # Opcode=2137 Name=t2STR_POST Format=ARM_FORMAT_THUMBFRM(25) -# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +# 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 # ------------------------------------------------------------------------------------------------- # | 1: 1: 1: 1| 1: 0: 0: 0| 0: 1: 0: 0| 1: 1: 1: 1| 1: 1: 1: 0| 1: 0: 1: 1| 1: 1: 1: 1| 1: 1: 1: 1| # ------------------------------------------------------------------------------------------------- -# +# # if Rn == '1111' then UNDEFINED 0x4f 0xf8 0xff 0xeb diff --git a/test/MC/Disassembler/ARM/memory-arm-instructions.txt b/test/MC/Disassembler/ARM/memory-arm-instructions.txt new file mode 100644 index 000000000000..4fa28975bec4 --- /dev/null +++ b/test/MC/Disassembler/ARM/memory-arm-instructions.txt @@ -0,0 +1,470 @@ +# RUN: llvm-mc -triple=armv7-apple-darwin -disassemble < %s | FileCheck %s + +#------------------------------------------------------------------------------ +# LDR (immediate) +#------------------------------------------------------------------------------ +# CHECK: ldr r5, [r7] +# CHECK: ldr r6, [r3, #63] +# CHECK: ldr r2, [r4, #4095]! +# CHECK: ldr r1, [r2], #30 +# CHECK: ldr r3, [r1], #-30 + +0x00 0x50 0x97 0xe5 +0x3f 0x60 0x93 0xe5 +0xff 0x2f 0xb4 0xe5 +0x1e 0x10 0x92 0xe4 +0x1e 0x30 0x11 0xe4 + +#------------------------------------------------------------------------------ +# FIXME: LDR (literal) +#------------------------------------------------------------------------------ +# label operands currently assert the show-encoding asm comment helper due +# to the use of non-contiguous bit ranges for fixups in ARM. Once that's +# cleaned up, we can write useful assembly testcases for these sorts of +# instructions. + +#------------------------------------------------------------------------------ +# LDR (register) +#------------------------------------------------------------------------------ +# CHECK: ldr r3, [r8, r1] +# CHECK: ldr r2, [r5, -r3] +# CHECK: ldr r1, [r5, r9]! +# CHECK: ldr r6, [r7, -r8]! +# CHECK: ldr r1, [r0, r2, lsr #3]! +# CHECK: ldr r5, [r9], r2 +# CHECK: ldr r4, [r3], -r6 +# CHECK: ldr r3, [r8, -r2, lsl #15 +# CHECK: ldr r1, [r5], r3, asr #15 + +0x01 0x30 0x98 0xe7 +0x03 0x20 0x15 0xe7 +0x09 0x10 0xb5 0xe7 +0x08 0x60 0x37 0xe7 +0xa2 0x11 0xb0 0xe7 +0x02 0x50 0x99 0xe6 +0x06 0x40 0x13 0xe6 +0x82 0x37 0x18 0xe7 +0xc3 0x17 0x95 0xe6 + + +#------------------------------------------------------------------------------ +# LDRB (immediate) +#------------------------------------------------------------------------------ +# CHECK: ldrb r3, [r8] +# CHECK: ldrb r1, [sp, #63] +# CHECK: ldrb r9, [r3, #4095]! +# CHECK: ldrb r8, [r1], #22 +# CHECK: ldrb r2, [r7], #-19 + +0x00 0x30 0xd8 0xe5 +0x3f 0x10 0xdd 0xe5 +0xff 0x9f 0xf3 0xe5 +0x16 0x80 0xd1 0xe4 +0x13 0x20 0x57 0xe4 + + +#------------------------------------------------------------------------------ +# LDRB (register) +#------------------------------------------------------------------------------ +# CHECK: ldrb r9, [r8, r5] +# CHECK: ldrb r1, [r5, -r1] +# CHECK: ldrb r3, [r5, r2]! +# CHECK: ldrb r6, [r9, -r3]! +# CHECK: ldrb r2, [r1], r4 +# CHECK: ldrb r8, [r4], -r5 +# CHECK: ldrb r7, [r12, -r1, lsl #15 +# CHECK: ldrb r5, [r2], r9, asr #15 + +0x05 0x90 0xd8 0xe7 +0x01 0x10 0x55 0xe7 +0x02 0x30 0xf5 0xe7 +0x03 0x60 0x79 0xe7 +0x04 0x20 0xd1 0xe6 +0x05 0x80 0x54 0xe6 +0x81 0x77 0x5c 0xe7 +0xc9 0x57 0xd2 0xe6 + + +#------------------------------------------------------------------------------ +# LDRBT +#------------------------------------------------------------------------------ +# FIXME: Optional offset operand. +# CHECK: ldrbt r3, [r1], #4 +# CHECK: ldrbt r2, [r8], #-8 +# CHECK: ldrbt r8, [r7], r6 +# CHECK: ldrbt r1, [r2], -r6, lsl #12 + + +0x04 0x30 0xf1 0xe4 +0x08 0x20 0x78 0xe4 +0x06 0x80 0xf7 0xe6 +0x06 0x16 0x72 0xe6 + + +#------------------------------------------------------------------------------ +# LDRD (immediate) +#------------------------------------------------------------------------------ +# CHECK: ldrd r0, r1, [r5] +# CHECK: ldrd r8, r9, [r2, #15] +# CHECK: ldrd r2, r3, [r9, #32]! +# CHECK: ldrd r6, r7, [r1], #8 +# CHECK: ldrd r2, r3, [r8], #0 +# CHECK: ldrd r2, r3, [r8], #0 +# CHECK: ldrd r2, r3, [r8], #-0 + +0xd0 0x00 0xc5 0xe1 +0xdf 0x80 0xc2 0xe1 +0xd0 0x22 0xe9 0xe1 +0xd8 0x60 0xc1 0xe0 +0xd0 0x20 0xc8 0xe0 +0xd0 0x20 0xc8 0xe0 +0xd0 0x20 0x48 0xe0 + + +#------------------------------------------------------------------------------ +# FIXME: LDRD (label) +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# LDRD (register) +#------------------------------------------------------------------------------ +# CHECK: ldrd r4, r5, [r1, r3] +# CHECK: ldrd r4, r5, [r7, r2]! +# CHECK: ldrd r0, r1, [r8], r12 +# CHECK: ldrd r0, r1, [r8], -r12 + +0xd3 0x40 0x81 0xe1 +0xd2 0x40 0xa7 0xe1 +0xdc 0x00 0x88 0xe0 +0xdc 0x00 0x08 0xe0 + + +#------------------------------------------------------------------------------ +# LDRH (immediate) +#------------------------------------------------------------------------------ +# CHECK: ldrh r3, [r4 +# CHECK: ldrh r2, [r7, #4 +# CHECK: ldrh r1, [r8, #64]! +# CHECK: ldrh r12, [sp], #4 + +0xb0 0x30 0xd4 0xe1 +0xb4 0x20 0xd7 0xe1 +0xb0 0x14 0xf8 0xe1 +0xb4 0xc0 0xdd 0xe0 + + +#------------------------------------------------------------------------------ +# FIXME: LDRH (label) +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# LDRH (register) +#------------------------------------------------------------------------------ +# CHECK: ldrh r6, [r5, r4 +# CHECK: ldrh r3, [r8, r11]! +# CHECK: ldrh r1, [r2, -r1]! +# CHECK: ldrh r9, [r7], r2 +# CHECK: ldrh r4, [r3], -r2 + +0xb4 0x60 0x95 0xe1 +0xbb 0x30 0xb8 0xe1 +0xb1 0x10 0x32 0xe1 +0xb2 0x90 0x97 0xe0 +0xb2 0x40 0x13 0xe0 + + +#------------------------------------------------------------------------------ +# LDRHT +#------------------------------------------------------------------------------ +# CHECK: ldrht r9, [r7], #128 +# CHECK: ldrht r4, [r3], #-75 +# CHECK: ldrht r9, [r7], r2 +# CHECK: ldrht r4, [r3], -r2 + +0xb0 0x98 0xf7 0xe0 +0xbb 0x44 0x73 0xe0 +0xb2 0x90 0xb7 0xe0 +0xb2 0x40 0x33 0xe0 + + +#------------------------------------------------------------------------------ +# LDRSB (immediate) +#------------------------------------------------------------------------------ +# CHECK: ldrsb r3, [r4 +# CHECK: ldrsb r2, [r7, #17 +# CHECK: ldrsb r1, [r8, #255]! +# CHECK: ldrsb r12, [sp], #9 + +0xd0 0x30 0xd4 0xe1 +0xd1 0x21 0xd7 0xe1 +0xdf 0x1f 0xf8 0xe1 +0xd9 0xc0 0xdd 0xe0 + + +#------------------------------------------------------------------------------ +# FIXME: LDRSB (label) +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# LDRSB (register) +#------------------------------------------------------------------------------ +# CHECK: ldrsb r6, [r5, r4 +# CHECK: ldrsb r3, [r8, r11]! +# CHECK: ldrsb r1, [r2, -r1]! +# CHECK: ldrsb r9, [r7], r2 +# CHECK: ldrsb r4, [r3], -r2 + + +0xd4 0x60 0x95 0xe1 +0xdb 0x30 0xb8 0xe1 +0xd1 0x10 0x32 0xe1 +0xd2 0x90 0x97 0xe0 +0xd2 0x40 0x13 0xe0 + + +#------------------------------------------------------------------------------ +# LDRSBT +#------------------------------------------------------------------------------ +# CHECK: ldrsbt r5, [r6], #1 +# CHECK: ldrsbt r3, [r8], #-12 +# CHECK: ldrsbt r8, [r9], r5 +# CHECK: ldrsbt r2, [r1], -r4 + +0xd1 0x50 0xf6 0xe0 +0xdc 0x30 0x78 0xe0 +0xd5 0x80 0xb9 0xe0 +0xd4 0x20 0x31 0xe0 + + +#------------------------------------------------------------------------------ +# LDRSH (immediate) +#------------------------------------------------------------------------------ +# CHECK: ldrsh r5, [r9 +# CHECK: ldrsh r4, [r5, #7 +# CHECK: ldrsh r3, [r6, #55]! +# CHECK: ldrsh r2, [r7], #-9 + +0xf0 0x50 0xd9 0xe1 +0xf7 0x40 0xd5 0xe1 +0xf7 0x33 0xf6 0xe1 +0xf9 0x20 0x57 0xe0 + + +#------------------------------------------------------------------------------ +# FIXME: LDRSH (label) +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# LDRSH (register) +#------------------------------------------------------------------------------ +# CHECK: ldrsh r3, [r1, r5 +# CHECK: ldrsh r4, [r6, r1]! +# CHECK: ldrsh r5, [r3, -r6]! +# CHECK: ldrsh r6, [r9], r8 +# CHECK: ldrsh r7, [r8], -r3 + +0xf5 0x30 0x91 0xe1 +0xf1 0x40 0xb6 0xe1 +0xf6 0x50 0x33 0xe1 +0xf8 0x60 0x99 0xe0 +0xf3 0x70 0x18 0xe0 + + +#------------------------------------------------------------------------------ +# LDRSHT +#------------------------------------------------------------------------------ +# CHECK: ldrsht r5, [r6], #1 +# CHECK: ldrsht r3, [r8], #-12 +# CHECK: ldrsht r8, [r9], r5 +# CHECK: ldrsht r2, [r1], -r4 + +0xf1 0x50 0xf6 0xe0 +0xfc 0x30 0x78 0xe0 +0xf5 0x80 0xb9 0xe0 +0xf4 0x20 0x31 0xe0 + + +#------------------------------------------------------------------------------ +# STR (immediate) +#------------------------------------------------------------------------------ +# CHECK: str r8, [r12 +# CHECK: str r7, [r1, #12 +# CHECK: str r3, [r5, #40]! +# CHECK: str r9, [sp], #4095 +# CHECK: str r1, [r7], #-128 + +0x00 0x80 0x8c 0xe5 +0x0c 0x70 0x81 0xe5 +0x28 0x30 0xa5 0xe5 +0xff 0x9f 0x8d 0xe4 +0x80 0x10 0x07 0xe4 + + +#------------------------------------------------------------------------------ +# FIXME: STR (literal) +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# STR (register) +#------------------------------------------------------------------------------ +# CHECK: str r9, [r6, r3 +# CHECK: str r8, [r0, -r2 +# CHECK: str r7, [r1, r6]! +# CHECK: str r6, [sp, -r1]! +# CHECK: str r5, [r3], r9 +# CHECK: str r4, [r2], -r5 +# CHECK: str r3, [r4, -r2, lsl #2 +# CHECK: str r2, [r7], r3, asr #24 + +0x03 0x90 0x86 0xe7 +0x02 0x80 0x00 0xe7 +0x06 0x70 0xa1 0xe7 +0x01 0x60 0x2d 0xe7 +0x09 0x50 0x83 0xe6 +0x05 0x40 0x02 0xe6 +0x02 0x31 0x04 0xe7 +0x43 0x2c 0x87 0xe6 + + +#------------------------------------------------------------------------------ +# STRB (immediate) +#------------------------------------------------------------------------------ +# CHECK: strb r9, [r2 +# CHECK: strb r7, [r1, #3 +# CHECK: strb r6, [r4, #405]! +# CHECK: strb r5, [r7], #72 +# CHECK: strb r1, [sp], #-1 + +0x00 0x90 0xc2 0xe5 +0x03 0x70 0xc1 0xe5 +0x95 0x61 0xe4 0xe5 +0x48 0x50 0xc7 0xe4 +0x01 0x10 0x4d 0xe4 + +#------------------------------------------------------------------------------ +# FIXME: STRB (literal) +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# STRB (register) +#------------------------------------------------------------------------------ +# CHECK: strb r1, [r2, r9 +# CHECK: strb r2, [r3, -r8 +# CHECK: strb r3, [r4, r7]! +# CHECK: strb r4, [r5, -r6]! +# CHECK: strb r5, [r6], r5 +# CHECK: strb r6, [r2], -r4 +# CHECK: strb r7, [r12, -r3, lsl #5 +# CHECK: strb sp, [r7], r2, asr #12 + +0x09 0x10 0xc2 0xe7 +0x08 0x20 0x43 0xe7 +0x07 0x30 0xe4 0xe7 +0x06 0x40 0x65 0xe7 +0x05 0x50 0xc6 0xe6 +0x04 0x60 0x42 0xe6 +0x83 0x72 0x4c 0xe7 +0x42 0xd6 0xc7 0xe6 + + +#------------------------------------------------------------------------------ +# STRBT +#------------------------------------------------------------------------------ +# FIXME: Optional offset operand. +# CHECK: strbt r6, [r2], #12 +# CHECK: strbt r5, [r6], #-13 +# CHECK: strbt r4, [r9], r5 +# CHECK: strbt r3, [r8], -r2, lsl #3 + +0x0c 0x60 0xe2 0xe4 +0x0d 0x50 0x66 0xe4 +0x05 0x40 0xe9 0xe6 +0x82 0x31 0x68 0xe6 + + +#------------------------------------------------------------------------------ +# STRD (immediate) +#------------------------------------------------------------------------------ +# CHECK: strd r0, r1, [r4] +# CHECK: strd r2, r3, [r6, #1] +# CHECK: strd r2, r3, [r7, #22]! +# CHECK: strd r4, r5, [r8], #7 +# CHECK: strd r4, r5, [sp], #0 +# CHECK: strd r6, r7, [lr], #0 +# CHECK: strd r6, r7, [r9], #-0 + +0xf0 0x00 0xc4 0xe1 +0xf1 0x20 0xc6 0xe1 +0xf6 0x21 0xe7 0xe1 +0xf7 0x40 0xc8 0xe0 +0xf0 0x40 0xcd 0xe0 +0xf0 0x60 0xce 0xe0 +0xf0 0x60 0x49 0xe0 + + +#------------------------------------------------------------------------------ +# FIXME: STRD (label) +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# STRD (register) +#------------------------------------------------------------------------------ +# CHECK: strd r8, r9, [r4, r1] +# CHECK: strd r6, r7, [r3, r9]! +# CHECK: strd r6, r7, [r5], r8 +# CHECK: strd r4, r5, [r12], -r10 + +0xf1 0x80 0x84 0xe1 +0xf9 0x60 0xa3 0xe1 +0xf8 0x60 0x85 0xe0 +0xfa 0x40 0x0c 0xe0 + +#------------------------------------------------------------------------------ +# STRH (immediate) +#------------------------------------------------------------------------------ +# CHECK: strh r3, [r4 +# CHECK: strh r2, [r7, #4 +# CHECK: strh r1, [r8, #64]! +# CHECK: strh r12, [sp], #4 + +0xb0 0x30 0xc4 0xe1 +0xb4 0x20 0xc7 0xe1 +0xb0 0x14 0xe8 0xe1 +0xb4 0xc0 0xcd 0xe0 + + +#------------------------------------------------------------------------------ +# FIXME: STRH (label) +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# STRH (register) +#------------------------------------------------------------------------------ +# CHECK: strh r6, [r5, r4 +# CHECK: strh r3, [r8, r11]! +# CHECK: strh r1, [r2, -r1]! +# CHECK: strh r9, [r7], r2 +# CHECK: strh r4, [r3], -r2 + +0xb4 0x60 0x85 0xe1 +0xbb 0x30 0xa8 0xe1 +0xb1 0x10 0x22 0xe1 +0xb2 0x90 0x87 0xe0 +0xb2 0x40 0x03 0xe0 + +#------------------------------------------------------------------------------ +# STRHT +#------------------------------------------------------------------------------ +# CHECK: strht r2, [r5], #76 +# CHECK: strht r8, [r1], #-25 +# CHECK: strht r5, [r3], r4 +# CHECK: strht r6, [r8], -r0 + +0xbc 0x24 0xe5 0xe0 +0xb9 0x81 0x61 0xe0 +0xb4 0x50 0xa3 0xe0 +0xb0 0x60 0x28 0xe0 diff --git a/test/MC/Disassembler/ARM/neon-tests.txt b/test/MC/Disassembler/ARM/neon-tests.txt index 4fa57230d72d..1e03debefab6 100644 --- a/test/MC/Disassembler/ARM/neon-tests.txt +++ b/test/MC/Disassembler/ARM/neon-tests.txt @@ -1,4 +1,4 @@ -# RUN: llvm-mc --disassemble %s -triple=arm-apple-darwin9 | FileCheck %s +# RUN: llvm-mc --disassemble %s -triple=armv7-apple-darwin9 | FileCheck %s # CHECK: vbif q15, q7, q0 0x50 0xe1 0x7e 0xf3 @@ -24,7 +24,7 @@ # CHECK: vld1.32 {d3[], d4[]}, [r0, :32]! 0xbd 0x3c 0xa0 0xf4 -# CHECK: vld4.16 {d3[], d4[], d5[], d6[]}, [r0, :64]! +# CHECK: vld4.16 {d3[], d5[], d7[], d9[]}, [r0, :64]! 0x7d 0x3f 0xa0 0xf4 # CHECK: vorr d0, d15, d15 @@ -87,5 +87,5 @@ # CHECK: usada8mi r8, r9, r5, r9 0x19 0x95 0x88 0x47 -# CHECK: vext.8 q4, q2, q1, #4 +# CHECK: vext.32 q4, q2, q1, #1 0x42 0x84 0xb4 0xf2 diff --git a/test/MC/Disassembler/ARM/neon.txt b/test/MC/Disassembler/ARM/neon.txt new file mode 100644 index 000000000000..5d2df93ed780 --- /dev/null +++ b/test/MC/Disassembler/ARM/neon.txt @@ -0,0 +1,1858 @@ +# RUN: llvm-mc -triple armv7-unknown-unknown -disassemble -mattr +fp16 < %s | FileCheck %s + +0x20 0x03 0xf1 0xf3 +# CHECK: vabs.s8 d16, d16 +0x20 0x03 0xf5 0xf3 +# CHECK: vabs.s16 d16, d16 +0x20 0x03 0xf9 0xf3 +# CHECK: vabs.s32 d16, d16 +0x20 0x07 0xf9 0xf3 +# CHECK: vabs.f32 d16, d16 +0x60 0x03 0xf1 0xf3 +# CHECK: vabs.s8 q8, q8 +0x60 0x03 0xf5 0xf3 +# CHECK: vabs.s16 q8, q8 +0x60 0x03 0xf9 0xf3 +# CHECK: vabs.s32 q8, q8 +0x60 0x07 0xf9 0xf3 +# CHECK: vabs.f32 q8, q8 + +0x20 0x07 0xf0 0xf3 +# CHECK: vqabs.s8 d16, d16 +0x20 0x07 0xf4 0xf3 +# CHECK: vqabs.s16 d16, d16 +0x20 0x07 0xf8 0xf3 +# CHECK: vqabs.s32 d16, d16 +0x60 0x07 0xf0 0xf3 +# CHECK: vqabs.s8 q8, q8 +0x60 0x07 0xf4 0xf3 +# CHECK: vqabs.s16 q8, q8 +0x60 0x07 0xf8 0xf3 +# CHECK: vqabs.s32 q8, q8 + +0xa1 0x07 0x40 0xf2 +# CHECK: vabd.s8 d16, d16, d17 +0xa1 0x07 0x50 0xf2 +# CHECK: vabd.s16 d16, d16, d17 +0xa1 0x07 0x60 0xf2 +# CHECK: vabd.s32 d16, d16, d17 +0xa1 0x07 0x40 0xf3 +# CHECK: vabd.u8 d16, d16, d17 +0xa1 0x07 0x50 0xf3 +# CHECK: vabd.u16 d16, d16, d17 + 0xa1 0x07 0x60 0xf3 +# CHECK: vabd.u32 d16, d16, d17 +0xa1 0x0d 0x60 0xf3 +# CHECK: vabd.f32 d16, d16, d17 +0xe2 0x07 0x40 0xf2 +# CHECK: vabd.s8 q8, q8, q9 +0xe2 0x07 0x50 0xf2 +# CHECK: vabd.s16 q8, q8, q9 +0xe2 0x07 0x60 0xf2 +# CHECK: vabd.s32 q8, q8, q9 +0xe2 0x07 0x40 0xf3 +# CHECK: vabd.u8 q8, q8, q9 +0xe2 0x07 0x50 0xf3 +# CHECK: vabd.u16 q8, q8, q9 +0xe2 0x07 0x60 0xf3 +# CHECK: vabd.u32 q8, q8, q9 +0xe2 0x0d 0x60 0xf3 +# CHECK: vabd.f32 q8, q8, q9 + +0xa1 0x07 0xc0 0xf2 +# CHECK: vabdl.s8 q8, d16, d17 +0xa1 0x07 0xd0 0xf2 +# CHECK: vabdl.s16 q8, d16, d17 +0xa1 0x07 0xe0 0xf2 +# CHECK: vabdl.s32 q8, d16, d17 +0xa1 0x07 0xc0 0xf3 +# CHECK: vabdl.u8 q8, d16, d17 +0xa1 0x07 0xd0 0xf3 +# CHECK: vabdl.u16 q8, d16, d17 +0xa1 0x07 0xe0 0xf3 +# CHECK: vabdl.u32 q8, d16, d17 + +0xb1 0x07 0x42 0xf2 +# CHECK: vaba.s8 d16, d18, d17 +0xb1 0x07 0x52 0xf2 +# CHECK: vaba.s16 d16, d18, d17 +0xb1 0x07 0x62 0xf2 +# CHECK: vaba.s32 d16, d18, d17 +0xb1 0x07 0x42 0xf3 +# CHECK: vaba.u8 d16, d18, d17 +0xb1 0x07 0x52 0xf3 +# CHECK: vaba.u16 d16, d18, d17 +0xb1 0x07 0x62 0xf3 +# CHECK: vaba.u32 d16, d18, d17 +0xf4 0x27 0x40 0xf2 +# CHECK: vaba.s8 q9, q8, q10 +0xf4 0x27 0x50 0xf2 +# CHECK: vaba.s16 q9, q8, q10 +0xf4 0x27 0x60 0xf2 +# CHECK: vaba.s32 q9, q8, q10 +0xf4 0x27 0x40 0xf3 +# CHECK: vaba.u8 q9, q8, q10 +0xf4 0x27 0x50 0xf3 +# CHECK: vaba.u16 q9, q8, q10 +0xf4 0x27 0x60 0xf3 +# CHECK: vaba.u32 q9, q8, q10 + +0xa2 0x05 0xc3 0xf2 +# CHECK: vabal.s8 q8, d19, d18 +0xa2 0x05 0xd3 0xf2 +# CHECK: vabal.s16 q8, d19, d18 +0xa2 0x05 0xe3 0xf2 +# CHECK: vabal.s32 q8, d19, d18 +0xa2 0x05 0xc3 0xf3 +# CHECK: vabal.u8 q8, d19, d18 +0xa2 0x05 0xd3 0xf3 +# CHECK: vabal.u16 q8, d19, d18 +0xa2 0x05 0xe3 0xf3 +# CHECK: vabal.u32 q8, d19, d18 + + + + +0xa0 0x08 0x41 0xf2 +# CHECK: vadd.i8 d16, d17, d16 +0xa0 0x08 0x51 0xf2 +# CHECK: vadd.i16 d16, d17, d16 +0xa0 0x08 0x71 0xf2 +# CHECK: vadd.i64 d16, d17, d16 +0xa0 0x08 0x61 0xf2 +# CHECK: vadd.i32 d16, d17, d16 +0xa1 0x0d 0x40 0xf2 +# CHECK: vadd.f32 d16, d16, d17 +0xe2 0x0d 0x40 0xf2 +# CHECK: vadd.f32 q8, q8, q9 + +0xa0 0x00 0xc1 0xf2 +# CHECK: vaddl.s8 q8, d17, d16 +0xa0 0x00 0xd1 0xf2 +# CHECK: vaddl.s16 q8, d17, d16 +0xa0 0x00 0xe1 0xf2 +# CHECK: vaddl.s32 q8, d17, d16 +0xa0 0x00 0xc1 0xf3 +# CHECK: vaddl.u8 q8, d17, d16 +0xa0 0x00 0xd1 0xf3 +# CHECK: vaddl.u16 q8, d17, d16 +0xa0 0x00 0xe1 0xf3 +# CHECK: vaddl.u32 q8, d17, d16 + +0xa2 0x01 0xc0 0xf2 +# CHECK: vaddw.s8 q8, q8, d18 +0xa2 0x01 0xd0 0xf2 +# CHECK: vaddw.s16 q8, q8, d18 +0xa2 0x01 0xe0 0xf2 +# CHECK: vaddw.s32 q8, q8, d18 +0xa2 0x01 0xc0 0xf3 +# CHECK: vaddw.u8 q8, q8, d18 +0xa2 0x01 0xd0 0xf3 +# CHECK: vaddw.u16 q8, q8, d18 +0xa2 0x01 0xe0 0xf3 +# CHECK: vaddw.u32 q8, q8, d18 + +0xa1 0x00 0x40 0xf2 +# CHECK: vhadd.s8 d16, d16, d17 +0xa1 0x00 0x50 0xf2 +# CHECK: vhadd.s16 d16, d16, d17 +0xa1 0x00 0x60 0xf2 +# CHECK: vhadd.s32 d16, d16, d17 +0xa1 0x00 0x40 0xf3 +# CHECK: vhadd.u8 d16, d16, d17 +0xa1 0x00 0x50 0xf3 +# CHECK: vhadd.u16 d16, d16, d17 +0xa1 0x00 0x60 0xf3 +# CHECK: vhadd.u32 d16, d16, d17 +0xe2 0x00 0x40 0xf2 +# CHECK: vhadd.s8 q8, q8, q9 +0xe2 0x00 0x50 0xf2 +# CHECK: vhadd.s16 q8, q8, q9 +0xe2 0x00 0x60 0xf2 +# CHECK: vhadd.s32 q8, q8, q9 + 0xe2 0x00 0x40 0xf3 +# CHECK: vhadd.u8 q8, q8, q9 +0xe2 0x00 0x50 0xf3 +# CHECK: vhadd.u16 q8, q8, q9 +0xe2 0x00 0x60 0xf3 +# CHECK: vhadd.u32 q8, q8, q9 + +0xa1 0x01 0x40 0xf2 +# CHECK: vrhadd.s8 d16, d16, d17 +0xa1 0x01 0x50 0xf2 +# CHECK: vrhadd.s16 d16, d16, d17 +0xa1 0x01 0x60 0xf2 +# CHECK: vrhadd.s32 d16, d16, d17 +0xa1 0x01 0x40 0xf3 +# CHECK: vrhadd.u8 d16, d16, d17 +0xa1 0x01 0x50 0xf3 +# CHECK: vrhadd.u16 d16, d16, d17 +0xa1 0x01 0x60 0xf3 +# CHECK: vrhadd.u32 d16, d16, d17 +0xe2 0x01 0x40 0xf2 +# CHECK: vrhadd.s8 q8, q8, q9 +0xe2 0x01 0x50 0xf2 +# CHECK: vrhadd.s16 q8, q8, q9 +0xe2 0x01 0x60 0xf2 +# CHECK: vrhadd.s32 q8, q8, q9 +0xe2 0x01 0x40 0xf3 +# CHECK: vrhadd.u8 q8, q8, q9 +0xe2 0x01 0x50 0xf3 +# CHECK: vrhadd.u16 q8, q8, q9 +0xe2 0x01 0x60 0xf3 +# CHECK: vrhadd.u32 q8, q8, q9 + +0xb1 0x00 0x40 0xf2 +# CHECK: vqadd.s8 d16, d16, d17 +0xb1 0x00 0x50 0xf2 +# CHECK: vqadd.s16 d16, d16, d17 +0xb1 0x00 0x60 0xf2 +# CHECK: vqadd.s32 d16, d16, d17 +0xb1 0x00 0x70 0xf2 +# CHECK: vqadd.s64 d16, d16, d17 +0xb1 0x00 0x40 0xf3 +# CHECK: vqadd.u8 d16, d16, d17 +0xb1 0x00 0x50 0xf3 +# CHECK: vqadd.u16 d16, d16, d17 +0xb1 0x00 0x60 0xf3 +# CHECK: vqadd.u32 d16, d16, d17 +0xb1 0x00 0x70 0xf3 +# CHECK: vqadd.u64 d16, d16, d17 +0xf2 0x00 0x40 0xf2 +# CHECK: vqadd.s8 q8, q8, q9 +0xf2 0x00 0x50 0xf2 +# CHECK: vqadd.s16 q8, q8, q9 +0xf2 0x00 0x60 0xf2 +# CHECK: vqadd.s32 q8, q8, q9 +0xf2 0x00 0x70 0xf2 +# CHECK: vqadd.s64 q8, q8, q9 +0xf2 0x00 0x40 0xf3 +# CHECK: vqadd.u8 q8, q8, q9 +0xf2 0x00 0x50 0xf3 +# CHECK: vqadd.u16 q8, q8, q9 +0xf2 0x00 0x60 0xf3 +# CHECK: vqadd.u32 q8, q8, q9 +0xf2 0x00 0x70 0xf3 +# CHECK: vqadd.u64 q8, q8, q9 + +0xa2 0x04 0xc0 0xf2 +# CHECK: vaddhn.i16 d16, q8, q9 +0xa2 0x04 0xd0 0xf2 +# CHECK: vaddhn.i32 d16, q8, q9 +0xa2 0x04 0xe0 0xf2 +# CHECK: vaddhn.i64 d16, q8, q9 +0xa2 0x04 0xc0 0xf3 +# CHECK: vraddhn.i16 d16, q8, q9 +0xa2 0x04 0xd0 0xf3 +# CHECK: vraddhn.i32 d16, q8, q9 +0xa2 0x04 0xe0 0xf3 +# CHECK: vraddhn.i64 d16, q8, q9 + + +0x20 0x05 0xf0 0xf3 +# CHECK: vcnt.8 d16, d16 +0x60 0x05 0xf0 0xf3 +# CHECK: vcnt.8 q8, q8 +0xa0 0x04 0xf0 0xf3 +# CHECK: vclz.i8 d16, d16 +0xa0 0x04 0xf4 0xf3 +# CHECK: vclz.i16 d16, d16 +0xa0 0x04 0xf8 0xf3 +# CHECK: vclz.i32 d16, d16 +0xe0 0x04 0xf0 0xf3 +# CHECK: vclz.i8 q8, q8 +0xe0 0x04 0xf4 0xf3 +# CHECK: vclz.i16 q8, q8 +0xe0 0x04 0xf8 0xf3 +# CHECK: vclz.i32 q8, q8 +0x20 0x04 0xf0 0xf3 +# CHECK: vcls.s8 d16, d16 +0x20 0x04 0xf4 0xf3 +# CHECK: vcls.s16 d16, d16 +0x20 0x04 0xf8 0xf3 +# CHECK: vcls.s32 d16, d16 +0x60 0x04 0xf0 0xf3 +# CHECK: vcls.s8 q8, q8 +0x60 0x04 0xf4 0xf3 +# CHECK: vcls.s16 q8, q8 +0x60 0x04 0xf8 0xf3 +# CHECK: vcls.s32 q8, q8 + + + + +0xb0 0x01 0x41 0xf2 +# CHECK: vand d16, d17, d16 +0xf2 0x01 0x40 0xf2 +# CHECK: vand q8, q8, q9 + +0xb0 0x01 0x41 0xf3 +# CHECK: veor d16, d17, d16 +0xf2 0x01 0x40 0xf3 +# CHECK: veor q8, q8, q9 + +0xb0 0x01 0x61 0xf2 +# CHECK: vorr d16, d17, d16 +0xf2 0x01 0x60 0xf2 +# CHECK: vorr q8, q8, q9 +0x11 0x07 0xc0 0xf2 +# CHECK: vorr.i32 d16, #0x1000000 +0x51 0x07 0xc0 0xf2 +# CHECK: vorr.i32 q8, #0x1000000 +0x50 0x01 0xc0 0xf2 +# CHECK: vorr.i32 q8, #0x0 + +0xb0 0x01 0x51 0xf2 +# CHECK: vbic d16, d17, d16 +0xf2 0x01 0x50 0xf2 +# CHECK: vbic q8, q8, q9 +0x3f 0x07 0xc7 0xf3 +# CHECK: vbic.i32 d16, #0xFF000000 +0x7f 0x07 0xc7 0xf3 +# CHECK: vbic.i32 q8, #0xFF000000 + +0xb0 0x01 0x71 0xf2 +# CHECK: vorn d16, d17, d16 +0xf2 0x01 0x70 0xf2 +# CHECK: vorn q8, q8, q9 + +0xa0 0x05 0xf0 0xf3 +# CHECK: vmvn d16, d16 +0xe0 0x05 0xf0 0xf3 +# CHECK: vmvn q8, q8 + +0xb0 0x21 0x51 0xf3 +# CHECK: vbsl d18, d17, d16 +0xf2 0x01 0x54 0xf3 +# CHECK: vbsl q8, q10, q9 + + +# CHECK: vceq.i8 d16, d16, d17 +# CHECK: vceq.i16 d16, d16, d17 +# CHECK: vceq.i32 d16, d16, d17 +# CHECK: vceq.f32 d16, d16, d17 +# CHECK: vceq.i8 q8, q8, q9 +# CHECK: vceq.i16 q8, q8, q9 +# CHECK: vceq.i32 q8, q8, q9 +# CHECK: vceq.f32 q8, q8, q9 + +0xb1 0x08 0x40 0xf3 +0xb1 0x08 0x50 0xf3 +0xb1 0x08 0x60 0xf3 +0xa1 0x0e 0x40 0xf2 +0xf2 0x08 0x40 0xf3 +0xf2 0x08 0x50 0xf3 +0xf2 0x08 0x60 0xf3 +0xe2 0x0e 0x40 0xf2 + +# CHECK: vcge.s8 d16, d16, d17 +# CHECK: vcge.s16 d16, d16, d17 +# CHECK: vcge.s32 d16, d16, d17 +# CHECK: vcge.u8 d16, d16, d17 +# CHECK: vcge.u16 d16, d16, d17 +# CHECK: vcge.u32 d16, d16, d17 +# CHECK: vcge.f32 d16, d16, d17 +# CHECK: vcge.s8 q8, q8, q9 +# CHECK: vcge.s16 q8, q8, q9 +# CHECK: vcge.s32 q8, q8, q9 +# CHECK: vcge.u8 q8, q8, q9 +# CHECK: vcge.u16 q8, q8, q9 +# CHECK: vcge.u32 q8, q8, q9 +# CHECK: vcge.f32 q8, q8, q9 +# CHECK: vacge.f32 d16, d16, d17 +# CHECK: vacge.f32 q8, q8, q9 + +0xb1 0x03 0x40 0xf2 +0xb1 0x03 0x50 0xf2 +0xb1 0x03 0x60 0xf2 +0xb1 0x03 0x40 0xf3 +0xb1 0x03 0x50 0xf3 +0xb1 0x03 0x60 0xf3 +0xa1 0x0e 0x40 0xf3 +0xf2 0x03 0x40 0xf2 +0xf2 0x03 0x50 0xf2 +0xf2 0x03 0x60 0xf2 +0xf2 0x03 0x40 0xf3 +0xf2 0x03 0x50 0xf3 +0xf2 0x03 0x60 0xf3 +0xe2 0x0e 0x40 0xf3 +0xb1 0x0e 0x40 0xf3 +0xf2 0x0e 0x40 0xf3 + +# CHECK: vcgt.s8 d16, d16, d17 +# CHECK: vcgt.s16 d16, d16, d17 +# CHECK: vcgt.s32 d16, d16, d17 +# CHECK: vcgt.u8 d16, d16, d17 +# CHECK: vcgt.u16 d16, d16, d17 +# CHECK: vcgt.u32 d16, d16, d17 +# CHECK: vcgt.f32 d16, d16, d17 +# CHECK: vcgt.s8 q8, q8, q9 +# CHECK: vcgt.s16 q8, q8, q9 +# CHECK: vcgt.s32 q8, q8, q9 +# CHECK: vcgt.u8 q8, q8, q9 +# CHECK: vcgt.u16 q8, q8, q9 +# CHECK: vcgt.u32 q8, q8, q9 +# CHECK: vcgt.f32 q8, q8, q9 +# CHECK: vacgt.f32 d16, d16, d17 +# CHECK: vacgt.f32 q8, q8, q9 + +0xa1 0x03 0x40 0xf2 +0xa1 0x03 0x50 0xf2 +0xa1 0x03 0x60 0xf2 +0xa1 0x03 0x40 0xf3 +0xa1 0x03 0x50 0xf3 +0xa1 0x03 0x60 0xf3 +0xa1 0x0e 0x60 0xf3 +0xe2 0x03 0x40 0xf2 +0xe2 0x03 0x50 0xf2 +0xe2 0x03 0x60 0xf2 +0xe2 0x03 0x40 0xf3 +0xe2 0x03 0x50 0xf3 +0xe2 0x03 0x60 0xf3 +0xe2 0x0e 0x60 0xf3 +0xb1 0x0e 0x60 0xf3 +0xf2 0x0e 0x60 0xf3 + +# CHECK: vtst.8 d16, d16, d17 +# CHECK: vtst.16 d16, d16, d17 +# CHECK: vtst.32 d16, d16, d17 +# CHECK: vtst.8 q8, q8, q9 +# CHECK: vtst.16 q8, q8, q9 +# CHECK: vtst.32 q8, q8, q9 + +0xb1 0x08 0x40 0xf2 +0xb1 0x08 0x50 0xf2 +0xb1 0x08 0x60 0xf2 +0xf2 0x08 0x40 0xf2 +0xf2 0x08 0x50 0xf2 +0xf2 0x08 0x60 0xf2 + +# CHECK: vceq.i8 d16, d16, #0 +# CHECK: vcge.s8 d16, d16, #0 +# CHECK: vcle.s8 d16, d16, #0 +# CHECK: vcgt.s8 d16, d16, #0 +# CHECK: vclt.s8 d16, d16, #0 + +0x20 0x01 0xf1 0xf3 +0xa0 0x00 0xf1 0xf3 +0xa0 0x01 0xf1 0xf3 +0x20 0x00 0xf1 0xf3 +0x20 0x02 0xf1 0xf3 + + +0x20 0x07 0xfb 0xf3 +# CHECK: vcvt.s32.f32 d16, d16 +0xa0 0x07 0xfb 0xf3 +# CHECK: vcvt.u32.f32 d16, d16 +0x20 0x06 0xfb 0xf3 +# CHECK: vcvt.f32.s32 d16, d16 +0xa0 0x06 0xfb 0xf3 +# CHECK: vcvt.f32.u32 d16, d16 +0x60 0x07 0xfb 0xf3 +# CHECK: vcvt.s32.f32 q8, q8 +0xe0 0x07 0xfb 0xf3 +# CHECK: vcvt.u32.f32 q8, q8 +0x60 0x06 0xfb 0xf3 +# CHECK: vcvt.f32.s32 q8, q8 +0xe0 0x06 0xfb 0xf3 +# CHECK: vcvt.f32.u32 q8, q8 +0x30 0x0f 0xff 0xf2 +# CHECK: vcvt.s32.f32 d16, d16, #1 +0x30 0x0f 0xff 0xf3 +# CHECK: vcvt.u32.f32 d16, d16, #1 +0x30 0x0e 0xff 0xf2 +# CHECK: vcvt.f32.s32 d16, d16, #1 +0x30 0x0e 0xff 0xf3 +# CHECK: vcvt.f32.u32 d16, d16, #1 +0x70 0x0f 0xff 0xf2 +# CHECK: vcvt.s32.f32 q8, q8, #1 +0x70 0x0f 0xff 0xf3 +# CHECK: vcvt.u32.f32 q8, q8, #1 +0x70 0x0e 0xff 0xf2 +# CHECK: vcvt.f32.s32 q8, q8, #1 +0x70 0x0e 0xff 0xf3 +# CHECK: vcvt.f32.u32 q8, q8, #1 +0x20 0x07 0xf6 0xf3 +# CHECK: vcvt.f32.f16 q8, d16 +0x20 0x06 0xf6 0xf3 +# CHECK: vcvt.f16.f32 d16, q8 + + + + +# CHECK: vdup.8 d16, r0 +# CHECK: vdup.16 d16, r0 +# CHECK: vdup.32 d16, r0 + +0x90 0x0b 0xc0 0xee +0xb0 0x0b 0x80 0xee +0x90 0x0b 0x80 0xee + +# CHECK: vdup.8 q8, r0 +# CHECK: vdup.16 q8, r0 +# CHECK: vdup.32 q8, r0 + +0x90 0x0b 0xe0 0xee +0xb0 0x0b 0xa0 0xee +0x90 0x0b 0xa0 0xee + +# CHECK: vdup.8 d16, d16[1 +# CHECK: vdup.16 d16, d16[1 +# CHECK: vdup.32 d16, d16[1 + +0x20 0x0c 0xf3 0xf3 +0x20 0x0c 0xf6 0xf3 +0x20 0x0c 0xfc 0xf3 + +# CHECK: vdup.8 q8, d16[1 +# CHECK: vdup.16 q8, d16[1 +# CHECK: vdup.32 q8, d16[1 + +0x60 0x0c 0xf3 0xf3 +0x60 0x0c 0xf6 0xf3 +0x60 0x0c 0xfc 0xf3 + + +0xb1 0x06 0x40 0xf2 +# CHECK: vmin.s8 d16, d16, d17 +0xb1 0x06 0x50 0xf2 +# CHECK: vmin.s16 d16, d16, d17 +0xb1 0x06 0x60 0xf2 +# CHECK: vmin.s32 d16, d16, d17 +0xb1 0x06 0x40 0xf3 +# CHECK: vmin.u8 d16, d16, d17 +0xb1 0x06 0x50 0xf3 +# CHECK: vmin.u16 d16, d16, d17 +0xb1 0x06 0x60 0xf3 +# CHECK: vmin.u32 d16, d16, d17 +0xa1 0x0f 0x60 0xf2 +# CHECK: vmin.f32 d16, d16, d17 +0xf2 0x06 0x40 0xf2 +# CHECK: vmin.s8 q8, q8, q9 +0xf2 0x06 0x50 0xf2 +# CHECK: vmin.s16 q8, q8, q9 +0xf2 0x06 0x60 0xf2 +# CHECK: vmin.s32 q8, q8, q9 +0xf2 0x06 0x40 0xf3 +# CHECK: vmin.u8 q8, q8, q9 +0xf2 0x06 0x50 0xf3 +# CHECK: vmin.u16 q8, q8, q9 +0xf2 0x06 0x60 0xf3 +# CHECK: vmin.u32 q8, q8, q9 +0xe2 0x0f 0x60 0xf2 +# CHECK: vmin.f32 q8, q8, q9 +0xa1 0x06 0x40 0xf2 +# CHECK: vmax.s8 d16, d16, d17 +0xa1 0x06 0x50 0xf2 +# CHECK: vmax.s16 d16, d16, d17 +0xa1 0x06 0x60 0xf2 +# CHECK: vmax.s32 d16, d16, d17 +0xa1 0x06 0x40 0xf3 +# CHECK: vmax.u8 d16, d16, d17 +0xa1 0x06 0x50 0xf3 +# CHECK: vmax.u16 d16, d16, d17 +0xa1 0x06 0x60 0xf3 +# CHECK: vmax.u32 d16, d16, d17 +0xa1 0x0f 0x40 0xf2 +# CHECK: vmax.f32 d16, d16, d17 +0xe2 0x06 0x40 0xf2 +# CHECK: vmax.s8 q8, q8, q9 +0xe2 0x06 0x50 0xf2 +# CHECK: vmax.s16 q8, q8, q9 +0xe2 0x06 0x60 0xf2 +# CHECK: vmax.s32 q8, q8, q9 +0xe2 0x06 0x40 0xf3 +# CHECK: vmax.u8 q8, q8, q9 +0xe2 0x06 0x50 0xf3 +# CHECK: vmax.u16 q8, q8, q9 +0xe2 0x06 0x60 0xf3 +# CHECK: vmax.u32 q8, q8, q9 +0xe2 0x0f 0x40 0xf2 +# CHECK: vmax.f32 q8, q8, q9 + + + +0x18 0x0e 0xc0 0xf2 +# CHECK: vmov.i8 d16, #0x8 +0x10 0x08 0xc1 0xf2 +# CHECK: vmov.i16 d16, #0x10 +0x10 0x0a 0xc1 0xf2 +# CHECK: vmov.i16 d16, #0x1000 +0x10 0x00 0xc2 0xf2 +# CHECK: vmov.i32 d16, #0x20 +0x10 0x02 0xc2 0xf2 +# CHECK: vmov.i32 d16, #0x2000 +0x10 0x04 0xc2 0xf2 +# CHECK: vmov.i32 d16, #0x200000 +0x10 0x06 0xc2 0xf2 +# CHECK: vmov.i32 d16, #0x20000000 +0x10 0x0c 0xc2 0xf2 +# CHECK: vmov.i32 d16, #0x20FF +0x10 0x0d 0xc2 0xf2 +# CHECK: vmov.i32 d16, #0x20FFFF +0x33 0x0e 0xc1 0xf3 +# CHECK: vmov.i64 d16, #0xFF0000FF0000FFFF +0x58 0x0e 0xc0 0xf2 +# CHECK: vmov.i8 q8, #0x8 +0x50 0x08 0xc1 0xf2 +# CHECK: vmov.i16 q8, #0x10 +0x50 0x0a 0xc1 0xf2 +# CHECK: vmov.i16 q8, #0x1000 +0x50 0x00 0xc2 0xf2 +# CHECK: vmov.i32 q8, #0x20 +0x50 0x02 0xc2 0xf2 +# CHECK: vmov.i32 q8, #0x2000 +0x50 0x04 0xc2 0xf2 +# CHECK: vmov.i32 q8, #0x200000 +0x50 0x06 0xc2 0xf2 +# CHECK: vmov.i32 q8, #0x20000000 +0x50 0x0c 0xc2 0xf2 +# CHECK: vmov.i32 q8, #0x20FF +0x50 0x0d 0xc2 0xf2 +# CHECK: vmov.i32 q8, #0x20FFFF +0x73 0x0e 0xc1 0xf3 +# CHECK: vmov.i64 q8, #0xFF0000FF0000FFFF +0x30 0x08 0xc1 0xf2 +# CHECK: vmvn.i16 d16, #0x10 +0x30 0x0a 0xc1 0xf2 +# CHECK: vmvn.i16 d16, #0x1000 +0x30 0x00 0xc2 0xf2 +# CHECK: vmvn.i32 d16, #0x20 +0x30 0x02 0xc2 0xf2 +# CHECK: vmvn.i32 d16, #0x2000 +0x30 0x04 0xc2 0xf2 +# CHECK: vmvn.i32 d16, #0x200000 +0x30 0x06 0xc2 0xf2 +# CHECK: vmvn.i32 d16, #0x20000000 +0x30 0x0c 0xc2 0xf2 +# CHECK: vmvn.i32 d16, #0x20FF +0x30 0x0d 0xc2 0xf2 +# CHECK: vmvn.i32 d16, #0x20FFFF +0x30 0x0a 0xc8 0xf2 +# CHECK: vmovl.s8 q8, d16 +0x30 0x0a 0xd0 0xf2 +# CHECK: vmovl.s16 q8, d16 +0x30 0x0a 0xe0 0xf2 +# CHECK: vmovl.s32 q8, d16 +0x30 0x0a 0xc8 0xf3 +# CHECK: vmovl.u8 q8, d16 +0x30 0x0a 0xd0 0xf3 +# CHECK: vmovl.u16 q8, d16 +0x30 0x0a 0xe0 0xf3 +# CHECK: vmovl.u32 q8, d16 +0x20 0x02 0xf2 0xf3 +# CHECK: vmovn.i16 d16, q8 +0x20 0x02 0xf6 0xf3 +# CHECK: vmovn.i32 d16, q8 +0x20 0x02 0xfa 0xf3 +# CHECK: vmovn.i64 d16, q8 +0xa0 0x02 0xf2 0xf3 +# CHECK: vqmovn.s16 d16, q8 +0xa0 0x02 0xf6 0xf3 +# CHECK: vqmovn.s32 d16, q8 +0xa0 0x02 0xfa 0xf3 +# CHECK: vqmovn.s64 d16, q8 +0xe0 0x02 0xf2 0xf3 +# CHECK: vqmovn.u16 d16, q8 +0xe0 0x02 0xf6 0xf3 +# CHECK: vqmovn.u32 d16, q8 +0xe0 0x02 0xfa 0xf3 +# CHECK: vqmovn.u64 d16, q8 +0x60 0x02 0xf2 0xf3 +# CHECK: vqmovun.s16 d16, q8 +0x60 0x02 0xf6 0xf3 +# CHECK: vqmovun.s32 d16, q8 +0x60 0x02 0xfa 0xf3 +# CHECK: vqmovun.s64 d16, q8 +0xb0 0x0b 0x50 0xee +# CHECK: vmov.s8 r0, d16[1 +0xf0 0x0b 0x10 0xee +# CHECK: vmov.s16 r0, d16[1 +0xb0 0x0b 0xd0 0xee +# CHECK: vmov.u8 r0, d16[1 +0xf0 0x0b 0x90 0xee +# CHECK: vmov.u16 r0, d16[1 +0x90 0x0b 0x30 0xee +# CHECK: vmov.32 r0, d16[1 +0xb0 0x1b 0x40 0xee +# CHECK: vmov.8 d16[1], r1 +0xf0 0x1b 0x00 0xee +# CHECK: vmov.16 d16[1], r1 +0x90 0x1b 0x20 0xee +# CHECK: vmov.32 d16[1], r1 +0xb0 0x1b 0x42 0xee +# CHECK: vmov.8 d18[1], r1 +0xf0 0x1b 0x02 0xee +# CHECK: vmov.16 d18[1], r1 +0x90 0x1b 0x22 0xee +# CHECK: vmov.32 d18[1], r1 + + + +0xa1 0x09 0x42 0xf2 +# CHECK: vmla.i8 d16, d18, d17 +0xa1 0x09 0x52 0xf2 +# CHECK: vmla.i16 d16, d18, d17 +0xa1 0x09 0x62 0xf2 +# CHECK: vmla.i32 d16, d18, d17 +0xb1 0x0d 0x42 0xf2 +# CHECK: vmla.f32 d16, d18, d17 +0xe4 0x29 0x40 0xf2 +# CHECK: vmla.i8 q9, q8, q10 +0xe4 0x29 0x50 0xf2 +# CHECK: vmla.i16 q9, q8, q10 +0xe4 0x29 0x60 0xf2 +# CHECK: vmla.i32 q9, q8, q10 +0xf4 0x2d 0x40 0xf2 +# CHECK: vmla.f32 q9, q8, q10 +0xa2 0x08 0xc3 0xf2 +# CHECK: vmlal.s8 q8, d19, d18 +0xa2 0x08 0xd3 0xf2 +# CHECK: vmlal.s16 q8, d19, d18 +0xa2 0x08 0xe3 0xf2 +# CHECK: vmlal.s32 q8, d19, d18 +0xa2 0x08 0xc3 0xf3 +# CHECK: vmlal.u8 q8, d19, d18 +0xa2 0x08 0xd3 0xf3 +# CHECK: vmlal.u16 q8, d19, d18 +0xa2 0x08 0xe3 0xf3 +# CHECK: vmlal.u32 q8, d19, d18 +0xa2 0x09 0xd3 0xf2 +# CHECK: vqdmlal.s16 q8, d19, d18 +0xa2 0x09 0xe3 0xf2 +# CHECK: vqdmlal.s32 q8, d19, d18 +0xa1 0x09 0x42 0xf3 +# CHECK: vmls.i8 d16, d18, d17 +0xa1 0x09 0x52 0xf3 +# CHECK: vmls.i16 d16, d18, d17 +0xa1 0x09 0x62 0xf3 +# CHECK: vmls.i32 d16, d18, d17 +0xb1 0x0d 0x62 0xf2 +# CHECK: vmls.f32 d16, d18, d17 +0xe4 0x29 0x40 0xf3 +# CHECK: vmls.i8 q9, q8, q10 +0xe4 0x29 0x50 0xf3 +# CHECK: vmls.i16 q9, q8, q10 +0xe4 0x29 0x60 0xf3 +# CHECK: vmls.i32 q9, q8, q10 +0xf4 0x2d 0x60 0xf2 +# CHECK: vmls.f32 q9, q8, q10 +0xa2 0x0a 0xc3 0xf2 +# CHECK: vmlsl.s8 q8, d19, d18 +0xa2 0x0a 0xd3 0xf2 +# CHECK: vmlsl.s16 q8, d19, d18 +0xa2 0x0a 0xe3 0xf2 +# CHECK: vmlsl.s32 q8, d19, d18 +0xa2 0x0a 0xc3 0xf3 +# CHECK: vmlsl.u8 q8, d19, d18 +0xa2 0x0a 0xd3 0xf3 +# CHECK: vmlsl.u16 q8, d19, d18 +0xa2 0x0a 0xe3 0xf3 +# CHECK: vmlsl.u32 q8, d19, d18 +0xa2 0x0b 0xd3 0xf2 +# CHECK: vqdmlsl.s16 q8, d19, d18 +0xa2 0x0b 0xe3 0xf2 +# CHECK: vqdmlsl.s32 q8, d19, d18 + + +0xb1 0x09 0x40 0xf2 +# CHECK: vmul.i8 d16, d16, d17 +0xb1 0x09 0x50 0xf2 +# CHECK: vmul.i16 d16, d16, d17 +0xb1 0x09 0x60 0xf2 +# CHECK: vmul.i32 d16, d16, d17 +0xb1 0x0d 0x40 0xf3 +# CHECK: vmul.f32 d16, d16, d17 +0xf2 0x09 0x40 0xf2 +# CHECK: vmul.i8 q8, q8, q9 +0xf2 0x09 0x50 0xf2 +# CHECK: vmul.i16 q8, q8, q9 +0xf2 0x09 0x60 0xf2 +# CHECK: vmul.i32 q8, q8, q9 +0xf2 0x0d 0x40 0xf3 +# CHECK: vmul.f32 q8, q8, q9 +0xb1 0x09 0x40 0xf3 +# CHECK: vmul.p8 d16, d16, d17 +0xf2 0x09 0x40 0xf3 +# CHECK: vmul.p8 q8, q8, q9 +0xa1 0x0b 0x50 0xf2 +# CHECK: vqdmulh.s16 d16, d16, d17 +0xa1 0x0b 0x60 0xf2 +# CHECK: vqdmulh.s32 d16, d16, d17 +0xe2 0x0b 0x50 0xf2 +# CHECK: vqdmulh.s16 q8, q8, q9 +0xe2 0x0b 0x60 0xf2 +# CHECK: vqdmulh.s32 q8, q8, q9 +0xa1 0x0b 0x50 0xf3 +# CHECK: vqrdmulh.s16 d16, d16, d17 +0xa1 0x0b 0x60 0xf3 +# CHECK: vqrdmulh.s32 d16, d16, d17 +0xe2 0x0b 0x50 0xf3 +# CHECK: vqrdmulh.s16 q8, q8, q9 +0xe2 0x0b 0x60 0xf3 +# CHECK: vqrdmulh.s32 q8, q8, q9 +0xa1 0x0c 0xc0 0xf2 +# CHECK: vmull.s8 q8, d16, d17 +0xa1 0x0c 0xd0 0xf2 +# CHECK: vmull.s16 q8, d16, d17 +0xa1 0x0c 0xe0 0xf2 +# CHECK: vmull.s32 q8, d16, d17 +0xa1 0x0c 0xc0 0xf3 +# CHECK: vmull.u8 q8, d16, d17 +0xa1 0x0c 0xd0 0xf3 +# CHECK: vmull.u16 q8, d16, d17 +0xa1 0x0c 0xe0 0xf3 +# CHECK: vmull.u32 q8, d16, d17 +0xa1 0x0e 0xc0 0xf2 +# CHECK: vmull.p8 q8, d16, d17 +0xa1 0x0d 0xd0 0xf2 +# CHECK: vqdmull.s16 q8, d16, d17 +0xa1 0x0d 0xe0 0xf2 +# CHECK: vqdmull.s32 q8, d16, d17 + + +0xa0 0x03 0xf1 0xf3 +# CHECK: vneg.s8 d16, d16 +0xa0 0x03 0xf5 0xf3 +# CHECK: vneg.s16 d16, d16 +0xa0 0x03 0xf9 0xf3 +# CHECK: vneg.s32 d16, d16 +0xa0 0x07 0xf9 0xf3 +# CHECK: vneg.f32 d16, d16 +0xe0 0x03 0xf1 0xf3 +# CHECK: vneg.s8 q8, q8 +0xe0 0x03 0xf5 0xf3 +# CHECK: vneg.s16 q8, q8 +0xe0 0x03 0xf9 0xf3 +# CHECK: vneg.s32 q8, q8 +0xe0 0x07 0xf9 0xf3 +# CHECK: vneg.f32 q8, q8 +0xa0 0x07 0xf0 0xf3 +# CHECK: vqneg.s8 d16, d16 +0xa0 0x07 0xf4 0xf3 +# CHECK: vqneg.s16 d16, d16 +0xa0 0x07 0xf8 0xf3 +# CHECK: vqneg.s32 d16, d16 +0xe0 0x07 0xf0 0xf3 +# CHECK: vqneg.s8 q8, q8 +0xe0 0x07 0xf4 0xf3 +# CHECK: vqneg.s16 q8, q8 +0xe0 0x07 0xf8 0xf3 +# CHECK: vqneg.s32 q8, q8 + + +0xb0 0x0b 0x41 0xf2 +# CHECK: vpadd.i8 d16, d17, d16 +0xb0 0x0b 0x51 0xf2 +# CHECK: vpadd.i16 d16, d17, d16 +0xb0 0x0b 0x61 0xf2 +# CHECK: vpadd.i32 d16, d17, d16 +0xa1 0x0d 0x40 0xf3 +# CHECK: vpadd.f32 d16, d16, d17 +0x20 0x02 0xf0 0xf3 +# CHECK: vpaddl.s8 d16, d16 +0x20 0x02 0xf4 0xf3 +# CHECK: vpaddl.s16 d16, d16 +0x20 0x02 0xf8 0xf3 +# CHECK: vpaddl.s32 d16, d16 +0xa0 0x02 0xf0 0xf3 +# CHECK: vpaddl.u8 d16, d16 +0xa0 0x02 0xf4 0xf3 +# CHECK: vpaddl.u16 d16, d16 +0xa0 0x02 0xf8 0xf3 +# CHECK: vpaddl.u32 d16, d16 +0x60 0x02 0xf0 0xf3 +# CHECK: vpaddl.s8 q8, q8 +0x60 0x02 0xf4 0xf3 +# CHECK: vpaddl.s16 q8, q8 +0x60 0x02 0xf8 0xf3 +# CHECK: vpaddl.s32 q8, q8 +0xe0 0x02 0xf0 0xf3 +# CHECK: vpaddl.u8 q8, q8 +0xe0 0x02 0xf4 0xf3 +# CHECK: vpaddl.u16 q8, q8 +0xe0 0x02 0xf8 0xf3 +# CHECK: vpaddl.u32 q8, q8 +0x21 0x06 0xf0 0xf3 +# CHECK: vpadal.s8 d16, d17 +0x21 0x06 0xf4 0xf3 +# CHECK: vpadal.s16 d16, d17 +0x21 0x06 0xf8 0xf3 +# CHECK: vpadal.s32 d16, d17 +0xa1 0x06 0xf0 0xf3 +# CHECK: vpadal.u8 d16, d17 +0xa1 0x06 0xf4 0xf3 +# CHECK: vpadal.u16 d16, d17 +0xa1 0x06 0xf8 0xf3 +# CHECK: vpadal.u32 d16, d17 +0x60 0x26 0xf0 0xf3 +# CHECK: vpadal.s8 q9, q8 +0x60 0x26 0xf4 0xf3 +# CHECK: vpadal.s16 q9, q8 +0x60 0x26 0xf8 0xf3 +# CHECK: vpadal.s32 q9, q8 +0xe0 0x26 0xf0 0xf3 +# CHECK: vpadal.u8 q9, q8 +0xe0 0x26 0xf4 0xf3 +# CHECK: vpadal.u16 q9, q8 +0xe0 0x26 0xf8 0xf3 +# CHECK: vpadal.u32 q9, q8 +0xb1 0x0a 0x40 0xf2 +# CHECK: vpmin.s8 d16, d16, d17 +0xb1 0x0a 0x50 0xf2 +# CHECK: vpmin.s16 d16, d16, d17 +0xb1 0x0a 0x60 0xf2 +# CHECK: vpmin.s32 d16, d16, d17 +0xb1 0x0a 0x40 0xf3 +# CHECK: vpmin.u8 d16, d16, d17 +0xb1 0x0a 0x50 0xf3 +# CHECK: vpmin.u16 d16, d16, d17 +0xb1 0x0a 0x60 0xf3 +# CHECK: vpmin.u32 d16, d16, d17 +0xa1 0x0f 0x60 0xf3 +# CHECK: vpmin.f32 d16, d16, d17 +0xa1 0x0a 0x40 0xf2 +# CHECK: vpmax.s8 d16, d16, d17 +0xa1 0x0a 0x50 0xf2 +# CHECK: vpmax.s16 d16, d16, d17 +0xa1 0x0a 0x60 0xf2 +# CHECK: vpmax.s32 d16, d16, d17 +0xa1 0x0a 0x40 0xf3 +# CHECK: vpmax.u8 d16, d16, d17 +0xa1 0x0a 0x50 0xf3 +# CHECK: vpmax.u16 d16, d16, d17 +0xa1 0x0a 0x60 0xf3 +# CHECK: vpmax.u32 d16, d16, d17 +0xa1 0x0f 0x40 0xf3 +# CHECK: vpmax.f32 d16, d16, d17 + + +0x20 0x04 0xfb 0xf3 +# CHECK: vrecpe.u32 d16, d16 +0x60 0x04 0xfb 0xf3 +# CHECK: vrecpe.u32 q8, q8 +0x20 0x05 0xfb 0xf3 +# CHECK: vrecpe.f32 d16, d16 +0x60 0x05 0xfb 0xf3 +# CHECK: vrecpe.f32 q8, q8 +0xb1 0x0f 0x40 0xf2 +# CHECK: vrecps.f32 d16, d16, d17 +0xf2 0x0f 0x40 0xf2 +# CHECK: vrecps.f32 q8, q8, q9 +0xa0 0x04 0xfb 0xf3 +# CHECK: vrsqrte.u32 d16, d16 +0xe0 0x04 0xfb 0xf3 +# CHECK: vrsqrte.u32 q8, q8 +0xa0 0x05 0xfb 0xf3 +# CHECK: vrsqrte.f32 d16, d16 +0xe0 0x05 0xfb 0xf3 +# CHECK: vrsqrte.f32 q8, q8 +0xb1 0x0f 0x60 0xf2 +# CHECK: vrsqrts.f32 d16, d16, d17 +0xf2 0x0f 0x60 0xf2 +# CHECK: vrsqrts.f32 q8, q8, q9 + + +0x20 0x00 0xf0 0xf3 +# CHECK: vrev64.8 d16, d16 +0x20 0x00 0xf4 0xf3 +# CHECK: vrev64.16 d16, d16 +0x20 0x00 0xf8 0xf3 +# CHECK: vrev64.32 d16, d16 +0x60 0x00 0xf0 0xf3 +# CHECK: vrev64.8 q8, q8 +0x60 0x00 0xf4 0xf3 +# CHECK: vrev64.16 q8, q8 +0x60 0x00 0xf8 0xf3 +# CHECK: vrev64.32 q8, q8 +0xa0 0x00 0xf0 0xf3 +# CHECK: vrev32.8 d16, d16 +0xa0 0x00 0xf4 0xf3 +# CHECK: vrev32.16 d16, d16 +0xe0 0x00 0xf0 0xf3 +# CHECK: vrev32.8 q8, q8 +0xe0 0x00 0xf4 0xf3 +# CHECK: vrev32.16 q8, q8 +0x20 0x01 0xf0 0xf3 +# CHECK: vrev16.8 d16, d16 +0x60 0x01 0xf0 0xf3 +# CHECK: vrev16.8 q8, q8 + + +0xb0 0x04 0x41 0xf2 +# CHECK: vqshl.s8 d16, d16, d17 +0xb0 0x04 0x51 0xf2 +# CHECK: vqshl.s16 d16, d16, d17 +0xb0 0x04 0x61 0xf2 +# CHECK: vqshl.s32 d16, d16, d17 +0xb0 0x04 0x71 0xf2 +# CHECK: vqshl.s64 d16, d16, d17 +0xb0 0x04 0x41 0xf3 +# CHECK: vqshl.u8 d16, d16, d17 +0xb0 0x04 0x51 0xf3 +# CHECK: vqshl.u16 d16, d16, d17 +0xb0 0x04 0x61 0xf3 +# CHECK: vqshl.u32 d16, d16, d17 +0xb0 0x04 0x71 0xf3 +# CHECK: vqshl.u64 d16, d16, d17 +0xf0 0x04 0x42 0xf2 +# CHECK: vqshl.s8 q8, q8, q9 +0xf0 0x04 0x52 0xf2 +# CHECK: vqshl.s16 q8, q8, q9 +0xf0 0x04 0x62 0xf2 +# CHECK: vqshl.s32 q8, q8, q9 +0xf0 0x04 0x72 0xf2 +# CHECK: vqshl.s64 q8, q8, q9 +0xf0 0x04 0x42 0xf3 +# CHECK: vqshl.u8 q8, q8, q9 +0xf0 0x04 0x52 0xf3 +# CHECK: vqshl.u16 q8, q8, q9 +0xf0 0x04 0x62 0xf3 +# CHECK: vqshl.u32 q8, q8, q9 +0xf0 0x04 0x72 0xf3 +# CHECK: vqshl.u64 q8, q8, q9 +0x30 0x07 0xcf 0xf2 +# CHECK: vqshl.s8 d16, d16, #7 +0x30 0x07 0xdf 0xf2 +# CHECK: vqshl.s16 d16, d16, #15 +0x30 0x07 0xff 0xf2 +# CHECK: vqshl.s32 d16, d16, #31 +0xb0 0x07 0xff 0xf2 +# CHECK: vqshl.s64 d16, d16, #63 +0x30 0x07 0xcf 0xf3 +# CHECK: vqshl.u8 d16, d16, #7 +0x30 0x07 0xdf 0xf3 +# CHECK: vqshl.u16 d16, d16, #15 +0x30 0x07 0xff 0xf3 +# CHECK: vqshl.u32 d16, d16, #31 +0xb0 0x07 0xff 0xf3 +# CHECK: vqshl.u64 d16, d16, #63 +0x30 0x06 0xcf 0xf3 +# CHECK: vqshlu.s8 d16, d16, #7 +0x30 0x06 0xdf 0xf3 +# CHECK: vqshlu.s16 d16, d16, #15 +0x30 0x06 0xff 0xf3 +# CHECK: vqshlu.s32 d16, d16, #31 +0xb0 0x06 0xff 0xf3 +# CHECK: vqshlu.s64 d16, d16, #63 +0x70 0x07 0xcf 0xf2 +# CHECK: vqshl.s8 q8, q8, #7 +0x70 0x07 0xdf 0xf2 +# CHECK: vqshl.s16 q8, q8, #15 +0x70 0x07 0xff 0xf2 +# CHECK: vqshl.s32 q8, q8, #31 +0xf0 0x07 0xff 0xf2 +# CHECK: vqshl.s64 q8, q8, #63 +0x70 0x07 0xcf 0xf3 +# CHECK: vqshl.u8 q8, q8, #7 +0x70 0x07 0xdf 0xf3 +# CHECK: vqshl.u16 q8, q8, #15 +0x70 0x07 0xff 0xf3 +# CHECK: vqshl.u32 q8, q8, #31 +0xf0 0x07 0xff 0xf3 +# CHECK: vqshl.u64 q8, q8, #63 +0x70 0x06 0xcf 0xf3 +# CHECK: vqshlu.s8 q8, q8, #7 +0x70 0x06 0xdf 0xf3 +# CHECK: vqshlu.s16 q8, q8, #15 +0x70 0x06 0xff 0xf3 +# CHECK: vqshlu.s32 q8, q8, #31 +0xf0 0x06 0xff 0xf3 +# CHECK: vqshlu.s64 q8, q8, #63 +0xb0 0x05 0x41 0xf2 +# CHECK: vqrshl.s8 d16, d16, d17 +0xb0 0x05 0x51 0xf2 +# CHECK: vqrshl.s16 d16, d16, d17 +0xb0 0x05 0x61 0xf2 +# CHECK: vqrshl.s32 d16, d16, d17 +0xb0 0x05 0x71 0xf2 +# CHECK: vqrshl.s64 d16, d16, d17 +0xb0 0x05 0x41 0xf3 +# CHECK: vqrshl.u8 d16, d16, d17 +0xb0 0x05 0x51 0xf3 +# CHECK: vqrshl.u16 d16, d16, d17 +0xb0 0x05 0x61 0xf3 +# CHECK: vqrshl.u32 d16, d16, d17 +0xb0 0x05 0x71 0xf3 +# CHECK: vqrshl.u64 d16, d16, d17 +0xf0 0x05 0x42 0xf2 +# CHECK: vqrshl.s8 q8, q8, q9 +0xf0 0x05 0x52 0xf2 +# CHECK: vqrshl.s16 q8, q8, q9 +0xf0 0x05 0x62 0xf2 +# CHECK: vqrshl.s32 q8, q8, q9 +0xf0 0x05 0x72 0xf2 +# CHECK: vqrshl.s64 q8, q8, q9 +0xf0 0x05 0x42 0xf3 +# CHECK: vqrshl.u8 q8, q8, q9 +0xf0 0x05 0x52 0xf3 +# CHECK: vqrshl.u16 q8, q8, q9 +0xf0 0x05 0x62 0xf3 +# CHECK: vqrshl.u32 q8, q8, q9 +0xf0 0x05 0x72 0xf3 +# CHECK: vqrshl.u64 q8, q8, q9 +0x30 0x09 0xc8 0xf2 +# CHECK: vqshrn.s16 d16, q8, #8 +0x30 0x09 0xd0 0xf2 +# CHECK: vqshrn.s32 d16, q8, #16 +0x30 0x09 0xe0 0xf2 +# CHECK: vqshrn.s64 d16, q8, #32 +0x30 0x09 0xc8 0xf3 +# CHECK: vqshrn.u16 d16, q8, #8 +0x30 0x09 0xd0 0xf3 +# CHECK: vqshrn.u32 d16, q8, #16 +0x30 0x09 0xe0 0xf3 +# CHECK: vqshrn.u64 d16, q8, #32 +0x30 0x08 0xc8 0xf3 +# CHECK: vqshrun.s16 d16, q8, #8 +0x30 0x08 0xd0 0xf3 +# CHECK: vqshrun.s32 d16, q8, #16 +0x30 0x08 0xe0 0xf3 +# CHECK: vqshrun.s64 d16, q8, #32 +0x70 0x09 0xc8 0xf2 +# CHECK: vqrshrn.s16 d16, q8, #8 +0x70 0x09 0xd0 0xf2 +# CHECK: vqrshrn.s32 d16, q8, #16 +0x70 0x09 0xe0 0xf2 +# CHECK: vqrshrn.s64 d16, q8, #32 +0x70 0x09 0xc8 0xf3 +# CHECK: vqrshrn.u16 d16, q8, #8 +0x70 0x09 0xd0 0xf3 +# CHECK: vqrshrn.u32 d16, q8, #16 +0x70 0x09 0xe0 0xf3 +# CHECK: vqrshrn.u64 d16, q8, #32 +0x70 0x08 0xc8 0xf3 +# CHECK: vqrshrun.s16 d16, q8, #8 +0x70 0x08 0xd0 0xf3 +# CHECK: vqrshrun.s32 d16, q8, #16 +0x70 0x08 0xe0 0xf3 +# CHECK: vqrshrun.s64 d16, q8, #32 + + +0xa1 0x04 0x40 0xf3 +# CHECK: vshl.u8 d16, d17, d16 +0xa1 0x04 0x50 0xf3 +# CHECK: vshl.u16 d16, d17, d16 +0xa1 0x04 0x60 0xf3 +# CHECK: vshl.u32 d16, d17, d16 +0xa1 0x04 0x70 0xf3 +# CHECK: vshl.u64 d16, d17, d16 +0x30 0x05 0xcf 0xf2 +# CHECK: vshl.i8 d16, d16, #7 +0x30 0x05 0xdf 0xf2 +# CHECK: vshl.i16 d16, d16, #15 +0x30 0x05 0xff 0xf2 +# CHECK: vshl.i32 d16, d16, #31 +0xb0 0x05 0xff 0xf2 +# CHECK: vshl.i64 d16, d16, #63 +0xe2 0x04 0x40 0xf3 +# CHECK: vshl.u8 q8, q9, q8 +0xe2 0x04 0x50 0xf3 +# CHECK: vshl.u16 q8, q9, q8 +0xe2 0x04 0x60 0xf3 +# CHECK: vshl.u32 q8, q9, q8 +0xe2 0x04 0x70 0xf3 +# CHECK: vshl.u64 q8, q9, q8 +0x70 0x05 0xcf 0xf2 +# CHECK: vshl.i8 q8, q8, #7 +0x70 0x05 0xdf 0xf2 +# CHECK: vshl.i16 q8, q8, #15 +0x70 0x05 0xff 0xf2 +# CHECK: vshl.i32 q8, q8, #31 +0xf0 0x05 0xff 0xf2 +# CHECK: vshl.i64 q8, q8, #63 +0x30 0x00 0xc9 0xf3 +# CHECK: vshr.u8 d16, d16, #7 +0x30 0x00 0xd1 0xf3 +# CHECK: vshr.u16 d16, d16, #15 +0x30 0x00 0xe1 0xf3 +# CHECK: vshr.u32 d16, d16, #31 +0xb0 0x00 0xc1 0xf3 +# CHECK: vshr.u64 d16, d16, #63 +0x70 0x00 0xc9 0xf3 +# CHECK: vshr.u8 q8, q8, #7 +0x70 0x00 0xd1 0xf3 +# CHECK: vshr.u16 q8, q8, #15 +0x70 0x00 0xe1 0xf3 +# CHECK: vshr.u32 q8, q8, #31 +0xf0 0x00 0xc1 0xf3 +# CHECK: vshr.u64 q8, q8, #63 +0x30 0x00 0xc9 0xf2 +# CHECK: vshr.s8 d16, d16, #7 +0x30 0x00 0xd1 0xf2 +# CHECK: vshr.s16 d16, d16, #15 +0x30 0x00 0xe1 0xf2 +# CHECK: vshr.s32 d16, d16, #31 +0xb0 0x00 0xc1 0xf2 +# CHECK: vshr.s64 d16, d16, #63 +0x70 0x00 0xc9 0xf2 +# CHECK: vshr.s8 q8, q8, #7 +0x70 0x00 0xd1 0xf2 +# CHECK: vshr.s16 q8, q8, #15 +0x70 0x00 0xe1 0xf2 +# CHECK: vshr.s32 q8, q8, #31 +0xf0 0x00 0xc1 0xf2 +# CHECK: vshr.s64 q8, q8, #63 +0x30 0x01 0xc9 0xf3 +# CHECK: vsra.u8 d16, d16, #7 +0x30 0x01 0xd1 0xf3 +# CHECK: vsra.u16 d16, d16, #15 +0x30 0x01 0xe1 0xf3 +# CHECK: vsra.u32 d16, d16, #31 +0xb0 0x01 0xc1 0xf3 +# CHECK: vsra.u64 d16, d16, #63 +0x70 0x01 0xc9 0xf3 +# CHECK: vsra.u8 q8, q8, #7 +0x70 0x01 0xd1 0xf3 +# CHECK: vsra.u16 q8, q8, #15 +0x70 0x01 0xe1 0xf3 +# CHECK: vsra.u32 q8, q8, #31 +0xf0 0x01 0xc1 0xf3 +# CHECK: vsra.u64 q8, q8, #63 +0x30 0x01 0xc9 0xf2 +# CHECK: vsra.s8 d16, d16, #7 +0x30 0x01 0xd1 0xf2 +# CHECK: vsra.s16 d16, d16, #15 +0x30 0x01 0xe1 0xf2 +# CHECK: vsra.s32 d16, d16, #31 +0xb0 0x01 0xc1 0xf2 +# CHECK: vsra.s64 d16, d16, #63 +0x70 0x01 0xc9 0xf2 +# CHECK: vsra.s8 q8, q8, #7 +0x70 0x01 0xd1 0xf2 +# CHECK: vsra.s16 q8, q8, #15 +0x70 0x01 0xe1 0xf2 +# CHECK: vsra.s32 q8, q8, #31 +0xf0 0x01 0xc1 0xf2 +# CHECK: vsra.s64 q8, q8, #63 +0x30 0x04 0xc9 0xf3 +# CHECK: vsri.8 d16, d16, #7 +0x30 0x04 0xd1 0xf3 +# CHECK: vsri.16 d16, d16, #15 +0x30 0x04 0xe1 0xf3 +# CHECK: vsri.32 d16, d16, #31 +0xb0 0x04 0xc1 0xf3 +# CHECK: vsri.64 d16, d16, #63 +0x70 0x04 0xc9 0xf3 +# CHECK: vsri.8 q8, q8, #7 +0x70 0x04 0xd1 0xf3 +# CHECK: vsri.16 q8, q8, #15 +0x70 0x04 0xe1 0xf3 +# CHECK: vsri.32 q8, q8, #31 +0xf0 0x04 0xc1 0xf3 +# CHECK: vsri.64 q8, q8, #63 +0x30 0x05 0xcf 0xf3 +# CHECK: vsli.8 d16, d16, #7 +0x30 0x05 0xdf 0xf3 +# CHECK: vsli.16 d16, d16, #15 +0x30 0x05 0xff 0xf3 +# CHECK: vsli.32 d16, d16, #31 +0xb0 0x05 0xff 0xf3 +# CHECK: vsli.64 d16, d16, #63 +0x70 0x05 0xcf 0xf3 +# CHECK: vsli.8 q8, q8, #7 +0x70 0x05 0xdf 0xf3 +# CHECK: vsli.16 q8, q8, #15 +0x70 0x05 0xff 0xf3 +# CHECK: vsli.32 q8, q8, #31 +0xf0 0x05 0xff 0xf3 +# CHECK: vsli.64 q8, q8, #63 +0x30 0x0a 0xcf 0xf2 +# CHECK: vshll.s8 q8, d16, #7 +0x30 0x0a 0xdf 0xf2 +# CHECK: vshll.s16 q8, d16, #15 +0x30 0x0a 0xff 0xf2 +# CHECK: vshll.s32 q8, d16, #31 +0x30 0x0a 0xcf 0xf3 +# CHECK: vshll.u8 q8, d16, #7 +0x30 0x0a 0xdf 0xf3 +# CHECK: vshll.u16 q8, d16, #15 +0x30 0x0a 0xff 0xf3 +# CHECK: vshll.u32 q8, d16, #31 +0x20 0x03 0xf2 0xf3 +# CHECK: vshll.i8 q8, d16, #8 +0x20 0x03 0xf6 0xf3 +# CHECK: vshll.i16 q8, d16, #16 +0x20 0x03 0xfa 0xf3 +# CHECK: vshll.i32 q8, d16, #32 +0x30 0x08 0xc8 0xf2 +# CHECK: vshrn.i16 d16, q8, #8 +0x30 0x08 0xd0 0xf2 +# CHECK: vshrn.i32 d16, q8, #16 +0x30 0x08 0xe0 0xf2 +# CHECK: vshrn.i64 d16, q8, #32 +0xa1 0x05 0x40 0xf2 +# CHECK: vrshl.s8 d16, d17, d16 +0xa1 0x05 0x50 0xf2 +# CHECK: vrshl.s16 d16, d17, d16 +0xa1 0x05 0x60 0xf2 +# CHECK: vrshl.s32 d16, d17, d16 +0xa1 0x05 0x70 0xf2 +# CHECK: vrshl.s64 d16, d17, d16 +0xa1 0x05 0x40 0xf3 +# CHECK: vrshl.u8 d16, d17, d16 +0xa1 0x05 0x50 0xf3 +# CHECK: vrshl.u16 d16, d17, d16 +0xa1 0x05 0x60 0xf3 +# CHECK: vrshl.u32 d16, d17, d16 +0xa1 0x05 0x70 0xf3 +# CHECK: vrshl.u64 d16, d17, d16 +0xe2 0x05 0x40 0xf2 +# CHECK: vrshl.s8 q8, q9, q8 +0xe2 0x05 0x50 0xf2 +# CHECK: vrshl.s16 q8, q9, q8 +0xe2 0x05 0x60 0xf2 +# CHECK: vrshl.s32 q8, q9, q8 +0xe2 0x05 0x70 0xf2 +# CHECK: vrshl.s64 q8, q9, q8 +0xe2 0x05 0x40 0xf3 +# CHECK: vrshl.u8 q8, q9, q8 +0xe2 0x05 0x50 0xf3 +# CHECK: vrshl.u16 q8, q9, q8 +0xe2 0x05 0x60 0xf3 +# CHECK: vrshl.u32 q8, q9, q8 +0xe2 0x05 0x70 0xf3 +# CHECK: vrshl.u64 q8, q9, q8 +0x30 0x02 0xc8 0xf2 +# CHECK: vrshr.s8 d16, d16, #8 +0x30 0x02 0xd0 0xf2 +# CHECK: vrshr.s16 d16, d16, #16 +0x30 0x02 0xe0 0xf2 +# CHECK: vrshr.s32 d16, d16, #32 +0xb0 0x02 0xc0 0xf2 +# CHECK: vrshr.s64 d16, d16, #64 +0x30 0x02 0xc8 0xf3 +# CHECK: vrshr.u8 d16, d16, #8 +0x30 0x02 0xd0 0xf3 +# CHECK: vrshr.u16 d16, d16, #16 +0x30 0x02 0xe0 0xf3 +# CHECK: vrshr.u32 d16, d16, #32 +0xb0 0x02 0xc0 0xf3 +# CHECK: vrshr.u64 d16, d16, #64 +0x70 0x02 0xc8 0xf2 +# CHECK: vrshr.s8 q8, q8, #8 +0x70 0x02 0xd0 0xf2 +# CHECK: vrshr.s16 q8, q8, #16 +0x70 0x02 0xe0 0xf2 +# CHECK: vrshr.s32 q8, q8, #32 +0xf0 0x02 0xc0 0xf2 +# CHECK: vrshr.s64 q8, q8, #64 +0x70 0x02 0xc8 0xf3 +# CHECK: vrshr.u8 q8, q8, #8 +0x70 0x02 0xd0 0xf3 +# CHECK: vrshr.u16 q8, q8, #16 +0x70 0x02 0xe0 0xf3 +# CHECK: vrshr.u32 q8, q8, #32 +0xf0 0x02 0xc0 0xf3 +# CHECK: vrshr.u64 q8, q8, #64 +0x70 0x08 0xc8 0xf2 +# CHECK: vrshrn.i16 d16, q8, #8 +0x70 0x08 0xd0 0xf2 +# CHECK: vrshrn.i32 d16, q8, #16 +0x70 0x08 0xe0 0xf2 +# CHECK: vrshrn.i64 d16, q8, #32 +0x70 0x09 0xcc 0xf2 +# CHECK: vqrshrn.s16 d16, q8, #4 +0x70 0x09 0xd3 0xf2 +# CHECK: vqrshrn.s32 d16, q8, #13 +0x70 0x09 0xf3 0xf2 +# CHECK: vqrshrn.s64 d16, q8, #13 +0x70 0x09 0xcc 0xf3 +# CHECK: vqrshrn.u16 d16, q8, #4 +0x70 0x09 0xd3 0xf3 +# CHECK: vqrshrn.u32 d16, q8, #13 +0x70 0x09 0xf3 0xf3 +# CHECK: vqrshrn.u64 d16, q8, #13 + + +0x30 0x11 0xc8 0xf2 +# CHECK: vsra.s8 d17, d16, #8 +0x30 0x11 0xd0 0xf2 +# CHECK: vsra.s16 d17, d16, #16 +0x30 0x11 0xe0 0xf2 +# CHECK: vsra.s32 d17, d16, #32 +0xb0 0x11 0xc0 0xf2 +# CHECK: vsra.s64 d17, d16, #64 +0x72 0x01 0xc8 0xf2 +# CHECK: vsra.s8 q8, q9, #8 +0x72 0x01 0xd0 0xf2 +# CHECK: vsra.s16 q8, q9, #16 +0x72 0x01 0xe0 0xf2 +# CHECK: vsra.s32 q8, q9, #32 +0xf2 0x01 0xc0 0xf2 +# CHECK: vsra.s64 q8, q9, #64 +0x30 0x11 0xc8 0xf3 +# CHECK: vsra.u8 d17, d16, #8 +0x30 0x11 0xd0 0xf3 +# CHECK: vsra.u16 d17, d16, #16 +0x30 0x11 0xe0 0xf3 +# CHECK: vsra.u32 d17, d16, #32 +0xb0 0x11 0xc0 0xf3 +# CHECK: vsra.u64 d17, d16, #64 +0x72 0x01 0xc8 0xf3 +# CHECK: vsra.u8 q8, q9, #8 +0x72 0x01 0xd0 0xf3 +# CHECK: vsra.u16 q8, q9, #16 +0x72 0x01 0xe0 0xf3 +# CHECK: vsra.u32 q8, q9, #32 +0xf2 0x01 0xc0 0xf3 +# CHECK: vsra.u64 q8, q9, #64 +0x30 0x13 0xc8 0xf2 +# CHECK: vrsra.s8 d17, d16, #8 +0x30 0x13 0xd0 0xf2 +# CHECK: vrsra.s16 d17, d16, #16 +0x30 0x13 0xe0 0xf2 +# CHECK: vrsra.s32 d17, d16, #32 +0xb0 0x13 0xc0 0xf2 +# CHECK: vrsra.s64 d17, d16, #64 +0x30 0x13 0xc8 0xf3 +# CHECK: vrsra.u8 d17, d16, #8 +0x30 0x13 0xd0 0xf3 +# CHECK: vrsra.u16 d17, d16, #16 +0x30 0x13 0xe0 0xf3 +# CHECK: vrsra.u32 d17, d16, #32 +0xb0 0x13 0xc0 0xf3 +# CHECK: vrsra.u64 d17, d16, #64 +0x72 0x03 0xc8 0xf2 +# CHECK: vrsra.s8 q8, q9, #8 +0x72 0x03 0xd0 0xf2 +# CHECK: vrsra.s16 q8, q9, #16 +0x72 0x03 0xe0 0xf2 +# CHECK: vrsra.s32 q8, q9, #32 +0xf2 0x03 0xc0 0xf2 +# CHECK: vrsra.s64 q8, q9, #64 +0x72 0x03 0xc8 0xf3 +# CHECK: vrsra.u8 q8, q9, #8 +0x72 0x03 0xd0 0xf3 +# CHECK: vrsra.u16 q8, q9, #16 +0x72 0x03 0xe0 0xf3 +# CHECK: vrsra.u32 q8, q9, #32 +0xf2 0x03 0xc0 0xf3 +# CHECK: vrsra.u64 q8, q9, #64 +0x30 0x15 0xcf 0xf3 +# CHECK: vsli.8 d17, d16, #7 +0x30 0x15 0xdf 0xf3 +# CHECK: vsli.16 d17, d16, #15 +0x30 0x15 0xff 0xf3 +# CHECK: vsli.32 d17, d16, #31 +0xb0 0x15 0xff 0xf3 +# CHECK: vsli.64 d17, d16, #63 +0x70 0x25 0xcf 0xf3 +# CHECK: vsli.8 q9, q8, #7 +0x70 0x25 0xdf 0xf3 +# CHECK: vsli.16 q9, q8, #15 +0x70 0x25 0xff 0xf3 +# CHECK: vsli.32 q9, q8, #31 +0xf0 0x25 0xff 0xf3 +# CHECK: vsli.64 q9, q8, #63 +0x30 0x14 0xc8 0xf3 +# CHECK: vsri.8 d17, d16, #8 +0x30 0x14 0xd0 0xf3 +# CHECK: vsri.16 d17, d16, #16 +0x30 0x14 0xe0 0xf3 +# CHECK: vsri.32 d17, d16, #32 +0xb0 0x14 0xc0 0xf3 +# CHECK: vsri.64 d17, d16, #64 +0x70 0x24 0xc8 0xf3 +# CHECK: vsri.8 q9, q8, #8 +0x70 0x24 0xd0 0xf3 +# CHECK: vsri.16 q9, q8, #16 +0x70 0x24 0xe0 0xf3 +# CHECK: vsri.32 q9, q8, #32 +0xf0 0x24 0xc0 0xf3 +# CHECK: vsri.64 q9, q8, #64 + + +0xa0 0x03 0xf1 0xf2 +# CHECK: vext.8 d16, d17, d16, #3 +0xa0 0x05 0xf1 0xf2 +# CHECK: vext.8 d16, d17, d16, #5 +0xe0 0x03 0xf2 0xf2 +# CHECK: vext.8 q8, q9, q8, #3 +0xe0 0x07 0xf2 0xf2 +# CHECK: vext.8 q8, q9, q8, #7 +0xa0 0x06 0xf1 0xf2 +# CHECK: vext.16 d16, d17, d16, #3 +0xe0 0x0c 0xf2 0xf2 +# CHECK: vext.32 q8, q9, q8, #3 +0xa0 0x10 0xf2 0xf3 +# CHECK: vtrn.8 d17, d16 +0xa0 0x10 0xf6 0xf3 +# CHECK: vtrn.16 d17, d16 +0xa0 0x10 0xfa 0xf3 +# CHECK: vtrn.32 d17, d16 +0xe0 0x20 0xf2 0xf3 +# CHECK: vtrn.8 q9, q8 +0xe0 0x20 0xf6 0xf3 +# CHECK: vtrn.16 q9, q8 +0xe0 0x20 0xfa 0xf3 +# CHECK: vtrn.32 q9, q8 +0x20 0x11 0xf2 0xf3 +# CHECK: vuzp.8 d17, d16 +0x20 0x11 0xf6 0xf3 +# CHECK: vuzp.16 d17, d16 +0x60 0x21 0xf2 0xf3 +# CHECK: vuzp.8 q9, q8 +0x60 0x21 0xf6 0xf3 +# CHECK: vuzp.16 q9, q8 +0x60 0x21 0xfa 0xf3 +# CHECK: vuzp.32 q9, q8 +0xa0 0x11 0xf2 0xf3 +# CHECK: vzip.8 d17, d16 +0xa0 0x11 0xf6 0xf3 +# CHECK: vzip.16 d17, d16 +0xe0 0x21 0xf2 0xf3 +# CHECK: vzip.8 q9, q8 +0xe0 0x21 0xf6 0xf3 +# CHECK: vzip.16 q9, q8 +0xe0 0x21 0xfa 0xf3 +# CHECK: vzip.32 q9, q8 + + +0xa0 0x08 0x41 0xf3 +# CHECK: vsub.i8 d16, d17, d16 +0xa0 0x08 0x51 0xf3 +# CHECK: vsub.i16 d16, d17, d16 +0xa0 0x08 0x61 0xf3 +# CHECK: vsub.i32 d16, d17, d16 +0xa0 0x08 0x71 0xf3 +# CHECK: vsub.i64 d16, d17, d16 +0xa1 0x0d 0x60 0xf2 +# CHECK: vsub.f32 d16, d16, d17 +0xe2 0x08 0x40 0xf3 +# CHECK: vsub.i8 q8, q8, q9 +0xe2 0x08 0x50 0xf3 +# CHECK: vsub.i16 q8, q8, q9 +0xe2 0x08 0x60 0xf3 +# CHECK: vsub.i32 q8, q8, q9 +0xe2 0x08 0x70 0xf3 +# CHECK: vsub.i64 q8, q8, q9 +0xe2 0x0d 0x60 0xf2 +# CHECK: vsub.f32 q8, q8, q9 +0xa0 0x02 0xc1 0xf2 +# CHECK: vsubl.s8 q8, d17, d16 +0xa0 0x02 0xd1 0xf2 +# CHECK: vsubl.s16 q8, d17, d16 +0xa0 0x02 0xe1 0xf2 +# CHECK: vsubl.s32 q8, d17, d16 +0xa0 0x02 0xc1 0xf3 +# CHECK: vsubl.u8 q8, d17, d16 +0xa0 0x02 0xd1 0xf3 +# CHECK: vsubl.u16 q8, d17, d16 +0xa0 0x02 0xe1 0xf3 +# CHECK: vsubl.u32 q8, d17, d16 +0xa2 0x03 0xc0 0xf2 +# CHECK: vsubw.s8 q8, q8, d18 +0xa2 0x03 0xd0 0xf2 +# CHECK: vsubw.s16 q8, q8, d18 +0xa2 0x03 0xe0 0xf2 +# CHECK: vsubw.s32 q8, q8, d18 +0xa2 0x03 0xc0 0xf3 +# CHECK: vsubw.u8 q8, q8, d18 +0xa2 0x03 0xd0 0xf3 +# CHECK: vsubw.u16 q8, q8, d18 +0xa2 0x03 0xe0 0xf3 +# CHECK: vsubw.u32 q8, q8, d18 +0xa1 0x02 0x40 0xf2 +# CHECK: vhsub.s8 d16, d16, d17 +0xa1 0x02 0x50 0xf2 +# CHECK: vhsub.s16 d16, d16, d17 +0xa1 0x02 0x60 0xf2 +# CHECK: vhsub.s32 d16, d16, d17 +0xa1 0x02 0x40 0xf3 +# CHECK: vhsub.u8 d16, d16, d17 +0xa1 0x02 0x50 0xf3 +# CHECK: vhsub.u16 d16, d16, d17 +0xa1 0x02 0x60 0xf3 +# CHECK: vhsub.u32 d16, d16, d17 +0xe2 0x02 0x40 0xf2 +# CHECK: vhsub.s8 q8, q8, q9 +0xe2 0x02 0x50 0xf2 +# CHECK: vhsub.s16 q8, q8, q9 +0xe2 0x02 0x60 0xf2 +# CHECK: vhsub.s32 q8, q8, q9 +0xb1 0x02 0x40 0xf2 +# CHECK: vqsub.s8 d16, d16, d17 +0xb1 0x02 0x50 0xf2 +# CHECK: vqsub.s16 d16, d16, d17 +0xb1 0x02 0x60 0xf2 +# CHECK: vqsub.s32 d16, d16, d17 +0xb1 0x02 0x70 0xf2 +# CHECK: vqsub.s64 d16, d16, d17 +0xb1 0x02 0x40 0xf3 +# CHECK: vqsub.u8 d16, d16, d17 +0xb1 0x02 0x50 0xf3 +# CHECK: vqsub.u16 d16, d16, d17 +0xb1 0x02 0x60 0xf3 +# CHECK: vqsub.u32 d16, d16, d17 +0xb1 0x02 0x70 0xf3 +# CHECK: vqsub.u64 d16, d16, d17 +0xf2 0x02 0x40 0xf2 +# CHECK: vqsub.s8 q8, q8, q9 +0xf2 0x02 0x50 0xf2 +# CHECK: vqsub.s16 q8, q8, q9 +0xf2 0x02 0x60 0xf2 +# CHECK: vqsub.s32 q8, q8, q9 +0xf2 0x02 0x70 0xf2 +# CHECK: vqsub.s64 q8, q8, q9 +0xf2 0x02 0x40 0xf3 +# CHECK: vqsub.u8 q8, q8, q9 +0xf2 0x02 0x50 0xf3 +# CHECK: vqsub.u16 q8, q8, q9 +0xf2 0x02 0x60 0xf3 +# CHECK: vqsub.u32 q8, q8, q9 +0xf2 0x02 0x70 0xf3 +# CHECK: vqsub.u64 q8, q8, q9 +0xa2 0x06 0xc0 0xf2 +# CHECK: vsubhn.i16 d16, q8, q9 +0xa2 0x06 0xd0 0xf2 +# CHECK: vsubhn.i32 d16, q8, q9 +0xa2 0x06 0xe0 0xf2 +# CHECK: vsubhn.i64 d16, q8, q9 +0xa2 0x06 0xc0 0xf3 +# CHECK: vrsubhn.i16 d16, q8, q9 +0xa2 0x06 0xd0 0xf3 +# CHECK: vrsubhn.i32 d16, q8, q9 +0xa2 0x06 0xe0 0xf3 +# CHECK: vrsubhn.i64 d16, q8, q9 + + + +0xa0 0x08 0xf1 0xf3 +# CHECK: vtbl.8 d16, {d17}, d16 +0xa2 0x09 0xf0 0xf3 +# CHECK: vtbl.8 d16, {d16, d17}, d18 +0xa4 0x0a 0xf0 0xf3 +# CHECK: vtbl.8 d16, {d16, d17, d18}, d20 +0xa4 0x0b 0xf0 0xf3 +# CHECK: vtbl.8 d16, {d16, d17, d18, d19}, d20 +0xe1 0x28 0xf0 0xf3 +# CHECK: vtbx.8 d18, {d16}, d17 +0xe2 0x39 0xf0 0xf3 +# CHECK: vtbx.8 d19, {d16, d17}, d18 +0xe5 0x4a 0xf0 0xf3 +# CHECK: vtbx.8 d20, {d16, d17, d18}, d21 +0xe5 0x4b 0xf0 0xf3 +# CHECK: vtbx.8 d20, {d16, d17, d18, d19}, d21 + + + +0x1f 0x07 0x60 0xf4 +# CHECK: vld1.8 {d16}, [r0, :64] +0x4f 0x07 0x60 0xf4 +# CHECK: vld1.16 {d16}, [r0] +0x8f 0x07 0x60 0xf4 +# CHECK: vld1.32 {d16}, [r0] +0xcf 0x07 0x60 0xf4 +# CHECK: vld1.64 {d16}, [r0] +0x1f 0x0a 0x60 0xf4 +# CHECK: vld1.8 {d16, d17}, [r0, :64] +0x6f 0x0a 0x60 0xf4 +# CHECK: vld1.16 {d16, d17}, [r0, :128] +0x8f 0x0a 0x60 0xf4 +# CHECK: vld1.32 {d16, d17}, [r0] +0xcf 0x0a 0x60 0xf4 +# CHECK: vld1.64 {d16, d17}, [r0] + +0x1f 0x08 0x60 0xf4 +# CHECK: vld2.8 {d16, d17}, [r0, :64] +0x6f 0x08 0x60 0xf4 +# CHECK: vld2.16 {d16, d17}, [r0, :128] +0x8f 0x08 0x60 0xf4 +# CHECK: vld2.32 {d16, d17}, [r0] +0x1f 0x03 0x60 0xf4 +# CHECK: vld2.8 {d16, d17, d18, d19}, [r0, :64] +0x6f 0x03 0x60 0xf4 +# CHECK: vld2.16 {d16, d17, d18, d19}, [r0, :128] +0xbf 0x03 0x60 0xf4 +# CHECK: vld2.32 {d16, d17, d18, d19}, [r0, :256] + +0x1f 0x04 0x60 0xf4 +# CHECK: vld3.8 {d16, d17, d18}, [r0, :64] +0x4f 0x04 0x60 0xf4 +# CHECK: vld3.16 {d16, d17, d18}, [r0] +0x8f 0x04 0x60 0xf4 +# CHECK: vld3.32 {d16, d17, d18}, [r0] +0x1d 0x05 0x60 0xf4 +# CHECK: vld3.8 {d16, d18, d20}, [r0, :64]! +0x1d 0x15 0x60 0xf4 +# CHECK: vld3.8 {d17, d19, d21}, [r0, :64]! +0x4d 0x05 0x60 0xf4 +# CHECK: vld3.16 {d16, d18, d20}, [r0]! +0x4d 0x15 0x60 0xf4 +# CHECK: vld3.16 {d17, d19, d21}, [r0]! +0x8d 0x05 0x60 0xf4 +# CHECK: vld3.32 {d16, d18, d20}, [r0]! +0x8d 0x15 0x60 0xf4 +# CHECK: vld3.32 {d17, d19, d21}, [r0]! + +0x1f 0x00 0x60 0xf4 +# CHECK: vld4.8 {d16, d17, d18, d19}, [r0, :64] +0x6f 0x00 0x60 0xf4 +# CHECK: vld4.16 {d16, d17, d18, d19}, [r0, :128] +0xbf 0x00 0x60 0xf4 +# CHECK: vld4.32 {d16, d17, d18, d19}, [r0, :256] +0x3d 0x01 0x60 0xf4 +# CHECK: vld4.8 {d16, d18, d20, d22}, [r0, :256]! +0x3d 0x11 0x60 0xf4 +# CHECK: vld4.8 {d17, d19, d21, d23}, [r0, :256]! +0x4d 0x01 0x60 0xf4 +# CHECK: vld4.16 {d16, d18, d20, d22}, [r0]! +0x4d 0x11 0x60 0xf4 +# CHECK: vld4.16 {d17, d19, d21, d23}, [r0]! +0x8d 0x01 0x60 0xf4 +# CHECK: vld4.32 {d16, d18, d20, d22}, [r0]! +0x8d 0x11 0x60 0xf4 +# CHECK: vld4.32 {d17, d19, d21, d23}, [r0]! + +0x6f 0x00 0xe0 0xf4 +# CHECK: vld1.8 {d16[3]}, [r0] +0x9f 0x04 0xe0 0xf4 +# CHECK: vld1.16 {d16[2]}, [r0, :16] +0xbf 0x08 0xe0 0xf4 +# CHECK: vld1.32 {d16[1]}, [r0, :32] + +0x3f 0x01 0xe0 0xf4 +# CHECK: vld2.8 {d16[1], d17[1]}, [r0, :16] +0x5f 0x05 0xe0 0xf4 +# CHECK: vld2.16 {d16[1], d17[1]}, [r0, :32] +0x8f 0x09 0xe0 0xf4 +# CHECK: vld2.32 {d16[1], d17[1]}, [r0] +0x6f 0x15 0xe0 0xf4 +# CHECK: vld2.16 {d17[1], d19[1]}, [r0] +0x5f 0x19 0xe0 0xf4 +# CHECK: vld2.32 {d17[0], d19[0]}, [r0, :64] + +0x2f 0x02 0xe0 0xf4 +# CHECK: vld3.8 {d16[1], d17[1], d18[1]}, [r0] +0x4f 0x06 0xe0 0xf4 +# CHECK: vld3.16 {d16[1], d17[1], d18[1]}, [r0] +0x8f 0x0a 0xe0 0xf4 +# CHECK: vld3.32 {d16[1], d17[1], d18[1]}, [r0] +0x6f 0x06 0xe0 0xf4 +# CHECK: vld3.16 {d16[1], d18[1], d20[1]}, [r0] +0xcf 0x1a 0xe0 0xf4 +# CHECK: vld3.32 {d17[1], d19[1], d21[1]}, [r0] + +0x3f 0x03 0xe0 0xf4 +# CHECK: vld4.8 {d16[1], d17[1], d18[1], d19[1]}, [r0, :32] +0x4f 0x07 0xe0 0xf4 +# CHECK: vld4.16 {d16[1], d17[1], d18[1], d19[1]}, [r0] +0xaf 0x0b 0xe0 0xf4 +# CHECK: vld4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0, :128] +0x7f 0x07 0xe0 0xf4 +# CHECK: vld4.16 {d16[1], d18[1], d20[1], d22[1]}, [r0, :64] +0x4f 0x1b 0xe0 0xf4 +# CHECK: vld4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0] + + + +0x1f 0x07 0x40 0xf4 +# CHECK: vst1.8 {d16}, [r0, :64] +0x4f 0x07 0x40 0xf4 +# CHECK: vst1.16 {d16}, [r0] +0x8f 0x07 0x40 0xf4 +# CHECK: vst1.32 {d16}, [r0] +0xcf 0x07 0x40 0xf4 +# CHECK: vst1.64 {d16}, [r0] +0x1f 0x0a 0x40 0xf4 +# CHECK: vst1.8 {d16, d17}, [r0, :64] +0x6f 0x0a 0x40 0xf4 +# CHECK: vst1.16 {d16, d17}, [r0, :128] +0x8f 0x0a 0x40 0xf4 +# CHECK: vst1.32 {d16, d17}, [r0] +0xcf 0x0a 0x40 0xf4 +# CHECK: vst1.64 {d16, d17}, [r0] + +0x1f 0x08 0x40 0xf4 +# CHECK: vst2.8 {d16, d17}, [r0, :64] +0x6f 0x08 0x40 0xf4 +# CHECK: vst2.16 {d16, d17}, [r0, :128] +0x8f 0x08 0x40 0xf4 +# CHECK: vst2.32 {d16, d17}, [r0] +0x1f 0x03 0x40 0xf4 +# CHECK: vst2.8 {d16, d17, d18, d19}, [r0, :64] +0x6f 0x03 0x40 0xf4 +# CHECK: vst2.16 {d16, d17, d18, d19}, [r0, :128] +0xbf 0x03 0x40 0xf4 +# CHECK: vst2.32 {d16, d17, d18, d19}, [r0, :256] + +0x1f 0x04 0x40 0xf4 +# CHECK: vst3.8 {d16, d17, d18}, [r0, :64] +0x4f 0x04 0x40 0xf4 +# CHECK: vst3.16 {d16, d17, d18}, [r0] +0x8f 0x04 0x40 0xf4 +# CHECK: vst3.32 {d16, d17, d18}, [r0] +0x1d 0x05 0x40 0xf4 +# CHECK: vst3.8 {d16, d18, d20}, [r0, :64]! +0x1d 0x15 0x40 0xf4 +# CHECK: vst3.8 {d17, d19, d21}, [r0, :64]! +0x4d 0x05 0x40 0xf4 +# CHECK: vst3.16 {d16, d18, d20}, [r0]! +0x4d 0x15 0x40 0xf4 +# CHECK: vst3.16 {d17, d19, d21}, [r0]! +0x8d 0x05 0x40 0xf4 +# CHECK: vst3.32 {d16, d18, d20}, [r0]! +0x8d 0x15 0x40 0xf4 +# CHECK: vst3.32 {d17, d19, d21}, [r0]! + +0x1f 0x00 0x40 0xf4 +# CHECK: vst4.8 {d16, d17, d18, d19}, [r0, :64] +0x6f 0x00 0x40 0xf4 +# CHECK: vst4.16 {d16, d17, d18, d19}, [r0, :128] +0x3d 0x01 0x40 0xf4 +# CHECK: vst4.8 {d16, d18, d20, d22}, [r0, :256]! +0x3d 0x11 0x40 0xf4 +# CHECK: vst4.8 {d17, d19, d21, d23}, [r0, :256]! +0x4d 0x01 0x40 0xf4 +# CHECK: vst4.16 {d16, d18, d20, d22}, [r0]! +0x4d 0x11 0x40 0xf4 +# CHECK: vst4.16 {d17, d19, d21, d23}, [r0]! +0x8d 0x01 0x40 0xf4 +# CHECK: vst4.32 {d16, d18, d20, d22}, [r0]! +0x8d 0x11 0x40 0xf4 +# CHECK: vst4.32 {d17, d19, d21, d23}, [r0]! + +0x3f 0x01 0xc0 0xf4 +# CHECK: vst2.8 {d16[1], d17[1]}, [r0, :16] +0x5f 0x05 0xc0 0xf4 +# CHECK: vst2.16 {d16[1], d17[1]}, [r0, :32] +0x8f 0x09 0xc0 0xf4 +# CHECK: vst2.32 {d16[1], d17[1]}, [r0] +0x6f 0x15 0xc0 0xf4 +# CHECK: vst2.16 {d17[1], d19[1]}, [r0] +0x5f 0x19 0xc0 0xf4 +# CHECK: vst2.32 {d17[0], d19[0]}, [r0, :64] + +0x2f 0x02 0xc0 0xf4 +# CHECK: vst3.8 {d16[1], d17[1], d18[1]}, [r0] +0x4f 0x06 0xc0 0xf4 +# CHECK: vst3.16 {d16[1], d17[1], d18[1]}, [r0] +0x8f 0x0a 0xc0 0xf4 +# CHECK: vst3.32 {d16[1], d17[1], d18[1]}, [r0] +0xaf 0x16 0xc0 0xf4 +# CHECK: vst3.16 {d17[2], d19[2], d21[2]}, [r0] +0x4f 0x0a 0xc0 0xf4 +# CHECK: vst3.32 {d16[0], d18[0], d20[0]}, [r0] + +0x3f 0x03 0xc0 0xf4 +# CHECK: vst4.8 {d16[1], d17[1], d18[1], d19[1]}, [r0, :32] +0x4f 0x07 0xc0 0xf4 +# CHECK: vst4.16 {d16[1], d17[1], d18[1], d19[1]}, [r0] +0xaf 0x0b 0xc0 0xf4 +# CHECK: vst4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0, :128] +0xff 0x17 0xc0 0xf4 +# CHECK: vst4.16 {d17[3], d19[3], d21[3], d23[3]}, [r0, :64] +0x4f 0x1b 0xc0 0xf4 +# CHECK: vst4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0] + +0x0 0xc 0xa0 0xf4 +# CHECK: vld1.8 {d0[]}, [r0], r0 +0x0d 0x03 0x80 0xf4 +# CHECK: vst4.8 {d0[0], d1[0], d2[0], d3[0]}, [r0]! + +0x3d 0x2a 0x5e 0x6c +# CHECK: vmovvs r2, lr, s29, s30 + +0xe9 0x1a 0xb2 0x4e +# CHECK: vcvttmi.f32.f16 s2, s19 diff --git a/test/MC/Disassembler/ARM/neont2.txt b/test/MC/Disassembler/ARM/neont2.txt new file mode 100644 index 000000000000..577703c804b7 --- /dev/null +++ b/test/MC/Disassembler/ARM/neont2.txt @@ -0,0 +1,1586 @@ +# RUN: llvm-mc -triple thumbv7-unknown-unknown -disassemble -mattr +fp16 < %s | FileCheck %s + +0xf1 0xff 0x20 0x03 +# CHECK: vabs.s8 d16, d16 +0xf5 0xff 0x20 0x03 +# CHECK: vabs.s16 d16, d16 +0xf9 0xff 0x20 0x03 +# CHECK: vabs.s32 d16, d16 +0xf9 0xff 0x20 0x07 +# CHECK: vabs.f32 d16, d16 +0xf1 0xff 0x60 0x03 +# CHECK: vabs.s8 q8, q8 +0xf5 0xff 0x60 0x03 +# CHECK: vabs.s16 q8, q8 +0xf9 0xff 0x60 0x03 +# CHECK: vabs.s32 q8, q8 +0xf9 0xff 0x60 0x07 +# CHECK: vabs.f32 q8, q8 + +0xf0 0xff 0x20 0x07 +# CHECK: vqabs.s8 d16, d16 +0xf4 0xff 0x20 0x07 +# CHECK: vqabs.s16 d16, d16 +0xf8 0xff 0x20 0x07 +# CHECK: vqabs.s32 d16, d16 +0xf0 0xff 0x60 0x07 +# CHECK: vqabs.s8 q8, q8 +0xf4 0xff 0x60 0x07 +# CHECK: vqabs.s16 q8, q8 +0xf8 0xff 0x60 0x07 +# CHECK: vqabs.s32 q8, q8 + +0x40 0xef 0xa1 0x07 +# CHECK: vabd.s8 d16, d16, d17 +0x50 0xef 0xa1 0x07 +# CHECK: vabd.s16 d16, d16, d17 +0x60 0xef 0xa1 0x07 +# CHECK: vabd.s32 d16, d16, d17 +0x40 0xff 0xa1 0x07 +# CHECK: vabd.u8 d16, d16, d17 +0x50 0xff 0xa1 0x07 +# CHECK: vabd.u16 d16, d16, d17 +0x60 0xff 0xa1 0x07 +# CHECK: vabd.u32 d16, d16, d17 +0x60 0xff 0xa1 0x0d +# CHECK: vabd.f32 d16, d16, d17 +0x40 0xef 0xe2 0x07 +# CHECK: vabd.s8 q8, q8, q9 +0x50 0xef 0xe2 0x07 +# CHECK: vabd.s16 q8, q8, q9 +0x60 0xef 0xe2 0x07 +# CHECK: vabd.s32 q8, q8, q9 +0x40 0xff 0xe2 0x07 +# CHECK: vabd.u8 q8, q8, q9 +0x50 0xff 0xe2 0x07 +# CHECK: vabd.u16 q8, q8, q9 +0x60 0xff 0xe2 0x07 +# CHECK: vabd.u32 q8, q8, q9 +0x60 0xff 0xe2 0x0d +# CHECK: vabd.f32 q8, q8, q9 + +0xc0 0xef 0xa1 0x07 +# CHECK: vabdl.s8 q8, d16, d17 +0xd0 0xef 0xa1 0x07 +# CHECK: vabdl.s16 q8, d16, d17 +0xe0 0xef 0xa1 0x07 +# CHECK: vabdl.s32 q8, d16, d17 +0xc0 0xff 0xa1 0x07 +# CHECK: vabdl.u8 q8, d16, d17 +0xd0 0xff 0xa1 0x07 +# CHECK: vabdl.u16 q8, d16, d17 +0xe0 0xff 0xa1 0x07 +# CHECK: vabdl.u32 q8, d16, d17 + +0x42 0xef 0xb1 0x07 +# CHECK: vaba.s8 d16, d18, d17 +0x52 0xef 0xb1 0x07 +# CHECK: vaba.s16 d16, d18, d17 +0x62 0xef 0xb1 0x07 +# CHECK: vaba.s32 d16, d18, d17 +0x42 0xff 0xb1 0x07 +# CHECK: vaba.u8 d16, d18, d17 +0x52 0xff 0xb1 0x07 +# CHECK: vaba.u16 d16, d18, d17 +0x62 0xff 0xb1 0x07 +# CHECK: vaba.u32 d16, d18, d17 +0x40 0xef 0xf4 0x27 +# CHECK: vaba.s8 q9, q8, q10 +0x50 0xef 0xf4 0x27 +# CHECK: vaba.s16 q9, q8, q10 +0x60 0xef 0xf4 0x27 +# CHECK: vaba.s32 q9, q8, q10 +0x40 0xff 0xf4 0x27 +# CHECK: vaba.u8 q9, q8, q10 +0x50 0xff 0xf4 0x27 +# CHECK: vaba.u16 q9, q8, q10 +0x60 0xff 0xf4 0x27 +# CHECK: vaba.u32 q9, q8, q10 + +0xc3 0xef 0xa2 0x05 +# CHECK: vabal.s8 q8, d19, d18 +0xd3 0xef 0xa2 0x05 +# CHECK: vabal.s16 q8, d19, d18 +0xe3 0xef 0xa2 0x05 +# CHECK: vabal.s32 q8, d19, d18 +0xc3 0xff 0xa2 0x05 +# CHECK: vabal.u8 q8, d19, d18 +0xd3 0xff 0xa2 0x05 +# CHECK: vabal.u16 q8, d19, d18 +0xe3 0xff 0xa2 0x05 +# CHECK: vabal.u32 q8, d19, d18 + +0x41 0xef 0xa0 0x08 +# CHECK: vadd.i8 d16, d17, d16 +0x51 0xef 0xa0 0x08 +# CHECK: vadd.i16 d16, d17, d16 +0x71 0xef 0xa0 0x08 +# CHECK: vadd.i64 d16, d17, d16 +0x61 0xef 0xa0 0x08 +# CHECK: vadd.i32 d16, d17, d16 +0x40 0xef 0xa1 0x0d +# CHECK: vadd.f32 d16, d16, d17 +0x40 0xef 0xe2 0x0d +# CHECK: vadd.f32 q8, q8, q9 + +0xc1 0xef 0xa0 0x00 +# CHECK: vaddl.s8 q8, d17, d16 +0xd1 0xef 0xa0 0x00 +# CHECK: vaddl.s16 q8, d17, d16 +0xe1 0xef 0xa0 0x00 +# CHECK: vaddl.s32 q8, d17, d16 +0xc1 0xff 0xa0 0x00 +# CHECK: vaddl.u8 q8, d17, d16 +0xd1 0xff 0xa0 0x00 +# CHECK: vaddl.u16 q8, d17, d16 +0xe1 0xff 0xa0 0x00 +# CHECK: vaddl.u32 q8, d17, d16 + +0xc0 0xef 0xa2 0x01 +# CHECK: vaddw.s8 q8, q8, d18 +0xd0 0xef 0xa2 0x01 +# CHECK: vaddw.s16 q8, q8, d18 +0xe0 0xef 0xa2 0x01 +# CHECK: vaddw.s32 q8, q8, d18 +0xc0 0xff 0xa2 0x01 +# CHECK: vaddw.u8 q8, q8, d18 +0xd0 0xff 0xa2 0x01 +# CHECK: vaddw.u16 q8, q8, d18 +0xe0 0xff 0xa2 0x01 +# CHECK: vaddw.u32 q8, q8, d18 + +0x40 0xef 0xa1 0x00 +# CHECK: vhadd.s8 d16, d16, d17 +0x50 0xef 0xa1 0x00 +# CHECK: vhadd.s16 d16, d16, d17 +0x60 0xef 0xa1 0x00 +# CHECK: vhadd.s32 d16, d16, d17 +0x40 0xff 0xa1 0x00 +# CHECK: vhadd.u8 d16, d16, d17 +0x50 0xff 0xa1 0x00 +# CHECK: vhadd.u16 d16, d16, d17 +0x60 0xff 0xa1 0x00 +# CHECK: vhadd.u32 d16, d16, d17 +0x40 0xef 0xe2 0x00 +# CHECK: vhadd.s8 q8, q8, q9 +0x50 0xef 0xe2 0x00 +# CHECK: vhadd.s16 q8, q8, q9 +0x60 0xef 0xe2 0x00 +# CHECK: vhadd.s32 q8, q8, q9 +0x40 0xff 0xe2 0x00 +# CHECK: vhadd.u8 q8, q8, q9 +0x50 0xff 0xe2 0x00 +# CHECK: vhadd.u16 q8, q8, q9 +0x60 0xff 0xe2 0x00 +# CHECK: vhadd.u32 q8, q8, q9 + +0x40 0xef 0xa1 0x01 +# CHECK: vrhadd.s8 d16, d16, d17 +0x50 0xef 0xa1 0x01 +# CHECK: vrhadd.s16 d16, d16, d17 +0x60 0xef 0xa1 0x01 +# CHECK: vrhadd.s32 d16, d16, d17 +0x40 0xff 0xa1 0x01 +# CHECK: vrhadd.u8 d16, d16, d17 +0x50 0xff 0xa1 0x01 +# CHECK: vrhadd.u16 d16, d16, d17 +0x60 0xff 0xa1 0x01 +# CHECK: vrhadd.u32 d16, d16, d17 +0x40 0xef 0xe2 0x01 +# CHECK: vrhadd.s8 q8, q8, q9 +0x50 0xef 0xe2 0x01 +# CHECK: vrhadd.s16 q8, q8, q9 +0x60 0xef 0xe2 0x01 +# CHECK: vrhadd.s32 q8, q8, q9 +0x40 0xff 0xe2 0x01 +# CHECK: vrhadd.u8 q8, q8, q9 +0x50 0xff 0xe2 0x01 +# CHECK: vrhadd.u16 q8, q8, q9 +0x60 0xff 0xe2 0x01 +# CHECK: vrhadd.u32 q8, q8, q9 + +0x40 0xef 0xb1 0x00 +# CHECK: vqadd.s8 d16, d16, d17 +0x50 0xef 0xb1 0x00 +# CHECK: vqadd.s16 d16, d16, d17 +0x60 0xef 0xb1 0x00 +# CHECK: vqadd.s32 d16, d16, d17 +0x70 0xef 0xb1 0x00 +# CHECK: vqadd.s64 d16, d16, d17 +0x40 0xff 0xb1 0x00 +# CHECK: vqadd.u8 d16, d16, d17 +0x50 0xff 0xb1 0x00 +# CHECK: vqadd.u16 d16, d16, d17 +0x60 0xff 0xb1 0x00 +# CHECK: vqadd.u32 d16, d16, d17 +0x70 0xff 0xb1 0x00 +# CHECK: vqadd.u64 d16, d16, d17 +0x40 0xef 0xf2 0x00 +# CHECK: vqadd.s8 q8, q8, q9 +0x50 0xef 0xf2 0x00 +# CHECK: vqadd.s16 q8, q8, q9 +0x60 0xef 0xf2 0x00 +# CHECK: vqadd.s32 q8, q8, q9 +0x70 0xef 0xf2 0x00 +# CHECK: vqadd.s64 q8, q8, q9 +0x40 0xff 0xf2 0x00 +# CHECK: vqadd.u8 q8, q8, q9 +0x50 0xff 0xf2 0x00 +# CHECK: vqadd.u16 q8, q8, q9 +0x60 0xff 0xf2 0x00 +# CHECK: vqadd.u32 q8, q8, q9 +0x70 0xff 0xf2 0x00 +# CHECK: vqadd.u64 q8, q8, q9 + +0xc0 0xef 0xa2 0x04 +# CHECK: vaddhn.i16 d16, q8, q9 +0xd0 0xef 0xa2 0x04 +# CHECK: vaddhn.i32 d16, q8, q9 +0xe0 0xef 0xa2 0x04 +# CHECK: vaddhn.i64 d16, q8, q9 +0xc0 0xff 0xa2 0x04 +# CHECK: vraddhn.i16 d16, q8, q9 +0xd0 0xff 0xa2 0x04 +# CHECK: vraddhn.i32 d16, q8, q9 +0xe0 0xff 0xa2 0x04 +# CHECK: vraddhn.i64 d16, q8, q9 + +0xf0 0xff 0x20 0x05 +# CHECK: vcnt.8 d16, d16 +0xf0 0xff 0x60 0x05 +# CHECK: vcnt.8 q8, q8 +0xf0 0xff 0xa0 0x04 +# CHECK: vclz.i8 d16, d16 +0xf4 0xff 0xa0 0x04 +# CHECK: vclz.i16 d16, d16 +0xf8 0xff 0xa0 0x04 +# CHECK: vclz.i32 d16, d16 +0xf0 0xff 0xe0 0x04 +# CHECK: vclz.i8 q8, q8 +0xf4 0xff 0xe0 0x04 +# CHECK: vclz.i16 q8, q8 +0xf8 0xff 0xe0 0x04 +# CHECK: vclz.i32 q8, q8 +0xf0 0xff 0x20 0x04 +# CHECK: vcls.s8 d16, d16 +0xf4 0xff 0x20 0x04 +# CHECK: vcls.s16 d16, d16 +0xf8 0xff 0x20 0x04 +# CHECK: vcls.s32 d16, d16 +0xf0 0xff 0x60 0x04 +# CHECK: vcls.s8 q8, q8 +0xf4 0xff 0x60 0x04 +# CHECK: vcls.s16 q8, q8 +0xf8 0xff 0x60 0x04 +# CHECK: vcls.s32 q8, q8 + + +0x41 0xef 0xb0 0x01 +# CHECK: vand d16, d17, d16 +0x40 0xef 0xf2 0x01 +# CHECK: vand q8, q8, q9 + +0x41 0xff 0xb0 0x01 +# CHECK: veor d16, d17, d16 +0x40 0xff 0xf2 0x01 +# CHECK: veor q8, q8, q9 + +0x61 0xef 0xb0 0x01 +# CHECK: vorr d16, d17, d16 +0x60 0xef 0xf2 0x01 +# CHECK: vorr q8, q8, q9 +0xc0 0xef 0x11 0x07 +# CHECK: vorr.i32 d16, #0x1000000 +0xc0 0xef 0x51 0x07 +# CHECK: vorr.i32 q8, #0x1000000 +0xc0 0xef 0x50 0x01 +# CHECK: vorr.i32 q8, #0x0 + +0x51 0xef 0xb0 0x01 +# CHECK: vbic d16, d17, d16 +0x50 0xef 0xf2 0x01 +# CHECK: vbic q8, q8, q9 +0xc7 0xff 0x3f 0x07 +# CHECK: vbic.i32 d16, #0xFF000000 +0xc7 0xff 0x7f 0x07 +# CHECK: vbic.i32 q8, #0xFF000000 + +0x71 0xef 0xb0 0x01 +# CHECK: vorn d16, d17, d16 +0x70 0xef 0xf2 0x01 +# CHECK: vorn q8, q8, q9 + +0xf0 0xff 0xa0 0x05 +# CHECK: vmvn d16, d16 +0xf0 0xff 0xe0 0x05 +# CHECK: vmvn q8, q8 + +0x51 0xff 0xb0 0x21 +# CHECK: vbsl d18, d17, d16 +0x54 0xff 0xf2 0x01 +# CHECK: vbsl q8, q10, q9 + +0xfb 0xff 0x20 0x07 +# CHECK: vcvt.s32.f32 d16, d16 +0xfb 0xff 0xa0 0x07 +# CHECK: vcvt.u32.f32 d16, d16 +0xfb 0xff 0x20 0x06 +# CHECK: vcvt.f32.s32 d16, d16 +0xfb 0xff 0xa0 0x06 +# CHECK: vcvt.f32.u32 d16, d16 +0xfb 0xff 0x60 0x07 +# CHECK: vcvt.s32.f32 q8, q8 +0xfb 0xff 0xe0 0x07 +# CHECK: vcvt.u32.f32 q8, q8 +0xfb 0xff 0x60 0x06 +# CHECK: vcvt.f32.s32 q8, q8 +0xfb 0xff 0xe0 0x06 +# CHECK: vcvt.f32.u32 q8, q8 +0xff 0xef 0x30 0x0f +# CHECK: vcvt.s32.f32 d16, d16, #1 +0xff 0xff 0x30 0x0f +# CHECK: vcvt.u32.f32 d16, d16, #1 +0xff 0xef 0x30 0x0e +# CHECK: vcvt.f32.s32 d16, d16, #1 +0xff 0xff 0x30 0x0e +# CHECK: vcvt.f32.u32 d16, d16, #1 +0xff 0xef 0x70 0x0f +# CHECK: vcvt.s32.f32 q8, q8, #1 +0xff 0xff 0x70 0x0f +# CHECK: vcvt.u32.f32 q8, q8, #1 +0xff 0xef 0x70 0x0e +# CHECK: vcvt.f32.s32 q8, q8, #1 +0xff 0xff 0x70 0x0e +# CHECK: vcvt.f32.u32 q8, q8, #1 +0xfb 0xff 0x20 0x07 +# CHECK: vcvt.s32.f32 d16, d16 +0xfb 0xff 0xa0 0x07 +# CHECK: vcvt.u32.f32 d16, d16 +0xfb 0xff 0x20 0x06 +# CHECK: vcvt.f32.s32 d16, d16 +0xfb 0xff 0xa0 0x06 +# CHECK: vcvt.f32.u32 d16, d16 +0xfb 0xff 0x60 0x07 +# CHECK: vcvt.s32.f32 q8, q8 +0xfb 0xff 0xe0 0x07 +# CHECK: vcvt.u32.f32 q8, q8 +0xfb 0xff 0x60 0x06 +# CHECK: vcvt.f32.s32 q8, q8 +0xfb 0xff 0xe0 0x06 +# CHECK: vcvt.f32.u32 q8, q8 +0xff 0xef 0x30 0x0f +# CHECK: vcvt.s32.f32 d16, d16, #1 +0xff 0xff 0x30 0x0f +# CHECK: vcvt.u32.f32 d16, d16, #1 +0xff 0xef 0x30 0x0e +# CHECK: vcvt.f32.s32 d16, d16, #1 +0xff 0xff 0x30 0x0e +# CHECK: vcvt.f32.u32 d16, d16, #1 +0xff 0xef 0x70 0x0f +# CHECK: vcvt.s32.f32 q8, q8, #1 +0xff 0xff 0x70 0x0f +# CHECK: vcvt.u32.f32 q8, q8, #1 +0xff 0xef 0x70 0x0e +# CHECK: vcvt.f32.s32 q8, q8, #1 +0xff 0xff 0x70 0x0e +# CHECK: vcvt.f32.u32 q8, q8, #1 +0xf6 0xff 0x20 0x07 +# CHECK: vcvt.f32.f16 q8, d16 +0xf6 0xff 0x20 0x06 +# CHECK: vcvt.f16.f32 d16, q8 + +0xc0 0xee 0x90 0x0b +# CHECK: vdup.8 d16, r0 +0x80 0xee 0xb0 0x0b +# CHECK: vdup.16 d16, r0 +0x80 0xee 0x90 0x0b +# CHECK: vdup.32 d16, r0 +0xe0 0xee 0x90 0x0b +# CHECK: vdup.8 q8, r0 +0xa0 0xee 0xb0 0x0b +# CHECK: vdup.16 q8, r0 +0xa0 0xee 0x90 0x0b +# CHECK: vdup.32 q8, r0 +0xf3 0xff 0x20 0x0c +# CHECK: vdup.8 d16, d16[1] +0xf6 0xff 0x20 0x0c +# CHECK: vdup.16 d16, d16[1] +0xfc 0xff 0x20 0x0c +# CHECK: vdup.32 d16, d16[1] +0xf3 0xff 0x60 0x0c +# CHECK: vdup.8 q8, d16[1] +0xf6 0xff 0x60 0x0c +# CHECK: vdup.16 q8, d16[1] +0xfc 0xff 0x60 0x0c +# CHECK: vdup.32 q8, d16[1] + +0x40 0xef 0xb1 0x06 +# CHECK: vmin.s8 d16, d16, d17 +0x50 0xef 0xb1 0x06 +# CHECK: vmin.s16 d16, d16, d17 +0x60 0xef 0xb1 0x06 +# CHECK: vmin.s32 d16, d16, d17 +0x40 0xff 0xb1 0x06 +# CHECK: vmin.u8 d16, d16, d17 +0x50 0xff 0xb1 0x06 +# CHECK: vmin.u16 d16, d16, d17 +0x60 0xff 0xb1 0x06 +# CHECK: vmin.u32 d16, d16, d17 +0x60 0xef 0xa1 0x0f +# CHECK: vmin.f32 d16, d16, d17 +0x40 0xef 0xf2 0x06 +# CHECK: vmin.s8 q8, q8, q9 +0x50 0xef 0xf2 0x06 +# CHECK: vmin.s16 q8, q8, q9 +0x60 0xef 0xf2 0x06 +# CHECK: vmin.s32 q8, q8, q9 +0x40 0xff 0xf2 0x06 +# CHECK: vmin.u8 q8, q8, q9 +0x50 0xff 0xf2 0x06 +# CHECK: vmin.u16 q8, q8, q9 +0x60 0xff 0xf2 0x06 +# CHECK: vmin.u32 q8, q8, q9 +0x60 0xef 0xe2 0x0f +# CHECK: vmin.f32 q8, q8, q9 +0x40 0xef 0xa1 0x06 +# CHECK: vmax.s8 d16, d16, d17 +0x50 0xef 0xa1 0x06 +# CHECK: vmax.s16 d16, d16, d17 +0x60 0xef 0xa1 0x06 +# CHECK: vmax.s32 d16, d16, d17 +0x40 0xff 0xa1 0x06 +# CHECK: vmax.u8 d16, d16, d17 +0x50 0xff 0xa1 0x06 +# CHECK: vmax.u16 d16, d16, d17 +0x60 0xff 0xa1 0x06 +# CHECK: vmax.u32 d16, d16, d17 +0x40 0xef 0xa1 0x0f +# CHECK: vmax.f32 d16, d16, d17 +0x40 0xef 0xe2 0x06 +# CHECK: vmax.s8 q8, q8, q9 +0x50 0xef 0xe2 0x06 +# CHECK: vmax.s16 q8, q8, q9 +0x60 0xef 0xe2 0x06 +# CHECK: vmax.s32 q8, q8, q9 +0x40 0xff 0xe2 0x06 +# CHECK: vmax.u8 q8, q8, q9 +0x50 0xff 0xe2 0x06 +# CHECK: vmax.u16 q8, q8, q9 +0x60 0xff 0xe2 0x06 +# CHECK: vmax.u32 q8, q8, q9 +0x40 0xef 0xe2 0x0f +# CHECK: vmax.f32 q8, q8, q9 + +0xc0 0xef 0x18 0x0e +# CHECK: vmov.i8 d16, #0x8 +0xc1 0xef 0x10 0x08 +# CHECK: vmov.i16 d16, #0x10 +0xc1 0xef 0x10 0x0a +# CHECK: vmov.i16 d16, #0x1000 +0xc2 0xef 0x10 0x00 +# CHECK: vmov.i32 d16, #0x20 +0xc2 0xef 0x10 0x02 +# CHECK: vmov.i32 d16, #0x2000 +0xc2 0xef 0x10 0x04 +# CHECK: vmov.i32 d16, #0x200000 +0xc2 0xef 0x10 0x06 +# CHECK: vmov.i32 d16, #0x20000000 +0xc2 0xef 0x10 0x0c +# CHECK: vmov.i32 d16, #0x20FF +0xc2 0xef 0x10 0x0d +# CHECK: vmov.i32 d16, #0x20FFFF +0xc1 0xff 0x33 0x0e +# CHECK: vmov.i64 d16, #0xFF0000FF0000FFFF +0xc0 0xef 0x58 0x0e +# CHECK: vmov.i8 q8, #0x8 +0xc1 0xef 0x50 0x08 +# CHECK: vmov.i16 q8, #0x10 +0xc1 0xef 0x50 0x0a +# CHECK: vmov.i16 q8, #0x1000 +0xc2 0xef 0x50 0x00 +# CHECK: vmov.i32 q8, #0x20 +0xc2 0xef 0x50 0x02 +# CHECK: vmov.i32 q8, #0x2000 +0xc2 0xef 0x50 0x04 +# CHECK: vmov.i32 q8, #0x200000 +0xc2 0xef 0x50 0x06 +# CHECK: vmov.i32 q8, #0x20000000 +0xc2 0xef 0x50 0x0c +# CHECK: vmov.i32 q8, #0x20FF +0xc2 0xef 0x50 0x0d +# CHECK: vmov.i32 q8, #0x20FFFF +0xc1 0xff 0x73 0x0e +# CHECK: vmov.i64 q8, #0xFF0000FF0000FFFF +0xc1 0xef 0x30 0x08 +# CHECK: vmvn.i16 d16, #0x10 +0xc1 0xef 0x30 0x0a +# CHECK: vmvn.i16 d16, #0x1000 +0xc2 0xef 0x30 0x00 +# CHECK: vmvn.i32 d16, #0x20 +0xc2 0xef 0x30 0x02 +# CHECK: vmvn.i32 d16, #0x2000 +0xc2 0xef 0x30 0x04 +# CHECK: vmvn.i32 d16, #0x200000 +0xc2 0xef 0x30 0x06 +# CHECK: vmvn.i32 d16, #0x20000000 +0xc2 0xef 0x30 0x0c +# CHECK: vmvn.i32 d16, #0x20FF +0xc2 0xef 0x30 0x0d +# CHECK: vmvn.i32 d16, #0x20FFFF +0xc8 0xef 0x30 0x0a +# CHECK: vmovl.s8 q8, d16 +0xd0 0xef 0x30 0x0a +# CHECK: vmovl.s16 q8, d16 +0xe0 0xef 0x30 0x0a +# CHECK: vmovl.s32 q8, d16 +0xc8 0xff 0x30 0x0a +# CHECK: vmovl.u8 q8, d16 +0xd0 0xff 0x30 0x0a +# CHECK: vmovl.u16 q8, d16 +0xe0 0xff 0x30 0x0a +# CHECK: vmovl.u32 q8, d16 +0xf2 0xff 0x20 0x02 +# CHECK: vmovn.i16 d16, q8 +0xf6 0xff 0x20 0x02 +# CHECK: vmovn.i32 d16, q8 +0xfa 0xff 0x20 0x02 +# CHECK: vmovn.i64 d16, q8 +0xf2 0xff 0xa0 0x02 +# CHECK: vqmovn.s16 d16, q8 +0xf6 0xff 0xa0 0x02 +# CHECK: vqmovn.s32 d16, q8 +0xfa 0xff 0xa0 0x02 +# CHECK: vqmovn.s64 d16, q8 +0xf2 0xff 0xe0 0x02 +# CHECK: vqmovn.u16 d16, q8 +0xf6 0xff 0xe0 0x02 +# CHECK: vqmovn.u32 d16, q8 +0xfa 0xff 0xe0 0x02 +# CHECK: vqmovn.u64 d16, q8 +0xf2 0xff 0x60 0x02 +# CHECK: vqmovun.s16 d16, q8 +0xf6 0xff 0x60 0x02 +# CHECK: vqmovun.s32 d16, q8 +0xfa 0xff 0x60 0x02 +# CHECK: vqmovun.s64 d16, q8 +0x50 0xee 0xb0 0x0b +# CHECK: vmov.s8 r0, d16[1] +0x10 0xee 0xf0 0x0b +# CHECK: vmov.s16 r0, d16[1] +0xd0 0xee 0xb0 0x0b +# CHECK: vmov.u8 r0, d16[1] +0x90 0xee 0xf0 0x0b +# CHECK: vmov.u16 r0, d16[1] +0x30 0xee 0x90 0x0b +# CHECK: vmov.32 r0, d16[1] +0x40 0xee 0xb0 0x1b +# CHECK: vmov.8 d16[1], r1 +0x00 0xee 0xf0 0x1b +# CHECK: vmov.16 d16[1], r1 +0x20 0xee 0x90 0x1b +# CHECK: vmov.32 d16[1], r1 +0x42 0xee 0xb0 0x1b +# CHECK: vmov.8 d18[1], r1 +0x02 0xee 0xf0 0x1b +# CHECK: vmov.16 d18[1], r1 +0x22 0xee 0x90 0x1b +# CHECK: vmov.32 d18[1], r1 + +0x42 0xef 0xa1 0x09 +# CHECK: vmla.i8 d16, d18, d17 +0x52 0xef 0xa1 0x09 +# CHECK: vmla.i16 d16, d18, d17 +0x62 0xef 0xa1 0x09 +# CHECK: vmla.i32 d16, d18, d17 +0x42 0xef 0xb1 0x0d +# CHECK: vmla.f32 d16, d18, d17 +0x40 0xef 0xe4 0x29 +# CHECK: vmla.i8 q9, q8, q10 +0x50 0xef 0xe4 0x29 +# CHECK: vmla.i16 q9, q8, q10 +0x60 0xef 0xe4 0x29 +# CHECK: vmla.i32 q9, q8, q10 +0x40 0xef 0xf4 0x2d +# CHECK: vmla.f32 q9, q8, q10 +0xc3 0xef 0xa2 0x08 +# CHECK: vmlal.s8 q8, d19, d18 +0xd3 0xef 0xa2 0x08 +# CHECK: vmlal.s16 q8, d19, d18 +0xe3 0xef 0xa2 0x08 +# CHECK: vmlal.s32 q8, d19, d18 +0xc3 0xff 0xa2 0x08 +# CHECK: vmlal.u8 q8, d19, d18 +0xd3 0xff 0xa2 0x08 +# CHECK: vmlal.u16 q8, d19, d18 +0xe3 0xff 0xa2 0x08 +# CHECK: vmlal.u32 q8, d19, d18 +0xd3 0xef 0xa2 0x09 +# CHECK: vqdmlal.s16 q8, d19, d18 +0xe3 0xef 0xa2 0x09 +# CHECK: vqdmlal.s32 q8, d19, d18 +0x42 0xff 0xa1 0x09 +# CHECK: vmls.i8 d16, d18, d17 +0x52 0xff 0xa1 0x09 +# CHECK: vmls.i16 d16, d18, d17 +0x62 0xff 0xa1 0x09 +# CHECK: vmls.i32 d16, d18, d17 +0x62 0xef 0xb1 0x0d +# CHECK: vmls.f32 d16, d18, d17 +0x40 0xff 0xe4 0x29 +# CHECK: vmls.i8 q9, q8, q10 +0x50 0xff 0xe4 0x29 +# CHECK: vmls.i16 q9, q8, q10 +0x60 0xff 0xe4 0x29 +# CHECK: vmls.i32 q9, q8, q10 +0x60 0xef 0xf4 0x2d +# CHECK: vmls.f32 q9, q8, q10 +0xc3 0xef 0xa2 0x0a +# CHECK: vmlsl.s8 q8, d19, d18 +0xd3 0xef 0xa2 0x0a +# CHECK: vmlsl.s16 q8, d19, d18 +0xe3 0xef 0xa2 0x0a +# CHECK: vmlsl.s32 q8, d19, d18 +0xc3 0xff 0xa2 0x0a +# CHECK: vmlsl.u8 q8, d19, d18 +0xd3 0xff 0xa2 0x0a +# CHECK: vmlsl.u16 q8, d19, d18 +0xe3 0xff 0xa2 0x0a +# CHECK: vmlsl.u32 q8, d19, d18 +0xd3 0xef 0xa2 0x0b +# CHECK: vqdmlsl.s16 q8, d19, d18 +0xe3 0xef 0xa2 0x0b +# CHECK: vqdmlsl.s32 q8, d19, d18 + +0x40 0xef 0xb1 0x09 +# CHECK: vmul.i8 d16, d16, d17 +0x50 0xef 0xb1 0x09 +# CHECK: vmul.i16 d16, d16, d17 +0x60 0xef 0xb1 0x09 +# CHECK: vmul.i32 d16, d16, d17 +0x40 0xff 0xb1 0x0d +# CHECK: vmul.f32 d16, d16, d17 +0x40 0xef 0xf2 0x09 +# CHECK: vmul.i8 q8, q8, q9 +0x50 0xef 0xf2 0x09 +# CHECK: vmul.i16 q8, q8, q9 +0x60 0xef 0xf2 0x09 +# CHECK: vmul.i32 q8, q8, q9 +0x40 0xff 0xf2 0x0d +# CHECK: vmul.f32 q8, q8, q9 +0x40 0xff 0xb1 0x09 +# CHECK: vmul.p8 d16, d16, d17 +0x40 0xff 0xf2 0x09 +# CHECK: vmul.p8 q8, q8, q9 +0x50 0xef 0xa1 0x0b +# CHECK: vqdmulh.s16 d16, d16, d17 +0x60 0xef 0xa1 0x0b +# CHECK: vqdmulh.s32 d16, d16, d17 +0x50 0xef 0xe2 0x0b +# CHECK: vqdmulh.s16 q8, q8, q9 +0x60 0xef 0xe2 0x0b +# CHECK: vqdmulh.s32 q8, q8, q9 +0x50 0xff 0xa1 0x0b +# CHECK: vqrdmulh.s16 d16, d16, d17 +0x60 0xff 0xa1 0x0b +# CHECK: vqrdmulh.s32 d16, d16, d17 +0x50 0xff 0xe2 0x0b +# CHECK: vqrdmulh.s16 q8, q8, q9 +0x60 0xff 0xe2 0x0b +# CHECK: vqrdmulh.s32 q8, q8, q9 +0xc0 0xef 0xa1 0x0c +# CHECK: vmull.s8 q8, d16, d17 +0xd0 0xef 0xa1 0x0c +# CHECK: vmull.s16 q8, d16, d17 +0xe0 0xef 0xa1 0x0c +# CHECK: vmull.s32 q8, d16, d17 +0xc0 0xff 0xa1 0x0c +# CHECK: vmull.u8 q8, d16, d17 +0xd0 0xff 0xa1 0x0c +# CHECK: vmull.u16 q8, d16, d17 +0xe0 0xff 0xa1 0x0c +# CHECK: vmull.u32 q8, d16, d17 +0xc0 0xef 0xa1 0x0e +# CHECK: vmull.p8 q8, d16, d17 +0xd0 0xef 0xa1 0x0d +# CHECK: vqdmull.s16 q8, d16, d17 +0xe0 0xef 0xa1 0x0d +# CHECK: vqdmull.s32 q8, d16, d17 +0xf1 0xff 0xa0 0x03 +# CHECK: vneg.s8 d16, d16 +0xf5 0xff 0xa0 0x03 +# CHECK: vneg.s16 d16, d16 +0xf9 0xff 0xa0 0x03 +# CHECK: vneg.s32 d16, d16 +0xf9 0xff 0xa0 0x07 +# CHECK: vneg.f32 d16, d16 +0xf1 0xff 0xe0 0x03 +# CHECK: vneg.s8 q8, q8 +0xf5 0xff 0xe0 0x03 +# CHECK: vneg.s16 q8, q8 +0xf9 0xff 0xe0 0x03 +# CHECK: vneg.s32 q8, q8 +0xf9 0xff 0xe0 0x07 +# CHECK: vneg.f32 q8, q8 +0xf0 0xff 0xa0 0x07 +# CHECK: vqneg.s8 d16, d16 +0xf4 0xff 0xa0 0x07 +# CHECK: vqneg.s16 d16, d16 +0xf8 0xff 0xa0 0x07 +# CHECK: vqneg.s32 d16, d16 +0xf0 0xff 0xe0 0x07 +# CHECK: vqneg.s8 q8, q8 +0xf4 0xff 0xe0 0x07 +# CHECK: vqneg.s16 q8, q8 +0xf8 0xff 0xe0 0x07 +# CHECK: vqneg.s32 q8, q8 + +0x41 0xef 0xb0 0x0b +# CHECK: vpadd.i8 d16, d17, d16 +0x51 0xef 0xb0 0x0b +# CHECK: vpadd.i16 d16, d17, d16 +0x61 0xef 0xb0 0x0b +# CHECK: vpadd.i32 d16, d17, d16 +0x40 0xff 0xa1 0x0d +# CHECK: vpadd.f32 d16, d16, d17 +0xf0 0xff 0x20 0x02 +# CHECK: vpaddl.s8 d16, d16 +0xf4 0xff 0x20 0x02 +# CHECK: vpaddl.s16 d16, d16 +0xf8 0xff 0x20 0x02 +# CHECK: vpaddl.s32 d16, d16 +0xf0 0xff 0xa0 0x02 +# CHECK: vpaddl.u8 d16, d16 +0xf4 0xff 0xa0 0x02 +# CHECK: vpaddl.u16 d16, d16 +0xf8 0xff 0xa0 0x02 +# CHECK: vpaddl.u32 d16, d16 +0xf0 0xff 0x60 0x02 +# CHECK: vpaddl.s8 q8, q8 +0xf4 0xff 0x60 0x02 +# CHECK: vpaddl.s16 q8, q8 +0xf8 0xff 0x60 0x02 +# CHECK: vpaddl.s32 q8, q8 +0xf0 0xff 0xe0 0x02 +# CHECK: vpaddl.u8 q8, q8 +0xf4 0xff 0xe0 0x02 +# CHECK: vpaddl.u16 q8, q8 +0xf8 0xff 0xe0 0x02 +# CHECK: vpaddl.u32 q8, q8 +0xf0 0xff 0x21 0x06 +# CHECK: vpadal.s8 d16, d17 +0xf4 0xff 0x21 0x06 +# CHECK: vpadal.s16 d16, d17 +0xf8 0xff 0x21 0x06 +# CHECK: vpadal.s32 d16, d17 +0xf0 0xff 0xa1 0x06 +# CHECK: vpadal.u8 d16, d17 +0xf4 0xff 0xa1 0x06 +# CHECK: vpadal.u16 d16, d17 +0xf8 0xff 0xa1 0x06 +# CHECK: vpadal.u32 d16, d17 +0xf0 0xff 0x60 0x26 +# CHECK: vpadal.s8 q9, q8 +0xf4 0xff 0x60 0x26 +# CHECK: vpadal.s16 q9, q8 +0xf8 0xff 0x60 0x26 +# CHECK: vpadal.s32 q9, q8 +0xf0 0xff 0xe0 0x26 +# CHECK: vpadal.u8 q9, q8 +0xf4 0xff 0xe0 0x26 +# CHECK: vpadal.u16 q9, q8 +0xf8 0xff 0xe0 0x26 +# CHECK: vpadal.u32 q9, q8 +0x40 0xef 0xb1 0x0a +# CHECK: vpmin.s8 d16, d16, d17 +0x50 0xef 0xb1 0x0a +# CHECK: vpmin.s16 d16, d16, d17 +0x60 0xef 0xb1 0x0a +# CHECK: vpmin.s32 d16, d16, d17 +0x40 0xff 0xb1 0x0a +# CHECK: vpmin.u8 d16, d16, d17 +0x50 0xff 0xb1 0x0a +# CHECK: vpmin.u16 d16, d16, d17 +0x60 0xff 0xb1 0x0a +# CHECK: vpmin.u32 d16, d16, d17 +0x60 0xff 0xa1 0x0f +# CHECK: vpmin.f32 d16, d16, d17 +0x40 0xef 0xa1 0x0a +# CHECK: vpmax.s8 d16, d16, d17 +0x50 0xef 0xa1 0x0a +# CHECK: vpmax.s16 d16, d16, d17 +0x60 0xef 0xa1 0x0a +# CHECK: vpmax.s32 d16, d16, d17 +0x40 0xff 0xa1 0x0a +# CHECK: vpmax.u8 d16, d16, d17 +0x50 0xff 0xa1 0x0a +# CHECK: vpmax.u16 d16, d16, d17 +0x60 0xff 0xa1 0x0a +# CHECK: vpmax.u32 d16, d16, d17 +0x40 0xff 0xa1 0x0f +# CHECK: vpmax.f32 d16, d16, d17 +0xfb 0xff 0x20 0x04 +# CHECK: vrecpe.u32 d16, d16 +0xfb 0xff 0x60 0x04 +# CHECK: vrecpe.u32 q8, q8 +0xfb 0xff 0x20 0x05 +# CHECK: vrecpe.f32 d16, d16 +0xfb 0xff 0x60 0x05 +# CHECK: vrecpe.f32 q8, q8 +0x40 0xef 0xb1 0x0f +# CHECK: vrecps.f32 d16, d16, d17 +0x40 0xef 0xf2 0x0f +# CHECK: vrecps.f32 q8, q8, q9 +0xfb 0xff 0xa0 0x04 +# CHECK: vrsqrte.u32 d16, d16 +0xfb 0xff 0xe0 0x04 +# CHECK: vrsqrte.u32 q8, q8 +0xfb 0xff 0xa0 0x05 +# CHECK: vrsqrte.f32 d16, d16 +0xfb 0xff 0xe0 0x05 +# CHECK: vrsqrte.f32 q8, q8 +0x60 0xef 0xb1 0x0f +# CHECK: vrsqrts.f32 d16, d16, d17 +0x60 0xef 0xf2 0x0f +# CHECK: vrsqrts.f32 q8, q8, q9 + + +0xf0 0xff 0x20 0x00 +# CHECK: vrev64.8 d16, d16 +0xf4 0xff 0x20 0x00 +# CHECK: vrev64.16 d16, d16 +0xf8 0xff 0x20 0x00 +# CHECK: vrev64.32 d16, d16 +0xf0 0xff 0x60 0x00 +# CHECK: vrev64.8 q8, q8 +0xf4 0xff 0x60 0x00 +# CHECK: vrev64.16 q8, q8 +0xf8 0xff 0x60 0x00 +# CHECK: vrev64.32 q8, q8 +0xf0 0xff 0xa0 0x00 +# CHECK: vrev32.8 d16, d16 +0xf4 0xff 0xa0 0x00 +# CHECK: vrev32.16 d16, d16 +0xf0 0xff 0xe0 0x00 +# CHECK: vrev32.8 q8, q8 +0xf4 0xff 0xe0 0x00 +# CHECK: vrev32.16 q8, q8 +0xf0 0xff 0x20 0x01 +# CHECK: vrev16.8 d16, d16 +0xf0 0xff 0x60 0x01 +# CHECK: vrev16.8 q8, q8 +0x41 0xef 0xb0 0x04 +# CHECK: vqshl.s8 d16, d16, d17 +0x51 0xef 0xb0 0x04 +# CHECK: vqshl.s16 d16, d16, d17 +0x61 0xef 0xb0 0x04 +# CHECK: vqshl.s32 d16, d16, d17 +0x71 0xef 0xb0 0x04 +# CHECK: vqshl.s64 d16, d16, d17 +0x41 0xff 0xb0 0x04 +# CHECK: vqshl.u8 d16, d16, d17 +0x51 0xff 0xb0 0x04 +# CHECK: vqshl.u16 d16, d16, d17 +0x61 0xff 0xb0 0x04 +# CHECK: vqshl.u32 d16, d16, d17 +0x71 0xff 0xb0 0x04 +# CHECK: vqshl.u64 d16, d16, d17 +0x42 0xef 0xf0 0x04 +# CHECK: vqshl.s8 q8, q8, q9 +0x52 0xef 0xf0 0x04 +# CHECK: vqshl.s16 q8, q8, q9 +0x62 0xef 0xf0 0x04 +# CHECK: vqshl.s32 q8, q8, q9 +0x72 0xef 0xf0 0x04 +# CHECK: vqshl.s64 q8, q8, q9 +0x42 0xff 0xf0 0x04 +# CHECK: vqshl.u8 q8, q8, q9 +0x52 0xff 0xf0 0x04 +# CHECK: vqshl.u16 q8, q8, q9 +0x62 0xff 0xf0 0x04 +# CHECK: vqshl.u32 q8, q8, q9 +0x72 0xff 0xf0 0x04 +# CHECK: vqshl.u64 q8, q8, q9 +0xcf 0xef 0x30 0x07 +# CHECK: vqshl.s8 d16, d16, #7 +0xdf 0xef 0x30 0x07 +# CHECK: vqshl.s16 d16, d16, #15 +0xff 0xef 0x30 0x07 +# CHECK: vqshl.s32 d16, d16, #31 +0xff 0xef 0xb0 0x07 +# CHECK: vqshl.s64 d16, d16, #63 +0xcf 0xff 0x30 0x07 +# CHECK: vqshl.u8 d16, d16, #7 +0xdf 0xff 0x30 0x07 +# CHECK: vqshl.u16 d16, d16, #15 +0xff 0xff 0x30 0x07 +# CHECK: vqshl.u32 d16, d16, #31 +0xff 0xff 0xb0 0x07 +# CHECK: vqshl.u64 d16, d16, #63 +0xcf 0xff 0x30 0x06 +# CHECK: vqshlu.s8 d16, d16, #7 +0xdf 0xff 0x30 0x06 +# CHECK: vqshlu.s16 d16, d16, #15 +0xff 0xff 0x30 0x06 +# CHECK: vqshlu.s32 d16, d16, #31 +0xff 0xff 0xb0 0x06 +# CHECK: vqshlu.s64 d16, d16, #63 +0xcf 0xef 0x70 0x07 +# CHECK: vqshl.s8 q8, q8, #7 +0xdf 0xef 0x70 0x07 +# CHECK: vqshl.s16 q8, q8, #15 +0xff 0xef 0x70 0x07 +# CHECK: vqshl.s32 q8, q8, #31 +0xff 0xef 0xf0 0x07 +# CHECK: vqshl.s64 q8, q8, #63 +0xcf 0xff 0x70 0x07 +# CHECK: vqshl.u8 q8, q8, #7 +0xdf 0xff 0x70 0x07 +# CHECK: vqshl.u16 q8, q8, #15 +0xff 0xff 0x70 0x07 +# CHECK: vqshl.u32 q8, q8, #31 +0xff 0xff 0xf0 0x07 +# CHECK: vqshl.u64 q8, q8, #63 +0xcf 0xff 0x70 0x06 +# CHECK: vqshlu.s8 q8, q8, #7 +0xdf 0xff 0x70 0x06 +# CHECK: vqshlu.s16 q8, q8, #15 +0xff 0xff 0x70 0x06 +# CHECK: vqshlu.s32 q8, q8, #31 +0xff 0xff 0xf0 0x06 +# CHECK: vqshlu.s64 q8, q8, #63 +0x41 0xef 0xb0 0x05 +# CHECK: vqrshl.s8 d16, d16, d17 +0x51 0xef 0xb0 0x05 +# CHECK: vqrshl.s16 d16, d16, d17 +0x61 0xef 0xb0 0x05 +# CHECK: vqrshl.s32 d16, d16, d17 +0x71 0xef 0xb0 0x05 +# CHECK: vqrshl.s64 d16, d16, d17 +0x41 0xff 0xb0 0x05 +# CHECK: vqrshl.u8 d16, d16, d17 +0x51 0xff 0xb0 0x05 +# CHECK: vqrshl.u16 d16, d16, d17 +0x61 0xff 0xb0 0x05 +# CHECK: vqrshl.u32 d16, d16, d17 +0x71 0xff 0xb0 0x05 +# CHECK: vqrshl.u64 d16, d16, d17 +0x42 0xef 0xf0 0x05 +# CHECK: vqrshl.s8 q8, q8, q9 +0x52 0xef 0xf0 0x05 +# CHECK: vqrshl.s16 q8, q8, q9 +0x62 0xef 0xf0 0x05 +# CHECK: vqrshl.s32 q8, q8, q9 +0x72 0xef 0xf0 0x05 +# CHECK: vqrshl.s64 q8, q8, q9 +0x42 0xff 0xf0 0x05 +# CHECK: vqrshl.u8 q8, q8, q9 +0x52 0xff 0xf0 0x05 +# CHECK: vqrshl.u16 q8, q8, q9 +0x62 0xff 0xf0 0x05 +# CHECK: vqrshl.u32 q8, q8, q9 +0x72 0xff 0xf0 0x05 +# CHECK: vqrshl.u64 q8, q8, q9 +0xc8 0xef 0x30 0x09 +# CHECK: vqshrn.s16 d16, q8, #8 +0xd0 0xef 0x30 0x09 +# CHECK: vqshrn.s32 d16, q8, #16 +0xe0 0xef 0x30 0x09 +# CHECK: vqshrn.s64 d16, q8, #32 +0xc8 0xff 0x30 0x09 +# CHECK: vqshrn.u16 d16, q8, #8 +0xd0 0xff 0x30 0x09 +# CHECK: vqshrn.u32 d16, q8, #16 +0xe0 0xff 0x30 0x09 +# CHECK: vqshrn.u64 d16, q8, #32 +0xc8 0xff 0x30 0x08 +# CHECK: vqshrun.s16 d16, q8, #8 +0xd0 0xff 0x30 0x08 +# CHECK: vqshrun.s32 d16, q8, #16 +0xe0 0xff 0x30 0x08 +# CHECK: vqshrun.s64 d16, q8, #32 +0xc8 0xef 0x70 0x09 +# CHECK: vqrshrn.s16 d16, q8, #8 +0xd0 0xef 0x70 0x09 +# CHECK: vqrshrn.s32 d16, q8, #16 +0xe0 0xef 0x70 0x09 +# CHECK: vqrshrn.s64 d16, q8, #32 +0xc8 0xff 0x70 0x09 +# CHECK: vqrshrn.u16 d16, q8, #8 +0xd0 0xff 0x70 0x09 +# CHECK: vqrshrn.u32 d16, q8, #16 +0xe0 0xff 0x70 0x09 +# CHECK: vqrshrn.u64 d16, q8, #32 +0xc8 0xff 0x70 0x08 +# CHECK: vqrshrun.s16 d16, q8, #8 +0xd0 0xff 0x70 0x08 +# CHECK: vqrshrun.s32 d16, q8, #16 +0xe0 0xff 0x70 0x08 +# CHECK: vqrshrun.s64 d16, q8, #32 +0x40 0xff 0xa1 0x04 +# CHECK: vshl.u8 d16, d17, d16 +0x50 0xff 0xa1 0x04 +# CHECK: vshl.u16 d16, d17, d16 +0x60 0xff 0xa1 0x04 +# CHECK: vshl.u32 d16, d17, d16 +0x70 0xff 0xa1 0x04 +# CHECK: vshl.u64 d16, d17, d16 +0xcf 0xef 0x30 0x05 +# CHECK: vshl.i8 d16, d16, #7 +0xdf 0xef 0x30 0x05 +# CHECK: vshl.i16 d16, d16, #15 +0xff 0xef 0x30 0x05 +# CHECK: vshl.i32 d16, d16, #31 +0xff 0xef 0xb0 0x05 +# CHECK: vshl.i64 d16, d16, #63 +0x40 0xff 0xe2 0x04 +# CHECK: vshl.u8 q8, q9, q8 +0x50 0xff 0xe2 0x04 +# CHECK: vshl.u16 q8, q9, q8 +0x60 0xff 0xe2 0x04 +# CHECK: vshl.u32 q8, q9, q8 +0x70 0xff 0xe2 0x04 +# CHECK: vshl.u64 q8, q9, q8 +0xcf 0xef 0x70 0x05 +# CHECK: vshl.i8 q8, q8, #7 +0xdf 0xef 0x70 0x05 +# CHECK: vshl.i16 q8, q8, #15 +0xff 0xef 0x70 0x05 +# CHECK: vshl.i32 q8, q8, #31 +0xff 0xef 0xf0 0x05 +# CHECK: vshl.i64 q8, q8, #63 +0xc8 0xff 0x30 0x00 +# CHECK: vshr.u8 d16, d16, #8 +0xd0 0xff 0x30 0x00 +# CHECK: vshr.u16 d16, d16, #16 +0xe0 0xff 0x30 0x00 +# CHECK: vshr.u32 d16, d16, #32 +0xc0 0xff 0xb0 0x00 +# CHECK: vshr.u64 d16, d16, #64 +0xc8 0xff 0x70 0x00 +# CHECK: vshr.u8 q8, q8, #8 +0xd0 0xff 0x70 0x00 +# CHECK: vshr.u16 q8, q8, #16 +0xe0 0xff 0x70 0x00 +# CHECK: vshr.u32 q8, q8, #32 +0xc0 0xff 0xf0 0x00 +# CHECK: vshr.u64 q8, q8, #64 +0xc8 0xef 0x30 0x00 +# CHECK: vshr.s8 d16, d16, #8 +0xd0 0xef 0x30 0x00 +# CHECK: vshr.s16 d16, d16, #16 +0xe0 0xef 0x30 0x00 +# CHECK: vshr.s32 d16, d16, #32 +0xc0 0xef 0xb0 0x00 +# CHECK: vshr.s64 d16, d16, #64 +0xc8 0xef 0x70 0x00 +# CHECK: vshr.s8 q8, q8, #8 +0xd0 0xef 0x70 0x00 +# CHECK: vshr.s16 q8, q8, #16 +0xe0 0xef 0x70 0x00 +# CHECK: vshr.s32 q8, q8, #32 +0xc0 0xef 0xf0 0x00 +# CHECK: vshr.s64 q8, q8, #64 +0xcf 0xef 0x30 0x0a +# CHECK: vshll.s8 q8, d16, #7 +0xdf 0xef 0x30 0x0a +# CHECK: vshll.s16 q8, d16, #15 +0xff 0xef 0x30 0x0a +# CHECK: vshll.s32 q8, d16, #31 +0xcf 0xff 0x30 0x0a +# CHECK: vshll.u8 q8, d16, #7 +0xdf 0xff 0x30 0x0a +# CHECK: vshll.u16 q8, d16, #15 +0xff 0xff 0x30 0x0a +# CHECK: vshll.u32 q8, d16, #31 +0xf2 0xff 0x20 0x03 +# CHECK: vshll.i8 q8, d16, #8 +0xf6 0xff 0x20 0x03 +# CHECK: vshll.i16 q8, d16, #16 +0xfa 0xff 0x20 0x03 +# CHECK: vshll.i32 q8, d16, #32 +0xc8 0xef 0x30 0x08 +# CHECK: vshrn.i16 d16, q8, #8 +0xd0 0xef 0x30 0x08 +# CHECK: vshrn.i32 d16, q8, #16 +0xe0 0xef 0x30 0x08 +# CHECK: vshrn.i64 d16, q8, #32 +0x40 0xef 0xa1 0x05 +# CHECK: vrshl.s8 d16, d17, d16 +0x50 0xef 0xa1 0x05 +# CHECK: vrshl.s16 d16, d17, d16 +0x60 0xef 0xa1 0x05 +# CHECK: vrshl.s32 d16, d17, d16 +0x70 0xef 0xa1 0x05 +# CHECK: vrshl.s64 d16, d17, d16 +0x40 0xff 0xa1 0x05 +# CHECK: vrshl.u8 d16, d17, d16 +0x50 0xff 0xa1 0x05 +# CHECK: vrshl.u16 d16, d17, d16 +0x60 0xff 0xa1 0x05 +# CHECK: vrshl.u32 d16, d17, d16 +0x70 0xff 0xa1 0x05 +# CHECK: vrshl.u64 d16, d17, d16 +0x40 0xef 0xe2 0x05 +# CHECK: vrshl.s8 q8, q9, q8 +0x50 0xef 0xe2 0x05 +# CHECK: vrshl.s16 q8, q9, q8 +0x60 0xef 0xe2 0x05 +# CHECK: vrshl.s32 q8, q9, q8 +0x70 0xef 0xe2 0x05 +# CHECK: vrshl.s64 q8, q9, q8 +0x40 0xff 0xe2 0x05 +# CHECK: vrshl.u8 q8, q9, q8 +0x50 0xff 0xe2 0x05 +# CHECK: vrshl.u16 q8, q9, q8 +0x60 0xff 0xe2 0x05 +# CHECK: vrshl.u32 q8, q9, q8 +0x70 0xff 0xe2 0x05 +# CHECK: vrshl.u64 q8, q9, q8 +0xc8 0xef 0x30 0x02 +# CHECK: vrshr.s8 d16, d16, #8 +0xd0 0xef 0x30 0x02 +# CHECK: vrshr.s16 d16, d16, #16 +0xe0 0xef 0x30 0x02 +# CHECK: vrshr.s32 d16, d16, #32 +0xc0 0xef 0xb0 0x02 +# CHECK: vrshr.s64 d16, d16, #64 +0xc8 0xff 0x30 0x02 +# CHECK: vrshr.u8 d16, d16, #8 +0xd0 0xff 0x30 0x02 +# CHECK: vrshr.u16 d16, d16, #16 +0xe0 0xff 0x30 0x02 +# CHECK: vrshr.u32 d16, d16, #32 +0xc0 0xff 0xb0 0x02 +# CHECK: vrshr.u64 d16, d16, #64 +0xc8 0xef 0x70 0x02 +# CHECK: vrshr.s8 q8, q8, #8 +0xd0 0xef 0x70 0x02 +# CHECK: vrshr.s16 q8, q8, #16 +0xe0 0xef 0x70 0x02 +# CHECK: vrshr.s32 q8, q8, #32 +0xc0 0xef 0xf0 0x02 +# CHECK: vrshr.s64 q8, q8, #64 +0xc8 0xff 0x70 0x02 +# CHECK: vrshr.u8 q8, q8, #8 +0xd0 0xff 0x70 0x02 +# CHECK: vrshr.u16 q8, q8, #16 +0xe0 0xff 0x70 0x02 +# CHECK: vrshr.u32 q8, q8, #32 +0xc0 0xff 0xf0 0x02 +# CHECK: vrshr.u64 q8, q8, #64 +0xc8 0xef 0x70 0x08 +# CHECK: vrshrn.i16 d16, q8, #8 +0xd0 0xef 0x70 0x08 +# CHECK: vrshrn.i32 d16, q8, #16 +0xe0 0xef 0x70 0x08 +# CHECK: vrshrn.i64 d16, q8, #32 +0xc8 0xef 0x30 0x11 +# CHECK: vsra.s8 d17, d16, #8 +0xd0 0xef 0x30 0x11 +# CHECK: vsra.s16 d17, d16, #16 +0xe0 0xef 0x30 0x11 +# CHECK: vsra.s32 d17, d16, #32 +0xc0 0xef 0xb0 0x11 +# CHECK: vsra.s64 d17, d16, #64 +0xc8 0xef 0x72 0x01 +# CHECK: vsra.s8 q8, q9, #8 +0xd0 0xef 0x72 0x01 +# CHECK: vsra.s16 q8, q9, #16 +0xe0 0xef 0x72 0x01 +# CHECK: vsra.s32 q8, q9, #32 +0xc0 0xef 0xf2 0x01 +# CHECK: vsra.s64 q8, q9, #64 +0xc8 0xff 0x30 0x11 +# CHECK: vsra.u8 d17, d16, #8 +0xd0 0xff 0x30 0x11 +# CHECK: vsra.u16 d17, d16, #16 +0xe0 0xff 0x30 0x11 +# CHECK: vsra.u32 d17, d16, #32 +0xc0 0xff 0xb0 0x11 +# CHECK: vsra.u64 d17, d16, #64 +0xc8 0xff 0x72 0x01 +# CHECK: vsra.u8 q8, q9, #8 +0xd0 0xff 0x72 0x01 +# CHECK: vsra.u16 q8, q9, #16 +0xe0 0xff 0x72 0x01 +# CHECK: vsra.u32 q8, q9, #32 +0xc0 0xff 0xf2 0x01 +# CHECK: vsra.u64 q8, q9, #64 +0xc8 0xef 0x30 0x13 +# CHECK: vrsra.s8 d17, d16, #8 +0xd0 0xef 0x30 0x13 +# CHECK: vrsra.s16 d17, d16, #16 +0xe0 0xef 0x30 0x13 +# CHECK: vrsra.s32 d17, d16, #32 +0xc0 0xef 0xb0 0x13 +# CHECK: vrsra.s64 d17, d16, #64 +0xc8 0xff 0x30 0x13 +# CHECK: vrsra.u8 d17, d16, #8 +0xd0 0xff 0x30 0x13 +# CHECK: vrsra.u16 d17, d16, #16 +0xe0 0xff 0x30 0x13 +# CHECK: vrsra.u32 d17, d16, #32 +0xc0 0xff 0xb0 0x13 +# CHECK: vrsra.u64 d17, d16, #64 +0xc8 0xef 0x72 0x03 +# CHECK: vrsra.s8 q8, q9, #8 +0xd0 0xef 0x72 0x03 +# CHECK: vrsra.s16 q8, q9, #16 +0xe0 0xef 0x72 0x03 +# CHECK: vrsra.s32 q8, q9, #32 +0xc0 0xef 0xf2 0x03 +# CHECK: vrsra.s64 q8, q9, #64 +0xc8 0xff 0x72 0x03 +# CHECK: vrsra.u8 q8, q9, #8 +0xd0 0xff 0x72 0x03 +# CHECK: vrsra.u16 q8, q9, #16 +0xe0 0xff 0x72 0x03 +# CHECK: vrsra.u32 q8, q9, #32 +0xc0 0xff 0xf2 0x03 +# CHECK: vrsra.u64 q8, q9, #64 +0xcf 0xff 0x30 0x15 +# CHECK: vsli.8 d17, d16, #7 +0xdf 0xff 0x30 0x15 +# CHECK: vsli.16 d17, d16, #15 +0xff 0xff 0x30 0x15 +# CHECK: vsli.32 d17, d16, #31 +0xff 0xff 0xb0 0x15 +# CHECK: vsli.64 d17, d16, #63 +0xcf 0xff 0x70 0x25 +# CHECK: vsli.8 q9, q8, #7 +0xdf 0xff 0x70 0x25 +# CHECK: vsli.16 q9, q8, #15 +0xff 0xff 0x70 0x25 +# CHECK: vsli.32 q9, q8, #31 +0xff 0xff 0xf0 0x25 +# CHECK: vsli.64 q9, q8, #63 +0xc8 0xff 0x30 0x14 +# CHECK: vsri.8 d17, d16, #8 +0xd0 0xff 0x30 0x14 +# CHECK: vsri.16 d17, d16, #16 +0xe0 0xff 0x30 0x14 +# CHECK: vsri.32 d17, d16, #32 +0xc0 0xff 0xb0 0x14 +# CHECK: vsri.64 d17, d16, #64 +0xc8 0xff 0x70 0x24 +# CHECK: vsri.8 q9, q8, #8 +0xd0 0xff 0x70 0x24 +# CHECK: vsri.16 q9, q8, #16 +0xe0 0xff 0x70 0x24 +# CHECK: vsri.32 q9, q8, #32 +0xc0 0xff 0xf0 0x24 +# CHECK: vsri.64 q9, q8, #64 +0xf1 0xef 0xa0 0x03 +# CHECK: vext.8 d16, d17, d16, #3 +0xf1 0xef 0xa0 0x05 +# CHECK: vext.8 d16, d17, d16, #5 +0xf2 0xef 0xe0 0x03 +# CHECK: vext.8 q8, q9, q8, #3 +0xf2 0xef 0xe0 0x07 +# CHECK: vext.8 q8, q9, q8, #7 +0xf1 0xef 0xa0 0x06 +# CHECK: vext.16 d16, d17, d16, #3 +0xf2 0xef 0xe0 0x0c +# CHECK: vext.32 q8, q9, q8, #3 +0xf2 0xff 0xa0 0x10 +# CHECK: vtrn.8 d17, d16 +0xf6 0xff 0xa0 0x10 +# CHECK: vtrn.16 d17, d16 +0xfa 0xff 0xa0 0x10 +# CHECK: vtrn.32 d17, d16 +0xf2 0xff 0xe0 0x20 +# CHECK: vtrn.8 q9, q8 +0xf6 0xff 0xe0 0x20 +# CHECK: vtrn.16 q9, q8 +0xfa 0xff 0xe0 0x20 +# CHECK: vtrn.32 q9, q8 +0xf2 0xff 0x20 0x11 +# CHECK: vuzp.8 d17, d16 +0xf6 0xff 0x20 0x11 +# CHECK: vuzp.16 d17, d16 +0xf2 0xff 0x60 0x21 +# CHECK: vuzp.8 q9, q8 +0xf6 0xff 0x60 0x21 +# CHECK: vuzp.16 q9, q8 +0xfa 0xff 0x60 0x21 +# CHECK: vuzp.32 q9, q8 +0xf2 0xff 0xa0 0x11 +# CHECK: vzip.8 d17, d16 +0xf6 0xff 0xa0 0x11 +# CHECK: vzip.16 d17, d16 +0xf2 0xff 0xe0 0x21 +# CHECK: vzip.8 q9, q8 +0xf6 0xff 0xe0 0x21 +# CHECK: vzip.16 q9, q8 +0xfa 0xff 0xe0 0x21 +# CHECK: vzip.32 q9, q8 + + +0xf1 0xef 0xa0 0x03 +# CHECK: vext.8 d16, d17, d16, #3 +0xf1 0xef 0xa0 0x05 +# CHECK: vext.8 d16, d17, d16, #5 +0xf2 0xef 0xe0 0x03 +# CHECK: vext.8 q8, q9, q8, #3 +0xf2 0xef 0xe0 0x07 +# CHECK: vext.8 q8, q9, q8, #7 +0xf1 0xef 0xa0 0x06 +# CHECK: vext.16 d16, d17, d16, #3 +0xf2 0xef 0xe0 0x0c +# CHECK: vext.32 q8, q9, q8, #3 +0xf2 0xff 0xa0 0x10 +# CHECK: vtrn.8 d17, d16 +0xf6 0xff 0xa0 0x10 +# CHECK: vtrn.16 d17, d16 +0xfa 0xff 0xa0 0x10 +# CHECK: vtrn.32 d17, d16 +0xf2 0xff 0xe0 0x20 +# CHECK: vtrn.8 q9, q8 +0xf6 0xff 0xe0 0x20 +# CHECK: vtrn.16 q9, q8 +0xfa 0xff 0xe0 0x20 +# CHECK: vtrn.32 q9, q8 +0xf2 0xff 0x20 0x11 +# CHECK: vuzp.8 d17, d16 +0xf6 0xff 0x20 0x11 +# CHECK: vuzp.16 d17, d16 +0xf2 0xff 0x60 0x21 +# CHECK: vuzp.8 q9, q8 +0xf6 0xff 0x60 0x21 +# CHECK: vuzp.16 q9, q8 +0xfa 0xff 0x60 0x21 +# CHECK: vuzp.32 q9, q8 +0xf2 0xff 0xa0 0x11 +# CHECK: vzip.8 d17, d16 +0xf6 0xff 0xa0 0x11 +# CHECK: vzip.16 d17, d16 +0xf2 0xff 0xe0 0x21 +# CHECK: vzip.8 q9, q8 +0xf6 0xff 0xe0 0x21 +# CHECK: vzip.16 q9, q8 +0xfa 0xff 0xe0 0x21 +# CHECK: vzip.32 q9, q8 + +0xf1 0xff 0xa0 0x08 +# CHECK: vtbl.8 d16, {d17}, d16 +0xf0 0xff 0xa2 0x09 +# CHECK: vtbl.8 d16, {d16, d17}, d18 +0xf0 0xff 0xa4 0x0a +# CHECK: vtbl.8 d16, {d16, d17, d18}, d20 +0xf0 0xff 0xa4 0x0b +# CHECK: vtbl.8 d16, {d16, d17, d18, d19}, d20 +0xf0 0xff 0xe1 0x28 +# CHECK: vtbx.8 d18, {d16}, d17 +0xf0 0xff 0xe2 0x39 +# CHECK: vtbx.8 d19, {d16, d17}, d18 +0xf0 0xff 0xe5 0x4a +# CHECK: vtbx.8 d20, {d16, d17, d18}, d21 +0xf0 0xff 0xe5 0x4b +# CHECK: vtbx.8 d20, {d16, d17, d18, d19}, d21 + +0x60 0xf9 0x1f 0x07 +# CHECK: vld1.8 {d16}, [r0, :64] +0x60 0xf9 0x4f 0x07 +# CHECK: vld1.16 {d16}, [r0] +0x60 0xf9 0x8f 0x07 +# CHECK: vld1.32 {d16}, [r0] +0x60 0xf9 0xcf 0x07 +# CHECK: vld1.64 {d16}, [r0] +0x60 0xf9 0x1f 0x0a +# CHECK: vld1.8 {d16, d17}, [r0, :64] +0x60 0xf9 0x6f 0x0a +# CHECK: vld1.16 {d16, d17}, [r0, :128] +0x60 0xf9 0x8f 0x0a +# CHECK: vld1.32 {d16, d17}, [r0] +0x60 0xf9 0xcf 0x0a +# CHECK: vld1.64 {d16, d17}, [r0] + +0x60 0xf9 0x1f 0x08 +# CHECK: vld2.8 {d16, d17}, [r0, :64] +0x60 0xf9 0x6f 0x08 +# CHECK: vld2.16 {d16, d17}, [r0, :128] +0x60 0xf9 0x8f 0x08 +# CHECK: vld2.32 {d16, d17}, [r0] +0x60 0xf9 0x1f 0x03 +# CHECK: vld2.8 {d16, d17, d18, d19}, [r0, :64] +0x60 0xf9 0x6f 0x03 +# CHECK: vld2.16 {d16, d17, d18, d19}, [r0, :128] +0x60 0xf9 0xbf 0x03 +# CHECK: vld2.32 {d16, d17, d18, d19}, [r0, :256] + +0x60 0xf9 0x1f 0x04 +# CHECK: vld3.8 {d16, d17, d18}, [r0, :64] +0x60 0xf9 0x4f 0x04 +# CHECK: vld3.16 {d16, d17, d18}, [r0] +0x60 0xf9 0x8f 0x04 +# CHECK: vld3.32 {d16, d17, d18}, [r0] +0x60 0xf9 0x1d 0x05 +# CHECK: vld3.8 {d16, d18, d20}, [r0, :64]! +0x60 0xf9 0x1d 0x15 +# CHECK: vld3.8 {d17, d19, d21}, [r0, :64]! +0x60 0xf9 0x4d 0x05 +# CHECK: vld3.16 {d16, d18, d20}, [r0]! +0x60 0xf9 0x4d 0x15 +# CHECK: vld3.16 {d17, d19, d21}, [r0]! +0x60 0xf9 0x8d 0x05 +# CHECK: vld3.32 {d16, d18, d20}, [r0]! +0x60 0xf9 0x8d 0x15 +# CHECK: vld3.32 {d17, d19, d21}, [r0]! + +0x60 0xf9 0x1f 0x00 +# CHECK: vld4.8 {d16, d17, d18, d19}, [r0, :64] +0x60 0xf9 0x6f 0x00 +# CHECK: vld4.16 {d16, d17, d18, d19}, [r0, :128] +0x60 0xf9 0xbf 0x00 +# CHECK: vld4.32 {d16, d17, d18, d19}, [r0, :256] +0x60 0xf9 0x3d 0x01 +# CHECK: vld4.8 {d16, d18, d20, d22}, [r0, :256]! +0x60 0xf9 0x3d 0x11 +# CHECK: vld4.8 {d17, d19, d21, d23}, [r0, :256]! +0x60 0xf9 0x4d 0x01 +# CHECK: vld4.16 {d16, d18, d20, d22}, [r0]! +0x60 0xf9 0x4d 0x11 +# CHECK: vld4.16 {d17, d19, d21, d23}, [r0]! +0x60 0xf9 0x8d 0x01 +# CHECK: vld4.32 {d16, d18, d20, d22}, [r0]! +0x60 0xf9 0x8d 0x11 +# CHECK: vld4.32 {d17, d19, d21, d23}, [r0]! + +0xe0 0xf9 0x6f 0x00 +# CHECK: vld1.8 {d16[3]}, [r0] +0xe0 0xf9 0x9f 0x04 +# CHECK: vld1.16 {d16[2]}, [r0, :16] +0xe0 0xf9 0xbf 0x08 +# CHECK: vld1.32 {d16[1]}, [r0, :32] + +0xe0 0xf9 0x3f 0x01 +# CHECK: vld2.8 {d16[1], d17[1]}, [r0, :16] +0xe0 0xf9 0x5f 0x05 +# CHECK: vld2.16 {d16[1], d17[1]}, [r0, :32] +0xe0 0xf9 0x8f 0x09 +# CHECK: vld2.32 {d16[1], d17[1]}, [r0] +0xe0 0xf9 0x6f 0x15 +# CHECK: vld2.16 {d17[1], d19[1]}, [r0] +0xe0 0xf9 0x5f 0x19 +# CHECK: vld2.32 {d17[0], d19[0]}, [r0, :64] + +0xe0 0xf9 0x2f 0x02 +# CHECK: vld3.8 {d16[1], d17[1], d18[1]}, [r0] +0xe0 0xf9 0x4f 0x06 +# CHECK: vld3.16 {d16[1], d17[1], d18[1]}, [r0] +0xe0 0xf9 0x8f 0x0a +# CHECK: vld3.32 {d16[1], d17[1], d18[1]}, [r0] +0xe0 0xf9 0x6f 0x06 +# CHECK: vld3.16 {d16[1], d18[1], d20[1]}, [r0] +0xe0 0xf9 0xcf 0x1a +# CHECK: vld3.32 {d17[1], d19[1], d21[1]}, [r0] + +0xe0 0xf9 0x3f 0x03 +# CHECK: vld4.8 {d16[1], d17[1], d18[1], d19[1]}, [r0, :32] +0xe0 0xf9 0x4f 0x07 +# CHECK: vld4.16 {d16[1], d17[1], d18[1], d19[1]}, [r0] +0xe0 0xf9 0xaf 0x0b +# CHECK: vld4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0, :128] +0xe0 0xf9 0x7f 0x07 +# CHECK: vld4.16 {d16[1], d18[1], d20[1], d22[1]}, [r0, :64] +0xe0 0xf9 0x4f 0x1b +# CHECK: vld4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0] + +0x40 0xf9 0x1f 0x07 +# CHECK: vst1.8 {d16}, [r0, :64] +0x40 0xf9 0x4f 0x07 +# CHECK: vst1.16 {d16}, [r0] +0x40 0xf9 0x8f 0x07 +# CHECK: vst1.32 {d16}, [r0] +0x40 0xf9 0xcf 0x07 +# CHECK: vst1.64 {d16}, [r0] +0x40 0xf9 0x1f 0x0a +# CHECK: vst1.8 {d16, d17}, [r0, :64] +0x40 0xf9 0x6f 0x0a +# CHECK: vst1.16 {d16, d17}, [r0, :128] +0x40 0xf9 0x8f 0x0a +# CHECK: vst1.32 {d16, d17}, [r0] +0x40 0xf9 0xcf 0x0a +# CHECK: vst1.64 {d16, d17}, [r0] + +0x40 0xf9 0x1f 0x08 +# CHECK: vst2.8 {d16, d17}, [r0, :64] +0x40 0xf9 0x6f 0x08 +# CHECK: vst2.16 {d16, d17}, [r0, :128] +0x40 0xf9 0x8f 0x08 +# CHECK: vst2.32 {d16, d17}, [r0] +0x40 0xf9 0x1f 0x03 +# CHECK: vst2.8 {d16, d17, d18, d19}, [r0, :64] +0x40 0xf9 0x6f 0x03 +# CHECK: vst2.16 {d16, d17, d18, d19}, [r0, :128] +0x40 0xf9 0xbf 0x03 +# CHECK: vst2.32 {d16, d17, d18, d19}, [r0, :256] + +0x40 0xf9 0x1f 0x04 +# CHECK: vst3.8 {d16, d17, d18}, [r0, :64] +0x40 0xf9 0x4f 0x04 +# CHECK: vst3.16 {d16, d17, d18}, [r0] +0x40 0xf9 0x8f 0x04 +# CHECK: vst3.32 {d16, d17, d18}, [r0] +0x40 0xf9 0x1d 0x05 +# CHECK: vst3.8 {d16, d18, d20}, [r0, :64]! +0x40 0xf9 0x1d 0x15 +# CHECK: vst3.8 {d17, d19, d21}, [r0, :64]! +0x40 0xf9 0x4d 0x05 +# CHECK: vst3.16 {d16, d18, d20}, [r0]! +0x40 0xf9 0x4d 0x15 +# CHECK: vst3.16 {d17, d19, d21}, [r0]! +0x40 0xf9 0x8d 0x05 +# CHECK: vst3.32 {d16, d18, d20}, [r0]! +0x40 0xf9 0x8d 0x15 +# CHECK: vst3.32 {d17, d19, d21}, [r0]! + +0x40 0xf9 0x1f 0x00 +# CHECK: vst4.8 {d16, d17, d18, d19}, [r0, :64] +0x40 0xf9 0x6f 0x00 +# CHECK: vst4.16 {d16, d17, d18, d19}, [r0, :128] +0x40 0xf9 0x3d 0x01 +# CHECK: vst4.8 {d16, d18, d20, d22}, [r0, :256]! +0x40 0xf9 0x3d 0x11 +# CHECK: vst4.8 {d17, d19, d21, d23}, [r0, :256]! +0x40 0xf9 0x4d 0x01 +# CHECK: vst4.16 {d16, d18, d20, d22}, [r0]! +0x40 0xf9 0x4d 0x11 +# CHECK: vst4.16 {d17, d19, d21, d23}, [r0]! +0x40 0xf9 0x8d 0x01 +# CHECK: vst4.32 {d16, d18, d20, d22}, [r0]! +0x40 0xf9 0x8d 0x11 +# CHECK: vst4.32 {d17, d19, d21, d23}, [r0]! + +0xc0 0xf9 0x3f 0x01 +# CHECK: vst2.8 {d16[1], d17[1]}, [r0, :16] +0xc0 0xf9 0x5f 0x05 +# CHECK: vst2.16 {d16[1], d17[1]}, [r0, :32] +0xc0 0xf9 0x8f 0x09 +# CHECK: vst2.32 {d16[1], d17[1]}, [r0] +0xc0 0xf9 0x6f 0x15 +# CHECK: vst2.16 {d17[1], d19[1]}, [r0] +0xc0 0xf9 0x5f 0x19 +# CHECK: vst2.32 {d17[0], d19[0]}, [r0, :64] + +0xc0 0xf9 0x2f 0x02 +# CHECK: vst3.8 {d16[1], d17[1], d18[1]}, [r0] +0xc0 0xf9 0x4f 0x06 +# CHECK: vst3.16 {d16[1], d17[1], d18[1]}, [r0] +0xc0 0xf9 0x8f 0x0a +# CHECK: vst3.32 {d16[1], d17[1], d18[1]}, [r0] +0xc0 0xf9 0xaf 0x16 +# CHECK: vst3.16 {d17[2], d19[2], d21[2]}, [r0] +0xc0 0xf9 0x4f 0x0a +# CHECK: vst3.32 {d16[0], d18[0], d20[0]}, [r0] + +0xc0 0xf9 0x3f 0x03 +# CHECK: vst4.8 {d16[1], d17[1], d18[1], d19[1]}, [r0, :32] +0xc0 0xf9 0x4f 0x07 +# CHECK: vst4.16 {d16[1], d17[1], d18[1], d19[1]}, [r0] +0xc0 0xf9 0xaf 0x0b +# CHECK: vst4.32 {d16[1], d17[1], d18[1], d19[1]}, [r0, :128] +0xc0 0xf9 0xff 0x17 +# CHECK: vst4.16 {d17[3], d19[3], d21[3], d23[3]}, [r0, :64] +0xc0 0xf9 0x4f 0x1b +# CHECK: vst4.32 {d17[0], d19[0], d21[0], d23[0]}, [r0] diff --git a/test/MC/Disassembler/ARM/thumb-MSR-MClass.txt b/test/MC/Disassembler/ARM/thumb-MSR-MClass.txt new file mode 100644 index 000000000000..497cb9a2a5e0 --- /dev/null +++ b/test/MC/Disassembler/ARM/thumb-MSR-MClass.txt @@ -0,0 +1,7 @@ +# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 -mcpu cortex-m3 | FileCheck %s + +# CHECK: msr primask, r0 +0x80 0xf3 0x10 0x80 + +# CHECK: mrs r0, primask +0xef 0xf3 0x10 0x80 diff --git a/test/MC/Disassembler/ARM/thumb-printf.txt b/test/MC/Disassembler/ARM/thumb-printf.txt index 6c2c500630d5..8158a73edcb5 100644 --- a/test/MC/Disassembler/ARM/thumb-printf.txt +++ b/test/MC/Disassembler/ARM/thumb-printf.txt @@ -1,4 +1,4 @@ -# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 | FileCheck %s +# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 | FileCheck %s # CHECK: push {r0, r1, r2, r3} # CHECK-NEXT: push {r4, r5, r7, lr} diff --git a/test/MC/Disassembler/ARM/thumb-tests.txt b/test/MC/Disassembler/ARM/thumb-tests.txt index 895a5bb346dd..18b8f4701da6 100644 --- a/test/MC/Disassembler/ARM/thumb-tests.txt +++ b/test/MC/Disassembler/ARM/thumb-tests.txt @@ -1,4 +1,4 @@ -# RUN: llvm-mc --disassemble %s -triple=thumb-apple-darwin9 | FileCheck %s +# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 -mattr +t2xtpk,+mp | FileCheck %s # CHECK: add r5, sp, #68 0x11 0xad @@ -27,7 +27,7 @@ # CHECK: cmn.w r0, #31 0x10 0xf1 0x1f 0x0f -# CHECK: ldmia r0!, {r1} +# CHECK: ldm r0!, {r1} 0x02 0xc8 # CHECK: ldr r5, #432 @@ -42,7 +42,7 @@ # CHECK: str r2, [r5, r3] 0xea 0x50 -# CHECK: ldrb.w r8, #-24 +# CHECK: ldrb.w r8, [pc, #-24] 0x1f 0xf8 0x18 0x80 # CHECK: ldrd r0, r1, [r7, #64]! @@ -112,7 +112,7 @@ # CHECK: lsleq r1, r0, #28 0x01 0x07 -# CHECK: stmiane r0!, {r1, r2, r3} +# CHECK: stmne r0!, {r1, r2, r3} 0x0e 0xc0 # IT block end @@ -131,7 +131,7 @@ # CHECK: cpsie aif 0x67 0xb6 -# CHECK: msr cpsr_fc, r0 +# CHECK: msr CPSR_fc, r0 0x80 0xf3 0x00 0x89 # CHECK: blx #-4 @@ -143,16 +143,16 @@ # CHECK: vcmpe.f64 d8, #0 0xb5 0xee 0xc0 0x8b -# CHECK: stmdb.w sp, {r0, r2, r3, r8, r11, lr} +# CHECK: stmdb sp, {r0, r2, r3, r8, r11, lr} 0x0d 0xe9 0x0d 0x49 -# CHECK: stmia r5!, {r0, r1, r2, r3, r4} +# CHECK: stm r5!, {r0, r1, r2, r3, r4} 0x1f 0xc5 -# CHECK: ldmia r5, {r0, r1, r2, r3, r4, r5} +# CHECK: ldm r5, {r0, r1, r2, r3, r4, r5} 0x3f 0xcd -# CHECK: ldmia r5!, {r0, r1, r2, r3, r4} +# CHECK: ldm r5!, {r0, r1, r2, r3, r4} 0x1f 0xcd # CHECK: addw r0, pc, #1050 @@ -218,7 +218,7 @@ # CHECK: pld [r5, #30] 0x95 0xf8 0x1e 0xf0 -# CHECK: stc2 p12, cr15, [r9], {137} +# CHECK: stc2 p12, c15, [r9], {137} 0x89 0xfc 0x89 0xfc # CHECK: vmov r1, r0, d11 @@ -265,3 +265,39 @@ # CHECK: bne #24 0x0c 0xd1 + +# CHECK: vadd.f32 q0, q1, q2 +0x02 0xef 0x44 0x0d + +# CHECK: ldrsb r1, [r0, r0] +0x01 0x56 + +# CHECK: ldrsh r1, [r0, r0] +0x01 0x5E + +# CHECK: and.w r5, r1, r10, ror #7 +0x1 0xea 0xfa 0x95 + +# CHECK: ldrsh r6, [sp], #81 +0x3d 0xf9 0x51 0x6b + +# CHECK: usat16 r4, #10, r1 +0xa1 0xf3 0x0a 0x04 + +# CHECK: smlad r5, r12, r8, r11 +0x2c 0xfb 0x8 0xb5 + +# CHECK: teq.w r0, r11 +0x90 0xea 0xb 0x8f + +# CHECK: uxtb16 r9, r12, ror #16 +0x3f 0xfa 0xec 0xf9 + +# CHECK: pldw [r11, r12, lsl #2] +0x3b 0xf8 0x2c 0xf0 + +# CHECK: msr CPSR_fc, r0 +0x80 0xf3 0x00 0x89 + +# CHECK: mrs r0, apsr +0xef 0xf3 0x00 0x80 diff --git a/test/MC/Disassembler/ARM/thumb1.txt b/test/MC/Disassembler/ARM/thumb1.txt new file mode 100644 index 000000000000..17c4bad239ef --- /dev/null +++ b/test/MC/Disassembler/ARM/thumb1.txt @@ -0,0 +1,530 @@ +# RUN: llvm-mc -triple=thumbv6-apple-darwin -disassemble < %s | FileCheck %s + +#------------------------------------------------------------------------------ +# ADC (register) +#------------------------------------------------------------------------------ +# CHECK: adcs r4, r6 + +0x74 0x41 + + +#------------------------------------------------------------------------------ +# ADD (immediate) +#------------------------------------------------------------------------------ +# CHECK: adds r1, r2, #3 +# CHECK: adds r2, r2, #3 +# CHECK: adds r2, #8 + +0xd1 0x1c +0xd2 0x1c +0x08 0x32 + +#------------------------------------------------------------------------------ +# ADD (register) +#------------------------------------------------------------------------------ +# CHECK: adds r1, r2, r3 +# CHECK: add r2, r8 + +0xd1 0x18 +0x42 0x44 + +#------------------------------------------------------------------------------ +# ADD (SP plus immediate) +#------------------------------------------------------------------------------ +# CHECK: add sp, #508 +# CHECK: add sp, #4 +# CHECK: add r2, sp, #8 +# CHECK: add r2, sp, #1020 + +0x7f 0xb0 +0x01 0xb0 +0x02 0xaa +0xff 0xaa + + +#------------------------------------------------------------------------------ +# ADD (SP plus register) +#------------------------------------------------------------------------------ +# CHECK: add sp, r3 +# CHECK: add r2, sp, r2 + +0x9d 0x44 +0x6a 0x44 + +#------------------------------------------------------------------------------ +# ADR +#------------------------------------------------------------------------------ +# CHECK: adr r2, #3 +0x03 0xa2 + +#------------------------------------------------------------------------------ +# ASR (immediate) +#------------------------------------------------------------------------------ +# CHECK: asrs r2, r3, #32 +# CHECK: asrs r2, r3, #5 +# CHECK: asrs r2, r3, #1 + +0x1a 0x10 +0x5a 0x11 +0x5a 0x10 + +#------------------------------------------------------------------------------ +# ASR (register) +#------------------------------------------------------------------------------ +# CHECK: asrs r5, r2 + +0x15 0x41 + +#------------------------------------------------------------------------------ +# BICS +#------------------------------------------------------------------------------ +# CHECK: bics r1, r6 + +0xb1 0x43 + +#------------------------------------------------------------------------------ +# BKPT +#------------------------------------------------------------------------------ +# CHECK: bkpt #0 +# CHECK: bkpt #255 + +0x00 0xbe +0xff 0xbe + +#------------------------------------------------------------------------------ +# BLX (register) +#------------------------------------------------------------------------------ +# CHECK: blx r4 + +0xa0 0x47 + +#------------------------------------------------------------------------------ +# BX +#------------------------------------------------------------------------------ +# CHECK: bx r2 + +0x10 0x47 + +#------------------------------------------------------------------------------ +# CMN +#------------------------------------------------------------------------------ +# CHECK: cmn r5, r1 + +0xcd 0x42 + +#------------------------------------------------------------------------------ +# CMP +#------------------------------------------------------------------------------ +# CHECK: cmp r6, #32 +# CHECK: cmp r3, r4 +# CHECK: cmp r8, r1 + +0x20 0x2e +0xa3 0x42 +0x88 0x45 + +#------------------------------------------------------------------------------ +# EOR +#------------------------------------------------------------------------------ +# CHECK: eors r4, r5 + +0x6c 0x40 + +#------------------------------------------------------------------------------ +# LDM +#------------------------------------------------------------------------------ +# CHECK: ldm r3, {r0, r1, r2, r3, r4, r5, r6, r7} +# CHECK: ldm r2!, {r1, r3, r4, r5, r7} +# CHECK: ldm r1, {r1} + +0xff 0xcb +0xba 0xca +0x02 0xc9 + + +#------------------------------------------------------------------------------ +# LDR (immediate) +#------------------------------------------------------------------------------ +# CHECK: ldr r1, [r5] +# CHECK: ldr r2, [r6, #32] +# CHECK: ldr r3, [r7, #124] +# CHECK: ldr r1, [sp] +# CHECK: ldr r2, [sp, #24] +# CHECK: ldr r3, [sp, #1020] + + +0x29 0x68 +0x32 0x6a +0xfb 0x6f +0x00 0x99 +0x06 0x9a +0xff 0x9b + +#------------------------------------------------------------------------------ +# LDR (register) +#------------------------------------------------------------------------------ +# CHECK: ldr r1, [r2, r3] + +0xd1 0x58 + + +#------------------------------------------------------------------------------ +# LDRB (immediate) +#------------------------------------------------------------------------------ +# CHECK: ldrb r4, [r3] +# CHECK: ldrb r5, [r6] +# CHECK: ldrb r6, [r7, #31] + +0x1c 0x78 +0x35 0x78 +0xfe 0x7f + + +#------------------------------------------------------------------------------ +# LDRB (register) +#------------------------------------------------------------------------------ +# CHECK: ldrb r6, [r4, r5] + +0x66 0x5d + + +#------------------------------------------------------------------------------ +# LDRH (immediate) +#------------------------------------------------------------------------------ +# CHECK: ldrh r3, [r3] +# CHECK: ldrh r4, [r6, #2] +# CHECK: ldrh r5, [r7, #62] + +0x1b 0x88 +0x74 0x88 +0xfd 0x8f + +#------------------------------------------------------------------------------ +# LDRH (register) +#------------------------------------------------------------------------------ +# CHECK: ldrh r6, [r2, r6] + +0x96 0x5b + + +#------------------------------------------------------------------------------ +# LDRSB/LDRSH +#------------------------------------------------------------------------------ +# CHECK: ldrsb r6, [r2, r6] +# CHECK: ldrsh r3, [r7, r1] + +0x96 0x57 +0x7b 0x5e + +#------------------------------------------------------------------------------ +# LSL (immediate) +#------------------------------------------------------------------------------ +# CHECK: movs r4, r5 +# CHECK: lsls r4, r5, #4 + +0x2c 0x00 +0x2c 0x01 + + +#------------------------------------------------------------------------------ +# LSL (register) +#------------------------------------------------------------------------------ +# CHECK: lsls r2, r6 + +0xb2 0x40 + + +#------------------------------------------------------------------------------ +# LSR (immediate) +#------------------------------------------------------------------------------ +# CHECK: lsrs r1, r3, #1 +# CHECK: lsrs r1, r3, #32 + +0x59 0x08 +0x19 0x08 + + +#------------------------------------------------------------------------------ +# LSR (register) +#------------------------------------------------------------------------------ +# CHECK: lsrs r2, r6 + +0xf2 0x40 + +#------------------------------------------------------------------------------ +# MOV (immediate) +#------------------------------------------------------------------------------ +# CHECK: movs r2, #0 +# CHECK: movs r2, #255 +# CHECK: movs r2, #23 + +0x00 0x22 +0xff 0x22 +0x17 0x22 + + +#------------------------------------------------------------------------------ +# MOV (register) +#------------------------------------------------------------------------------ +# CHECK: mov r3, r4 +# CHECK: movs r1, r3 + +0x23 0x46 +0x19 0x00 + + +#------------------------------------------------------------------------------ +# MUL +#------------------------------------------------------------------------------ +# CHECK: muls r1, r2, r1 +# CHECK: muls r3, r4 + +0x51 0x43 +0x63 0x43 + + +#------------------------------------------------------------------------------ +# MVN +#------------------------------------------------------------------------------ +# CHECK: mvns r6, r3 + +0xde 0x43 + +#------------------------------------------------------------------------------ +# NEG +#------------------------------------------------------------------------------ +# CHECK: rsbs r3, r4, #0 + +0x63 0x42 + + +#------------------------------------------------------------------------------ +# NOP +#------------------------------------------------------------------------------ +# CHECK: nop + +0xc0 0x46 + + +#------------------------------------------------------------------------------ +# ORR +#------------------------------------------------------------------------------ +# CHECK: orrs r3, r4 + +0x23 0x43 + +#------------------------------------------------------------------------------ +# POP +#------------------------------------------------------------------------------ +# CHECK: pop {r2, r3, r6} + +0x4c 0xbc + + +#------------------------------------------------------------------------------ +# PUSH +#------------------------------------------------------------------------------ +# CHECK: push {r1, r2, r7} + +0x86 0xb4 + + +#------------------------------------------------------------------------------ +# REV/REV16/REVSH +#------------------------------------------------------------------------------ +# CHECK: rev r6, r3 +# CHECK: rev16 r7, r2 +# CHECK: revsh r5, r1 + +0x1e 0xba +0x57 0xba +0xcd 0xba + + +#------------------------------------------------------------------------------ +# ROR +#------------------------------------------------------------------------------ +# CHECK: rors r2, r7 + +0xfa 0x41 + +#------------------------------------------------------------------------------ +# RSB +#------------------------------------------------------------------------------ +# CHECK: rsbs r1, r3, #0 + +0x59 0x42 + + +#------------------------------------------------------------------------------ +# SBC +#------------------------------------------------------------------------------ +# CHECK: sbcs r4, r3 + +0x9c 0x41 + + +#------------------------------------------------------------------------------ +# SETEND +#------------------------------------------------------------------------------ +# CHECK: setend be +# CHECK: setend le + +0x58 0xb6 +0x50 0xb6 + +#------------------------------------------------------------------------------ +# STM +#------------------------------------------------------------------------------ +# CHECK: stm r1!, {r2, r6} +# CHECK: stm r1!, {r1, r2, r3, r7} + +0x44 0xc1 +0x8e 0xc1 + + +#------------------------------------------------------------------------------ +# STR (immediate) +#------------------------------------------------------------------------------ +# CHECK: str r2, [r7] +# CHECK: str r2, [r7] +# CHECK: str r5, [r1, #4] +# CHECK: str r3, [r7, #124] +# CHECK: str r2, [sp] +# CHECK: str r3, [sp] +# CHECK: str r4, [sp, #20] +# CHECK: str r5, [sp, #1020] + +0x3a 0x60 +0x3a 0x60 +0x4d 0x60 +0xfb 0x67 +0x00 0x92 +0x00 0x93 +0x05 0x94 +0xff 0x95 + + +#------------------------------------------------------------------------------ +# STR (register) +#------------------------------------------------------------------------------ +# CHECK: str r2, [r7, r3] + +0xfa 0x50 + + +#------------------------------------------------------------------------------ +# STRB (immediate) +#------------------------------------------------------------------------------ +# CHECK: strb r4, [r3] +# CHECK: strb r5, [r6] +# CHECK: strb r6, [r7, #31] + +0x1c 0x70 +0x35 0x70 +0xfe 0x77 + + +#------------------------------------------------------------------------------ +# STRB (register) +#------------------------------------------------------------------------------ +# CHECK: strb r6, [r4, r5] + +0x66 0x55 + + +#------------------------------------------------------------------------------ +# STRH (immediate) +#------------------------------------------------------------------------------ +# CHECK: strh r3, [r3] +# CHECK: strh r4, [r6, #2] +# CHECK: strh r5, [r7, #62] + +0x1b 0x80 +0x74 0x80 +0xfd 0x87 + + +#------------------------------------------------------------------------------ +# STRH (register) +#------------------------------------------------------------------------------ +# CHECK: strh r6, [r2, r6] + +0x96 0x53 + + +#------------------------------------------------------------------------------ +# SUB (immediate) +#------------------------------------------------------------------------------ +# CHECK: subs r1, r2, #3 +# CHECK: subs r2, #3 +# CHECK: subs r2, #8 + +0xd1 0x1e +0x03 0x3a +0x08 0x3a + +#------------------------------------------------------------------------------ +# SUB (register) +#------------------------------------------------------------------------------ +# CHECK: subs r1, r2, r3 + +0xd1 0x1a + +#------------------------------------------------------------------------------ +# SUB (SP minus immediate) +#------------------------------------------------------------------------------ +# CHECK: sub sp, #12 +# CHECK: sub sp, #508 + +0x83 0xb0 +0xff 0xb0 + +#------------------------------------------------------------------------------ +# SVC +#------------------------------------------------------------------------------ +# CHECK: svc #0 +# CHECK: svc #255 + +0x00 0xdf +0xff 0xdf + + +#------------------------------------------------------------------------------ +# SXTB/SXTH +#------------------------------------------------------------------------------ +# CHECK: sxtb r3, r5 +# CHECK: sxth r3, r5 + +0x6b 0xb2 +0x2b 0xb2 + + +#------------------------------------------------------------------------------ +# TST +#------------------------------------------------------------------------------ +# CHECK: tst r6, r1 + +0x0e 0x42 + + +#------------------------------------------------------------------------------ +# UXTB/UXTH +#------------------------------------------------------------------------------ +# CHECK: uxtb r7, r2 +# CHECK: uxth r1, r4 + +0xd7 0xb2 +0xa1 0xb2 + + +#------------------------------------------------------------------------------ +# WFE/WFI/YIELD +#------------------------------------------------------------------------------ +# CHECK: wfe +# CHECK: wfi +# CHECK: yield + +0x20 0xbf +0x30 0xbf +0x10 0xbf diff --git a/test/MC/Disassembler/ARM/thumb2.txt b/test/MC/Disassembler/ARM/thumb2.txt new file mode 100644 index 000000000000..ed8d9886cdbb --- /dev/null +++ b/test/MC/Disassembler/ARM/thumb2.txt @@ -0,0 +1,2558 @@ +# RUN: llvm-mc -triple=thumbv7-apple-darwin -disassemble < %s | FileCheck %s + +#------------------------------------------------------------------------------ +# ADC (immediate) +#------------------------------------------------------------------------------ +# CHECK: adc r0, r1, #4 +# CHECK: adcs r0, r1, #0 +# CHECK: adc r1, r2, #255 +# CHECK: adc r3, r7, #5570645 +# CHECK: adc r8, r12, #2852170240 +# CHECK: adc r9, r7, #2779096485 +# CHECK: adc r5, r3, #2264924160 +# CHECK: adc r4, r2, #2139095040 +# CHECK: adc r4, r2, #1664 + +0x41 0xf1 0x04 0x00 +0x51 0xf1 0x00 0x00 +0x42 0xf1 0xff 0x01 +0x47 0xf1 0x55 0x13 +0x4c 0xf1 0xaa 0x28 +0x47 0xf1 0xa5 0x39 +0x43 0xf1 0x07 0x45 +0x42 0xf1 0xff 0x44 +0x42 0xf5 0xd0 0x64 + +#------------------------------------------------------------------------------ +# ADC (register) +#------------------------------------------------------------------------------ +# CHECK: adc.w r4, r5, r6 +# CHECK: adcs.w r4, r5, r6 +# CHECK: adc.w r9, r1, r3 +# CHECK: adcs.w r9, r1, r3 +# CHECK: adc.w r0, r1, r3, ror #4 +# CHECK: adcs.w r0, r1, r3, lsl #7 +# CHECK: adc.w r0, r1, r3, lsr #31 +# CHECK: adcs.w r0, r1, r3, asr #32 + +0x45 0xeb 0x06 0x04 +0x55 0xeb 0x06 0x04 +0x41 0xeb 0x03 0x09 +0x51 0xeb 0x03 0x09 +0x41 0xeb 0x33 0x10 +0x51 0xeb 0xc3 0x10 +0x41 0xeb 0xd3 0x70 +0x51 0xeb 0x23 0x00 + + +#------------------------------------------------------------------------------ +# ADD (immediate) +#------------------------------------------------------------------------------ +# CHECK: itet eq +# CHECK: addeq r1, r2, #4 +# CHECK: addwne r5, r3, #1023 +# CHECK: addweq r4, r5, #293 +# CHECK: add.w r2, sp, #1024 +# CHECK: add.w r2, r8, #65280 +# CHECK: addw r2, r3, #257 +# CHECK: add.w r12, r6, #256 +# CHECK: addw r12, r6, #256 +# CHECK: adds.w r1, r2, #496 + +0x0a 0xbf +0x11 0x1d +0x03 0xf2 0xff 0x35 +0x05 0xf2 0x25 0x14 +0x0d 0xf5 0x80 0x62 +0x08 0xf5 0x7f 0x42 +0x03 0xf2 0x01 0x12 +0x06 0xf5 0x80 0x7c +0x06 0xf2 0x00 0x1c +0x12 0xf5 0xf8 0x71 + + +#------------------------------------------------------------------------------ +# ADD (register) +#------------------------------------------------------------------------------ +# CHECK: add.w r1, r2, r8 +# CHECK: add.w r5, r9, r2, asr #32 +# CHECK: adds.w r7, r3, r1, lsl #31 +# CHECK: adds.w r0, r3, r6, lsr #25 +# CHECK: add.w r4, r8, r1, ror #12 + +0x02 0xeb 0x08 0x01 +0x09 0xeb 0x22 0x05 +0x13 0xeb 0xc1 0x77 +0x13 0xeb 0x56 0x60 +0x08 0xeb 0x31 0x34 + + +#------------------------------------------------------------------------------ +# ADR +#------------------------------------------------------------------------------ +# CHECK: subw r11, pc, #3270 +# CHECK: subw r11, pc, #826 + +0xaf 0xf6 0xc6 0x4b +0xaf 0xf2 0x3a 0x3b + +#------------------------------------------------------------------------------ +# AND (immediate) +#------------------------------------------------------------------------------ +# CHECK: and r2, r5, #1044480 +# CHECK: ands r3, r12, #15 +# CHECK: and r1, r1, #255 + +0x05 0xf4 0x7f 0x22 +0x1c 0xf0 0x0f 0x03 +0x01 0xf0 0xff 0x01 + + +#------------------------------------------------------------------------------ +# AND (register) +#------------------------------------------------------------------------------ +# CHECK: and.w r4, r9, r8 +# CHECK: and.w r1, r4, r8, asr #3 +# CHECK: ands.w r2, r1, r7, lsl #1 +# CHECK: ands.w r4, r5, r2, lsr #20 +# CHECK: and.w r9, r12, r1, ror #17 + +0x09 0xea 0x08 0x04 +0x04 0xea 0xe8 0x01 +0x11 0xea 0x47 0x02 +0x15 0xea 0x12 0x54 +0x0c 0xea 0x71 0x49 + +#------------------------------------------------------------------------------ +# ASR (immediate) +#------------------------------------------------------------------------------ +# CHECK: asr.w r2, r3, #12 +# CHECK: asrs.w r8, r3, #32 +# CHECK: asrs.w r2, r3, #1 +# CHECK: asr.w r2, r3, #4 +# CHECK: asrs.w r2, r12, #15 + +# CHECK: asr.w r3, r3, #19 +# CHECK: asrs.w r8, r8, #2 +# CHECK: asrs.w r7, r7, #5 +# CHECK: asr.w r12, r12, #21 + +0x4f 0xea 0x23 0x32 +0x5f 0xea 0x23 0x08 +0x5f 0xea 0x63 0x02 +0x4f 0xea 0x23 0x12 +0x5f 0xea 0xec 0x32 + +0x4f 0xea 0xe3 0x43 +0x5f 0xea 0xa8 0x08 +0x5f 0xea 0x67 0x17 +0x4f 0xea 0x6c 0x5c + + +#------------------------------------------------------------------------------ +# ASR (register) +#------------------------------------------------------------------------------ +# CHECK: asr.w r3, r4, r2 +# CHECK: asr.w r1, r1, r2 +# CHECK: asrs.w r3, r4, r8 + +0x44 0xfa 0x02 0xf3 +0x41 0xfa 0x02 0xf1 +0x54 0xfa 0x08 0xf3 + +#------------------------------------------------------------------------------ +# B +#------------------------------------------------------------------------------ +# CHECK: bmi.w #-183396 + +0x13 0xf5 0xce 0xa9 + + +#------------------------------------------------------------------------------ +# BFC +#------------------------------------------------------------------------------ +# CHECK: bfc r5, #3, #17 +# CHECK: it lo +# CHECK: bfclo r5, #3, #17 + +0x6f 0xf3 0xd3 0x05 +0x38 0xbf +0x6f 0xf3 0xd3 0x05 + + +#------------------------------------------------------------------------------ +# BFI +#------------------------------------------------------------------------------ +# CHECK: bfi r5, r2, #3, #17 +# CHECK: it ne +# CHECK: bfine r5, r2, #3, #17 +# CHECK: bfi r6, r0, #0, #32 +# CHECK: bfi r6, r0, #31, #1 + +0x62 0xf3 0xd3 0x05 +0x18 0xbf +0x62 0xf3 0xd3 0x05 +0x60 0xf3 0x1f 0x06 +0x60 0xf3 0xdf 0x76 + + +#------------------------------------------------------------------------------ +# BIC +#------------------------------------------------------------------------------ +# CHECK: bic r10, r1, #15 +# CHECK: bic.w r12, r3, r6 +# CHECK: bic.w r11, r2, r6, lsl #12 +# CHECK: bic.w r8, r4, r1, lsr #11 +# CHECK: bic.w r7, r5, r7, lsr #15 +# CHECK: bic.w r6, r7, r9, asr #32 +# CHECK: bic.w r5, r6, r8, ror #1 + +# CHECK: bic r1, r1, #15 +# CHECK: bic.w r1, r1, r1 +# CHECK: bic.w r4, r4, r2, lsl #31 +# CHECK: bic.w r6, r6, r3, lsr #12 +# CHECK: bic.w r7, r7, r4, lsr #7 +# CHECK: bic.w r8, r8, r5, asr #15 +# CHECK: bic.w r12, r12, r6, ror #29 + +0x21 0xf0 0x0f 0x0a +0x23 0xea 0x06 0x0c +0x22 0xea 0x06 0x3b +0x24 0xea 0xd1 0x28 +0x25 0xea 0xd7 0x37 +0x27 0xea 0x29 0x06 +0x26 0xea 0x78 0x05 + +0x21 0xf0 0x0f 0x01 +0x21 0xea 0x01 0x01 +0x24 0xea 0xc2 0x74 +0x26 0xea 0x13 0x36 +0x27 0xea 0xd4 0x17 +0x28 0xea 0xe5 0x38 +0x2c 0xea 0x76 0x7c + + +#------------------------------------------------------------------------------ +# BXJ +#------------------------------------------------------------------------------ +# CHECK: bxj r5 +# CHECK: it ne +# CHECK: bxjne r7 + +0xc5 0xf3 0x00 0x8f +0x18 0xbf +0xc7 0xf3 0x00 0x8f + + +#------------------------------------------------------------------------------ +# CBZ/CBNZ +#------------------------------------------------------------------------------ +# CHECK: cbnz r7, #6 +# CHECK: cbnz r7, #12 + +0x1f 0xb9 +0x37 0xb9 + +#------------------------------------------------------------------------------ +# CDP/CDP2 +#------------------------------------------------------------------------------ +# CHECK: cdp p7, #1, c1, c1, c1, #4 +# CHECK: cdp2 p7, #1, c1, c1, c1, #4 + +0x11 0xee 0x81 0x17 +0x11 0xfe 0x81 0x17 + + +#------------------------------------------------------------------------------ +# CLREX +#------------------------------------------------------------------------------ +#CHECK: clrex +#CHECK: it ne +#CHECK: clrexne + +0xbf 0xf3 0x2f 0x8f +0x18 0xbf +0xbf 0xf3 0x2f 0x8f + + +#------------------------------------------------------------------------------ +# CLZ +#------------------------------------------------------------------------------ +#CHECK: clz r1, r2 +#CHECK: it eq +#CHECK: clzeq r1, r2 + +0xb2 0xfa 0x82 0xf1 +0x08 0xbf +0xb2 0xfa 0x82 0xf1 + + +#------------------------------------------------------------------------------ +# CMN +#------------------------------------------------------------------------------ +#CHECK: cmn.w r1, #15 +#CHECK: cmn.w r8, r6 +#CHECK: cmn.w r1, r6, lsl #10 +#CHECK: cmn.w r1, r6, lsr #10 +#CHECK: cmn.w sp, r6, lsr #10 +#CHECK: cmn.w r1, r6, asr #10 +#CHECK: cmn.w r1, r6, ror #10 + +0x11 0xf1 0x0f 0x0f +0x18 0xeb 0x06 0x0f +0x11 0xeb 0x86 0x2f +0x11 0xeb 0x96 0x2f +0x1d 0xeb 0x96 0x2f +0x11 0xeb 0xa6 0x2f +0x11 0xeb 0xb6 0x2f + + +#------------------------------------------------------------------------------ +# CMP +#------------------------------------------------------------------------------ +#CHECK: cmp.w r5, #65280 +#CHECK: cmp.w r4, r12 +#CHECK: cmp.w r9, r6, lsl #12 +#CHECK: cmp.w r3, r7, lsr #31 +#CHECK: cmp.w sp, r6, lsr #1 +#CHECK: cmp.w r2, r5, asr #24 +#CHECK: cmp.w r1, r4, ror #15 + +0xb5 0xf5 0x7f 0x4f +0xb4 0xeb 0x0c 0x0f +0xb9 0xeb 0x06 0x3f +0xb3 0xeb 0xd7 0x7f +0xbd 0xeb 0x56 0x0f +0xb2 0xeb 0x25 0x6f +0xb1 0xeb 0xf4 0x3f + + +#------------------------------------------------------------------------------ +# DBG +#------------------------------------------------------------------------------ +#CHECK: dbg #5 +#CHECK: dbg #0 +#CHECK: dbg #15 + +0xaf 0xf3 0xf5 0x80 +0xaf 0xf3 0xf0 0x80 +0xaf 0xf3 0xff 0x80 + + +#------------------------------------------------------------------------------ +# DMB +#------------------------------------------------------------------------------ +#CHECK: dmb sy +#CHECK: dmb st +#CHECK: dmb ish +#CHECK: dmb ishst +#CHECK: dmb nsh +#CHECK: dmb nshst +#CHECK: dmb osh +#CHECK: dmb oshst +#CHECK: dmb + +0xbf 0xf3 0x5f 0x8f +0xbf 0xf3 0x5e 0x8f +0xbf 0xf3 0x5b 0x8f +0xbf 0xf3 0x5a 0x8f +0xbf 0xf3 0x57 0x8f +0xbf 0xf3 0x56 0x8f +0xbf 0xf3 0x53 0x8f +0xbf 0xf3 0x52 0x8f +0xbf 0xf3 0x5f 0x8f + + +#------------------------------------------------------------------------------ +# DSB +#------------------------------------------------------------------------------ +#CHECK: dsb sy +#CHECK: dsb st +#CHECK: dsb ish +#CHECK: dsb ishst +#CHECK: dsb nsh +#CHECK: dsb nshst +#CHECK: dsb osh +#CHECK: dsb oshst + +0xbf 0xf3 0x4f 0x8f +0xbf 0xf3 0x4e 0x8f +0xbf 0xf3 0x4b 0x8f +0xbf 0xf3 0x4a 0x8f +0xbf 0xf3 0x47 0x8f +0xbf 0xf3 0x46 0x8f +0xbf 0xf3 0x43 0x8f +0xbf 0xf3 0x42 0x8f + + +#------------------------------------------------------------------------------ +# EOR +#------------------------------------------------------------------------------ +#CHECK: eor r4, r5, #61440 +#CHECK: eor.w r4, r5, r6 +#CHECK: eor.w r4, r5, r6, lsl #5 +#CHECK: eor.w r4, r5, r6, lsr #5 +#CHECK: eor.w r4, r5, r6, lsr #5 +#CHECK: eor.w r4, r5, r6, asr #5 +#CHECK: eor.w r4, r5, r6, ror #5 + +0x85 0xf4 0x70 0x44 +0x85 0xea 0x06 0x04 +0x85 0xea 0x46 0x14 +0x85 0xea 0x56 0x14 +0x85 0xea 0x56 0x14 +0x85 0xea 0x66 0x14 +0x85 0xea 0x76 0x14 + + +#------------------------------------------------------------------------------ +# ISB +#------------------------------------------------------------------------------ +#CHECK: isb sy + +0xbf 0xf3 0x6f 0x8f + +#------------------------------------------------------------------------------ +# IT +#------------------------------------------------------------------------------ +# Test encodings of a few full IT blocks, not just the IT instruction + +# CHECK: iteet eq +# CHECK: addeq r0, r1, r2 +# CHECK: nopne +# CHECK: subne r5, r6, r7 +# CHECK: addeq r1, r2, #4 + +0x0d 0xbf +0x88 0x18 +0x00 0xbf +0xf5 0x1b +0x11 0x1d + +# CHECK: ittee ls +# CHECK: addls r0, r1, r2 +# CHECK: nopls +# CHECK: subhi r5, r6, r7 +# CHECK: addhi r1, r2, #4 + +0x99 0xbf +0x88 0x18 +0x00 0xbf +0xf5 0x1b +0x11 0x1d + + +#------------------------------------------------------------------------------ +# LDMIA +#------------------------------------------------------------------------------ +# CHECK: ldm.w r4, {r4, r5, r8, r9} +# CHECK: ldm.w r4, {r5, r6} +# CHECK: ldm.w r5!, {r3, r8} +# CHECK: ldm.w r4, {r4, r5, r8, r9} +# CHECK: ldm.w r4, {r5, r6} +# CHECK: ldm.w r5!, {r3, r8} +# CHECK: ldm.w r5!, {r1, r2} +# CHECK: ldm.w r2, {r1, r2} + +# CHECK: ldm.w r4, {r4, r5, r8, r9} +# CHECK: ldm.w r4, {r5, r6} +# CHECK: ldm.w r5!, {r3, r8} +# CHECK: ldm.w r4, {r4, r5, r8, r9} +# CHECK: ldm.w r4, {r5, r6} +# CHECK: ldm.w r5!, {r3, r8} +# CHECK: ldm.w r5!, {r3, r8} + +0x94 0xe8 0x30 0x03 +0x94 0xe8 0x60 0x00 +0xb5 0xe8 0x08 0x01 +0x94 0xe8 0x30 0x03 +0x94 0xe8 0x60 0x00 +0xb5 0xe8 0x08 0x01 +0xb5 0xe8 0x06 0x00 +0x92 0xe8 0x06 0x00 + +0x94 0xe8 0x30 0x03 +0x94 0xe8 0x60 0x00 +0xb5 0xe8 0x08 0x01 +0x94 0xe8 0x30 0x03 +0x94 0xe8 0x60 0x00 +0xb5 0xe8 0x08 0x01 +0xb5 0xe8 0x08 0x01 + + +#------------------------------------------------------------------------------ +# LDMDB +#------------------------------------------------------------------------------ +# CHECK: ldmdb r4, {r4, r5, r8, r9} +# CHECK: ldmdb r4, {r5, r6} +# CHECK: ldmdb r5!, {r3, r8} +# CHECK: ldmdb r5!, {r3, r8} + +0x14 0xe9 0x30 0x03 +0x14 0xe9 0x60 0x00 +0x35 0xe9 0x08 0x01 +0x35 0xe9 0x08 0x01 + + +#------------------------------------------------------------------------------ +# LDR(immediate) +#------------------------------------------------------------------------------ +# CHECK: ldr r5, [r5, #-4] +# CHECK: ldr r5, [r6, #32] +# CHECK: ldr.w r5, [r6, #33] +# CHECK: ldr.w r5, [r6, #257] +# CHECK: ldr.w pc, [r7, #257] + +0x55 0xf8 0x04 0x5c +0x35 0x6a +0xd6 0xf8 0x21 0x50 +0xd6 0xf8 0x01 0x51 +0xd7 0xf8 0x01 0xf1 + + +#------------------------------------------------------------------------------ +# LDR(register) +#------------------------------------------------------------------------------ +# CHECK: ldr.w r1, [r8, r1] +# CHECK: ldr.w r4, [r5, r2] +# CHECK: ldr.w r6, [r0, r2, lsl #3] +# CHECK: ldr.w r8, [r8, r2, lsl #2] +# CHECK: ldr.w r7, [sp, r2, lsl #1] +# CHECK: ldr.w r7, [sp, r2] +# CHECK: ldr r2, [r4, #255]! +# CHECK: ldr r8, [sp, #4]! +# CHECK: ldr lr, [sp, #-4]! +# CHECK: ldr r2, [r4], #255 +# CHECK: ldr r8, [sp], #4 +# CHECK: ldr lr, [sp], #-4 + +0x58 0xf8 0x01 0x10 +0x55 0xf8 0x02 0x40 +0x50 0xf8 0x32 0x60 +0x58 0xf8 0x22 0x80 +0x5d 0xf8 0x12 0x70 +0x5d 0xf8 0x02 0x70 +0x54 0xf8 0xff 0x2f +0x5d 0xf8 0x04 0x8f +0x5d 0xf8 0x04 0xed +0x54 0xf8 0xff 0x2b +0x5d 0xf8 0x04 0x8b +0x5d 0xf8 0x04 0xe9 + + +#------------------------------------------------------------------------------ +# LDRB(immediate) +#------------------------------------------------------------------------------ +# CHECK: ldrb r5, [r5, #-4] +# CHECK: ldrb.w r5, [r6, #32] +# CHECK: ldrb.w r5, [r6, #33] +# CHECK: ldrb.w r5, [r6, #257] +# CHECK: ldrb.w lr, [r7, #257] + +0x15 0xf8 0x04 0x5c +0x96 0xf8 0x20 0x50 +0x96 0xf8 0x21 0x50 +0x96 0xf8 0x01 0x51 +0x97 0xf8 0x01 0xe1 + + +#------------------------------------------------------------------------------ +# LDRB(register) +#------------------------------------------------------------------------------ +# CHECK: ldrb.w r1, [r8, r1] +# CHECK: ldrb.w r4, [r5, r2] +# CHECK: ldrb.w r6, [r0, r2, lsl #3] +# CHECK: ldrb.w r8, [r8, r2, lsl #2] +# CHECK: ldrb.w r7, [sp, r2, lsl #1] +# CHECK: ldrb.w r7, [sp, r2] +# CHECK: ldrb r5, [r8, #255]! +# CHECK: ldrb r2, [r5, #4]! +# CHECK: ldrb r1, [r4, #-4]! +# CHECK: ldrb lr, [r3], #255 +# CHECK: ldrb r9, [r2], #4 +# CHECK: ldrb r3, [sp], #-4 + +0x18 0xf8 0x01 0x10 +0x15 0xf8 0x02 0x40 +0x10 0xf8 0x32 0x60 +0x18 0xf8 0x22 0x80 +0x1d 0xf8 0x12 0x70 +0x1d 0xf8 0x02 0x70 +0x18 0xf8 0xff 0x5f +0x15 0xf8 0x04 0x2f +0x14 0xf8 0x04 0x1d +0x13 0xf8 0xff 0xeb +0x12 0xf8 0x04 0x9b +0x1d 0xf8 0x04 0x39 + + +#------------------------------------------------------------------------------ +# LDRBT +#------------------------------------------------------------------------------ +# CHECK: ldrbt r1, [r2] +# CHECK: ldrbt r1, [r8] +# CHECK: ldrbt r1, [r8, #3] +# CHECK: ldrbt r1, [r8, #255] + +0x12 0xf8 0x00 0x1e +0x18 0xf8 0x00 0x1e +0x18 0xf8 0x03 0x1e +0x18 0xf8 0xff 0x1e + + +#------------------------------------------------------------------------------ +# LDRD(immediate) +#------------------------------------------------------------------------------ +# CHECK: ldrd r3, r5, [r6, #24] +# CHECK: ldrd r3, r5, [r6, #24]! +# CHECK: ldrd r3, r5, [r6], #4 +# CHECK: ldrd r3, r5, [r6], #-8 +# CHECK: ldrd r3, r5, [r6] +# CHECK: ldrd r8, r1, [r3] + +0xd6 0xe9 0x06 0x35 +0xf6 0xe9 0x06 0x35 +0xf6 0xe8 0x01 0x35 +0x76 0xe8 0x02 0x35 +0xd6 0xe9 0x00 0x35 +0xd3 0xe9 0x00 0x81 + + +#------------------------------------------------------------------------------ +# FIXME: LDRD(literal) +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# LDREX/LDREXB/LDREXH/LDREXD +#------------------------------------------------------------------------------ +# CHECK: ldrex r1, [r4] +# CHECK: ldrex r8, [r4] +# CHECK: ldrex r2, [sp, #128] +# CHECK: ldrexb r5, [r7] +# CHECK: ldrexh r9, [r12] +# CHECK: ldrexd r9, r3, [r4] + +0x54 0xe8 0x00 0x1f +0x54 0xe8 0x00 0x8f +0x5d 0xe8 0x20 0x2f +0xd7 0xe8 0x4f 0x5f +0xdc 0xe8 0x5f 0x9f +0xd4 0xe8 0x7f 0x93 + + +#------------------------------------------------------------------------------ +# LDRH(immediate) +#------------------------------------------------------------------------------ +# CHECK: ldrh r5, [r5, #-4] +# CHECK: ldrh r5, [r6, #32] +# CHECK: ldrh.w r5, [r6, #33] +# CHECK: ldrh.w r5, [r6, #257] +# CHECK: ldrh.w lr, [r7, #257] +# CHECK: ldrh.w r0, [pc, #-21] + +0x35 0xf8 0x04 0x5c +0x35 0x8c +0xb6 0xf8 0x21 0x50 +0xb6 0xf8 0x01 0x51 +0xb7 0xf8 0x01 0xe1 +0x3f 0xf8 0x15 0x00 + + +#------------------------------------------------------------------------------ +# LDRH(register) +#------------------------------------------------------------------------------ +# CHECK: ldrh.w r1, [r8, r1] +# CHECK: ldrh.w r4, [r5, r2] +# CHECK: ldrh.w r6, [r0, r2, lsl #3] +# CHECK: ldrh.w r8, [r8, r2, lsl #2] +# CHECK: ldrh.w r7, [sp, r2, lsl #1] +# CHECK: ldrh.w r7, [sp, r2] +# CHECK: ldrh r5, [r8, #255]! +# CHECK: ldrh r2, [r5, #4]! +# CHECK: ldrh r1, [r4, #-4]! +# CHECK: ldrh lr, [r3], #255 +# CHECK: ldrh r9, [r2], #4 +# CHECK: ldrh r3, [sp], #-4 + +0x38 0xf8 0x01 0x10 +0x35 0xf8 0x02 0x40 +0x30 0xf8 0x32 0x60 +0x38 0xf8 0x22 0x80 +0x3d 0xf8 0x12 0x70 +0x3d 0xf8 0x02 0x70 +0x38 0xf8 0xff 0x5f +0x35 0xf8 0x04 0x2f +0x34 0xf8 0x04 0x1d +0x33 0xf8 0xff 0xeb +0x32 0xf8 0x04 0x9b +0x3d 0xf8 0x04 0x39 + + +#------------------------------------------------------------------------------ +# LDRSB(immediate) +#------------------------------------------------------------------------------ +# CHECK: ldrsb r5, [r5, #-4] +# CHECK: ldrsb.w r5, [r6, #32] +# CHECK: ldrsb.w r5, [r6, #33] +# CHECK: ldrsb.w r5, [r6, #257] +# CHECK: ldrsb.w lr, [r7, #257] + +0x15 0xf9 0x04 0x5c +0x96 0xf9 0x20 0x50 +0x96 0xf9 0x21 0x50 +0x96 0xf9 0x01 0x51 +0x97 0xf9 0x01 0xe1 + + +#------------------------------------------------------------------------------ +# LDRSB(register) +#------------------------------------------------------------------------------ +# CHECK: ldrsb.w r1, [r8, r1] +# CHECK: ldrsb.w r4, [r5, r2] +# CHECK: ldrsb.w r6, [r0, r2, lsl #3] +# CHECK: ldrsb.w r8, [r8, r2, lsl #2] +# CHECK: ldrsb.w r7, [sp, r2, lsl #1] +# CHECK: ldrsb.w r7, [sp, r2] +# CHECK: ldrsb r5, [r8, #255]! +# CHECK: ldrsb r2, [r5, #4]! +# CHECK: ldrsb r1, [r4, #-4]! +# CHECK: ldrsb lr, [r3], #255 +# CHECK: ldrsb r9, [r2], #4 +# CHECK: ldrsb r3, [sp], #-4 + +0x18 0xf9 0x01 0x10 +0x15 0xf9 0x02 0x40 +0x10 0xf9 0x32 0x60 +0x18 0xf9 0x22 0x80 +0x1d 0xf9 0x12 0x70 +0x1d 0xf9 0x02 0x70 +0x18 0xf9 0xff 0x5f +0x15 0xf9 0x04 0x2f +0x14 0xf9 0x04 0x1d +0x13 0xf9 0xff 0xeb +0x12 0xf9 0x04 0x9b +0x1d 0xf9 0x04 0x39 + + +#------------------------------------------------------------------------------ +# LDRSBT +#------------------------------------------------------------------------------ +# CHECK: ldrsbt r1, [r2] +# CHECK: ldrsbt r1, [r8] +# CHECK: ldrsbt r1, [r8, #3] +# CHECK: ldrsbt r1, [r8, #255] + +0x12 0xf9 0x00 0x1e +0x18 0xf9 0x00 0x1e +0x18 0xf9 0x03 0x1e +0x18 0xf9 0xff 0x1e + + +#------------------------------------------------------------------------------ +# LDRSH(immediate) +#------------------------------------------------------------------------------ +# CHECK: ldrsh r5, [r5, #-4] +# CHECK: ldrsh.w r5, [r6, #32] +# CHECK: ldrsh.w r5, [r6, #33] +# CHECK: ldrsh.w r5, [r6, #257] +# CHECK: ldrsh.w lr, [r7, #257] +# CHECK: ldrsh r10, [r5, #-0] + +0x35 0xf9 0x04 0x5c +0xb6 0xf9 0x20 0x50 +0xb6 0xf9 0x21 0x50 +0xb6 0xf9 0x01 0x51 +0xb7 0xf9 0x01 0xe1 +0x35 0xf9 0x00 0xac + +#------------------------------------------------------------------------------ +# LDRSH(register) +#------------------------------------------------------------------------------ +# CHECK: ldrsh.w r1, [r8, r1] +# CHECK: ldrsh.w r4, [r5, r2] +# CHECK: ldrsh.w r6, [r0, r2, lsl #3] +# CHECK: ldrsh.w r8, [r8, r2, lsl #2] +# CHECK: ldrsh.w r7, [sp, r2, lsl #1] +# CHECK: ldrsh.w r7, [sp, r2] +# CHECK: ldrsh r5, [r8, #255]! +# CHECK: ldrsh r2, [r5, #4]! +# CHECK: ldrsh r1, [r4, #-4]! +# CHECK: ldrsh lr, [r3], #255 +# CHECK: ldrsh r9, [r2], #4 +# CHECK: ldrsh r3, [sp], #-4 + +0x38 0xf9 0x01 0x10 +0x35 0xf9 0x02 0x40 +0x30 0xf9 0x32 0x60 +0x38 0xf9 0x22 0x80 +0x3d 0xf9 0x12 0x70 +0x3d 0xf9 0x02 0x70 +0x38 0xf9 0xff 0x5f +0x35 0xf9 0x04 0x2f +0x34 0xf9 0x04 0x1d +0x33 0xf9 0xff 0xeb +0x32 0xf9 0x04 0x9b +0x3d 0xf9 0x04 0x39 + + +#------------------------------------------------------------------------------ +# LDRSHT +#------------------------------------------------------------------------------ +# CHECK: ldrsht r1, [r2] +# CHECK: ldrsht r1, [r8] +# CHECK: ldrsht r1, [r8, #3] +# CHECK: ldrsht r1, [r8, #255] + +0x32 0xf9 0x00 0x1e +0x38 0xf9 0x00 0x1e +0x38 0xf9 0x03 0x1e +0x38 0xf9 0xff 0x1e + + +#------------------------------------------------------------------------------ +# LDRT +#------------------------------------------------------------------------------ +# CHECK: ldrt r1, [r2] +# CHECK: ldrt r2, [r6] +# CHECK: ldrt r3, [r7, #3] +# CHECK: ldrt r4, [r9, #255] + +0x52 0xf8 0x00 0x1e +0x56 0xf8 0x00 0x2e +0x57 0xf8 0x03 0x3e +0x59 0xf8 0xff 0x4e + + +#------------------------------------------------------------------------------ +# LSL (immediate) +#------------------------------------------------------------------------------ +# CHECK: lsl.w r2, r3, #12 +# CHECK: lsls.w r8, r3, #31 +# CHECK: lsls.w r2, r3, #1 +# CHECK: lsl.w r2, r3, #4 +# CHECK: lsls.w r2, r12, #15 + +# CHECK: lsl.w r3, r3, #19 +# CHECK: lsls.w r8, r8, #2 +# CHECK: lsls.w r7, r7, #5 +# CHECK: lsl.w r12, r12, #21 + +0x4f 0xea 0x03 0x32 +0x5f 0xea 0xc3 0x78 +0x5f 0xea 0x43 0x02 +0x4f 0xea 0x03 0x12 +0x5f 0xea 0xcc 0x32 + +0x4f 0xea 0xc3 0x43 +0x5f 0xea 0x88 0x08 +0x5f 0xea 0x47 0x17 +0x4f 0xea 0x4c 0x5c + + +#------------------------------------------------------------------------------ +# LSL (register) +#------------------------------------------------------------------------------ +# CHECK: lsl.w r3, r4, r2 +# CHECK: lsl.w r1, r1, r2 +# CHECK: lsls.w r3, r4, r8 + +0x04 0xfa 0x02 0xf3 +0x01 0xfa 0x02 0xf1 +0x14 0xfa 0x08 0xf3 + + +#------------------------------------------------------------------------------ +# LSR (immediate) +#------------------------------------------------------------------------------ +# CHECK: lsr.w r2, r3, #12 +# CHECK: lsrs.w r8, r3, #32 +# CHECK: lsrs.w r2, r3, #1 +# CHECK: lsr.w r2, r3, #4 +# CHECK: lsrs.w r2, r12, #15 + +# CHECK: lsr.w r3, r3, #19 +# CHECK: lsrs.w r8, r8, #2 +# CHECK: lsrs.w r7, r7, #5 +# CHECK: lsr.w r12, r12, #21 + +0x4f 0xea 0x13 0x32 +0x5f 0xea 0x13 0x08 +0x5f 0xea 0x53 0x02 +0x4f 0xea 0x13 0x12 +0x5f 0xea 0xdc 0x32 + +0x4f 0xea 0xd3 0x43 +0x5f 0xea 0x98 0x08 +0x5f 0xea 0x57 0x17 +0x4f 0xea 0x5c 0x5c + + +#------------------------------------------------------------------------------ +# LSR (register) +#------------------------------------------------------------------------------ +# CHECK: lsr.w r3, r4, r2 +# CHECK: lsr.w r1, r1, r2 +# CHECK: lsrs.w r3, r4, r8 + +0x24 0xfa 0x02 0xf3 +0x21 0xfa 0x02 0xf1 +0x34 0xfa 0x08 0xf3 + +#------------------------------------------------------------------------------ +# MCR/MCR2 +#------------------------------------------------------------------------------ +# CHECK: mcr p7, #1, r5, c1, c1, #4 +# CHECK: mcr2 p7, #1, r5, c1, c1, #4 + +0x21 0xee 0x91 0x57 +0x21 0xfe 0x91 0x57 + + +#------------------------------------------------------------------------------ +# MCRR/MCRR2 +#------------------------------------------------------------------------------ +# CHECK: mcrr p7, #15, r5, r4, c1 +# CHECK: mcrr2 p7, #15, r5, r4, c1 + +0x44 0xec 0xf1 0x57 +0x44 0xfc 0xf1 0x57 + + +#------------------------------------------------------------------------------ +# MLA/MLS +#------------------------------------------------------------------------------ +# CHECK: mla r1, r2, r3, r4 +# CHECK: mls r1, r2, r3, r4 + +0x02 0xfb 0x03 0x41 +0x02 0xfb 0x13 0x41 + + +#------------------------------------------------------------------------------ +# MOV(immediate) +#------------------------------------------------------------------------------ +# CHECK: movs r1, #21 +# CHECK: movs.w r1, #21 +# CHECK: movs.w r8, #21 +# CHECK: movw r0, #65535 +# CHECK: movw r1, #43777 +# CHECK: movw r1, #43792 +# CHECK: mov.w r0, #66846720 +# CHECK: mov.w r0, #66846720 +# CHECK: movs.w r0, #66846720 + +0x15 0x21 +0x5f 0xf0 0x15 0x01 +0x5f 0xf0 0x15 0x08 +0x4f 0xf6 0xff 0x70 +0x4a 0xf6 0x01 0x31 +0x4a 0xf6 0x10 0x31 +0x4f 0xf0 0x7f 0x70 +0x4f 0xf0 0x7f 0x70 +0x5f 0xf0 0x7f 0x70 + +#------------------------------------------------------------------------------ +# MOVT +#------------------------------------------------------------------------------ +# CHECK: movt r3, #7 +# CHECK: movt r6, #65535 +# CHECK: it eq +# CHECK: movteq r4, #4080 + +0xc0 0xf2 0x07 0x03 +0xcf 0xf6 0xff 0x76 +0x08 0xbf +0xc0 0xf6 0xf0 0x74 + +#------------------------------------------------------------------------------ +# MRC/MRC2 +#------------------------------------------------------------------------------ +# CHECK: mrc p14, #0, r1, c1, c2, #4 +# CHECK: mrc2 p14, #0, r1, c1, c2, #4 + +0x11 0xee 0x92 0x1e +0x11 0xfe 0x92 0x1e + + +#------------------------------------------------------------------------------ +# MRRC/MRRC2 +#------------------------------------------------------------------------------ +# CHECK: mrrc p7, #1, r5, r4, c1 +# CHECK: mrrc2 p7, #1, r5, r4, c1 + +0x54 0xec 0x11 0x57 +0x54 0xfc 0x11 0x57 + + +#------------------------------------------------------------------------------ +# MRS +#------------------------------------------------------------------------------ +# CHECK: mrs r8, apsr +# CHECK: mrs r8, spsr + +0xef 0xf3 0x00 0x88 +0xff 0xf3 0x00 0x88 + + +#------------------------------------------------------------------------------ +# MSR +#------------------------------------------------------------------------------ +# CHECK: msr APSR_nzcvq, r1 +# CHECK: msr APSR_g, r2 +# CHECK: msr APSR_nzcvq, r3 +# CHECK: msr APSR_nzcvq, r4 +# CHECK: msr APSR_nzcvqg, r5 +# CHECK: msr CPSR_fc, r6 +# CHECK: msr CPSR_c, r7 +# CHECK: msr CPSR_x, r8 +# CHECK: msr CPSR_fc, r9 +# CHECK: msr CPSR_fc, r11 +# CHECK: msr CPSR_fsx, r12 +# CHECK: msr SPSR_fc, r0 +# CHECK: msr SPSR_fsxc, r5 +# CHECK: msr CPSR_fsxc, r8 + +0x81 0xf3 0x00 0x88 +0x82 0xf3 0x00 0x84 +0x83 0xf3 0x00 0x88 +0x84 0xf3 0x00 0x88 +0x85 0xf3 0x00 0x8c +0x86 0xf3 0x00 0x89 +0x87 0xf3 0x00 0x81 +0x88 0xf3 0x00 0x82 +0x89 0xf3 0x00 0x89 +0x8b 0xf3 0x00 0x89 +0x8c 0xf3 0x00 0x8e +0x90 0xf3 0x00 0x89 +0x95 0xf3 0x00 0x8f +0x88 0xf3 0x00 0x8f + + +#------------------------------------------------------------------------------ +# MUL +#------------------------------------------------------------------------------ +# CHECK: muls r3, r4, r3 +# CHECK: mul r3, r4, r3 +# CHECK: mul r3, r4, r6 +# CHECK: it eq +# CHECK: muleq r3, r4, r5 + +0x63 0x43 +0x04 0xfb 0x03 0xf3 +0x04 0xfb 0x06 0xf3 +0x08 0xbf +0x04 0xfb 0x05 0xf3 + + +#------------------------------------------------------------------------------ +# MVN(immediate) +#------------------------------------------------------------------------------ +# CHECK: mvns r8, #21 +# CHECK: mvn r0, #66846720 +# CHECK: mvns r0, #66846720 +# CHECK: itte eq +# CHECK: mvnseq r1, #12 +# CHECK: mvneq r1, #12 +# CHECK: mvnne r1, #12 + +0x7f 0xf0 0x15 0x08 +0x6f 0xf0 0x7f 0x70 +0x7f 0xf0 0x7f 0x70 +0x06 0xbf +0x7f 0xf0 0x0c 0x01 +0x6f 0xf0 0x0c 0x01 +0x6f 0xf0 0x0c 0x01 + + +#------------------------------------------------------------------------------ +# MVN(register) +#------------------------------------------------------------------------------ +# CHECK: mvn.w r2, r3 +# CHECK: mvns r2, r3 +# CHECK: mvn.w r5, r6, lsl #19 +# CHECK: mvn.w r5, r6, lsr #9 +# CHECK: mvn.w r5, r6, asr #4 +# CHECK: mvn.w r5, r6, ror #6 +# CHECK: mvn.w r5, r6, rrx +# CHECK: it eq +# CHECK: mvneq r2, r3 + +0x6f 0xea 0x03 0x02 +0xda 0x43 +0x6f 0xea 0xc6 0x45 +0x6f 0xea 0x56 0x25 +0x6f 0xea 0x26 0x15 +0x6f 0xea 0xb6 0x15 +0x6f 0xea 0x36 0x05 +0x08 0xbf +0xda 0x43 + +#------------------------------------------------------------------------------ +# NOP +#------------------------------------------------------------------------------ +# CHECK: nop.w + +0xaf 0xf3 0x00 0x80 + + +#------------------------------------------------------------------------------ +# ORN +#------------------------------------------------------------------------------ +# CHECK: orn r4, r5, #61440 +# CHECK: orn r4, r5, r6 +# CHECK: orns r4, r5, r6 +# CHECK: orn r4, r5, r6, lsl #5 +# CHECK: orns r4, r5, r6, lsr #5 +# CHECK: orn r4, r5, r6, lsr #5 +# CHECK: orns r4, r5, r6, asr #5 +# CHECK: orn r4, r5, r6, ror #5 + +0x65 0xf4 0x70 0x44 +0x65 0xea 0x06 0x04 +0x75 0xea 0x06 0x04 +0x65 0xea 0x46 0x14 +0x75 0xea 0x56 0x14 +0x65 0xea 0x56 0x14 +0x75 0xea 0x66 0x14 +0x65 0xea 0x76 0x14 + + +#------------------------------------------------------------------------------ +# ORR +#------------------------------------------------------------------------------ +# CHECK: orr r4, r5, #61440 +# CHECK: orr.w r4, r5, r6 +# CHECK: orr.w r4, r5, r6, lsl #5 +# CHECK: orrs.w r4, r5, r6, lsr #5 +# CHECK: orr.w r4, r5, r6, lsr #5 +# CHECK: orrs.w r4, r5, r6, asr #5 +# CHECK: orr.w r4, r5, r6, ror #5 + +0x45 0xf4 0x70 0x44 +0x45 0xea 0x06 0x04 +0x45 0xea 0x46 0x14 +0x55 0xea 0x56 0x14 +0x45 0xea 0x56 0x14 +0x55 0xea 0x66 0x14 +0x45 0xea 0x76 0x14 + + +#------------------------------------------------------------------------------ +# PKH +#------------------------------------------------------------------------------ +# CHECK: pkhbt r2, r2, r3 +# CHECK: pkhbt r2, r2, r3, lsl #31 +# CHECK: pkhbt r2, r2, r3, lsl #15 + +# CHECK: pkhtb r2, r2, r3, asr #31 +# CHECK: pkhtb r2, r2, r3, asr #15 + +0xc2 0xea 0x03 0x02 +0xc2 0xea 0xc3 0x72 +0xc2 0xea 0xc3 0x32 + +0xc2 0xea 0xe3 0x72 +0xc2 0xea 0xe3 0x32 + + +#------------------------------------------------------------------------------ +# PLD(immediate) +#------------------------------------------------------------------------------ +# CHECK: pld [r5, #-4] +# CHECK: pld [r6, #32] +# CHECK: pld [r6, #33] +# CHECK: pld [r6, #257] +# CHECK: pld [r7, #257] + +0x15 0xf8 0x04 0xfc +0x96 0xf8 0x20 0xf0 +0x96 0xf8 0x21 0xf0 +0x96 0xf8 0x01 0xf1 +0x97 0xf8 0x01 0xf1 + +#------------------------------------------------------------------------------ +# PLD(register) +#------------------------------------------------------------------------------ +# CHECK: pld [r8, r1] +# CHECK: pld [r5, r2] +# CHECK: pld [r0, r2, lsl #3] +# CHECK: pld [r8, r2, lsl #2] +# CHECK: pld [sp, r2, lsl #1] +# CHECK: pld [sp, r2] + +0x18 0xf8 0x01 0xf0 +0x15 0xf8 0x02 0xf0 +0x10 0xf8 0x32 0xf0 +0x18 0xf8 0x22 0xf0 +0x1d 0xf8 0x12 0xf0 +0x1d 0xf8 0x02 0xf0 + +#------------------------------------------------------------------------------ +# PLI(immediate) +#------------------------------------------------------------------------------ +# CHECK: pli [r5, #-4] +# CHECK: pli [r6, #32] +# CHECK: pli [r6, #33] +# CHECK: pli [r6, #257] +# CHECK: pli [r7, #257] + +0x15 0xf9 0x04 0xfc +0x96 0xf9 0x20 0xf0 +0x96 0xf9 0x21 0xf0 +0x96 0xf9 0x01 0xf1 +0x97 0xf9 0x01 0xf1 + +#------------------------------------------------------------------------------ +# PLI(register) +#------------------------------------------------------------------------------ +# CHECK: pli [r8, r1] +# CHECK: pli [r5, r2] +# CHECK: pli [r0, r2, lsl #3] +# CHECK: pli [r8, r2, lsl #2] +# CHECK: pli [sp, r2, lsl #1] +# CHECK: pli [sp, r2] + +0x18 0xf9 0x01 0xf0 +0x15 0xf9 0x02 0xf0 +0x10 0xf9 0x32 0xf0 +0x18 0xf9 0x22 0xf0 +0x1d 0xf9 0x12 0xf0 +0x1d 0xf9 0x02 0xf0 + + +#------------------------------------------------------------------------------ +# QADD/QADD16/QADD8 +#------------------------------------------------------------------------------ +# CHECK: qadd r1, r2, r3 +# CHECK: qadd16 r1, r2, r3 +# CHECK: qadd8 r1, r2, r3 +# CHECK: itte gt +# CHECK: qaddgt r1, r2, r3 +# CHECK: qadd16gt r1, r2, r3 +# CHECK: qadd8le r1, r2, r3 + +0x83 0xfa 0x82 0xf1 +0x92 0xfa 0x13 0xf1 +0x82 0xfa 0x13 0xf1 +0xc6 0xbf +0x83 0xfa 0x82 0xf1 +0x92 0xfa 0x13 0xf1 +0x82 0xfa 0x13 0xf1 + + +#------------------------------------------------------------------------------ +# QDADD/QDSUB +#------------------------------------------------------------------------------ +# CHECK: qdadd r6, r7, r8 +# CHECK: qdsub r6, r7, r8 +# CHECK: itt hi +# CHECK: qdaddhi r6, r7, r8 +# CHECK: qdsubhi r6, r7, r8 + +0x88 0xfa 0x97 0xf6 +0x88 0xfa 0xb7 0xf6 +0x84 0xbf +0x88 0xfa 0x97 0xf6 +0x88 0xfa 0xb7 0xf6 + + +#------------------------------------------------------------------------------ +# QSAX +#------------------------------------------------------------------------------ +# CHECK: qsax r9, r12, r0 +# CHECK: it eq +# CHECK: qsaxeq r9, r12, r0 + +0xec 0xfa 0x10 0xf9 +0x08 0xbf +0xec 0xfa 0x10 0xf9 + + +#------------------------------------------------------------------------------ +# QSUB/QSUB16/QSUB8 +#------------------------------------------------------------------------------ +# CHECK: qsub r1, r2, r3 +# CHECK: qsub16 r1, r2, r3 +# CHECK: qsub8 r1, r2, r3 +# CHECK: itet le +# CHECK: qsuble r1, r2, r3 +# CHECK: qsub16gt r1, r2, r3 +# CHECK: qsub8le r1, r2, r3 + +0x83 0xfa 0xa2 0xf1 +0xd2 0xfa 0x13 0xf1 +0xc2 0xfa 0x13 0xf1 +0xd6 0xbf +0x83 0xfa 0xa2 0xf1 +0xd2 0xfa 0x13 0xf1 +0xc2 0xfa 0x13 0xf1 + + +#------------------------------------------------------------------------------ +# RBIT +#------------------------------------------------------------------------------ +# CHECK: rbit r1, r2 +# CHECK: it ne +# CHECK: rbitne r1, r2 + +0x92 0xfa 0xa2 0xf1 +0x18 0xbf +0x92 0xfa 0xa2 0xf1 + + +#------------------------------------------------------------------------------ +# REV +#------------------------------------------------------------------------------ +# CHECK: rev.w r1, r2 +# CHECK: rev.w r2, r8 +# CHECK: itt ne +# CHECK: revne r1, r2 +# CHECK: revne.w r1, r8 + +0x92 0xfa 0x82 0xf1 +0x98 0xfa 0x88 0xf2 +0x1c 0xbf +0x11 0xba +0x98 0xfa 0x88 0xf1 + + +#------------------------------------------------------------------------------ +# REV16 +#------------------------------------------------------------------------------ +# CHECK: rev16.w r1, r2 +# CHECK: rev16.w r2, r8 +# CHECK: itt ne +# CHECK: rev16ne r1, r2 +# CHECK: rev16ne.w r1, r8 + +0x92 0xfa 0x92 0xf1 +0x98 0xfa 0x98 0xf2 +0x1c 0xbf +0x51 0xba +0x98 0xfa 0x98 0xf1 + + +#------------------------------------------------------------------------------ +# REVSH +#------------------------------------------------------------------------------ +# CHECK: revsh.w r1, r2 +# CHECK: revsh.w r2, r8 +# CHECK: itt ne +# CHECK: revshne r1, r2 +# CHECK: revshne.w r1, r8 + +0x92 0xfa 0xb2 0xf1 +0x98 0xfa 0xb8 0xf2 +0x1c 0xbf +0xd1 0xba +0x98 0xfa 0xb8 0xf1 + + +#------------------------------------------------------------------------------ +# ROR (immediate) +#------------------------------------------------------------------------------ +# CHECK: ror.w r2, r3, #12 +# CHECK: rors.w r8, r3, #31 +# CHECK: rors.w r2, r3, #1 +# CHECK: ror.w r2, r3, #4 +# CHECK: rors.w r2, r12, #15 + +# CHECK: ror.w r3, r3, #19 +# CHECK: rors.w r8, r8, #2 +# CHECK: rors.w r7, r7, #5 +# CHECK: ror.w r12, r12, #21 + +0x4f 0xea 0x33 0x32 +0x5f 0xea 0xf3 0x78 +0x5f 0xea 0x73 0x02 +0x4f 0xea 0x33 0x12 +0x5f 0xea 0xfc 0x32 + +0x4f 0xea 0xf3 0x43 +0x5f 0xea 0xb8 0x08 +0x5f 0xea 0x77 0x17 +0x4f 0xea 0x7c 0x5c + + +#------------------------------------------------------------------------------ +# ROR (register) +#------------------------------------------------------------------------------ +# CHECK: ror.w r3, r4, r2 +# CHECK: ror.w r1, r1, r2 +# CHECK: rors.w r3, r4, r8 + +0x64 0xfa 0x02 0xf3 +0x61 0xfa 0x02 0xf1 +0x74 0xfa 0x08 0xf3 + + +#------------------------------------------------------------------------------ +# RRX +#------------------------------------------------------------------------------ +# CHECK: rrx r1, r2 +# CHECK: rrxs r1, r2 +# CHECK: ite lt +# CHECK: rrxlt r9, r12 +# CHECK: rrxsge r8, r3 + +0x4f 0xea 0x32 0x01 +0x5f 0xea 0x32 0x01 +0xb4 0xbf +0x4f 0xea 0x3c 0x09 +0x5f 0xea 0x33 0x08 + +#------------------------------------------------------------------------------ +# RSB (immediate) +#------------------------------------------------------------------------------ +# CHECK: rsb.w r2, r5, #1044480 +# CHECK: rsbs.w r3, r12, #15 +# CHECK: rsb.w r1, r1, #255 + +0xc5 0xf5 0x7f 0x22 +0xdc 0xf1 0x0f 0x03 +0xc1 0xf1 0xff 0x01 + + +#------------------------------------------------------------------------------ +# RSB (register) +#------------------------------------------------------------------------------ +# CHECK: rsb r4, r4, r8 +# CHECK: rsb r4, r9, r8 +# CHECK: rsb r1, r4, r8, asr #3 +# CHECK: rsbs r2, r1, r7, lsl #1 + +0xc4 0xeb 0x08 0x04 +0xc9 0xeb 0x08 0x04 +0xc4 0xeb 0xe8 0x01 +0xd1 0xeb 0x47 0x02 + + +#------------------------------------------------------------------------------ +# SADD16 +#------------------------------------------------------------------------------ +# CHECK: sadd16 r3, r4, r8 +# CHECK: it ne +# CHECK: sadd16ne r3, r4, r8 + +0x94 0xfa 0x08 0xf3 +0x18 0xbf +0x94 0xfa 0x08 0xf3 + + +#------------------------------------------------------------------------------ +# SADD8 +#------------------------------------------------------------------------------ +# CHECK: sadd8 r3, r4, r8 +# CHECK: it ne +# CHECK: sadd8ne r3, r4, r8 + +0x84 0xfa 0x08 0xf3 +0x18 0xbf +0x84 0xfa 0x08 0xf3 + + +#------------------------------------------------------------------------------ +# SASX +#------------------------------------------------------------------------------ +# CHECK: sasx r9, r2, r7 +# CHECK: it ne +# CHECK: sasxne r2, r5, r6 + +0xa2 0xfa 0x07 0xf9 +0x18 0xbf +0xa5 0xfa 0x06 0xf2 + + +#------------------------------------------------------------------------------ +# SBC (immediate) +#------------------------------------------------------------------------------ +# CHECK: sbc r0, r1, #4 +# CHECK: sbcs r0, r1, #0 +# CHECK: sbc r1, r2, #255 +# CHECK: sbc r3, r7, #5570645 +# CHECK: sbc r8, r12, #2852170240 +# CHECK: sbc r9, r7, #2779096485 +# CHECK: sbc r5, r3, #2264924160 +# CHECK: sbc r4, r2, #2139095040 +# CHECK: sbc r4, r2, #1664 + +0x61 0xf1 0x04 0x00 +0x71 0xf1 0x00 0x00 +0x62 0xf1 0xff 0x01 +0x67 0xf1 0x55 0x13 +0x6c 0xf1 0xaa 0x28 +0x67 0xf1 0xa5 0x39 +0x63 0xf1 0x07 0x45 +0x62 0xf1 0xff 0x44 +0x62 0xf5 0xd0 0x64 + + +#------------------------------------------------------------------------------ +# SBC (register) +#------------------------------------------------------------------------------ +# CHECK: sbc.w r4, r5, r6 +# CHECK: sbcs.w r4, r5, r6 +# CHECK: sbc.w r9, r1, r3 +# CHECK: sbcs.w r9, r1, r3 +# CHECK: sbc.w r0, r1, r3, ror #4 +# CHECK: sbcs.w r0, r1, r3, lsl #7 +# CHECK: sbc.w r0, r1, r3, lsr #31 +# CHECK: sbcs.w r0, r1, r3, asr #32 + +0x65 0xeb 0x06 0x04 +0x75 0xeb 0x06 0x04 +0x61 0xeb 0x03 0x09 +0x71 0xeb 0x03 0x09 +0x61 0xeb 0x33 0x10 +0x71 0xeb 0xc3 0x10 +0x61 0xeb 0xd3 0x70 +0x71 0xeb 0x23 0x00 + + +#------------------------------------------------------------------------------ +# SBFX +#------------------------------------------------------------------------------ +# CHECK: sbfx r4, r5, #16, #1 +# CHECK: it gt +# CHECK: sbfxgt r4, r5, #16, #16 + +0x45 0xf3 0x00 0x44 +0xc8 0xbf +0x45 0xf3 0x0f 0x44 + + +#------------------------------------------------------------------------------ +# SEL +#------------------------------------------------------------------------------ +# CHECK: sel r5, r9, r2 +# CHECK: it le +# CHECK: selle r5, r9, r2 + +0xa9 0xfa 0x82 0xf5 +0xd8 0xbf +0xa9 0xfa 0x82 0xf5 + + +#------------------------------------------------------------------------------ +# SEV +#------------------------------------------------------------------------------ +# CHECK: sev.w +# CHECK: it eq +# CHECK: seveq.w + +0xaf 0xf3 0x04 0x80 +0x08 0xbf +0xaf 0xf3 0x04 0x80 + + +#------------------------------------------------------------------------------ +# SADD16/SADD8 +#------------------------------------------------------------------------------ +# CHECK: sadd16 r1, r2, r3 +# CHECK: sadd8 r1, r2, r3 +# CHECK: ite gt +# CHECK: sadd16gt r1, r2, r3 +# CHECK: sadd8le r1, r2, r3 + +0x92 0xfa 0x03 0xf1 +0x82 0xfa 0x03 0xf1 +0xcc 0xbf +0x92 0xfa 0x03 0xf1 +0x82 0xfa 0x03 0xf1 + + +#------------------------------------------------------------------------------ +# SHASX +#------------------------------------------------------------------------------ +# CHECK: shasx r4, r8, r2 +# CHECK: it gt +# CHECK: shasxgt r4, r8, r2 + +0xa8 0xfa 0x22 0xf4 +0xc8 0xbf +0xa8 0xfa 0x22 0xf4 + + +#------------------------------------------------------------------------------ +# SHASX +#------------------------------------------------------------------------------ +# CHECK: shsax r4, r8, r2 +# CHECK: it gt +# CHECK: shsaxgt r4, r8, r2 + +0xe8 0xfa 0x22 0xf4 +0xc8 0xbf +0xe8 0xfa 0x22 0xf4 + + +#------------------------------------------------------------------------------ +# SHSUB16/SHSUB8 +#------------------------------------------------------------------------------ +# CHECK: shsub16 r4, r8, r2 +# CHECK: shsub8 r4, r8, r2 +# CHECK: itt gt +# CHECK: shsub16gt r4, r8, r2 +# CHECK: shsub8gt r4, r8, r2 + +0xd8 0xfa 0x22 0xf4 +0xc8 0xfa 0x22 0xf4 +0xc4 0xbf +0xd8 0xfa 0x22 0xf4 +0xc8 0xfa 0x22 0xf4 + + +#------------------------------------------------------------------------------ +# SMLABB/SMLABT/SMLATB/SMLATT +#------------------------------------------------------------------------------ +# CHECK: smlabb r3, r1, r9, r0 +# CHECK: smlabt r5, r6, r4, r1 +# CHECK: smlatb r4, r2, r3, r2 +# CHECK: smlatt r8, r3, r8, r4 +# CHECK: itete gt +# CHECK: smlabbgt r3, r1, r9, r0 +# CHECK: smlabtle r5, r6, r4, r1 +# CHECK: smlatbgt r4, r2, r3, r2 +# CHECK: smlattle r8, r3, r8, r4 + +0x11 0xfb 0x09 0x03 +0x16 0xfb 0x14 0x15 +0x12 0xfb 0x23 0x24 +0x13 0xfb 0x38 0x48 +0xcb 0xbf +0x11 0xfb 0x09 0x03 +0x16 0xfb 0x14 0x15 +0x12 0xfb 0x23 0x24 +0x13 0xfb 0x38 0x48 + + +#------------------------------------------------------------------------------ +# SMLAD/SMLADX +#------------------------------------------------------------------------------ +# CHECK: smlad r2, r3, r5, r8 +# CHECK: smladx r2, r3, r5, r8 +# CHECK: itt hi +# CHECK: smladhi r2, r3, r5, r8 +# CHECK: smladxhi r2, r3, r5, r8 + +0x23 0xfb 0x05 0x82 +0x23 0xfb 0x15 0x82 +0x84 0xbf +0x23 0xfb 0x05 0x82 +0x23 0xfb 0x15 0x82 + + +#------------------------------------------------------------------------------ +# SMLAL +#------------------------------------------------------------------------------ +# CHECK: smlal r2, r3, r5, r8 +# CHECK: it eq +# CHECK: smlaleq r2, r3, r5, r8 + +0xc5 0xfb 0x08 0x23 +0x08 0xbf +0xc5 0xfb 0x08 0x23 + + +#------------------------------------------------------------------------------ +# SMLALBB/SMLALBT/SMLALTB/SMLALTT +#------------------------------------------------------------------------------ +# CHECK: smlalbb r3, r1, r9, r0 +# CHECK: smlalbt r5, r6, r4, r1 +# CHECK: smlaltb r4, r2, r3, r2 +# CHECK: smlaltt r8, r3, r8, r4 +# CHECK: iteet ge +# CHECK: smlalbbge r3, r1, r9, r0 +# CHECK: smlalbtlt r5, r6, r4, r1 +# CHECK: smlaltblt r4, r2, r3, r2 +# CHECK: smlalttge r8, r3, r8, r4 + +0xc9 0xfb 0x80 0x31 +0xc4 0xfb 0x91 0x56 +0xc3 0xfb 0xa2 0x42 +0xc8 0xfb 0xb4 0x83 +0xad 0xbf +0xc9 0xfb 0x80 0x31 +0xc4 0xfb 0x91 0x56 +0xc3 0xfb 0xa2 0x42 +0xc8 0xfb 0xb4 0x83 + +#------------------------------------------------------------------------------ +# SMLALD/SMLALDX +#------------------------------------------------------------------------------ +# CHECK: smlald r2, r3, r5, r8 +# CHECK: smlaldx r2, r3, r5, r8 +# CHECK: ite eq +# CHECK: smlaldeq r2, r3, r5, r8 +# CHECK: smlaldxne r2, r3, r5, r8 + +0xc5 0xfb 0xc8 0x23 +0xc5 0xfb 0xd8 0x23 +0x0c 0xbf +0xc5 0xfb 0xc8 0x23 +0xc5 0xfb 0xd8 0x23 + + +#------------------------------------------------------------------------------ +# SMLAWB/SMLAWT +#------------------------------------------------------------------------------ +# CHECK: smlawb r2, r3, r10, r8 +# CHECK: smlawt r8, r3, r5, r9 +# CHECK: ite eq +# CHECK: smlawbeq r2, r7, r5, r8 +# CHECK: smlawtne r1, r3, r0, r8 + +0x33 0xfb 0x0a 0x82 +0x33 0xfb 0x15 0x98 +0x0c 0xbf +0x37 0xfb 0x05 0x82 +0x33 0xfb 0x10 0x81 + + +#------------------------------------------------------------------------------ +# SMLSD/SMLSDX +#------------------------------------------------------------------------------ +# CHECK: smlsd r2, r3, r5, r8 +# CHECK: smlsdx r2, r3, r5, r8 +# CHECK: ite le +# CHECK: smlsdle r2, r3, r5, r8 +# CHECK: smlsdxgt r2, r3, r5, r8 + +0x43 0xfb 0x05 0x82 +0x43 0xfb 0x15 0x82 +0xd4 0xbf +0x43 0xfb 0x05 0x82 +0x43 0xfb 0x15 0x82 + + +#------------------------------------------------------------------------------ +# SMLSLD/SMLSLDX +#------------------------------------------------------------------------------ +# CHECK: smlsld r2, r9, r5, r1 +# CHECK: smlsldx r4, r11, r2, r8 +# CHECK: ite ge +# CHECK: smlsldge r8, r2, r5, r6 +# CHECK: smlsldxlt r1, r0, r3, r8 + +0xd5 0xfb 0xc1 0x29 +0xd2 0xfb 0xd8 0x4b +0xac 0xbf +0xd5 0xfb 0xc6 0x82 +0xd3 0xfb 0xd8 0x10 + + +#------------------------------------------------------------------------------ +# SMMLA/SMMLAR +#------------------------------------------------------------------------------ +# CHECK: smmla r1, r2, r3, r4 +# CHECK: smmlar r4, r3, r2, r1 +# CHECK: ite lo +# CHECK: smmlalo r1, r2, r3, r4 +# CHECK: smmlarhs r4, r3, r2, r1 + +0x52 0xfb 0x03 0x41 +0x53 0xfb 0x12 0x14 +0x34 0xbf +0x52 0xfb 0x03 0x41 +0x53 0xfb 0x12 0x14 + + +#------------------------------------------------------------------------------ +# SMMLS/SMMLSR +#------------------------------------------------------------------------------ +# CHECK: smmls r1, r2, r3, r4 +# CHECK: smmlsr r4, r3, r2, r1 +# CHECK: ite lo +# CHECK: smmlslo r1, r2, r3, r4 +# CHECK: smmlsrhs r4, r3, r2, r1 + +0x62 0xfb 0x03 0x41 +0x63 0xfb 0x12 0x14 +0x34 0xbf +0x62 0xfb 0x03 0x41 +0x63 0xfb 0x12 0x14 + +#------------------------------------------------------------------------------ +# SSAT +#------------------------------------------------------------------------------ +# CHECK: ssat r9, #30, r0, asr #2 + +0x20 0xf3 0x9d 0x09 + +#------------------------------------------------------------------------------ +# STR (immediate) +#------------------------------------------------------------------------------ +# CHECK: str r10, [r11], #0 + +0x4b 0xf8 0x00 0xab + +#------------------------------------------------------------------------------ +# STRD (immediate) +#------------------------------------------------------------------------------ +# CHECK: strd r6, r3, [r5], #-8 +# CHECK: strd r8, r5, [r5]{{$}} +# CHECK: strd r7, r4, [r5], #-4 + +0x65 0xe8 0x02 0x63 +0x65 0xe8 0x00 0x85 +0x65 0xe8 0x01 0x74 + +#------------------------------------------------------------------------------ +# STREX/STREXB/STREXH/STREXD +#------------------------------------------------------------------------------ +# CHECK: strex r1, r8, [r4] +# CHECK: strex r8, r2, [r4] +# CHECK: strex r2, r12, [sp, #128] +# CHECK: strexb r5, r1, [r7] +# CHECK: strexh r9, r7, [r12] +# CHECK: strexd r9, r3, r6, [r4] + +0x44 0xe8 0x00 0x81 +0x44 0xe8 0x00 0x28 +0x4d 0xe8 0x20 0xc2 +0xc7 0xe8 0x45 0x1f +0xcc 0xe8 0x59 0x7f +0xc4 0xe8 0x79 0x36 + + +#------------------------------------------------------------------------------ +# STRH(immediate) +#------------------------------------------------------------------------------ +# CHECK: strh r5, [r5, #-4] +# CHECK: strh r5, [r6, #32] +# CHECK: strh.w r5, [r6, #33] +# CHECK: strh.w r5, [r6, #257] +# CHECK: strh.w lr, [r7, #257] +# CHECK: strh r5, [r8, #255]! +# CHECK: strh r2, [r5, #4]! +# CHECK: strh r1, [r4, #-4]! +# CHECK: strh lr, [r3], #255 +# CHECK: strh r9, [r2], #4 +# CHECK: strh r3, [sp], #-4 + +0x25 0xf8 0x04 0x5c +0x35 0x84 +0xa6 0xf8 0x21 0x50 +0xa6 0xf8 0x01 0x51 +0xa7 0xf8 0x01 0xe1 +0x28 0xf8 0xff 0x5f +0x25 0xf8 0x04 0x2f +0x24 0xf8 0x04 0x1d +0x23 0xf8 0xff 0xeb +0x22 0xf8 0x04 0x9b +0x2d 0xf8 0x04 0x39 + + +#------------------------------------------------------------------------------ +# STRH(register) +#------------------------------------------------------------------------------ +# CHECK: strh.w r1, [r8, r1] +# CHECK: strh.w r4, [r5, r2] +# CHECK: strh.w r6, [r0, r2, lsl #3] +# CHECK: strh.w r8, [r8, r2, lsl #2] +# CHECK: strh.w r7, [sp, r2, lsl #1] +# CHECK: strh.w r7, [sp, r2] + +0x28 0xf8 0x01 0x10 +0x25 0xf8 0x02 0x40 +0x20 0xf8 0x32 0x60 +0x28 0xf8 0x22 0x80 +0x2d 0xf8 0x12 0x70 +0x2d 0xf8 0x02 0x70 + + +#------------------------------------------------------------------------------ +# STRHT +#------------------------------------------------------------------------------ +# CHECK: strht r1, [r2] +# CHECK: strht r1, [r8] +# CHECK: strht r1, [r8, #3] +# CHECK: strht r1, [r8, #255] + +0x22 0xf8 0x00 0x1e +0x28 0xf8 0x00 0x1e +0x28 0xf8 0x03 0x1e +0x28 0xf8 0xff 0x1e + + +#------------------------------------------------------------------------------ +# STRT +#------------------------------------------------------------------------------ +# CHECK: strt r1, [r2] +# CHECK: strt r1, [r8] +# CHECK: strt r1, [r8, #3] +# CHECK: strt r1, [r8, #255] + +0x42 0xf8 0x00 0x1e +0x48 0xf8 0x00 0x1e +0x48 0xf8 0x03 0x1e +0x48 0xf8 0xff 0x1e + + +#------------------------------------------------------------------------------ +# SUB (immediate) +#------------------------------------------------------------------------------ +# CHECK: itet eq +# CHECK: subeq r1, r2, #4 +# CHECK: subwne r5, r3, #1023 +# CHECK: subweq r4, r5, #293 +# CHECK: sub.w r2, sp, #1024 +# CHECK: sub.w r2, r8, #65280 +# CHECK: subw r2, r3, #257 +# CHECK: sub.w r12, r6, #256 +# CHECK: subw r12, r6, #256 +# CHECK: subs.w r1, r2, #496 + +0x0a 0xbf +0x11 0x1f +0xa3 0xf2 0xff 0x35 +0xa5 0xf2 0x25 0x14 +0xad 0xf5 0x80 0x62 +0xa8 0xf5 0x7f 0x42 +0xa3 0xf2 0x01 0x12 +0xa6 0xf5 0x80 0x7c +0xa6 0xf2 0x00 0x1c +0xb2 0xf5 0xf8 0x71 + + +#------------------------------------------------------------------------------ +# SUB (register) +#------------------------------------------------------------------------------ +# CHECK: sub.w r4, r5, r6 +# CHECK: sub.w r4, r5, r6, lsl #5 +# CHECK: sub.w r4, r5, r6, lsr #5 +# CHECK: sub.w r4, r5, r6, lsr #5 +# CHECK: sub.w r4, r5, r6, asr #5 +# CHECK: sub.w r4, r5, r6, ror #5 +# CHECK: sub.w r5, r2, r12, rrx + +0xa5 0xeb 0x06 0x04 +0xa5 0xeb 0x46 0x14 +0xa5 0xeb 0x56 0x14 +0xa5 0xeb 0x56 0x14 +0xa5 0xeb 0x66 0x14 +0xa5 0xeb 0x76 0x14 +0xa2 0xeb 0x3c 0x05 + + +#------------------------------------------------------------------------------ +# SVC +#------------------------------------------------------------------------------ +# CHECK: svc #0 +# CHECK: ite eq +# CHECK: svceq #255 +# CHECK: svcne #33 + +0x00 0xdf +0x0c 0xbf +0xff 0xdf +0x21 0xdf + +#------------------------------------------------------------------------------ +# SXTAB +#------------------------------------------------------------------------------ +# CHECK: sxtab r2, r3, r4 +# CHECK: sxtab r4, r5, r6 +# CHECK: it lt +# CHECK: sxtablt r6, r2, r9, ror #8 +# CHECK: sxtab r5, r1, r4, ror #16 +# CHECK: sxtab r7, r8, r3, ror #24 + +0x43 0xfa 0x84 0xf2 +0x45 0xfa 0x86 0xf4 +0xb8 0xbf +0x42 0xfa 0x99 0xf6 +0x41 0xfa 0xa4 0xf5 +0x48 0xfa 0xb3 0xf7 + + +#------------------------------------------------------------------------------ +# SXTAB16 +#------------------------------------------------------------------------------ +# CHECK: sxtab16 r6, r2, r7 +# CHECK: sxtab16 r3, r5, r8, ror #8 +# CHECK: sxtab16 r3, r2, r1, ror #16 +# CHECK: ite ne +# CHECK: sxtab16ne r0, r1, r4 +# CHECK: sxtab16eq r1, r2, r3, ror #24 + +0x22 0xfa 0x87 0xf6 +0x25 0xfa 0x98 0xf3 +0x22 0xfa 0xa1 0xf3 +0x14 0xbf +0x21 0xfa 0x84 0xf0 +0x22 0xfa 0xb3 0xf1 + + +#------------------------------------------------------------------------------ +# SXTAH +#------------------------------------------------------------------------------ +# CHECK: sxtah r1, r3, r9 +# CHECK: sxtah r3, r8, r3, ror #8 +# CHECK: sxtah r9, r3, r3, ror #24 +# CHECK: ite hi +# CHECK: sxtahhi r6, r1, r6 +# CHECK: sxtahls r2, r2, r4, ror #16 + +0x03 0xfa 0x89 0xf1 +0x08 0xfa 0x93 0xf3 +0x03 0xfa 0xb3 0xf9 +0x8c 0xbf +0x01 0xfa 0x86 0xf6 +0x02 0xfa 0xa4 0xf2 + + +#------------------------------------------------------------------------------ +# SXTB +#------------------------------------------------------------------------------ +# CHECK: sxtb r5, r6 +# CHECK: sxtb.w r6, r9, ror #8 +# CHECK: sxtb.w r8, r3, ror #24 +# CHECK: ite ge +# CHECK: sxtbge r2, r4 +# CHECK: sxtblt.w r5, r1, ror #16 + +0x75 0xb2 +0x4f 0xfa 0x99 0xf6 +0x4f 0xfa 0xb3 0xf8 +0xac 0xbf +0x62 0xb2 +0x4f 0xfa 0xa1 0xf5 + + +#------------------------------------------------------------------------------ +# SXTB16 +#------------------------------------------------------------------------------ +# CHECK: sxtb16 r1, r4 +# CHECK: sxtb16 r6, r7 +# CHECK: sxtb16 r3, r1, ror #16 +# CHECK: ite hs +# CHECK: sxtb16hs r3, r5, ror #8 +# CHECK: sxtb16lo r2, r3, ror #24 + +0x2f 0xfa 0x84 0xf1 +0x2f 0xfa 0x87 0xf6 +0x2f 0xfa 0xa1 0xf3 +0x2c 0xbf +0x2f 0xfa 0x95 0xf3 +0x2f 0xfa 0xb3 0xf2 + + +#------------------------------------------------------------------------------ +# SXTH +#------------------------------------------------------------------------------ +# CHECK: sxth r1, r6 +# CHECK: sxth.w r3, r8, ror #8 +# CHECK: sxth.w r9, r3, ror #24 +# CHECK: itt ne +# CHECK: sxthne.w r3, r9 +# CHECK: sxthne.w r2, r2, ror #16 + +0x31 0xb2 +0x0f 0xfa 0x98 0xf3 +0x0f 0xfa 0xb3 0xf9 +0x1c 0xbf +0x0f 0xfa 0x89 0xf3 +0x0f 0xfa 0xa2 0xf2 + + +#------------------------------------------------------------------------------ +# SXTB +#------------------------------------------------------------------------------ +# CHECK: sxtb r5, r6 +# CHECK: sxtb.w r6, r9, ror #8 +# CHECK: sxtb.w r8, r3, ror #24 +# CHECK: ite ge +# CHECK: sxtbge r2, r4 +# CHECK: sxtblt.w r5, r1, ror #16 + +0x75 0xb2 +0x4f 0xfa 0x99 0xf6 +0x4f 0xfa 0xb3 0xf8 +0xac 0xbf +0x62 0xb2 +0x4f 0xfa 0xa1 0xf5 + + +#------------------------------------------------------------------------------ +# SXTB16 +#------------------------------------------------------------------------------ +# CHECK: sxtb16 r1, r4 +# CHECK: sxtb16 r6, r7 +# CHECK: sxtb16 r3, r1, ror #16 +# CHECK: ite hs +# CHECK: sxtb16hs r3, r5, ror #8 +# CHECK: sxtb16lo r2, r3, ror #24 + +0x2f 0xfa 0x84 0xf1 +0x2f 0xfa 0x87 0xf6 +0x2f 0xfa 0xa1 0xf3 +0x2c 0xbf +0x2f 0xfa 0x95 0xf3 +0x2f 0xfa 0xb3 0xf2 + + +#------------------------------------------------------------------------------ +# SXTH +#------------------------------------------------------------------------------ +# CHECK: sxth r1, r6 +# CHECK: sxth.w r3, r8, ror #8 +# CHECK: sxth.w r9, r3, ror #24 +# CHECK: itt ne +# CHECK: sxthne.w r3, r9 +# CHECK: sxthne.w r2, r2, ror #16 + +0x31 0xb2 +0x0f 0xfa 0x98 0xf3 +0x0f 0xfa 0xb3 0xf9 +0x1c 0xbf +0x0f 0xfa 0x89 0xf3 +0x0f 0xfa 0xa2 0xf2 + + +#------------------------------------------------------------------------------ +# TBB/TBH +#------------------------------------------------------------------------------ +# CHECK: tbb [r3, r8] +# CHECK: tbh [r3, r8, lsl #1] +# CHECK: it eq +# CHECK: tbbeq [r3, r8] +# CHECK: it hs +# CHECK: tbhhs [r3, r8, lsl #1] + +0xd3 0xe8 0x08 0xf0 +0xd3 0xe8 0x18 0xf0 +0x08 0xbf +0xd3 0xe8 0x08 0xf0 +0x28 0xbf +0xd3 0xe8 0x18 0xf0 + + +#------------------------------------------------------------------------------ +# TEQ +#------------------------------------------------------------------------------ +# CHECK: teq.w r5, #61440 +# CHECK: teq.w r4, r5 +# CHECK: teq.w r4, r5, lsl #5 +# CHECK: teq.w r4, r5, lsr #5 +# CHECK: teq.w r4, r5, lsr #5 +# CHECK: teq.w r4, r5, asr #5 +# CHECK: teq.w r4, r5, ror #5 + +0x95 0xf4 0x70 0x4f +0x94 0xea 0x05 0x0f +0x94 0xea 0x45 0x1f +0x94 0xea 0x55 0x1f +0x94 0xea 0x55 0x1f +0x94 0xea 0x65 0x1f +0x94 0xea 0x75 0x1f + + +#------------------------------------------------------------------------------ +# TST +#------------------------------------------------------------------------------ +# CHECK: tst.w r5, #61440 +# CHECK: tst r2, r5 +# CHECK: tst.w r3, r12, lsl #5 +# CHECK: tst.w r4, r11, lsr #4 +# CHECK: tst.w r5, r10, lsr #12 +# CHECK: tst.w r6, r9, asr #30 +# CHECK: tst.w r7, r8, ror #2 + +0x15 0xf4 0x70 0x4f +0x2a 0x42 +0x13 0xea 0x4c 0x1f +0x14 0xea 0x1b 0x1f +0x15 0xea 0x1a 0x3f +0x16 0xea 0xa9 0x7f +0x17 0xea 0xb8 0x0f + + +#------------------------------------------------------------------------------ +# UADD16/UADD8 +#------------------------------------------------------------------------------ +# CHECK: uadd16 r1, r2, r3 +# CHECK: uadd8 r1, r2, r3 +# CHECK: ite gt +# CHECK: uadd16gt r1, r2, r3 +# CHECK: uadd8le r1, r2, r3 + +0x92 0xfa 0x43 0xf1 +0x82 0xfa 0x43 0xf1 +0xcc 0xbf +0x92 0xfa 0x43 0xf1 +0x82 0xfa 0x43 0xf1 + + +#------------------------------------------------------------------------------ +# UASX +#------------------------------------------------------------------------------ +# CHECK: uasx r9, r12, r0 +# CHECK: it eq +# CHECK: uasxeq r9, r12, r0 +# CHECK: uasx r9, r12, r0 +# CHECK: it eq +# CHECK: uasxeq r9, r12, r0 + +0xac 0xfa 0x40 0xf9 +0x08 0xbf +0xac 0xfa 0x40 0xf9 +0xac 0xfa 0x40 0xf9 +0x08 0xbf +0xac 0xfa 0x40 0xf9 + + +#------------------------------------------------------------------------------ +# UBFX +#------------------------------------------------------------------------------ +# CHECK: ubfx r4, r5, #16, #1 +# CHECK: it gt +# CHECK: ubfxgt r4, r5, #16, #16 + +0xc5 0xf3 0x00 0x44 +0xc8 0xbf +0xc5 0xf3 0x0f 0x44 + + +#------------------------------------------------------------------------------ +# UHADD16/UHADD8 +#------------------------------------------------------------------------------ +# CHECK: uhadd16 r4, r8, r2 +# CHECK: uhadd8 r4, r8, r2 +# CHECK: itt gt +# CHECK: uhadd16gt r4, r8, r2 +# CHECK: uhadd8gt r4, r8, r2 + +0x98 0xfa 0x62 0xf4 +0x88 0xfa 0x62 0xf4 +0xc4 0xbf +0x98 0xfa 0x62 0xf4 +0x88 0xfa 0x62 0xf4 + + +#------------------------------------------------------------------------------ +# UHASX/UHSAX +#------------------------------------------------------------------------------ +# CHECK: uhasx r4, r1, r5 +# CHECK: uhsax r5, r6, r6 +# CHECK: itt gt +# CHECK: uhasxgt r6, r9, r8 +# CHECK: uhsaxgt r7, r8, r12 + +0xa1 0xfa 0x65 0xf4 +0xe6 0xfa 0x66 0xf5 +0xc4 0xbf +0xa9 0xfa 0x68 0xf6 +0xe8 0xfa 0x6c 0xf7 + +#------------------------------------------------------------------------------ +# UHSUB16/UHSUB8 +#------------------------------------------------------------------------------ +# CHECK: uhsub16 r5, r8, r3 +# CHECK: uhsub8 r1, r7, r6 +# CHECK: itt lt +# CHECK: uhsub16lt r4, r9, r12 +# CHECK: uhsub8lt r3, r1, r5 + +0xd8 0xfa 0x63 0xf5 +0xc7 0xfa 0x66 0xf1 +0xbc 0xbf +0xd9 0xfa 0x6c 0xf4 +0xc1 0xfa 0x65 0xf3 + + +#------------------------------------------------------------------------------ +# UMAAL +#------------------------------------------------------------------------------ +# CHECK: umaal r3, r4, r5, r6 +# CHECK: it lt +# CHECK: umaallt r3, r4, r5, r6 + +0xe5 0xfb 0x66 0x34 +0xb8 0xbf +0xe5 0xfb 0x66 0x34 + + +#------------------------------------------------------------------------------ +# UMLAL +#------------------------------------------------------------------------------ +# CHECK: umlal r2, r4, r6, r8 +# CHECK: it gt +# CHECK: umlalgt r6, r1, r2, r6 + +0xe6 0xfb 0x08 0x24 +0xc8 0xbf +0xe2 0xfb 0x06 0x61 + + +#------------------------------------------------------------------------------ +# UMULL +#------------------------------------------------------------------------------ +# CHECK: umull r2, r4, r6, r8 +# CHECK: it gt +# CHECK: umullgt r6, r1, r2, r6 + +0xa6 0xfb 0x08 0x24 +0xc8 0xbf +0xa2 0xfb 0x06 0x61 + + +#------------------------------------------------------------------------------ +# UQADD16/UQADD8 +#------------------------------------------------------------------------------ +# CHECK: uqadd16 r1, r2, r3 +# CHECK: uqadd8 r3, r4, r8 +# CHECK: ite gt +# CHECK: uqadd16gt r4, r7, r9 +# CHECK: uqadd8le r8, r1, r2 + +0x92 0xfa 0x53 0xf1 +0x84 0xfa 0x58 0xf3 +0xcc 0xbf +0x97 0xfa 0x59 0xf4 +0x81 0xfa 0x52 0xf8 + + +#------------------------------------------------------------------------------ +# UQASX/UQSAX +#------------------------------------------------------------------------------ +# CHECK: uqasx r1, r2, r3 +# CHECK: uqsax r3, r4, r8 +# CHECK: ite gt +# CHECK: uqasxgt r4, r7, r9 +# CHECK: uqsaxle r8, r1, r2 + +0xa2 0xfa 0x53 0xf1 +0xe4 0xfa 0x58 0xf3 +0xcc 0xbf +0xa7 0xfa 0x59 0xf4 +0xe1 0xfa 0x52 0xf8 + + +#------------------------------------------------------------------------------ +# UQSUB16/UQSUB8 +#------------------------------------------------------------------------------ +# CHECK: uqsub8 r8, r2, r9 +# CHECK: uqsub16 r1, r9, r7 +# CHECK: ite gt +# CHECK: uqsub8gt r3, r1, r6 +# CHECK: uqsub16le r4, r6, r4 + +0xc2 0xfa 0x59 0xf8 +0xd9 0xfa 0x57 0xf1 +0xcc 0xbf +0xc1 0xfa 0x56 0xf3 +0xd6 0xfa 0x54 0xf4 + + +#------------------------------------------------------------------------------ +# UQSUB16/UQSUB8 +#------------------------------------------------------------------------------ +# CHECK: usad8 r1, r9, r7 +# CHECK: usada8 r8, r2, r9, r12 +# CHECK: ite gt +# CHECK: usada8gt r3, r1, r6, r9 +# CHECK: usad8le r4, r6, r4 + +0x79 0xfb 0x07 0xf1 +0x72 0xfb 0x09 0xc8 +0xcc 0xbf +0x71 0xfb 0x06 0x93 +0x76 0xfb 0x04 0xf4 + + +#------------------------------------------------------------------------------ +# USAT +#------------------------------------------------------------------------------ +# CHECK: usat r8, #1, r10 +# CHECK: usat r8, #4, r10 +# CHECK: usat r8, #5, r10, lsl #31 +# CHECK: usat r8, #16, r10, asr #1 + +0x8a 0xf3 0x01 0x08 +0x8a 0xf3 0x04 0x08 +0x8a 0xf3 0xc5 0x78 +0xaa 0xf3 0x50 0x08 + + +#------------------------------------------------------------------------------ +# USAT16 +#------------------------------------------------------------------------------ +# CHECK: usat16 r2, #2, r7 +# CHECK: usat16 r3, #15, r5 + +0xa7 0xf3 0x02 0x02 +0xa5 0xf3 0x0f 0x03 + + +#------------------------------------------------------------------------------ +# USAX +#------------------------------------------------------------------------------ +# CHECK: usax r2, r3, r4 +# CHECK: it ne +# CHECK: usaxne r6, r1, r9 +# CHECK: usax r2, r3, r4 +# CHECK: it ne +# CHECK: usaxne r6, r1, r9 + +0xe3 0xfa 0x44 0xf2 +0x18 0xbf +0xe1 0xfa 0x49 0xf6 +0xe3 0xfa 0x44 0xf2 +0x18 0xbf +0xe1 0xfa 0x49 0xf6 + + +#------------------------------------------------------------------------------ +# USUB16/USUB8 +#------------------------------------------------------------------------------ +# CHECK: usub16 r4, r2, r7 +# CHECK: usub8 r1, r8, r5 +# CHECK: ite hi +# CHECK: usub16hi r1, r1, r3 +# CHECK: usub8ls r9, r2, r3 + +0xd2 0xfa 0x47 0xf4 +0xc8 0xfa 0x45 0xf1 +0x8c 0xbf +0xd1 0xfa 0x43 0xf1 +0xc2 0xfa 0x43 0xf9 + + +#------------------------------------------------------------------------------ +# UXTAB +#------------------------------------------------------------------------------ +# CHECK: uxtab r2, r3, r4 +# CHECK: uxtab r4, r5, r6 +# CHECK: it lt +# CHECK: uxtablt r6, r2, r9, ror #8 +# CHECK: uxtab r5, r1, r4, ror #16 +# CHECK: uxtab r7, r8, r3, ror #24 + +0x53 0xfa 0x84 0xf2 +0x55 0xfa 0x86 0xf4 +0xb8 0xbf +0x52 0xfa 0x99 0xf6 +0x51 0xfa 0xa4 0xf5 +0x58 0xfa 0xb3 0xf7 + + +#------------------------------------------------------------------------------ +# UXTAB16 +#------------------------------------------------------------------------------ +# CHECK: it ge +# CHECK: uxtab16ge r0, r1, r4 +# CHECK: uxtab16 r6, r2, r7 +# CHECK: uxtab16 r3, r5, r8, ror #8 +# CHECK: uxtab16 r3, r2, r1, ror #16 +# CHECK: it eq +# CHECK: uxtab16eq r1, r2, r3, ror #24 + +0xa8 0xbf +0x31 0xfa 0x84 0xf0 +0x32 0xfa 0x87 0xf6 +0x35 0xfa 0x98 0xf3 +0x32 0xfa 0xa1 0xf3 +0x08 0xbf +0x32 0xfa 0xb3 0xf1 + + +#------------------------------------------------------------------------------ +# UXTAH +#------------------------------------------------------------------------------ +# CHECK: uxtah r1, r3, r9 +# CHECK: it hi +# CHECK: uxtahhi r6, r1, r6 +# CHECK: uxtah r3, r8, r3, ror #8 +# CHECK: it lo +# CHECK: uxtahlo r2, r2, r4, ror #16 +# CHECK: uxtah r9, r3, r3, ror #24 + +0x13 0xfa 0x89 0xf1 +0x88 0xbf +0x11 0xfa 0x86 0xf6 +0x18 0xfa 0x93 0xf3 +0x38 0xbf +0x12 0xfa 0xa4 0xf2 +0x13 0xfa 0xb3 0xf9 + + +#------------------------------------------------------------------------------ +# UXTB +#------------------------------------------------------------------------------ +# CHECK: it ge +# CHECK: uxtbge r2, r4 +# CHECK: uxtb r5, r6 +# CHECK: uxtb.w r6, r9, ror #8 +# CHECK: it lo +# CHECK: uxtblo.w r5, r1, ror #16 +# CHECK: uxtb.w r8, r3, ror #24 + +0xa8 0xbf +0xe2 0xb2 +0xf5 0xb2 +0x5f 0xfa 0x99 0xf6 +0x38 0xbf +0x5f 0xfa 0xa1 0xf5 +0x5f 0xfa 0xb3 0xf8 + + +#------------------------------------------------------------------------------ +# UXTB16 +#------------------------------------------------------------------------------ +# CHECK: uxtb16 r1, r4 +# CHECK: uxtb16 r6, r7 +# CHECK: it hs +# CHECK: uxtb16hs r3, r5, ror #8 +# CHECK: uxtb16 r3, r1, ror #16 +# CHECK: it ge +# CHECK: uxtb16ge r2, r3, ror #24 + +0x3f 0xfa 0x84 0xf1 +0x3f 0xfa 0x87 0xf6 +0x28 0xbf +0x3f 0xfa 0x95 0xf3 +0x3f 0xfa 0xa1 0xf3 +0xa8 0xbf +0x3f 0xfa 0xb3 0xf2 + + +#------------------------------------------------------------------------------ +# UXTH +#------------------------------------------------------------------------------ +# CHECK: it ne +# CHECK: uxthne.w r3, r9 +# CHECK: uxth r1, r6 +# CHECK: uxth.w r3, r8, ror #8 +# CHECK: it le +# CHECK: uxthle.w r2, r2, ror #16 +# CHECK: uxth.w r9, r3, ror #24 + +0x18 0xbf +0x1f 0xfa 0x89 0xf3 +0xb1 0xb2 +0x1f 0xfa 0x98 0xf3 +0xd8 0xbf +0x1f 0xfa 0xa2 0xf2 +0x1f 0xfa 0xb3 0xf9 + + +#------------------------------------------------------------------------------ +# WFE/WFI/YIELD +#------------------------------------------------------------------------------ +# CHECK: wfe +# CHECK: wfi +# CHECK: yield +# CHECK: itet lt +# CHECK: wfelt +# CHECK: wfige +# CHECK: yieldlt + +0x20 0xbf +0x30 0xbf +0x10 0xbf +0xb6 0xbf +0x20 0xbf +0x30 0xbf +0x10 0xbf + diff --git a/test/MC/Disassembler/X86/enhanced.txt b/test/MC/Disassembler/X86/enhanced.txt index fc6949901b72..752ab179af66 100644 --- a/test/MC/Disassembler/X86/enhanced.txt +++ b/test/MC/Disassembler/X86/enhanced.txt @@ -4,3 +4,7 @@ 0x0f 0x85 0xf6 0xff 0xff 0xff # CHECK: [o:movq][w: ][1-r:%gs=r63][1-p::][1-l:8=8][p:,][w: ][0-r:%rcx=r108] 0:[RCX/108]=0 1:[GS/63]=8 0x65 0x48 0x8b 0x0c 0x25 0x08 0x00 0x00 0x00 +# CHECK: [o:xorps][w: ][2-r:%xmm1=r129][p:,][w: ][0-r:%xmm2=r130] 0:[XMM2/130]=0 1:[XMM2/130]=0 2:[XMM1/129]=0 +0x0f 0x57 0xd1 +# CHECK: [o:andps][w: ][2-r:%xmm1=r129][p:,][w: ][0-r:%xmm2=r130] 0:[XMM2/130]=0 1:[XMM2/130]=0 2:[XMM1/129]=0 +0x0f 0x54 0xd1 diff --git a/test/MC/Disassembler/X86/intel-syntax.txt b/test/MC/Disassembler/X86/intel-syntax.txt new file mode 100644 index 000000000000..54b242d7b2ef --- /dev/null +++ b/test/MC/Disassembler/X86/intel-syntax.txt @@ -0,0 +1,79 @@ +# RUN: llvm-mc --disassemble %s -triple=x86_64-apple-darwin9 -x86-asm-syntax=intel | FileCheck %s + +# CHECK: movsb +0xa4 + +# CHECK: movsw +0x66 0xa5 + +# CHECK: movsd +0xa5 + +# CHECK: movsq +0x48 0xa5 + +# CHECK: pop FS +0x0f 0xa1 + +# CHECK: pop GS +0x0f 0xa9 + +# CHECK: in AL, DX +0xec + +# CHECK: nop +0x90 + +# CHECK: xchg EAX, R8D +0x41 0x90 + +# CHECK: xchg RAX, R8 +0x49 0x90 + +# CHECK: add AL, 0 +0x04 0x00 + +# CHECK: add AX, 0 +0x66 0x05 0x00 0x00 + +# CHECK: add EAX, 0 +0x05 0x00 0x00 0x00 0x00 + +# CHECK: add RAX, 0 +0x48 0x05 0x00 0x00 0x00 0x00 + +# CHECK: adc AL, 0 +0x14 0x00 + +# CHECK: adc AX, 0 +0x66 0x15 0x00 0x00 + +# CHECK: adc EAX, 0 +0x15 0x00 0x00 0x00 0x00 + +# CHECK: adc RAX, 0 +0x48 0x15 0x00 0x00 0x00 0x00 + +# CHECK: cmp AL, 0 +0x3c 0x00 + +# CHECK: cmp AX, 0 +0x66 0x3d 0x00 0x00 + +# CHECK: cmp EAX, 0 +0x3d 0x00 0x00 0x00 0x00 + +# CHECK: cmp RAX, 0 +0x48 0x3d 0x00 0x00 0x00 0x00 + +# CHECK: test AL, 0 +0xa8 0x00 + +# CHECK: test AX, 0 +0x66 0xa9 0x00 0x00 + +# CHECK: test EAX, 0 +0xa9 0x00 0x00 0x00 0x00 + +# CHECK: test RAX, 0 +0x48 0xa9 0x00 0x00 0x00 0x00 diff --git a/test/MC/Disassembler/X86/invalid-VEX-vvvv.txt b/test/MC/Disassembler/X86/invalid-VEX-vvvv.txt new file mode 100644 index 000000000000..9feb54c517e4 --- /dev/null +++ b/test/MC/Disassembler/X86/invalid-VEX-vvvv.txt @@ -0,0 +1,4 @@ +# RUN: llvm-mc --disassemble %s -triple=x86_64-apple-darwin9 |& grep {invalid instruction encoding} + +# This instruction would decode as movmskps if the vvvv field in the VEX prefix was all 1s. +0xc5 0xf0 0x50 0xc0 diff --git a/test/MC/Disassembler/X86/simple-tests.txt b/test/MC/Disassembler/X86/simple-tests.txt index 08fb4c55b385..2dc918cb0dca 100644 --- a/test/MC/Disassembler/X86/simple-tests.txt +++ b/test/MC/Disassembler/X86/simple-tests.txt @@ -72,3 +72,449 @@ # CHECK: vaddps %ymm3, %ymm1, %ymm0 0xc5 0xf4 0x58 0xc3 + +# CHECK: vandpd %ymm13, %ymm1, %ymm0 +0xc4 0xc1 0x75 0x54 0xc5 + +# CHECK: vandps %ymm3, %ymm1, %ymm0 +0xc5 0xf4 0x54 0xc3 + +# CHECK: vzeroall +0xc5 0xfc 0x77 + +# CHECK: vcvtps2pd %xmm0, %ymm0 +0xc5 0xfc 0x5a 0xc0 + +# CHECK: vandps (%rdx), %xmm1, %xmm7 +0xc5 0xf0 0x54 0x3a + +# CHECK: vcvtss2sil %xmm0, %eax +0xc5 0xfa 0x2d 0xc0 + +# CHECK: vcvtsd2si %xmm0, %eax +0xc5 0xfb 0x2d 0xc0 + +# CHECK: vcvtsd2si %xmm0, %rax +0xc4 0xe1 0xfb 0x2d 0xc0 + +# CHECK: vmaskmovpd %xmm0, %xmm1, (%rax) +0xc4 0xe2 0x71 0x2f 0x00 + +# CHECK: vmovapd %xmm0, %xmm2 +0xc5 0xf9 0x28 0xd0 + +# Check X86 immediates print as signed values by default. radr://8795217 +# CHECK: andq $-16, %rsp +0x48 0x83 0xe4 0xf0 + +# Check these special case instructions that the immediate is not sign-extend. +# CHECK: blendps $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x0c 0xca 0x81 + +# CHECK: blendpd $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x0d 0xca 0x81 + +# CHECK: pblendw $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x0e 0xca 0x81 + +# CHECK: mpsadbw $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x42 0xca 0x81 + +# CHECK: dpps $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x40 0xca 0x81 + +# CHECK: dppd $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x41 0xca 0x81 + +# CHECK: insertps $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x21 0xca 0x81 + +# CHECK: vblendps $129, %ymm2, %ymm5, %ymm1 +0xc4 0xe3 0x55 0x0c 0xca 0x81 + +# CHECK: vblendps $129, (%rax), %ymm5, %ymm1 +0xc4 0xe3 0x55 0x0c 0x08 0x81 + +# CHECK: vblendpd $129, %ymm2, %ymm5, %ymm1 +0xc4 0xe3 0x55 0x0d 0xca 0x81 + +# CHECK: vblendpd $129, (%rax), %ymm5, %ymm1 +0xc4 0xe3 0x55 0x0d 0x08 0x81 + +# CHECK: vpblendw $129, %xmm2, %xmm5, %xmm1 +0xc4 0xe3 0x51 0x0e 0xca 0x81 + +# CHECK: vmpsadbw $129, %xmm2, %xmm5, %xmm1 +0xc4 0xe3 0x51 0x42 0xca 0x81 + +# CHECK: vdpps $129, %ymm2, %ymm5, %ymm1 +0xc4 0xe3 0x55 0x40 0xca 0x81 + +# CHECK: vdpps $129, (%rax), %ymm5, %ymm1 +0xc4 0xe3 0x55 0x40 0x08 0x81 + +# CHECK: vdppd $129, %xmm2, %xmm5, %xmm1 +0xc4 0xe3 0x51 0x41 0xca 0x81 + +# CHECK: vinsertps $129, %xmm3, %xmm2, %xmm1 +0xc4 0xe3 0x69 0x21 0xcb 0x81 + +# CHECK: pause +0xf3 0x90 + +# CHECK: addl %eax, %edi +0x01 0xc7 + +# CHECK: addl %edi, %eax +0x03 0xc7 + +# CHECK: movl %eax, %edi +0x89 0xc7 + +# CHECK: movl %edi, %eax +0x8b 0xc7 + +# CHECK: movups %xmm1, %xmm0 +0x0f 0x10 0xc1 + +# CHECK: movups %xmm0, %xmm1 +0x0f 0x11 0xc1 + +# CHECK: movaps %xmm1, %xmm0 +0x0f 0x28 0xc1 + +# CHECK: movaps %xmm0, %xmm1 +0x0f 0x29 0xc1 + +# CHECK: movupd %xmm1, %xmm0 +0x66 0x0f 0x10 0xc1 + +# CHECK: movupd %xmm0, %xmm1 +0x66 0x0f 0x11 0xc1 + +# CHECK: movapd %xmm1, %xmm0 +0x66 0x0f 0x28 0xc1 + +# CHECK: movapd %xmm0, %xmm1 +0x66 0x0f 0x29 0xc1 + +# CHECK: vmovups %xmm1, %xmm0 +0xc5 0xf8 0x10 0xc1 + +# CHECK: vmovups %xmm0, %xmm1 +0xc5 0xf8 0x11 0xc1 + +# CHECK: vmovaps %xmm1, %xmm0 +0xc5 0xf8 0x28 0xc1 + +# CHECK: vmovaps %xmm0, %xmm1 +0xc5 0xf8 0x29 0xc1 + +# CHECK: vmovupd %xmm1, %xmm0 +0xc5 0xf9 0x10 0xc1 + +# CHECK: vmovupd %xmm0, %xmm1 +0xc5 0xf9 0x11 0xc1 + +# CHECK: vmovapd %xmm1, %xmm0 +0xc5 0xf9 0x28 0xc1 + +# CHECK: vmovapd %xmm0, %xmm1 +0xc5 0xf9 0x29 0xc1 + +# CHECK: vmovups %ymm1, %ymm0 +0xc5 0xfc 0x10 0xc1 + +# CHECK: vmovups %ymm0, %ymm1 +0xc5 0xfc 0x11 0xc1 + +# CHECK: vmovaps %ymm1, %ymm0 +0xc5 0xfc 0x28 0xc1 + +# CHECK: vmovaps %ymm0, %ymm1 +0xc5 0xfc 0x29 0xc1 + +# CHECK: movdqa %xmm1, %xmm0 +0x66 0x0f 0x6f 0xc1 + +# CHECK: movdqa %xmm0, %xmm1 +0x66 0x0f 0x7f 0xc1 + +# CHECK: movdqu %xmm1, %xmm0 +0xf3 0x0f 0x6f 0xc1 + +# CHECK: movdqu %xmm0, %xmm1 +0xf3 0x0f 0x7f 0xc1 + +# CHECK: vmovdqa %xmm1, %xmm0 +0xc5 0xf9 0x6f 0xc1 + +# CHECK: vmovdqa %xmm0, %xmm1 +0xc5 0xf9 0x7f 0xc1 + +# CHECK: vmovdqa %ymm1, %ymm0 +0xc5 0xfd 0x6f 0xc1 + +# CHECK: vmovdqa %ymm0, %ymm1 +0xc5 0xfd 0x7f 0xc1 + +# CHECK: vmovdqu %xmm1, %xmm0 +0xc5 0xfa 0x6f 0xc1 + +# CHECK: vmovdqu %xmm0, %xmm1 +0xc5 0xfa 0x7f 0xc1 + +# CHECK: vmovdqu %ymm1, %ymm0 +0xc5 0xfe 0x6f 0xc1 + +# CHECK: vmovdqu %ymm0, %ymm1 +0xc5 0xfe 0x7f 0xc1 + +# CHECK: vblendvps %xmm4, %xmm1, %xmm2, %xmm3 +0xc4 0xe3 0x69 0x4a 0xd9 0x41 + +# CHECK: vroundpd $0, %xmm0, %xmm0 +0xc4 0xe3 0x79 0x09 0xc0 0x00 + +# CHECK: vroundps $0, %xmm0, %xmm0 +0xc4 0xe3 0x79 0x08 0xc0 0x00 + +# CHECK: vroundpd $0, %ymm0, %ymm0 +0xc4 0xe3 0x7d 0x09 0xc0 0x00 + +# CHECK: vroundps $0, %ymm0, %ymm0 +0xc4 0xe3 0x7d 0x08 0xc0 0x00 + +# CHECK: vroundss $0, %xmm0, %xmm0, %xmm0 +0xc4 0xe3 0x79 0x0a 0xc0 0x00 + +# CHECK: vroundsd $0, %xmm0, %xmm0, %xmm0 +0xc4 0xe3 0x79 0x0b 0xc0 0x00 + +# CHECK: crc32b %al, %eax +0xf2 0x0f 0x38 0xf0 0xc0 + +# CHECK: crc32w %ax, %eax +0x66 0xf2 0x0f 0x38 0xf1 0xc0 + +# CHECK: crc32l %eax, %eax +0xf2 0x0f 0x38 0xf1 0xc0 + +# CHECK: crc32q %rax, %rax +0xf2 0x48 0x0f 0x38 0xf1 0xc0 + +# CHECK: invept (%rax), %rax +0x66 0x0f 0x38 0x80 0x00 + +# CHECK: invvpid (%rax), %rax +0x66 0x0f 0x38 0x81 0x00 + +# CHECK: nop +0x90 + +# CHECK: xchgl %r8d, %eax +0x41 0x90 + +# CHECK: xchgq %r8, %rax +0x49 0x90 + +# CHECK: addb $0, %al +0x04 0x00 + +# CHECK: addw $0, %ax +0x66 0x05 0x00 0x00 + +# CHECK: addl $0, %eax +0x05 0x00 0x00 0x00 0x00 + +# CHECK: addq $0, %rax +0x48 0x05 0x00 0x00 0x00 0x00 + +# CHECK: adcb $0, %al +0x14 0x00 + +# CHECK: adcw $0, %ax +0x66 0x15 0x00 0x00 + +# CHECK: adcl $0, %eax +0x15 0x00 0x00 0x00 0x00 + +# CHECK: adcq $0, %rax +0x48 0x15 0x00 0x00 0x00 0x00 + +# CHECK: cmpb $0, %al +0x3c 0x00 + +# CHECK: cmpw $0, %ax +0x66 0x3d 0x00 0x00 + +# CHECK: cmpl $0, %eax +0x3d 0x00 0x00 0x00 0x00 + +# CHECK: cmpq $0, %rax +0x48 0x3d 0x00 0x00 0x00 0x00 + +# CHECK: testb $0, %al +0xa8 0x00 + +# CHECK: testw $0, %ax +0x66 0xa9 0x00 0x00 + +# CHECK: testl $0, %eax +0xa9 0x00 0x00 0x00 0x00 + +# CHECK: testq $0, %rax +0x48 0xa9 0x00 0x00 0x00 0x00 + +# CHECK: vaddps %xmm3, %xmm15, %xmm0 +0xc4 0xe1 0x00 0x58 0xc3 + +# CHECK: movbel (%rax), %eax +0x0f 0x38 0xf0 0x00 + +# CHECK: movbel %eax, (%rax) +0x0f 0x38 0xf1 0x00 + +# CHECK: movbew (%rax), %ax +0x66 0x0f 0x38 0xf0 0x00 + +# CHECK: movbew %ax, (%rax) +0x66 0x0f 0x38 0xf1 0x00 + +# CHECK: movbeq (%rax), %rax +0x48 0x0f 0x38 0xf0 0x00 + +# CHECK: movbeq %rax, (%rax) +0x48 0x0f 0x38 0xf1 0x00 + +# CHECK: rdrandw %ax +0x66 0x0f 0xc7 0xf0 + +# CHECK: rdrandl %eax +0x0f 0xc7 0xf0 + +# CHECK: rdrandq %rax +0x48 0x0f 0xc7 0xf0 + +# CHECK: vroundss $0, %xmm0, %xmm0, %xmm0 +0xc4 0xe3 0x7d 0x0a 0xc0 0x00 + +# CHECK: vroundsd $0, %xmm0, %xmm0, %xmm0 +0xc4 0xe3 0x7d 0x0b 0xc0 0x00 + +# CHECK: vcvtsd2si %xmm0, %eax +0xc4 0xe1 0x7f 0x2d 0xc0 + +# CHECK: vcvtsd2si %xmm0, %rax +0xc4 0xe1 0xff 0x2d 0xc0 + +# CHECK: vucomisd %xmm1, %xmm0 +0xc5 0xfd 0x2e 0xc1 + +# CHECK: vucomiss %xmm1, %xmm0 +0xc5 0xfc 0x2e 0xc1 + +# CHECK: vcomisd %xmm1, %xmm0 +0xc5 0xfd 0x2f 0xc1 + +# CHECK: vcomiss %xmm1, %xmm0 +0xc5 0xfc 0x2f 0xc1 + +# CHECK: vaddss %xmm1, %xmm0, %xmm0 +0xc5 0xfe 0x58 0xc1 + +# CHECK: xsave (%rax) +0x0f 0xae 0x20 + +# CHECK: xrstor (%rax) +0x0f 0xae 0x28 + +# CHECK: xsaveopt (%rax) +0x0f 0xae 0x30 + +# CHECK: rdfsbasel %eax +0xf3 0x0f 0xae 0xc0 + +# CHECK: rdgsbasel %eax +0xf3 0x0f 0xae 0xc8 + +# CHECK: wrfsbasel %eax +0xf3 0x0f 0xae 0xd0 + +# CHECK: wrgsbasel %eax +0xf3 0x0f 0xae 0xd8 + +# CHECK: rdfsbaseq %rax +0xf3 0x48 0x0f 0xae 0xc0 + +# CHECK: rdgsbaseq %rax +0xf3 0x48 0x0f 0xae 0xc8 + +# CHECK: wrfsbaseq %rax +0xf3 0x48 0x0f 0xae 0xd0 + +# CHECK: wrgsbaseq %rax +0xf3 0x48 0x0f 0xae 0xd8 + +# CHECK: vcvtph2ps %xmm0, %xmm0 +0xc4 0xe2 0x79 0x13 0xc0 + +# CHECK: vcvtph2ps (%rax), %xmm0 +0xc4 0xe2 0x79 0x13 0x00 + +# CHECK: vcvtph2ps %xmm0, %ymm0 +0xc4 0xe2 0x7d 0x13 0xc0 + +# CHECK: vcvtph2ps (%rax), %ymm0 +0xc4 0xe2 0x7d 0x13 0x00 + +# CHECK: vcvtps2ph $0, %xmm0, %xmm0 +0xc4 0xe3 0x79 0x1d 0xc0 0x00 + +# CHECK: vcvtps2ph $0, %xmm0, (%rax) +0xc4 0xe3 0x79 0x1d 0x00 0x00 + +# CHECK: vcvtps2ph $0, %ymm0, %xmm0 +0xc4 0xe3 0x7d 0x1d 0xc0 0x00 + +# CHECK: vcvtps2ph $0, %ymm0, (%rax) +0xc4 0xe3 0x7d 0x1d 0x00 0x00 + +# CHECK: popcntl %eax, %eax +0xf3 0x0f 0xb8 0xc0 + +# CHECK: popcntw %ax, %ax +0x66 0xf3 0x0f 0xb8 0xc0 + +# CHECK: popcntq %rax, %rax +0xf3 0x48 0x0f 0xb8 0xc0 + +# CHECK: lzcntl %eax, %eax +0xf3 0x0f 0xbd 0xc0 + +# CHECK: lzcntw %ax, %ax +0x66 0xf3 0x0f 0xbd 0xc0 + +# CHECK: lzcntq %rax, %rax +0xf3 0x48 0x0f 0xbd 0xc0 + +# CHECK: tzcntl %eax, %eax +0xf3 0x0f 0xbc 0xc0 + +# CHECK: tzcntw %ax, %ax +0x66 0xf3 0x0f 0xbc 0xc0 + +# CHECK: tzcntq %rax, %rax +0xf3 0x48 0x0f 0xbc 0xc0 + +# CHECK: andnl %ecx, %r15d, %eax +0xc4 0xe2 0x00 0xf2 0xc1 + +# CHECK: andnq %rax, %r15, %rax +0xc4 0xe2 0x80 0xf2 0xc0 + +# CHECK: andnl (%rax), %r15d, %eax +0xc4 0xe2 0x00 0xf2 0x00 + +# CHECK: andnq (%rax), %r15, %rax +0xc4 0xe2 0x80 0xf2 0x00 diff --git a/test/MC/Disassembler/X86/x86-32.txt b/test/MC/Disassembler/X86/x86-32.txt index dd313f158108..c4437ba35d74 100644 --- a/test/MC/Disassembler/X86/x86-32.txt +++ b/test/MC/Disassembler/X86/x86-32.txt @@ -24,3 +24,474 @@ # CHECK: pshufb 0x0f 0x38 0x00 0xc0 + +# CHECK: crc32b %al, %eax +0xf2 0x0f 0x38 0xf0 0xc0 + +# CHECK: crc32w %ax, %eax +0x66 0xf2 0x0f 0x38 0xf1 0xc0 + +# CHECK: crc32l %eax, %eax +0xf2 0x0f 0x38 0xf1 0xc0 + + +# CHECK: int $33 +0xCD 0x21 + +# CHECK: int $33 +0xCD 0x21 + + +# CHECK: addb %al, (%eax) +0 0 + +# CHECK: calll -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 + +# CHECK: vmxon +0xf3 0x0f 0xc7 0x30 + +# CHECK: vmptrld +0x0f 0xc7 0x30 + +# CHECK: vmptrst +0x0f 0xc7 0x38 + +# CHECK: movl $0, -4(%ebp) +0xc7 0x45 0xfc 0x00 0x00 0x00 0x00 + +# CHECK: movl %cr0, %ecx +0x0f 0x20 0xc1 + +# CHECK: leal 4(%esp), %ecx +0x8d 0x4c 0x24 0x04 + +# CHECK: enter $1, $2 +0xc8 0x01 0x00 0x02 + +# CHECK: movw $47416, -66(%ebp) +0x66 0xc7 0x45 0xbe 0x38 0xb9 + +# CHECK: vaddpd %ymm5, %ymm1, %ymm0 +0xc4 0xc1 0x75 0x58 0xc5 + +# CHECK: vaddps %ymm3, %ymm1, %ymm0 +0xc5 0xf4 0x58 0xc3 + +# CHECK: vandpd %ymm5, %ymm1, %ymm0 +0xc4 0xc1 0x75 0x54 0xc5 + +# CHECK: vandps %ymm3, %ymm1, %ymm0 +0xc5 0xf4 0x54 0xc3 + +# CHECK: vzeroall +0xc5 0xfc 0x77 + +# CHECK: vcvtps2pd %xmm0, %ymm0 +0xc5 0xfc 0x5a 0xc0 + +# CHECK: vandps (%edx), %xmm1, %xmm7 +0xc5 0xf0 0x54 0x3a + +# CHECK: vcvtss2sil %xmm0, %eax +0xc5 0xfa 0x2d 0xc0 + +# CHECK: vcvtsd2si %xmm0, %eax +0xc5 0xfb 0x2d 0xc0 + +# CHECK: vcvtsd2si %xmm0, %eax +0xc4 0xe1 0x7b 0x2d 0xc0 + +# CHECK: vmaskmovpd %xmm0, %xmm1, (%eax) +0xc4 0xe2 0x71 0x2f 0x00 + +# CHECK: vmovapd %xmm0, %xmm2 +0xc5 0xf9 0x28 0xd0 + +# Check these special case instructions that the immediate is not sign-extend. +# CHECK: blendps $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x0c 0xca 0x81 + +# CHECK: blendpd $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x0d 0xca 0x81 + +# CHECK: pblendw $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x0e 0xca 0x81 + +# CHECK: mpsadbw $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x42 0xca 0x81 + +# CHECK: dpps $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x40 0xca 0x81 + +# CHECK: dppd $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x41 0xca 0x81 + +# CHECK: insertps $129, %xmm2, %xmm1 +0x66 0x0f 0x3a 0x21 0xca 0x81 + +# CHECK: vblendps $129, %ymm2, %ymm5, %ymm1 +0xc4 0xe3 0x55 0x0c 0xca 0x81 + +# CHECK: vblendps $129, (%eax), %ymm5, %ymm1 +0xc4 0xe3 0x55 0x0c 0x08 0x81 + +# CHECK: vblendpd $129, %ymm2, %ymm5, %ymm1 +0xc4 0xe3 0x55 0x0d 0xca 0x81 + +# CHECK: vblendpd $129, (%eax), %ymm5, %ymm1 +0xc4 0xe3 0x55 0x0d 0x08 0x81 + +# CHECK: vpblendw $129, %xmm2, %xmm5, %xmm1 +0xc4 0xe3 0x51 0x0e 0xca 0x81 + +# CHECK: vmpsadbw $129, %xmm2, %xmm5, %xmm1 +0xc4 0xe3 0x51 0x42 0xca 0x81 + +# CHECK: vdpps $129, %ymm2, %ymm5, %ymm1 +0xc4 0xe3 0x55 0x40 0xca 0x81 + +# CHECK: vdpps $129, (%eax), %ymm5, %ymm1 +0xc4 0xe3 0x55 0x40 0x08 0x81 + +# CHECK: vdppd $129, %xmm2, %xmm5, %xmm1 +0xc4 0xe3 0x51 0x41 0xca 0x81 + +# CHECK: vinsertps $129, %xmm3, %xmm2, %xmm1 +0xc4 0xe3 0x69 0x21 0xcb 0x81 + +# CHECK: pause +0xf3 0x90 + +# CHECK: addl %eax, %edi +0x01 0xc7 + +# CHECK: addl %edi, %eax +0x03 0xc7 + +# CHECK: movl %eax, %edi +0x89 0xc7 + +# CHECK: movl %edi, %eax +0x8b 0xc7 + +# CHECK: movups %xmm1, %xmm0 +0x0f 0x10 0xc1 + +# CHECK: movups %xmm0, %xmm1 +0x0f 0x11 0xc1 + +# CHECK: movaps %xmm1, %xmm0 +0x0f 0x28 0xc1 + +# CHECK: movaps %xmm0, %xmm1 +0x0f 0x29 0xc1 + +# CHECK: movupd %xmm1, %xmm0 +0x66 0x0f 0x10 0xc1 + +# CHECK: movupd %xmm0, %xmm1 +0x66 0x0f 0x11 0xc1 + +# CHECK: movapd %xmm1, %xmm0 +0x66 0x0f 0x28 0xc1 + +# CHECK: movapd %xmm0, %xmm1 +0x66 0x0f 0x29 0xc1 + +# CHECK: vmovups %xmm1, %xmm0 +0xc5 0xf8 0x10 0xc1 + +# CHECK: vmovups %xmm0, %xmm1 +0xc5 0xf8 0x11 0xc1 + +# CHECK: vmovaps %xmm1, %xmm0 +0xc5 0xf8 0x28 0xc1 + +# CHECK: vmovaps %xmm0, %xmm1 +0xc5 0xf8 0x29 0xc1 + +# CHECK: vmovupd %xmm1, %xmm0 +0xc5 0xf9 0x10 0xc1 + +# CHECK: vmovupd %xmm0, %xmm1 +0xc5 0xf9 0x11 0xc1 + +# CHECK: vmovapd %xmm1, %xmm0 +0xc5 0xf9 0x28 0xc1 + +# CHECK: vmovapd %xmm0, %xmm1 +0xc5 0xf9 0x29 0xc1 + +# CHECK: vmovups %ymm1, %ymm0 +0xc5 0xfc 0x10 0xc1 + +# CHECK: vmovups %ymm0, %ymm1 +0xc5 0xfc 0x11 0xc1 + +# CHECK: vmovaps %ymm1, %ymm0 +0xc5 0xfc 0x28 0xc1 + +# CHECK: vmovaps %ymm0, %ymm1 +0xc5 0xfc 0x29 0xc1 + +# CHECK: movdqa %xmm1, %xmm0 +0x66 0x0f 0x6f 0xc1 + +# CHECK: movdqa %xmm0, %xmm1 +0x66 0x0f 0x7f 0xc1 + +# CHECK: movdqu %xmm1, %xmm0 +0xf3 0x0f 0x6f 0xc1 + +# CHECK: movdqu %xmm0, %xmm1 +0xf3 0x0f 0x7f 0xc1 + +# CHECK: vmovdqa %xmm1, %xmm0 +0xc5 0xf9 0x6f 0xc1 + +# CHECK: vmovdqa %xmm0, %xmm1 +0xc5 0xf9 0x7f 0xc1 + +# CHECK: vmovdqa %ymm1, %ymm0 +0xc5 0xfd 0x6f 0xc1 + +# CHECK: vmovdqa %ymm0, %ymm1 +0xc5 0xfd 0x7f 0xc1 + +# CHECK: vmovdqu %xmm1, %xmm0 +0xc5 0xfa 0x6f 0xc1 + +# CHECK: vmovdqu %xmm0, %xmm1 +0xc5 0xfa 0x7f 0xc1 + +# CHECK: vmovdqu %ymm1, %ymm0 +0xc5 0xfe 0x6f 0xc1 + +# CHECK: vmovdqu %ymm0, %ymm1 +0xc5 0xfe 0x7f 0xc1 + +# CHECK: vblendvps %xmm4, %xmm1, %xmm2, %xmm3 +0xc4 0xe3 0x69 0x4a 0xd9 0x41 + +# CHECK: vroundpd $0, %xmm0, %xmm0 +0xc4 0xe3 0x79 0x09 0xc0 0x00 + +# CHECK: vroundps $0, %xmm0, %xmm0 +0xc4 0xe3 0x79 0x08 0xc0 0x00 + +# CHECK: vroundpd $0, %ymm0, %ymm0 +0xc4 0xe3 0x7d 0x09 0xc0 0x00 + +# CHECK: vroundps $0, %ymm0, %ymm0 +0xc4 0xe3 0x7d 0x08 0xc0 0x00 + +# CHECK: vroundss $0, %xmm0, %xmm0, %xmm0 +0xc4 0xe3 0x79 0x0a 0xc0 0x00 + +# CHECK: vroundsd $0, %xmm0, %xmm0, %xmm0 +0xc4 0xe3 0x79 0x0b 0xc0 0x00 + +# CHECK: invept (%eax), %eax +0x66 0x0f 0x38 0x80 0x00 + +# CHECK: invvpid (%eax), %eax +0x66 0x0f 0x38 0x81 0x00 + +# CHECK: nop +0x90 + +# CHECK: addb $0, %al +0x04 0x00 + +# CHECK: addw $0, %ax +0x66 0x05 0x00 0x00 + +# CHECK: addl $0, %eax +0x05 0x00 0x00 0x00 0x00 + +# CHECK: adcb $0, %al +0x14 0x00 + +# CHECK: adcw $0, %ax +0x66 0x15 0x00 0x00 + +# CHECK: adcl $0, %eax +0x15 0x00 0x00 0x00 0x00 + +# CHECK: cmpb $0, %al +0x3c 0x00 + +# CHECK: cmpw $0, %ax +0x66 0x3d 0x00 0x00 + +# CHECK: cmpl $0, %eax +0x3d 0x00 0x00 0x00 0x00 + +# CHECK: testb $0, %al +0xa8 0x00 + +# CHECK: testw $0, %ax +0x66 0xa9 0x00 0x00 + +# CHECK: testl $0, %eax +0xa9 0x00 0x00 0x00 0x00 + +# CHECK: movb 0, %al +0xa0 0x00 0x00 0x00 0x00 + +# CHECK: movw 0, %ax +0x66 0xa1 0x00 0x00 0x00 0x00 + +# CHECK: movl 0, %eax +0xa1 0x00 0x00 0x00 0x00 + +# CHECK: movb %al, 0 +0xa2 0x00 0x00 0x00 0x00 + +# CHECK: movw %ax, 0 +0x66 0xa3 0x00 0x00 0x00 0x00 + +# CHECK: movl %eax, 0 +0xa3 0x00 0x00 0x00 0x00 + +# CHECK: vaddps %xmm3, %xmm7, %xmm0 +0xc4 0xe1 0x00 0x58 0xc3 + +# CHECK: movbel (%eax), %eax +0x0f 0x38 0xf0 0x00 + +# CHECK: movbel %eax, (%eax) +0x0f 0x38 0xf1 0x00 + +# CHECK: movbew (%eax), %ax +0x66 0x0f 0x38 0xf0 0x00 + +# CHECK: movbew %ax, (%eax) +0x66 0x0f 0x38 0xf1 0x00 + +# CHECK: rdrandw %ax +0x66 0x0f 0xc7 0xf0 + +# CHECK: rdrandl %eax +0x0f 0xc7 0xf0 + +# CHECK: vroundss $0, %xmm0, %xmm0, %xmm0 +0xc4 0xe3 0x7d 0x0a 0xc0 0x00 + +# CHECK: vroundsd $0, %xmm0, %xmm0, %xmm0 +0xc4 0xe3 0x7d 0x0b 0xc0 0x00 + +# CHECK: vcvtsd2si %xmm0, %eax +0xc4 0xe1 0x7f 0x2d 0xc0 + +# CHECK: vcvtsd2si %xmm0, %eax +0xc4 0xe1 0xff 0x2d 0xc0 + +# CHECK: vucomisd %xmm1, %xmm0 +0xc5 0xfd 0x2e 0xc1 + +# CHECK: vucomiss %xmm1, %xmm0 +0xc5 0xfc 0x2e 0xc1 + +# CHECK: vcomisd %xmm1, %xmm0 +0xc5 0xfd 0x2f 0xc1 + +# CHECK: vcomiss %xmm1, %xmm0 +0xc5 0xfc 0x2f 0xc1 + +# CHECK: vaddss %xmm1, %xmm0, %xmm0 +0xc5 0xfe 0x58 0xc1 + +# CHECK: xsave (%eax) +0x0f 0xae 0x20 + +# CHECK: xrstor (%eax) +0x0f 0xae 0x28 + +# CHECK: xsaveopt (%eax) +0x0f 0xae 0x30 + +# CHECK: vcvtph2ps %xmm0, %xmm0 +0xc4 0xe2 0x79 0x13 0xc0 + +# CHECK: vcvtph2ps (%eax), %xmm0 +0xc4 0xe2 0x79 0x13 0x00 + +# CHECK: vcvtph2ps %xmm0, %ymm0 +0xc4 0xe2 0x7d 0x13 0xc0 + +# CHECK: vcvtph2ps (%eax), %ymm0 +0xc4 0xe2 0x7d 0x13 0x00 + +# CHECK: vcvtps2ph $0, %xmm0, %xmm0 +0xc4 0xe3 0x79 0x1d 0xc0 0x00 + +# CHECK: vcvtps2ph $0, %xmm0, (%eax) +0xc4 0xe3 0x79 0x1d 0x00 0x00 + +# CHECK: vcvtps2ph $0, %ymm0, %xmm0 +0xc4 0xe3 0x7d 0x1d 0xc0 0x00 + +# CHECK: vcvtps2ph $0, %ymm0, (%eax) +0xc4 0xe3 0x7d 0x1d 0x00 0x00 + +# CHECK: popcntl %eax, %eax +0xf3 0x0f 0xb8 0xc0 + +# CHECK: popcntw %ax, %ax +0x66 0xf3 0x0f 0xb8 0xc0 + +# CHECK: lzcntl %eax, %eax +0xf3 0x0f 0xbd 0xc0 + +# CHECK: lzcntw %ax, %ax +0x66 0xf3 0x0f 0xbd 0xc0 + +# CHECK: tzcntl %eax, %eax +0xf3 0x0f 0xbc 0xc0 + +# CHECK: tzcntw %ax, %ax +0x66 0xf3 0x0f 0xbc 0xc0 + +# CHECK: andnl %ecx, %edi, %eax +0xc4 0xe2 0x00 0xf2 0xc1 + +# CHECK: andnl (%eax), %edi, %eax +0xc4 0xe2 0x00 0xf2 0x00 + +# CHECK: andnl %ecx, %edi, %eax +0xc4 0xe2 0x80 0xf2 0xc1 + +# CHECK: andnl (%eax), %edi, %eax +0xc4 0xe2 0x80 0xf2 0x00 diff --git a/test/MC/ELF/abs.s b/test/MC/ELF/abs.s index c598b11e291d..48dbe3dffcc5 100644 --- a/test/MC/ELF/abs.s +++ b/test/MC/ELF/abs.s @@ -6,11 +6,11 @@ .Lbar: zed = .Lfoo - .Lbar -// CHECK: # Symbol 0x00000001 +// CHECK: # Symbol 1 // CHECK-NEXT: (('st_name', 0x00000001) # 'zed' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x0000fff1) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0xfff1) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) diff --git a/test/MC/ELF/alias-reloc.s b/test/MC/ELF/alias-reloc.s index 67266d652064..f0db81592e78 100644 --- a/test/MC/ELF/alias-reloc.s +++ b/test/MC/ELF/alias-reloc.s @@ -17,36 +17,36 @@ foo2: .set bar2,foo2 .quad bar2 -// CHECK: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000001) +// CHECK: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000001) // CHECK-NEXT: ('r_sym', 0x00000001) // CHECK-NEXT: ('r_type', 0x00000004) -// CHECK-NEXT: ('r_addend', 0xfffffffc) +// CHECK-NEXT: ('r_addend', 0xfffffffffffffffc) // CHECK-NEXT: ), -// CHECK: # Relocation 0x00000001 -// CHECK-NEXT: (('r_offset', 0x00000005) +// CHECK: # Relocation 1 +// CHECK-NEXT: (('r_offset', 0x0000000000000005) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x00000001) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK: # Symbol 0x00000001 +// CHECK: # Symbol 1 // CHECK-NEXT: (('st_name', 0x00000005) # 'bar' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK: # Symbol 0x00000006 +// CHECK: # Symbol 6 // CHECK-NEXT: (('st_name', 0x0000000e) # 'bar2' -// CHECK-NEXT: ('st_bind', 0x00000002) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000004) +// CHECK-NEXT: ('st_bind', 0x2) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0004) // CHECK-NEXT: ('st_value', 0x0000000000000005) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/alias.s b/test/MC/ELF/alias.s index 42d54bc431dc..f38262801353 100644 --- a/test/MC/ELF/alias.s +++ b/test/MC/ELF/alias.s @@ -16,70 +16,70 @@ foo4: bar4 = foo4 .long foo2 -// CHECK: # Symbol 0x00000001 +// CHECK: # Symbol 1 // CHECK-NEXT: (('st_name', 0x00000005) # 'bar' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000002 +// CHECK-NEXT: # Symbol 2 // CHECK-NEXT: (('st_name', 0x0000001d) # 'bar4' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000002) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x2) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000003 +// CHECK-NEXT: # Symbol 3 // CHECK-NEXT: (('st_name', 0x00000001) # 'foo' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000004 +// CHECK-NEXT: # Symbol 4 // CHECK-NEXT: (('st_name', 0x0000000e) # 'foo3' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000005 +// CHECK-NEXT: # Symbol 5 // CHECK-NEXT: (('st_name', 0x00000018) # 'foo4' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000002) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x2) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000006 +// CHECK-NEXT: # Symbol 6 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK: # Symbol 0x00000007 +// CHECK: # Symbol 7 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK: # Symbol 0x00000008 +// CHECK: # Symbol 8 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK: # Symbol 0x00000009 +// CHECK: # Symbol 9 // CHECK-NEXT: (('st_name', 0x00000013) # 'bar3' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) -// CHECK: # Symbol 0x0000000a +// CHECK: # Symbol 10 // CHECK-NEXT: (('st_name', 0x00000009) # 'bar2' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) diff --git a/test/MC/ELF/align-bss.s b/test/MC/ELF/align-bss.s index ca6da9184e8e..a59232b812a4 100644 --- a/test/MC/ELF/align-bss.s +++ b/test/MC/ELF/align-bss.s @@ -7,11 +7,11 @@ // CHECK: ('sh_name', 0x00000007) # '.bss' // CHECK-NEXT: ('sh_type', 0x00000008) -// CHECK-NEXT: ('sh_flags', 0x00000003) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x00000800) +// CHECK-NEXT: ('sh_flags', 0x0000000000000003) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x0000000000000800) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000010) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000010) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) diff --git a/test/MC/ELF/align-nops.s b/test/MC/ELF/align-nops.s index d29cb5b5e316..3bf96e956a93 100644 --- a/test/MC/ELF/align-nops.s +++ b/test/MC/ELF/align-nops.s @@ -17,24 +17,24 @@ f0: // CHECK: (('sh_name', 0x00000001) # '.text' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000006) +// CHECK-NEXT: ('sh_flags', 0x0000000000000006) // CHECK-NEXT: ('sh_addr', // CHECK-NEXT: ('sh_offset', -// CHECK-NEXT: ('sh_size', 0x00000010) +// CHECK-NEXT: ('sh_size', 0x0000000000000010) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '00000000 0f1f4000 00000000 0f1f4000') // CHECK: (('sh_name', 0x00000026) # '.data' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000003) +// CHECK-NEXT: ('sh_flags', 0x0000000000000003) // CHECK-NEXT: ('sh_addr', // CHECK-NEXT: ('sh_offset', -// CHECK-NEXT: ('sh_size', 0x00000010) +// CHECK-NEXT: ('sh_size', 0x0000000000000010) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '00000000 90909090 00000000 00000000') diff --git a/test/MC/ELF/align-size.s b/test/MC/ELF/align-size.s index 85331d7ae915..f6282910db07 100644 --- a/test/MC/ELF/align-size.s +++ b/test/MC/ELF/align-size.s @@ -7,7 +7,7 @@ // CHECK: (('sh_name', 0x00000001) # '.text' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000006) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x00000008) +// CHECK-NEXT: ('sh_flags', 0x0000000000000006) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x0000000000000008) diff --git a/test/MC/ELF/align-text.s b/test/MC/ELF/align-text.s index 1d2dacb3a067..2fd3cba50231 100644 --- a/test/MC/ELF/align-text.s +++ b/test/MC/ELF/align-text.s @@ -8,12 +8,12 @@ // CHECK: (('sh_name', 0x00000001) # '.text' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000006) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x00000002) +// CHECK-NEXT: ('sh_flags', 0x0000000000000006) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x0000000000000002) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/align.s b/test/MC/ELF/align.s index c1e7086b8e60..3142ffb55351 100644 --- a/test/MC/ELF/align.s +++ b/test/MC/ELF/align.s @@ -7,26 +7,26 @@ .section .rodata,"a",@progbits .align 8 -// CHECK: # Section 0x00000003 +// CHECK: # Section 3 // CHECK-NEXT: (('sh_name', 0x00000007) # '.bss' // CHECK-NEXT: ('sh_type', 0x00000008) -// CHECK-NEXT: ('sh_flags', 0x00000003) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000044) -// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000003) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000044) +// CHECK-NEXT: ('sh_size', 0x0000000000000000) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Section 0x00000004 +// CHECK-NEXT: # Section 4 // CHECK-NEXT: (('sh_name', 0x00000026) # '.rodata' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000048) -// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000048) +// CHECK-NEXT: ('sh_size', 0x0000000000000000) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) diff --git a/test/MC/ELF/basic-elf-32.s b/test/MC/ELF/basic-elf-32.s index 7c2927ad79b5..2c6a9841956c 100644 --- a/test/MC/ELF/basic-elf-32.s +++ b/test/MC/ELF/basic-elf-32.s @@ -30,9 +30,9 @@ main: # @main .section .note.GNU-stack,"",@progbits -// CHECK: ('e_indent[EI_CLASS]', 0x00000001) -// CHECK: ('e_indent[EI_DATA]', 0x00000001) -// CHECK: ('e_indent[EI_VERSION]', 0x00000001) +// CHECK: ('e_indent[EI_CLASS]', 0x01) +// CHECK: ('e_indent[EI_DATA]', 0x01) +// CHECK: ('e_indent[EI_VERSION]', 0x01) // CHECK: ('_sections', [ // CHECK: # Section 0 // CHECK: (('sh_name', 0x00000000) # '' @@ -42,37 +42,37 @@ main: # @main // CHECK: # '.rel.text' // CHECK: ('_relocations', [ -// CHECK: # Relocation 0x00000000 +// CHECK: # Relocation 0 // CHECK: (('r_offset', 0x00000006) -// CHECK: ('r_type', 0x00000001) +// CHECK: ('r_type', 0x01) // CHECK: ), -// CHECK: # Relocation 0x00000001 +// CHECK: # Relocation 1 // CHECK: (('r_offset', 0x0000000b) -// CHECK: ('r_type', 0x00000002) +// CHECK: ('r_type', 0x02) // CHECK: ), -// CHECK: # Relocation 0x00000002 +// CHECK: # Relocation 2 // CHECK: (('r_offset', 0x00000012) -// CHECK: ('r_type', 0x00000001) +// CHECK: ('r_type', 0x01) // CHECK: ), -// CHECK: # Relocation 0x00000003 +// CHECK: # Relocation 3 // CHECK: (('r_offset', 0x00000017) -// CHECK: ('r_type', 0x00000002) +// CHECK: ('r_type', 0x02) // CHECK: ), // CHECK: ]) -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) +// CHECK: ('st_bind', 0x0) +// CHECK: ('st_type', 0x3) -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) +// CHECK: ('st_bind', 0x0) +// CHECK: ('st_type', 0x3) -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) +// CHECK: ('st_bind', 0x0) +// CHECK: ('st_type', 0x3) // CHECK: # 'main' -// CHECK: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000002) +// CHECK: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x2) // CHECK: # 'puts' -// CHECK: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) +// CHECK: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) diff --git a/test/MC/ELF/basic-elf-64.s b/test/MC/ELF/basic-elf-64.s index 5ae1f4516639..38ffaa724acc 100644 --- a/test/MC/ELF/basic-elf-64.s +++ b/test/MC/ELF/basic-elf-64.s @@ -30,9 +30,9 @@ main: # @main .section .note.GNU-stack,"",@progbits -// CHECK: ('e_indent[EI_CLASS]', 0x00000002) -// CHECK: ('e_indent[EI_DATA]', 0x00000001) -// CHECK: ('e_indent[EI_VERSION]', 0x00000001) +// CHECK: ('e_indent[EI_CLASS]', 0x02) +// CHECK: ('e_indent[EI_DATA]', 0x01) +// CHECK: ('e_indent[EI_VERSION]', 0x01) // CHECK: ('_sections', [ // CHECK: # Section 0 // CHECK: (('sh_name', 0x00000000) # '' @@ -42,41 +42,41 @@ main: # @main // CHECK: # '.rela.text' // CHECK: ('_relocations', [ -// CHECK: # Relocation 0x00000000 -// CHECK: (('r_offset', 0x00000005) +// CHECK: # Relocation 0 +// CHECK: (('r_offset', 0x0000000000000005) // CHECK: ('r_type', 0x0000000a) -// CHECK: ('r_addend', 0x00000000) +// CHECK: ('r_addend', 0x0000000000000000) // CHECK: ), -// CHECK: # Relocation 0x00000001 -// CHECK: (('r_offset', 0x0000000a) +// CHECK: # Relocation 1 +// CHECK: (('r_offset', 0x000000000000000a) // CHECK: ('r_type', 0x00000002) -// CHECK: ('r_addend', 0xfffffffc) +// CHECK: ('r_addend', 0xfffffffffffffffc) // CHECK: ), -// CHECK: # Relocation 0x00000002 -// CHECK: (('r_offset', 0x0000000f) +// CHECK: # Relocation 2 +// CHECK: (('r_offset', 0x000000000000000f) // CHECK: ('r_type', 0x0000000a) -// CHECK: ('r_addend', 0x00000006) +// CHECK: ('r_addend', 0x0000000000000006) // CHECK: ), -// CHECK: # Relocation 0x00000003 -// CHECK: (('r_offset', 0x00000014) +// CHECK: # Relocation 3 +// CHECK: (('r_offset', 0x0000000000000014) // CHECK: ('r_type', 0x00000002) -// CHECK: ('r_addend', 0xfffffffc) +// CHECK: ('r_addend', 0xfffffffffffffffc) // CHECK: ), // CHECK: ]) -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) +// CHECK: ('st_bind', 0x0) +// CHECK: ('st_type', 0x3) -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) +// CHECK: ('st_bind', 0x0) +// CHECK: ('st_type', 0x3) -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) +// CHECK: ('st_bind', 0x0) +// CHECK: ('st_type', 0x3) // CHECK: # 'main' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000002) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x2) // CHECK: # 'puts' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) diff --git a/test/MC/ELF/call-abs.s b/test/MC/ELF/call-abs.s index 885c2d19bad2..795a65993c0d 100644 --- a/test/MC/ELF/call-abs.s +++ b/test/MC/ELF/call-abs.s @@ -16,9 +16,9 @@ f: # @f .section .note.GNU-stack,"",@progbits // CHECK: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: # Relocation 0 // CHECK-NEXT: (('r_offset', 0x00000004) -// CHECK-NEXT: ('r_sym', 0x00000000) -// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_sym', 0x000000) +// CHECK-NEXT: ('r_type', 0x02) // CHECK-NEXT: ), // CHECK-NEXT: ]) diff --git a/test/MC/ELF/cfi-adjust-cfa-offset.s b/test/MC/ELF/cfi-adjust-cfa-offset.s index 5c1a9f9d8b78..f0d9c5fe23ee 100644 --- a/test/MC/ELF/cfi-adjust-cfa-offset.s +++ b/test/MC/ELF/cfi-adjust-cfa-offset.s @@ -11,36 +11,36 @@ f: ret .cfi_endproc -// CHECK: # Section 0x00000004 +// CHECK: # Section 4 // CHECK-NEXT: (('sh_name', 0x00000011) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000050) -// CHECK-NEXT: ('sh_size', 0x00000038) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000050) +// CHECK-NEXT: ('sh_size', 0x0000000000000038) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 1c000000 1c000000 00000000 0a000000 00440e10 410e1444 0e080000 00000000') // CHECK-NEXT: ), -// CHECK-NEXT: # Section 0x00000005 +// CHECK-NEXT: # Section 5 // CHECK-NEXT: (('sh_name', 0x0000000c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x000003a0) -// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x00000000000003a0) +// CHECK-NEXT: ('sh_size', 0x0000000000000018) // CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/cfi-advance-loc2.s b/test/MC/ELF/cfi-advance-loc2.s index 163e81022dde..b3c08e0a0ec0 100644 --- a/test/MC/ELF/cfi-advance-loc2.s +++ b/test/MC/ELF/cfi-advance-loc2.s @@ -12,34 +12,34 @@ f: // CHECK: (('sh_name', 0x00000011) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000148) -// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000148) +// CHECK-NEXT: ('sh_size', 0x0000000000000030) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 01010000 00030001 0e080000') // CHECK-NEXT: ), // CHECK: (('sh_name', 0x0000000c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000490) -// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000490) +// CHECK-NEXT: ('sh_size', 0x0000000000000018) // CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/cfi-def-cfa-offset.s b/test/MC/ELF/cfi-def-cfa-offset.s index 124d02e95df1..0ed2be057edd 100644 --- a/test/MC/ELF/cfi-def-cfa-offset.s +++ b/test/MC/ELF/cfi-def-cfa-offset.s @@ -10,37 +10,37 @@ f: ret .cfi_endproc -// CHECK: # Section 0x00000004 +// CHECK: # Section 4 // CHECK-NEXT: (('sh_name', 0x00000011) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000050) -// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000050) +// CHECK-NEXT: ('sh_size', 0x0000000000000030) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 0a000000 00440e10 450e0800') // CHECK-NEXT: ), -// CHECK: # Section 0x00000005 +// CHECK: # Section 5 // CHECK-NEXT: (('sh_name', 0x0000000c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000398) -// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000398) +// CHECK-NEXT: ('sh_size', 0x0000000000000018) // CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/cfi-def-cfa-register.s b/test/MC/ELF/cfi-def-cfa-register.s index 75311e2e8443..e87b4f67d4b6 100644 --- a/test/MC/ELF/cfi-def-cfa-register.s +++ b/test/MC/ELF/cfi-def-cfa-register.s @@ -9,33 +9,33 @@ f: // CHECK: (('sh_name', 0x00000011) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000048) -// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000048) +// CHECK-NEXT: ('sh_size', 0x0000000000000030) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 02000000 00410d06 00000000') // CHECK-NEXT: ), // CHECK: (('sh_name', 0x0000000c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000390) -// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000390) +// CHECK-NEXT: ('sh_size', 0x0000000000000018) // CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/cfi-def-cfa.s b/test/MC/ELF/cfi-def-cfa.s index 53a169c09ddf..e25bf5c8e3c4 100644 --- a/test/MC/ELF/cfi-def-cfa.s +++ b/test/MC/ELF/cfi-def-cfa.s @@ -9,34 +9,34 @@ f: // CHECK: (('sh_name', 0x00000011) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000048) -// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000048) +// CHECK-NEXT: ('sh_size', 0x0000000000000030) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 02000000 00410c07 08000000') // CHECK-NEXT: ), // CHECK: (('sh_name', 0x0000000c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000390) -// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000390) +// CHECK-NEXT: ('sh_size', 0x0000000000000018) // CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/cfi-offset.s b/test/MC/ELF/cfi-offset.s index f54dec0ec8ad..9acb76c24d5b 100644 --- a/test/MC/ELF/cfi-offset.s +++ b/test/MC/ELF/cfi-offset.s @@ -9,34 +9,34 @@ f: // CHECK: (('sh_name', 0x00000011) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000048) -// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000048) +// CHECK-NEXT: ('sh_size', 0x0000000000000030) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 02000000 00418602 00000000') // CHECK-NEXT: ), // CHECK: (('sh_name', 0x0000000c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000390) -// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000390) +// CHECK-NEXT: ('sh_size', 0x0000000000000018) // CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/cfi-rel-offset.s b/test/MC/ELF/cfi-rel-offset.s index 87c0cf3b6589..82bbd8d6cef5 100644 --- a/test/MC/ELF/cfi-rel-offset.s +++ b/test/MC/ELF/cfi-rel-offset.s @@ -14,36 +14,36 @@ f: .cfi_rel_offset 6,0 .cfi_endproc -// CHECK: # Section 0x00000004 +// CHECK: # Section 4 // CHECK-NEXT: (('sh_name', 0x00000011) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000048) -// CHECK-NEXT: ('sh_size', 0x00000040) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000048) +// CHECK-NEXT: ('sh_size', 0x0000000000000040) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 24000000 1c000000 00000000 05000000 00410e08 410d0641 11067f41 0e104186 02000000 00000000') // CHECK-NEXT: ), -// CHECK-NEXT: # Section 0x00000005 +// CHECK-NEXT: # Section 5 // CHECK-NEXT: (('sh_name', 0x0000000c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x000003a0) -// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x00000000000003a0) +// CHECK-NEXT: ('sh_size', 0x0000000000000018) // CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/cfi-rel-offset2.s b/test/MC/ELF/cfi-rel-offset2.s index f14beaf09d21..7726adbe38f1 100644 --- a/test/MC/ELF/cfi-rel-offset2.s +++ b/test/MC/ELF/cfi-rel-offset2.s @@ -6,36 +6,36 @@ f: .cfi_rel_offset 6,16 .cfi_endproc -// CHECK: # Section 0x00000004 +// CHECK: # Section 4 // CHECK-NEXT: (('sh_name', 0x00000011) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000048) -// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000048) +// CHECK-NEXT: ('sh_size', 0x0000000000000030) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 01000000 00411106 7f000000') // CHECK-NEXT: ), -// CHECK-NEXT: # Section 0x00000005 +// CHECK-NEXT: # Section 5 // CHECK-NEXT: (('sh_name', 0x0000000c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000390) -// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000390) +// CHECK-NEXT: ('sh_size', 0x0000000000000018) // CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/cfi-remember.s b/test/MC/ELF/cfi-remember.s index 814812e2aaa6..1717662c1090 100644 --- a/test/MC/ELF/cfi-remember.s +++ b/test/MC/ELF/cfi-remember.s @@ -9,37 +9,37 @@ f: nop .cfi_endproc -// CHECK: # Section 0x00000004 +// CHECK: # Section 4 // CHECK-NEXT: (('sh_name', 0x00000011) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000048) -// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000048) +// CHECK-NEXT: ('sh_size', 0x0000000000000030) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 03000000 00410a41 0b000000') // CHECK-NEXT: ), -// CHECK: # Section 0x00000005 +// CHECK: # Section 5 // CHECK-NEXT: (('sh_name', 0x0000000c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000390) -// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000390) +// CHECK-NEXT: ('sh_size', 0x0000000000000018) // CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/cfi-same-value.s b/test/MC/ELF/cfi-same-value.s index eab1ae4d4b21..4c80a0a06660 100644 --- a/test/MC/ELF/cfi-same-value.s +++ b/test/MC/ELF/cfi-same-value.s @@ -7,36 +7,36 @@ f: nop .cfi_endproc -// CHECK: # Section 0x00000004 +// CHECK: # Section 4 // CHECK-NEXT: (('sh_name', 0x00000011) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000048) -// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000048) +// CHECK-NEXT: ('sh_size', 0x0000000000000030) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 02000000 00410806 00000000') // CHECK-NEXT: ), -// CHECK-NEXT: # Section 0x00000005 +// CHECK-NEXT: # Section 5 // CHECK-NEXT: (('sh_name', 0x0000000c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000390) -// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000390) +// CHECK-NEXT: ('sh_size', 0x0000000000000018) // CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/cfi-sections.s b/test/MC/ELF/cfi-sections.s index a73f3a9f5866..b256bbf4cd44 100644 --- a/test/MC/ELF/cfi-sections.s +++ b/test/MC/ELF/cfi-sections.s @@ -15,14 +15,14 @@ f2: // ELF_64: (('sh_name', 0x00000011) # '.debug_frame' // ELF_64-NEXT: ('sh_type', 0x00000001) -// ELF_64-NEXT: ('sh_flags', 0x00000000) -// ELF_64-NEXT: ('sh_addr', 0x00000000) -// ELF_64-NEXT: ('sh_offset', 0x00000048) -// ELF_64-NEXT: ('sh_size', 0x00000048) +// ELF_64-NEXT: ('sh_flags', 0x0000000000000000) +// ELF_64-NEXT: ('sh_addr', 0x0000000000000000) +// ELF_64-NEXT: ('sh_offset', 0x0000000000000048) +// ELF_64-NEXT: ('sh_size', 0x0000000000000048) // ELF_64-NEXT: ('sh_link', 0x00000000) // ELF_64-NEXT: ('sh_info', 0x00000000) -// ELF_64-NEXT: ('sh_addralign', 0x00000008) -// ELF_64-NEXT: ('sh_entsize', 0x00000000) +// ELF_64-NEXT: ('sh_addralign', 0x0000000000000008) +// ELF_64-NEXT: ('sh_entsize', 0x0000000000000000) // ELF_64-NEXT: ('_section_data', '14000000 ffffffff 01000178 100c0708 90010000 00000000 14000000 00000000 00000000 00000000 01000000 00000000 14000000 00000000 00000000 00000000 01000000 00000000') // ELF_32: (('sh_name', 0x00000010) # '.debug_frame' diff --git a/test/MC/ELF/cfi-zero-addr-delta.s b/test/MC/ELF/cfi-zero-addr-delta.s index 3ddf69ec50c6..9e818e694846 100644 --- a/test/MC/ELF/cfi-zero-addr-delta.s +++ b/test/MC/ELF/cfi-zero-addr-delta.s @@ -16,33 +16,33 @@ f: // CHECK: (('sh_name', 0x00000011) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000048) -// CHECK-NEXT: ('sh_size', 0x00000038) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000048) +// CHECK-NEXT: ('sh_size', 0x0000000000000038) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 1c000000 1c000000 00000000 04000000 00410e10 410a0e08 410b0000 00000000') // CHECK-NEXT: ), // CHECK: (('sh_name', 0x0000000c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000398) -// CHECK-NEXT: ('sh_size', 0x00000018) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000398) +// CHECK-NEXT: ('sh_size', 0x0000000000000018) // CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/cfi.s b/test/MC/ELF/cfi.s index 133b85809aa6..9320894226fa 100644 --- a/test/MC/ELF/cfi.s +++ b/test/MC/ELF/cfi.s @@ -212,463 +212,463 @@ f36: nop .cfi_endproc -// CHECK: # Section 0x00000004 +// CHECK: # Section 4 // CHECK-NEXT: (('sh_name', 0x00000011) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000068) -// CHECK-NEXT: ('sh_size', 0x000006c8) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000068) +// CHECK-NEXT: ('sh_size', 0x00000000000006c8) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '14000000 00000000 017a4c52 00017810 02031b0c 07089001 14000000 1c000000 00000000 01000000 04000000 00000000 20000000 00000000 017a504c 52000178 100b0000 00000000 00000003 1b0c0708 90010000 14000000 28000000 00000000 01000000 04000000 00000000 14000000 70000000 00000000 01000000 04000000 00000000 20000000 00000000 017a504c 52000178 100b0000 00000000 00000002 1b0c0708 90010000 10000000 28000000 00000000 01000000 02000000 18000000 00000000 017a5052 00017810 04020000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06030000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a040000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 040a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 060b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a0c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a080000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a100000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04120000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06130000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a140000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 041a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 061b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a1c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a180000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a800000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04820000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06830000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a840000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 048a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 068b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a8c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a880000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a900000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 04920000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 06930000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a940000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 049a0000 1b0c0708 90010000 10000000 20000000 00000000 01000000 00000000 18000000 00000000 017a5052 00017810 069b0000 00001b0c 07089001 10000000 20000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a9c0000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000 1c000000 00000000 017a5052 00017810 0a980000 00000000 00001b0c 07089001 10000000 24000000 00000000 01000000 00000000') // CHECK-NEXT: ), -// CHECK: # Section 0x00000005 +// CHECK: # Section 5 // CHECK-NEXT: (('sh_name', 0x0000000c) # '.rela.eh_frame' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000e30) -// CHECK-NEXT: ('sh_size', 0x000006c0) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000e30) +// CHECK-NEXT: ('sh_size', 0x00000000000006c0) // CHECK-NEXT: ('sh_link', 0x00000007) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000020) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000020) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000001 -// CHECK-NEXT: (('r_offset', 0x00000029) +// CHECK-NEXT: # Relocation 1 +// CHECK-NEXT: (('r_offset', 0x0000000000000029) // CHECK-NEXT: ('r_sym', 0x00000028) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000002 -// CHECK-NEXT: (('r_offset', 0x00000043) +// CHECK-NEXT: # Relocation 2 +// CHECK-NEXT: (('r_offset', 0x0000000000000043) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000003 -// CHECK-NEXT: (('r_offset', 0x0000005c) +// CHECK-NEXT: # Relocation 3 +// CHECK-NEXT: (('r_offset', 0x000000000000005c) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x0000000000000001) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000004 -// CHECK-NEXT: (('r_offset', 0x00000065) +// CHECK-NEXT: # Relocation 4 +// CHECK-NEXT: (('r_offset', 0x0000000000000065) // CHECK-NEXT: ('r_sym', 0x00000028) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000005 -// CHECK-NEXT: (('r_offset', 0x00000074) +// CHECK-NEXT: # Relocation 5 +// CHECK-NEXT: (('r_offset', 0x0000000000000074) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000002) +// CHECK-NEXT: ('r_addend', 0x0000000000000002) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000006 -// CHECK-NEXT: (('r_offset', 0x0000007d) +// CHECK-NEXT: # Relocation 6 +// CHECK-NEXT: (('r_offset', 0x000000000000007d) // CHECK-NEXT: ('r_sym', 0x00000028) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000007 -// CHECK-NEXT: (('r_offset', 0x00000097) +// CHECK-NEXT: # Relocation 7 +// CHECK-NEXT: (('r_offset', 0x0000000000000097) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000008 -// CHECK-NEXT: (('r_offset', 0x000000b0) +// CHECK-NEXT: # Relocation 8 +// CHECK-NEXT: (('r_offset', 0x00000000000000b0) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000003) +// CHECK-NEXT: ('r_addend', 0x0000000000000003) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000009 -// CHECK-NEXT: (('r_offset', 0x000000b9) +// CHECK-NEXT: # Relocation 9 +// CHECK-NEXT: (('r_offset', 0x00000000000000b9) // CHECK-NEXT: ('r_sym', 0x00000028) // CHECK-NEXT: ('r_type', 0x0000000c) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000000a -// CHECK-NEXT: (('r_offset', 0x000000ce) +// CHECK-NEXT: # Relocation 10 +// CHECK-NEXT: (('r_offset', 0x00000000000000ce) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000c) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000000b -// CHECK-NEXT: (('r_offset', 0x000000e0) +// CHECK-NEXT: # Relocation 11 +// CHECK-NEXT: (('r_offset', 0x00000000000000e0) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000004) +// CHECK-NEXT: ('r_addend', 0x0000000000000004) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000000c -// CHECK-NEXT: (('r_offset', 0x000000fe) +// CHECK-NEXT: # Relocation 12 +// CHECK-NEXT: (('r_offset', 0x00000000000000fe) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000000d -// CHECK-NEXT: (('r_offset', 0x00000110) +// CHECK-NEXT: # Relocation 13 +// CHECK-NEXT: (('r_offset', 0x0000000000000110) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000005) +// CHECK-NEXT: ('r_addend', 0x0000000000000005) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000000e -// CHECK-NEXT: (('r_offset', 0x0000012e) +// CHECK-NEXT: # Relocation 14 +// CHECK-NEXT: (('r_offset', 0x000000000000012e) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000000f -// CHECK-NEXT: (('r_offset', 0x00000144) +// CHECK-NEXT: # Relocation 15 +// CHECK-NEXT: (('r_offset', 0x0000000000000144) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000006) +// CHECK-NEXT: ('r_addend', 0x0000000000000006) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000010 -// CHECK-NEXT: (('r_offset', 0x00000162) +// CHECK-NEXT: # Relocation 16 +// CHECK-NEXT: (('r_offset', 0x0000000000000162) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000c) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000011 -// CHECK-NEXT: (('r_offset', 0x00000174) +// CHECK-NEXT: # Relocation 17 +// CHECK-NEXT: (('r_offset', 0x0000000000000174) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000007) +// CHECK-NEXT: ('r_addend', 0x0000000000000007) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000012 -// CHECK-NEXT: (('r_offset', 0x00000192) +// CHECK-NEXT: # Relocation 18 +// CHECK-NEXT: (('r_offset', 0x0000000000000192) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000013 -// CHECK-NEXT: (('r_offset', 0x000001a4) +// CHECK-NEXT: # Relocation 19 +// CHECK-NEXT: (('r_offset', 0x00000000000001a4) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000008) +// CHECK-NEXT: ('r_addend', 0x0000000000000008) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000014 -// CHECK-NEXT: (('r_offset', 0x000001c2) +// CHECK-NEXT: # Relocation 20 +// CHECK-NEXT: (('r_offset', 0x00000000000001c2) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000015 -// CHECK-NEXT: (('r_offset', 0x000001d8) +// CHECK-NEXT: # Relocation 21 +// CHECK-NEXT: (('r_offset', 0x00000000000001d8) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000009) +// CHECK-NEXT: ('r_addend', 0x0000000000000009) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000016 -// CHECK-NEXT: (('r_offset', 0x000001f6) +// CHECK-NEXT: # Relocation 22 +// CHECK-NEXT: (('r_offset', 0x00000000000001f6) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000017 -// CHECK-NEXT: (('r_offset', 0x0000020c) +// CHECK-NEXT: # Relocation 23 +// CHECK-NEXT: (('r_offset', 0x000000000000020c) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000000a) +// CHECK-NEXT: ('r_addend', 0x000000000000000a) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000018 -// CHECK-NEXT: (('r_offset', 0x0000022a) +// CHECK-NEXT: # Relocation 24 +// CHECK-NEXT: (('r_offset', 0x000000000000022a) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000018) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000019 -// CHECK-NEXT: (('r_offset', 0x00000240) +// CHECK-NEXT: # Relocation 25 +// CHECK-NEXT: (('r_offset', 0x0000000000000240) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000000b) +// CHECK-NEXT: ('r_addend', 0x000000000000000b) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000001a -// CHECK-NEXT: (('r_offset', 0x0000025e) +// CHECK-NEXT: # Relocation 26 +// CHECK-NEXT: (('r_offset', 0x000000000000025e) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000d) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000001b -// CHECK-NEXT: (('r_offset', 0x00000270) +// CHECK-NEXT: # Relocation 27 +// CHECK-NEXT: (('r_offset', 0x0000000000000270) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000000c) +// CHECK-NEXT: ('r_addend', 0x000000000000000c) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000001c -// CHECK-NEXT: (('r_offset', 0x0000028e) +// CHECK-NEXT: # Relocation 28 +// CHECK-NEXT: (('r_offset', 0x000000000000028e) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000001d -// CHECK-NEXT: (('r_offset', 0x000002a0) +// CHECK-NEXT: # Relocation 29 +// CHECK-NEXT: (('r_offset', 0x00000000000002a0) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000000d) +// CHECK-NEXT: ('r_addend', 0x000000000000000d) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000001e -// CHECK-NEXT: (('r_offset', 0x000002be) +// CHECK-NEXT: # Relocation 30 +// CHECK-NEXT: (('r_offset', 0x00000000000002be) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000018) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000001f -// CHECK-NEXT: (('r_offset', 0x000002d4) +// CHECK-NEXT: # Relocation 31 +// CHECK-NEXT: (('r_offset', 0x00000000000002d4) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000000e) +// CHECK-NEXT: ('r_addend', 0x000000000000000e) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000020 -// CHECK-NEXT: (('r_offset', 0x000002f2) +// CHECK-NEXT: # Relocation 32 +// CHECK-NEXT: (('r_offset', 0x00000000000002f2) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000d) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000021 -// CHECK-NEXT: (('r_offset', 0x00000304) +// CHECK-NEXT: # Relocation 33 +// CHECK-NEXT: (('r_offset', 0x0000000000000304) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000000f) +// CHECK-NEXT: ('r_addend', 0x000000000000000f) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000022 -// CHECK-NEXT: (('r_offset', 0x00000322) +// CHECK-NEXT: # Relocation 34 +// CHECK-NEXT: (('r_offset', 0x0000000000000322) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000023 -// CHECK-NEXT: (('r_offset', 0x00000334) +// CHECK-NEXT: # Relocation 35 +// CHECK-NEXT: (('r_offset', 0x0000000000000334) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000010) +// CHECK-NEXT: ('r_addend', 0x0000000000000010) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000024 -// CHECK-NEXT: (('r_offset', 0x00000352) +// CHECK-NEXT: # Relocation 36 +// CHECK-NEXT: (('r_offset', 0x0000000000000352) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000018) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000025 -// CHECK-NEXT: (('r_offset', 0x00000368) +// CHECK-NEXT: # Relocation 37 +// CHECK-NEXT: (('r_offset', 0x0000000000000368) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000011) +// CHECK-NEXT: ('r_addend', 0x0000000000000011) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000026 -// CHECK-NEXT: (('r_offset', 0x00000386) +// CHECK-NEXT: # Relocation 38 +// CHECK-NEXT: (('r_offset', 0x0000000000000386) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000018) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000027 -// CHECK-NEXT: (('r_offset', 0x0000039c) +// CHECK-NEXT: # Relocation 39 +// CHECK-NEXT: (('r_offset', 0x000000000000039c) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000012) +// CHECK-NEXT: ('r_addend', 0x0000000000000012) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000028 -// CHECK-NEXT: (('r_offset', 0x000003ba) +// CHECK-NEXT: # Relocation 40 +// CHECK-NEXT: (('r_offset', 0x00000000000003ba) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000029 -// CHECK-NEXT: (('r_offset', 0x000003d0) +// CHECK-NEXT: # Relocation 41 +// CHECK-NEXT: (('r_offset', 0x00000000000003d0) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000013) +// CHECK-NEXT: ('r_addend', 0x0000000000000013) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000002a -// CHECK-NEXT: (('r_offset', 0x000003ee) +// CHECK-NEXT: # Relocation 42 +// CHECK-NEXT: (('r_offset', 0x00000000000003ee) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000c) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000002b -// CHECK-NEXT: (('r_offset', 0x00000400) +// CHECK-NEXT: # Relocation 43 +// CHECK-NEXT: (('r_offset', 0x0000000000000400) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000014) +// CHECK-NEXT: ('r_addend', 0x0000000000000014) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000002c -// CHECK-NEXT: (('r_offset', 0x0000041e) +// CHECK-NEXT: # Relocation 44 +// CHECK-NEXT: (('r_offset', 0x000000000000041e) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000002d -// CHECK-NEXT: (('r_offset', 0x00000430) +// CHECK-NEXT: # Relocation 45 +// CHECK-NEXT: (('r_offset', 0x0000000000000430) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000015) +// CHECK-NEXT: ('r_addend', 0x0000000000000015) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000002e -// CHECK-NEXT: (('r_offset', 0x0000044e) +// CHECK-NEXT: # Relocation 46 +// CHECK-NEXT: (('r_offset', 0x000000000000044e) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000002f -// CHECK-NEXT: (('r_offset', 0x00000464) +// CHECK-NEXT: # Relocation 47 +// CHECK-NEXT: (('r_offset', 0x0000000000000464) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000016) +// CHECK-NEXT: ('r_addend', 0x0000000000000016) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000030 -// CHECK-NEXT: (('r_offset', 0x00000482) +// CHECK-NEXT: # Relocation 48 +// CHECK-NEXT: (('r_offset', 0x0000000000000482) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000c) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000031 -// CHECK-NEXT: (('r_offset', 0x00000494) +// CHECK-NEXT: # Relocation 49 +// CHECK-NEXT: (('r_offset', 0x0000000000000494) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000017) +// CHECK-NEXT: ('r_addend', 0x0000000000000017) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000032 -// CHECK-NEXT: (('r_offset', 0x000004b2) +// CHECK-NEXT: # Relocation 50 +// CHECK-NEXT: (('r_offset', 0x00000000000004b2) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000033 -// CHECK-NEXT: (('r_offset', 0x000004c4) +// CHECK-NEXT: # Relocation 51 +// CHECK-NEXT: (('r_offset', 0x00000000000004c4) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000018) +// CHECK-NEXT: ('r_addend', 0x0000000000000018) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000034 -// CHECK-NEXT: (('r_offset', 0x000004e2) +// CHECK-NEXT: # Relocation 52 +// CHECK-NEXT: (('r_offset', 0x00000000000004e2) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000035 -// CHECK-NEXT: (('r_offset', 0x000004f8) +// CHECK-NEXT: # Relocation 53 +// CHECK-NEXT: (('r_offset', 0x00000000000004f8) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000019) +// CHECK-NEXT: ('r_addend', 0x0000000000000019) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000036 -// CHECK-NEXT: (('r_offset', 0x00000516) +// CHECK-NEXT: # Relocation 54 +// CHECK-NEXT: (('r_offset', 0x0000000000000516) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000001) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000037 -// CHECK-NEXT: (('r_offset', 0x0000052c) +// CHECK-NEXT: # Relocation 55 +// CHECK-NEXT: (('r_offset', 0x000000000000052c) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000001a) +// CHECK-NEXT: ('r_addend', 0x000000000000001a) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000038 -// CHECK-NEXT: (('r_offset', 0x0000054a) +// CHECK-NEXT: # Relocation 56 +// CHECK-NEXT: (('r_offset', 0x000000000000054a) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000018) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000039 -// CHECK-NEXT: (('r_offset', 0x00000560) +// CHECK-NEXT: # Relocation 57 +// CHECK-NEXT: (('r_offset', 0x0000000000000560) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000001b) +// CHECK-NEXT: ('r_addend', 0x000000000000001b) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000003a -// CHECK-NEXT: (('r_offset', 0x0000057e) +// CHECK-NEXT: # Relocation 58 +// CHECK-NEXT: (('r_offset', 0x000000000000057e) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000d) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000003b -// CHECK-NEXT: (('r_offset', 0x00000590) +// CHECK-NEXT: # Relocation 59 +// CHECK-NEXT: (('r_offset', 0x0000000000000590) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000001c) +// CHECK-NEXT: ('r_addend', 0x000000000000001c) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000003c -// CHECK-NEXT: (('r_offset', 0x000005ae) +// CHECK-NEXT: # Relocation 60 +// CHECK-NEXT: (('r_offset', 0x00000000000005ae) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000003d -// CHECK-NEXT: (('r_offset', 0x000005c0) +// CHECK-NEXT: # Relocation 61 +// CHECK-NEXT: (('r_offset', 0x00000000000005c0) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000001d) +// CHECK-NEXT: ('r_addend', 0x000000000000001d) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000003e -// CHECK-NEXT: (('r_offset', 0x000005de) +// CHECK-NEXT: # Relocation 62 +// CHECK-NEXT: (('r_offset', 0x00000000000005de) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000018) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x0000003f -// CHECK-NEXT: (('r_offset', 0x000005f4) +// CHECK-NEXT: # Relocation 63 +// CHECK-NEXT: (('r_offset', 0x00000000000005f4) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000001e) +// CHECK-NEXT: ('r_addend', 0x000000000000001e) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000040 -// CHECK-NEXT: (('r_offset', 0x00000612) +// CHECK-NEXT: # Relocation 64 +// CHECK-NEXT: (('r_offset', 0x0000000000000612) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x0000000d) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000041 -// CHECK-NEXT: (('r_offset', 0x00000624) +// CHECK-NEXT: # Relocation 65 +// CHECK-NEXT: (('r_offset', 0x0000000000000624) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000001f) +// CHECK-NEXT: ('r_addend', 0x000000000000001f) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000042 -// CHECK-NEXT: (('r_offset', 0x00000642) +// CHECK-NEXT: # Relocation 66 +// CHECK-NEXT: (('r_offset', 0x0000000000000642) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000043 -// CHECK-NEXT: (('r_offset', 0x00000654) +// CHECK-NEXT: # Relocation 67 +// CHECK-NEXT: (('r_offset', 0x0000000000000654) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000020) +// CHECK-NEXT: ('r_addend', 0x0000000000000020) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000044 -// CHECK-NEXT: (('r_offset', 0x00000672) +// CHECK-NEXT: # Relocation 68 +// CHECK-NEXT: (('r_offset', 0x0000000000000672) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000018) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000045 -// CHECK-NEXT: (('r_offset', 0x00000688) +// CHECK-NEXT: # Relocation 69 +// CHECK-NEXT: (('r_offset', 0x0000000000000688) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000021) +// CHECK-NEXT: ('r_addend', 0x0000000000000021) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000046 -// CHECK-NEXT: (('r_offset', 0x000006a6) +// CHECK-NEXT: # Relocation 70 +// CHECK-NEXT: (('r_offset', 0x00000000000006a6) // CHECK-NEXT: ('r_sym', 0x00000029) // CHECK-NEXT: ('r_type', 0x00000018) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000047 -// CHECK-NEXT: (('r_offset', 0x000006bc) +// CHECK-NEXT: # Relocation 71 +// CHECK-NEXT: (('r_offset', 0x00000000000006bc) // CHECK-NEXT: ('r_sym', 0x00000024) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000022) +// CHECK-NEXT: ('r_addend', 0x0000000000000022) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/comdat.s b/test/MC/ELF/comdat.s index be7128baf4e6..d7acea6778d4 100644 --- a/test/MC/ELF/comdat.s +++ b/test/MC/ELF/comdat.s @@ -3,70 +3,70 @@ // Test that we produce the group sections and that they are a the beginning // of the file. -// CHECK: # Section 0x00000001 +// CHECK: # Section 1 // CHECK-NEXT: (('sh_name', 0x0000001b) # '.group' // CHECK-NEXT: ('sh_type', 0x00000011) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x0000000c) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x000000000000000c) // CHECK-NEXT: ('sh_link', 0x0000000d) // CHECK-NEXT: ('sh_info', 0x00000001) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000004) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000004) // CHECK-NEXT: ), -// CHECK-NEXT: # Section 0x00000002 +// CHECK-NEXT: # Section 2 // CHECK-NEXT: (('sh_name', 0x0000001b) # '.group' // CHECK-NEXT: ('sh_type', 0x00000011) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x0000004c) -// CHECK-NEXT: ('sh_size', 0x00000008) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x000000000000004c) +// CHECK-NEXT: ('sh_size', 0x0000000000000008) // CHECK-NEXT: ('sh_link', 0x0000000d) // CHECK-NEXT: ('sh_info', 0x00000002) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000004) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000004) // CHECK-NEXT: ), -// CHECK-NEXT: # Section 0x00000003 +// CHECK-NEXT: # Section 3 // CHECK-NEXT: (('sh_name', 0x0000001b) # '.group' // CHECK-NEXT: ('sh_type', 0x00000011) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000054) -// CHECK-NEXT: ('sh_size', 0x00000008) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000054) +// CHECK-NEXT: ('sh_size', 0x0000000000000008) // CHECK-NEXT: ('sh_link', 0x0000000d) // CHECK-NEXT: ('sh_info', 0x0000000d) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000004) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000004) // CHECK-NEXT: ), // Test that g1 and g2 are local, but g3 is an undefined global. -// CHECK: # Symbol 0x00000001 +// CHECK: # Symbol 1 // CHECK-NEXT: (('st_name', 0x00000001) # 'g1' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000007) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0007) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000002 +// CHECK-NEXT: # Symbol 2 // CHECK-NEXT: (('st_name', 0x00000004) # 'g2' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000002) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0002) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK: # Symbol 0x0000000d +// CHECK: # Symbol 13 // CHECK-NEXT: (('st_name', 0x00000007) # 'g3' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/common.s b/test/MC/ELF/common.s index 70e2ed2a95a6..046306e3d37d 100644 --- a/test/MC/ELF/common.s +++ b/test/MC/ELF/common.s @@ -9,9 +9,9 @@ .comm common1,1,1 // CHECK: ('st_name', 0x00000001) # 'common1' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000001) -// CHECK-NEXT: ('st_other', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x1) +// CHECK-NEXT: ('st_other', 0x00) // CHECK-NEXT: ('st_shndx', // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000001) @@ -23,9 +23,9 @@ .comm common2,1,1 // CHECK: ('st_name', 0x00000009) # 'common2' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000001) -// CHECK-NEXT: ('st_other', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x1) +// CHECK-NEXT: ('st_other', 0x00) // CHECK-NEXT: ('st_shndx', // CHECK-NEXT: ('st_value', 0x0000000000000001) // CHECK-NEXT: ('st_size', 0x0000000000000001) @@ -33,12 +33,12 @@ .local common6 .comm common6,8,16 -// CHECK: # Symbol 0x00000003 +// CHECK: # Symbol 3 // CHECK-NEXT: (('st_name', 0x00000011) # 'common6' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000001) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000004) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x1) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0004) // CHECK-NEXT: ('st_value', 0x0000000000000010) // CHECK-NEXT: ('st_size', 0x0000000000000008) // CHECK-NEXT: ), @@ -48,10 +48,10 @@ .comm common3,4,4 // CHECK: ('st_name', 0x00000019) # 'common3' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000001) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x0000fff2) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x1) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0xfff2) // CHECK-NEXT: ('st_value', 0x0000000000000004) // CHECK-NEXT: ('st_size', 0x0000000000000004) @@ -68,21 +68,21 @@ foo: .comm common4,40,16 // CHECK: ('st_name', 0x00000025) # 'common4' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000001) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x0000fff2) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x1) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0xfff2) // CHECK-NEXT: ('st_value', 0x0000000000000010) // CHECK-NEXT: ('st_size', 0x0000000000000028) .comm common5,4,4 -// CHECK: # Symbol 0x00000009 +// CHECK: # Symbol 9 // CHECK-NEXT: (('st_name', 0x0000002d) # 'common5' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000001) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x0000fff2) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x1) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0xfff2) // CHECK-NEXT: ('st_value', 0x0000000000000004) // CHECK-NEXT: ('st_size', 0x0000000000000004) // CHECK-NEXT: ), diff --git a/test/MC/ELF/common2.s b/test/MC/ELF/common2.s index b48ca66b91e1..b13577d4a004 100644 --- a/test/MC/ELF/common2.s +++ b/test/MC/ELF/common2.s @@ -14,7 +14,7 @@ // CHECK-NEXT: ('sh_flags' // CHECK-NEXT: ('sh_addr', // CHECK-NEXT: ('sh_offset', -// CHECK-NEXT: ('sh_size', 0x00000009) +// CHECK-NEXT: ('sh_size', 0x0000000000000009) // CHECK-NEXT: ('sh_link', // CHECK-NEXT: ('sh_info', // CHECK-NEXT: ('sh_addralign', diff --git a/test/MC/ELF/debug-line.s b/test/MC/ELF/debug-line.s index aa0197d0ce29..fed816afccef 100644 --- a/test/MC/ELF/debug-line.s +++ b/test/MC/ELF/debug-line.s @@ -4,14 +4,14 @@ // CHECK: (('sh_name', 0x00000011) # '.debug_line' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000044) -// CHECK-NEXT: ('sh_size', 0x00000037) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000044) +// CHECK-NEXT: ('sh_size', 0x0000000000000037) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '33000000 02001c00 00000101 fb0e0d00 01010101 00000001 00000100 666f6f2e 63000000 00000009 02000000 00000000 00150204 000101') .section .debug_line,"",@progbits diff --git a/test/MC/ELF/debug-loc.s b/test/MC/ELF/debug-loc.s index 68e36a55c715..3eb3797f443f 100644 --- a/test/MC/ELF/debug-loc.s +++ b/test/MC/ELF/debug-loc.s @@ -7,17 +7,17 @@ // FIXME: This size is the same as gnu as, but we can probably do a bit better. // FIXME2: We need a debug_line dumper so that we can test the actual contents. -// CHECK: # Section 0x00000004 +// CHECK: # Section 4 // CHECK-NEXT: (('sh_name', 0x00000011) # '.debug_line' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000044) -// CHECK-NEXT: ('sh_size', 0x0000003d) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000044) +// CHECK-NEXT: ('sh_size', 0x000000000000003d) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ), .section .debug_line,"",@progbits diff --git a/test/MC/ELF/diff.s b/test/MC/ELF/diff.s index 1879a39e8b9a..4214fc7c0368 100644 --- a/test/MC/ELF/diff.s +++ b/test/MC/ELF/diff.s @@ -8,8 +8,8 @@ bar: zed: mov zed+(bar-foo), %eax -// CHECK: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000005) +// CHECK: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000005) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x0000000b) -// CHECK-NEXT: ('r_addend', 0x00000001) +// CHECK-NEXT: ('r_addend', 0x0000000000000001) diff --git a/test/MC/ELF/empty-dwarf-lines.s b/test/MC/ELF/empty-dwarf-lines.s index 1b135a677ddc..7baedbcfb826 100644 --- a/test/MC/ELF/empty-dwarf-lines.s +++ b/test/MC/ELF/empty-dwarf-lines.s @@ -7,15 +7,15 @@ c: .asciz "hi\n" -// CHECK: # Section 0x00000004 +// CHECK: # Section 4 // CHECK-NEXT: (('sh_name', 0x0000000c) # '.debug_line' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000044) -// CHECK-NEXT: ('sh_size', 0x00000027) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000044) +// CHECK-NEXT: ('sh_size', 0x0000000000000027) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/empty.s b/test/MC/ELF/empty.s index d98f0c6a9692..b38a621054b4 100644 --- a/test/MC/ELF/empty.s +++ b/test/MC/ELF/empty.s @@ -5,66 +5,66 @@ // CHECK: ('sh_name', 0x00000001) # '.text' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000006) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000006) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x0000000000000000) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK: ('sh_name', 0x00000026) # '.data' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000003) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000003) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x0000000000000000) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK: ('sh_name', 0x00000007) # '.bss' // CHECK-NEXT: ('sh_type', 0x00000008) -// CHECK-NEXT: ('sh_flags', 0x00000003) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000003) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x0000000000000000) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK: ('sh_name', 0x0000000c) # '.shstrtab' // CHECK-NEXT: ('sh_type', 0x00000003) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x0000002c) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x000000000000002c) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK: ('sh_name', 0x0000001e) # '.symtab' // CHECK-NEXT: ('sh_type', 0x00000002) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) // CHECK-NEXT: ('sh_offset', -// CHECK-NEXT: ('sh_size', 0x00000060) +// CHECK-NEXT: ('sh_size', 0x0000000000000060) // CHECK-NEXT: ('sh_link', 0x00000006) // CHECK-NEXT: ('sh_info', 0x00000004) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK: ('sh_name', 0x00000016) # '.strtab' // CHECK-NEXT: ('sh_type', 0x00000003) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) // CHECK-NEXT: ('sh_offset', -// CHECK-NEXT: ('sh_size', 0x00000001) +// CHECK-NEXT: ('sh_size', 0x0000000000000001) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) diff --git a/test/MC/ELF/entsize.ll b/test/MC/ELF/entsize.ll index 74f0413ecbe6..dce6dbaa2a07 100644 --- a/test/MC/ELF/entsize.ll +++ b/test/MC/ELF/entsize.ll @@ -22,23 +22,23 @@ declare void @foo(i64* nocapture) nounwind ; 64: (('sh_name', 0x0000004e) # '.rodata.str1.1' ; 64-NEXT: ('sh_type', 0x00000001) -; 64-NEXT: ('sh_flags', 0x00000032) +; 64-NEXT: ('sh_flags', 0x0000000000000032) ; 64-NEXT: ('sh_addr', ; 64-NEXT: ('sh_offset', -; 64-NEXT: ('sh_size', 0x0000000d) +; 64-NEXT: ('sh_size', 0x000000000000000d) ; 64-NEXT: ('sh_link', ; 64-NEXT: ('sh_info', -; 64-NEXT: ('sh_addralign', 0x00000001) -; 64-NEXT: ('sh_entsize', 0x00000001) +; 64-NEXT: ('sh_addralign', 0x0000000000000001) +; 64-NEXT: ('sh_entsize', 0x0000000000000001) ; 64: (('sh_name', 0x00000041) # '.rodata.cst8' ; 64-NEXT: ('sh_type', 0x00000001) -; 64-NEXT: ('sh_flags', 0x00000012) +; 64-NEXT: ('sh_flags', 0x0000000000000012) ; 64-NEXT: ('sh_addr', ; 64-NEXT: ('sh_offset', -; 64-NEXT: ('sh_size', 0x00000010) +; 64-NEXT: ('sh_size', 0x0000000000000010) ; 64-NEXT: ('sh_link', ; 64-NEXT: ('sh_info', -; 64-NEXT: ('sh_addralign', 0x00000008) -; 64-NEXT: ('sh_entsize', 0x00000008) +; 64-NEXT: ('sh_addralign', 0x0000000000000008) +; 64-NEXT: ('sh_entsize', 0x0000000000000008) diff --git a/test/MC/ELF/entsize.s b/test/MC/ELF/entsize.s index 415eaefe4660..4645686b6d4e 100644 --- a/test/MC/ELF/entsize.s +++ b/test/MC/ELF/entsize.s @@ -32,38 +32,38 @@ .quad 42 .quad 42 -// CHECK: # Section 0x00000004 +// CHECK: # Section 4 // CHECK-NEXT: ('sh_name', 0x00000048) # '.rodata.str1.1' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000032) +// CHECK-NEXT: ('sh_flags', 0x0000000000000032) // CHECK-NEXT: ('sh_addr', // CHECK-NEXT: ('sh_offset', -// CHECK-NEXT: ('sh_size', 0x0000000d) +// CHECK-NEXT: ('sh_size', 0x000000000000000d) // CHECK-NEXT: ('sh_link', // CHECK-NEXT: ('sh_info', -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000001) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000001) -// CHECK: # Section 0x00000005 +// CHECK: # Section 5 // CHECK-NEXT: ('sh_name', 0x00000039) # '.rodata.str2.1' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000032) +// CHECK-NEXT: ('sh_flags', 0x0000000000000032) // CHECK-NEXT: ('sh_addr', // CHECK-NEXT: ('sh_offset', -// CHECK-NEXT: ('sh_size', 0x00000010) +// CHECK-NEXT: ('sh_size', 0x0000000000000010) // CHECK-NEXT: ('sh_link', // CHECK-NEXT: ('sh_info', -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000002) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000002) -// CHECK: # Section 0x00000006 +// CHECK: # Section 6 // CHECK-NEXT: ('sh_name', 0x0000002c) # '.rodata.cst8 // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000012) +// CHECK-NEXT: ('sh_flags', 0x0000000000000012) // CHECK-NEXT: ('sh_addr', // CHECK-NEXT: ('sh_offset', -// CHECK-NEXT: ('sh_size', 0x00000010) +// CHECK-NEXT: ('sh_size', 0x0000000000000010) // CHECK-NEXT: ('sh_link', // CHECK-NEXT: ('sh_info', -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000008) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000008) diff --git a/test/MC/ELF/file.s b/test/MC/ELF/file.s index d8ccbe6e5aee..434fb6e2b3c6 100644 --- a/test/MC/ELF/file.s +++ b/test/MC/ELF/file.s @@ -4,20 +4,20 @@ .file "foo" foa: -// CHECK: # Symbol 0x00000001 +// CHECK: # Symbol 1 // CHECK-NEXT: (('st_name', 0x00000001) # 'foo' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000004) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x0000fff1) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x4) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0xfff1) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000002 +// CHECK-NEXT: # Symbol 2 // CHECK-NEXT: (('st_name', 0x00000005) # 'foa' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) diff --git a/test/MC/ELF/global-offset.s b/test/MC/ELF/global-offset.s index 77f72677108b..8cc5dbb8d822 100644 --- a/test/MC/ELF/global-offset.s +++ b/test/MC/ELF/global-offset.s @@ -1,9 +1,10 @@ // RUN: llvm-mc -filetype=obj -triple i386-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s // We test that _GLOBAL_OFFSET_TABLE_ will account for the two bytes at the -// start of the addl. +// start of the addl/leal. addl $_GLOBAL_OFFSET_TABLE_, %ebx + leal _GLOBAL_OFFSET_TABLE_(%ebx), %ebx // CHECK: ('sh_name', 0x00000005) # '.text' // CHECK-NEXT: ('sh_type', @@ -15,4 +16,4 @@ // CHECK-NEXT: ('sh_info', // CHECK-NEXT: ('sh_addralign', // CHECK-NEXT: ('sh_entsize', -// CHECK-NEXT: ('_section_data', '81c30200 0000') +// CHECK-NEXT: ('_section_data', '81c30200 00008d9b 02000000') diff --git a/test/MC/ELF/got.s b/test/MC/ELF/got.s index a3abef536a00..a84987281818 100644 --- a/test/MC/ELF/got.s +++ b/test/MC/ELF/got.s @@ -7,13 +7,13 @@ movl foo@GOTPCREL(%rip), %eax // CHECK: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: # Relocation 0 // CHECK-NEXT: (('r_offset', // CHECK-NEXT: ('r_sym', // CHECK-NEXT: ('r_type', 0x00000003) // CHECK-NEXT: ('r_addend', // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000001 +// CHECK-NEXT: # Relocation 1 // CHECK-NEXT: (('r_offset', // CHECK-NEXT: ('r_sym', // CHECK-NEXT: ('r_type', 0x00000009) @@ -22,4 +22,4 @@ // CHECK-NEXT: ]) // CHECK: (('st_name', 0x00000005) # '_GLOBAL_OFFSET_TABLE_' -// CHECK-NEXT: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) diff --git a/test/MC/ELF/ident.s b/test/MC/ELF/ident.s index b364d6007fec..56af19a30752 100644 --- a/test/MC/ELF/ident.s +++ b/test/MC/ELF/ident.s @@ -2,14 +2,14 @@ // CHECK: (('sh_name', 0x00000007) # '.comment' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000030) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x0000000d) +// CHECK-NEXT: ('sh_flags', 0x0000000000000030) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x000000000000000d) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000001) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000001) // CHECK-NEXT: ('_section_data', '00666f6f 00626172 007a6564 00') .ident "foo" diff --git a/test/MC/ELF/leb128.s b/test/MC/ELF/leb128.s index e5f31f4834dd..f6daac8ace5c 100644 --- a/test/MC/ELF/leb128.s +++ b/test/MC/ELF/leb128.s @@ -8,12 +8,12 @@ // CHECK: (('sh_name', 0x00000001) # '.text' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000006) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x00000081) +// CHECK-NEXT: ('sh_flags', 0x0000000000000006) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x0000000000000081) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '817f7f90 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90909090 90') diff --git a/test/MC/ELF/local-reloc.s b/test/MC/ELF/local-reloc.s index 8384e0e6cb77..b32a9cc16973 100644 --- a/test/MC/ELF/local-reloc.s +++ b/test/MC/ELF/local-reloc.s @@ -7,12 +7,12 @@ foo: // Section number 1 is .text -// CHECK: # Section 0x00000001 +// CHECK: # Section 1 // CHECK-next: (('sh_name', 0x00000001) # '.text' // Relocation refers to symbol number 2 // CHECK: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: # Relocation 0 // CHECK-NEXT: (('r_offset', // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', @@ -21,11 +21,11 @@ foo: // CHECK-NEXT: ]) // Symbol number 2 is section number 1 -// CHECK: # Symbol 0x00000002 +// CHECK: # Symbol 2 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x3) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) diff --git a/test/MC/ELF/many-section.s b/test/MC/ELF/many-section.s new file mode 100644 index 000000000000..e7e723ad9059 --- /dev/null +++ b/test/MC/ELF/many-section.s @@ -0,0 +1,93319 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t +// RUN: llvm-nm %t | FileCheck %s + +// CHECK: s000a +// CHECK-NOT: U +// CHECK: szzzb + +.section saaaa +.section saaab +.section saaba +.section saabb +.section saaca +.section saacb +.section saada +.section saadb +.section saaea +.section saaeb +.section saafa +.section saafb +.section saaga +.section saagb +.section saaha +.section saahb +.section saaia +.section saaib +.section saaja +.section saajb +.section saaka +.section saakb +.section saala +.section saalb +.section saama +.section saamb +.section saana +.section saanb +.section saaoa +.section saaob +.section saapa +.section saapb +.section saaqa +.section saaqb +.section saara +.section saarb +.section saasa +.section saasb +.section saata +.section saatb +.section saaua +.section saaub +.section saava +.section saavb +.section saawa +.section saawb +.section saaxa +.section saaxb +.section saaya +.section saayb +.section saaza +.section saazb +.section saa1a +.section saa1b +.section saa2a +.section saa2b +.section saa3a +.section saa3b +.section saa4a +.section saa4b +.section saa5a +.section saa5b +.section saa6a +.section saa6b +.section saa7a +.section saa7b +.section saa8a +.section saa8b +.section saa9a +.section saa9b +.section saa0a +.section saa0b +.section sabaa +.section sabab +.section sabba +.section sabbb +.section sabca +.section sabcb +.section sabda +.section sabdb +.section sabea +.section sabeb +.section sabfa +.section sabfb +.section sabga +.section sabgb +.section sabha +.section sabhb +.section sabia +.section sabib +.section sabja +.section sabjb +.section sabka +.section sabkb +.section sabla +.section sablb +.section sabma +.section sabmb +.section sabna +.section sabnb +.section saboa +.section sabob +.section sabpa +.section sabpb +.section sabqa +.section sabqb +.section sabra +.section sabrb +.section sabsa +.section sabsb +.section sabta +.section sabtb +.section sabua +.section sabub +.section sabva +.section sabvb +.section sabwa +.section sabwb +.section sabxa +.section sabxb +.section sabya +.section sabyb +.section sabza +.section sabzb +.section sab1a +.section sab1b +.section sab2a +.section sab2b +.section sab3a +.section sab3b +.section sab4a +.section sab4b +.section sab5a +.section sab5b +.section sab6a +.section sab6b +.section sab7a +.section sab7b +.section sab8a +.section sab8b +.section sab9a +.section sab9b +.section sab0a +.section sab0b +.section sacaa +.section sacab +.section sacba +.section sacbb +.section sacca +.section saccb +.section sacda +.section sacdb +.section sacea +.section saceb +.section sacfa +.section sacfb +.section sacga +.section sacgb +.section sacha +.section sachb +.section sacia +.section sacib +.section sacja +.section sacjb +.section sacka +.section sackb +.section sacla +.section saclb +.section sacma +.section sacmb +.section sacna +.section sacnb +.section sacoa +.section sacob +.section sacpa +.section sacpb +.section sacqa +.section sacqb +.section sacra +.section sacrb +.section sacsa +.section sacsb +.section sacta +.section sactb +.section sacua +.section sacub +.section sacva +.section sacvb +.section sacwa +.section sacwb +.section sacxa +.section sacxb +.section sacya +.section sacyb +.section sacza +.section saczb +.section sac1a +.section sac1b +.section sac2a +.section sac2b +.section sac3a +.section sac3b +.section sac4a +.section sac4b +.section sac5a +.section sac5b +.section sac6a +.section sac6b +.section sac7a +.section sac7b +.section sac8a +.section sac8b +.section sac9a +.section sac9b +.section sac0a +.section sac0b +.section sadaa +.section sadab +.section sadba +.section sadbb +.section sadca +.section sadcb +.section sadda +.section saddb +.section sadea +.section sadeb +.section sadfa +.section sadfb +.section sadga +.section sadgb +.section sadha +.section sadhb +.section sadia +.section sadib +.section sadja +.section sadjb +.section sadka +.section sadkb +.section sadla +.section sadlb +.section sadma +.section sadmb +.section sadna +.section sadnb +.section sadoa +.section sadob +.section sadpa +.section sadpb +.section sadqa +.section sadqb +.section sadra +.section sadrb +.section sadsa +.section sadsb +.section sadta +.section sadtb +.section sadua +.section sadub +.section sadva +.section sadvb +.section sadwa +.section sadwb +.section sadxa +.section sadxb +.section sadya +.section sadyb +.section sadza +.section sadzb +.section sad1a +.section sad1b +.section sad2a +.section sad2b +.section sad3a +.section sad3b +.section sad4a +.section sad4b +.section sad5a +.section sad5b +.section sad6a +.section sad6b +.section sad7a +.section sad7b +.section sad8a +.section sad8b +.section sad9a +.section sad9b +.section sad0a +.section sad0b +.section saeaa +.section saeab +.section saeba +.section saebb +.section saeca +.section saecb +.section saeda +.section saedb +.section saeea +.section saeeb +.section saefa +.section saefb +.section saega +.section saegb +.section saeha +.section saehb +.section saeia +.section saeib +.section saeja +.section saejb +.section saeka +.section saekb +.section saela +.section saelb +.section saema +.section saemb +.section saena +.section saenb +.section saeoa +.section saeob +.section saepa +.section saepb +.section saeqa +.section saeqb +.section saera +.section saerb +.section saesa +.section saesb +.section saeta +.section saetb +.section saeua +.section saeub +.section saeva +.section saevb +.section saewa +.section saewb +.section saexa +.section saexb +.section saeya +.section saeyb +.section saeza +.section saezb +.section sae1a +.section sae1b +.section sae2a +.section sae2b +.section sae3a +.section sae3b +.section sae4a +.section sae4b +.section sae5a +.section sae5b +.section sae6a +.section sae6b +.section sae7a +.section sae7b +.section sae8a +.section sae8b +.section sae9a +.section sae9b +.section sae0a +.section sae0b +.section safaa +.section safab +.section safba +.section safbb +.section safca +.section safcb +.section safda +.section safdb +.section safea +.section safeb +.section saffa +.section saffb +.section safga +.section safgb +.section safha +.section safhb +.section safia +.section safib +.section safja +.section safjb +.section safka +.section safkb +.section safla +.section saflb +.section safma +.section safmb +.section safna +.section safnb +.section safoa +.section safob +.section safpa +.section safpb +.section safqa +.section safqb +.section safra +.section safrb +.section safsa +.section safsb +.section safta +.section saftb +.section safua +.section safub +.section safva +.section safvb +.section safwa +.section safwb +.section safxa +.section safxb +.section safya +.section safyb +.section safza +.section safzb +.section saf1a +.section saf1b +.section saf2a +.section saf2b +.section saf3a +.section saf3b +.section saf4a +.section saf4b +.section saf5a +.section saf5b +.section saf6a +.section saf6b +.section saf7a +.section saf7b +.section saf8a +.section saf8b +.section saf9a +.section saf9b +.section saf0a +.section saf0b +.section sagaa +.section sagab +.section sagba +.section sagbb +.section sagca +.section sagcb +.section sagda +.section sagdb +.section sagea +.section sageb +.section sagfa +.section sagfb +.section sagga +.section saggb +.section sagha +.section saghb +.section sagia +.section sagib +.section sagja +.section sagjb +.section sagka +.section sagkb +.section sagla +.section saglb +.section sagma +.section sagmb +.section sagna +.section sagnb +.section sagoa +.section sagob +.section sagpa +.section sagpb +.section sagqa +.section sagqb +.section sagra +.section sagrb +.section sagsa +.section sagsb +.section sagta +.section sagtb +.section sagua +.section sagub +.section sagva +.section sagvb +.section sagwa +.section sagwb +.section sagxa +.section sagxb +.section sagya +.section sagyb +.section sagza +.section sagzb +.section sag1a +.section sag1b +.section sag2a +.section sag2b +.section sag3a +.section sag3b +.section sag4a +.section sag4b +.section sag5a +.section sag5b +.section sag6a +.section sag6b +.section sag7a +.section sag7b +.section sag8a +.section sag8b +.section sag9a +.section sag9b +.section sag0a +.section sag0b +.section sahaa +.section sahab +.section sahba +.section sahbb +.section sahca +.section sahcb +.section sahda +.section sahdb +.section sahea +.section saheb +.section sahfa +.section sahfb +.section sahga +.section sahgb +.section sahha +.section sahhb +.section sahia +.section sahib +.section sahja +.section sahjb +.section sahka +.section sahkb +.section sahla +.section sahlb +.section sahma +.section sahmb +.section sahna +.section sahnb +.section sahoa +.section sahob +.section sahpa +.section sahpb +.section sahqa +.section sahqb +.section sahra +.section sahrb +.section sahsa +.section sahsb +.section sahta +.section sahtb +.section sahua +.section sahub +.section sahva +.section sahvb +.section sahwa +.section sahwb +.section sahxa +.section sahxb +.section sahya +.section sahyb +.section sahza +.section sahzb +.section sah1a +.section sah1b +.section sah2a +.section sah2b +.section sah3a +.section sah3b +.section sah4a +.section sah4b +.section sah5a +.section sah5b +.section sah6a +.section sah6b +.section sah7a +.section sah7b +.section sah8a +.section sah8b +.section sah9a +.section sah9b +.section sah0a +.section sah0b +.section saiaa +.section saiab +.section saiba +.section saibb +.section saica +.section saicb +.section saida +.section saidb +.section saiea +.section saieb +.section saifa +.section saifb +.section saiga +.section saigb +.section saiha +.section saihb +.section saiia +.section saiib +.section saija +.section saijb +.section saika +.section saikb +.section saila +.section sailb +.section saima +.section saimb +.section saina +.section sainb +.section saioa +.section saiob +.section saipa +.section saipb +.section saiqa +.section saiqb +.section saira +.section sairb +.section saisa +.section saisb +.section saita +.section saitb +.section saiua +.section saiub +.section saiva +.section saivb +.section saiwa +.section saiwb +.section saixa +.section saixb +.section saiya +.section saiyb +.section saiza +.section saizb +.section sai1a +.section sai1b +.section sai2a +.section sai2b +.section sai3a +.section sai3b +.section sai4a +.section sai4b +.section sai5a +.section sai5b +.section sai6a +.section sai6b +.section sai7a +.section sai7b +.section sai8a +.section sai8b +.section sai9a +.section sai9b +.section sai0a +.section sai0b +.section sajaa +.section sajab +.section sajba +.section sajbb +.section sajca +.section sajcb +.section sajda +.section sajdb +.section sajea +.section sajeb +.section sajfa +.section sajfb +.section sajga +.section sajgb +.section sajha +.section sajhb +.section sajia +.section sajib +.section sajja +.section sajjb +.section sajka +.section sajkb +.section sajla +.section sajlb +.section sajma +.section sajmb +.section sajna +.section sajnb +.section sajoa +.section sajob +.section sajpa +.section sajpb +.section sajqa +.section sajqb +.section sajra +.section sajrb +.section sajsa +.section sajsb +.section sajta +.section sajtb +.section sajua +.section sajub +.section sajva +.section sajvb +.section sajwa +.section sajwb +.section sajxa +.section sajxb +.section sajya +.section sajyb +.section sajza +.section sajzb +.section saj1a +.section saj1b +.section saj2a +.section saj2b +.section saj3a +.section saj3b +.section saj4a +.section saj4b +.section saj5a +.section saj5b +.section saj6a +.section saj6b +.section saj7a +.section saj7b +.section saj8a +.section saj8b +.section saj9a +.section saj9b +.section saj0a +.section saj0b +.section sakaa +.section sakab +.section sakba +.section sakbb +.section sakca +.section sakcb +.section sakda +.section sakdb +.section sakea +.section sakeb +.section sakfa +.section sakfb +.section sakga +.section sakgb +.section sakha +.section sakhb +.section sakia +.section sakib +.section sakja +.section sakjb +.section sakka +.section sakkb +.section sakla +.section saklb +.section sakma +.section sakmb +.section sakna +.section saknb +.section sakoa +.section sakob +.section sakpa +.section sakpb +.section sakqa +.section sakqb +.section sakra +.section sakrb +.section saksa +.section saksb +.section sakta +.section saktb +.section sakua +.section sakub +.section sakva +.section sakvb +.section sakwa +.section sakwb +.section sakxa +.section sakxb +.section sakya +.section sakyb +.section sakza +.section sakzb +.section sak1a +.section sak1b +.section sak2a +.section sak2b +.section sak3a +.section sak3b +.section sak4a +.section sak4b +.section sak5a +.section sak5b +.section sak6a +.section sak6b +.section sak7a +.section sak7b +.section sak8a +.section sak8b +.section sak9a +.section sak9b +.section sak0a +.section sak0b +.section salaa +.section salab +.section salba +.section salbb +.section salca +.section salcb +.section salda +.section saldb +.section salea +.section saleb +.section salfa +.section salfb +.section salga +.section salgb +.section salha +.section salhb +.section salia +.section salib +.section salja +.section saljb +.section salka +.section salkb +.section salla +.section sallb +.section salma +.section salmb +.section salna +.section salnb +.section saloa +.section salob +.section salpa +.section salpb +.section salqa +.section salqb +.section salra +.section salrb +.section salsa +.section salsb +.section salta +.section saltb +.section salua +.section salub +.section salva +.section salvb +.section salwa +.section salwb +.section salxa +.section salxb +.section salya +.section salyb +.section salza +.section salzb +.section sal1a +.section sal1b +.section sal2a +.section sal2b +.section sal3a +.section sal3b +.section sal4a +.section sal4b +.section sal5a +.section sal5b +.section sal6a +.section sal6b +.section sal7a +.section sal7b +.section sal8a +.section sal8b +.section sal9a +.section sal9b +.section sal0a +.section sal0b +.section samaa +.section samab +.section samba +.section sambb +.section samca +.section samcb +.section samda +.section samdb +.section samea +.section sameb +.section samfa +.section samfb +.section samga +.section samgb +.section samha +.section samhb +.section samia +.section samib +.section samja +.section samjb +.section samka +.section samkb +.section samla +.section samlb +.section samma +.section sammb +.section samna +.section samnb +.section samoa +.section samob +.section sampa +.section sampb +.section samqa +.section samqb +.section samra +.section samrb +.section samsa +.section samsb +.section samta +.section samtb +.section samua +.section samub +.section samva +.section samvb +.section samwa +.section samwb +.section samxa +.section samxb +.section samya +.section samyb +.section samza +.section samzb +.section sam1a +.section sam1b +.section sam2a +.section sam2b +.section sam3a +.section sam3b +.section sam4a +.section sam4b +.section sam5a +.section sam5b +.section sam6a +.section sam6b +.section sam7a +.section sam7b +.section sam8a +.section sam8b +.section sam9a +.section sam9b +.section sam0a +.section sam0b +.section sanaa +.section sanab +.section sanba +.section sanbb +.section sanca +.section sancb +.section sanda +.section sandb +.section sanea +.section saneb +.section sanfa +.section sanfb +.section sanga +.section sangb +.section sanha +.section sanhb +.section sania +.section sanib +.section sanja +.section sanjb +.section sanka +.section sankb +.section sanla +.section sanlb +.section sanma +.section sanmb +.section sanna +.section sannb +.section sanoa +.section sanob +.section sanpa +.section sanpb +.section sanqa +.section sanqb +.section sanra +.section sanrb +.section sansa +.section sansb +.section santa +.section santb +.section sanua +.section sanub +.section sanva +.section sanvb +.section sanwa +.section sanwb +.section sanxa +.section sanxb +.section sanya +.section sanyb +.section sanza +.section sanzb +.section san1a +.section san1b +.section san2a +.section san2b +.section san3a +.section san3b +.section san4a +.section san4b +.section san5a +.section san5b +.section san6a +.section san6b +.section san7a +.section san7b +.section san8a +.section san8b +.section san9a +.section san9b +.section san0a +.section san0b +.section saoaa +.section saoab +.section saoba +.section saobb +.section saoca +.section saocb +.section saoda +.section saodb +.section saoea +.section saoeb +.section saofa +.section saofb +.section saoga +.section saogb +.section saoha +.section saohb +.section saoia +.section saoib +.section saoja +.section saojb +.section saoka +.section saokb +.section saola +.section saolb +.section saoma +.section saomb +.section saona +.section saonb +.section saooa +.section saoob +.section saopa +.section saopb +.section saoqa +.section saoqb +.section saora +.section saorb +.section saosa +.section saosb +.section saota +.section saotb +.section saoua +.section saoub +.section saova +.section saovb +.section saowa +.section saowb +.section saoxa +.section saoxb +.section saoya +.section saoyb +.section saoza +.section saozb +.section sao1a +.section sao1b +.section sao2a +.section sao2b +.section sao3a +.section sao3b +.section sao4a +.section sao4b +.section sao5a +.section sao5b +.section sao6a +.section sao6b +.section sao7a +.section sao7b +.section sao8a +.section sao8b +.section sao9a +.section sao9b +.section sao0a +.section sao0b +.section sapaa +.section sapab +.section sapba +.section sapbb +.section sapca +.section sapcb +.section sapda +.section sapdb +.section sapea +.section sapeb +.section sapfa +.section sapfb +.section sapga +.section sapgb +.section sapha +.section saphb +.section sapia +.section sapib +.section sapja +.section sapjb +.section sapka +.section sapkb +.section sapla +.section saplb +.section sapma +.section sapmb +.section sapna +.section sapnb +.section sapoa +.section sapob +.section sappa +.section sappb +.section sapqa +.section sapqb +.section sapra +.section saprb +.section sapsa +.section sapsb +.section sapta +.section saptb +.section sapua +.section sapub +.section sapva +.section sapvb +.section sapwa +.section sapwb +.section sapxa +.section sapxb +.section sapya +.section sapyb +.section sapza +.section sapzb +.section sap1a +.section sap1b +.section sap2a +.section sap2b +.section sap3a +.section sap3b +.section sap4a +.section sap4b +.section sap5a +.section sap5b +.section sap6a +.section sap6b +.section sap7a +.section sap7b +.section sap8a +.section sap8b +.section sap9a +.section sap9b +.section sap0a +.section sap0b +.section saqaa +.section saqab +.section saqba +.section saqbb +.section saqca +.section saqcb +.section saqda +.section saqdb +.section saqea +.section saqeb +.section saqfa +.section saqfb +.section saqga +.section saqgb +.section saqha +.section saqhb +.section saqia +.section saqib +.section saqja +.section saqjb +.section saqka +.section saqkb +.section saqla +.section saqlb +.section saqma +.section saqmb +.section saqna +.section saqnb +.section saqoa +.section saqob +.section saqpa +.section saqpb +.section saqqa +.section saqqb +.section saqra +.section saqrb +.section saqsa +.section saqsb +.section saqta +.section saqtb +.section saqua +.section saqub +.section saqva +.section saqvb +.section saqwa +.section saqwb +.section saqxa +.section saqxb +.section saqya +.section saqyb +.section saqza +.section saqzb +.section saq1a +.section saq1b +.section saq2a +.section saq2b +.section saq3a +.section saq3b +.section saq4a +.section saq4b +.section saq5a +.section saq5b +.section saq6a +.section saq6b +.section saq7a +.section saq7b +.section saq8a +.section saq8b +.section saq9a +.section saq9b +.section saq0a +.section saq0b +.section saraa +.section sarab +.section sarba +.section sarbb +.section sarca +.section sarcb +.section sarda +.section sardb +.section sarea +.section sareb +.section sarfa +.section sarfb +.section sarga +.section sargb +.section sarha +.section sarhb +.section saria +.section sarib +.section sarja +.section sarjb +.section sarka +.section sarkb +.section sarla +.section sarlb +.section sarma +.section sarmb +.section sarna +.section sarnb +.section saroa +.section sarob +.section sarpa +.section sarpb +.section sarqa +.section sarqb +.section sarra +.section sarrb +.section sarsa +.section sarsb +.section sarta +.section sartb +.section sarua +.section sarub +.section sarva +.section sarvb +.section sarwa +.section sarwb +.section sarxa +.section sarxb +.section sarya +.section saryb +.section sarza +.section sarzb +.section sar1a +.section sar1b +.section sar2a +.section sar2b +.section sar3a +.section sar3b +.section sar4a +.section sar4b +.section sar5a +.section sar5b +.section sar6a +.section sar6b +.section sar7a +.section sar7b +.section sar8a +.section sar8b +.section sar9a +.section sar9b +.section sar0a +.section sar0b +.section sasaa +.section sasab +.section sasba +.section sasbb +.section sasca +.section sascb +.section sasda +.section sasdb +.section sasea +.section saseb +.section sasfa +.section sasfb +.section sasga +.section sasgb +.section sasha +.section sashb +.section sasia +.section sasib +.section sasja +.section sasjb +.section saska +.section saskb +.section sasla +.section saslb +.section sasma +.section sasmb +.section sasna +.section sasnb +.section sasoa +.section sasob +.section saspa +.section saspb +.section sasqa +.section sasqb +.section sasra +.section sasrb +.section sassa +.section sassb +.section sasta +.section sastb +.section sasua +.section sasub +.section sasva +.section sasvb +.section saswa +.section saswb +.section sasxa +.section sasxb +.section sasya +.section sasyb +.section sasza +.section saszb +.section sas1a +.section sas1b +.section sas2a +.section sas2b +.section sas3a +.section sas3b +.section sas4a +.section sas4b +.section sas5a +.section sas5b +.section sas6a +.section sas6b +.section sas7a +.section sas7b +.section sas8a +.section sas8b +.section sas9a +.section sas9b +.section sas0a +.section sas0b +.section sataa +.section satab +.section satba +.section satbb +.section satca +.section satcb +.section satda +.section satdb +.section satea +.section sateb +.section satfa +.section satfb +.section satga +.section satgb +.section satha +.section sathb +.section satia +.section satib +.section satja +.section satjb +.section satka +.section satkb +.section satla +.section satlb +.section satma +.section satmb +.section satna +.section satnb +.section satoa +.section satob +.section satpa +.section satpb +.section satqa +.section satqb +.section satra +.section satrb +.section satsa +.section satsb +.section satta +.section sattb +.section satua +.section satub +.section satva +.section satvb +.section satwa +.section satwb +.section satxa +.section satxb +.section satya +.section satyb +.section satza +.section satzb +.section sat1a +.section sat1b +.section sat2a +.section sat2b +.section sat3a +.section sat3b +.section sat4a +.section sat4b +.section sat5a +.section sat5b +.section sat6a +.section sat6b +.section sat7a +.section sat7b +.section sat8a +.section sat8b +.section sat9a +.section sat9b +.section sat0a +.section sat0b +.section sauaa +.section sauab +.section sauba +.section saubb +.section sauca +.section saucb +.section sauda +.section saudb +.section sauea +.section saueb +.section saufa +.section saufb +.section sauga +.section saugb +.section sauha +.section sauhb +.section sauia +.section sauib +.section sauja +.section saujb +.section sauka +.section saukb +.section saula +.section saulb +.section sauma +.section saumb +.section sauna +.section saunb +.section sauoa +.section sauob +.section saupa +.section saupb +.section sauqa +.section sauqb +.section saura +.section saurb +.section sausa +.section sausb +.section sauta +.section sautb +.section sauua +.section sauub +.section sauva +.section sauvb +.section sauwa +.section sauwb +.section sauxa +.section sauxb +.section sauya +.section sauyb +.section sauza +.section sauzb +.section sau1a +.section sau1b +.section sau2a +.section sau2b +.section sau3a +.section sau3b +.section sau4a +.section sau4b +.section sau5a +.section sau5b +.section sau6a +.section sau6b +.section sau7a +.section sau7b +.section sau8a +.section sau8b +.section sau9a +.section sau9b +.section sau0a +.section sau0b +.section savaa +.section savab +.section savba +.section savbb +.section savca +.section savcb +.section savda +.section savdb +.section savea +.section saveb +.section savfa +.section savfb +.section savga +.section savgb +.section savha +.section savhb +.section savia +.section savib +.section savja +.section savjb +.section savka +.section savkb +.section savla +.section savlb +.section savma +.section savmb +.section savna +.section savnb +.section savoa +.section savob +.section savpa +.section savpb +.section savqa +.section savqb +.section savra +.section savrb +.section savsa +.section savsb +.section savta +.section savtb +.section savua +.section savub +.section savva +.section savvb +.section savwa +.section savwb +.section savxa +.section savxb +.section savya +.section savyb +.section savza +.section savzb +.section sav1a +.section sav1b +.section sav2a +.section sav2b +.section sav3a +.section sav3b +.section sav4a +.section sav4b +.section sav5a +.section sav5b +.section sav6a +.section sav6b +.section sav7a +.section sav7b +.section sav8a +.section sav8b +.section sav9a +.section sav9b +.section sav0a +.section sav0b +.section sawaa +.section sawab +.section sawba +.section sawbb +.section sawca +.section sawcb +.section sawda +.section sawdb +.section sawea +.section saweb +.section sawfa +.section sawfb +.section sawga +.section sawgb +.section sawha +.section sawhb +.section sawia +.section sawib +.section sawja +.section sawjb +.section sawka +.section sawkb +.section sawla +.section sawlb +.section sawma +.section sawmb +.section sawna +.section sawnb +.section sawoa +.section sawob +.section sawpa +.section sawpb +.section sawqa +.section sawqb +.section sawra +.section sawrb +.section sawsa +.section sawsb +.section sawta +.section sawtb +.section sawua +.section sawub +.section sawva +.section sawvb +.section sawwa +.section sawwb +.section sawxa +.section sawxb +.section sawya +.section sawyb +.section sawza +.section sawzb +.section saw1a +.section saw1b +.section saw2a +.section saw2b +.section saw3a +.section saw3b +.section saw4a +.section saw4b +.section saw5a +.section saw5b +.section saw6a +.section saw6b +.section saw7a +.section saw7b +.section saw8a +.section saw8b +.section saw9a +.section saw9b +.section saw0a +.section saw0b +.section saxaa +.section saxab +.section saxba +.section saxbb +.section saxca +.section saxcb +.section saxda +.section saxdb +.section saxea +.section saxeb +.section saxfa +.section saxfb +.section saxga +.section saxgb +.section saxha +.section saxhb +.section saxia +.section saxib +.section saxja +.section saxjb +.section saxka +.section saxkb +.section saxla +.section saxlb +.section saxma +.section saxmb +.section saxna +.section saxnb +.section saxoa +.section saxob +.section saxpa +.section saxpb +.section saxqa +.section saxqb +.section saxra +.section saxrb +.section saxsa +.section saxsb +.section saxta +.section saxtb +.section saxua +.section saxub +.section saxva +.section saxvb +.section saxwa +.section saxwb +.section saxxa +.section saxxb +.section saxya +.section saxyb +.section saxza +.section saxzb +.section sax1a +.section sax1b +.section sax2a +.section sax2b +.section sax3a +.section sax3b +.section sax4a +.section sax4b +.section sax5a +.section sax5b +.section sax6a +.section sax6b +.section sax7a +.section sax7b +.section sax8a +.section sax8b +.section sax9a +.section sax9b +.section sax0a +.section sax0b +.section sayaa +.section sayab +.section sayba +.section saybb +.section sayca +.section saycb +.section sayda +.section saydb +.section sayea +.section sayeb +.section sayfa +.section sayfb +.section sayga +.section saygb +.section sayha +.section sayhb +.section sayia +.section sayib +.section sayja +.section sayjb +.section sayka +.section saykb +.section sayla +.section saylb +.section sayma +.section saymb +.section sayna +.section saynb +.section sayoa +.section sayob +.section saypa +.section saypb +.section sayqa +.section sayqb +.section sayra +.section sayrb +.section saysa +.section saysb +.section sayta +.section saytb +.section sayua +.section sayub +.section sayva +.section sayvb +.section saywa +.section saywb +.section sayxa +.section sayxb +.section sayya +.section sayyb +.section sayza +.section sayzb +.section say1a +.section say1b +.section say2a +.section say2b +.section say3a +.section say3b +.section say4a +.section say4b +.section say5a +.section say5b +.section say6a +.section say6b +.section say7a +.section say7b +.section say8a +.section say8b +.section say9a +.section say9b +.section say0a +.section say0b +.section sazaa +.section sazab +.section sazba +.section sazbb +.section sazca +.section sazcb +.section sazda +.section sazdb +.section sazea +.section sazeb +.section sazfa +.section sazfb +.section sazga +.section sazgb +.section sazha +.section sazhb +.section sazia +.section sazib +.section sazja +.section sazjb +.section sazka +.section sazkb +.section sazla +.section sazlb +.section sazma +.section sazmb +.section sazna +.section saznb +.section sazoa +.section sazob +.section sazpa +.section sazpb +.section sazqa +.section sazqb +.section sazra +.section sazrb +.section sazsa +.section sazsb +.section sazta +.section saztb +.section sazua +.section sazub +.section sazva +.section sazvb +.section sazwa +.section sazwb +.section sazxa +.section sazxb +.section sazya +.section sazyb +.section sazza +.section sazzb +.section saz1a +.section saz1b +.section saz2a +.section saz2b +.section saz3a +.section saz3b +.section saz4a +.section saz4b +.section saz5a +.section saz5b +.section saz6a +.section saz6b +.section saz7a +.section saz7b +.section saz8a +.section saz8b +.section saz9a +.section saz9b +.section saz0a +.section saz0b +.section sa1aa +.section sa1ab +.section sa1ba +.section sa1bb +.section sa1ca +.section sa1cb +.section sa1da +.section sa1db +.section sa1ea +.section sa1eb +.section sa1fa +.section sa1fb +.section sa1ga +.section sa1gb +.section sa1ha +.section sa1hb +.section sa1ia +.section sa1ib +.section sa1ja +.section sa1jb +.section sa1ka +.section sa1kb +.section sa1la +.section sa1lb +.section sa1ma +.section sa1mb +.section sa1na +.section sa1nb +.section sa1oa +.section sa1ob +.section sa1pa +.section sa1pb +.section sa1qa +.section sa1qb +.section sa1ra +.section sa1rb +.section sa1sa +.section sa1sb +.section sa1ta +.section sa1tb +.section sa1ua +.section sa1ub +.section sa1va +.section sa1vb +.section sa1wa +.section sa1wb +.section sa1xa +.section sa1xb +.section sa1ya +.section sa1yb +.section sa1za +.section sa1zb +.section sa11a +.section sa11b +.section sa12a +.section sa12b +.section sa13a +.section sa13b +.section sa14a +.section sa14b +.section sa15a +.section sa15b +.section sa16a +.section sa16b +.section sa17a +.section sa17b +.section sa18a +.section sa18b +.section sa19a +.section sa19b +.section sa10a +.section sa10b +.section sa2aa +.section sa2ab +.section sa2ba +.section sa2bb +.section sa2ca +.section sa2cb +.section sa2da +.section sa2db +.section sa2ea +.section sa2eb +.section sa2fa +.section sa2fb +.section sa2ga +.section sa2gb +.section sa2ha +.section sa2hb +.section sa2ia +.section sa2ib +.section sa2ja +.section sa2jb +.section sa2ka +.section sa2kb +.section sa2la +.section sa2lb +.section sa2ma +.section sa2mb +.section sa2na +.section sa2nb +.section sa2oa +.section sa2ob +.section sa2pa +.section sa2pb +.section sa2qa +.section sa2qb +.section sa2ra +.section sa2rb +.section sa2sa +.section sa2sb +.section sa2ta +.section sa2tb +.section sa2ua +.section sa2ub +.section sa2va +.section sa2vb +.section sa2wa +.section sa2wb +.section sa2xa +.section sa2xb +.section sa2ya +.section sa2yb +.section sa2za +.section sa2zb +.section sa21a +.section sa21b +.section sa22a +.section sa22b +.section sa23a +.section sa23b +.section sa24a +.section sa24b +.section sa25a +.section sa25b +.section sa26a +.section sa26b +.section sa27a +.section sa27b +.section sa28a +.section sa28b +.section sa29a +.section sa29b +.section sa20a +.section sa20b +.section sa3aa +.section sa3ab +.section sa3ba +.section sa3bb +.section sa3ca +.section sa3cb +.section sa3da +.section sa3db +.section sa3ea +.section sa3eb +.section sa3fa +.section sa3fb +.section sa3ga +.section sa3gb +.section sa3ha +.section sa3hb +.section sa3ia +.section sa3ib +.section sa3ja +.section sa3jb +.section sa3ka +.section sa3kb +.section sa3la +.section sa3lb +.section sa3ma +.section sa3mb +.section sa3na +.section sa3nb +.section sa3oa +.section sa3ob +.section sa3pa +.section sa3pb +.section sa3qa +.section sa3qb +.section sa3ra +.section sa3rb +.section sa3sa +.section sa3sb +.section sa3ta +.section sa3tb +.section sa3ua +.section sa3ub +.section sa3va +.section sa3vb +.section sa3wa +.section sa3wb +.section sa3xa +.section sa3xb +.section sa3ya +.section sa3yb +.section sa3za +.section sa3zb +.section sa31a +.section sa31b +.section sa32a +.section sa32b +.section sa33a +.section sa33b +.section sa34a +.section sa34b +.section sa35a +.section sa35b +.section sa36a +.section sa36b +.section sa37a +.section sa37b +.section sa38a +.section sa38b +.section sa39a +.section sa39b +.section sa30a +.section sa30b +.section sa4aa +.section sa4ab +.section sa4ba +.section sa4bb +.section sa4ca +.section sa4cb +.section sa4da +.section sa4db +.section sa4ea +.section sa4eb +.section sa4fa +.section sa4fb +.section sa4ga +.section sa4gb +.section sa4ha +.section sa4hb +.section sa4ia +.section sa4ib +.section sa4ja +.section sa4jb +.section sa4ka +.section sa4kb +.section sa4la +.section sa4lb +.section sa4ma +.section sa4mb +.section sa4na +.section sa4nb +.section sa4oa +.section sa4ob +.section sa4pa +.section sa4pb +.section sa4qa +.section sa4qb +.section sa4ra +.section sa4rb +.section sa4sa +.section sa4sb +.section sa4ta +.section sa4tb +.section sa4ua +.section sa4ub +.section sa4va +.section sa4vb +.section sa4wa +.section sa4wb +.section sa4xa +.section sa4xb +.section sa4ya +.section sa4yb +.section sa4za +.section sa4zb +.section sa41a +.section sa41b +.section sa42a +.section sa42b +.section sa43a +.section sa43b +.section sa44a +.section sa44b +.section sa45a +.section sa45b +.section sa46a +.section sa46b +.section sa47a +.section sa47b +.section sa48a +.section sa48b +.section sa49a +.section sa49b +.section sa40a +.section sa40b +.section sa5aa +.section sa5ab +.section sa5ba +.section sa5bb +.section sa5ca +.section sa5cb +.section sa5da +.section sa5db +.section sa5ea +.section sa5eb +.section sa5fa +.section sa5fb +.section sa5ga +.section sa5gb +.section sa5ha +.section sa5hb +.section sa5ia +.section sa5ib +.section sa5ja +.section sa5jb +.section sa5ka +.section sa5kb +.section sa5la +.section sa5lb +.section sa5ma +.section sa5mb +.section sa5na +.section sa5nb +.section sa5oa +.section sa5ob +.section sa5pa +.section sa5pb +.section sa5qa +.section sa5qb +.section sa5ra +.section sa5rb +.section sa5sa +.section sa5sb +.section sa5ta +.section sa5tb +.section sa5ua +.section sa5ub +.section sa5va +.section sa5vb +.section sa5wa +.section sa5wb +.section sa5xa +.section sa5xb +.section sa5ya +.section sa5yb +.section sa5za +.section sa5zb +.section sa51a +.section sa51b +.section sa52a +.section sa52b +.section sa53a +.section sa53b +.section sa54a +.section sa54b +.section sa55a +.section sa55b +.section sa56a +.section sa56b +.section sa57a +.section sa57b +.section sa58a +.section sa58b +.section sa59a +.section sa59b +.section sa50a +.section sa50b +.section sa6aa +.section sa6ab +.section sa6ba +.section sa6bb +.section sa6ca +.section sa6cb +.section sa6da +.section sa6db +.section sa6ea +.section sa6eb +.section sa6fa +.section sa6fb +.section sa6ga +.section sa6gb +.section sa6ha +.section sa6hb +.section sa6ia +.section sa6ib +.section sa6ja +.section sa6jb +.section sa6ka +.section sa6kb +.section sa6la +.section sa6lb +.section sa6ma +.section sa6mb +.section sa6na +.section sa6nb +.section sa6oa +.section sa6ob +.section sa6pa +.section sa6pb +.section sa6qa +.section sa6qb +.section sa6ra +.section sa6rb +.section sa6sa +.section sa6sb +.section sa6ta +.section sa6tb +.section sa6ua +.section sa6ub +.section sa6va +.section sa6vb +.section sa6wa +.section sa6wb +.section sa6xa +.section sa6xb +.section sa6ya +.section sa6yb +.section sa6za +.section sa6zb +.section sa61a +.section sa61b +.section sa62a +.section sa62b +.section sa63a +.section sa63b +.section sa64a +.section sa64b +.section sa65a +.section sa65b +.section sa66a +.section sa66b +.section sa67a +.section sa67b +.section sa68a +.section sa68b +.section sa69a +.section sa69b +.section sa60a +.section sa60b +.section sa7aa +.section sa7ab +.section sa7ba +.section sa7bb +.section sa7ca +.section sa7cb +.section sa7da +.section sa7db +.section sa7ea +.section sa7eb +.section sa7fa +.section sa7fb +.section sa7ga +.section sa7gb +.section sa7ha +.section sa7hb +.section sa7ia +.section sa7ib +.section sa7ja +.section sa7jb +.section sa7ka +.section sa7kb +.section sa7la +.section sa7lb +.section sa7ma +.section sa7mb +.section sa7na +.section sa7nb +.section sa7oa +.section sa7ob +.section sa7pa +.section sa7pb +.section sa7qa +.section sa7qb +.section sa7ra +.section sa7rb +.section sa7sa +.section sa7sb +.section sa7ta +.section sa7tb +.section sa7ua +.section sa7ub +.section sa7va +.section sa7vb +.section sa7wa +.section sa7wb +.section sa7xa +.section sa7xb +.section sa7ya +.section sa7yb +.section sa7za +.section sa7zb +.section sa71a +.section sa71b +.section sa72a +.section sa72b +.section sa73a +.section sa73b +.section sa74a +.section sa74b +.section sa75a +.section sa75b +.section sa76a +.section sa76b +.section sa77a +.section sa77b +.section sa78a +.section sa78b +.section sa79a +.section sa79b +.section sa70a +.section sa70b +.section sa8aa +.section sa8ab +.section sa8ba +.section sa8bb +.section sa8ca +.section sa8cb +.section sa8da +.section sa8db +.section sa8ea +.section sa8eb +.section sa8fa +.section sa8fb +.section sa8ga +.section sa8gb +.section sa8ha +.section sa8hb +.section sa8ia +.section sa8ib +.section sa8ja +.section sa8jb +.section sa8ka +.section sa8kb +.section sa8la +.section sa8lb +.section sa8ma +.section sa8mb +.section sa8na +.section sa8nb +.section sa8oa +.section sa8ob +.section sa8pa +.section sa8pb +.section sa8qa +.section sa8qb +.section sa8ra +.section sa8rb +.section sa8sa +.section sa8sb +.section sa8ta +.section sa8tb +.section sa8ua +.section sa8ub +.section sa8va +.section sa8vb +.section sa8wa +.section sa8wb +.section sa8xa +.section sa8xb +.section sa8ya +.section sa8yb +.section sa8za +.section sa8zb +.section sa81a +.section sa81b +.section sa82a +.section sa82b +.section sa83a +.section sa83b +.section sa84a +.section sa84b +.section sa85a +.section sa85b +.section sa86a +.section sa86b +.section sa87a +.section sa87b +.section sa88a +.section sa88b +.section sa89a +.section sa89b +.section sa80a +.section sa80b +.section sa9aa +.section sa9ab +.section sa9ba +.section sa9bb +.section sa9ca +.section sa9cb +.section sa9da +.section sa9db +.section sa9ea +.section sa9eb +.section sa9fa +.section sa9fb +.section sa9ga +.section sa9gb +.section sa9ha +.section sa9hb +.section sa9ia +.section sa9ib +.section sa9ja +.section sa9jb +.section sa9ka +.section sa9kb +.section sa9la +.section sa9lb +.section sa9ma +.section sa9mb +.section sa9na +.section sa9nb +.section sa9oa +.section sa9ob +.section sa9pa +.section sa9pb +.section sa9qa +.section sa9qb +.section sa9ra +.section sa9rb +.section sa9sa +.section sa9sb +.section sa9ta +.section sa9tb +.section sa9ua +.section sa9ub +.section sa9va +.section sa9vb +.section sa9wa +.section sa9wb +.section sa9xa +.section sa9xb +.section sa9ya +.section sa9yb +.section sa9za +.section sa9zb +.section sa91a +.section sa91b +.section sa92a +.section sa92b +.section sa93a +.section sa93b +.section sa94a +.section sa94b +.section sa95a +.section sa95b +.section sa96a +.section sa96b +.section sa97a +.section sa97b +.section sa98a +.section sa98b +.section sa99a +.section sa99b +.section sa90a +.section sa90b +.section sa0aa +.section sa0ab +.section sa0ba +.section sa0bb +.section sa0ca +.section sa0cb +.section sa0da +.section sa0db +.section sa0ea +.section sa0eb +.section sa0fa +.section sa0fb +.section sa0ga +.section sa0gb +.section sa0ha +.section sa0hb +.section sa0ia +.section sa0ib +.section sa0ja +.section sa0jb +.section sa0ka +.section sa0kb +.section sa0la +.section sa0lb +.section sa0ma +.section sa0mb +.section sa0na +.section sa0nb +.section sa0oa +.section sa0ob +.section sa0pa +.section sa0pb +.section sa0qa +.section sa0qb +.section sa0ra +.section sa0rb +.section sa0sa +.section sa0sb +.section sa0ta +.section sa0tb +.section sa0ua +.section sa0ub +.section sa0va +.section sa0vb +.section sa0wa +.section sa0wb +.section sa0xa +.section sa0xb +.section sa0ya +.section sa0yb +.section sa0za +.section sa0zb +.section sa01a +.section sa01b +.section sa02a +.section sa02b +.section sa03a +.section sa03b +.section sa04a +.section sa04b +.section sa05a +.section sa05b +.section sa06a +.section sa06b +.section sa07a +.section sa07b +.section sa08a +.section sa08b +.section sa09a +.section sa09b +.section sa00a +.section sa00b +.section sbaaa +.section sbaab +.section sbaba +.section sbabb +.section sbaca +.section sbacb +.section sbada +.section sbadb +.section sbaea +.section sbaeb +.section sbafa +.section sbafb +.section sbaga +.section sbagb +.section sbaha +.section sbahb +.section sbaia +.section sbaib +.section sbaja +.section sbajb +.section sbaka +.section sbakb +.section sbala +.section sbalb +.section sbama +.section sbamb +.section sbana +.section sbanb +.section sbaoa +.section sbaob +.section sbapa +.section sbapb +.section sbaqa +.section sbaqb +.section sbara +.section sbarb +.section sbasa +.section sbasb +.section sbata +.section sbatb +.section sbaua +.section sbaub +.section sbava +.section sbavb +.section sbawa +.section sbawb +.section sbaxa +.section sbaxb +.section sbaya +.section sbayb +.section sbaza +.section sbazb +.section sba1a +.section sba1b +.section sba2a +.section sba2b +.section sba3a +.section sba3b +.section sba4a +.section sba4b +.section sba5a +.section sba5b +.section sba6a +.section sba6b +.section sba7a +.section sba7b +.section sba8a +.section sba8b +.section sba9a +.section sba9b +.section sba0a +.section sba0b +.section sbbaa +.section sbbab +.section sbbba +.section sbbbb +.section sbbca +.section sbbcb +.section sbbda +.section sbbdb +.section sbbea +.section sbbeb +.section sbbfa +.section sbbfb +.section sbbga +.section sbbgb +.section sbbha +.section sbbhb +.section sbbia +.section sbbib +.section sbbja +.section sbbjb +.section sbbka +.section sbbkb +.section sbbla +.section sbblb +.section sbbma +.section sbbmb +.section sbbna +.section sbbnb +.section sbboa +.section sbbob +.section sbbpa +.section sbbpb +.section sbbqa +.section sbbqb +.section sbbra +.section sbbrb +.section sbbsa +.section sbbsb +.section sbbta +.section sbbtb +.section sbbua +.section sbbub +.section sbbva +.section sbbvb +.section sbbwa +.section sbbwb +.section sbbxa +.section sbbxb +.section sbbya +.section sbbyb +.section sbbza +.section sbbzb +.section sbb1a +.section sbb1b +.section sbb2a +.section sbb2b +.section sbb3a +.section sbb3b +.section sbb4a +.section sbb4b +.section sbb5a +.section sbb5b +.section sbb6a +.section sbb6b +.section sbb7a +.section sbb7b +.section sbb8a +.section sbb8b +.section sbb9a +.section sbb9b +.section sbb0a +.section sbb0b +.section sbcaa +.section sbcab +.section sbcba +.section sbcbb +.section sbcca +.section sbccb +.section sbcda +.section sbcdb +.section sbcea +.section sbceb +.section sbcfa +.section sbcfb +.section sbcga +.section sbcgb +.section sbcha +.section sbchb +.section sbcia +.section sbcib +.section sbcja +.section sbcjb +.section sbcka +.section sbckb +.section sbcla +.section sbclb +.section sbcma +.section sbcmb +.section sbcna +.section sbcnb +.section sbcoa +.section sbcob +.section sbcpa +.section sbcpb +.section sbcqa +.section sbcqb +.section sbcra +.section sbcrb +.section sbcsa +.section sbcsb +.section sbcta +.section sbctb +.section sbcua +.section sbcub +.section sbcva +.section sbcvb +.section sbcwa +.section sbcwb +.section sbcxa +.section sbcxb +.section sbcya +.section sbcyb +.section sbcza +.section sbczb +.section sbc1a +.section sbc1b +.section sbc2a +.section sbc2b +.section sbc3a +.section sbc3b +.section sbc4a +.section sbc4b +.section sbc5a +.section sbc5b +.section sbc6a +.section sbc6b +.section sbc7a +.section sbc7b +.section sbc8a +.section sbc8b +.section sbc9a +.section sbc9b +.section sbc0a +.section sbc0b +.section sbdaa +.section sbdab +.section sbdba +.section sbdbb +.section sbdca +.section sbdcb +.section sbdda +.section sbddb +.section sbdea +.section sbdeb +.section sbdfa +.section sbdfb +.section sbdga +.section sbdgb +.section sbdha +.section sbdhb +.section sbdia +.section sbdib +.section sbdja +.section sbdjb +.section sbdka +.section sbdkb +.section sbdla +.section sbdlb +.section sbdma +.section sbdmb +.section sbdna +.section sbdnb +.section sbdoa +.section sbdob +.section sbdpa +.section sbdpb +.section sbdqa +.section sbdqb +.section sbdra +.section sbdrb +.section sbdsa +.section sbdsb +.section sbdta +.section sbdtb +.section sbdua +.section sbdub +.section sbdva +.section sbdvb +.section sbdwa +.section sbdwb +.section sbdxa +.section sbdxb +.section sbdya +.section sbdyb +.section sbdza +.section sbdzb +.section sbd1a +.section sbd1b +.section sbd2a +.section sbd2b +.section sbd3a +.section sbd3b +.section sbd4a +.section sbd4b +.section sbd5a +.section sbd5b +.section sbd6a +.section sbd6b +.section sbd7a +.section sbd7b +.section sbd8a +.section sbd8b +.section sbd9a +.section sbd9b +.section sbd0a +.section sbd0b +.section sbeaa +.section sbeab +.section sbeba +.section sbebb +.section sbeca +.section sbecb +.section sbeda +.section sbedb +.section sbeea +.section sbeeb +.section sbefa +.section sbefb +.section sbega +.section sbegb +.section sbeha +.section sbehb +.section sbeia +.section sbeib +.section sbeja +.section sbejb +.section sbeka +.section sbekb +.section sbela +.section sbelb +.section sbema +.section sbemb +.section sbena +.section sbenb +.section sbeoa +.section sbeob +.section sbepa +.section sbepb +.section sbeqa +.section sbeqb +.section sbera +.section sberb +.section sbesa +.section sbesb +.section sbeta +.section sbetb +.section sbeua +.section sbeub +.section sbeva +.section sbevb +.section sbewa +.section sbewb +.section sbexa +.section sbexb +.section sbeya +.section sbeyb +.section sbeza +.section sbezb +.section sbe1a +.section sbe1b +.section sbe2a +.section sbe2b +.section sbe3a +.section sbe3b +.section sbe4a +.section sbe4b +.section sbe5a +.section sbe5b +.section sbe6a +.section sbe6b +.section sbe7a +.section sbe7b +.section sbe8a +.section sbe8b +.section sbe9a +.section sbe9b +.section sbe0a +.section sbe0b +.section sbfaa +.section sbfab +.section sbfba +.section sbfbb +.section sbfca +.section sbfcb +.section sbfda +.section sbfdb +.section sbfea +.section sbfeb +.section sbffa +.section sbffb +.section sbfga +.section sbfgb +.section sbfha +.section sbfhb +.section sbfia +.section sbfib +.section sbfja +.section sbfjb +.section sbfka +.section sbfkb +.section sbfla +.section sbflb +.section sbfma +.section sbfmb +.section sbfna +.section sbfnb +.section sbfoa +.section sbfob +.section sbfpa +.section sbfpb +.section sbfqa +.section sbfqb +.section sbfra +.section sbfrb +.section sbfsa +.section sbfsb +.section sbfta +.section sbftb +.section sbfua +.section sbfub +.section sbfva +.section sbfvb +.section sbfwa +.section sbfwb +.section sbfxa +.section sbfxb +.section sbfya +.section sbfyb +.section sbfza +.section sbfzb +.section sbf1a +.section sbf1b +.section sbf2a +.section sbf2b +.section sbf3a +.section sbf3b +.section sbf4a +.section sbf4b +.section sbf5a +.section sbf5b +.section sbf6a +.section sbf6b +.section sbf7a +.section sbf7b +.section sbf8a +.section sbf8b +.section sbf9a +.section sbf9b +.section sbf0a +.section sbf0b +.section sbgaa +.section sbgab +.section sbgba +.section sbgbb +.section sbgca +.section sbgcb +.section sbgda +.section sbgdb +.section sbgea +.section sbgeb +.section sbgfa +.section sbgfb +.section sbgga +.section sbggb +.section sbgha +.section sbghb +.section sbgia +.section sbgib +.section sbgja +.section sbgjb +.section sbgka +.section sbgkb +.section sbgla +.section sbglb +.section sbgma +.section sbgmb +.section sbgna +.section sbgnb +.section sbgoa +.section sbgob +.section sbgpa +.section sbgpb +.section sbgqa +.section sbgqb +.section sbgra +.section sbgrb +.section sbgsa +.section sbgsb +.section sbgta +.section sbgtb +.section sbgua +.section sbgub +.section sbgva +.section sbgvb +.section sbgwa +.section sbgwb +.section sbgxa +.section sbgxb +.section sbgya +.section sbgyb +.section sbgza +.section sbgzb +.section sbg1a +.section sbg1b +.section sbg2a +.section sbg2b +.section sbg3a +.section sbg3b +.section sbg4a +.section sbg4b +.section sbg5a +.section sbg5b +.section sbg6a +.section sbg6b +.section sbg7a +.section sbg7b +.section sbg8a +.section sbg8b +.section sbg9a +.section sbg9b +.section sbg0a +.section sbg0b +.section sbhaa +.section sbhab +.section sbhba +.section sbhbb +.section sbhca +.section sbhcb +.section sbhda +.section sbhdb +.section sbhea +.section sbheb +.section sbhfa +.section sbhfb +.section sbhga +.section sbhgb +.section sbhha +.section sbhhb +.section sbhia +.section sbhib +.section sbhja +.section sbhjb +.section sbhka +.section sbhkb +.section sbhla +.section sbhlb +.section sbhma +.section sbhmb +.section sbhna +.section sbhnb +.section sbhoa +.section sbhob +.section sbhpa +.section sbhpb +.section sbhqa +.section sbhqb +.section sbhra +.section sbhrb +.section sbhsa +.section sbhsb +.section sbhta +.section sbhtb +.section sbhua +.section sbhub +.section sbhva +.section sbhvb +.section sbhwa +.section sbhwb +.section sbhxa +.section sbhxb +.section sbhya +.section sbhyb +.section sbhza +.section sbhzb +.section sbh1a +.section sbh1b +.section sbh2a +.section sbh2b +.section sbh3a +.section sbh3b +.section sbh4a +.section sbh4b +.section sbh5a +.section sbh5b +.section sbh6a +.section sbh6b +.section sbh7a +.section sbh7b +.section sbh8a +.section sbh8b +.section sbh9a +.section sbh9b +.section sbh0a +.section sbh0b +.section sbiaa +.section sbiab +.section sbiba +.section sbibb +.section sbica +.section sbicb +.section sbida +.section sbidb +.section sbiea +.section sbieb +.section sbifa +.section sbifb +.section sbiga +.section sbigb +.section sbiha +.section sbihb +.section sbiia +.section sbiib +.section sbija +.section sbijb +.section sbika +.section sbikb +.section sbila +.section sbilb +.section sbima +.section sbimb +.section sbina +.section sbinb +.section sbioa +.section sbiob +.section sbipa +.section sbipb +.section sbiqa +.section sbiqb +.section sbira +.section sbirb +.section sbisa +.section sbisb +.section sbita +.section sbitb +.section sbiua +.section sbiub +.section sbiva +.section sbivb +.section sbiwa +.section sbiwb +.section sbixa +.section sbixb +.section sbiya +.section sbiyb +.section sbiza +.section sbizb +.section sbi1a +.section sbi1b +.section sbi2a +.section sbi2b +.section sbi3a +.section sbi3b +.section sbi4a +.section sbi4b +.section sbi5a +.section sbi5b +.section sbi6a +.section sbi6b +.section sbi7a +.section sbi7b +.section sbi8a +.section sbi8b +.section sbi9a +.section sbi9b +.section sbi0a +.section sbi0b +.section sbjaa +.section sbjab +.section sbjba +.section sbjbb +.section sbjca +.section sbjcb +.section sbjda +.section sbjdb +.section sbjea +.section sbjeb +.section sbjfa +.section sbjfb +.section sbjga +.section sbjgb +.section sbjha +.section sbjhb +.section sbjia +.section sbjib +.section sbjja +.section sbjjb +.section sbjka +.section sbjkb +.section sbjla +.section sbjlb +.section sbjma +.section sbjmb +.section sbjna +.section sbjnb +.section sbjoa +.section sbjob +.section sbjpa +.section sbjpb +.section sbjqa +.section sbjqb +.section sbjra +.section sbjrb +.section sbjsa +.section sbjsb +.section sbjta +.section sbjtb +.section sbjua +.section sbjub +.section sbjva +.section sbjvb +.section sbjwa +.section sbjwb +.section sbjxa +.section sbjxb +.section sbjya +.section sbjyb +.section sbjza +.section sbjzb +.section sbj1a +.section sbj1b +.section sbj2a +.section sbj2b +.section sbj3a +.section sbj3b +.section sbj4a +.section sbj4b +.section sbj5a +.section sbj5b +.section sbj6a +.section sbj6b +.section sbj7a +.section sbj7b +.section sbj8a +.section sbj8b +.section sbj9a +.section sbj9b +.section sbj0a +.section sbj0b +.section sbkaa +.section sbkab +.section sbkba +.section sbkbb +.section sbkca +.section sbkcb +.section sbkda +.section sbkdb +.section sbkea +.section sbkeb +.section sbkfa +.section sbkfb +.section sbkga +.section sbkgb +.section sbkha +.section sbkhb +.section sbkia +.section sbkib +.section sbkja +.section sbkjb +.section sbkka +.section sbkkb +.section sbkla +.section sbklb +.section sbkma +.section sbkmb +.section sbkna +.section sbknb +.section sbkoa +.section sbkob +.section sbkpa +.section sbkpb +.section sbkqa +.section sbkqb +.section sbkra +.section sbkrb +.section sbksa +.section sbksb +.section sbkta +.section sbktb +.section sbkua +.section sbkub +.section sbkva +.section sbkvb +.section sbkwa +.section sbkwb +.section sbkxa +.section sbkxb +.section sbkya +.section sbkyb +.section sbkza +.section sbkzb +.section sbk1a +.section sbk1b +.section sbk2a +.section sbk2b +.section sbk3a +.section sbk3b +.section sbk4a +.section sbk4b +.section sbk5a +.section sbk5b +.section sbk6a +.section sbk6b +.section sbk7a +.section sbk7b +.section sbk8a +.section sbk8b +.section sbk9a +.section sbk9b +.section sbk0a +.section sbk0b +.section sblaa +.section sblab +.section sblba +.section sblbb +.section sblca +.section sblcb +.section sblda +.section sbldb +.section sblea +.section sbleb +.section sblfa +.section sblfb +.section sblga +.section sblgb +.section sblha +.section sblhb +.section sblia +.section sblib +.section sblja +.section sbljb +.section sblka +.section sblkb +.section sblla +.section sbllb +.section sblma +.section sblmb +.section sblna +.section sblnb +.section sbloa +.section sblob +.section sblpa +.section sblpb +.section sblqa +.section sblqb +.section sblra +.section sblrb +.section sblsa +.section sblsb +.section sblta +.section sbltb +.section sblua +.section sblub +.section sblva +.section sblvb +.section sblwa +.section sblwb +.section sblxa +.section sblxb +.section sblya +.section sblyb +.section sblza +.section sblzb +.section sbl1a +.section sbl1b +.section sbl2a +.section sbl2b +.section sbl3a +.section sbl3b +.section sbl4a +.section sbl4b +.section sbl5a +.section sbl5b +.section sbl6a +.section sbl6b +.section sbl7a +.section sbl7b +.section sbl8a +.section sbl8b +.section sbl9a +.section sbl9b +.section sbl0a +.section sbl0b +.section sbmaa +.section sbmab +.section sbmba +.section sbmbb +.section sbmca +.section sbmcb +.section sbmda +.section sbmdb +.section sbmea +.section sbmeb +.section sbmfa +.section sbmfb +.section sbmga +.section sbmgb +.section sbmha +.section sbmhb +.section sbmia +.section sbmib +.section sbmja +.section sbmjb +.section sbmka +.section sbmkb +.section sbmla +.section sbmlb +.section sbmma +.section sbmmb +.section sbmna +.section sbmnb +.section sbmoa +.section sbmob +.section sbmpa +.section sbmpb +.section sbmqa +.section sbmqb +.section sbmra +.section sbmrb +.section sbmsa +.section sbmsb +.section sbmta +.section sbmtb +.section sbmua +.section sbmub +.section sbmva +.section sbmvb +.section sbmwa +.section sbmwb +.section sbmxa +.section sbmxb +.section sbmya +.section sbmyb +.section sbmza +.section sbmzb +.section sbm1a +.section sbm1b +.section sbm2a +.section sbm2b +.section sbm3a +.section sbm3b +.section sbm4a +.section sbm4b +.section sbm5a +.section sbm5b +.section sbm6a +.section sbm6b +.section sbm7a +.section sbm7b +.section sbm8a +.section sbm8b +.section sbm9a +.section sbm9b +.section sbm0a +.section sbm0b +.section sbnaa +.section sbnab +.section sbnba +.section sbnbb +.section sbnca +.section sbncb +.section sbnda +.section sbndb +.section sbnea +.section sbneb +.section sbnfa +.section sbnfb +.section sbnga +.section sbngb +.section sbnha +.section sbnhb +.section sbnia +.section sbnib +.section sbnja +.section sbnjb +.section sbnka +.section sbnkb +.section sbnla +.section sbnlb +.section sbnma +.section sbnmb +.section sbnna +.section sbnnb +.section sbnoa +.section sbnob +.section sbnpa +.section sbnpb +.section sbnqa +.section sbnqb +.section sbnra +.section sbnrb +.section sbnsa +.section sbnsb +.section sbnta +.section sbntb +.section sbnua +.section sbnub +.section sbnva +.section sbnvb +.section sbnwa +.section sbnwb +.section sbnxa +.section sbnxb +.section sbnya +.section sbnyb +.section sbnza +.section sbnzb +.section sbn1a +.section sbn1b +.section sbn2a +.section sbn2b +.section sbn3a +.section sbn3b +.section sbn4a +.section sbn4b +.section sbn5a +.section sbn5b +.section sbn6a +.section sbn6b +.section sbn7a +.section sbn7b +.section sbn8a +.section sbn8b +.section sbn9a +.section sbn9b +.section sbn0a +.section sbn0b +.section sboaa +.section sboab +.section sboba +.section sbobb +.section sboca +.section sbocb +.section sboda +.section sbodb +.section sboea +.section sboeb +.section sbofa +.section sbofb +.section sboga +.section sbogb +.section sboha +.section sbohb +.section sboia +.section sboib +.section sboja +.section sbojb +.section sboka +.section sbokb +.section sbola +.section sbolb +.section sboma +.section sbomb +.section sbona +.section sbonb +.section sbooa +.section sboob +.section sbopa +.section sbopb +.section sboqa +.section sboqb +.section sbora +.section sborb +.section sbosa +.section sbosb +.section sbota +.section sbotb +.section sboua +.section sboub +.section sbova +.section sbovb +.section sbowa +.section sbowb +.section sboxa +.section sboxb +.section sboya +.section sboyb +.section sboza +.section sbozb +.section sbo1a +.section sbo1b +.section sbo2a +.section sbo2b +.section sbo3a +.section sbo3b +.section sbo4a +.section sbo4b +.section sbo5a +.section sbo5b +.section sbo6a +.section sbo6b +.section sbo7a +.section sbo7b +.section sbo8a +.section sbo8b +.section sbo9a +.section sbo9b +.section sbo0a +.section sbo0b +.section sbpaa +.section sbpab +.section sbpba +.section sbpbb +.section sbpca +.section sbpcb +.section sbpda +.section sbpdb +.section sbpea +.section sbpeb +.section sbpfa +.section sbpfb +.section sbpga +.section sbpgb +.section sbpha +.section sbphb +.section sbpia +.section sbpib +.section sbpja +.section sbpjb +.section sbpka +.section sbpkb +.section sbpla +.section sbplb +.section sbpma +.section sbpmb +.section sbpna +.section sbpnb +.section sbpoa +.section sbpob +.section sbppa +.section sbppb +.section sbpqa +.section sbpqb +.section sbpra +.section sbprb +.section sbpsa +.section sbpsb +.section sbpta +.section sbptb +.section sbpua +.section sbpub +.section sbpva +.section sbpvb +.section sbpwa +.section sbpwb +.section sbpxa +.section sbpxb +.section sbpya +.section sbpyb +.section sbpza +.section sbpzb +.section sbp1a +.section sbp1b +.section sbp2a +.section sbp2b +.section sbp3a +.section sbp3b +.section sbp4a +.section sbp4b +.section sbp5a +.section sbp5b +.section sbp6a +.section sbp6b +.section sbp7a +.section sbp7b +.section sbp8a +.section sbp8b +.section sbp9a +.section sbp9b +.section sbp0a +.section sbp0b +.section sbqaa +.section sbqab +.section sbqba +.section sbqbb +.section sbqca +.section sbqcb +.section sbqda +.section sbqdb +.section sbqea +.section sbqeb +.section sbqfa +.section sbqfb +.section sbqga +.section sbqgb +.section sbqha +.section sbqhb +.section sbqia +.section sbqib +.section sbqja +.section sbqjb +.section sbqka +.section sbqkb +.section sbqla +.section sbqlb +.section sbqma +.section sbqmb +.section sbqna +.section sbqnb +.section sbqoa +.section sbqob +.section sbqpa +.section sbqpb +.section sbqqa +.section sbqqb +.section sbqra +.section sbqrb +.section sbqsa +.section sbqsb +.section sbqta +.section sbqtb +.section sbqua +.section sbqub +.section sbqva +.section sbqvb +.section sbqwa +.section sbqwb +.section sbqxa +.section sbqxb +.section sbqya +.section sbqyb +.section sbqza +.section sbqzb +.section sbq1a +.section sbq1b +.section sbq2a +.section sbq2b +.section sbq3a +.section sbq3b +.section sbq4a +.section sbq4b +.section sbq5a +.section sbq5b +.section sbq6a +.section sbq6b +.section sbq7a +.section sbq7b +.section sbq8a +.section sbq8b +.section sbq9a +.section sbq9b +.section sbq0a +.section sbq0b +.section sbraa +.section sbrab +.section sbrba +.section sbrbb +.section sbrca +.section sbrcb +.section sbrda +.section sbrdb +.section sbrea +.section sbreb +.section sbrfa +.section sbrfb +.section sbrga +.section sbrgb +.section sbrha +.section sbrhb +.section sbria +.section sbrib +.section sbrja +.section sbrjb +.section sbrka +.section sbrkb +.section sbrla +.section sbrlb +.section sbrma +.section sbrmb +.section sbrna +.section sbrnb +.section sbroa +.section sbrob +.section sbrpa +.section sbrpb +.section sbrqa +.section sbrqb +.section sbrra +.section sbrrb +.section sbrsa +.section sbrsb +.section sbrta +.section sbrtb +.section sbrua +.section sbrub +.section sbrva +.section sbrvb +.section sbrwa +.section sbrwb +.section sbrxa +.section sbrxb +.section sbrya +.section sbryb +.section sbrza +.section sbrzb +.section sbr1a +.section sbr1b +.section sbr2a +.section sbr2b +.section sbr3a +.section sbr3b +.section sbr4a +.section sbr4b +.section sbr5a +.section sbr5b +.section sbr6a +.section sbr6b +.section sbr7a +.section sbr7b +.section sbr8a +.section sbr8b +.section sbr9a +.section sbr9b +.section sbr0a +.section sbr0b +.section sbsaa +.section sbsab +.section sbsba +.section sbsbb +.section sbsca +.section sbscb +.section sbsda +.section sbsdb +.section sbsea +.section sbseb +.section sbsfa +.section sbsfb +.section sbsga +.section sbsgb +.section sbsha +.section sbshb +.section sbsia +.section sbsib +.section sbsja +.section sbsjb +.section sbska +.section sbskb +.section sbsla +.section sbslb +.section sbsma +.section sbsmb +.section sbsna +.section sbsnb +.section sbsoa +.section sbsob +.section sbspa +.section sbspb +.section sbsqa +.section sbsqb +.section sbsra +.section sbsrb +.section sbssa +.section sbssb +.section sbsta +.section sbstb +.section sbsua +.section sbsub +.section sbsva +.section sbsvb +.section sbswa +.section sbswb +.section sbsxa +.section sbsxb +.section sbsya +.section sbsyb +.section sbsza +.section sbszb +.section sbs1a +.section sbs1b +.section sbs2a +.section sbs2b +.section sbs3a +.section sbs3b +.section sbs4a +.section sbs4b +.section sbs5a +.section sbs5b +.section sbs6a +.section sbs6b +.section sbs7a +.section sbs7b +.section sbs8a +.section sbs8b +.section sbs9a +.section sbs9b +.section sbs0a +.section sbs0b +.section sbtaa +.section sbtab +.section sbtba +.section sbtbb +.section sbtca +.section sbtcb +.section sbtda +.section sbtdb +.section sbtea +.section sbteb +.section sbtfa +.section sbtfb +.section sbtga +.section sbtgb +.section sbtha +.section sbthb +.section sbtia +.section sbtib +.section sbtja +.section sbtjb +.section sbtka +.section sbtkb +.section sbtla +.section sbtlb +.section sbtma +.section sbtmb +.section sbtna +.section sbtnb +.section sbtoa +.section sbtob +.section sbtpa +.section sbtpb +.section sbtqa +.section sbtqb +.section sbtra +.section sbtrb +.section sbtsa +.section sbtsb +.section sbtta +.section sbttb +.section sbtua +.section sbtub +.section sbtva +.section sbtvb +.section sbtwa +.section sbtwb +.section sbtxa +.section sbtxb +.section sbtya +.section sbtyb +.section sbtza +.section sbtzb +.section sbt1a +.section sbt1b +.section sbt2a +.section sbt2b +.section sbt3a +.section sbt3b +.section sbt4a +.section sbt4b +.section sbt5a +.section sbt5b +.section sbt6a +.section sbt6b +.section sbt7a +.section sbt7b +.section sbt8a +.section sbt8b +.section sbt9a +.section sbt9b +.section sbt0a +.section sbt0b +.section sbuaa +.section sbuab +.section sbuba +.section sbubb +.section sbuca +.section sbucb +.section sbuda +.section sbudb +.section sbuea +.section sbueb +.section sbufa +.section sbufb +.section sbuga +.section sbugb +.section sbuha +.section sbuhb +.section sbuia +.section sbuib +.section sbuja +.section sbujb +.section sbuka +.section sbukb +.section sbula +.section sbulb +.section sbuma +.section sbumb +.section sbuna +.section sbunb +.section sbuoa +.section sbuob +.section sbupa +.section sbupb +.section sbuqa +.section sbuqb +.section sbura +.section sburb +.section sbusa +.section sbusb +.section sbuta +.section sbutb +.section sbuua +.section sbuub +.section sbuva +.section sbuvb +.section sbuwa +.section sbuwb +.section sbuxa +.section sbuxb +.section sbuya +.section sbuyb +.section sbuza +.section sbuzb +.section sbu1a +.section sbu1b +.section sbu2a +.section sbu2b +.section sbu3a +.section sbu3b +.section sbu4a +.section sbu4b +.section sbu5a +.section sbu5b +.section sbu6a +.section sbu6b +.section sbu7a +.section sbu7b +.section sbu8a +.section sbu8b +.section sbu9a +.section sbu9b +.section sbu0a +.section sbu0b +.section sbvaa +.section sbvab +.section sbvba +.section sbvbb +.section sbvca +.section sbvcb +.section sbvda +.section sbvdb +.section sbvea +.section sbveb +.section sbvfa +.section sbvfb +.section sbvga +.section sbvgb +.section sbvha +.section sbvhb +.section sbvia +.section sbvib +.section sbvja +.section sbvjb +.section sbvka +.section sbvkb +.section sbvla +.section sbvlb +.section sbvma +.section sbvmb +.section sbvna +.section sbvnb +.section sbvoa +.section sbvob +.section sbvpa +.section sbvpb +.section sbvqa +.section sbvqb +.section sbvra +.section sbvrb +.section sbvsa +.section sbvsb +.section sbvta +.section sbvtb +.section sbvua +.section sbvub +.section sbvva +.section sbvvb +.section sbvwa +.section sbvwb +.section sbvxa +.section sbvxb +.section sbvya +.section sbvyb +.section sbvza +.section sbvzb +.section sbv1a +.section sbv1b +.section sbv2a +.section sbv2b +.section sbv3a +.section sbv3b +.section sbv4a +.section sbv4b +.section sbv5a +.section sbv5b +.section sbv6a +.section sbv6b +.section sbv7a +.section sbv7b +.section sbv8a +.section sbv8b +.section sbv9a +.section sbv9b +.section sbv0a +.section sbv0b +.section sbwaa +.section sbwab +.section sbwba +.section sbwbb +.section sbwca +.section sbwcb +.section sbwda +.section sbwdb +.section sbwea +.section sbweb +.section sbwfa +.section sbwfb +.section sbwga +.section sbwgb +.section sbwha +.section sbwhb +.section sbwia +.section sbwib +.section sbwja +.section sbwjb +.section sbwka +.section sbwkb +.section sbwla +.section sbwlb +.section sbwma +.section sbwmb +.section sbwna +.section sbwnb +.section sbwoa +.section sbwob +.section sbwpa +.section sbwpb +.section sbwqa +.section sbwqb +.section sbwra +.section sbwrb +.section sbwsa +.section sbwsb +.section sbwta +.section sbwtb +.section sbwua +.section sbwub +.section sbwva +.section sbwvb +.section sbwwa +.section sbwwb +.section sbwxa +.section sbwxb +.section sbwya +.section sbwyb +.section sbwza +.section sbwzb +.section sbw1a +.section sbw1b +.section sbw2a +.section sbw2b +.section sbw3a +.section sbw3b +.section sbw4a +.section sbw4b +.section sbw5a +.section sbw5b +.section sbw6a +.section sbw6b +.section sbw7a +.section sbw7b +.section sbw8a +.section sbw8b +.section sbw9a +.section sbw9b +.section sbw0a +.section sbw0b +.section sbxaa +.section sbxab +.section sbxba +.section sbxbb +.section sbxca +.section sbxcb +.section sbxda +.section sbxdb +.section sbxea +.section sbxeb +.section sbxfa +.section sbxfb +.section sbxga +.section sbxgb +.section sbxha +.section sbxhb +.section sbxia +.section sbxib +.section sbxja +.section sbxjb +.section sbxka +.section sbxkb +.section sbxla +.section sbxlb +.section sbxma +.section sbxmb +.section sbxna +.section sbxnb +.section sbxoa +.section sbxob +.section sbxpa +.section sbxpb +.section sbxqa +.section sbxqb +.section sbxra +.section sbxrb +.section sbxsa +.section sbxsb +.section sbxta +.section sbxtb +.section sbxua +.section sbxub +.section sbxva +.section sbxvb +.section sbxwa +.section sbxwb +.section sbxxa +.section sbxxb +.section sbxya +.section sbxyb +.section sbxza +.section sbxzb +.section sbx1a +.section sbx1b +.section sbx2a +.section sbx2b +.section sbx3a +.section sbx3b +.section sbx4a +.section sbx4b +.section sbx5a +.section sbx5b +.section sbx6a +.section sbx6b +.section sbx7a +.section sbx7b +.section sbx8a +.section sbx8b +.section sbx9a +.section sbx9b +.section sbx0a +.section sbx0b +.section sbyaa +.section sbyab +.section sbyba +.section sbybb +.section sbyca +.section sbycb +.section sbyda +.section sbydb +.section sbyea +.section sbyeb +.section sbyfa +.section sbyfb +.section sbyga +.section sbygb +.section sbyha +.section sbyhb +.section sbyia +.section sbyib +.section sbyja +.section sbyjb +.section sbyka +.section sbykb +.section sbyla +.section sbylb +.section sbyma +.section sbymb +.section sbyna +.section sbynb +.section sbyoa +.section sbyob +.section sbypa +.section sbypb +.section sbyqa +.section sbyqb +.section sbyra +.section sbyrb +.section sbysa +.section sbysb +.section sbyta +.section sbytb +.section sbyua +.section sbyub +.section sbyva +.section sbyvb +.section sbywa +.section sbywb +.section sbyxa +.section sbyxb +.section sbyya +.section sbyyb +.section sbyza +.section sbyzb +.section sby1a +.section sby1b +.section sby2a +.section sby2b +.section sby3a +.section sby3b +.section sby4a +.section sby4b +.section sby5a +.section sby5b +.section sby6a +.section sby6b +.section sby7a +.section sby7b +.section sby8a +.section sby8b +.section sby9a +.section sby9b +.section sby0a +.section sby0b +.section sbzaa +.section sbzab +.section sbzba +.section sbzbb +.section sbzca +.section sbzcb +.section sbzda +.section sbzdb +.section sbzea +.section sbzeb +.section sbzfa +.section sbzfb +.section sbzga +.section sbzgb +.section sbzha +.section sbzhb +.section sbzia +.section sbzib +.section sbzja +.section sbzjb +.section sbzka +.section sbzkb +.section sbzla +.section sbzlb +.section sbzma +.section sbzmb +.section sbzna +.section sbznb +.section sbzoa +.section sbzob +.section sbzpa +.section sbzpb +.section sbzqa +.section sbzqb +.section sbzra +.section sbzrb +.section sbzsa +.section sbzsb +.section sbzta +.section sbztb +.section sbzua +.section sbzub +.section sbzva +.section sbzvb +.section sbzwa +.section sbzwb +.section sbzxa +.section sbzxb +.section sbzya +.section sbzyb +.section sbzza +.section sbzzb +.section sbz1a +.section sbz1b +.section sbz2a +.section sbz2b +.section sbz3a +.section sbz3b +.section sbz4a +.section sbz4b +.section sbz5a +.section sbz5b +.section sbz6a +.section sbz6b +.section sbz7a +.section sbz7b +.section sbz8a +.section sbz8b +.section sbz9a +.section sbz9b +.section sbz0a +.section sbz0b +.section sb1aa +.section sb1ab +.section sb1ba +.section sb1bb +.section sb1ca +.section sb1cb +.section sb1da +.section sb1db +.section sb1ea +.section sb1eb +.section sb1fa +.section sb1fb +.section sb1ga +.section sb1gb +.section sb1ha +.section sb1hb +.section sb1ia +.section sb1ib +.section sb1ja +.section sb1jb +.section sb1ka +.section sb1kb +.section sb1la +.section sb1lb +.section sb1ma +.section sb1mb +.section sb1na +.section sb1nb +.section sb1oa +.section sb1ob +.section sb1pa +.section sb1pb +.section sb1qa +.section sb1qb +.section sb1ra +.section sb1rb +.section sb1sa +.section sb1sb +.section sb1ta +.section sb1tb +.section sb1ua +.section sb1ub +.section sb1va +.section sb1vb +.section sb1wa +.section sb1wb +.section sb1xa +.section sb1xb +.section sb1ya +.section sb1yb +.section sb1za +.section sb1zb +.section sb11a +.section sb11b +.section sb12a +.section sb12b +.section sb13a +.section sb13b +.section sb14a +.section sb14b +.section sb15a +.section sb15b +.section sb16a +.section sb16b +.section sb17a +.section sb17b +.section sb18a +.section sb18b +.section sb19a +.section sb19b +.section sb10a +.section sb10b +.section sb2aa +.section sb2ab +.section sb2ba +.section sb2bb +.section sb2ca +.section sb2cb +.section sb2da +.section sb2db +.section sb2ea +.section sb2eb +.section sb2fa +.section sb2fb +.section sb2ga +.section sb2gb +.section sb2ha +.section sb2hb +.section sb2ia +.section sb2ib +.section sb2ja +.section sb2jb +.section sb2ka +.section sb2kb +.section sb2la +.section sb2lb +.section sb2ma +.section sb2mb +.section sb2na +.section sb2nb +.section sb2oa +.section sb2ob +.section sb2pa +.section sb2pb +.section sb2qa +.section sb2qb +.section sb2ra +.section sb2rb +.section sb2sa +.section sb2sb +.section sb2ta +.section sb2tb +.section sb2ua +.section sb2ub +.section sb2va +.section sb2vb +.section sb2wa +.section sb2wb +.section sb2xa +.section sb2xb +.section sb2ya +.section sb2yb +.section sb2za +.section sb2zb +.section sb21a +.section sb21b +.section sb22a +.section sb22b +.section sb23a +.section sb23b +.section sb24a +.section sb24b +.section sb25a +.section sb25b +.section sb26a +.section sb26b +.section sb27a +.section sb27b +.section sb28a +.section sb28b +.section sb29a +.section sb29b +.section sb20a +.section sb20b +.section sb3aa +.section sb3ab +.section sb3ba +.section sb3bb +.section sb3ca +.section sb3cb +.section sb3da +.section sb3db +.section sb3ea +.section sb3eb +.section sb3fa +.section sb3fb +.section sb3ga +.section sb3gb +.section sb3ha +.section sb3hb +.section sb3ia +.section sb3ib +.section sb3ja +.section sb3jb +.section sb3ka +.section sb3kb +.section sb3la +.section sb3lb +.section sb3ma +.section sb3mb +.section sb3na +.section sb3nb +.section sb3oa +.section sb3ob +.section sb3pa +.section sb3pb +.section sb3qa +.section sb3qb +.section sb3ra +.section sb3rb +.section sb3sa +.section sb3sb +.section sb3ta +.section sb3tb +.section sb3ua +.section sb3ub +.section sb3va +.section sb3vb +.section sb3wa +.section sb3wb +.section sb3xa +.section sb3xb +.section sb3ya +.section sb3yb +.section sb3za +.section sb3zb +.section sb31a +.section sb31b +.section sb32a +.section sb32b +.section sb33a +.section sb33b +.section sb34a +.section sb34b +.section sb35a +.section sb35b +.section sb36a +.section sb36b +.section sb37a +.section sb37b +.section sb38a +.section sb38b +.section sb39a +.section sb39b +.section sb30a +.section sb30b +.section sb4aa +.section sb4ab +.section sb4ba +.section sb4bb +.section sb4ca +.section sb4cb +.section sb4da +.section sb4db +.section sb4ea +.section sb4eb +.section sb4fa +.section sb4fb +.section sb4ga +.section sb4gb +.section sb4ha +.section sb4hb +.section sb4ia +.section sb4ib +.section sb4ja +.section sb4jb +.section sb4ka +.section sb4kb +.section sb4la +.section sb4lb +.section sb4ma +.section sb4mb +.section sb4na +.section sb4nb +.section sb4oa +.section sb4ob +.section sb4pa +.section sb4pb +.section sb4qa +.section sb4qb +.section sb4ra +.section sb4rb +.section sb4sa +.section sb4sb +.section sb4ta +.section sb4tb +.section sb4ua +.section sb4ub +.section sb4va +.section sb4vb +.section sb4wa +.section sb4wb +.section sb4xa +.section sb4xb +.section sb4ya +.section sb4yb +.section sb4za +.section sb4zb +.section sb41a +.section sb41b +.section sb42a +.section sb42b +.section sb43a +.section sb43b +.section sb44a +.section sb44b +.section sb45a +.section sb45b +.section sb46a +.section sb46b +.section sb47a +.section sb47b +.section sb48a +.section sb48b +.section sb49a +.section sb49b +.section sb40a +.section sb40b +.section sb5aa +.section sb5ab +.section sb5ba +.section sb5bb +.section sb5ca +.section sb5cb +.section sb5da +.section sb5db +.section sb5ea +.section sb5eb +.section sb5fa +.section sb5fb +.section sb5ga +.section sb5gb +.section sb5ha +.section sb5hb +.section sb5ia +.section sb5ib +.section sb5ja +.section sb5jb +.section sb5ka +.section sb5kb +.section sb5la +.section sb5lb +.section sb5ma +.section sb5mb +.section sb5na +.section sb5nb +.section sb5oa +.section sb5ob +.section sb5pa +.section sb5pb +.section sb5qa +.section sb5qb +.section sb5ra +.section sb5rb +.section sb5sa +.section sb5sb +.section sb5ta +.section sb5tb +.section sb5ua +.section sb5ub +.section sb5va +.section sb5vb +.section sb5wa +.section sb5wb +.section sb5xa +.section sb5xb +.section sb5ya +.section sb5yb +.section sb5za +.section sb5zb +.section sb51a +.section sb51b +.section sb52a +.section sb52b +.section sb53a +.section sb53b +.section sb54a +.section sb54b +.section sb55a +.section sb55b +.section sb56a +.section sb56b +.section sb57a +.section sb57b +.section sb58a +.section sb58b +.section sb59a +.section sb59b +.section sb50a +.section sb50b +.section sb6aa +.section sb6ab +.section sb6ba +.section sb6bb +.section sb6ca +.section sb6cb +.section sb6da +.section sb6db +.section sb6ea +.section sb6eb +.section sb6fa +.section sb6fb +.section sb6ga +.section sb6gb +.section sb6ha +.section sb6hb +.section sb6ia +.section sb6ib +.section sb6ja +.section sb6jb +.section sb6ka +.section sb6kb +.section sb6la +.section sb6lb +.section sb6ma +.section sb6mb +.section sb6na +.section sb6nb +.section sb6oa +.section sb6ob +.section sb6pa +.section sb6pb +.section sb6qa +.section sb6qb +.section sb6ra +.section sb6rb +.section sb6sa +.section sb6sb +.section sb6ta +.section sb6tb +.section sb6ua +.section sb6ub +.section sb6va +.section sb6vb +.section sb6wa +.section sb6wb +.section sb6xa +.section sb6xb +.section sb6ya +.section sb6yb +.section sb6za +.section sb6zb +.section sb61a +.section sb61b +.section sb62a +.section sb62b +.section sb63a +.section sb63b +.section sb64a +.section sb64b +.section sb65a +.section sb65b +.section sb66a +.section sb66b +.section sb67a +.section sb67b +.section sb68a +.section sb68b +.section sb69a +.section sb69b +.section sb60a +.section sb60b +.section sb7aa +.section sb7ab +.section sb7ba +.section sb7bb +.section sb7ca +.section sb7cb +.section sb7da +.section sb7db +.section sb7ea +.section sb7eb +.section sb7fa +.section sb7fb +.section sb7ga +.section sb7gb +.section sb7ha +.section sb7hb +.section sb7ia +.section sb7ib +.section sb7ja +.section sb7jb +.section sb7ka +.section sb7kb +.section sb7la +.section sb7lb +.section sb7ma +.section sb7mb +.section sb7na +.section sb7nb +.section sb7oa +.section sb7ob +.section sb7pa +.section sb7pb +.section sb7qa +.section sb7qb +.section sb7ra +.section sb7rb +.section sb7sa +.section sb7sb +.section sb7ta +.section sb7tb +.section sb7ua +.section sb7ub +.section sb7va +.section sb7vb +.section sb7wa +.section sb7wb +.section sb7xa +.section sb7xb +.section sb7ya +.section sb7yb +.section sb7za +.section sb7zb +.section sb71a +.section sb71b +.section sb72a +.section sb72b +.section sb73a +.section sb73b +.section sb74a +.section sb74b +.section sb75a +.section sb75b +.section sb76a +.section sb76b +.section sb77a +.section sb77b +.section sb78a +.section sb78b +.section sb79a +.section sb79b +.section sb70a +.section sb70b +.section sb8aa +.section sb8ab +.section sb8ba +.section sb8bb +.section sb8ca +.section sb8cb +.section sb8da +.section sb8db +.section sb8ea +.section sb8eb +.section sb8fa +.section sb8fb +.section sb8ga +.section sb8gb +.section sb8ha +.section sb8hb +.section sb8ia +.section sb8ib +.section sb8ja +.section sb8jb +.section sb8ka +.section sb8kb +.section sb8la +.section sb8lb +.section sb8ma +.section sb8mb +.section sb8na +.section sb8nb +.section sb8oa +.section sb8ob +.section sb8pa +.section sb8pb +.section sb8qa +.section sb8qb +.section sb8ra +.section sb8rb +.section sb8sa +.section sb8sb +.section sb8ta +.section sb8tb +.section sb8ua +.section sb8ub +.section sb8va +.section sb8vb +.section sb8wa +.section sb8wb +.section sb8xa +.section sb8xb +.section sb8ya +.section sb8yb +.section sb8za +.section sb8zb +.section sb81a +.section sb81b +.section sb82a +.section sb82b +.section sb83a +.section sb83b +.section sb84a +.section sb84b +.section sb85a +.section sb85b +.section sb86a +.section sb86b +.section sb87a +.section sb87b +.section sb88a +.section sb88b +.section sb89a +.section sb89b +.section sb80a +.section sb80b +.section sb9aa +.section sb9ab +.section sb9ba +.section sb9bb +.section sb9ca +.section sb9cb +.section sb9da +.section sb9db +.section sb9ea +.section sb9eb +.section sb9fa +.section sb9fb +.section sb9ga +.section sb9gb +.section sb9ha +.section sb9hb +.section sb9ia +.section sb9ib +.section sb9ja +.section sb9jb +.section sb9ka +.section sb9kb +.section sb9la +.section sb9lb +.section sb9ma +.section sb9mb +.section sb9na +.section sb9nb +.section sb9oa +.section sb9ob +.section sb9pa +.section sb9pb +.section sb9qa +.section sb9qb +.section sb9ra +.section sb9rb +.section sb9sa +.section sb9sb +.section sb9ta +.section sb9tb +.section sb9ua +.section sb9ub +.section sb9va +.section sb9vb +.section sb9wa +.section sb9wb +.section sb9xa +.section sb9xb +.section sb9ya +.section sb9yb +.section sb9za +.section sb9zb +.section sb91a +.section sb91b +.section sb92a +.section sb92b +.section sb93a +.section sb93b +.section sb94a +.section sb94b +.section sb95a +.section sb95b +.section sb96a +.section sb96b +.section sb97a +.section sb97b +.section sb98a +.section sb98b +.section sb99a +.section sb99b +.section sb90a +.section sb90b +.section sb0aa +.section sb0ab +.section sb0ba +.section sb0bb +.section sb0ca +.section sb0cb +.section sb0da +.section sb0db +.section sb0ea +.section sb0eb +.section sb0fa +.section sb0fb +.section sb0ga +.section sb0gb +.section sb0ha +.section sb0hb +.section sb0ia +.section sb0ib +.section sb0ja +.section sb0jb +.section sb0ka +.section sb0kb +.section sb0la +.section sb0lb +.section sb0ma +.section sb0mb +.section sb0na +.section sb0nb +.section sb0oa +.section sb0ob +.section sb0pa +.section sb0pb +.section sb0qa +.section sb0qb +.section sb0ra +.section sb0rb +.section sb0sa +.section sb0sb +.section sb0ta +.section sb0tb +.section sb0ua +.section sb0ub +.section sb0va +.section sb0vb +.section sb0wa +.section sb0wb +.section sb0xa +.section sb0xb +.section sb0ya +.section sb0yb +.section sb0za +.section sb0zb +.section sb01a +.section sb01b +.section sb02a +.section sb02b +.section sb03a +.section sb03b +.section sb04a +.section sb04b +.section sb05a +.section sb05b +.section sb06a +.section sb06b +.section sb07a +.section sb07b +.section sb08a +.section sb08b +.section sb09a +.section sb09b +.section sb00a +.section sb00b +.section scaaa +.section scaab +.section scaba +.section scabb +.section scaca +.section scacb +.section scada +.section scadb +.section scaea +.section scaeb +.section scafa +.section scafb +.section scaga +.section scagb +.section scaha +.section scahb +.section scaia +.section scaib +.section scaja +.section scajb +.section scaka +.section scakb +.section scala +.section scalb +.section scama +.section scamb +.section scana +.section scanb +.section scaoa +.section scaob +.section scapa +.section scapb +.section scaqa +.section scaqb +.section scara +.section scarb +.section scasa +.section scasb +.section scata +.section scatb +.section scaua +.section scaub +.section scava +.section scavb +.section scawa +.section scawb +.section scaxa +.section scaxb +.section scaya +.section scayb +.section scaza +.section scazb +.section sca1a +.section sca1b +.section sca2a +.section sca2b +.section sca3a +.section sca3b +.section sca4a +.section sca4b +.section sca5a +.section sca5b +.section sca6a +.section sca6b +.section sca7a +.section sca7b +.section sca8a +.section sca8b +.section sca9a +.section sca9b +.section sca0a +.section sca0b +.section scbaa +.section scbab +.section scbba +.section scbbb +.section scbca +.section scbcb +.section scbda +.section scbdb +.section scbea +.section scbeb +.section scbfa +.section scbfb +.section scbga +.section scbgb +.section scbha +.section scbhb +.section scbia +.section scbib +.section scbja +.section scbjb +.section scbka +.section scbkb +.section scbla +.section scblb +.section scbma +.section scbmb +.section scbna +.section scbnb +.section scboa +.section scbob +.section scbpa +.section scbpb +.section scbqa +.section scbqb +.section scbra +.section scbrb +.section scbsa +.section scbsb +.section scbta +.section scbtb +.section scbua +.section scbub +.section scbva +.section scbvb +.section scbwa +.section scbwb +.section scbxa +.section scbxb +.section scbya +.section scbyb +.section scbza +.section scbzb +.section scb1a +.section scb1b +.section scb2a +.section scb2b +.section scb3a +.section scb3b +.section scb4a +.section scb4b +.section scb5a +.section scb5b +.section scb6a +.section scb6b +.section scb7a +.section scb7b +.section scb8a +.section scb8b +.section scb9a +.section scb9b +.section scb0a +.section scb0b +.section sccaa +.section sccab +.section sccba +.section sccbb +.section sccca +.section scccb +.section sccda +.section sccdb +.section sccea +.section scceb +.section sccfa +.section sccfb +.section sccga +.section sccgb +.section sccha +.section scchb +.section sccia +.section sccib +.section sccja +.section sccjb +.section sccka +.section scckb +.section sccla +.section scclb +.section sccma +.section sccmb +.section sccna +.section sccnb +.section sccoa +.section sccob +.section sccpa +.section sccpb +.section sccqa +.section sccqb +.section sccra +.section sccrb +.section sccsa +.section sccsb +.section sccta +.section scctb +.section sccua +.section sccub +.section sccva +.section sccvb +.section sccwa +.section sccwb +.section sccxa +.section sccxb +.section sccya +.section sccyb +.section sccza +.section scczb +.section scc1a +.section scc1b +.section scc2a +.section scc2b +.section scc3a +.section scc3b +.section scc4a +.section scc4b +.section scc5a +.section scc5b +.section scc6a +.section scc6b +.section scc7a +.section scc7b +.section scc8a +.section scc8b +.section scc9a +.section scc9b +.section scc0a +.section scc0b +.section scdaa +.section scdab +.section scdba +.section scdbb +.section scdca +.section scdcb +.section scdda +.section scddb +.section scdea +.section scdeb +.section scdfa +.section scdfb +.section scdga +.section scdgb +.section scdha +.section scdhb +.section scdia +.section scdib +.section scdja +.section scdjb +.section scdka +.section scdkb +.section scdla +.section scdlb +.section scdma +.section scdmb +.section scdna +.section scdnb +.section scdoa +.section scdob +.section scdpa +.section scdpb +.section scdqa +.section scdqb +.section scdra +.section scdrb +.section scdsa +.section scdsb +.section scdta +.section scdtb +.section scdua +.section scdub +.section scdva +.section scdvb +.section scdwa +.section scdwb +.section scdxa +.section scdxb +.section scdya +.section scdyb +.section scdza +.section scdzb +.section scd1a +.section scd1b +.section scd2a +.section scd2b +.section scd3a +.section scd3b +.section scd4a +.section scd4b +.section scd5a +.section scd5b +.section scd6a +.section scd6b +.section scd7a +.section scd7b +.section scd8a +.section scd8b +.section scd9a +.section scd9b +.section scd0a +.section scd0b +.section sceaa +.section sceab +.section sceba +.section scebb +.section sceca +.section scecb +.section sceda +.section scedb +.section sceea +.section sceeb +.section scefa +.section scefb +.section scega +.section scegb +.section sceha +.section scehb +.section sceia +.section sceib +.section sceja +.section scejb +.section sceka +.section scekb +.section scela +.section scelb +.section scema +.section scemb +.section scena +.section scenb +.section sceoa +.section sceob +.section scepa +.section scepb +.section sceqa +.section sceqb +.section scera +.section scerb +.section scesa +.section scesb +.section sceta +.section scetb +.section sceua +.section sceub +.section sceva +.section scevb +.section scewa +.section scewb +.section scexa +.section scexb +.section sceya +.section sceyb +.section sceza +.section scezb +.section sce1a +.section sce1b +.section sce2a +.section sce2b +.section sce3a +.section sce3b +.section sce4a +.section sce4b +.section sce5a +.section sce5b +.section sce6a +.section sce6b +.section sce7a +.section sce7b +.section sce8a +.section sce8b +.section sce9a +.section sce9b +.section sce0a +.section sce0b +.section scfaa +.section scfab +.section scfba +.section scfbb +.section scfca +.section scfcb +.section scfda +.section scfdb +.section scfea +.section scfeb +.section scffa +.section scffb +.section scfga +.section scfgb +.section scfha +.section scfhb +.section scfia +.section scfib +.section scfja +.section scfjb +.section scfka +.section scfkb +.section scfla +.section scflb +.section scfma +.section scfmb +.section scfna +.section scfnb +.section scfoa +.section scfob +.section scfpa +.section scfpb +.section scfqa +.section scfqb +.section scfra +.section scfrb +.section scfsa +.section scfsb +.section scfta +.section scftb +.section scfua +.section scfub +.section scfva +.section scfvb +.section scfwa +.section scfwb +.section scfxa +.section scfxb +.section scfya +.section scfyb +.section scfza +.section scfzb +.section scf1a +.section scf1b +.section scf2a +.section scf2b +.section scf3a +.section scf3b +.section scf4a +.section scf4b +.section scf5a +.section scf5b +.section scf6a +.section scf6b +.section scf7a +.section scf7b +.section scf8a +.section scf8b +.section scf9a +.section scf9b +.section scf0a +.section scf0b +.section scgaa +.section scgab +.section scgba +.section scgbb +.section scgca +.section scgcb +.section scgda +.section scgdb +.section scgea +.section scgeb +.section scgfa +.section scgfb +.section scgga +.section scggb +.section scgha +.section scghb +.section scgia +.section scgib +.section scgja +.section scgjb +.section scgka +.section scgkb +.section scgla +.section scglb +.section scgma +.section scgmb +.section scgna +.section scgnb +.section scgoa +.section scgob +.section scgpa +.section scgpb +.section scgqa +.section scgqb +.section scgra +.section scgrb +.section scgsa +.section scgsb +.section scgta +.section scgtb +.section scgua +.section scgub +.section scgva +.section scgvb +.section scgwa +.section scgwb +.section scgxa +.section scgxb +.section scgya +.section scgyb +.section scgza +.section scgzb +.section scg1a +.section scg1b +.section scg2a +.section scg2b +.section scg3a +.section scg3b +.section scg4a +.section scg4b +.section scg5a +.section scg5b +.section scg6a +.section scg6b +.section scg7a +.section scg7b +.section scg8a +.section scg8b +.section scg9a +.section scg9b +.section scg0a +.section scg0b +.section schaa +.section schab +.section schba +.section schbb +.section schca +.section schcb +.section schda +.section schdb +.section schea +.section scheb +.section schfa +.section schfb +.section schga +.section schgb +.section schha +.section schhb +.section schia +.section schib +.section schja +.section schjb +.section schka +.section schkb +.section schla +.section schlb +.section schma +.section schmb +.section schna +.section schnb +.section schoa +.section schob +.section schpa +.section schpb +.section schqa +.section schqb +.section schra +.section schrb +.section schsa +.section schsb +.section schta +.section schtb +.section schua +.section schub +.section schva +.section schvb +.section schwa +.section schwb +.section schxa +.section schxb +.section schya +.section schyb +.section schza +.section schzb +.section sch1a +.section sch1b +.section sch2a +.section sch2b +.section sch3a +.section sch3b +.section sch4a +.section sch4b +.section sch5a +.section sch5b +.section sch6a +.section sch6b +.section sch7a +.section sch7b +.section sch8a +.section sch8b +.section sch9a +.section sch9b +.section sch0a +.section sch0b +.section sciaa +.section sciab +.section sciba +.section scibb +.section scica +.section scicb +.section scida +.section scidb +.section sciea +.section scieb +.section scifa +.section scifb +.section sciga +.section scigb +.section sciha +.section scihb +.section sciia +.section sciib +.section scija +.section scijb +.section scika +.section scikb +.section scila +.section scilb +.section scima +.section scimb +.section scina +.section scinb +.section scioa +.section sciob +.section scipa +.section scipb +.section sciqa +.section sciqb +.section scira +.section scirb +.section scisa +.section scisb +.section scita +.section scitb +.section sciua +.section sciub +.section sciva +.section scivb +.section sciwa +.section sciwb +.section scixa +.section scixb +.section sciya +.section sciyb +.section sciza +.section scizb +.section sci1a +.section sci1b +.section sci2a +.section sci2b +.section sci3a +.section sci3b +.section sci4a +.section sci4b +.section sci5a +.section sci5b +.section sci6a +.section sci6b +.section sci7a +.section sci7b +.section sci8a +.section sci8b +.section sci9a +.section sci9b +.section sci0a +.section sci0b +.section scjaa +.section scjab +.section scjba +.section scjbb +.section scjca +.section scjcb +.section scjda +.section scjdb +.section scjea +.section scjeb +.section scjfa +.section scjfb +.section scjga +.section scjgb +.section scjha +.section scjhb +.section scjia +.section scjib +.section scjja +.section scjjb +.section scjka +.section scjkb +.section scjla +.section scjlb +.section scjma +.section scjmb +.section scjna +.section scjnb +.section scjoa +.section scjob +.section scjpa +.section scjpb +.section scjqa +.section scjqb +.section scjra +.section scjrb +.section scjsa +.section scjsb +.section scjta +.section scjtb +.section scjua +.section scjub +.section scjva +.section scjvb +.section scjwa +.section scjwb +.section scjxa +.section scjxb +.section scjya +.section scjyb +.section scjza +.section scjzb +.section scj1a +.section scj1b +.section scj2a +.section scj2b +.section scj3a +.section scj3b +.section scj4a +.section scj4b +.section scj5a +.section scj5b +.section scj6a +.section scj6b +.section scj7a +.section scj7b +.section scj8a +.section scj8b +.section scj9a +.section scj9b +.section scj0a +.section scj0b +.section sckaa +.section sckab +.section sckba +.section sckbb +.section sckca +.section sckcb +.section sckda +.section sckdb +.section sckea +.section sckeb +.section sckfa +.section sckfb +.section sckga +.section sckgb +.section sckha +.section sckhb +.section sckia +.section sckib +.section sckja +.section sckjb +.section sckka +.section sckkb +.section sckla +.section scklb +.section sckma +.section sckmb +.section sckna +.section scknb +.section sckoa +.section sckob +.section sckpa +.section sckpb +.section sckqa +.section sckqb +.section sckra +.section sckrb +.section scksa +.section scksb +.section sckta +.section scktb +.section sckua +.section sckub +.section sckva +.section sckvb +.section sckwa +.section sckwb +.section sckxa +.section sckxb +.section sckya +.section sckyb +.section sckza +.section sckzb +.section sck1a +.section sck1b +.section sck2a +.section sck2b +.section sck3a +.section sck3b +.section sck4a +.section sck4b +.section sck5a +.section sck5b +.section sck6a +.section sck6b +.section sck7a +.section sck7b +.section sck8a +.section sck8b +.section sck9a +.section sck9b +.section sck0a +.section sck0b +.section sclaa +.section sclab +.section sclba +.section sclbb +.section sclca +.section sclcb +.section sclda +.section scldb +.section sclea +.section scleb +.section sclfa +.section sclfb +.section sclga +.section sclgb +.section sclha +.section sclhb +.section sclia +.section sclib +.section sclja +.section scljb +.section sclka +.section sclkb +.section sclla +.section scllb +.section sclma +.section sclmb +.section sclna +.section sclnb +.section scloa +.section sclob +.section sclpa +.section sclpb +.section sclqa +.section sclqb +.section sclra +.section sclrb +.section sclsa +.section sclsb +.section sclta +.section scltb +.section sclua +.section sclub +.section sclva +.section sclvb +.section sclwa +.section sclwb +.section sclxa +.section sclxb +.section sclya +.section sclyb +.section sclza +.section sclzb +.section scl1a +.section scl1b +.section scl2a +.section scl2b +.section scl3a +.section scl3b +.section scl4a +.section scl4b +.section scl5a +.section scl5b +.section scl6a +.section scl6b +.section scl7a +.section scl7b +.section scl8a +.section scl8b +.section scl9a +.section scl9b +.section scl0a +.section scl0b +.section scmaa +.section scmab +.section scmba +.section scmbb +.section scmca +.section scmcb +.section scmda +.section scmdb +.section scmea +.section scmeb +.section scmfa +.section scmfb +.section scmga +.section scmgb +.section scmha +.section scmhb +.section scmia +.section scmib +.section scmja +.section scmjb +.section scmka +.section scmkb +.section scmla +.section scmlb +.section scmma +.section scmmb +.section scmna +.section scmnb +.section scmoa +.section scmob +.section scmpa +.section scmpb +.section scmqa +.section scmqb +.section scmra +.section scmrb +.section scmsa +.section scmsb +.section scmta +.section scmtb +.section scmua +.section scmub +.section scmva +.section scmvb +.section scmwa +.section scmwb +.section scmxa +.section scmxb +.section scmya +.section scmyb +.section scmza +.section scmzb +.section scm1a +.section scm1b +.section scm2a +.section scm2b +.section scm3a +.section scm3b +.section scm4a +.section scm4b +.section scm5a +.section scm5b +.section scm6a +.section scm6b +.section scm7a +.section scm7b +.section scm8a +.section scm8b +.section scm9a +.section scm9b +.section scm0a +.section scm0b +.section scnaa +.section scnab +.section scnba +.section scnbb +.section scnca +.section scncb +.section scnda +.section scndb +.section scnea +.section scneb +.section scnfa +.section scnfb +.section scnga +.section scngb +.section scnha +.section scnhb +.section scnia +.section scnib +.section scnja +.section scnjb +.section scnka +.section scnkb +.section scnla +.section scnlb +.section scnma +.section scnmb +.section scnna +.section scnnb +.section scnoa +.section scnob +.section scnpa +.section scnpb +.section scnqa +.section scnqb +.section scnra +.section scnrb +.section scnsa +.section scnsb +.section scnta +.section scntb +.section scnua +.section scnub +.section scnva +.section scnvb +.section scnwa +.section scnwb +.section scnxa +.section scnxb +.section scnya +.section scnyb +.section scnza +.section scnzb +.section scn1a +.section scn1b +.section scn2a +.section scn2b +.section scn3a +.section scn3b +.section scn4a +.section scn4b +.section scn5a +.section scn5b +.section scn6a +.section scn6b +.section scn7a +.section scn7b +.section scn8a +.section scn8b +.section scn9a +.section scn9b +.section scn0a +.section scn0b +.section scoaa +.section scoab +.section scoba +.section scobb +.section scoca +.section scocb +.section scoda +.section scodb +.section scoea +.section scoeb +.section scofa +.section scofb +.section scoga +.section scogb +.section scoha +.section scohb +.section scoia +.section scoib +.section scoja +.section scojb +.section scoka +.section scokb +.section scola +.section scolb +.section scoma +.section scomb +.section scona +.section sconb +.section scooa +.section scoob +.section scopa +.section scopb +.section scoqa +.section scoqb +.section scora +.section scorb +.section scosa +.section scosb +.section scota +.section scotb +.section scoua +.section scoub +.section scova +.section scovb +.section scowa +.section scowb +.section scoxa +.section scoxb +.section scoya +.section scoyb +.section scoza +.section scozb +.section sco1a +.section sco1b +.section sco2a +.section sco2b +.section sco3a +.section sco3b +.section sco4a +.section sco4b +.section sco5a +.section sco5b +.section sco6a +.section sco6b +.section sco7a +.section sco7b +.section sco8a +.section sco8b +.section sco9a +.section sco9b +.section sco0a +.section sco0b +.section scpaa +.section scpab +.section scpba +.section scpbb +.section scpca +.section scpcb +.section scpda +.section scpdb +.section scpea +.section scpeb +.section scpfa +.section scpfb +.section scpga +.section scpgb +.section scpha +.section scphb +.section scpia +.section scpib +.section scpja +.section scpjb +.section scpka +.section scpkb +.section scpla +.section scplb +.section scpma +.section scpmb +.section scpna +.section scpnb +.section scpoa +.section scpob +.section scppa +.section scppb +.section scpqa +.section scpqb +.section scpra +.section scprb +.section scpsa +.section scpsb +.section scpta +.section scptb +.section scpua +.section scpub +.section scpva +.section scpvb +.section scpwa +.section scpwb +.section scpxa +.section scpxb +.section scpya +.section scpyb +.section scpza +.section scpzb +.section scp1a +.section scp1b +.section scp2a +.section scp2b +.section scp3a +.section scp3b +.section scp4a +.section scp4b +.section scp5a +.section scp5b +.section scp6a +.section scp6b +.section scp7a +.section scp7b +.section scp8a +.section scp8b +.section scp9a +.section scp9b +.section scp0a +.section scp0b +.section scqaa +.section scqab +.section scqba +.section scqbb +.section scqca +.section scqcb +.section scqda +.section scqdb +.section scqea +.section scqeb +.section scqfa +.section scqfb +.section scqga +.section scqgb +.section scqha +.section scqhb +.section scqia +.section scqib +.section scqja +.section scqjb +.section scqka +.section scqkb +.section scqla +.section scqlb +.section scqma +.section scqmb +.section scqna +.section scqnb +.section scqoa +.section scqob +.section scqpa +.section scqpb +.section scqqa +.section scqqb +.section scqra +.section scqrb +.section scqsa +.section scqsb +.section scqta +.section scqtb +.section scqua +.section scqub +.section scqva +.section scqvb +.section scqwa +.section scqwb +.section scqxa +.section scqxb +.section scqya +.section scqyb +.section scqza +.section scqzb +.section scq1a +.section scq1b +.section scq2a +.section scq2b +.section scq3a +.section scq3b +.section scq4a +.section scq4b +.section scq5a +.section scq5b +.section scq6a +.section scq6b +.section scq7a +.section scq7b +.section scq8a +.section scq8b +.section scq9a +.section scq9b +.section scq0a +.section scq0b +.section scraa +.section scrab +.section scrba +.section scrbb +.section scrca +.section scrcb +.section scrda +.section scrdb +.section screa +.section screb +.section scrfa +.section scrfb +.section scrga +.section scrgb +.section scrha +.section scrhb +.section scria +.section scrib +.section scrja +.section scrjb +.section scrka +.section scrkb +.section scrla +.section scrlb +.section scrma +.section scrmb +.section scrna +.section scrnb +.section scroa +.section scrob +.section scrpa +.section scrpb +.section scrqa +.section scrqb +.section scrra +.section scrrb +.section scrsa +.section scrsb +.section scrta +.section scrtb +.section scrua +.section scrub +.section scrva +.section scrvb +.section scrwa +.section scrwb +.section scrxa +.section scrxb +.section scrya +.section scryb +.section scrza +.section scrzb +.section scr1a +.section scr1b +.section scr2a +.section scr2b +.section scr3a +.section scr3b +.section scr4a +.section scr4b +.section scr5a +.section scr5b +.section scr6a +.section scr6b +.section scr7a +.section scr7b +.section scr8a +.section scr8b +.section scr9a +.section scr9b +.section scr0a +.section scr0b +.section scsaa +.section scsab +.section scsba +.section scsbb +.section scsca +.section scscb +.section scsda +.section scsdb +.section scsea +.section scseb +.section scsfa +.section scsfb +.section scsga +.section scsgb +.section scsha +.section scshb +.section scsia +.section scsib +.section scsja +.section scsjb +.section scska +.section scskb +.section scsla +.section scslb +.section scsma +.section scsmb +.section scsna +.section scsnb +.section scsoa +.section scsob +.section scspa +.section scspb +.section scsqa +.section scsqb +.section scsra +.section scsrb +.section scssa +.section scssb +.section scsta +.section scstb +.section scsua +.section scsub +.section scsva +.section scsvb +.section scswa +.section scswb +.section scsxa +.section scsxb +.section scsya +.section scsyb +.section scsza +.section scszb +.section scs1a +.section scs1b +.section scs2a +.section scs2b +.section scs3a +.section scs3b +.section scs4a +.section scs4b +.section scs5a +.section scs5b +.section scs6a +.section scs6b +.section scs7a +.section scs7b +.section scs8a +.section scs8b +.section scs9a +.section scs9b +.section scs0a +.section scs0b +.section sctaa +.section sctab +.section sctba +.section sctbb +.section sctca +.section sctcb +.section sctda +.section sctdb +.section sctea +.section scteb +.section sctfa +.section sctfb +.section sctga +.section sctgb +.section sctha +.section scthb +.section sctia +.section sctib +.section sctja +.section sctjb +.section sctka +.section sctkb +.section sctla +.section sctlb +.section sctma +.section sctmb +.section sctna +.section sctnb +.section sctoa +.section sctob +.section sctpa +.section sctpb +.section sctqa +.section sctqb +.section sctra +.section sctrb +.section sctsa +.section sctsb +.section sctta +.section scttb +.section sctua +.section sctub +.section sctva +.section sctvb +.section sctwa +.section sctwb +.section sctxa +.section sctxb +.section sctya +.section sctyb +.section sctza +.section sctzb +.section sct1a +.section sct1b +.section sct2a +.section sct2b +.section sct3a +.section sct3b +.section sct4a +.section sct4b +.section sct5a +.section sct5b +.section sct6a +.section sct6b +.section sct7a +.section sct7b +.section sct8a +.section sct8b +.section sct9a +.section sct9b +.section sct0a +.section sct0b +.section scuaa +.section scuab +.section scuba +.section scubb +.section scuca +.section scucb +.section scuda +.section scudb +.section scuea +.section scueb +.section scufa +.section scufb +.section scuga +.section scugb +.section scuha +.section scuhb +.section scuia +.section scuib +.section scuja +.section scujb +.section scuka +.section scukb +.section scula +.section sculb +.section scuma +.section scumb +.section scuna +.section scunb +.section scuoa +.section scuob +.section scupa +.section scupb +.section scuqa +.section scuqb +.section scura +.section scurb +.section scusa +.section scusb +.section scuta +.section scutb +.section scuua +.section scuub +.section scuva +.section scuvb +.section scuwa +.section scuwb +.section scuxa +.section scuxb +.section scuya +.section scuyb +.section scuza +.section scuzb +.section scu1a +.section scu1b +.section scu2a +.section scu2b +.section scu3a +.section scu3b +.section scu4a +.section scu4b +.section scu5a +.section scu5b +.section scu6a +.section scu6b +.section scu7a +.section scu7b +.section scu8a +.section scu8b +.section scu9a +.section scu9b +.section scu0a +.section scu0b +.section scvaa +.section scvab +.section scvba +.section scvbb +.section scvca +.section scvcb +.section scvda +.section scvdb +.section scvea +.section scveb +.section scvfa +.section scvfb +.section scvga +.section scvgb +.section scvha +.section scvhb +.section scvia +.section scvib +.section scvja +.section scvjb +.section scvka +.section scvkb +.section scvla +.section scvlb +.section scvma +.section scvmb +.section scvna +.section scvnb +.section scvoa +.section scvob +.section scvpa +.section scvpb +.section scvqa +.section scvqb +.section scvra +.section scvrb +.section scvsa +.section scvsb +.section scvta +.section scvtb +.section scvua +.section scvub +.section scvva +.section scvvb +.section scvwa +.section scvwb +.section scvxa +.section scvxb +.section scvya +.section scvyb +.section scvza +.section scvzb +.section scv1a +.section scv1b +.section scv2a +.section scv2b +.section scv3a +.section scv3b +.section scv4a +.section scv4b +.section scv5a +.section scv5b +.section scv6a +.section scv6b +.section scv7a +.section scv7b +.section scv8a +.section scv8b +.section scv9a +.section scv9b +.section scv0a +.section scv0b +.section scwaa +.section scwab +.section scwba +.section scwbb +.section scwca +.section scwcb +.section scwda +.section scwdb +.section scwea +.section scweb +.section scwfa +.section scwfb +.section scwga +.section scwgb +.section scwha +.section scwhb +.section scwia +.section scwib +.section scwja +.section scwjb +.section scwka +.section scwkb +.section scwla +.section scwlb +.section scwma +.section scwmb +.section scwna +.section scwnb +.section scwoa +.section scwob +.section scwpa +.section scwpb +.section scwqa +.section scwqb +.section scwra +.section scwrb +.section scwsa +.section scwsb +.section scwta +.section scwtb +.section scwua +.section scwub +.section scwva +.section scwvb +.section scwwa +.section scwwb +.section scwxa +.section scwxb +.section scwya +.section scwyb +.section scwza +.section scwzb +.section scw1a +.section scw1b +.section scw2a +.section scw2b +.section scw3a +.section scw3b +.section scw4a +.section scw4b +.section scw5a +.section scw5b +.section scw6a +.section scw6b +.section scw7a +.section scw7b +.section scw8a +.section scw8b +.section scw9a +.section scw9b +.section scw0a +.section scw0b +.section scxaa +.section scxab +.section scxba +.section scxbb +.section scxca +.section scxcb +.section scxda +.section scxdb +.section scxea +.section scxeb +.section scxfa +.section scxfb +.section scxga +.section scxgb +.section scxha +.section scxhb +.section scxia +.section scxib +.section scxja +.section scxjb +.section scxka +.section scxkb +.section scxla +.section scxlb +.section scxma +.section scxmb +.section scxna +.section scxnb +.section scxoa +.section scxob +.section scxpa +.section scxpb +.section scxqa +.section scxqb +.section scxra +.section scxrb +.section scxsa +.section scxsb +.section scxta +.section scxtb +.section scxua +.section scxub +.section scxva +.section scxvb +.section scxwa +.section scxwb +.section scxxa +.section scxxb +.section scxya +.section scxyb +.section scxza +.section scxzb +.section scx1a +.section scx1b +.section scx2a +.section scx2b +.section scx3a +.section scx3b +.section scx4a +.section scx4b +.section scx5a +.section scx5b +.section scx6a +.section scx6b +.section scx7a +.section scx7b +.section scx8a +.section scx8b +.section scx9a +.section scx9b +.section scx0a +.section scx0b +.section scyaa +.section scyab +.section scyba +.section scybb +.section scyca +.section scycb +.section scyda +.section scydb +.section scyea +.section scyeb +.section scyfa +.section scyfb +.section scyga +.section scygb +.section scyha +.section scyhb +.section scyia +.section scyib +.section scyja +.section scyjb +.section scyka +.section scykb +.section scyla +.section scylb +.section scyma +.section scymb +.section scyna +.section scynb +.section scyoa +.section scyob +.section scypa +.section scypb +.section scyqa +.section scyqb +.section scyra +.section scyrb +.section scysa +.section scysb +.section scyta +.section scytb +.section scyua +.section scyub +.section scyva +.section scyvb +.section scywa +.section scywb +.section scyxa +.section scyxb +.section scyya +.section scyyb +.section scyza +.section scyzb +.section scy1a +.section scy1b +.section scy2a +.section scy2b +.section scy3a +.section scy3b +.section scy4a +.section scy4b +.section scy5a +.section scy5b +.section scy6a +.section scy6b +.section scy7a +.section scy7b +.section scy8a +.section scy8b +.section scy9a +.section scy9b +.section scy0a +.section scy0b +.section sczaa +.section sczab +.section sczba +.section sczbb +.section sczca +.section sczcb +.section sczda +.section sczdb +.section sczea +.section sczeb +.section sczfa +.section sczfb +.section sczga +.section sczgb +.section sczha +.section sczhb +.section sczia +.section sczib +.section sczja +.section sczjb +.section sczka +.section sczkb +.section sczla +.section sczlb +.section sczma +.section sczmb +.section sczna +.section scznb +.section sczoa +.section sczob +.section sczpa +.section sczpb +.section sczqa +.section sczqb +.section sczra +.section sczrb +.section sczsa +.section sczsb +.section sczta +.section scztb +.section sczua +.section sczub +.section sczva +.section sczvb +.section sczwa +.section sczwb +.section sczxa +.section sczxb +.section sczya +.section sczyb +.section sczza +.section sczzb +.section scz1a +.section scz1b +.section scz2a +.section scz2b +.section scz3a +.section scz3b +.section scz4a +.section scz4b +.section scz5a +.section scz5b +.section scz6a +.section scz6b +.section scz7a +.section scz7b +.section scz8a +.section scz8b +.section scz9a +.section scz9b +.section scz0a +.section scz0b +.section sc1aa +.section sc1ab +.section sc1ba +.section sc1bb +.section sc1ca +.section sc1cb +.section sc1da +.section sc1db +.section sc1ea +.section sc1eb +.section sc1fa +.section sc1fb +.section sc1ga +.section sc1gb +.section sc1ha +.section sc1hb +.section sc1ia +.section sc1ib +.section sc1ja +.section sc1jb +.section sc1ka +.section sc1kb +.section sc1la +.section sc1lb +.section sc1ma +.section sc1mb +.section sc1na +.section sc1nb +.section sc1oa +.section sc1ob +.section sc1pa +.section sc1pb +.section sc1qa +.section sc1qb +.section sc1ra +.section sc1rb +.section sc1sa +.section sc1sb +.section sc1ta +.section sc1tb +.section sc1ua +.section sc1ub +.section sc1va +.section sc1vb +.section sc1wa +.section sc1wb +.section sc1xa +.section sc1xb +.section sc1ya +.section sc1yb +.section sc1za +.section sc1zb +.section sc11a +.section sc11b +.section sc12a +.section sc12b +.section sc13a +.section sc13b +.section sc14a +.section sc14b +.section sc15a +.section sc15b +.section sc16a +.section sc16b +.section sc17a +.section sc17b +.section sc18a +.section sc18b +.section sc19a +.section sc19b +.section sc10a +.section sc10b +.section sc2aa +.section sc2ab +.section sc2ba +.section sc2bb +.section sc2ca +.section sc2cb +.section sc2da +.section sc2db +.section sc2ea +.section sc2eb +.section sc2fa +.section sc2fb +.section sc2ga +.section sc2gb +.section sc2ha +.section sc2hb +.section sc2ia +.section sc2ib +.section sc2ja +.section sc2jb +.section sc2ka +.section sc2kb +.section sc2la +.section sc2lb +.section sc2ma +.section sc2mb +.section sc2na +.section sc2nb +.section sc2oa +.section sc2ob +.section sc2pa +.section sc2pb +.section sc2qa +.section sc2qb +.section sc2ra +.section sc2rb +.section sc2sa +.section sc2sb +.section sc2ta +.section sc2tb +.section sc2ua +.section sc2ub +.section sc2va +.section sc2vb +.section sc2wa +.section sc2wb +.section sc2xa +.section sc2xb +.section sc2ya +.section sc2yb +.section sc2za +.section sc2zb +.section sc21a +.section sc21b +.section sc22a +.section sc22b +.section sc23a +.section sc23b +.section sc24a +.section sc24b +.section sc25a +.section sc25b +.section sc26a +.section sc26b +.section sc27a +.section sc27b +.section sc28a +.section sc28b +.section sc29a +.section sc29b +.section sc20a +.section sc20b +.section sc3aa +.section sc3ab +.section sc3ba +.section sc3bb +.section sc3ca +.section sc3cb +.section sc3da +.section sc3db +.section sc3ea +.section sc3eb +.section sc3fa +.section sc3fb +.section sc3ga +.section sc3gb +.section sc3ha +.section sc3hb +.section sc3ia +.section sc3ib +.section sc3ja +.section sc3jb +.section sc3ka +.section sc3kb +.section sc3la +.section sc3lb +.section sc3ma +.section sc3mb +.section sc3na +.section sc3nb +.section sc3oa +.section sc3ob +.section sc3pa +.section sc3pb +.section sc3qa +.section sc3qb +.section sc3ra +.section sc3rb +.section sc3sa +.section sc3sb +.section sc3ta +.section sc3tb +.section sc3ua +.section sc3ub +.section sc3va +.section sc3vb +.section sc3wa +.section sc3wb +.section sc3xa +.section sc3xb +.section sc3ya +.section sc3yb +.section sc3za +.section sc3zb +.section sc31a +.section sc31b +.section sc32a +.section sc32b +.section sc33a +.section sc33b +.section sc34a +.section sc34b +.section sc35a +.section sc35b +.section sc36a +.section sc36b +.section sc37a +.section sc37b +.section sc38a +.section sc38b +.section sc39a +.section sc39b +.section sc30a +.section sc30b +.section sc4aa +.section sc4ab +.section sc4ba +.section sc4bb +.section sc4ca +.section sc4cb +.section sc4da +.section sc4db +.section sc4ea +.section sc4eb +.section sc4fa +.section sc4fb +.section sc4ga +.section sc4gb +.section sc4ha +.section sc4hb +.section sc4ia +.section sc4ib +.section sc4ja +.section sc4jb +.section sc4ka +.section sc4kb +.section sc4la +.section sc4lb +.section sc4ma +.section sc4mb +.section sc4na +.section sc4nb +.section sc4oa +.section sc4ob +.section sc4pa +.section sc4pb +.section sc4qa +.section sc4qb +.section sc4ra +.section sc4rb +.section sc4sa +.section sc4sb +.section sc4ta +.section sc4tb +.section sc4ua +.section sc4ub +.section sc4va +.section sc4vb +.section sc4wa +.section sc4wb +.section sc4xa +.section sc4xb +.section sc4ya +.section sc4yb +.section sc4za +.section sc4zb +.section sc41a +.section sc41b +.section sc42a +.section sc42b +.section sc43a +.section sc43b +.section sc44a +.section sc44b +.section sc45a +.section sc45b +.section sc46a +.section sc46b +.section sc47a +.section sc47b +.section sc48a +.section sc48b +.section sc49a +.section sc49b +.section sc40a +.section sc40b +.section sc5aa +.section sc5ab +.section sc5ba +.section sc5bb +.section sc5ca +.section sc5cb +.section sc5da +.section sc5db +.section sc5ea +.section sc5eb +.section sc5fa +.section sc5fb +.section sc5ga +.section sc5gb +.section sc5ha +.section sc5hb +.section sc5ia +.section sc5ib +.section sc5ja +.section sc5jb +.section sc5ka +.section sc5kb +.section sc5la +.section sc5lb +.section sc5ma +.section sc5mb +.section sc5na +.section sc5nb +.section sc5oa +.section sc5ob +.section sc5pa +.section sc5pb +.section sc5qa +.section sc5qb +.section sc5ra +.section sc5rb +.section sc5sa +.section sc5sb +.section sc5ta +.section sc5tb +.section sc5ua +.section sc5ub +.section sc5va +.section sc5vb +.section sc5wa +.section sc5wb +.section sc5xa +.section sc5xb +.section sc5ya +.section sc5yb +.section sc5za +.section sc5zb +.section sc51a +.section sc51b +.section sc52a +.section sc52b +.section sc53a +.section sc53b +.section sc54a +.section sc54b +.section sc55a +.section sc55b +.section sc56a +.section sc56b +.section sc57a +.section sc57b +.section sc58a +.section sc58b +.section sc59a +.section sc59b +.section sc50a +.section sc50b +.section sc6aa +.section sc6ab +.section sc6ba +.section sc6bb +.section sc6ca +.section sc6cb +.section sc6da +.section sc6db +.section sc6ea +.section sc6eb +.section sc6fa +.section sc6fb +.section sc6ga +.section sc6gb +.section sc6ha +.section sc6hb +.section sc6ia +.section sc6ib +.section sc6ja +.section sc6jb +.section sc6ka +.section sc6kb +.section sc6la +.section sc6lb +.section sc6ma +.section sc6mb +.section sc6na +.section sc6nb +.section sc6oa +.section sc6ob +.section sc6pa +.section sc6pb +.section sc6qa +.section sc6qb +.section sc6ra +.section sc6rb +.section sc6sa +.section sc6sb +.section sc6ta +.section sc6tb +.section sc6ua +.section sc6ub +.section sc6va +.section sc6vb +.section sc6wa +.section sc6wb +.section sc6xa +.section sc6xb +.section sc6ya +.section sc6yb +.section sc6za +.section sc6zb +.section sc61a +.section sc61b +.section sc62a +.section sc62b +.section sc63a +.section sc63b +.section sc64a +.section sc64b +.section sc65a +.section sc65b +.section sc66a +.section sc66b +.section sc67a +.section sc67b +.section sc68a +.section sc68b +.section sc69a +.section sc69b +.section sc60a +.section sc60b +.section sc7aa +.section sc7ab +.section sc7ba +.section sc7bb +.section sc7ca +.section sc7cb +.section sc7da +.section sc7db +.section sc7ea +.section sc7eb +.section sc7fa +.section sc7fb +.section sc7ga +.section sc7gb +.section sc7ha +.section sc7hb +.section sc7ia +.section sc7ib +.section sc7ja +.section sc7jb +.section sc7ka +.section sc7kb +.section sc7la +.section sc7lb +.section sc7ma +.section sc7mb +.section sc7na +.section sc7nb +.section sc7oa +.section sc7ob +.section sc7pa +.section sc7pb +.section sc7qa +.section sc7qb +.section sc7ra +.section sc7rb +.section sc7sa +.section sc7sb +.section sc7ta +.section sc7tb +.section sc7ua +.section sc7ub +.section sc7va +.section sc7vb +.section sc7wa +.section sc7wb +.section sc7xa +.section sc7xb +.section sc7ya +.section sc7yb +.section sc7za +.section sc7zb +.section sc71a +.section sc71b +.section sc72a +.section sc72b +.section sc73a +.section sc73b +.section sc74a +.section sc74b +.section sc75a +.section sc75b +.section sc76a +.section sc76b +.section sc77a +.section sc77b +.section sc78a +.section sc78b +.section sc79a +.section sc79b +.section sc70a +.section sc70b +.section sc8aa +.section sc8ab +.section sc8ba +.section sc8bb +.section sc8ca +.section sc8cb +.section sc8da +.section sc8db +.section sc8ea +.section sc8eb +.section sc8fa +.section sc8fb +.section sc8ga +.section sc8gb +.section sc8ha +.section sc8hb +.section sc8ia +.section sc8ib +.section sc8ja +.section sc8jb +.section sc8ka +.section sc8kb +.section sc8la +.section sc8lb +.section sc8ma +.section sc8mb +.section sc8na +.section sc8nb +.section sc8oa +.section sc8ob +.section sc8pa +.section sc8pb +.section sc8qa +.section sc8qb +.section sc8ra +.section sc8rb +.section sc8sa +.section sc8sb +.section sc8ta +.section sc8tb +.section sc8ua +.section sc8ub +.section sc8va +.section sc8vb +.section sc8wa +.section sc8wb +.section sc8xa +.section sc8xb +.section sc8ya +.section sc8yb +.section sc8za +.section sc8zb +.section sc81a +.section sc81b +.section sc82a +.section sc82b +.section sc83a +.section sc83b +.section sc84a +.section sc84b +.section sc85a +.section sc85b +.section sc86a +.section sc86b +.section sc87a +.section sc87b +.section sc88a +.section sc88b +.section sc89a +.section sc89b +.section sc80a +.section sc80b +.section sc9aa +.section sc9ab +.section sc9ba +.section sc9bb +.section sc9ca +.section sc9cb +.section sc9da +.section sc9db +.section sc9ea +.section sc9eb +.section sc9fa +.section sc9fb +.section sc9ga +.section sc9gb +.section sc9ha +.section sc9hb +.section sc9ia +.section sc9ib +.section sc9ja +.section sc9jb +.section sc9ka +.section sc9kb +.section sc9la +.section sc9lb +.section sc9ma +.section sc9mb +.section sc9na +.section sc9nb +.section sc9oa +.section sc9ob +.section sc9pa +.section sc9pb +.section sc9qa +.section sc9qb +.section sc9ra +.section sc9rb +.section sc9sa +.section sc9sb +.section sc9ta +.section sc9tb +.section sc9ua +.section sc9ub +.section sc9va +.section sc9vb +.section sc9wa +.section sc9wb +.section sc9xa +.section sc9xb +.section sc9ya +.section sc9yb +.section sc9za +.section sc9zb +.section sc91a +.section sc91b +.section sc92a +.section sc92b +.section sc93a +.section sc93b +.section sc94a +.section sc94b +.section sc95a +.section sc95b +.section sc96a +.section sc96b +.section sc97a +.section sc97b +.section sc98a +.section sc98b +.section sc99a +.section sc99b +.section sc90a +.section sc90b +.section sc0aa +.section sc0ab +.section sc0ba +.section sc0bb +.section sc0ca +.section sc0cb +.section sc0da +.section sc0db +.section sc0ea +.section sc0eb +.section sc0fa +.section sc0fb +.section sc0ga +.section sc0gb +.section sc0ha +.section sc0hb +.section sc0ia +.section sc0ib +.section sc0ja +.section sc0jb +.section sc0ka +.section sc0kb +.section sc0la +.section sc0lb +.section sc0ma +.section sc0mb +.section sc0na +.section sc0nb +.section sc0oa +.section sc0ob +.section sc0pa +.section sc0pb +.section sc0qa +.section sc0qb +.section sc0ra +.section sc0rb +.section sc0sa +.section sc0sb +.section sc0ta +.section sc0tb +.section sc0ua +.section sc0ub +.section sc0va +.section sc0vb +.section sc0wa +.section sc0wb +.section sc0xa +.section sc0xb +.section sc0ya +.section sc0yb +.section sc0za +.section sc0zb +.section sc01a +.section sc01b +.section sc02a +.section sc02b +.section sc03a +.section sc03b +.section sc04a +.section sc04b +.section sc05a +.section sc05b +.section sc06a +.section sc06b +.section sc07a +.section sc07b +.section sc08a +.section sc08b +.section sc09a +.section sc09b +.section sc00a +.section sc00b +.section sdaaa +.section sdaab +.section sdaba +.section sdabb +.section sdaca +.section sdacb +.section sdada +.section sdadb +.section sdaea +.section sdaeb +.section sdafa +.section sdafb +.section sdaga +.section sdagb +.section sdaha +.section sdahb +.section sdaia +.section sdaib +.section sdaja +.section sdajb +.section sdaka +.section sdakb +.section sdala +.section sdalb +.section sdama +.section sdamb +.section sdana +.section sdanb +.section sdaoa +.section sdaob +.section sdapa +.section sdapb +.section sdaqa +.section sdaqb +.section sdara +.section sdarb +.section sdasa +.section sdasb +.section sdata +.section sdatb +.section sdaua +.section sdaub +.section sdava +.section sdavb +.section sdawa +.section sdawb +.section sdaxa +.section sdaxb +.section sdaya +.section sdayb +.section sdaza +.section sdazb +.section sda1a +.section sda1b +.section sda2a +.section sda2b +.section sda3a +.section sda3b +.section sda4a +.section sda4b +.section sda5a +.section sda5b +.section sda6a +.section sda6b +.section sda7a +.section sda7b +.section sda8a +.section sda8b +.section sda9a +.section sda9b +.section sda0a +.section sda0b +.section sdbaa +.section sdbab +.section sdbba +.section sdbbb +.section sdbca +.section sdbcb +.section sdbda +.section sdbdb +.section sdbea +.section sdbeb +.section sdbfa +.section sdbfb +.section sdbga +.section sdbgb +.section sdbha +.section sdbhb +.section sdbia +.section sdbib +.section sdbja +.section sdbjb +.section sdbka +.section sdbkb +.section sdbla +.section sdblb +.section sdbma +.section sdbmb +.section sdbna +.section sdbnb +.section sdboa +.section sdbob +.section sdbpa +.section sdbpb +.section sdbqa +.section sdbqb +.section sdbra +.section sdbrb +.section sdbsa +.section sdbsb +.section sdbta +.section sdbtb +.section sdbua +.section sdbub +.section sdbva +.section sdbvb +.section sdbwa +.section sdbwb +.section sdbxa +.section sdbxb +.section sdbya +.section sdbyb +.section sdbza +.section sdbzb +.section sdb1a +.section sdb1b +.section sdb2a +.section sdb2b +.section sdb3a +.section sdb3b +.section sdb4a +.section sdb4b +.section sdb5a +.section sdb5b +.section sdb6a +.section sdb6b +.section sdb7a +.section sdb7b +.section sdb8a +.section sdb8b +.section sdb9a +.section sdb9b +.section sdb0a +.section sdb0b +.section sdcaa +.section sdcab +.section sdcba +.section sdcbb +.section sdcca +.section sdccb +.section sdcda +.section sdcdb +.section sdcea +.section sdceb +.section sdcfa +.section sdcfb +.section sdcga +.section sdcgb +.section sdcha +.section sdchb +.section sdcia +.section sdcib +.section sdcja +.section sdcjb +.section sdcka +.section sdckb +.section sdcla +.section sdclb +.section sdcma +.section sdcmb +.section sdcna +.section sdcnb +.section sdcoa +.section sdcob +.section sdcpa +.section sdcpb +.section sdcqa +.section sdcqb +.section sdcra +.section sdcrb +.section sdcsa +.section sdcsb +.section sdcta +.section sdctb +.section sdcua +.section sdcub +.section sdcva +.section sdcvb +.section sdcwa +.section sdcwb +.section sdcxa +.section sdcxb +.section sdcya +.section sdcyb +.section sdcza +.section sdczb +.section sdc1a +.section sdc1b +.section sdc2a +.section sdc2b +.section sdc3a +.section sdc3b +.section sdc4a +.section sdc4b +.section sdc5a +.section sdc5b +.section sdc6a +.section sdc6b +.section sdc7a +.section sdc7b +.section sdc8a +.section sdc8b +.section sdc9a +.section sdc9b +.section sdc0a +.section sdc0b +.section sddaa +.section sddab +.section sddba +.section sddbb +.section sddca +.section sddcb +.section sddda +.section sdddb +.section sddea +.section sddeb +.section sddfa +.section sddfb +.section sddga +.section sddgb +.section sddha +.section sddhb +.section sddia +.section sddib +.section sddja +.section sddjb +.section sddka +.section sddkb +.section sddla +.section sddlb +.section sddma +.section sddmb +.section sddna +.section sddnb +.section sddoa +.section sddob +.section sddpa +.section sddpb +.section sddqa +.section sddqb +.section sddra +.section sddrb +.section sddsa +.section sddsb +.section sddta +.section sddtb +.section sddua +.section sddub +.section sddva +.section sddvb +.section sddwa +.section sddwb +.section sddxa +.section sddxb +.section sddya +.section sddyb +.section sddza +.section sddzb +.section sdd1a +.section sdd1b +.section sdd2a +.section sdd2b +.section sdd3a +.section sdd3b +.section sdd4a +.section sdd4b +.section sdd5a +.section sdd5b +.section sdd6a +.section sdd6b +.section sdd7a +.section sdd7b +.section sdd8a +.section sdd8b +.section sdd9a +.section sdd9b +.section sdd0a +.section sdd0b +.section sdeaa +.section sdeab +.section sdeba +.section sdebb +.section sdeca +.section sdecb +.section sdeda +.section sdedb +.section sdeea +.section sdeeb +.section sdefa +.section sdefb +.section sdega +.section sdegb +.section sdeha +.section sdehb +.section sdeia +.section sdeib +.section sdeja +.section sdejb +.section sdeka +.section sdekb +.section sdela +.section sdelb +.section sdema +.section sdemb +.section sdena +.section sdenb +.section sdeoa +.section sdeob +.section sdepa +.section sdepb +.section sdeqa +.section sdeqb +.section sdera +.section sderb +.section sdesa +.section sdesb +.section sdeta +.section sdetb +.section sdeua +.section sdeub +.section sdeva +.section sdevb +.section sdewa +.section sdewb +.section sdexa +.section sdexb +.section sdeya +.section sdeyb +.section sdeza +.section sdezb +.section sde1a +.section sde1b +.section sde2a +.section sde2b +.section sde3a +.section sde3b +.section sde4a +.section sde4b +.section sde5a +.section sde5b +.section sde6a +.section sde6b +.section sde7a +.section sde7b +.section sde8a +.section sde8b +.section sde9a +.section sde9b +.section sde0a +.section sde0b +.section sdfaa +.section sdfab +.section sdfba +.section sdfbb +.section sdfca +.section sdfcb +.section sdfda +.section sdfdb +.section sdfea +.section sdfeb +.section sdffa +.section sdffb +.section sdfga +.section sdfgb +.section sdfha +.section sdfhb +.section sdfia +.section sdfib +.section sdfja +.section sdfjb +.section sdfka +.section sdfkb +.section sdfla +.section sdflb +.section sdfma +.section sdfmb +.section sdfna +.section sdfnb +.section sdfoa +.section sdfob +.section sdfpa +.section sdfpb +.section sdfqa +.section sdfqb +.section sdfra +.section sdfrb +.section sdfsa +.section sdfsb +.section sdfta +.section sdftb +.section sdfua +.section sdfub +.section sdfva +.section sdfvb +.section sdfwa +.section sdfwb +.section sdfxa +.section sdfxb +.section sdfya +.section sdfyb +.section sdfza +.section sdfzb +.section sdf1a +.section sdf1b +.section sdf2a +.section sdf2b +.section sdf3a +.section sdf3b +.section sdf4a +.section sdf4b +.section sdf5a +.section sdf5b +.section sdf6a +.section sdf6b +.section sdf7a +.section sdf7b +.section sdf8a +.section sdf8b +.section sdf9a +.section sdf9b +.section sdf0a +.section sdf0b +.section sdgaa +.section sdgab +.section sdgba +.section sdgbb +.section sdgca +.section sdgcb +.section sdgda +.section sdgdb +.section sdgea +.section sdgeb +.section sdgfa +.section sdgfb +.section sdgga +.section sdggb +.section sdgha +.section sdghb +.section sdgia +.section sdgib +.section sdgja +.section sdgjb +.section sdgka +.section sdgkb +.section sdgla +.section sdglb +.section sdgma +.section sdgmb +.section sdgna +.section sdgnb +.section sdgoa +.section sdgob +.section sdgpa +.section sdgpb +.section sdgqa +.section sdgqb +.section sdgra +.section sdgrb +.section sdgsa +.section sdgsb +.section sdgta +.section sdgtb +.section sdgua +.section sdgub +.section sdgva +.section sdgvb +.section sdgwa +.section sdgwb +.section sdgxa +.section sdgxb +.section sdgya +.section sdgyb +.section sdgza +.section sdgzb +.section sdg1a +.section sdg1b +.section sdg2a +.section sdg2b +.section sdg3a +.section sdg3b +.section sdg4a +.section sdg4b +.section sdg5a +.section sdg5b +.section sdg6a +.section sdg6b +.section sdg7a +.section sdg7b +.section sdg8a +.section sdg8b +.section sdg9a +.section sdg9b +.section sdg0a +.section sdg0b +.section sdhaa +.section sdhab +.section sdhba +.section sdhbb +.section sdhca +.section sdhcb +.section sdhda +.section sdhdb +.section sdhea +.section sdheb +.section sdhfa +.section sdhfb +.section sdhga +.section sdhgb +.section sdhha +.section sdhhb +.section sdhia +.section sdhib +.section sdhja +.section sdhjb +.section sdhka +.section sdhkb +.section sdhla +.section sdhlb +.section sdhma +.section sdhmb +.section sdhna +.section sdhnb +.section sdhoa +.section sdhob +.section sdhpa +.section sdhpb +.section sdhqa +.section sdhqb +.section sdhra +.section sdhrb +.section sdhsa +.section sdhsb +.section sdhta +.section sdhtb +.section sdhua +.section sdhub +.section sdhva +.section sdhvb +.section sdhwa +.section sdhwb +.section sdhxa +.section sdhxb +.section sdhya +.section sdhyb +.section sdhza +.section sdhzb +.section sdh1a +.section sdh1b +.section sdh2a +.section sdh2b +.section sdh3a +.section sdh3b +.section sdh4a +.section sdh4b +.section sdh5a +.section sdh5b +.section sdh6a +.section sdh6b +.section sdh7a +.section sdh7b +.section sdh8a +.section sdh8b +.section sdh9a +.section sdh9b +.section sdh0a +.section sdh0b +.section sdiaa +.section sdiab +.section sdiba +.section sdibb +.section sdica +.section sdicb +.section sdida +.section sdidb +.section sdiea +.section sdieb +.section sdifa +.section sdifb +.section sdiga +.section sdigb +.section sdiha +.section sdihb +.section sdiia +.section sdiib +.section sdija +.section sdijb +.section sdika +.section sdikb +.section sdila +.section sdilb +.section sdima +.section sdimb +.section sdina +.section sdinb +.section sdioa +.section sdiob +.section sdipa +.section sdipb +.section sdiqa +.section sdiqb +.section sdira +.section sdirb +.section sdisa +.section sdisb +.section sdita +.section sditb +.section sdiua +.section sdiub +.section sdiva +.section sdivb +.section sdiwa +.section sdiwb +.section sdixa +.section sdixb +.section sdiya +.section sdiyb +.section sdiza +.section sdizb +.section sdi1a +.section sdi1b +.section sdi2a +.section sdi2b +.section sdi3a +.section sdi3b +.section sdi4a +.section sdi4b +.section sdi5a +.section sdi5b +.section sdi6a +.section sdi6b +.section sdi7a +.section sdi7b +.section sdi8a +.section sdi8b +.section sdi9a +.section sdi9b +.section sdi0a +.section sdi0b +.section sdjaa +.section sdjab +.section sdjba +.section sdjbb +.section sdjca +.section sdjcb +.section sdjda +.section sdjdb +.section sdjea +.section sdjeb +.section sdjfa +.section sdjfb +.section sdjga +.section sdjgb +.section sdjha +.section sdjhb +.section sdjia +.section sdjib +.section sdjja +.section sdjjb +.section sdjka +.section sdjkb +.section sdjla +.section sdjlb +.section sdjma +.section sdjmb +.section sdjna +.section sdjnb +.section sdjoa +.section sdjob +.section sdjpa +.section sdjpb +.section sdjqa +.section sdjqb +.section sdjra +.section sdjrb +.section sdjsa +.section sdjsb +.section sdjta +.section sdjtb +.section sdjua +.section sdjub +.section sdjva +.section sdjvb +.section sdjwa +.section sdjwb +.section sdjxa +.section sdjxb +.section sdjya +.section sdjyb +.section sdjza +.section sdjzb +.section sdj1a +.section sdj1b +.section sdj2a +.section sdj2b +.section sdj3a +.section sdj3b +.section sdj4a +.section sdj4b +.section sdj5a +.section sdj5b +.section sdj6a +.section sdj6b +.section sdj7a +.section sdj7b +.section sdj8a +.section sdj8b +.section sdj9a +.section sdj9b +.section sdj0a +.section sdj0b +.section sdkaa +.section sdkab +.section sdkba +.section sdkbb +.section sdkca +.section sdkcb +.section sdkda +.section sdkdb +.section sdkea +.section sdkeb +.section sdkfa +.section sdkfb +.section sdkga +.section sdkgb +.section sdkha +.section sdkhb +.section sdkia +.section sdkib +.section sdkja +.section sdkjb +.section sdkka +.section sdkkb +.section sdkla +.section sdklb +.section sdkma +.section sdkmb +.section sdkna +.section sdknb +.section sdkoa +.section sdkob +.section sdkpa +.section sdkpb +.section sdkqa +.section sdkqb +.section sdkra +.section sdkrb +.section sdksa +.section sdksb +.section sdkta +.section sdktb +.section sdkua +.section sdkub +.section sdkva +.section sdkvb +.section sdkwa +.section sdkwb +.section sdkxa +.section sdkxb +.section sdkya +.section sdkyb +.section sdkza +.section sdkzb +.section sdk1a +.section sdk1b +.section sdk2a +.section sdk2b +.section sdk3a +.section sdk3b +.section sdk4a +.section sdk4b +.section sdk5a +.section sdk5b +.section sdk6a +.section sdk6b +.section sdk7a +.section sdk7b +.section sdk8a +.section sdk8b +.section sdk9a +.section sdk9b +.section sdk0a +.section sdk0b +.section sdlaa +.section sdlab +.section sdlba +.section sdlbb +.section sdlca +.section sdlcb +.section sdlda +.section sdldb +.section sdlea +.section sdleb +.section sdlfa +.section sdlfb +.section sdlga +.section sdlgb +.section sdlha +.section sdlhb +.section sdlia +.section sdlib +.section sdlja +.section sdljb +.section sdlka +.section sdlkb +.section sdlla +.section sdllb +.section sdlma +.section sdlmb +.section sdlna +.section sdlnb +.section sdloa +.section sdlob +.section sdlpa +.section sdlpb +.section sdlqa +.section sdlqb +.section sdlra +.section sdlrb +.section sdlsa +.section sdlsb +.section sdlta +.section sdltb +.section sdlua +.section sdlub +.section sdlva +.section sdlvb +.section sdlwa +.section sdlwb +.section sdlxa +.section sdlxb +.section sdlya +.section sdlyb +.section sdlza +.section sdlzb +.section sdl1a +.section sdl1b +.section sdl2a +.section sdl2b +.section sdl3a +.section sdl3b +.section sdl4a +.section sdl4b +.section sdl5a +.section sdl5b +.section sdl6a +.section sdl6b +.section sdl7a +.section sdl7b +.section sdl8a +.section sdl8b +.section sdl9a +.section sdl9b +.section sdl0a +.section sdl0b +.section sdmaa +.section sdmab +.section sdmba +.section sdmbb +.section sdmca +.section sdmcb +.section sdmda +.section sdmdb +.section sdmea +.section sdmeb +.section sdmfa +.section sdmfb +.section sdmga +.section sdmgb +.section sdmha +.section sdmhb +.section sdmia +.section sdmib +.section sdmja +.section sdmjb +.section sdmka +.section sdmkb +.section sdmla +.section sdmlb +.section sdmma +.section sdmmb +.section sdmna +.section sdmnb +.section sdmoa +.section sdmob +.section sdmpa +.section sdmpb +.section sdmqa +.section sdmqb +.section sdmra +.section sdmrb +.section sdmsa +.section sdmsb +.section sdmta +.section sdmtb +.section sdmua +.section sdmub +.section sdmva +.section sdmvb +.section sdmwa +.section sdmwb +.section sdmxa +.section sdmxb +.section sdmya +.section sdmyb +.section sdmza +.section sdmzb +.section sdm1a +.section sdm1b +.section sdm2a +.section sdm2b +.section sdm3a +.section sdm3b +.section sdm4a +.section sdm4b +.section sdm5a +.section sdm5b +.section sdm6a +.section sdm6b +.section sdm7a +.section sdm7b +.section sdm8a +.section sdm8b +.section sdm9a +.section sdm9b +.section sdm0a +.section sdm0b +.section sdnaa +.section sdnab +.section sdnba +.section sdnbb +.section sdnca +.section sdncb +.section sdnda +.section sdndb +.section sdnea +.section sdneb +.section sdnfa +.section sdnfb +.section sdnga +.section sdngb +.section sdnha +.section sdnhb +.section sdnia +.section sdnib +.section sdnja +.section sdnjb +.section sdnka +.section sdnkb +.section sdnla +.section sdnlb +.section sdnma +.section sdnmb +.section sdnna +.section sdnnb +.section sdnoa +.section sdnob +.section sdnpa +.section sdnpb +.section sdnqa +.section sdnqb +.section sdnra +.section sdnrb +.section sdnsa +.section sdnsb +.section sdnta +.section sdntb +.section sdnua +.section sdnub +.section sdnva +.section sdnvb +.section sdnwa +.section sdnwb +.section sdnxa +.section sdnxb +.section sdnya +.section sdnyb +.section sdnza +.section sdnzb +.section sdn1a +.section sdn1b +.section sdn2a +.section sdn2b +.section sdn3a +.section sdn3b +.section sdn4a +.section sdn4b +.section sdn5a +.section sdn5b +.section sdn6a +.section sdn6b +.section sdn7a +.section sdn7b +.section sdn8a +.section sdn8b +.section sdn9a +.section sdn9b +.section sdn0a +.section sdn0b +.section sdoaa +.section sdoab +.section sdoba +.section sdobb +.section sdoca +.section sdocb +.section sdoda +.section sdodb +.section sdoea +.section sdoeb +.section sdofa +.section sdofb +.section sdoga +.section sdogb +.section sdoha +.section sdohb +.section sdoia +.section sdoib +.section sdoja +.section sdojb +.section sdoka +.section sdokb +.section sdola +.section sdolb +.section sdoma +.section sdomb +.section sdona +.section sdonb +.section sdooa +.section sdoob +.section sdopa +.section sdopb +.section sdoqa +.section sdoqb +.section sdora +.section sdorb +.section sdosa +.section sdosb +.section sdota +.section sdotb +.section sdoua +.section sdoub +.section sdova +.section sdovb +.section sdowa +.section sdowb +.section sdoxa +.section sdoxb +.section sdoya +.section sdoyb +.section sdoza +.section sdozb +.section sdo1a +.section sdo1b +.section sdo2a +.section sdo2b +.section sdo3a +.section sdo3b +.section sdo4a +.section sdo4b +.section sdo5a +.section sdo5b +.section sdo6a +.section sdo6b +.section sdo7a +.section sdo7b +.section sdo8a +.section sdo8b +.section sdo9a +.section sdo9b +.section sdo0a +.section sdo0b +.section sdpaa +.section sdpab +.section sdpba +.section sdpbb +.section sdpca +.section sdpcb +.section sdpda +.section sdpdb +.section sdpea +.section sdpeb +.section sdpfa +.section sdpfb +.section sdpga +.section sdpgb +.section sdpha +.section sdphb +.section sdpia +.section sdpib +.section sdpja +.section sdpjb +.section sdpka +.section sdpkb +.section sdpla +.section sdplb +.section sdpma +.section sdpmb +.section sdpna +.section sdpnb +.section sdpoa +.section sdpob +.section sdppa +.section sdppb +.section sdpqa +.section sdpqb +.section sdpra +.section sdprb +.section sdpsa +.section sdpsb +.section sdpta +.section sdptb +.section sdpua +.section sdpub +.section sdpva +.section sdpvb +.section sdpwa +.section sdpwb +.section sdpxa +.section sdpxb +.section sdpya +.section sdpyb +.section sdpza +.section sdpzb +.section sdp1a +.section sdp1b +.section sdp2a +.section sdp2b +.section sdp3a +.section sdp3b +.section sdp4a +.section sdp4b +.section sdp5a +.section sdp5b +.section sdp6a +.section sdp6b +.section sdp7a +.section sdp7b +.section sdp8a +.section sdp8b +.section sdp9a +.section sdp9b +.section sdp0a +.section sdp0b +.section sdqaa +.section sdqab +.section sdqba +.section sdqbb +.section sdqca +.section sdqcb +.section sdqda +.section sdqdb +.section sdqea +.section sdqeb +.section sdqfa +.section sdqfb +.section sdqga +.section sdqgb +.section sdqha +.section sdqhb +.section sdqia +.section sdqib +.section sdqja +.section sdqjb +.section sdqka +.section sdqkb +.section sdqla +.section sdqlb +.section sdqma +.section sdqmb +.section sdqna +.section sdqnb +.section sdqoa +.section sdqob +.section sdqpa +.section sdqpb +.section sdqqa +.section sdqqb +.section sdqra +.section sdqrb +.section sdqsa +.section sdqsb +.section sdqta +.section sdqtb +.section sdqua +.section sdqub +.section sdqva +.section sdqvb +.section sdqwa +.section sdqwb +.section sdqxa +.section sdqxb +.section sdqya +.section sdqyb +.section sdqza +.section sdqzb +.section sdq1a +.section sdq1b +.section sdq2a +.section sdq2b +.section sdq3a +.section sdq3b +.section sdq4a +.section sdq4b +.section sdq5a +.section sdq5b +.section sdq6a +.section sdq6b +.section sdq7a +.section sdq7b +.section sdq8a +.section sdq8b +.section sdq9a +.section sdq9b +.section sdq0a +.section sdq0b +.section sdraa +.section sdrab +.section sdrba +.section sdrbb +.section sdrca +.section sdrcb +.section sdrda +.section sdrdb +.section sdrea +.section sdreb +.section sdrfa +.section sdrfb +.section sdrga +.section sdrgb +.section sdrha +.section sdrhb +.section sdria +.section sdrib +.section sdrja +.section sdrjb +.section sdrka +.section sdrkb +.section sdrla +.section sdrlb +.section sdrma +.section sdrmb +.section sdrna +.section sdrnb +.section sdroa +.section sdrob +.section sdrpa +.section sdrpb +.section sdrqa +.section sdrqb +.section sdrra +.section sdrrb +.section sdrsa +.section sdrsb +.section sdrta +.section sdrtb +.section sdrua +.section sdrub +.section sdrva +.section sdrvb +.section sdrwa +.section sdrwb +.section sdrxa +.section sdrxb +.section sdrya +.section sdryb +.section sdrza +.section sdrzb +.section sdr1a +.section sdr1b +.section sdr2a +.section sdr2b +.section sdr3a +.section sdr3b +.section sdr4a +.section sdr4b +.section sdr5a +.section sdr5b +.section sdr6a +.section sdr6b +.section sdr7a +.section sdr7b +.section sdr8a +.section sdr8b +.section sdr9a +.section sdr9b +.section sdr0a +.section sdr0b +.section sdsaa +.section sdsab +.section sdsba +.section sdsbb +.section sdsca +.section sdscb +.section sdsda +.section sdsdb +.section sdsea +.section sdseb +.section sdsfa +.section sdsfb +.section sdsga +.section sdsgb +.section sdsha +.section sdshb +.section sdsia +.section sdsib +.section sdsja +.section sdsjb +.section sdska +.section sdskb +.section sdsla +.section sdslb +.section sdsma +.section sdsmb +.section sdsna +.section sdsnb +.section sdsoa +.section sdsob +.section sdspa +.section sdspb +.section sdsqa +.section sdsqb +.section sdsra +.section sdsrb +.section sdssa +.section sdssb +.section sdsta +.section sdstb +.section sdsua +.section sdsub +.section sdsva +.section sdsvb +.section sdswa +.section sdswb +.section sdsxa +.section sdsxb +.section sdsya +.section sdsyb +.section sdsza +.section sdszb +.section sds1a +.section sds1b +.section sds2a +.section sds2b +.section sds3a +.section sds3b +.section sds4a +.section sds4b +.section sds5a +.section sds5b +.section sds6a +.section sds6b +.section sds7a +.section sds7b +.section sds8a +.section sds8b +.section sds9a +.section sds9b +.section sds0a +.section sds0b +.section sdtaa +.section sdtab +.section sdtba +.section sdtbb +.section sdtca +.section sdtcb +.section sdtda +.section sdtdb +.section sdtea +.section sdteb +.section sdtfa +.section sdtfb +.section sdtga +.section sdtgb +.section sdtha +.section sdthb +.section sdtia +.section sdtib +.section sdtja +.section sdtjb +.section sdtka +.section sdtkb +.section sdtla +.section sdtlb +.section sdtma +.section sdtmb +.section sdtna +.section sdtnb +.section sdtoa +.section sdtob +.section sdtpa +.section sdtpb +.section sdtqa +.section sdtqb +.section sdtra +.section sdtrb +.section sdtsa +.section sdtsb +.section sdtta +.section sdttb +.section sdtua +.section sdtub +.section sdtva +.section sdtvb +.section sdtwa +.section sdtwb +.section sdtxa +.section sdtxb +.section sdtya +.section sdtyb +.section sdtza +.section sdtzb +.section sdt1a +.section sdt1b +.section sdt2a +.section sdt2b +.section sdt3a +.section sdt3b +.section sdt4a +.section sdt4b +.section sdt5a +.section sdt5b +.section sdt6a +.section sdt6b +.section sdt7a +.section sdt7b +.section sdt8a +.section sdt8b +.section sdt9a +.section sdt9b +.section sdt0a +.section sdt0b +.section sduaa +.section sduab +.section sduba +.section sdubb +.section sduca +.section sducb +.section sduda +.section sdudb +.section sduea +.section sdueb +.section sdufa +.section sdufb +.section sduga +.section sdugb +.section sduha +.section sduhb +.section sduia +.section sduib +.section sduja +.section sdujb +.section sduka +.section sdukb +.section sdula +.section sdulb +.section sduma +.section sdumb +.section sduna +.section sdunb +.section sduoa +.section sduob +.section sdupa +.section sdupb +.section sduqa +.section sduqb +.section sdura +.section sdurb +.section sdusa +.section sdusb +.section sduta +.section sdutb +.section sduua +.section sduub +.section sduva +.section sduvb +.section sduwa +.section sduwb +.section sduxa +.section sduxb +.section sduya +.section sduyb +.section sduza +.section sduzb +.section sdu1a +.section sdu1b +.section sdu2a +.section sdu2b +.section sdu3a +.section sdu3b +.section sdu4a +.section sdu4b +.section sdu5a +.section sdu5b +.section sdu6a +.section sdu6b +.section sdu7a +.section sdu7b +.section sdu8a +.section sdu8b +.section sdu9a +.section sdu9b +.section sdu0a +.section sdu0b +.section sdvaa +.section sdvab +.section sdvba +.section sdvbb +.section sdvca +.section sdvcb +.section sdvda +.section sdvdb +.section sdvea +.section sdveb +.section sdvfa +.section sdvfb +.section sdvga +.section sdvgb +.section sdvha +.section sdvhb +.section sdvia +.section sdvib +.section sdvja +.section sdvjb +.section sdvka +.section sdvkb +.section sdvla +.section sdvlb +.section sdvma +.section sdvmb +.section sdvna +.section sdvnb +.section sdvoa +.section sdvob +.section sdvpa +.section sdvpb +.section sdvqa +.section sdvqb +.section sdvra +.section sdvrb +.section sdvsa +.section sdvsb +.section sdvta +.section sdvtb +.section sdvua +.section sdvub +.section sdvva +.section sdvvb +.section sdvwa +.section sdvwb +.section sdvxa +.section sdvxb +.section sdvya +.section sdvyb +.section sdvza +.section sdvzb +.section sdv1a +.section sdv1b +.section sdv2a +.section sdv2b +.section sdv3a +.section sdv3b +.section sdv4a +.section sdv4b +.section sdv5a +.section sdv5b +.section sdv6a +.section sdv6b +.section sdv7a +.section sdv7b +.section sdv8a +.section sdv8b +.section sdv9a +.section sdv9b +.section sdv0a +.section sdv0b +.section sdwaa +.section sdwab +.section sdwba +.section sdwbb +.section sdwca +.section sdwcb +.section sdwda +.section sdwdb +.section sdwea +.section sdweb +.section sdwfa +.section sdwfb +.section sdwga +.section sdwgb +.section sdwha +.section sdwhb +.section sdwia +.section sdwib +.section sdwja +.section sdwjb +.section sdwka +.section sdwkb +.section sdwla +.section sdwlb +.section sdwma +.section sdwmb +.section sdwna +.section sdwnb +.section sdwoa +.section sdwob +.section sdwpa +.section sdwpb +.section sdwqa +.section sdwqb +.section sdwra +.section sdwrb +.section sdwsa +.section sdwsb +.section sdwta +.section sdwtb +.section sdwua +.section sdwub +.section sdwva +.section sdwvb +.section sdwwa +.section sdwwb +.section sdwxa +.section sdwxb +.section sdwya +.section sdwyb +.section sdwza +.section sdwzb +.section sdw1a +.section sdw1b +.section sdw2a +.section sdw2b +.section sdw3a +.section sdw3b +.section sdw4a +.section sdw4b +.section sdw5a +.section sdw5b +.section sdw6a +.section sdw6b +.section sdw7a +.section sdw7b +.section sdw8a +.section sdw8b +.section sdw9a +.section sdw9b +.section sdw0a +.section sdw0b +.section sdxaa +.section sdxab +.section sdxba +.section sdxbb +.section sdxca +.section sdxcb +.section sdxda +.section sdxdb +.section sdxea +.section sdxeb +.section sdxfa +.section sdxfb +.section sdxga +.section sdxgb +.section sdxha +.section sdxhb +.section sdxia +.section sdxib +.section sdxja +.section sdxjb +.section sdxka +.section sdxkb +.section sdxla +.section sdxlb +.section sdxma +.section sdxmb +.section sdxna +.section sdxnb +.section sdxoa +.section sdxob +.section sdxpa +.section sdxpb +.section sdxqa +.section sdxqb +.section sdxra +.section sdxrb +.section sdxsa +.section sdxsb +.section sdxta +.section sdxtb +.section sdxua +.section sdxub +.section sdxva +.section sdxvb +.section sdxwa +.section sdxwb +.section sdxxa +.section sdxxb +.section sdxya +.section sdxyb +.section sdxza +.section sdxzb +.section sdx1a +.section sdx1b +.section sdx2a +.section sdx2b +.section sdx3a +.section sdx3b +.section sdx4a +.section sdx4b +.section sdx5a +.section sdx5b +.section sdx6a +.section sdx6b +.section sdx7a +.section sdx7b +.section sdx8a +.section sdx8b +.section sdx9a +.section sdx9b +.section sdx0a +.section sdx0b +.section sdyaa +.section sdyab +.section sdyba +.section sdybb +.section sdyca +.section sdycb +.section sdyda +.section sdydb +.section sdyea +.section sdyeb +.section sdyfa +.section sdyfb +.section sdyga +.section sdygb +.section sdyha +.section sdyhb +.section sdyia +.section sdyib +.section sdyja +.section sdyjb +.section sdyka +.section sdykb +.section sdyla +.section sdylb +.section sdyma +.section sdymb +.section sdyna +.section sdynb +.section sdyoa +.section sdyob +.section sdypa +.section sdypb +.section sdyqa +.section sdyqb +.section sdyra +.section sdyrb +.section sdysa +.section sdysb +.section sdyta +.section sdytb +.section sdyua +.section sdyub +.section sdyva +.section sdyvb +.section sdywa +.section sdywb +.section sdyxa +.section sdyxb +.section sdyya +.section sdyyb +.section sdyza +.section sdyzb +.section sdy1a +.section sdy1b +.section sdy2a +.section sdy2b +.section sdy3a +.section sdy3b +.section sdy4a +.section sdy4b +.section sdy5a +.section sdy5b +.section sdy6a +.section sdy6b +.section sdy7a +.section sdy7b +.section sdy8a +.section sdy8b +.section sdy9a +.section sdy9b +.section sdy0a +.section sdy0b +.section sdzaa +.section sdzab +.section sdzba +.section sdzbb +.section sdzca +.section sdzcb +.section sdzda +.section sdzdb +.section sdzea +.section sdzeb +.section sdzfa +.section sdzfb +.section sdzga +.section sdzgb +.section sdzha +.section sdzhb +.section sdzia +.section sdzib +.section sdzja +.section sdzjb +.section sdzka +.section sdzkb +.section sdzla +.section sdzlb +.section sdzma +.section sdzmb +.section sdzna +.section sdznb +.section sdzoa +.section sdzob +.section sdzpa +.section sdzpb +.section sdzqa +.section sdzqb +.section sdzra +.section sdzrb +.section sdzsa +.section sdzsb +.section sdzta +.section sdztb +.section sdzua +.section sdzub +.section sdzva +.section sdzvb +.section sdzwa +.section sdzwb +.section sdzxa +.section sdzxb +.section sdzya +.section sdzyb +.section sdzza +.section sdzzb +.section sdz1a +.section sdz1b +.section sdz2a +.section sdz2b +.section sdz3a +.section sdz3b +.section sdz4a +.section sdz4b +.section sdz5a +.section sdz5b +.section sdz6a +.section sdz6b +.section sdz7a +.section sdz7b +.section sdz8a +.section sdz8b +.section sdz9a +.section sdz9b +.section sdz0a +.section sdz0b +.section sd1aa +.section sd1ab +.section sd1ba +.section sd1bb +.section sd1ca +.section sd1cb +.section sd1da +.section sd1db +.section sd1ea +.section sd1eb +.section sd1fa +.section sd1fb +.section sd1ga +.section sd1gb +.section sd1ha +.section sd1hb +.section sd1ia +.section sd1ib +.section sd1ja +.section sd1jb +.section sd1ka +.section sd1kb +.section sd1la +.section sd1lb +.section sd1ma +.section sd1mb +.section sd1na +.section sd1nb +.section sd1oa +.section sd1ob +.section sd1pa +.section sd1pb +.section sd1qa +.section sd1qb +.section sd1ra +.section sd1rb +.section sd1sa +.section sd1sb +.section sd1ta +.section sd1tb +.section sd1ua +.section sd1ub +.section sd1va +.section sd1vb +.section sd1wa +.section sd1wb +.section sd1xa +.section sd1xb +.section sd1ya +.section sd1yb +.section sd1za +.section sd1zb +.section sd11a +.section sd11b +.section sd12a +.section sd12b +.section sd13a +.section sd13b +.section sd14a +.section sd14b +.section sd15a +.section sd15b +.section sd16a +.section sd16b +.section sd17a +.section sd17b +.section sd18a +.section sd18b +.section sd19a +.section sd19b +.section sd10a +.section sd10b +.section sd2aa +.section sd2ab +.section sd2ba +.section sd2bb +.section sd2ca +.section sd2cb +.section sd2da +.section sd2db +.section sd2ea +.section sd2eb +.section sd2fa +.section sd2fb +.section sd2ga +.section sd2gb +.section sd2ha +.section sd2hb +.section sd2ia +.section sd2ib +.section sd2ja +.section sd2jb +.section sd2ka +.section sd2kb +.section sd2la +.section sd2lb +.section sd2ma +.section sd2mb +.section sd2na +.section sd2nb +.section sd2oa +.section sd2ob +.section sd2pa +.section sd2pb +.section sd2qa +.section sd2qb +.section sd2ra +.section sd2rb +.section sd2sa +.section sd2sb +.section sd2ta +.section sd2tb +.section sd2ua +.section sd2ub +.section sd2va +.section sd2vb +.section sd2wa +.section sd2wb +.section sd2xa +.section sd2xb +.section sd2ya +.section sd2yb +.section sd2za +.section sd2zb +.section sd21a +.section sd21b +.section sd22a +.section sd22b +.section sd23a +.section sd23b +.section sd24a +.section sd24b +.section sd25a +.section sd25b +.section sd26a +.section sd26b +.section sd27a +.section sd27b +.section sd28a +.section sd28b +.section sd29a +.section sd29b +.section sd20a +.section sd20b +.section sd3aa +.section sd3ab +.section sd3ba +.section sd3bb +.section sd3ca +.section sd3cb +.section sd3da +.section sd3db +.section sd3ea +.section sd3eb +.section sd3fa +.section sd3fb +.section sd3ga +.section sd3gb +.section sd3ha +.section sd3hb +.section sd3ia +.section sd3ib +.section sd3ja +.section sd3jb +.section sd3ka +.section sd3kb +.section sd3la +.section sd3lb +.section sd3ma +.section sd3mb +.section sd3na +.section sd3nb +.section sd3oa +.section sd3ob +.section sd3pa +.section sd3pb +.section sd3qa +.section sd3qb +.section sd3ra +.section sd3rb +.section sd3sa +.section sd3sb +.section sd3ta +.section sd3tb +.section sd3ua +.section sd3ub +.section sd3va +.section sd3vb +.section sd3wa +.section sd3wb +.section sd3xa +.section sd3xb +.section sd3ya +.section sd3yb +.section sd3za +.section sd3zb +.section sd31a +.section sd31b +.section sd32a +.section sd32b +.section sd33a +.section sd33b +.section sd34a +.section sd34b +.section sd35a +.section sd35b +.section sd36a +.section sd36b +.section sd37a +.section sd37b +.section sd38a +.section sd38b +.section sd39a +.section sd39b +.section sd30a +.section sd30b +.section sd4aa +.section sd4ab +.section sd4ba +.section sd4bb +.section sd4ca +.section sd4cb +.section sd4da +.section sd4db +.section sd4ea +.section sd4eb +.section sd4fa +.section sd4fb +.section sd4ga +.section sd4gb +.section sd4ha +.section sd4hb +.section sd4ia +.section sd4ib +.section sd4ja +.section sd4jb +.section sd4ka +.section sd4kb +.section sd4la +.section sd4lb +.section sd4ma +.section sd4mb +.section sd4na +.section sd4nb +.section sd4oa +.section sd4ob +.section sd4pa +.section sd4pb +.section sd4qa +.section sd4qb +.section sd4ra +.section sd4rb +.section sd4sa +.section sd4sb +.section sd4ta +.section sd4tb +.section sd4ua +.section sd4ub +.section sd4va +.section sd4vb +.section sd4wa +.section sd4wb +.section sd4xa +.section sd4xb +.section sd4ya +.section sd4yb +.section sd4za +.section sd4zb +.section sd41a +.section sd41b +.section sd42a +.section sd42b +.section sd43a +.section sd43b +.section sd44a +.section sd44b +.section sd45a +.section sd45b +.section sd46a +.section sd46b +.section sd47a +.section sd47b +.section sd48a +.section sd48b +.section sd49a +.section sd49b +.section sd40a +.section sd40b +.section sd5aa +.section sd5ab +.section sd5ba +.section sd5bb +.section sd5ca +.section sd5cb +.section sd5da +.section sd5db +.section sd5ea +.section sd5eb +.section sd5fa +.section sd5fb +.section sd5ga +.section sd5gb +.section sd5ha +.section sd5hb +.section sd5ia +.section sd5ib +.section sd5ja +.section sd5jb +.section sd5ka +.section sd5kb +.section sd5la +.section sd5lb +.section sd5ma +.section sd5mb +.section sd5na +.section sd5nb +.section sd5oa +.section sd5ob +.section sd5pa +.section sd5pb +.section sd5qa +.section sd5qb +.section sd5ra +.section sd5rb +.section sd5sa +.section sd5sb +.section sd5ta +.section sd5tb +.section sd5ua +.section sd5ub +.section sd5va +.section sd5vb +.section sd5wa +.section sd5wb +.section sd5xa +.section sd5xb +.section sd5ya +.section sd5yb +.section sd5za +.section sd5zb +.section sd51a +.section sd51b +.section sd52a +.section sd52b +.section sd53a +.section sd53b +.section sd54a +.section sd54b +.section sd55a +.section sd55b +.section sd56a +.section sd56b +.section sd57a +.section sd57b +.section sd58a +.section sd58b +.section sd59a +.section sd59b +.section sd50a +.section sd50b +.section sd6aa +.section sd6ab +.section sd6ba +.section sd6bb +.section sd6ca +.section sd6cb +.section sd6da +.section sd6db +.section sd6ea +.section sd6eb +.section sd6fa +.section sd6fb +.section sd6ga +.section sd6gb +.section sd6ha +.section sd6hb +.section sd6ia +.section sd6ib +.section sd6ja +.section sd6jb +.section sd6ka +.section sd6kb +.section sd6la +.section sd6lb +.section sd6ma +.section sd6mb +.section sd6na +.section sd6nb +.section sd6oa +.section sd6ob +.section sd6pa +.section sd6pb +.section sd6qa +.section sd6qb +.section sd6ra +.section sd6rb +.section sd6sa +.section sd6sb +.section sd6ta +.section sd6tb +.section sd6ua +.section sd6ub +.section sd6va +.section sd6vb +.section sd6wa +.section sd6wb +.section sd6xa +.section sd6xb +.section sd6ya +.section sd6yb +.section sd6za +.section sd6zb +.section sd61a +.section sd61b +.section sd62a +.section sd62b +.section sd63a +.section sd63b +.section sd64a +.section sd64b +.section sd65a +.section sd65b +.section sd66a +.section sd66b +.section sd67a +.section sd67b +.section sd68a +.section sd68b +.section sd69a +.section sd69b +.section sd60a +.section sd60b +.section sd7aa +.section sd7ab +.section sd7ba +.section sd7bb +.section sd7ca +.section sd7cb +.section sd7da +.section sd7db +.section sd7ea +.section sd7eb +.section sd7fa +.section sd7fb +.section sd7ga +.section sd7gb +.section sd7ha +.section sd7hb +.section sd7ia +.section sd7ib +.section sd7ja +.section sd7jb +.section sd7ka +.section sd7kb +.section sd7la +.section sd7lb +.section sd7ma +.section sd7mb +.section sd7na +.section sd7nb +.section sd7oa +.section sd7ob +.section sd7pa +.section sd7pb +.section sd7qa +.section sd7qb +.section sd7ra +.section sd7rb +.section sd7sa +.section sd7sb +.section sd7ta +.section sd7tb +.section sd7ua +.section sd7ub +.section sd7va +.section sd7vb +.section sd7wa +.section sd7wb +.section sd7xa +.section sd7xb +.section sd7ya +.section sd7yb +.section sd7za +.section sd7zb +.section sd71a +.section sd71b +.section sd72a +.section sd72b +.section sd73a +.section sd73b +.section sd74a +.section sd74b +.section sd75a +.section sd75b +.section sd76a +.section sd76b +.section sd77a +.section sd77b +.section sd78a +.section sd78b +.section sd79a +.section sd79b +.section sd70a +.section sd70b +.section sd8aa +.section sd8ab +.section sd8ba +.section sd8bb +.section sd8ca +.section sd8cb +.section sd8da +.section sd8db +.section sd8ea +.section sd8eb +.section sd8fa +.section sd8fb +.section sd8ga +.section sd8gb +.section sd8ha +.section sd8hb +.section sd8ia +.section sd8ib +.section sd8ja +.section sd8jb +.section sd8ka +.section sd8kb +.section sd8la +.section sd8lb +.section sd8ma +.section sd8mb +.section sd8na +.section sd8nb +.section sd8oa +.section sd8ob +.section sd8pa +.section sd8pb +.section sd8qa +.section sd8qb +.section sd8ra +.section sd8rb +.section sd8sa +.section sd8sb +.section sd8ta +.section sd8tb +.section sd8ua +.section sd8ub +.section sd8va +.section sd8vb +.section sd8wa +.section sd8wb +.section sd8xa +.section sd8xb +.section sd8ya +.section sd8yb +.section sd8za +.section sd8zb +.section sd81a +.section sd81b +.section sd82a +.section sd82b +.section sd83a +.section sd83b +.section sd84a +.section sd84b +.section sd85a +.section sd85b +.section sd86a +.section sd86b +.section sd87a +.section sd87b +.section sd88a +.section sd88b +.section sd89a +.section sd89b +.section sd80a +.section sd80b +.section sd9aa +.section sd9ab +.section sd9ba +.section sd9bb +.section sd9ca +.section sd9cb +.section sd9da +.section sd9db +.section sd9ea +.section sd9eb +.section sd9fa +.section sd9fb +.section sd9ga +.section sd9gb +.section sd9ha +.section sd9hb +.section sd9ia +.section sd9ib +.section sd9ja +.section sd9jb +.section sd9ka +.section sd9kb +.section sd9la +.section sd9lb +.section sd9ma +.section sd9mb +.section sd9na +.section sd9nb +.section sd9oa +.section sd9ob +.section sd9pa +.section sd9pb +.section sd9qa +.section sd9qb +.section sd9ra +.section sd9rb +.section sd9sa +.section sd9sb +.section sd9ta +.section sd9tb +.section sd9ua +.section sd9ub +.section sd9va +.section sd9vb +.section sd9wa +.section sd9wb +.section sd9xa +.section sd9xb +.section sd9ya +.section sd9yb +.section sd9za +.section sd9zb +.section sd91a +.section sd91b +.section sd92a +.section sd92b +.section sd93a +.section sd93b +.section sd94a +.section sd94b +.section sd95a +.section sd95b +.section sd96a +.section sd96b +.section sd97a +.section sd97b +.section sd98a +.section sd98b +.section sd99a +.section sd99b +.section sd90a +.section sd90b +.section sd0aa +.section sd0ab +.section sd0ba +.section sd0bb +.section sd0ca +.section sd0cb +.section sd0da +.section sd0db +.section sd0ea +.section sd0eb +.section sd0fa +.section sd0fb +.section sd0ga +.section sd0gb +.section sd0ha +.section sd0hb +.section sd0ia +.section sd0ib +.section sd0ja +.section sd0jb +.section sd0ka +.section sd0kb +.section sd0la +.section sd0lb +.section sd0ma +.section sd0mb +.section sd0na +.section sd0nb +.section sd0oa +.section sd0ob +.section sd0pa +.section sd0pb +.section sd0qa +.section sd0qb +.section sd0ra +.section sd0rb +.section sd0sa +.section sd0sb +.section sd0ta +.section sd0tb +.section sd0ua +.section sd0ub +.section sd0va +.section sd0vb +.section sd0wa +.section sd0wb +.section sd0xa +.section sd0xb +.section sd0ya +.section sd0yb +.section sd0za +.section sd0zb +.section sd01a +.section sd01b +.section sd02a +.section sd02b +.section sd03a +.section sd03b +.section sd04a +.section sd04b +.section sd05a +.section sd05b +.section sd06a +.section sd06b +.section sd07a +.section sd07b +.section sd08a +.section sd08b +.section sd09a +.section sd09b +.section sd00a +.section sd00b +.section seaaa +.section seaab +.section seaba +.section seabb +.section seaca +.section seacb +.section seada +.section seadb +.section seaea +.section seaeb +.section seafa +.section seafb +.section seaga +.section seagb +.section seaha +.section seahb +.section seaia +.section seaib +.section seaja +.section seajb +.section seaka +.section seakb +.section seala +.section sealb +.section seama +.section seamb +.section seana +.section seanb +.section seaoa +.section seaob +.section seapa +.section seapb +.section seaqa +.section seaqb +.section seara +.section searb +.section seasa +.section seasb +.section seata +.section seatb +.section seaua +.section seaub +.section seava +.section seavb +.section seawa +.section seawb +.section seaxa +.section seaxb +.section seaya +.section seayb +.section seaza +.section seazb +.section sea1a +.section sea1b +.section sea2a +.section sea2b +.section sea3a +.section sea3b +.section sea4a +.section sea4b +.section sea5a +.section sea5b +.section sea6a +.section sea6b +.section sea7a +.section sea7b +.section sea8a +.section sea8b +.section sea9a +.section sea9b +.section sea0a +.section sea0b +.section sebaa +.section sebab +.section sebba +.section sebbb +.section sebca +.section sebcb +.section sebda +.section sebdb +.section sebea +.section sebeb +.section sebfa +.section sebfb +.section sebga +.section sebgb +.section sebha +.section sebhb +.section sebia +.section sebib +.section sebja +.section sebjb +.section sebka +.section sebkb +.section sebla +.section seblb +.section sebma +.section sebmb +.section sebna +.section sebnb +.section seboa +.section sebob +.section sebpa +.section sebpb +.section sebqa +.section sebqb +.section sebra +.section sebrb +.section sebsa +.section sebsb +.section sebta +.section sebtb +.section sebua +.section sebub +.section sebva +.section sebvb +.section sebwa +.section sebwb +.section sebxa +.section sebxb +.section sebya +.section sebyb +.section sebza +.section sebzb +.section seb1a +.section seb1b +.section seb2a +.section seb2b +.section seb3a +.section seb3b +.section seb4a +.section seb4b +.section seb5a +.section seb5b +.section seb6a +.section seb6b +.section seb7a +.section seb7b +.section seb8a +.section seb8b +.section seb9a +.section seb9b +.section seb0a +.section seb0b +.section secaa +.section secab +.section secba +.section secbb +.section secca +.section seccb +.section secda +.section secdb +.section secea +.section seceb +.section secfa +.section secfb +.section secga +.section secgb +.section secha +.section sechb +.section secia +.section secib +.section secja +.section secjb +.section secka +.section seckb +.section secla +.section seclb +.section secma +.section secmb +.section secna +.section secnb +.section secoa +.section secob +.section secpa +.section secpb +.section secqa +.section secqb +.section secra +.section secrb +.section secsa +.section secsb +.section secta +.section sectb +.section secua +.section secub +.section secva +.section secvb +.section secwa +.section secwb +.section secxa +.section secxb +.section secya +.section secyb +.section secza +.section seczb +.section sec1a +.section sec1b +.section sec2a +.section sec2b +.section sec3a +.section sec3b +.section sec4a +.section sec4b +.section sec5a +.section sec5b +.section sec6a +.section sec6b +.section sec7a +.section sec7b +.section sec8a +.section sec8b +.section sec9a +.section sec9b +.section sec0a +.section sec0b +.section sedaa +.section sedab +.section sedba +.section sedbb +.section sedca +.section sedcb +.section sedda +.section seddb +.section sedea +.section sedeb +.section sedfa +.section sedfb +.section sedga +.section sedgb +.section sedha +.section sedhb +.section sedia +.section sedib +.section sedja +.section sedjb +.section sedka +.section sedkb +.section sedla +.section sedlb +.section sedma +.section sedmb +.section sedna +.section sednb +.section sedoa +.section sedob +.section sedpa +.section sedpb +.section sedqa +.section sedqb +.section sedra +.section sedrb +.section sedsa +.section sedsb +.section sedta +.section sedtb +.section sedua +.section sedub +.section sedva +.section sedvb +.section sedwa +.section sedwb +.section sedxa +.section sedxb +.section sedya +.section sedyb +.section sedza +.section sedzb +.section sed1a +.section sed1b +.section sed2a +.section sed2b +.section sed3a +.section sed3b +.section sed4a +.section sed4b +.section sed5a +.section sed5b +.section sed6a +.section sed6b +.section sed7a +.section sed7b +.section sed8a +.section sed8b +.section sed9a +.section sed9b +.section sed0a +.section sed0b +.section seeaa +.section seeab +.section seeba +.section seebb +.section seeca +.section seecb +.section seeda +.section seedb +.section seeea +.section seeeb +.section seefa +.section seefb +.section seega +.section seegb +.section seeha +.section seehb +.section seeia +.section seeib +.section seeja +.section seejb +.section seeka +.section seekb +.section seela +.section seelb +.section seema +.section seemb +.section seena +.section seenb +.section seeoa +.section seeob +.section seepa +.section seepb +.section seeqa +.section seeqb +.section seera +.section seerb +.section seesa +.section seesb +.section seeta +.section seetb +.section seeua +.section seeub +.section seeva +.section seevb +.section seewa +.section seewb +.section seexa +.section seexb +.section seeya +.section seeyb +.section seeza +.section seezb +.section see1a +.section see1b +.section see2a +.section see2b +.section see3a +.section see3b +.section see4a +.section see4b +.section see5a +.section see5b +.section see6a +.section see6b +.section see7a +.section see7b +.section see8a +.section see8b +.section see9a +.section see9b +.section see0a +.section see0b +.section sefaa +.section sefab +.section sefba +.section sefbb +.section sefca +.section sefcb +.section sefda +.section sefdb +.section sefea +.section sefeb +.section seffa +.section seffb +.section sefga +.section sefgb +.section sefha +.section sefhb +.section sefia +.section sefib +.section sefja +.section sefjb +.section sefka +.section sefkb +.section sefla +.section seflb +.section sefma +.section sefmb +.section sefna +.section sefnb +.section sefoa +.section sefob +.section sefpa +.section sefpb +.section sefqa +.section sefqb +.section sefra +.section sefrb +.section sefsa +.section sefsb +.section sefta +.section seftb +.section sefua +.section sefub +.section sefva +.section sefvb +.section sefwa +.section sefwb +.section sefxa +.section sefxb +.section sefya +.section sefyb +.section sefza +.section sefzb +.section sef1a +.section sef1b +.section sef2a +.section sef2b +.section sef3a +.section sef3b +.section sef4a +.section sef4b +.section sef5a +.section sef5b +.section sef6a +.section sef6b +.section sef7a +.section sef7b +.section sef8a +.section sef8b +.section sef9a +.section sef9b +.section sef0a +.section sef0b +.section segaa +.section segab +.section segba +.section segbb +.section segca +.section segcb +.section segda +.section segdb +.section segea +.section segeb +.section segfa +.section segfb +.section segga +.section seggb +.section segha +.section seghb +.section segia +.section segib +.section segja +.section segjb +.section segka +.section segkb +.section segla +.section seglb +.section segma +.section segmb +.section segna +.section segnb +.section segoa +.section segob +.section segpa +.section segpb +.section segqa +.section segqb +.section segra +.section segrb +.section segsa +.section segsb +.section segta +.section segtb +.section segua +.section segub +.section segva +.section segvb +.section segwa +.section segwb +.section segxa +.section segxb +.section segya +.section segyb +.section segza +.section segzb +.section seg1a +.section seg1b +.section seg2a +.section seg2b +.section seg3a +.section seg3b +.section seg4a +.section seg4b +.section seg5a +.section seg5b +.section seg6a +.section seg6b +.section seg7a +.section seg7b +.section seg8a +.section seg8b +.section seg9a +.section seg9b +.section seg0a +.section seg0b +.section sehaa +.section sehab +.section sehba +.section sehbb +.section sehca +.section sehcb +.section sehda +.section sehdb +.section sehea +.section seheb +.section sehfa +.section sehfb +.section sehga +.section sehgb +.section sehha +.section sehhb +.section sehia +.section sehib +.section sehja +.section sehjb +.section sehka +.section sehkb +.section sehla +.section sehlb +.section sehma +.section sehmb +.section sehna +.section sehnb +.section sehoa +.section sehob +.section sehpa +.section sehpb +.section sehqa +.section sehqb +.section sehra +.section sehrb +.section sehsa +.section sehsb +.section sehta +.section sehtb +.section sehua +.section sehub +.section sehva +.section sehvb +.section sehwa +.section sehwb +.section sehxa +.section sehxb +.section sehya +.section sehyb +.section sehza +.section sehzb +.section seh1a +.section seh1b +.section seh2a +.section seh2b +.section seh3a +.section seh3b +.section seh4a +.section seh4b +.section seh5a +.section seh5b +.section seh6a +.section seh6b +.section seh7a +.section seh7b +.section seh8a +.section seh8b +.section seh9a +.section seh9b +.section seh0a +.section seh0b +.section seiaa +.section seiab +.section seiba +.section seibb +.section seica +.section seicb +.section seida +.section seidb +.section seiea +.section seieb +.section seifa +.section seifb +.section seiga +.section seigb +.section seiha +.section seihb +.section seiia +.section seiib +.section seija +.section seijb +.section seika +.section seikb +.section seila +.section seilb +.section seima +.section seimb +.section seina +.section seinb +.section seioa +.section seiob +.section seipa +.section seipb +.section seiqa +.section seiqb +.section seira +.section seirb +.section seisa +.section seisb +.section seita +.section seitb +.section seiua +.section seiub +.section seiva +.section seivb +.section seiwa +.section seiwb +.section seixa +.section seixb +.section seiya +.section seiyb +.section seiza +.section seizb +.section sei1a +.section sei1b +.section sei2a +.section sei2b +.section sei3a +.section sei3b +.section sei4a +.section sei4b +.section sei5a +.section sei5b +.section sei6a +.section sei6b +.section sei7a +.section sei7b +.section sei8a +.section sei8b +.section sei9a +.section sei9b +.section sei0a +.section sei0b +.section sejaa +.section sejab +.section sejba +.section sejbb +.section sejca +.section sejcb +.section sejda +.section sejdb +.section sejea +.section sejeb +.section sejfa +.section sejfb +.section sejga +.section sejgb +.section sejha +.section sejhb +.section sejia +.section sejib +.section sejja +.section sejjb +.section sejka +.section sejkb +.section sejla +.section sejlb +.section sejma +.section sejmb +.section sejna +.section sejnb +.section sejoa +.section sejob +.section sejpa +.section sejpb +.section sejqa +.section sejqb +.section sejra +.section sejrb +.section sejsa +.section sejsb +.section sejta +.section sejtb +.section sejua +.section sejub +.section sejva +.section sejvb +.section sejwa +.section sejwb +.section sejxa +.section sejxb +.section sejya +.section sejyb +.section sejza +.section sejzb +.section sej1a +.section sej1b +.section sej2a +.section sej2b +.section sej3a +.section sej3b +.section sej4a +.section sej4b +.section sej5a +.section sej5b +.section sej6a +.section sej6b +.section sej7a +.section sej7b +.section sej8a +.section sej8b +.section sej9a +.section sej9b +.section sej0a +.section sej0b +.section sekaa +.section sekab +.section sekba +.section sekbb +.section sekca +.section sekcb +.section sekda +.section sekdb +.section sekea +.section sekeb +.section sekfa +.section sekfb +.section sekga +.section sekgb +.section sekha +.section sekhb +.section sekia +.section sekib +.section sekja +.section sekjb +.section sekka +.section sekkb +.section sekla +.section seklb +.section sekma +.section sekmb +.section sekna +.section seknb +.section sekoa +.section sekob +.section sekpa +.section sekpb +.section sekqa +.section sekqb +.section sekra +.section sekrb +.section seksa +.section seksb +.section sekta +.section sektb +.section sekua +.section sekub +.section sekva +.section sekvb +.section sekwa +.section sekwb +.section sekxa +.section sekxb +.section sekya +.section sekyb +.section sekza +.section sekzb +.section sek1a +.section sek1b +.section sek2a +.section sek2b +.section sek3a +.section sek3b +.section sek4a +.section sek4b +.section sek5a +.section sek5b +.section sek6a +.section sek6b +.section sek7a +.section sek7b +.section sek8a +.section sek8b +.section sek9a +.section sek9b +.section sek0a +.section sek0b +.section selaa +.section selab +.section selba +.section selbb +.section selca +.section selcb +.section selda +.section seldb +.section selea +.section seleb +.section selfa +.section selfb +.section selga +.section selgb +.section selha +.section selhb +.section selia +.section selib +.section selja +.section seljb +.section selka +.section selkb +.section sella +.section sellb +.section selma +.section selmb +.section selna +.section selnb +.section seloa +.section selob +.section selpa +.section selpb +.section selqa +.section selqb +.section selra +.section selrb +.section selsa +.section selsb +.section selta +.section seltb +.section selua +.section selub +.section selva +.section selvb +.section selwa +.section selwb +.section selxa +.section selxb +.section selya +.section selyb +.section selza +.section selzb +.section sel1a +.section sel1b +.section sel2a +.section sel2b +.section sel3a +.section sel3b +.section sel4a +.section sel4b +.section sel5a +.section sel5b +.section sel6a +.section sel6b +.section sel7a +.section sel7b +.section sel8a +.section sel8b +.section sel9a +.section sel9b +.section sel0a +.section sel0b +.section semaa +.section semab +.section semba +.section sembb +.section semca +.section semcb +.section semda +.section semdb +.section semea +.section semeb +.section semfa +.section semfb +.section semga +.section semgb +.section semha +.section semhb +.section semia +.section semib +.section semja +.section semjb +.section semka +.section semkb +.section semla +.section semlb +.section semma +.section semmb +.section semna +.section semnb +.section semoa +.section semob +.section sempa +.section sempb +.section semqa +.section semqb +.section semra +.section semrb +.section semsa +.section semsb +.section semta +.section semtb +.section semua +.section semub +.section semva +.section semvb +.section semwa +.section semwb +.section semxa +.section semxb +.section semya +.section semyb +.section semza +.section semzb +.section sem1a +.section sem1b +.section sem2a +.section sem2b +.section sem3a +.section sem3b +.section sem4a +.section sem4b +.section sem5a +.section sem5b +.section sem6a +.section sem6b +.section sem7a +.section sem7b +.section sem8a +.section sem8b +.section sem9a +.section sem9b +.section sem0a +.section sem0b +.section senaa +.section senab +.section senba +.section senbb +.section senca +.section sencb +.section senda +.section sendb +.section senea +.section seneb +.section senfa +.section senfb +.section senga +.section sengb +.section senha +.section senhb +.section senia +.section senib +.section senja +.section senjb +.section senka +.section senkb +.section senla +.section senlb +.section senma +.section senmb +.section senna +.section sennb +.section senoa +.section senob +.section senpa +.section senpb +.section senqa +.section senqb +.section senra +.section senrb +.section sensa +.section sensb +.section senta +.section sentb +.section senua +.section senub +.section senva +.section senvb +.section senwa +.section senwb +.section senxa +.section senxb +.section senya +.section senyb +.section senza +.section senzb +.section sen1a +.section sen1b +.section sen2a +.section sen2b +.section sen3a +.section sen3b +.section sen4a +.section sen4b +.section sen5a +.section sen5b +.section sen6a +.section sen6b +.section sen7a +.section sen7b +.section sen8a +.section sen8b +.section sen9a +.section sen9b +.section sen0a +.section sen0b +.section seoaa +.section seoab +.section seoba +.section seobb +.section seoca +.section seocb +.section seoda +.section seodb +.section seoea +.section seoeb +.section seofa +.section seofb +.section seoga +.section seogb +.section seoha +.section seohb +.section seoia +.section seoib +.section seoja +.section seojb +.section seoka +.section seokb +.section seola +.section seolb +.section seoma +.section seomb +.section seona +.section seonb +.section seooa +.section seoob +.section seopa +.section seopb +.section seoqa +.section seoqb +.section seora +.section seorb +.section seosa +.section seosb +.section seota +.section seotb +.section seoua +.section seoub +.section seova +.section seovb +.section seowa +.section seowb +.section seoxa +.section seoxb +.section seoya +.section seoyb +.section seoza +.section seozb +.section seo1a +.section seo1b +.section seo2a +.section seo2b +.section seo3a +.section seo3b +.section seo4a +.section seo4b +.section seo5a +.section seo5b +.section seo6a +.section seo6b +.section seo7a +.section seo7b +.section seo8a +.section seo8b +.section seo9a +.section seo9b +.section seo0a +.section seo0b +.section sepaa +.section sepab +.section sepba +.section sepbb +.section sepca +.section sepcb +.section sepda +.section sepdb +.section sepea +.section sepeb +.section sepfa +.section sepfb +.section sepga +.section sepgb +.section sepha +.section sephb +.section sepia +.section sepib +.section sepja +.section sepjb +.section sepka +.section sepkb +.section sepla +.section seplb +.section sepma +.section sepmb +.section sepna +.section sepnb +.section sepoa +.section sepob +.section seppa +.section seppb +.section sepqa +.section sepqb +.section sepra +.section seprb +.section sepsa +.section sepsb +.section septa +.section septb +.section sepua +.section sepub +.section sepva +.section sepvb +.section sepwa +.section sepwb +.section sepxa +.section sepxb +.section sepya +.section sepyb +.section sepza +.section sepzb +.section sep1a +.section sep1b +.section sep2a +.section sep2b +.section sep3a +.section sep3b +.section sep4a +.section sep4b +.section sep5a +.section sep5b +.section sep6a +.section sep6b +.section sep7a +.section sep7b +.section sep8a +.section sep8b +.section sep9a +.section sep9b +.section sep0a +.section sep0b +.section seqaa +.section seqab +.section seqba +.section seqbb +.section seqca +.section seqcb +.section seqda +.section seqdb +.section seqea +.section seqeb +.section seqfa +.section seqfb +.section seqga +.section seqgb +.section seqha +.section seqhb +.section seqia +.section seqib +.section seqja +.section seqjb +.section seqka +.section seqkb +.section seqla +.section seqlb +.section seqma +.section seqmb +.section seqna +.section seqnb +.section seqoa +.section seqob +.section seqpa +.section seqpb +.section seqqa +.section seqqb +.section seqra +.section seqrb +.section seqsa +.section seqsb +.section seqta +.section seqtb +.section sequa +.section sequb +.section seqva +.section seqvb +.section seqwa +.section seqwb +.section seqxa +.section seqxb +.section seqya +.section seqyb +.section seqza +.section seqzb +.section seq1a +.section seq1b +.section seq2a +.section seq2b +.section seq3a +.section seq3b +.section seq4a +.section seq4b +.section seq5a +.section seq5b +.section seq6a +.section seq6b +.section seq7a +.section seq7b +.section seq8a +.section seq8b +.section seq9a +.section seq9b +.section seq0a +.section seq0b +.section seraa +.section serab +.section serba +.section serbb +.section serca +.section sercb +.section serda +.section serdb +.section serea +.section sereb +.section serfa +.section serfb +.section serga +.section sergb +.section serha +.section serhb +.section seria +.section serib +.section serja +.section serjb +.section serka +.section serkb +.section serla +.section serlb +.section serma +.section sermb +.section serna +.section sernb +.section seroa +.section serob +.section serpa +.section serpb +.section serqa +.section serqb +.section serra +.section serrb +.section sersa +.section sersb +.section serta +.section sertb +.section serua +.section serub +.section serva +.section servb +.section serwa +.section serwb +.section serxa +.section serxb +.section serya +.section seryb +.section serza +.section serzb +.section ser1a +.section ser1b +.section ser2a +.section ser2b +.section ser3a +.section ser3b +.section ser4a +.section ser4b +.section ser5a +.section ser5b +.section ser6a +.section ser6b +.section ser7a +.section ser7b +.section ser8a +.section ser8b +.section ser9a +.section ser9b +.section ser0a +.section ser0b +.section sesaa +.section sesab +.section sesba +.section sesbb +.section sesca +.section sescb +.section sesda +.section sesdb +.section sesea +.section seseb +.section sesfa +.section sesfb +.section sesga +.section sesgb +.section sesha +.section seshb +.section sesia +.section sesib +.section sesja +.section sesjb +.section seska +.section seskb +.section sesla +.section seslb +.section sesma +.section sesmb +.section sesna +.section sesnb +.section sesoa +.section sesob +.section sespa +.section sespb +.section sesqa +.section sesqb +.section sesra +.section sesrb +.section sessa +.section sessb +.section sesta +.section sestb +.section sesua +.section sesub +.section sesva +.section sesvb +.section seswa +.section seswb +.section sesxa +.section sesxb +.section sesya +.section sesyb +.section sesza +.section seszb +.section ses1a +.section ses1b +.section ses2a +.section ses2b +.section ses3a +.section ses3b +.section ses4a +.section ses4b +.section ses5a +.section ses5b +.section ses6a +.section ses6b +.section ses7a +.section ses7b +.section ses8a +.section ses8b +.section ses9a +.section ses9b +.section ses0a +.section ses0b +.section setaa +.section setab +.section setba +.section setbb +.section setca +.section setcb +.section setda +.section setdb +.section setea +.section seteb +.section setfa +.section setfb +.section setga +.section setgb +.section setha +.section sethb +.section setia +.section setib +.section setja +.section setjb +.section setka +.section setkb +.section setla +.section setlb +.section setma +.section setmb +.section setna +.section setnb +.section setoa +.section setob +.section setpa +.section setpb +.section setqa +.section setqb +.section setra +.section setrb +.section setsa +.section setsb +.section setta +.section settb +.section setua +.section setub +.section setva +.section setvb +.section setwa +.section setwb +.section setxa +.section setxb +.section setya +.section setyb +.section setza +.section setzb +.section set1a +.section set1b +.section set2a +.section set2b +.section set3a +.section set3b +.section set4a +.section set4b +.section set5a +.section set5b +.section set6a +.section set6b +.section set7a +.section set7b +.section set8a +.section set8b +.section set9a +.section set9b +.section set0a +.section set0b +.section seuaa +.section seuab +.section seuba +.section seubb +.section seuca +.section seucb +.section seuda +.section seudb +.section seuea +.section seueb +.section seufa +.section seufb +.section seuga +.section seugb +.section seuha +.section seuhb +.section seuia +.section seuib +.section seuja +.section seujb +.section seuka +.section seukb +.section seula +.section seulb +.section seuma +.section seumb +.section seuna +.section seunb +.section seuoa +.section seuob +.section seupa +.section seupb +.section seuqa +.section seuqb +.section seura +.section seurb +.section seusa +.section seusb +.section seuta +.section seutb +.section seuua +.section seuub +.section seuva +.section seuvb +.section seuwa +.section seuwb +.section seuxa +.section seuxb +.section seuya +.section seuyb +.section seuza +.section seuzb +.section seu1a +.section seu1b +.section seu2a +.section seu2b +.section seu3a +.section seu3b +.section seu4a +.section seu4b +.section seu5a +.section seu5b +.section seu6a +.section seu6b +.section seu7a +.section seu7b +.section seu8a +.section seu8b +.section seu9a +.section seu9b +.section seu0a +.section seu0b +.section sevaa +.section sevab +.section sevba +.section sevbb +.section sevca +.section sevcb +.section sevda +.section sevdb +.section sevea +.section seveb +.section sevfa +.section sevfb +.section sevga +.section sevgb +.section sevha +.section sevhb +.section sevia +.section sevib +.section sevja +.section sevjb +.section sevka +.section sevkb +.section sevla +.section sevlb +.section sevma +.section sevmb +.section sevna +.section sevnb +.section sevoa +.section sevob +.section sevpa +.section sevpb +.section sevqa +.section sevqb +.section sevra +.section sevrb +.section sevsa +.section sevsb +.section sevta +.section sevtb +.section sevua +.section sevub +.section sevva +.section sevvb +.section sevwa +.section sevwb +.section sevxa +.section sevxb +.section sevya +.section sevyb +.section sevza +.section sevzb +.section sev1a +.section sev1b +.section sev2a +.section sev2b +.section sev3a +.section sev3b +.section sev4a +.section sev4b +.section sev5a +.section sev5b +.section sev6a +.section sev6b +.section sev7a +.section sev7b +.section sev8a +.section sev8b +.section sev9a +.section sev9b +.section sev0a +.section sev0b +.section sewaa +.section sewab +.section sewba +.section sewbb +.section sewca +.section sewcb +.section sewda +.section sewdb +.section sewea +.section seweb +.section sewfa +.section sewfb +.section sewga +.section sewgb +.section sewha +.section sewhb +.section sewia +.section sewib +.section sewja +.section sewjb +.section sewka +.section sewkb +.section sewla +.section sewlb +.section sewma +.section sewmb +.section sewna +.section sewnb +.section sewoa +.section sewob +.section sewpa +.section sewpb +.section sewqa +.section sewqb +.section sewra +.section sewrb +.section sewsa +.section sewsb +.section sewta +.section sewtb +.section sewua +.section sewub +.section sewva +.section sewvb +.section sewwa +.section sewwb +.section sewxa +.section sewxb +.section sewya +.section sewyb +.section sewza +.section sewzb +.section sew1a +.section sew1b +.section sew2a +.section sew2b +.section sew3a +.section sew3b +.section sew4a +.section sew4b +.section sew5a +.section sew5b +.section sew6a +.section sew6b +.section sew7a +.section sew7b +.section sew8a +.section sew8b +.section sew9a +.section sew9b +.section sew0a +.section sew0b +.section sexaa +.section sexab +.section sexba +.section sexbb +.section sexca +.section sexcb +.section sexda +.section sexdb +.section sexea +.section sexeb +.section sexfa +.section sexfb +.section sexga +.section sexgb +.section sexha +.section sexhb +.section sexia +.section sexib +.section sexja +.section sexjb +.section sexka +.section sexkb +.section sexla +.section sexlb +.section sexma +.section sexmb +.section sexna +.section sexnb +.section sexoa +.section sexob +.section sexpa +.section sexpb +.section sexqa +.section sexqb +.section sexra +.section sexrb +.section sexsa +.section sexsb +.section sexta +.section sextb +.section sexua +.section sexub +.section sexva +.section sexvb +.section sexwa +.section sexwb +.section sexxa +.section sexxb +.section sexya +.section sexyb +.section sexza +.section sexzb +.section sex1a +.section sex1b +.section sex2a +.section sex2b +.section sex3a +.section sex3b +.section sex4a +.section sex4b +.section sex5a +.section sex5b +.section sex6a +.section sex6b +.section sex7a +.section sex7b +.section sex8a +.section sex8b +.section sex9a +.section sex9b +.section sex0a +.section sex0b +.section seyaa +.section seyab +.section seyba +.section seybb +.section seyca +.section seycb +.section seyda +.section seydb +.section seyea +.section seyeb +.section seyfa +.section seyfb +.section seyga +.section seygb +.section seyha +.section seyhb +.section seyia +.section seyib +.section seyja +.section seyjb +.section seyka +.section seykb +.section seyla +.section seylb +.section seyma +.section seymb +.section seyna +.section seynb +.section seyoa +.section seyob +.section seypa +.section seypb +.section seyqa +.section seyqb +.section seyra +.section seyrb +.section seysa +.section seysb +.section seyta +.section seytb +.section seyua +.section seyub +.section seyva +.section seyvb +.section seywa +.section seywb +.section seyxa +.section seyxb +.section seyya +.section seyyb +.section seyza +.section seyzb +.section sey1a +.section sey1b +.section sey2a +.section sey2b +.section sey3a +.section sey3b +.section sey4a +.section sey4b +.section sey5a +.section sey5b +.section sey6a +.section sey6b +.section sey7a +.section sey7b +.section sey8a +.section sey8b +.section sey9a +.section sey9b +.section sey0a +.section sey0b +.section sezaa +.section sezab +.section sezba +.section sezbb +.section sezca +.section sezcb +.section sezda +.section sezdb +.section sezea +.section sezeb +.section sezfa +.section sezfb +.section sezga +.section sezgb +.section sezha +.section sezhb +.section sezia +.section sezib +.section sezja +.section sezjb +.section sezka +.section sezkb +.section sezla +.section sezlb +.section sezma +.section sezmb +.section sezna +.section seznb +.section sezoa +.section sezob +.section sezpa +.section sezpb +.section sezqa +.section sezqb +.section sezra +.section sezrb +.section sezsa +.section sezsb +.section sezta +.section seztb +.section sezua +.section sezub +.section sezva +.section sezvb +.section sezwa +.section sezwb +.section sezxa +.section sezxb +.section sezya +.section sezyb +.section sezza +.section sezzb +.section sez1a +.section sez1b +.section sez2a +.section sez2b +.section sez3a +.section sez3b +.section sez4a +.section sez4b +.section sez5a +.section sez5b +.section sez6a +.section sez6b +.section sez7a +.section sez7b +.section sez8a +.section sez8b +.section sez9a +.section sez9b +.section sez0a +.section sez0b +.section se1aa +.section se1ab +.section se1ba +.section se1bb +.section se1ca +.section se1cb +.section se1da +.section se1db +.section se1ea +.section se1eb +.section se1fa +.section se1fb +.section se1ga +.section se1gb +.section se1ha +.section se1hb +.section se1ia +.section se1ib +.section se1ja +.section se1jb +.section se1ka +.section se1kb +.section se1la +.section se1lb +.section se1ma +.section se1mb +.section se1na +.section se1nb +.section se1oa +.section se1ob +.section se1pa +.section se1pb +.section se1qa +.section se1qb +.section se1ra +.section se1rb +.section se1sa +.section se1sb +.section se1ta +.section se1tb +.section se1ua +.section se1ub +.section se1va +.section se1vb +.section se1wa +.section se1wb +.section se1xa +.section se1xb +.section se1ya +.section se1yb +.section se1za +.section se1zb +.section se11a +.section se11b +.section se12a +.section se12b +.section se13a +.section se13b +.section se14a +.section se14b +.section se15a +.section se15b +.section se16a +.section se16b +.section se17a +.section se17b +.section se18a +.section se18b +.section se19a +.section se19b +.section se10a +.section se10b +.section se2aa +.section se2ab +.section se2ba +.section se2bb +.section se2ca +.section se2cb +.section se2da +.section se2db +.section se2ea +.section se2eb +.section se2fa +.section se2fb +.section se2ga +.section se2gb +.section se2ha +.section se2hb +.section se2ia +.section se2ib +.section se2ja +.section se2jb +.section se2ka +.section se2kb +.section se2la +.section se2lb +.section se2ma +.section se2mb +.section se2na +.section se2nb +.section se2oa +.section se2ob +.section se2pa +.section se2pb +.section se2qa +.section se2qb +.section se2ra +.section se2rb +.section se2sa +.section se2sb +.section se2ta +.section se2tb +.section se2ua +.section se2ub +.section se2va +.section se2vb +.section se2wa +.section se2wb +.section se2xa +.section se2xb +.section se2ya +.section se2yb +.section se2za +.section se2zb +.section se21a +.section se21b +.section se22a +.section se22b +.section se23a +.section se23b +.section se24a +.section se24b +.section se25a +.section se25b +.section se26a +.section se26b +.section se27a +.section se27b +.section se28a +.section se28b +.section se29a +.section se29b +.section se20a +.section se20b +.section se3aa +.section se3ab +.section se3ba +.section se3bb +.section se3ca +.section se3cb +.section se3da +.section se3db +.section se3ea +.section se3eb +.section se3fa +.section se3fb +.section se3ga +.section se3gb +.section se3ha +.section se3hb +.section se3ia +.section se3ib +.section se3ja +.section se3jb +.section se3ka +.section se3kb +.section se3la +.section se3lb +.section se3ma +.section se3mb +.section se3na +.section se3nb +.section se3oa +.section se3ob +.section se3pa +.section se3pb +.section se3qa +.section se3qb +.section se3ra +.section se3rb +.section se3sa +.section se3sb +.section se3ta +.section se3tb +.section se3ua +.section se3ub +.section se3va +.section se3vb +.section se3wa +.section se3wb +.section se3xa +.section se3xb +.section se3ya +.section se3yb +.section se3za +.section se3zb +.section se31a +.section se31b +.section se32a +.section se32b +.section se33a +.section se33b +.section se34a +.section se34b +.section se35a +.section se35b +.section se36a +.section se36b +.section se37a +.section se37b +.section se38a +.section se38b +.section se39a +.section se39b +.section se30a +.section se30b +.section se4aa +.section se4ab +.section se4ba +.section se4bb +.section se4ca +.section se4cb +.section se4da +.section se4db +.section se4ea +.section se4eb +.section se4fa +.section se4fb +.section se4ga +.section se4gb +.section se4ha +.section se4hb +.section se4ia +.section se4ib +.section se4ja +.section se4jb +.section se4ka +.section se4kb +.section se4la +.section se4lb +.section se4ma +.section se4mb +.section se4na +.section se4nb +.section se4oa +.section se4ob +.section se4pa +.section se4pb +.section se4qa +.section se4qb +.section se4ra +.section se4rb +.section se4sa +.section se4sb +.section se4ta +.section se4tb +.section se4ua +.section se4ub +.section se4va +.section se4vb +.section se4wa +.section se4wb +.section se4xa +.section se4xb +.section se4ya +.section se4yb +.section se4za +.section se4zb +.section se41a +.section se41b +.section se42a +.section se42b +.section se43a +.section se43b +.section se44a +.section se44b +.section se45a +.section se45b +.section se46a +.section se46b +.section se47a +.section se47b +.section se48a +.section se48b +.section se49a +.section se49b +.section se40a +.section se40b +.section se5aa +.section se5ab +.section se5ba +.section se5bb +.section se5ca +.section se5cb +.section se5da +.section se5db +.section se5ea +.section se5eb +.section se5fa +.section se5fb +.section se5ga +.section se5gb +.section se5ha +.section se5hb +.section se5ia +.section se5ib +.section se5ja +.section se5jb +.section se5ka +.section se5kb +.section se5la +.section se5lb +.section se5ma +.section se5mb +.section se5na +.section se5nb +.section se5oa +.section se5ob +.section se5pa +.section se5pb +.section se5qa +.section se5qb +.section se5ra +.section se5rb +.section se5sa +.section se5sb +.section se5ta +.section se5tb +.section se5ua +.section se5ub +.section se5va +.section se5vb +.section se5wa +.section se5wb +.section se5xa +.section se5xb +.section se5ya +.section se5yb +.section se5za +.section se5zb +.section se51a +.section se51b +.section se52a +.section se52b +.section se53a +.section se53b +.section se54a +.section se54b +.section se55a +.section se55b +.section se56a +.section se56b +.section se57a +.section se57b +.section se58a +.section se58b +.section se59a +.section se59b +.section se50a +.section se50b +.section se6aa +.section se6ab +.section se6ba +.section se6bb +.section se6ca +.section se6cb +.section se6da +.section se6db +.section se6ea +.section se6eb +.section se6fa +.section se6fb +.section se6ga +.section se6gb +.section se6ha +.section se6hb +.section se6ia +.section se6ib +.section se6ja +.section se6jb +.section se6ka +.section se6kb +.section se6la +.section se6lb +.section se6ma +.section se6mb +.section se6na +.section se6nb +.section se6oa +.section se6ob +.section se6pa +.section se6pb +.section se6qa +.section se6qb +.section se6ra +.section se6rb +.section se6sa +.section se6sb +.section se6ta +.section se6tb +.section se6ua +.section se6ub +.section se6va +.section se6vb +.section se6wa +.section se6wb +.section se6xa +.section se6xb +.section se6ya +.section se6yb +.section se6za +.section se6zb +.section se61a +.section se61b +.section se62a +.section se62b +.section se63a +.section se63b +.section se64a +.section se64b +.section se65a +.section se65b +.section se66a +.section se66b +.section se67a +.section se67b +.section se68a +.section se68b +.section se69a +.section se69b +.section se60a +.section se60b +.section se7aa +.section se7ab +.section se7ba +.section se7bb +.section se7ca +.section se7cb +.section se7da +.section se7db +.section se7ea +.section se7eb +.section se7fa +.section se7fb +.section se7ga +.section se7gb +.section se7ha +.section se7hb +.section se7ia +.section se7ib +.section se7ja +.section se7jb +.section se7ka +.section se7kb +.section se7la +.section se7lb +.section se7ma +.section se7mb +.section se7na +.section se7nb +.section se7oa +.section se7ob +.section se7pa +.section se7pb +.section se7qa +.section se7qb +.section se7ra +.section se7rb +.section se7sa +.section se7sb +.section se7ta +.section se7tb +.section se7ua +.section se7ub +.section se7va +.section se7vb +.section se7wa +.section se7wb +.section se7xa +.section se7xb +.section se7ya +.section se7yb +.section se7za +.section se7zb +.section se71a +.section se71b +.section se72a +.section se72b +.section se73a +.section se73b +.section se74a +.section se74b +.section se75a +.section se75b +.section se76a +.section se76b +.section se77a +.section se77b +.section se78a +.section se78b +.section se79a +.section se79b +.section se70a +.section se70b +.section se8aa +.section se8ab +.section se8ba +.section se8bb +.section se8ca +.section se8cb +.section se8da +.section se8db +.section se8ea +.section se8eb +.section se8fa +.section se8fb +.section se8ga +.section se8gb +.section se8ha +.section se8hb +.section se8ia +.section se8ib +.section se8ja +.section se8jb +.section se8ka +.section se8kb +.section se8la +.section se8lb +.section se8ma +.section se8mb +.section se8na +.section se8nb +.section se8oa +.section se8ob +.section se8pa +.section se8pb +.section se8qa +.section se8qb +.section se8ra +.section se8rb +.section se8sa +.section se8sb +.section se8ta +.section se8tb +.section se8ua +.section se8ub +.section se8va +.section se8vb +.section se8wa +.section se8wb +.section se8xa +.section se8xb +.section se8ya +.section se8yb +.section se8za +.section se8zb +.section se81a +.section se81b +.section se82a +.section se82b +.section se83a +.section se83b +.section se84a +.section se84b +.section se85a +.section se85b +.section se86a +.section se86b +.section se87a +.section se87b +.section se88a +.section se88b +.section se89a +.section se89b +.section se80a +.section se80b +.section se9aa +.section se9ab +.section se9ba +.section se9bb +.section se9ca +.section se9cb +.section se9da +.section se9db +.section se9ea +.section se9eb +.section se9fa +.section se9fb +.section se9ga +.section se9gb +.section se9ha +.section se9hb +.section se9ia +.section se9ib +.section se9ja +.section se9jb +.section se9ka +.section se9kb +.section se9la +.section se9lb +.section se9ma +.section se9mb +.section se9na +.section se9nb +.section se9oa +.section se9ob +.section se9pa +.section se9pb +.section se9qa +.section se9qb +.section se9ra +.section se9rb +.section se9sa +.section se9sb +.section se9ta +.section se9tb +.section se9ua +.section se9ub +.section se9va +.section se9vb +.section se9wa +.section se9wb +.section se9xa +.section se9xb +.section se9ya +.section se9yb +.section se9za +.section se9zb +.section se91a +.section se91b +.section se92a +.section se92b +.section se93a +.section se93b +.section se94a +.section se94b +.section se95a +.section se95b +.section se96a +.section se96b +.section se97a +.section se97b +.section se98a +.section se98b +.section se99a +.section se99b +.section se90a +.section se90b +.section se0aa +.section se0ab +.section se0ba +.section se0bb +.section se0ca +.section se0cb +.section se0da +.section se0db +.section se0ea +.section se0eb +.section se0fa +.section se0fb +.section se0ga +.section se0gb +.section se0ha +.section se0hb +.section se0ia +.section se0ib +.section se0ja +.section se0jb +.section se0ka +.section se0kb +.section se0la +.section se0lb +.section se0ma +.section se0mb +.section se0na +.section se0nb +.section se0oa +.section se0ob +.section se0pa +.section se0pb +.section se0qa +.section se0qb +.section se0ra +.section se0rb +.section se0sa +.section se0sb +.section se0ta +.section se0tb +.section se0ua +.section se0ub +.section se0va +.section se0vb +.section se0wa +.section se0wb +.section se0xa +.section se0xb +.section se0ya +.section se0yb +.section se0za +.section se0zb +.section se01a +.section se01b +.section se02a +.section se02b +.section se03a +.section se03b +.section se04a +.section se04b +.section se05a +.section se05b +.section se06a +.section se06b +.section se07a +.section se07b +.section se08a +.section se08b +.section se09a +.section se09b +.section se00a +.section se00b +.section sfaaa +.section sfaab +.section sfaba +.section sfabb +.section sfaca +.section sfacb +.section sfada +.section sfadb +.section sfaea +.section sfaeb +.section sfafa +.section sfafb +.section sfaga +.section sfagb +.section sfaha +.section sfahb +.section sfaia +.section sfaib +.section sfaja +.section sfajb +.section sfaka +.section sfakb +.section sfala +.section sfalb +.section sfama +.section sfamb +.section sfana +.section sfanb +.section sfaoa +.section sfaob +.section sfapa +.section sfapb +.section sfaqa +.section sfaqb +.section sfara +.section sfarb +.section sfasa +.section sfasb +.section sfata +.section sfatb +.section sfaua +.section sfaub +.section sfava +.section sfavb +.section sfawa +.section sfawb +.section sfaxa +.section sfaxb +.section sfaya +.section sfayb +.section sfaza +.section sfazb +.section sfa1a +.section sfa1b +.section sfa2a +.section sfa2b +.section sfa3a +.section sfa3b +.section sfa4a +.section sfa4b +.section sfa5a +.section sfa5b +.section sfa6a +.section sfa6b +.section sfa7a +.section sfa7b +.section sfa8a +.section sfa8b +.section sfa9a +.section sfa9b +.section sfa0a +.section sfa0b +.section sfbaa +.section sfbab +.section sfbba +.section sfbbb +.section sfbca +.section sfbcb +.section sfbda +.section sfbdb +.section sfbea +.section sfbeb +.section sfbfa +.section sfbfb +.section sfbga +.section sfbgb +.section sfbha +.section sfbhb +.section sfbia +.section sfbib +.section sfbja +.section sfbjb +.section sfbka +.section sfbkb +.section sfbla +.section sfblb +.section sfbma +.section sfbmb +.section sfbna +.section sfbnb +.section sfboa +.section sfbob +.section sfbpa +.section sfbpb +.section sfbqa +.section sfbqb +.section sfbra +.section sfbrb +.section sfbsa +.section sfbsb +.section sfbta +.section sfbtb +.section sfbua +.section sfbub +.section sfbva +.section sfbvb +.section sfbwa +.section sfbwb +.section sfbxa +.section sfbxb +.section sfbya +.section sfbyb +.section sfbza +.section sfbzb +.section sfb1a +.section sfb1b +.section sfb2a +.section sfb2b +.section sfb3a +.section sfb3b +.section sfb4a +.section sfb4b +.section sfb5a +.section sfb5b +.section sfb6a +.section sfb6b +.section sfb7a +.section sfb7b +.section sfb8a +.section sfb8b +.section sfb9a +.section sfb9b +.section sfb0a +.section sfb0b +.section sfcaa +.section sfcab +.section sfcba +.section sfcbb +.section sfcca +.section sfccb +.section sfcda +.section sfcdb +.section sfcea +.section sfceb +.section sfcfa +.section sfcfb +.section sfcga +.section sfcgb +.section sfcha +.section sfchb +.section sfcia +.section sfcib +.section sfcja +.section sfcjb +.section sfcka +.section sfckb +.section sfcla +.section sfclb +.section sfcma +.section sfcmb +.section sfcna +.section sfcnb +.section sfcoa +.section sfcob +.section sfcpa +.section sfcpb +.section sfcqa +.section sfcqb +.section sfcra +.section sfcrb +.section sfcsa +.section sfcsb +.section sfcta +.section sfctb +.section sfcua +.section sfcub +.section sfcva +.section sfcvb +.section sfcwa +.section sfcwb +.section sfcxa +.section sfcxb +.section sfcya +.section sfcyb +.section sfcza +.section sfczb +.section sfc1a +.section sfc1b +.section sfc2a +.section sfc2b +.section sfc3a +.section sfc3b +.section sfc4a +.section sfc4b +.section sfc5a +.section sfc5b +.section sfc6a +.section sfc6b +.section sfc7a +.section sfc7b +.section sfc8a +.section sfc8b +.section sfc9a +.section sfc9b +.section sfc0a +.section sfc0b +.section sfdaa +.section sfdab +.section sfdba +.section sfdbb +.section sfdca +.section sfdcb +.section sfdda +.section sfddb +.section sfdea +.section sfdeb +.section sfdfa +.section sfdfb +.section sfdga +.section sfdgb +.section sfdha +.section sfdhb +.section sfdia +.section sfdib +.section sfdja +.section sfdjb +.section sfdka +.section sfdkb +.section sfdla +.section sfdlb +.section sfdma +.section sfdmb +.section sfdna +.section sfdnb +.section sfdoa +.section sfdob +.section sfdpa +.section sfdpb +.section sfdqa +.section sfdqb +.section sfdra +.section sfdrb +.section sfdsa +.section sfdsb +.section sfdta +.section sfdtb +.section sfdua +.section sfdub +.section sfdva +.section sfdvb +.section sfdwa +.section sfdwb +.section sfdxa +.section sfdxb +.section sfdya +.section sfdyb +.section sfdza +.section sfdzb +.section sfd1a +.section sfd1b +.section sfd2a +.section sfd2b +.section sfd3a +.section sfd3b +.section sfd4a +.section sfd4b +.section sfd5a +.section sfd5b +.section sfd6a +.section sfd6b +.section sfd7a +.section sfd7b +.section sfd8a +.section sfd8b +.section sfd9a +.section sfd9b +.section sfd0a +.section sfd0b +.section sfeaa +.section sfeab +.section sfeba +.section sfebb +.section sfeca +.section sfecb +.section sfeda +.section sfedb +.section sfeea +.section sfeeb +.section sfefa +.section sfefb +.section sfega +.section sfegb +.section sfeha +.section sfehb +.section sfeia +.section sfeib +.section sfeja +.section sfejb +.section sfeka +.section sfekb +.section sfela +.section sfelb +.section sfema +.section sfemb +.section sfena +.section sfenb +.section sfeoa +.section sfeob +.section sfepa +.section sfepb +.section sfeqa +.section sfeqb +.section sfera +.section sferb +.section sfesa +.section sfesb +.section sfeta +.section sfetb +.section sfeua +.section sfeub +.section sfeva +.section sfevb +.section sfewa +.section sfewb +.section sfexa +.section sfexb +.section sfeya +.section sfeyb +.section sfeza +.section sfezb +.section sfe1a +.section sfe1b +.section sfe2a +.section sfe2b +.section sfe3a +.section sfe3b +.section sfe4a +.section sfe4b +.section sfe5a +.section sfe5b +.section sfe6a +.section sfe6b +.section sfe7a +.section sfe7b +.section sfe8a +.section sfe8b +.section sfe9a +.section sfe9b +.section sfe0a +.section sfe0b +.section sffaa +.section sffab +.section sffba +.section sffbb +.section sffca +.section sffcb +.section sffda +.section sffdb +.section sffea +.section sffeb +.section sfffa +.section sfffb +.section sffga +.section sffgb +.section sffha +.section sffhb +.section sffia +.section sffib +.section sffja +.section sffjb +.section sffka +.section sffkb +.section sffla +.section sfflb +.section sffma +.section sffmb +.section sffna +.section sffnb +.section sffoa +.section sffob +.section sffpa +.section sffpb +.section sffqa +.section sffqb +.section sffra +.section sffrb +.section sffsa +.section sffsb +.section sffta +.section sfftb +.section sffua +.section sffub +.section sffva +.section sffvb +.section sffwa +.section sffwb +.section sffxa +.section sffxb +.section sffya +.section sffyb +.section sffza +.section sffzb +.section sff1a +.section sff1b +.section sff2a +.section sff2b +.section sff3a +.section sff3b +.section sff4a +.section sff4b +.section sff5a +.section sff5b +.section sff6a +.section sff6b +.section sff7a +.section sff7b +.section sff8a +.section sff8b +.section sff9a +.section sff9b +.section sff0a +.section sff0b +.section sfgaa +.section sfgab +.section sfgba +.section sfgbb +.section sfgca +.section sfgcb +.section sfgda +.section sfgdb +.section sfgea +.section sfgeb +.section sfgfa +.section sfgfb +.section sfgga +.section sfggb +.section sfgha +.section sfghb +.section sfgia +.section sfgib +.section sfgja +.section sfgjb +.section sfgka +.section sfgkb +.section sfgla +.section sfglb +.section sfgma +.section sfgmb +.section sfgna +.section sfgnb +.section sfgoa +.section sfgob +.section sfgpa +.section sfgpb +.section sfgqa +.section sfgqb +.section sfgra +.section sfgrb +.section sfgsa +.section sfgsb +.section sfgta +.section sfgtb +.section sfgua +.section sfgub +.section sfgva +.section sfgvb +.section sfgwa +.section sfgwb +.section sfgxa +.section sfgxb +.section sfgya +.section sfgyb +.section sfgza +.section sfgzb +.section sfg1a +.section sfg1b +.section sfg2a +.section sfg2b +.section sfg3a +.section sfg3b +.section sfg4a +.section sfg4b +.section sfg5a +.section sfg5b +.section sfg6a +.section sfg6b +.section sfg7a +.section sfg7b +.section sfg8a +.section sfg8b +.section sfg9a +.section sfg9b +.section sfg0a +.section sfg0b +.section sfhaa +.section sfhab +.section sfhba +.section sfhbb +.section sfhca +.section sfhcb +.section sfhda +.section sfhdb +.section sfhea +.section sfheb +.section sfhfa +.section sfhfb +.section sfhga +.section sfhgb +.section sfhha +.section sfhhb +.section sfhia +.section sfhib +.section sfhja +.section sfhjb +.section sfhka +.section sfhkb +.section sfhla +.section sfhlb +.section sfhma +.section sfhmb +.section sfhna +.section sfhnb +.section sfhoa +.section sfhob +.section sfhpa +.section sfhpb +.section sfhqa +.section sfhqb +.section sfhra +.section sfhrb +.section sfhsa +.section sfhsb +.section sfhta +.section sfhtb +.section sfhua +.section sfhub +.section sfhva +.section sfhvb +.section sfhwa +.section sfhwb +.section sfhxa +.section sfhxb +.section sfhya +.section sfhyb +.section sfhza +.section sfhzb +.section sfh1a +.section sfh1b +.section sfh2a +.section sfh2b +.section sfh3a +.section sfh3b +.section sfh4a +.section sfh4b +.section sfh5a +.section sfh5b +.section sfh6a +.section sfh6b +.section sfh7a +.section sfh7b +.section sfh8a +.section sfh8b +.section sfh9a +.section sfh9b +.section sfh0a +.section sfh0b +.section sfiaa +.section sfiab +.section sfiba +.section sfibb +.section sfica +.section sficb +.section sfida +.section sfidb +.section sfiea +.section sfieb +.section sfifa +.section sfifb +.section sfiga +.section sfigb +.section sfiha +.section sfihb +.section sfiia +.section sfiib +.section sfija +.section sfijb +.section sfika +.section sfikb +.section sfila +.section sfilb +.section sfima +.section sfimb +.section sfina +.section sfinb +.section sfioa +.section sfiob +.section sfipa +.section sfipb +.section sfiqa +.section sfiqb +.section sfira +.section sfirb +.section sfisa +.section sfisb +.section sfita +.section sfitb +.section sfiua +.section sfiub +.section sfiva +.section sfivb +.section sfiwa +.section sfiwb +.section sfixa +.section sfixb +.section sfiya +.section sfiyb +.section sfiza +.section sfizb +.section sfi1a +.section sfi1b +.section sfi2a +.section sfi2b +.section sfi3a +.section sfi3b +.section sfi4a +.section sfi4b +.section sfi5a +.section sfi5b +.section sfi6a +.section sfi6b +.section sfi7a +.section sfi7b +.section sfi8a +.section sfi8b +.section sfi9a +.section sfi9b +.section sfi0a +.section sfi0b +.section sfjaa +.section sfjab +.section sfjba +.section sfjbb +.section sfjca +.section sfjcb +.section sfjda +.section sfjdb +.section sfjea +.section sfjeb +.section sfjfa +.section sfjfb +.section sfjga +.section sfjgb +.section sfjha +.section sfjhb +.section sfjia +.section sfjib +.section sfjja +.section sfjjb +.section sfjka +.section sfjkb +.section sfjla +.section sfjlb +.section sfjma +.section sfjmb +.section sfjna +.section sfjnb +.section sfjoa +.section sfjob +.section sfjpa +.section sfjpb +.section sfjqa +.section sfjqb +.section sfjra +.section sfjrb +.section sfjsa +.section sfjsb +.section sfjta +.section sfjtb +.section sfjua +.section sfjub +.section sfjva +.section sfjvb +.section sfjwa +.section sfjwb +.section sfjxa +.section sfjxb +.section sfjya +.section sfjyb +.section sfjza +.section sfjzb +.section sfj1a +.section sfj1b +.section sfj2a +.section sfj2b +.section sfj3a +.section sfj3b +.section sfj4a +.section sfj4b +.section sfj5a +.section sfj5b +.section sfj6a +.section sfj6b +.section sfj7a +.section sfj7b +.section sfj8a +.section sfj8b +.section sfj9a +.section sfj9b +.section sfj0a +.section sfj0b +.section sfkaa +.section sfkab +.section sfkba +.section sfkbb +.section sfkca +.section sfkcb +.section sfkda +.section sfkdb +.section sfkea +.section sfkeb +.section sfkfa +.section sfkfb +.section sfkga +.section sfkgb +.section sfkha +.section sfkhb +.section sfkia +.section sfkib +.section sfkja +.section sfkjb +.section sfkka +.section sfkkb +.section sfkla +.section sfklb +.section sfkma +.section sfkmb +.section sfkna +.section sfknb +.section sfkoa +.section sfkob +.section sfkpa +.section sfkpb +.section sfkqa +.section sfkqb +.section sfkra +.section sfkrb +.section sfksa +.section sfksb +.section sfkta +.section sfktb +.section sfkua +.section sfkub +.section sfkva +.section sfkvb +.section sfkwa +.section sfkwb +.section sfkxa +.section sfkxb +.section sfkya +.section sfkyb +.section sfkza +.section sfkzb +.section sfk1a +.section sfk1b +.section sfk2a +.section sfk2b +.section sfk3a +.section sfk3b +.section sfk4a +.section sfk4b +.section sfk5a +.section sfk5b +.section sfk6a +.section sfk6b +.section sfk7a +.section sfk7b +.section sfk8a +.section sfk8b +.section sfk9a +.section sfk9b +.section sfk0a +.section sfk0b +.section sflaa +.section sflab +.section sflba +.section sflbb +.section sflca +.section sflcb +.section sflda +.section sfldb +.section sflea +.section sfleb +.section sflfa +.section sflfb +.section sflga +.section sflgb +.section sflha +.section sflhb +.section sflia +.section sflib +.section sflja +.section sfljb +.section sflka +.section sflkb +.section sflla +.section sfllb +.section sflma +.section sflmb +.section sflna +.section sflnb +.section sfloa +.section sflob +.section sflpa +.section sflpb +.section sflqa +.section sflqb +.section sflra +.section sflrb +.section sflsa +.section sflsb +.section sflta +.section sfltb +.section sflua +.section sflub +.section sflva +.section sflvb +.section sflwa +.section sflwb +.section sflxa +.section sflxb +.section sflya +.section sflyb +.section sflza +.section sflzb +.section sfl1a +.section sfl1b +.section sfl2a +.section sfl2b +.section sfl3a +.section sfl3b +.section sfl4a +.section sfl4b +.section sfl5a +.section sfl5b +.section sfl6a +.section sfl6b +.section sfl7a +.section sfl7b +.section sfl8a +.section sfl8b +.section sfl9a +.section sfl9b +.section sfl0a +.section sfl0b +.section sfmaa +.section sfmab +.section sfmba +.section sfmbb +.section sfmca +.section sfmcb +.section sfmda +.section sfmdb +.section sfmea +.section sfmeb +.section sfmfa +.section sfmfb +.section sfmga +.section sfmgb +.section sfmha +.section sfmhb +.section sfmia +.section sfmib +.section sfmja +.section sfmjb +.section sfmka +.section sfmkb +.section sfmla +.section sfmlb +.section sfmma +.section sfmmb +.section sfmna +.section sfmnb +.section sfmoa +.section sfmob +.section sfmpa +.section sfmpb +.section sfmqa +.section sfmqb +.section sfmra +.section sfmrb +.section sfmsa +.section sfmsb +.section sfmta +.section sfmtb +.section sfmua +.section sfmub +.section sfmva +.section sfmvb +.section sfmwa +.section sfmwb +.section sfmxa +.section sfmxb +.section sfmya +.section sfmyb +.section sfmza +.section sfmzb +.section sfm1a +.section sfm1b +.section sfm2a +.section sfm2b +.section sfm3a +.section sfm3b +.section sfm4a +.section sfm4b +.section sfm5a +.section sfm5b +.section sfm6a +.section sfm6b +.section sfm7a +.section sfm7b +.section sfm8a +.section sfm8b +.section sfm9a +.section sfm9b +.section sfm0a +.section sfm0b +.section sfnaa +.section sfnab +.section sfnba +.section sfnbb +.section sfnca +.section sfncb +.section sfnda +.section sfndb +.section sfnea +.section sfneb +.section sfnfa +.section sfnfb +.section sfnga +.section sfngb +.section sfnha +.section sfnhb +.section sfnia +.section sfnib +.section sfnja +.section sfnjb +.section sfnka +.section sfnkb +.section sfnla +.section sfnlb +.section sfnma +.section sfnmb +.section sfnna +.section sfnnb +.section sfnoa +.section sfnob +.section sfnpa +.section sfnpb +.section sfnqa +.section sfnqb +.section sfnra +.section sfnrb +.section sfnsa +.section sfnsb +.section sfnta +.section sfntb +.section sfnua +.section sfnub +.section sfnva +.section sfnvb +.section sfnwa +.section sfnwb +.section sfnxa +.section sfnxb +.section sfnya +.section sfnyb +.section sfnza +.section sfnzb +.section sfn1a +.section sfn1b +.section sfn2a +.section sfn2b +.section sfn3a +.section sfn3b +.section sfn4a +.section sfn4b +.section sfn5a +.section sfn5b +.section sfn6a +.section sfn6b +.section sfn7a +.section sfn7b +.section sfn8a +.section sfn8b +.section sfn9a +.section sfn9b +.section sfn0a +.section sfn0b +.section sfoaa +.section sfoab +.section sfoba +.section sfobb +.section sfoca +.section sfocb +.section sfoda +.section sfodb +.section sfoea +.section sfoeb +.section sfofa +.section sfofb +.section sfoga +.section sfogb +.section sfoha +.section sfohb +.section sfoia +.section sfoib +.section sfoja +.section sfojb +.section sfoka +.section sfokb +.section sfola +.section sfolb +.section sfoma +.section sfomb +.section sfona +.section sfonb +.section sfooa +.section sfoob +.section sfopa +.section sfopb +.section sfoqa +.section sfoqb +.section sfora +.section sforb +.section sfosa +.section sfosb +.section sfota +.section sfotb +.section sfoua +.section sfoub +.section sfova +.section sfovb +.section sfowa +.section sfowb +.section sfoxa +.section sfoxb +.section sfoya +.section sfoyb +.section sfoza +.section sfozb +.section sfo1a +.section sfo1b +.section sfo2a +.section sfo2b +.section sfo3a +.section sfo3b +.section sfo4a +.section sfo4b +.section sfo5a +.section sfo5b +.section sfo6a +.section sfo6b +.section sfo7a +.section sfo7b +.section sfo8a +.section sfo8b +.section sfo9a +.section sfo9b +.section sfo0a +.section sfo0b +.section sfpaa +.section sfpab +.section sfpba +.section sfpbb +.section sfpca +.section sfpcb +.section sfpda +.section sfpdb +.section sfpea +.section sfpeb +.section sfpfa +.section sfpfb +.section sfpga +.section sfpgb +.section sfpha +.section sfphb +.section sfpia +.section sfpib +.section sfpja +.section sfpjb +.section sfpka +.section sfpkb +.section sfpla +.section sfplb +.section sfpma +.section sfpmb +.section sfpna +.section sfpnb +.section sfpoa +.section sfpob +.section sfppa +.section sfppb +.section sfpqa +.section sfpqb +.section sfpra +.section sfprb +.section sfpsa +.section sfpsb +.section sfpta +.section sfptb +.section sfpua +.section sfpub +.section sfpva +.section sfpvb +.section sfpwa +.section sfpwb +.section sfpxa +.section sfpxb +.section sfpya +.section sfpyb +.section sfpza +.section sfpzb +.section sfp1a +.section sfp1b +.section sfp2a +.section sfp2b +.section sfp3a +.section sfp3b +.section sfp4a +.section sfp4b +.section sfp5a +.section sfp5b +.section sfp6a +.section sfp6b +.section sfp7a +.section sfp7b +.section sfp8a +.section sfp8b +.section sfp9a +.section sfp9b +.section sfp0a +.section sfp0b +.section sfqaa +.section sfqab +.section sfqba +.section sfqbb +.section sfqca +.section sfqcb +.section sfqda +.section sfqdb +.section sfqea +.section sfqeb +.section sfqfa +.section sfqfb +.section sfqga +.section sfqgb +.section sfqha +.section sfqhb +.section sfqia +.section sfqib +.section sfqja +.section sfqjb +.section sfqka +.section sfqkb +.section sfqla +.section sfqlb +.section sfqma +.section sfqmb +.section sfqna +.section sfqnb +.section sfqoa +.section sfqob +.section sfqpa +.section sfqpb +.section sfqqa +.section sfqqb +.section sfqra +.section sfqrb +.section sfqsa +.section sfqsb +.section sfqta +.section sfqtb +.section sfqua +.section sfqub +.section sfqva +.section sfqvb +.section sfqwa +.section sfqwb +.section sfqxa +.section sfqxb +.section sfqya +.section sfqyb +.section sfqza +.section sfqzb +.section sfq1a +.section sfq1b +.section sfq2a +.section sfq2b +.section sfq3a +.section sfq3b +.section sfq4a +.section sfq4b +.section sfq5a +.section sfq5b +.section sfq6a +.section sfq6b +.section sfq7a +.section sfq7b +.section sfq8a +.section sfq8b +.section sfq9a +.section sfq9b +.section sfq0a +.section sfq0b +.section sfraa +.section sfrab +.section sfrba +.section sfrbb +.section sfrca +.section sfrcb +.section sfrda +.section sfrdb +.section sfrea +.section sfreb +.section sfrfa +.section sfrfb +.section sfrga +.section sfrgb +.section sfrha +.section sfrhb +.section sfria +.section sfrib +.section sfrja +.section sfrjb +.section sfrka +.section sfrkb +.section sfrla +.section sfrlb +.section sfrma +.section sfrmb +.section sfrna +.section sfrnb +.section sfroa +.section sfrob +.section sfrpa +.section sfrpb +.section sfrqa +.section sfrqb +.section sfrra +.section sfrrb +.section sfrsa +.section sfrsb +.section sfrta +.section sfrtb +.section sfrua +.section sfrub +.section sfrva +.section sfrvb +.section sfrwa +.section sfrwb +.section sfrxa +.section sfrxb +.section sfrya +.section sfryb +.section sfrza +.section sfrzb +.section sfr1a +.section sfr1b +.section sfr2a +.section sfr2b +.section sfr3a +.section sfr3b +.section sfr4a +.section sfr4b +.section sfr5a +.section sfr5b +.section sfr6a +.section sfr6b +.section sfr7a +.section sfr7b +.section sfr8a +.section sfr8b +.section sfr9a +.section sfr9b +.section sfr0a +.section sfr0b +.section sfsaa +.section sfsab +.section sfsba +.section sfsbb +.section sfsca +.section sfscb +.section sfsda +.section sfsdb +.section sfsea +.section sfseb +.section sfsfa +.section sfsfb +.section sfsga +.section sfsgb +.section sfsha +.section sfshb +.section sfsia +.section sfsib +.section sfsja +.section sfsjb +.section sfska +.section sfskb +.section sfsla +.section sfslb +.section sfsma +.section sfsmb +.section sfsna +.section sfsnb +.section sfsoa +.section sfsob +.section sfspa +.section sfspb +.section sfsqa +.section sfsqb +.section sfsra +.section sfsrb +.section sfssa +.section sfssb +.section sfsta +.section sfstb +.section sfsua +.section sfsub +.section sfsva +.section sfsvb +.section sfswa +.section sfswb +.section sfsxa +.section sfsxb +.section sfsya +.section sfsyb +.section sfsza +.section sfszb +.section sfs1a +.section sfs1b +.section sfs2a +.section sfs2b +.section sfs3a +.section sfs3b +.section sfs4a +.section sfs4b +.section sfs5a +.section sfs5b +.section sfs6a +.section sfs6b +.section sfs7a +.section sfs7b +.section sfs8a +.section sfs8b +.section sfs9a +.section sfs9b +.section sfs0a +.section sfs0b +.section sftaa +.section sftab +.section sftba +.section sftbb +.section sftca +.section sftcb +.section sftda +.section sftdb +.section sftea +.section sfteb +.section sftfa +.section sftfb +.section sftga +.section sftgb +.section sftha +.section sfthb +.section sftia +.section sftib +.section sftja +.section sftjb +.section sftka +.section sftkb +.section sftla +.section sftlb +.section sftma +.section sftmb +.section sftna +.section sftnb +.section sftoa +.section sftob +.section sftpa +.section sftpb +.section sftqa +.section sftqb +.section sftra +.section sftrb +.section sftsa +.section sftsb +.section sftta +.section sfttb +.section sftua +.section sftub +.section sftva +.section sftvb +.section sftwa +.section sftwb +.section sftxa +.section sftxb +.section sftya +.section sftyb +.section sftza +.section sftzb +.section sft1a +.section sft1b +.section sft2a +.section sft2b +.section sft3a +.section sft3b +.section sft4a +.section sft4b +.section sft5a +.section sft5b +.section sft6a +.section sft6b +.section sft7a +.section sft7b +.section sft8a +.section sft8b +.section sft9a +.section sft9b +.section sft0a +.section sft0b +.section sfuaa +.section sfuab +.section sfuba +.section sfubb +.section sfuca +.section sfucb +.section sfuda +.section sfudb +.section sfuea +.section sfueb +.section sfufa +.section sfufb +.section sfuga +.section sfugb +.section sfuha +.section sfuhb +.section sfuia +.section sfuib +.section sfuja +.section sfujb +.section sfuka +.section sfukb +.section sfula +.section sfulb +.section sfuma +.section sfumb +.section sfuna +.section sfunb +.section sfuoa +.section sfuob +.section sfupa +.section sfupb +.section sfuqa +.section sfuqb +.section sfura +.section sfurb +.section sfusa +.section sfusb +.section sfuta +.section sfutb +.section sfuua +.section sfuub +.section sfuva +.section sfuvb +.section sfuwa +.section sfuwb +.section sfuxa +.section sfuxb +.section sfuya +.section sfuyb +.section sfuza +.section sfuzb +.section sfu1a +.section sfu1b +.section sfu2a +.section sfu2b +.section sfu3a +.section sfu3b +.section sfu4a +.section sfu4b +.section sfu5a +.section sfu5b +.section sfu6a +.section sfu6b +.section sfu7a +.section sfu7b +.section sfu8a +.section sfu8b +.section sfu9a +.section sfu9b +.section sfu0a +.section sfu0b +.section sfvaa +.section sfvab +.section sfvba +.section sfvbb +.section sfvca +.section sfvcb +.section sfvda +.section sfvdb +.section sfvea +.section sfveb +.section sfvfa +.section sfvfb +.section sfvga +.section sfvgb +.section sfvha +.section sfvhb +.section sfvia +.section sfvib +.section sfvja +.section sfvjb +.section sfvka +.section sfvkb +.section sfvla +.section sfvlb +.section sfvma +.section sfvmb +.section sfvna +.section sfvnb +.section sfvoa +.section sfvob +.section sfvpa +.section sfvpb +.section sfvqa +.section sfvqb +.section sfvra +.section sfvrb +.section sfvsa +.section sfvsb +.section sfvta +.section sfvtb +.section sfvua +.section sfvub +.section sfvva +.section sfvvb +.section sfvwa +.section sfvwb +.section sfvxa +.section sfvxb +.section sfvya +.section sfvyb +.section sfvza +.section sfvzb +.section sfv1a +.section sfv1b +.section sfv2a +.section sfv2b +.section sfv3a +.section sfv3b +.section sfv4a +.section sfv4b +.section sfv5a +.section sfv5b +.section sfv6a +.section sfv6b +.section sfv7a +.section sfv7b +.section sfv8a +.section sfv8b +.section sfv9a +.section sfv9b +.section sfv0a +.section sfv0b +.section sfwaa +.section sfwab +.section sfwba +.section sfwbb +.section sfwca +.section sfwcb +.section sfwda +.section sfwdb +.section sfwea +.section sfweb +.section sfwfa +.section sfwfb +.section sfwga +.section sfwgb +.section sfwha +.section sfwhb +.section sfwia +.section sfwib +.section sfwja +.section sfwjb +.section sfwka +.section sfwkb +.section sfwla +.section sfwlb +.section sfwma +.section sfwmb +.section sfwna +.section sfwnb +.section sfwoa +.section sfwob +.section sfwpa +.section sfwpb +.section sfwqa +.section sfwqb +.section sfwra +.section sfwrb +.section sfwsa +.section sfwsb +.section sfwta +.section sfwtb +.section sfwua +.section sfwub +.section sfwva +.section sfwvb +.section sfwwa +.section sfwwb +.section sfwxa +.section sfwxb +.section sfwya +.section sfwyb +.section sfwza +.section sfwzb +.section sfw1a +.section sfw1b +.section sfw2a +.section sfw2b +.section sfw3a +.section sfw3b +.section sfw4a +.section sfw4b +.section sfw5a +.section sfw5b +.section sfw6a +.section sfw6b +.section sfw7a +.section sfw7b +.section sfw8a +.section sfw8b +.section sfw9a +.section sfw9b +.section sfw0a +.section sfw0b +.section sfxaa +.section sfxab +.section sfxba +.section sfxbb +.section sfxca +.section sfxcb +.section sfxda +.section sfxdb +.section sfxea +.section sfxeb +.section sfxfa +.section sfxfb +.section sfxga +.section sfxgb +.section sfxha +.section sfxhb +.section sfxia +.section sfxib +.section sfxja +.section sfxjb +.section sfxka +.section sfxkb +.section sfxla +.section sfxlb +.section sfxma +.section sfxmb +.section sfxna +.section sfxnb +.section sfxoa +.section sfxob +.section sfxpa +.section sfxpb +.section sfxqa +.section sfxqb +.section sfxra +.section sfxrb +.section sfxsa +.section sfxsb +.section sfxta +.section sfxtb +.section sfxua +.section sfxub +.section sfxva +.section sfxvb +.section sfxwa +.section sfxwb +.section sfxxa +.section sfxxb +.section sfxya +.section sfxyb +.section sfxza +.section sfxzb +.section sfx1a +.section sfx1b +.section sfx2a +.section sfx2b +.section sfx3a +.section sfx3b +.section sfx4a +.section sfx4b +.section sfx5a +.section sfx5b +.section sfx6a +.section sfx6b +.section sfx7a +.section sfx7b +.section sfx8a +.section sfx8b +.section sfx9a +.section sfx9b +.section sfx0a +.section sfx0b +.section sfyaa +.section sfyab +.section sfyba +.section sfybb +.section sfyca +.section sfycb +.section sfyda +.section sfydb +.section sfyea +.section sfyeb +.section sfyfa +.section sfyfb +.section sfyga +.section sfygb +.section sfyha +.section sfyhb +.section sfyia +.section sfyib +.section sfyja +.section sfyjb +.section sfyka +.section sfykb +.section sfyla +.section sfylb +.section sfyma +.section sfymb +.section sfyna +.section sfynb +.section sfyoa +.section sfyob +.section sfypa +.section sfypb +.section sfyqa +.section sfyqb +.section sfyra +.section sfyrb +.section sfysa +.section sfysb +.section sfyta +.section sfytb +.section sfyua +.section sfyub +.section sfyva +.section sfyvb +.section sfywa +.section sfywb +.section sfyxa +.section sfyxb +.section sfyya +.section sfyyb +.section sfyza +.section sfyzb +.section sfy1a +.section sfy1b +.section sfy2a +.section sfy2b +.section sfy3a +.section sfy3b +.section sfy4a +.section sfy4b +.section sfy5a +.section sfy5b +.section sfy6a +.section sfy6b +.section sfy7a +.section sfy7b +.section sfy8a +.section sfy8b +.section sfy9a +.section sfy9b +.section sfy0a +.section sfy0b +.section sfzaa +.section sfzab +.section sfzba +.section sfzbb +.section sfzca +.section sfzcb +.section sfzda +.section sfzdb +.section sfzea +.section sfzeb +.section sfzfa +.section sfzfb +.section sfzga +.section sfzgb +.section sfzha +.section sfzhb +.section sfzia +.section sfzib +.section sfzja +.section sfzjb +.section sfzka +.section sfzkb +.section sfzla +.section sfzlb +.section sfzma +.section sfzmb +.section sfzna +.section sfznb +.section sfzoa +.section sfzob +.section sfzpa +.section sfzpb +.section sfzqa +.section sfzqb +.section sfzra +.section sfzrb +.section sfzsa +.section sfzsb +.section sfzta +.section sfztb +.section sfzua +.section sfzub +.section sfzva +.section sfzvb +.section sfzwa +.section sfzwb +.section sfzxa +.section sfzxb +.section sfzya +.section sfzyb +.section sfzza +.section sfzzb +.section sfz1a +.section sfz1b +.section sfz2a +.section sfz2b +.section sfz3a +.section sfz3b +.section sfz4a +.section sfz4b +.section sfz5a +.section sfz5b +.section sfz6a +.section sfz6b +.section sfz7a +.section sfz7b +.section sfz8a +.section sfz8b +.section sfz9a +.section sfz9b +.section sfz0a +.section sfz0b +.section sf1aa +.section sf1ab +.section sf1ba +.section sf1bb +.section sf1ca +.section sf1cb +.section sf1da +.section sf1db +.section sf1ea +.section sf1eb +.section sf1fa +.section sf1fb +.section sf1ga +.section sf1gb +.section sf1ha +.section sf1hb +.section sf1ia +.section sf1ib +.section sf1ja +.section sf1jb +.section sf1ka +.section sf1kb +.section sf1la +.section sf1lb +.section sf1ma +.section sf1mb +.section sf1na +.section sf1nb +.section sf1oa +.section sf1ob +.section sf1pa +.section sf1pb +.section sf1qa +.section sf1qb +.section sf1ra +.section sf1rb +.section sf1sa +.section sf1sb +.section sf1ta +.section sf1tb +.section sf1ua +.section sf1ub +.section sf1va +.section sf1vb +.section sf1wa +.section sf1wb +.section sf1xa +.section sf1xb +.section sf1ya +.section sf1yb +.section sf1za +.section sf1zb +.section sf11a +.section sf11b +.section sf12a +.section sf12b +.section sf13a +.section sf13b +.section sf14a +.section sf14b +.section sf15a +.section sf15b +.section sf16a +.section sf16b +.section sf17a +.section sf17b +.section sf18a +.section sf18b +.section sf19a +.section sf19b +.section sf10a +.section sf10b +.section sf2aa +.section sf2ab +.section sf2ba +.section sf2bb +.section sf2ca +.section sf2cb +.section sf2da +.section sf2db +.section sf2ea +.section sf2eb +.section sf2fa +.section sf2fb +.section sf2ga +.section sf2gb +.section sf2ha +.section sf2hb +.section sf2ia +.section sf2ib +.section sf2ja +.section sf2jb +.section sf2ka +.section sf2kb +.section sf2la +.section sf2lb +.section sf2ma +.section sf2mb +.section sf2na +.section sf2nb +.section sf2oa +.section sf2ob +.section sf2pa +.section sf2pb +.section sf2qa +.section sf2qb +.section sf2ra +.section sf2rb +.section sf2sa +.section sf2sb +.section sf2ta +.section sf2tb +.section sf2ua +.section sf2ub +.section sf2va +.section sf2vb +.section sf2wa +.section sf2wb +.section sf2xa +.section sf2xb +.section sf2ya +.section sf2yb +.section sf2za +.section sf2zb +.section sf21a +.section sf21b +.section sf22a +.section sf22b +.section sf23a +.section sf23b +.section sf24a +.section sf24b +.section sf25a +.section sf25b +.section sf26a +.section sf26b +.section sf27a +.section sf27b +.section sf28a +.section sf28b +.section sf29a +.section sf29b +.section sf20a +.section sf20b +.section sf3aa +.section sf3ab +.section sf3ba +.section sf3bb +.section sf3ca +.section sf3cb +.section sf3da +.section sf3db +.section sf3ea +.section sf3eb +.section sf3fa +.section sf3fb +.section sf3ga +.section sf3gb +.section sf3ha +.section sf3hb +.section sf3ia +.section sf3ib +.section sf3ja +.section sf3jb +.section sf3ka +.section sf3kb +.section sf3la +.section sf3lb +.section sf3ma +.section sf3mb +.section sf3na +.section sf3nb +.section sf3oa +.section sf3ob +.section sf3pa +.section sf3pb +.section sf3qa +.section sf3qb +.section sf3ra +.section sf3rb +.section sf3sa +.section sf3sb +.section sf3ta +.section sf3tb +.section sf3ua +.section sf3ub +.section sf3va +.section sf3vb +.section sf3wa +.section sf3wb +.section sf3xa +.section sf3xb +.section sf3ya +.section sf3yb +.section sf3za +.section sf3zb +.section sf31a +.section sf31b +.section sf32a +.section sf32b +.section sf33a +.section sf33b +.section sf34a +.section sf34b +.section sf35a +.section sf35b +.section sf36a +.section sf36b +.section sf37a +.section sf37b +.section sf38a +.section sf38b +.section sf39a +.section sf39b +.section sf30a +.section sf30b +.section sf4aa +.section sf4ab +.section sf4ba +.section sf4bb +.section sf4ca +.section sf4cb +.section sf4da +.section sf4db +.section sf4ea +.section sf4eb +.section sf4fa +.section sf4fb +.section sf4ga +.section sf4gb +.section sf4ha +.section sf4hb +.section sf4ia +.section sf4ib +.section sf4ja +.section sf4jb +.section sf4ka +.section sf4kb +.section sf4la +.section sf4lb +.section sf4ma +.section sf4mb +.section sf4na +.section sf4nb +.section sf4oa +.section sf4ob +.section sf4pa +.section sf4pb +.section sf4qa +.section sf4qb +.section sf4ra +.section sf4rb +.section sf4sa +.section sf4sb +.section sf4ta +.section sf4tb +.section sf4ua +.section sf4ub +.section sf4va +.section sf4vb +.section sf4wa +.section sf4wb +.section sf4xa +.section sf4xb +.section sf4ya +.section sf4yb +.section sf4za +.section sf4zb +.section sf41a +.section sf41b +.section sf42a +.section sf42b +.section sf43a +.section sf43b +.section sf44a +.section sf44b +.section sf45a +.section sf45b +.section sf46a +.section sf46b +.section sf47a +.section sf47b +.section sf48a +.section sf48b +.section sf49a +.section sf49b +.section sf40a +.section sf40b +.section sf5aa +.section sf5ab +.section sf5ba +.section sf5bb +.section sf5ca +.section sf5cb +.section sf5da +.section sf5db +.section sf5ea +.section sf5eb +.section sf5fa +.section sf5fb +.section sf5ga +.section sf5gb +.section sf5ha +.section sf5hb +.section sf5ia +.section sf5ib +.section sf5ja +.section sf5jb +.section sf5ka +.section sf5kb +.section sf5la +.section sf5lb +.section sf5ma +.section sf5mb +.section sf5na +.section sf5nb +.section sf5oa +.section sf5ob +.section sf5pa +.section sf5pb +.section sf5qa +.section sf5qb +.section sf5ra +.section sf5rb +.section sf5sa +.section sf5sb +.section sf5ta +.section sf5tb +.section sf5ua +.section sf5ub +.section sf5va +.section sf5vb +.section sf5wa +.section sf5wb +.section sf5xa +.section sf5xb +.section sf5ya +.section sf5yb +.section sf5za +.section sf5zb +.section sf51a +.section sf51b +.section sf52a +.section sf52b +.section sf53a +.section sf53b +.section sf54a +.section sf54b +.section sf55a +.section sf55b +.section sf56a +.section sf56b +.section sf57a +.section sf57b +.section sf58a +.section sf58b +.section sf59a +.section sf59b +.section sf50a +.section sf50b +.section sf6aa +.section sf6ab +.section sf6ba +.section sf6bb +.section sf6ca +.section sf6cb +.section sf6da +.section sf6db +.section sf6ea +.section sf6eb +.section sf6fa +.section sf6fb +.section sf6ga +.section sf6gb +.section sf6ha +.section sf6hb +.section sf6ia +.section sf6ib +.section sf6ja +.section sf6jb +.section sf6ka +.section sf6kb +.section sf6la +.section sf6lb +.section sf6ma +.section sf6mb +.section sf6na +.section sf6nb +.section sf6oa +.section sf6ob +.section sf6pa +.section sf6pb +.section sf6qa +.section sf6qb +.section sf6ra +.section sf6rb +.section sf6sa +.section sf6sb +.section sf6ta +.section sf6tb +.section sf6ua +.section sf6ub +.section sf6va +.section sf6vb +.section sf6wa +.section sf6wb +.section sf6xa +.section sf6xb +.section sf6ya +.section sf6yb +.section sf6za +.section sf6zb +.section sf61a +.section sf61b +.section sf62a +.section sf62b +.section sf63a +.section sf63b +.section sf64a +.section sf64b +.section sf65a +.section sf65b +.section sf66a +.section sf66b +.section sf67a +.section sf67b +.section sf68a +.section sf68b +.section sf69a +.section sf69b +.section sf60a +.section sf60b +.section sf7aa +.section sf7ab +.section sf7ba +.section sf7bb +.section sf7ca +.section sf7cb +.section sf7da +.section sf7db +.section sf7ea +.section sf7eb +.section sf7fa +.section sf7fb +.section sf7ga +.section sf7gb +.section sf7ha +.section sf7hb +.section sf7ia +.section sf7ib +.section sf7ja +.section sf7jb +.section sf7ka +.section sf7kb +.section sf7la +.section sf7lb +.section sf7ma +.section sf7mb +.section sf7na +.section sf7nb +.section sf7oa +.section sf7ob +.section sf7pa +.section sf7pb +.section sf7qa +.section sf7qb +.section sf7ra +.section sf7rb +.section sf7sa +.section sf7sb +.section sf7ta +.section sf7tb +.section sf7ua +.section sf7ub +.section sf7va +.section sf7vb +.section sf7wa +.section sf7wb +.section sf7xa +.section sf7xb +.section sf7ya +.section sf7yb +.section sf7za +.section sf7zb +.section sf71a +.section sf71b +.section sf72a +.section sf72b +.section sf73a +.section sf73b +.section sf74a +.section sf74b +.section sf75a +.section sf75b +.section sf76a +.section sf76b +.section sf77a +.section sf77b +.section sf78a +.section sf78b +.section sf79a +.section sf79b +.section sf70a +.section sf70b +.section sf8aa +.section sf8ab +.section sf8ba +.section sf8bb +.section sf8ca +.section sf8cb +.section sf8da +.section sf8db +.section sf8ea +.section sf8eb +.section sf8fa +.section sf8fb +.section sf8ga +.section sf8gb +.section sf8ha +.section sf8hb +.section sf8ia +.section sf8ib +.section sf8ja +.section sf8jb +.section sf8ka +.section sf8kb +.section sf8la +.section sf8lb +.section sf8ma +.section sf8mb +.section sf8na +.section sf8nb +.section sf8oa +.section sf8ob +.section sf8pa +.section sf8pb +.section sf8qa +.section sf8qb +.section sf8ra +.section sf8rb +.section sf8sa +.section sf8sb +.section sf8ta +.section sf8tb +.section sf8ua +.section sf8ub +.section sf8va +.section sf8vb +.section sf8wa +.section sf8wb +.section sf8xa +.section sf8xb +.section sf8ya +.section sf8yb +.section sf8za +.section sf8zb +.section sf81a +.section sf81b +.section sf82a +.section sf82b +.section sf83a +.section sf83b +.section sf84a +.section sf84b +.section sf85a +.section sf85b +.section sf86a +.section sf86b +.section sf87a +.section sf87b +.section sf88a +.section sf88b +.section sf89a +.section sf89b +.section sf80a +.section sf80b +.section sf9aa +.section sf9ab +.section sf9ba +.section sf9bb +.section sf9ca +.section sf9cb +.section sf9da +.section sf9db +.section sf9ea +.section sf9eb +.section sf9fa +.section sf9fb +.section sf9ga +.section sf9gb +.section sf9ha +.section sf9hb +.section sf9ia +.section sf9ib +.section sf9ja +.section sf9jb +.section sf9ka +.section sf9kb +.section sf9la +.section sf9lb +.section sf9ma +.section sf9mb +.section sf9na +.section sf9nb +.section sf9oa +.section sf9ob +.section sf9pa +.section sf9pb +.section sf9qa +.section sf9qb +.section sf9ra +.section sf9rb +.section sf9sa +.section sf9sb +.section sf9ta +.section sf9tb +.section sf9ua +.section sf9ub +.section sf9va +.section sf9vb +.section sf9wa +.section sf9wb +.section sf9xa +.section sf9xb +.section sf9ya +.section sf9yb +.section sf9za +.section sf9zb +.section sf91a +.section sf91b +.section sf92a +.section sf92b +.section sf93a +.section sf93b +.section sf94a +.section sf94b +.section sf95a +.section sf95b +.section sf96a +.section sf96b +.section sf97a +.section sf97b +.section sf98a +.section sf98b +.section sf99a +.section sf99b +.section sf90a +.section sf90b +.section sf0aa +.section sf0ab +.section sf0ba +.section sf0bb +.section sf0ca +.section sf0cb +.section sf0da +.section sf0db +.section sf0ea +.section sf0eb +.section sf0fa +.section sf0fb +.section sf0ga +.section sf0gb +.section sf0ha +.section sf0hb +.section sf0ia +.section sf0ib +.section sf0ja +.section sf0jb +.section sf0ka +.section sf0kb +.section sf0la +.section sf0lb +.section sf0ma +.section sf0mb +.section sf0na +.section sf0nb +.section sf0oa +.section sf0ob +.section sf0pa +.section sf0pb +.section sf0qa +.section sf0qb +.section sf0ra +.section sf0rb +.section sf0sa +.section sf0sb +.section sf0ta +.section sf0tb +.section sf0ua +.section sf0ub +.section sf0va +.section sf0vb +.section sf0wa +.section sf0wb +.section sf0xa +.section sf0xb +.section sf0ya +.section sf0yb +.section sf0za +.section sf0zb +.section sf01a +.section sf01b +.section sf02a +.section sf02b +.section sf03a +.section sf03b +.section sf04a +.section sf04b +.section sf05a +.section sf05b +.section sf06a +.section sf06b +.section sf07a +.section sf07b +.section sf08a +.section sf08b +.section sf09a +.section sf09b +.section sf00a +.section sf00b +.section sgaaa +.section sgaab +.section sgaba +.section sgabb +.section sgaca +.section sgacb +.section sgada +.section sgadb +.section sgaea +.section sgaeb +.section sgafa +.section sgafb +.section sgaga +.section sgagb +.section sgaha +.section sgahb +.section sgaia +.section sgaib +.section sgaja +.section sgajb +.section sgaka +.section sgakb +.section sgala +.section sgalb +.section sgama +.section sgamb +.section sgana +.section sganb +.section sgaoa +.section sgaob +.section sgapa +.section sgapb +.section sgaqa +.section sgaqb +.section sgara +.section sgarb +.section sgasa +.section sgasb +.section sgata +.section sgatb +.section sgaua +.section sgaub +.section sgava +.section sgavb +.section sgawa +.section sgawb +.section sgaxa +.section sgaxb +.section sgaya +.section sgayb +.section sgaza +.section sgazb +.section sga1a +.section sga1b +.section sga2a +.section sga2b +.section sga3a +.section sga3b +.section sga4a +.section sga4b +.section sga5a +.section sga5b +.section sga6a +.section sga6b +.section sga7a +.section sga7b +.section sga8a +.section sga8b +.section sga9a +.section sga9b +.section sga0a +.section sga0b +.section sgbaa +.section sgbab +.section sgbba +.section sgbbb +.section sgbca +.section sgbcb +.section sgbda +.section sgbdb +.section sgbea +.section sgbeb +.section sgbfa +.section sgbfb +.section sgbga +.section sgbgb +.section sgbha +.section sgbhb +.section sgbia +.section sgbib +.section sgbja +.section sgbjb +.section sgbka +.section sgbkb +.section sgbla +.section sgblb +.section sgbma +.section sgbmb +.section sgbna +.section sgbnb +.section sgboa +.section sgbob +.section sgbpa +.section sgbpb +.section sgbqa +.section sgbqb +.section sgbra +.section sgbrb +.section sgbsa +.section sgbsb +.section sgbta +.section sgbtb +.section sgbua +.section sgbub +.section sgbva +.section sgbvb +.section sgbwa +.section sgbwb +.section sgbxa +.section sgbxb +.section sgbya +.section sgbyb +.section sgbza +.section sgbzb +.section sgb1a +.section sgb1b +.section sgb2a +.section sgb2b +.section sgb3a +.section sgb3b +.section sgb4a +.section sgb4b +.section sgb5a +.section sgb5b +.section sgb6a +.section sgb6b +.section sgb7a +.section sgb7b +.section sgb8a +.section sgb8b +.section sgb9a +.section sgb9b +.section sgb0a +.section sgb0b +.section sgcaa +.section sgcab +.section sgcba +.section sgcbb +.section sgcca +.section sgccb +.section sgcda +.section sgcdb +.section sgcea +.section sgceb +.section sgcfa +.section sgcfb +.section sgcga +.section sgcgb +.section sgcha +.section sgchb +.section sgcia +.section sgcib +.section sgcja +.section sgcjb +.section sgcka +.section sgckb +.section sgcla +.section sgclb +.section sgcma +.section sgcmb +.section sgcna +.section sgcnb +.section sgcoa +.section sgcob +.section sgcpa +.section sgcpb +.section sgcqa +.section sgcqb +.section sgcra +.section sgcrb +.section sgcsa +.section sgcsb +.section sgcta +.section sgctb +.section sgcua +.section sgcub +.section sgcva +.section sgcvb +.section sgcwa +.section sgcwb +.section sgcxa +.section sgcxb +.section sgcya +.section sgcyb +.section sgcza +.section sgczb +.section sgc1a +.section sgc1b +.section sgc2a +.section sgc2b +.section sgc3a +.section sgc3b +.section sgc4a +.section sgc4b +.section sgc5a +.section sgc5b +.section sgc6a +.section sgc6b +.section sgc7a +.section sgc7b +.section sgc8a +.section sgc8b +.section sgc9a +.section sgc9b +.section sgc0a +.section sgc0b +.section sgdaa +.section sgdab +.section sgdba +.section sgdbb +.section sgdca +.section sgdcb +.section sgdda +.section sgddb +.section sgdea +.section sgdeb +.section sgdfa +.section sgdfb +.section sgdga +.section sgdgb +.section sgdha +.section sgdhb +.section sgdia +.section sgdib +.section sgdja +.section sgdjb +.section sgdka +.section sgdkb +.section sgdla +.section sgdlb +.section sgdma +.section sgdmb +.section sgdna +.section sgdnb +.section sgdoa +.section sgdob +.section sgdpa +.section sgdpb +.section sgdqa +.section sgdqb +.section sgdra +.section sgdrb +.section sgdsa +.section sgdsb +.section sgdta +.section sgdtb +.section sgdua +.section sgdub +.section sgdva +.section sgdvb +.section sgdwa +.section sgdwb +.section sgdxa +.section sgdxb +.section sgdya +.section sgdyb +.section sgdza +.section sgdzb +.section sgd1a +.section sgd1b +.section sgd2a +.section sgd2b +.section sgd3a +.section sgd3b +.section sgd4a +.section sgd4b +.section sgd5a +.section sgd5b +.section sgd6a +.section sgd6b +.section sgd7a +.section sgd7b +.section sgd8a +.section sgd8b +.section sgd9a +.section sgd9b +.section sgd0a +.section sgd0b +.section sgeaa +.section sgeab +.section sgeba +.section sgebb +.section sgeca +.section sgecb +.section sgeda +.section sgedb +.section sgeea +.section sgeeb +.section sgefa +.section sgefb +.section sgega +.section sgegb +.section sgeha +.section sgehb +.section sgeia +.section sgeib +.section sgeja +.section sgejb +.section sgeka +.section sgekb +.section sgela +.section sgelb +.section sgema +.section sgemb +.section sgena +.section sgenb +.section sgeoa +.section sgeob +.section sgepa +.section sgepb +.section sgeqa +.section sgeqb +.section sgera +.section sgerb +.section sgesa +.section sgesb +.section sgeta +.section sgetb +.section sgeua +.section sgeub +.section sgeva +.section sgevb +.section sgewa +.section sgewb +.section sgexa +.section sgexb +.section sgeya +.section sgeyb +.section sgeza +.section sgezb +.section sge1a +.section sge1b +.section sge2a +.section sge2b +.section sge3a +.section sge3b +.section sge4a +.section sge4b +.section sge5a +.section sge5b +.section sge6a +.section sge6b +.section sge7a +.section sge7b +.section sge8a +.section sge8b +.section sge9a +.section sge9b +.section sge0a +.section sge0b +.section sgfaa +.section sgfab +.section sgfba +.section sgfbb +.section sgfca +.section sgfcb +.section sgfda +.section sgfdb +.section sgfea +.section sgfeb +.section sgffa +.section sgffb +.section sgfga +.section sgfgb +.section sgfha +.section sgfhb +.section sgfia +.section sgfib +.section sgfja +.section sgfjb +.section sgfka +.section sgfkb +.section sgfla +.section sgflb +.section sgfma +.section sgfmb +.section sgfna +.section sgfnb +.section sgfoa +.section sgfob +.section sgfpa +.section sgfpb +.section sgfqa +.section sgfqb +.section sgfra +.section sgfrb +.section sgfsa +.section sgfsb +.section sgfta +.section sgftb +.section sgfua +.section sgfub +.section sgfva +.section sgfvb +.section sgfwa +.section sgfwb +.section sgfxa +.section sgfxb +.section sgfya +.section sgfyb +.section sgfza +.section sgfzb +.section sgf1a +.section sgf1b +.section sgf2a +.section sgf2b +.section sgf3a +.section sgf3b +.section sgf4a +.section sgf4b +.section sgf5a +.section sgf5b +.section sgf6a +.section sgf6b +.section sgf7a +.section sgf7b +.section sgf8a +.section sgf8b +.section sgf9a +.section sgf9b +.section sgf0a +.section sgf0b +.section sggaa +.section sggab +.section sggba +.section sggbb +.section sggca +.section sggcb +.section sggda +.section sggdb +.section sggea +.section sggeb +.section sggfa +.section sggfb +.section sggga +.section sgggb +.section sggha +.section sgghb +.section sggia +.section sggib +.section sggja +.section sggjb +.section sggka +.section sggkb +.section sggla +.section sgglb +.section sggma +.section sggmb +.section sggna +.section sggnb +.section sggoa +.section sggob +.section sggpa +.section sggpb +.section sggqa +.section sggqb +.section sggra +.section sggrb +.section sggsa +.section sggsb +.section sggta +.section sggtb +.section sggua +.section sggub +.section sggva +.section sggvb +.section sggwa +.section sggwb +.section sggxa +.section sggxb +.section sggya +.section sggyb +.section sggza +.section sggzb +.section sgg1a +.section sgg1b +.section sgg2a +.section sgg2b +.section sgg3a +.section sgg3b +.section sgg4a +.section sgg4b +.section sgg5a +.section sgg5b +.section sgg6a +.section sgg6b +.section sgg7a +.section sgg7b +.section sgg8a +.section sgg8b +.section sgg9a +.section sgg9b +.section sgg0a +.section sgg0b +.section sghaa +.section sghab +.section sghba +.section sghbb +.section sghca +.section sghcb +.section sghda +.section sghdb +.section sghea +.section sgheb +.section sghfa +.section sghfb +.section sghga +.section sghgb +.section sghha +.section sghhb +.section sghia +.section sghib +.section sghja +.section sghjb +.section sghka +.section sghkb +.section sghla +.section sghlb +.section sghma +.section sghmb +.section sghna +.section sghnb +.section sghoa +.section sghob +.section sghpa +.section sghpb +.section sghqa +.section sghqb +.section sghra +.section sghrb +.section sghsa +.section sghsb +.section sghta +.section sghtb +.section sghua +.section sghub +.section sghva +.section sghvb +.section sghwa +.section sghwb +.section sghxa +.section sghxb +.section sghya +.section sghyb +.section sghza +.section sghzb +.section sgh1a +.section sgh1b +.section sgh2a +.section sgh2b +.section sgh3a +.section sgh3b +.section sgh4a +.section sgh4b +.section sgh5a +.section sgh5b +.section sgh6a +.section sgh6b +.section sgh7a +.section sgh7b +.section sgh8a +.section sgh8b +.section sgh9a +.section sgh9b +.section sgh0a +.section sgh0b +.section sgiaa +.section sgiab +.section sgiba +.section sgibb +.section sgica +.section sgicb +.section sgida +.section sgidb +.section sgiea +.section sgieb +.section sgifa +.section sgifb +.section sgiga +.section sgigb +.section sgiha +.section sgihb +.section sgiia +.section sgiib +.section sgija +.section sgijb +.section sgika +.section sgikb +.section sgila +.section sgilb +.section sgima +.section sgimb +.section sgina +.section sginb +.section sgioa +.section sgiob +.section sgipa +.section sgipb +.section sgiqa +.section sgiqb +.section sgira +.section sgirb +.section sgisa +.section sgisb +.section sgita +.section sgitb +.section sgiua +.section sgiub +.section sgiva +.section sgivb +.section sgiwa +.section sgiwb +.section sgixa +.section sgixb +.section sgiya +.section sgiyb +.section sgiza +.section sgizb +.section sgi1a +.section sgi1b +.section sgi2a +.section sgi2b +.section sgi3a +.section sgi3b +.section sgi4a +.section sgi4b +.section sgi5a +.section sgi5b +.section sgi6a +.section sgi6b +.section sgi7a +.section sgi7b +.section sgi8a +.section sgi8b +.section sgi9a +.section sgi9b +.section sgi0a +.section sgi0b +.section sgjaa +.section sgjab +.section sgjba +.section sgjbb +.section sgjca +.section sgjcb +.section sgjda +.section sgjdb +.section sgjea +.section sgjeb +.section sgjfa +.section sgjfb +.section sgjga +.section sgjgb +.section sgjha +.section sgjhb +.section sgjia +.section sgjib +.section sgjja +.section sgjjb +.section sgjka +.section sgjkb +.section sgjla +.section sgjlb +.section sgjma +.section sgjmb +.section sgjna +.section sgjnb +.section sgjoa +.section sgjob +.section sgjpa +.section sgjpb +.section sgjqa +.section sgjqb +.section sgjra +.section sgjrb +.section sgjsa +.section sgjsb +.section sgjta +.section sgjtb +.section sgjua +.section sgjub +.section sgjva +.section sgjvb +.section sgjwa +.section sgjwb +.section sgjxa +.section sgjxb +.section sgjya +.section sgjyb +.section sgjza +.section sgjzb +.section sgj1a +.section sgj1b +.section sgj2a +.section sgj2b +.section sgj3a +.section sgj3b +.section sgj4a +.section sgj4b +.section sgj5a +.section sgj5b +.section sgj6a +.section sgj6b +.section sgj7a +.section sgj7b +.section sgj8a +.section sgj8b +.section sgj9a +.section sgj9b +.section sgj0a +.section sgj0b +.section sgkaa +.section sgkab +.section sgkba +.section sgkbb +.section sgkca +.section sgkcb +.section sgkda +.section sgkdb +.section sgkea +.section sgkeb +.section sgkfa +.section sgkfb +.section sgkga +.section sgkgb +.section sgkha +.section sgkhb +.section sgkia +.section sgkib +.section sgkja +.section sgkjb +.section sgkka +.section sgkkb +.section sgkla +.section sgklb +.section sgkma +.section sgkmb +.section sgkna +.section sgknb +.section sgkoa +.section sgkob +.section sgkpa +.section sgkpb +.section sgkqa +.section sgkqb +.section sgkra +.section sgkrb +.section sgksa +.section sgksb +.section sgkta +.section sgktb +.section sgkua +.section sgkub +.section sgkva +.section sgkvb +.section sgkwa +.section sgkwb +.section sgkxa +.section sgkxb +.section sgkya +.section sgkyb +.section sgkza +.section sgkzb +.section sgk1a +.section sgk1b +.section sgk2a +.section sgk2b +.section sgk3a +.section sgk3b +.section sgk4a +.section sgk4b +.section sgk5a +.section sgk5b +.section sgk6a +.section sgk6b +.section sgk7a +.section sgk7b +.section sgk8a +.section sgk8b +.section sgk9a +.section sgk9b +.section sgk0a +.section sgk0b +.section sglaa +.section sglab +.section sglba +.section sglbb +.section sglca +.section sglcb +.section sglda +.section sgldb +.section sglea +.section sgleb +.section sglfa +.section sglfb +.section sglga +.section sglgb +.section sglha +.section sglhb +.section sglia +.section sglib +.section sglja +.section sgljb +.section sglka +.section sglkb +.section sglla +.section sgllb +.section sglma +.section sglmb +.section sglna +.section sglnb +.section sgloa +.section sglob +.section sglpa +.section sglpb +.section sglqa +.section sglqb +.section sglra +.section sglrb +.section sglsa +.section sglsb +.section sglta +.section sgltb +.section sglua +.section sglub +.section sglva +.section sglvb +.section sglwa +.section sglwb +.section sglxa +.section sglxb +.section sglya +.section sglyb +.section sglza +.section sglzb +.section sgl1a +.section sgl1b +.section sgl2a +.section sgl2b +.section sgl3a +.section sgl3b +.section sgl4a +.section sgl4b +.section sgl5a +.section sgl5b +.section sgl6a +.section sgl6b +.section sgl7a +.section sgl7b +.section sgl8a +.section sgl8b +.section sgl9a +.section sgl9b +.section sgl0a +.section sgl0b +.section sgmaa +.section sgmab +.section sgmba +.section sgmbb +.section sgmca +.section sgmcb +.section sgmda +.section sgmdb +.section sgmea +.section sgmeb +.section sgmfa +.section sgmfb +.section sgmga +.section sgmgb +.section sgmha +.section sgmhb +.section sgmia +.section sgmib +.section sgmja +.section sgmjb +.section sgmka +.section sgmkb +.section sgmla +.section sgmlb +.section sgmma +.section sgmmb +.section sgmna +.section sgmnb +.section sgmoa +.section sgmob +.section sgmpa +.section sgmpb +.section sgmqa +.section sgmqb +.section sgmra +.section sgmrb +.section sgmsa +.section sgmsb +.section sgmta +.section sgmtb +.section sgmua +.section sgmub +.section sgmva +.section sgmvb +.section sgmwa +.section sgmwb +.section sgmxa +.section sgmxb +.section sgmya +.section sgmyb +.section sgmza +.section sgmzb +.section sgm1a +.section sgm1b +.section sgm2a +.section sgm2b +.section sgm3a +.section sgm3b +.section sgm4a +.section sgm4b +.section sgm5a +.section sgm5b +.section sgm6a +.section sgm6b +.section sgm7a +.section sgm7b +.section sgm8a +.section sgm8b +.section sgm9a +.section sgm9b +.section sgm0a +.section sgm0b +.section sgnaa +.section sgnab +.section sgnba +.section sgnbb +.section sgnca +.section sgncb +.section sgnda +.section sgndb +.section sgnea +.section sgneb +.section sgnfa +.section sgnfb +.section sgnga +.section sgngb +.section sgnha +.section sgnhb +.section sgnia +.section sgnib +.section sgnja +.section sgnjb +.section sgnka +.section sgnkb +.section sgnla +.section sgnlb +.section sgnma +.section sgnmb +.section sgnna +.section sgnnb +.section sgnoa +.section sgnob +.section sgnpa +.section sgnpb +.section sgnqa +.section sgnqb +.section sgnra +.section sgnrb +.section sgnsa +.section sgnsb +.section sgnta +.section sgntb +.section sgnua +.section sgnub +.section sgnva +.section sgnvb +.section sgnwa +.section sgnwb +.section sgnxa +.section sgnxb +.section sgnya +.section sgnyb +.section sgnza +.section sgnzb +.section sgn1a +.section sgn1b +.section sgn2a +.section sgn2b +.section sgn3a +.section sgn3b +.section sgn4a +.section sgn4b +.section sgn5a +.section sgn5b +.section sgn6a +.section sgn6b +.section sgn7a +.section sgn7b +.section sgn8a +.section sgn8b +.section sgn9a +.section sgn9b +.section sgn0a +.section sgn0b +.section sgoaa +.section sgoab +.section sgoba +.section sgobb +.section sgoca +.section sgocb +.section sgoda +.section sgodb +.section sgoea +.section sgoeb +.section sgofa +.section sgofb +.section sgoga +.section sgogb +.section sgoha +.section sgohb +.section sgoia +.section sgoib +.section sgoja +.section sgojb +.section sgoka +.section sgokb +.section sgola +.section sgolb +.section sgoma +.section sgomb +.section sgona +.section sgonb +.section sgooa +.section sgoob +.section sgopa +.section sgopb +.section sgoqa +.section sgoqb +.section sgora +.section sgorb +.section sgosa +.section sgosb +.section sgota +.section sgotb +.section sgoua +.section sgoub +.section sgova +.section sgovb +.section sgowa +.section sgowb +.section sgoxa +.section sgoxb +.section sgoya +.section sgoyb +.section sgoza +.section sgozb +.section sgo1a +.section sgo1b +.section sgo2a +.section sgo2b +.section sgo3a +.section sgo3b +.section sgo4a +.section sgo4b +.section sgo5a +.section sgo5b +.section sgo6a +.section sgo6b +.section sgo7a +.section sgo7b +.section sgo8a +.section sgo8b +.section sgo9a +.section sgo9b +.section sgo0a +.section sgo0b +.section sgpaa +.section sgpab +.section sgpba +.section sgpbb +.section sgpca +.section sgpcb +.section sgpda +.section sgpdb +.section sgpea +.section sgpeb +.section sgpfa +.section sgpfb +.section sgpga +.section sgpgb +.section sgpha +.section sgphb +.section sgpia +.section sgpib +.section sgpja +.section sgpjb +.section sgpka +.section sgpkb +.section sgpla +.section sgplb +.section sgpma +.section sgpmb +.section sgpna +.section sgpnb +.section sgpoa +.section sgpob +.section sgppa +.section sgppb +.section sgpqa +.section sgpqb +.section sgpra +.section sgprb +.section sgpsa +.section sgpsb +.section sgpta +.section sgptb +.section sgpua +.section sgpub +.section sgpva +.section sgpvb +.section sgpwa +.section sgpwb +.section sgpxa +.section sgpxb +.section sgpya +.section sgpyb +.section sgpza +.section sgpzb +.section sgp1a +.section sgp1b +.section sgp2a +.section sgp2b +.section sgp3a +.section sgp3b +.section sgp4a +.section sgp4b +.section sgp5a +.section sgp5b +.section sgp6a +.section sgp6b +.section sgp7a +.section sgp7b +.section sgp8a +.section sgp8b +.section sgp9a +.section sgp9b +.section sgp0a +.section sgp0b +.section sgqaa +.section sgqab +.section sgqba +.section sgqbb +.section sgqca +.section sgqcb +.section sgqda +.section sgqdb +.section sgqea +.section sgqeb +.section sgqfa +.section sgqfb +.section sgqga +.section sgqgb +.section sgqha +.section sgqhb +.section sgqia +.section sgqib +.section sgqja +.section sgqjb +.section sgqka +.section sgqkb +.section sgqla +.section sgqlb +.section sgqma +.section sgqmb +.section sgqna +.section sgqnb +.section sgqoa +.section sgqob +.section sgqpa +.section sgqpb +.section sgqqa +.section sgqqb +.section sgqra +.section sgqrb +.section sgqsa +.section sgqsb +.section sgqta +.section sgqtb +.section sgqua +.section sgqub +.section sgqva +.section sgqvb +.section sgqwa +.section sgqwb +.section sgqxa +.section sgqxb +.section sgqya +.section sgqyb +.section sgqza +.section sgqzb +.section sgq1a +.section sgq1b +.section sgq2a +.section sgq2b +.section sgq3a +.section sgq3b +.section sgq4a +.section sgq4b +.section sgq5a +.section sgq5b +.section sgq6a +.section sgq6b +.section sgq7a +.section sgq7b +.section sgq8a +.section sgq8b +.section sgq9a +.section sgq9b +.section sgq0a +.section sgq0b +.section sgraa +.section sgrab +.section sgrba +.section sgrbb +.section sgrca +.section sgrcb +.section sgrda +.section sgrdb +.section sgrea +.section sgreb +.section sgrfa +.section sgrfb +.section sgrga +.section sgrgb +.section sgrha +.section sgrhb +.section sgria +.section sgrib +.section sgrja +.section sgrjb +.section sgrka +.section sgrkb +.section sgrla +.section sgrlb +.section sgrma +.section sgrmb +.section sgrna +.section sgrnb +.section sgroa +.section sgrob +.section sgrpa +.section sgrpb +.section sgrqa +.section sgrqb +.section sgrra +.section sgrrb +.section sgrsa +.section sgrsb +.section sgrta +.section sgrtb +.section sgrua +.section sgrub +.section sgrva +.section sgrvb +.section sgrwa +.section sgrwb +.section sgrxa +.section sgrxb +.section sgrya +.section sgryb +.section sgrza +.section sgrzb +.section sgr1a +.section sgr1b +.section sgr2a +.section sgr2b +.section sgr3a +.section sgr3b +.section sgr4a +.section sgr4b +.section sgr5a +.section sgr5b +.section sgr6a +.section sgr6b +.section sgr7a +.section sgr7b +.section sgr8a +.section sgr8b +.section sgr9a +.section sgr9b +.section sgr0a +.section sgr0b +.section sgsaa +.section sgsab +.section sgsba +.section sgsbb +.section sgsca +.section sgscb +.section sgsda +.section sgsdb +.section sgsea +.section sgseb +.section sgsfa +.section sgsfb +.section sgsga +.section sgsgb +.section sgsha +.section sgshb +.section sgsia +.section sgsib +.section sgsja +.section sgsjb +.section sgska +.section sgskb +.section sgsla +.section sgslb +.section sgsma +.section sgsmb +.section sgsna +.section sgsnb +.section sgsoa +.section sgsob +.section sgspa +.section sgspb +.section sgsqa +.section sgsqb +.section sgsra +.section sgsrb +.section sgssa +.section sgssb +.section sgsta +.section sgstb +.section sgsua +.section sgsub +.section sgsva +.section sgsvb +.section sgswa +.section sgswb +.section sgsxa +.section sgsxb +.section sgsya +.section sgsyb +.section sgsza +.section sgszb +.section sgs1a +.section sgs1b +.section sgs2a +.section sgs2b +.section sgs3a +.section sgs3b +.section sgs4a +.section sgs4b +.section sgs5a +.section sgs5b +.section sgs6a +.section sgs6b +.section sgs7a +.section sgs7b +.section sgs8a +.section sgs8b +.section sgs9a +.section sgs9b +.section sgs0a +.section sgs0b +.section sgtaa +.section sgtab +.section sgtba +.section sgtbb +.section sgtca +.section sgtcb +.section sgtda +.section sgtdb +.section sgtea +.section sgteb +.section sgtfa +.section sgtfb +.section sgtga +.section sgtgb +.section sgtha +.section sgthb +.section sgtia +.section sgtib +.section sgtja +.section sgtjb +.section sgtka +.section sgtkb +.section sgtla +.section sgtlb +.section sgtma +.section sgtmb +.section sgtna +.section sgtnb +.section sgtoa +.section sgtob +.section sgtpa +.section sgtpb +.section sgtqa +.section sgtqb +.section sgtra +.section sgtrb +.section sgtsa +.section sgtsb +.section sgtta +.section sgttb +.section sgtua +.section sgtub +.section sgtva +.section sgtvb +.section sgtwa +.section sgtwb +.section sgtxa +.section sgtxb +.section sgtya +.section sgtyb +.section sgtza +.section sgtzb +.section sgt1a +.section sgt1b +.section sgt2a +.section sgt2b +.section sgt3a +.section sgt3b +.section sgt4a +.section sgt4b +.section sgt5a +.section sgt5b +.section sgt6a +.section sgt6b +.section sgt7a +.section sgt7b +.section sgt8a +.section sgt8b +.section sgt9a +.section sgt9b +.section sgt0a +.section sgt0b +.section sguaa +.section sguab +.section sguba +.section sgubb +.section sguca +.section sgucb +.section sguda +.section sgudb +.section sguea +.section sgueb +.section sgufa +.section sgufb +.section sguga +.section sgugb +.section sguha +.section sguhb +.section sguia +.section sguib +.section sguja +.section sgujb +.section sguka +.section sgukb +.section sgula +.section sgulb +.section sguma +.section sgumb +.section sguna +.section sgunb +.section sguoa +.section sguob +.section sgupa +.section sgupb +.section sguqa +.section sguqb +.section sgura +.section sgurb +.section sgusa +.section sgusb +.section sguta +.section sgutb +.section sguua +.section sguub +.section sguva +.section sguvb +.section sguwa +.section sguwb +.section sguxa +.section sguxb +.section sguya +.section sguyb +.section sguza +.section sguzb +.section sgu1a +.section sgu1b +.section sgu2a +.section sgu2b +.section sgu3a +.section sgu3b +.section sgu4a +.section sgu4b +.section sgu5a +.section sgu5b +.section sgu6a +.section sgu6b +.section sgu7a +.section sgu7b +.section sgu8a +.section sgu8b +.section sgu9a +.section sgu9b +.section sgu0a +.section sgu0b +.section sgvaa +.section sgvab +.section sgvba +.section sgvbb +.section sgvca +.section sgvcb +.section sgvda +.section sgvdb +.section sgvea +.section sgveb +.section sgvfa +.section sgvfb +.section sgvga +.section sgvgb +.section sgvha +.section sgvhb +.section sgvia +.section sgvib +.section sgvja +.section sgvjb +.section sgvka +.section sgvkb +.section sgvla +.section sgvlb +.section sgvma +.section sgvmb +.section sgvna +.section sgvnb +.section sgvoa +.section sgvob +.section sgvpa +.section sgvpb +.section sgvqa +.section sgvqb +.section sgvra +.section sgvrb +.section sgvsa +.section sgvsb +.section sgvta +.section sgvtb +.section sgvua +.section sgvub +.section sgvva +.section sgvvb +.section sgvwa +.section sgvwb +.section sgvxa +.section sgvxb +.section sgvya +.section sgvyb +.section sgvza +.section sgvzb +.section sgv1a +.section sgv1b +.section sgv2a +.section sgv2b +.section sgv3a +.section sgv3b +.section sgv4a +.section sgv4b +.section sgv5a +.section sgv5b +.section sgv6a +.section sgv6b +.section sgv7a +.section sgv7b +.section sgv8a +.section sgv8b +.section sgv9a +.section sgv9b +.section sgv0a +.section sgv0b +.section sgwaa +.section sgwab +.section sgwba +.section sgwbb +.section sgwca +.section sgwcb +.section sgwda +.section sgwdb +.section sgwea +.section sgweb +.section sgwfa +.section sgwfb +.section sgwga +.section sgwgb +.section sgwha +.section sgwhb +.section sgwia +.section sgwib +.section sgwja +.section sgwjb +.section sgwka +.section sgwkb +.section sgwla +.section sgwlb +.section sgwma +.section sgwmb +.section sgwna +.section sgwnb +.section sgwoa +.section sgwob +.section sgwpa +.section sgwpb +.section sgwqa +.section sgwqb +.section sgwra +.section sgwrb +.section sgwsa +.section sgwsb +.section sgwta +.section sgwtb +.section sgwua +.section sgwub +.section sgwva +.section sgwvb +.section sgwwa +.section sgwwb +.section sgwxa +.section sgwxb +.section sgwya +.section sgwyb +.section sgwza +.section sgwzb +.section sgw1a +.section sgw1b +.section sgw2a +.section sgw2b +.section sgw3a +.section sgw3b +.section sgw4a +.section sgw4b +.section sgw5a +.section sgw5b +.section sgw6a +.section sgw6b +.section sgw7a +.section sgw7b +.section sgw8a +.section sgw8b +.section sgw9a +.section sgw9b +.section sgw0a +.section sgw0b +.section sgxaa +.section sgxab +.section sgxba +.section sgxbb +.section sgxca +.section sgxcb +.section sgxda +.section sgxdb +.section sgxea +.section sgxeb +.section sgxfa +.section sgxfb +.section sgxga +.section sgxgb +.section sgxha +.section sgxhb +.section sgxia +.section sgxib +.section sgxja +.section sgxjb +.section sgxka +.section sgxkb +.section sgxla +.section sgxlb +.section sgxma +.section sgxmb +.section sgxna +.section sgxnb +.section sgxoa +.section sgxob +.section sgxpa +.section sgxpb +.section sgxqa +.section sgxqb +.section sgxra +.section sgxrb +.section sgxsa +.section sgxsb +.section sgxta +.section sgxtb +.section sgxua +.section sgxub +.section sgxva +.section sgxvb +.section sgxwa +.section sgxwb +.section sgxxa +.section sgxxb +.section sgxya +.section sgxyb +.section sgxza +.section sgxzb +.section sgx1a +.section sgx1b +.section sgx2a +.section sgx2b +.section sgx3a +.section sgx3b +.section sgx4a +.section sgx4b +.section sgx5a +.section sgx5b +.section sgx6a +.section sgx6b +.section sgx7a +.section sgx7b +.section sgx8a +.section sgx8b +.section sgx9a +.section sgx9b +.section sgx0a +.section sgx0b +.section sgyaa +.section sgyab +.section sgyba +.section sgybb +.section sgyca +.section sgycb +.section sgyda +.section sgydb +.section sgyea +.section sgyeb +.section sgyfa +.section sgyfb +.section sgyga +.section sgygb +.section sgyha +.section sgyhb +.section sgyia +.section sgyib +.section sgyja +.section sgyjb +.section sgyka +.section sgykb +.section sgyla +.section sgylb +.section sgyma +.section sgymb +.section sgyna +.section sgynb +.section sgyoa +.section sgyob +.section sgypa +.section sgypb +.section sgyqa +.section sgyqb +.section sgyra +.section sgyrb +.section sgysa +.section sgysb +.section sgyta +.section sgytb +.section sgyua +.section sgyub +.section sgyva +.section sgyvb +.section sgywa +.section sgywb +.section sgyxa +.section sgyxb +.section sgyya +.section sgyyb +.section sgyza +.section sgyzb +.section sgy1a +.section sgy1b +.section sgy2a +.section sgy2b +.section sgy3a +.section sgy3b +.section sgy4a +.section sgy4b +.section sgy5a +.section sgy5b +.section sgy6a +.section sgy6b +.section sgy7a +.section sgy7b +.section sgy8a +.section sgy8b +.section sgy9a +.section sgy9b +.section sgy0a +.section sgy0b +.section sgzaa +.section sgzab +.section sgzba +.section sgzbb +.section sgzca +.section sgzcb +.section sgzda +.section sgzdb +.section sgzea +.section sgzeb +.section sgzfa +.section sgzfb +.section sgzga +.section sgzgb +.section sgzha +.section sgzhb +.section sgzia +.section sgzib +.section sgzja +.section sgzjb +.section sgzka +.section sgzkb +.section sgzla +.section sgzlb +.section sgzma +.section sgzmb +.section sgzna +.section sgznb +.section sgzoa +.section sgzob +.section sgzpa +.section sgzpb +.section sgzqa +.section sgzqb +.section sgzra +.section sgzrb +.section sgzsa +.section sgzsb +.section sgzta +.section sgztb +.section sgzua +.section sgzub +.section sgzva +.section sgzvb +.section sgzwa +.section sgzwb +.section sgzxa +.section sgzxb +.section sgzya +.section sgzyb +.section sgzza +.section sgzzb +.section sgz1a +.section sgz1b +.section sgz2a +.section sgz2b +.section sgz3a +.section sgz3b +.section sgz4a +.section sgz4b +.section sgz5a +.section sgz5b +.section sgz6a +.section sgz6b +.section sgz7a +.section sgz7b +.section sgz8a +.section sgz8b +.section sgz9a +.section sgz9b +.section sgz0a +.section sgz0b +.section sg1aa +.section sg1ab +.section sg1ba +.section sg1bb +.section sg1ca +.section sg1cb +.section sg1da +.section sg1db +.section sg1ea +.section sg1eb +.section sg1fa +.section sg1fb +.section sg1ga +.section sg1gb +.section sg1ha +.section sg1hb +.section sg1ia +.section sg1ib +.section sg1ja +.section sg1jb +.section sg1ka +.section sg1kb +.section sg1la +.section sg1lb +.section sg1ma +.section sg1mb +.section sg1na +.section sg1nb +.section sg1oa +.section sg1ob +.section sg1pa +.section sg1pb +.section sg1qa +.section sg1qb +.section sg1ra +.section sg1rb +.section sg1sa +.section sg1sb +.section sg1ta +.section sg1tb +.section sg1ua +.section sg1ub +.section sg1va +.section sg1vb +.section sg1wa +.section sg1wb +.section sg1xa +.section sg1xb +.section sg1ya +.section sg1yb +.section sg1za +.section sg1zb +.section sg11a +.section sg11b +.section sg12a +.section sg12b +.section sg13a +.section sg13b +.section sg14a +.section sg14b +.section sg15a +.section sg15b +.section sg16a +.section sg16b +.section sg17a +.section sg17b +.section sg18a +.section sg18b +.section sg19a +.section sg19b +.section sg10a +.section sg10b +.section sg2aa +.section sg2ab +.section sg2ba +.section sg2bb +.section sg2ca +.section sg2cb +.section sg2da +.section sg2db +.section sg2ea +.section sg2eb +.section sg2fa +.section sg2fb +.section sg2ga +.section sg2gb +.section sg2ha +.section sg2hb +.section sg2ia +.section sg2ib +.section sg2ja +.section sg2jb +.section sg2ka +.section sg2kb +.section sg2la +.section sg2lb +.section sg2ma +.section sg2mb +.section sg2na +.section sg2nb +.section sg2oa +.section sg2ob +.section sg2pa +.section sg2pb +.section sg2qa +.section sg2qb +.section sg2ra +.section sg2rb +.section sg2sa +.section sg2sb +.section sg2ta +.section sg2tb +.section sg2ua +.section sg2ub +.section sg2va +.section sg2vb +.section sg2wa +.section sg2wb +.section sg2xa +.section sg2xb +.section sg2ya +.section sg2yb +.section sg2za +.section sg2zb +.section sg21a +.section sg21b +.section sg22a +.section sg22b +.section sg23a +.section sg23b +.section sg24a +.section sg24b +.section sg25a +.section sg25b +.section sg26a +.section sg26b +.section sg27a +.section sg27b +.section sg28a +.section sg28b +.section sg29a +.section sg29b +.section sg20a +.section sg20b +.section sg3aa +.section sg3ab +.section sg3ba +.section sg3bb +.section sg3ca +.section sg3cb +.section sg3da +.section sg3db +.section sg3ea +.section sg3eb +.section sg3fa +.section sg3fb +.section sg3ga +.section sg3gb +.section sg3ha +.section sg3hb +.section sg3ia +.section sg3ib +.section sg3ja +.section sg3jb +.section sg3ka +.section sg3kb +.section sg3la +.section sg3lb +.section sg3ma +.section sg3mb +.section sg3na +.section sg3nb +.section sg3oa +.section sg3ob +.section sg3pa +.section sg3pb +.section sg3qa +.section sg3qb +.section sg3ra +.section sg3rb +.section sg3sa +.section sg3sb +.section sg3ta +.section sg3tb +.section sg3ua +.section sg3ub +.section sg3va +.section sg3vb +.section sg3wa +.section sg3wb +.section sg3xa +.section sg3xb +.section sg3ya +.section sg3yb +.section sg3za +.section sg3zb +.section sg31a +.section sg31b +.section sg32a +.section sg32b +.section sg33a +.section sg33b +.section sg34a +.section sg34b +.section sg35a +.section sg35b +.section sg36a +.section sg36b +.section sg37a +.section sg37b +.section sg38a +.section sg38b +.section sg39a +.section sg39b +.section sg30a +.section sg30b +.section sg4aa +.section sg4ab +.section sg4ba +.section sg4bb +.section sg4ca +.section sg4cb +.section sg4da +.section sg4db +.section sg4ea +.section sg4eb +.section sg4fa +.section sg4fb +.section sg4ga +.section sg4gb +.section sg4ha +.section sg4hb +.section sg4ia +.section sg4ib +.section sg4ja +.section sg4jb +.section sg4ka +.section sg4kb +.section sg4la +.section sg4lb +.section sg4ma +.section sg4mb +.section sg4na +.section sg4nb +.section sg4oa +.section sg4ob +.section sg4pa +.section sg4pb +.section sg4qa +.section sg4qb +.section sg4ra +.section sg4rb +.section sg4sa +.section sg4sb +.section sg4ta +.section sg4tb +.section sg4ua +.section sg4ub +.section sg4va +.section sg4vb +.section sg4wa +.section sg4wb +.section sg4xa +.section sg4xb +.section sg4ya +.section sg4yb +.section sg4za +.section sg4zb +.section sg41a +.section sg41b +.section sg42a +.section sg42b +.section sg43a +.section sg43b +.section sg44a +.section sg44b +.section sg45a +.section sg45b +.section sg46a +.section sg46b +.section sg47a +.section sg47b +.section sg48a +.section sg48b +.section sg49a +.section sg49b +.section sg40a +.section sg40b +.section sg5aa +.section sg5ab +.section sg5ba +.section sg5bb +.section sg5ca +.section sg5cb +.section sg5da +.section sg5db +.section sg5ea +.section sg5eb +.section sg5fa +.section sg5fb +.section sg5ga +.section sg5gb +.section sg5ha +.section sg5hb +.section sg5ia +.section sg5ib +.section sg5ja +.section sg5jb +.section sg5ka +.section sg5kb +.section sg5la +.section sg5lb +.section sg5ma +.section sg5mb +.section sg5na +.section sg5nb +.section sg5oa +.section sg5ob +.section sg5pa +.section sg5pb +.section sg5qa +.section sg5qb +.section sg5ra +.section sg5rb +.section sg5sa +.section sg5sb +.section sg5ta +.section sg5tb +.section sg5ua +.section sg5ub +.section sg5va +.section sg5vb +.section sg5wa +.section sg5wb +.section sg5xa +.section sg5xb +.section sg5ya +.section sg5yb +.section sg5za +.section sg5zb +.section sg51a +.section sg51b +.section sg52a +.section sg52b +.section sg53a +.section sg53b +.section sg54a +.section sg54b +.section sg55a +.section sg55b +.section sg56a +.section sg56b +.section sg57a +.section sg57b +.section sg58a +.section sg58b +.section sg59a +.section sg59b +.section sg50a +.section sg50b +.section sg6aa +.section sg6ab +.section sg6ba +.section sg6bb +.section sg6ca +.section sg6cb +.section sg6da +.section sg6db +.section sg6ea +.section sg6eb +.section sg6fa +.section sg6fb +.section sg6ga +.section sg6gb +.section sg6ha +.section sg6hb +.section sg6ia +.section sg6ib +.section sg6ja +.section sg6jb +.section sg6ka +.section sg6kb +.section sg6la +.section sg6lb +.section sg6ma +.section sg6mb +.section sg6na +.section sg6nb +.section sg6oa +.section sg6ob +.section sg6pa +.section sg6pb +.section sg6qa +.section sg6qb +.section sg6ra +.section sg6rb +.section sg6sa +.section sg6sb +.section sg6ta +.section sg6tb +.section sg6ua +.section sg6ub +.section sg6va +.section sg6vb +.section sg6wa +.section sg6wb +.section sg6xa +.section sg6xb +.section sg6ya +.section sg6yb +.section sg6za +.section sg6zb +.section sg61a +.section sg61b +.section sg62a +.section sg62b +.section sg63a +.section sg63b +.section sg64a +.section sg64b +.section sg65a +.section sg65b +.section sg66a +.section sg66b +.section sg67a +.section sg67b +.section sg68a +.section sg68b +.section sg69a +.section sg69b +.section sg60a +.section sg60b +.section sg7aa +.section sg7ab +.section sg7ba +.section sg7bb +.section sg7ca +.section sg7cb +.section sg7da +.section sg7db +.section sg7ea +.section sg7eb +.section sg7fa +.section sg7fb +.section sg7ga +.section sg7gb +.section sg7ha +.section sg7hb +.section sg7ia +.section sg7ib +.section sg7ja +.section sg7jb +.section sg7ka +.section sg7kb +.section sg7la +.section sg7lb +.section sg7ma +.section sg7mb +.section sg7na +.section sg7nb +.section sg7oa +.section sg7ob +.section sg7pa +.section sg7pb +.section sg7qa +.section sg7qb +.section sg7ra +.section sg7rb +.section sg7sa +.section sg7sb +.section sg7ta +.section sg7tb +.section sg7ua +.section sg7ub +.section sg7va +.section sg7vb +.section sg7wa +.section sg7wb +.section sg7xa +.section sg7xb +.section sg7ya +.section sg7yb +.section sg7za +.section sg7zb +.section sg71a +.section sg71b +.section sg72a +.section sg72b +.section sg73a +.section sg73b +.section sg74a +.section sg74b +.section sg75a +.section sg75b +.section sg76a +.section sg76b +.section sg77a +.section sg77b +.section sg78a +.section sg78b +.section sg79a +.section sg79b +.section sg70a +.section sg70b +.section sg8aa +.section sg8ab +.section sg8ba +.section sg8bb +.section sg8ca +.section sg8cb +.section sg8da +.section sg8db +.section sg8ea +.section sg8eb +.section sg8fa +.section sg8fb +.section sg8ga +.section sg8gb +.section sg8ha +.section sg8hb +.section sg8ia +.section sg8ib +.section sg8ja +.section sg8jb +.section sg8ka +.section sg8kb +.section sg8la +.section sg8lb +.section sg8ma +.section sg8mb +.section sg8na +.section sg8nb +.section sg8oa +.section sg8ob +.section sg8pa +.section sg8pb +.section sg8qa +.section sg8qb +.section sg8ra +.section sg8rb +.section sg8sa +.section sg8sb +.section sg8ta +.section sg8tb +.section sg8ua +.section sg8ub +.section sg8va +.section sg8vb +.section sg8wa +.section sg8wb +.section sg8xa +.section sg8xb +.section sg8ya +.section sg8yb +.section sg8za +.section sg8zb +.section sg81a +.section sg81b +.section sg82a +.section sg82b +.section sg83a +.section sg83b +.section sg84a +.section sg84b +.section sg85a +.section sg85b +.section sg86a +.section sg86b +.section sg87a +.section sg87b +.section sg88a +.section sg88b +.section sg89a +.section sg89b +.section sg80a +.section sg80b +.section sg9aa +.section sg9ab +.section sg9ba +.section sg9bb +.section sg9ca +.section sg9cb +.section sg9da +.section sg9db +.section sg9ea +.section sg9eb +.section sg9fa +.section sg9fb +.section sg9ga +.section sg9gb +.section sg9ha +.section sg9hb +.section sg9ia +.section sg9ib +.section sg9ja +.section sg9jb +.section sg9ka +.section sg9kb +.section sg9la +.section sg9lb +.section sg9ma +.section sg9mb +.section sg9na +.section sg9nb +.section sg9oa +.section sg9ob +.section sg9pa +.section sg9pb +.section sg9qa +.section sg9qb +.section sg9ra +.section sg9rb +.section sg9sa +.section sg9sb +.section sg9ta +.section sg9tb +.section sg9ua +.section sg9ub +.section sg9va +.section sg9vb +.section sg9wa +.section sg9wb +.section sg9xa +.section sg9xb +.section sg9ya +.section sg9yb +.section sg9za +.section sg9zb +.section sg91a +.section sg91b +.section sg92a +.section sg92b +.section sg93a +.section sg93b +.section sg94a +.section sg94b +.section sg95a +.section sg95b +.section sg96a +.section sg96b +.section sg97a +.section sg97b +.section sg98a +.section sg98b +.section sg99a +.section sg99b +.section sg90a +.section sg90b +.section sg0aa +.section sg0ab +.section sg0ba +.section sg0bb +.section sg0ca +.section sg0cb +.section sg0da +.section sg0db +.section sg0ea +.section sg0eb +.section sg0fa +.section sg0fb +.section sg0ga +.section sg0gb +.section sg0ha +.section sg0hb +.section sg0ia +.section sg0ib +.section sg0ja +.section sg0jb +.section sg0ka +.section sg0kb +.section sg0la +.section sg0lb +.section sg0ma +.section sg0mb +.section sg0na +.section sg0nb +.section sg0oa +.section sg0ob +.section sg0pa +.section sg0pb +.section sg0qa +.section sg0qb +.section sg0ra +.section sg0rb +.section sg0sa +.section sg0sb +.section sg0ta +.section sg0tb +.section sg0ua +.section sg0ub +.section sg0va +.section sg0vb +.section sg0wa +.section sg0wb +.section sg0xa +.section sg0xb +.section sg0ya +.section sg0yb +.section sg0za +.section sg0zb +.section sg01a +.section sg01b +.section sg02a +.section sg02b +.section sg03a +.section sg03b +.section sg04a +.section sg04b +.section sg05a +.section sg05b +.section sg06a +.section sg06b +.section sg07a +.section sg07b +.section sg08a +.section sg08b +.section sg09a +.section sg09b +.section sg00a +.section sg00b +.section shaaa +.section shaab +.section shaba +.section shabb +.section shaca +.section shacb +.section shada +.section shadb +.section shaea +.section shaeb +.section shafa +.section shafb +.section shaga +.section shagb +.section shaha +.section shahb +.section shaia +.section shaib +.section shaja +.section shajb +.section shaka +.section shakb +.section shala +.section shalb +.section shama +.section shamb +.section shana +.section shanb +.section shaoa +.section shaob +.section shapa +.section shapb +.section shaqa +.section shaqb +.section shara +.section sharb +.section shasa +.section shasb +.section shata +.section shatb +.section shaua +.section shaub +.section shava +.section shavb +.section shawa +.section shawb +.section shaxa +.section shaxb +.section shaya +.section shayb +.section shaza +.section shazb +.section sha1a +.section sha1b +.section sha2a +.section sha2b +.section sha3a +.section sha3b +.section sha4a +.section sha4b +.section sha5a +.section sha5b +.section sha6a +.section sha6b +.section sha7a +.section sha7b +.section sha8a +.section sha8b +.section sha9a +.section sha9b +.section sha0a +.section sha0b +.section shbaa +.section shbab +.section shbba +.section shbbb +.section shbca +.section shbcb +.section shbda +.section shbdb +.section shbea +.section shbeb +.section shbfa +.section shbfb +.section shbga +.section shbgb +.section shbha +.section shbhb +.section shbia +.section shbib +.section shbja +.section shbjb +.section shbka +.section shbkb +.section shbla +.section shblb +.section shbma +.section shbmb +.section shbna +.section shbnb +.section shboa +.section shbob +.section shbpa +.section shbpb +.section shbqa +.section shbqb +.section shbra +.section shbrb +.section shbsa +.section shbsb +.section shbta +.section shbtb +.section shbua +.section shbub +.section shbva +.section shbvb +.section shbwa +.section shbwb +.section shbxa +.section shbxb +.section shbya +.section shbyb +.section shbza +.section shbzb +.section shb1a +.section shb1b +.section shb2a +.section shb2b +.section shb3a +.section shb3b +.section shb4a +.section shb4b +.section shb5a +.section shb5b +.section shb6a +.section shb6b +.section shb7a +.section shb7b +.section shb8a +.section shb8b +.section shb9a +.section shb9b +.section shb0a +.section shb0b +.section shcaa +.section shcab +.section shcba +.section shcbb +.section shcca +.section shccb +.section shcda +.section shcdb +.section shcea +.section shceb +.section shcfa +.section shcfb +.section shcga +.section shcgb +.section shcha +.section shchb +.section shcia +.section shcib +.section shcja +.section shcjb +.section shcka +.section shckb +.section shcla +.section shclb +.section shcma +.section shcmb +.section shcna +.section shcnb +.section shcoa +.section shcob +.section shcpa +.section shcpb +.section shcqa +.section shcqb +.section shcra +.section shcrb +.section shcsa +.section shcsb +.section shcta +.section shctb +.section shcua +.section shcub +.section shcva +.section shcvb +.section shcwa +.section shcwb +.section shcxa +.section shcxb +.section shcya +.section shcyb +.section shcza +.section shczb +.section shc1a +.section shc1b +.section shc2a +.section shc2b +.section shc3a +.section shc3b +.section shc4a +.section shc4b +.section shc5a +.section shc5b +.section shc6a +.section shc6b +.section shc7a +.section shc7b +.section shc8a +.section shc8b +.section shc9a +.section shc9b +.section shc0a +.section shc0b +.section shdaa +.section shdab +.section shdba +.section shdbb +.section shdca +.section shdcb +.section shdda +.section shddb +.section shdea +.section shdeb +.section shdfa +.section shdfb +.section shdga +.section shdgb +.section shdha +.section shdhb +.section shdia +.section shdib +.section shdja +.section shdjb +.section shdka +.section shdkb +.section shdla +.section shdlb +.section shdma +.section shdmb +.section shdna +.section shdnb +.section shdoa +.section shdob +.section shdpa +.section shdpb +.section shdqa +.section shdqb +.section shdra +.section shdrb +.section shdsa +.section shdsb +.section shdta +.section shdtb +.section shdua +.section shdub +.section shdva +.section shdvb +.section shdwa +.section shdwb +.section shdxa +.section shdxb +.section shdya +.section shdyb +.section shdza +.section shdzb +.section shd1a +.section shd1b +.section shd2a +.section shd2b +.section shd3a +.section shd3b +.section shd4a +.section shd4b +.section shd5a +.section shd5b +.section shd6a +.section shd6b +.section shd7a +.section shd7b +.section shd8a +.section shd8b +.section shd9a +.section shd9b +.section shd0a +.section shd0b +.section sheaa +.section sheab +.section sheba +.section shebb +.section sheca +.section shecb +.section sheda +.section shedb +.section sheea +.section sheeb +.section shefa +.section shefb +.section shega +.section shegb +.section sheha +.section shehb +.section sheia +.section sheib +.section sheja +.section shejb +.section sheka +.section shekb +.section shela +.section shelb +.section shema +.section shemb +.section shena +.section shenb +.section sheoa +.section sheob +.section shepa +.section shepb +.section sheqa +.section sheqb +.section shera +.section sherb +.section shesa +.section shesb +.section sheta +.section shetb +.section sheua +.section sheub +.section sheva +.section shevb +.section shewa +.section shewb +.section shexa +.section shexb +.section sheya +.section sheyb +.section sheza +.section shezb +.section she1a +.section she1b +.section she2a +.section she2b +.section she3a +.section she3b +.section she4a +.section she4b +.section she5a +.section she5b +.section she6a +.section she6b +.section she7a +.section she7b +.section she8a +.section she8b +.section she9a +.section she9b +.section she0a +.section she0b +.section shfaa +.section shfab +.section shfba +.section shfbb +.section shfca +.section shfcb +.section shfda +.section shfdb +.section shfea +.section shfeb +.section shffa +.section shffb +.section shfga +.section shfgb +.section shfha +.section shfhb +.section shfia +.section shfib +.section shfja +.section shfjb +.section shfka +.section shfkb +.section shfla +.section shflb +.section shfma +.section shfmb +.section shfna +.section shfnb +.section shfoa +.section shfob +.section shfpa +.section shfpb +.section shfqa +.section shfqb +.section shfra +.section shfrb +.section shfsa +.section shfsb +.section shfta +.section shftb +.section shfua +.section shfub +.section shfva +.section shfvb +.section shfwa +.section shfwb +.section shfxa +.section shfxb +.section shfya +.section shfyb +.section shfza +.section shfzb +.section shf1a +.section shf1b +.section shf2a +.section shf2b +.section shf3a +.section shf3b +.section shf4a +.section shf4b +.section shf5a +.section shf5b +.section shf6a +.section shf6b +.section shf7a +.section shf7b +.section shf8a +.section shf8b +.section shf9a +.section shf9b +.section shf0a +.section shf0b +.section shgaa +.section shgab +.section shgba +.section shgbb +.section shgca +.section shgcb +.section shgda +.section shgdb +.section shgea +.section shgeb +.section shgfa +.section shgfb +.section shgga +.section shggb +.section shgha +.section shghb +.section shgia +.section shgib +.section shgja +.section shgjb +.section shgka +.section shgkb +.section shgla +.section shglb +.section shgma +.section shgmb +.section shgna +.section shgnb +.section shgoa +.section shgob +.section shgpa +.section shgpb +.section shgqa +.section shgqb +.section shgra +.section shgrb +.section shgsa +.section shgsb +.section shgta +.section shgtb +.section shgua +.section shgub +.section shgva +.section shgvb +.section shgwa +.section shgwb +.section shgxa +.section shgxb +.section shgya +.section shgyb +.section shgza +.section shgzb +.section shg1a +.section shg1b +.section shg2a +.section shg2b +.section shg3a +.section shg3b +.section shg4a +.section shg4b +.section shg5a +.section shg5b +.section shg6a +.section shg6b +.section shg7a +.section shg7b +.section shg8a +.section shg8b +.section shg9a +.section shg9b +.section shg0a +.section shg0b +.section shhaa +.section shhab +.section shhba +.section shhbb +.section shhca +.section shhcb +.section shhda +.section shhdb +.section shhea +.section shheb +.section shhfa +.section shhfb +.section shhga +.section shhgb +.section shhha +.section shhhb +.section shhia +.section shhib +.section shhja +.section shhjb +.section shhka +.section shhkb +.section shhla +.section shhlb +.section shhma +.section shhmb +.section shhna +.section shhnb +.section shhoa +.section shhob +.section shhpa +.section shhpb +.section shhqa +.section shhqb +.section shhra +.section shhrb +.section shhsa +.section shhsb +.section shhta +.section shhtb +.section shhua +.section shhub +.section shhva +.section shhvb +.section shhwa +.section shhwb +.section shhxa +.section shhxb +.section shhya +.section shhyb +.section shhza +.section shhzb +.section shh1a +.section shh1b +.section shh2a +.section shh2b +.section shh3a +.section shh3b +.section shh4a +.section shh4b +.section shh5a +.section shh5b +.section shh6a +.section shh6b +.section shh7a +.section shh7b +.section shh8a +.section shh8b +.section shh9a +.section shh9b +.section shh0a +.section shh0b +.section shiaa +.section shiab +.section shiba +.section shibb +.section shica +.section shicb +.section shida +.section shidb +.section shiea +.section shieb +.section shifa +.section shifb +.section shiga +.section shigb +.section shiha +.section shihb +.section shiia +.section shiib +.section shija +.section shijb +.section shika +.section shikb +.section shila +.section shilb +.section shima +.section shimb +.section shina +.section shinb +.section shioa +.section shiob +.section shipa +.section shipb +.section shiqa +.section shiqb +.section shira +.section shirb +.section shisa +.section shisb +.section shita +.section shitb +.section shiua +.section shiub +.section shiva +.section shivb +.section shiwa +.section shiwb +.section shixa +.section shixb +.section shiya +.section shiyb +.section shiza +.section shizb +.section shi1a +.section shi1b +.section shi2a +.section shi2b +.section shi3a +.section shi3b +.section shi4a +.section shi4b +.section shi5a +.section shi5b +.section shi6a +.section shi6b +.section shi7a +.section shi7b +.section shi8a +.section shi8b +.section shi9a +.section shi9b +.section shi0a +.section shi0b +.section shjaa +.section shjab +.section shjba +.section shjbb +.section shjca +.section shjcb +.section shjda +.section shjdb +.section shjea +.section shjeb +.section shjfa +.section shjfb +.section shjga +.section shjgb +.section shjha +.section shjhb +.section shjia +.section shjib +.section shjja +.section shjjb +.section shjka +.section shjkb +.section shjla +.section shjlb +.section shjma +.section shjmb +.section shjna +.section shjnb +.section shjoa +.section shjob +.section shjpa +.section shjpb +.section shjqa +.section shjqb +.section shjra +.section shjrb +.section shjsa +.section shjsb +.section shjta +.section shjtb +.section shjua +.section shjub +.section shjva +.section shjvb +.section shjwa +.section shjwb +.section shjxa +.section shjxb +.section shjya +.section shjyb +.section shjza +.section shjzb +.section shj1a +.section shj1b +.section shj2a +.section shj2b +.section shj3a +.section shj3b +.section shj4a +.section shj4b +.section shj5a +.section shj5b +.section shj6a +.section shj6b +.section shj7a +.section shj7b +.section shj8a +.section shj8b +.section shj9a +.section shj9b +.section shj0a +.section shj0b +.section shkaa +.section shkab +.section shkba +.section shkbb +.section shkca +.section shkcb +.section shkda +.section shkdb +.section shkea +.section shkeb +.section shkfa +.section shkfb +.section shkga +.section shkgb +.section shkha +.section shkhb +.section shkia +.section shkib +.section shkja +.section shkjb +.section shkka +.section shkkb +.section shkla +.section shklb +.section shkma +.section shkmb +.section shkna +.section shknb +.section shkoa +.section shkob +.section shkpa +.section shkpb +.section shkqa +.section shkqb +.section shkra +.section shkrb +.section shksa +.section shksb +.section shkta +.section shktb +.section shkua +.section shkub +.section shkva +.section shkvb +.section shkwa +.section shkwb +.section shkxa +.section shkxb +.section shkya +.section shkyb +.section shkza +.section shkzb +.section shk1a +.section shk1b +.section shk2a +.section shk2b +.section shk3a +.section shk3b +.section shk4a +.section shk4b +.section shk5a +.section shk5b +.section shk6a +.section shk6b +.section shk7a +.section shk7b +.section shk8a +.section shk8b +.section shk9a +.section shk9b +.section shk0a +.section shk0b +.section shlaa +.section shlab +.section shlba +.section shlbb +.section shlca +.section shlcb +.section shlda +.section shldb +.section shlea +.section shleb +.section shlfa +.section shlfb +.section shlga +.section shlgb +.section shlha +.section shlhb +.section shlia +.section shlib +.section shlja +.section shljb +.section shlka +.section shlkb +.section shlla +.section shllb +.section shlma +.section shlmb +.section shlna +.section shlnb +.section shloa +.section shlob +.section shlpa +.section shlpb +.section shlqa +.section shlqb +.section shlra +.section shlrb +.section shlsa +.section shlsb +.section shlta +.section shltb +.section shlua +.section shlub +.section shlva +.section shlvb +.section shlwa +.section shlwb +.section shlxa +.section shlxb +.section shlya +.section shlyb +.section shlza +.section shlzb +.section shl1a +.section shl1b +.section shl2a +.section shl2b +.section shl3a +.section shl3b +.section shl4a +.section shl4b +.section shl5a +.section shl5b +.section shl6a +.section shl6b +.section shl7a +.section shl7b +.section shl8a +.section shl8b +.section shl9a +.section shl9b +.section shl0a +.section shl0b +.section shmaa +.section shmab +.section shmba +.section shmbb +.section shmca +.section shmcb +.section shmda +.section shmdb +.section shmea +.section shmeb +.section shmfa +.section shmfb +.section shmga +.section shmgb +.section shmha +.section shmhb +.section shmia +.section shmib +.section shmja +.section shmjb +.section shmka +.section shmkb +.section shmla +.section shmlb +.section shmma +.section shmmb +.section shmna +.section shmnb +.section shmoa +.section shmob +.section shmpa +.section shmpb +.section shmqa +.section shmqb +.section shmra +.section shmrb +.section shmsa +.section shmsb +.section shmta +.section shmtb +.section shmua +.section shmub +.section shmva +.section shmvb +.section shmwa +.section shmwb +.section shmxa +.section shmxb +.section shmya +.section shmyb +.section shmza +.section shmzb +.section shm1a +.section shm1b +.section shm2a +.section shm2b +.section shm3a +.section shm3b +.section shm4a +.section shm4b +.section shm5a +.section shm5b +.section shm6a +.section shm6b +.section shm7a +.section shm7b +.section shm8a +.section shm8b +.section shm9a +.section shm9b +.section shm0a +.section shm0b +.section shnaa +.section shnab +.section shnba +.section shnbb +.section shnca +.section shncb +.section shnda +.section shndb +.section shnea +.section shneb +.section shnfa +.section shnfb +.section shnga +.section shngb +.section shnha +.section shnhb +.section shnia +.section shnib +.section shnja +.section shnjb +.section shnka +.section shnkb +.section shnla +.section shnlb +.section shnma +.section shnmb +.section shnna +.section shnnb +.section shnoa +.section shnob +.section shnpa +.section shnpb +.section shnqa +.section shnqb +.section shnra +.section shnrb +.section shnsa +.section shnsb +.section shnta +.section shntb +.section shnua +.section shnub +.section shnva +.section shnvb +.section shnwa +.section shnwb +.section shnxa +.section shnxb +.section shnya +.section shnyb +.section shnza +.section shnzb +.section shn1a +.section shn1b +.section shn2a +.section shn2b +.section shn3a +.section shn3b +.section shn4a +.section shn4b +.section shn5a +.section shn5b +.section shn6a +.section shn6b +.section shn7a +.section shn7b +.section shn8a +.section shn8b +.section shn9a +.section shn9b +.section shn0a +.section shn0b +.section shoaa +.section shoab +.section shoba +.section shobb +.section shoca +.section shocb +.section shoda +.section shodb +.section shoea +.section shoeb +.section shofa +.section shofb +.section shoga +.section shogb +.section shoha +.section shohb +.section shoia +.section shoib +.section shoja +.section shojb +.section shoka +.section shokb +.section shola +.section sholb +.section shoma +.section shomb +.section shona +.section shonb +.section shooa +.section shoob +.section shopa +.section shopb +.section shoqa +.section shoqb +.section shora +.section shorb +.section shosa +.section shosb +.section shota +.section shotb +.section shoua +.section shoub +.section shova +.section shovb +.section showa +.section showb +.section shoxa +.section shoxb +.section shoya +.section shoyb +.section shoza +.section shozb +.section sho1a +.section sho1b +.section sho2a +.section sho2b +.section sho3a +.section sho3b +.section sho4a +.section sho4b +.section sho5a +.section sho5b +.section sho6a +.section sho6b +.section sho7a +.section sho7b +.section sho8a +.section sho8b +.section sho9a +.section sho9b +.section sho0a +.section sho0b +.section shpaa +.section shpab +.section shpba +.section shpbb +.section shpca +.section shpcb +.section shpda +.section shpdb +.section shpea +.section shpeb +.section shpfa +.section shpfb +.section shpga +.section shpgb +.section shpha +.section shphb +.section shpia +.section shpib +.section shpja +.section shpjb +.section shpka +.section shpkb +.section shpla +.section shplb +.section shpma +.section shpmb +.section shpna +.section shpnb +.section shpoa +.section shpob +.section shppa +.section shppb +.section shpqa +.section shpqb +.section shpra +.section shprb +.section shpsa +.section shpsb +.section shpta +.section shptb +.section shpua +.section shpub +.section shpva +.section shpvb +.section shpwa +.section shpwb +.section shpxa +.section shpxb +.section shpya +.section shpyb +.section shpza +.section shpzb +.section shp1a +.section shp1b +.section shp2a +.section shp2b +.section shp3a +.section shp3b +.section shp4a +.section shp4b +.section shp5a +.section shp5b +.section shp6a +.section shp6b +.section shp7a +.section shp7b +.section shp8a +.section shp8b +.section shp9a +.section shp9b +.section shp0a +.section shp0b +.section shqaa +.section shqab +.section shqba +.section shqbb +.section shqca +.section shqcb +.section shqda +.section shqdb +.section shqea +.section shqeb +.section shqfa +.section shqfb +.section shqga +.section shqgb +.section shqha +.section shqhb +.section shqia +.section shqib +.section shqja +.section shqjb +.section shqka +.section shqkb +.section shqla +.section shqlb +.section shqma +.section shqmb +.section shqna +.section shqnb +.section shqoa +.section shqob +.section shqpa +.section shqpb +.section shqqa +.section shqqb +.section shqra +.section shqrb +.section shqsa +.section shqsb +.section shqta +.section shqtb +.section shqua +.section shqub +.section shqva +.section shqvb +.section shqwa +.section shqwb +.section shqxa +.section shqxb +.section shqya +.section shqyb +.section shqza +.section shqzb +.section shq1a +.section shq1b +.section shq2a +.section shq2b +.section shq3a +.section shq3b +.section shq4a +.section shq4b +.section shq5a +.section shq5b +.section shq6a +.section shq6b +.section shq7a +.section shq7b +.section shq8a +.section shq8b +.section shq9a +.section shq9b +.section shq0a +.section shq0b +.section shraa +.section shrab +.section shrba +.section shrbb +.section shrca +.section shrcb +.section shrda +.section shrdb +.section shrea +.section shreb +.section shrfa +.section shrfb +.section shrga +.section shrgb +.section shrha +.section shrhb +.section shria +.section shrib +.section shrja +.section shrjb +.section shrka +.section shrkb +.section shrla +.section shrlb +.section shrma +.section shrmb +.section shrna +.section shrnb +.section shroa +.section shrob +.section shrpa +.section shrpb +.section shrqa +.section shrqb +.section shrra +.section shrrb +.section shrsa +.section shrsb +.section shrta +.section shrtb +.section shrua +.section shrub +.section shrva +.section shrvb +.section shrwa +.section shrwb +.section shrxa +.section shrxb +.section shrya +.section shryb +.section shrza +.section shrzb +.section shr1a +.section shr1b +.section shr2a +.section shr2b +.section shr3a +.section shr3b +.section shr4a +.section shr4b +.section shr5a +.section shr5b +.section shr6a +.section shr6b +.section shr7a +.section shr7b +.section shr8a +.section shr8b +.section shr9a +.section shr9b +.section shr0a +.section shr0b +.section shsaa +.section shsab +.section shsba +.section shsbb +.section shsca +.section shscb +.section shsda +.section shsdb +.section shsea +.section shseb +.section shsfa +.section shsfb +.section shsga +.section shsgb +.section shsha +.section shshb +.section shsia +.section shsib +.section shsja +.section shsjb +.section shska +.section shskb +.section shsla +.section shslb +.section shsma +.section shsmb +.section shsna +.section shsnb +.section shsoa +.section shsob +.section shspa +.section shspb +.section shsqa +.section shsqb +.section shsra +.section shsrb +.section shssa +.section shssb +.section shsta +.section shstb +.section shsua +.section shsub +.section shsva +.section shsvb +.section shswa +.section shswb +.section shsxa +.section shsxb +.section shsya +.section shsyb +.section shsza +.section shszb +.section shs1a +.section shs1b +.section shs2a +.section shs2b +.section shs3a +.section shs3b +.section shs4a +.section shs4b +.section shs5a +.section shs5b +.section shs6a +.section shs6b +.section shs7a +.section shs7b +.section shs8a +.section shs8b +.section shs9a +.section shs9b +.section shs0a +.section shs0b +.section shtaa +.section shtab +.section shtba +.section shtbb +.section shtca +.section shtcb +.section shtda +.section shtdb +.section shtea +.section shteb +.section shtfa +.section shtfb +.section shtga +.section shtgb +.section shtha +.section shthb +.section shtia +.section shtib +.section shtja +.section shtjb +.section shtka +.section shtkb +.section shtla +.section shtlb +.section shtma +.section shtmb +.section shtna +.section shtnb +.section shtoa +.section shtob +.section shtpa +.section shtpb +.section shtqa +.section shtqb +.section shtra +.section shtrb +.section shtsa +.section shtsb +.section shtta +.section shttb +.section shtua +.section shtub +.section shtva +.section shtvb +.section shtwa +.section shtwb +.section shtxa +.section shtxb +.section shtya +.section shtyb +.section shtza +.section shtzb +.section sht1a +.section sht1b +.section sht2a +.section sht2b +.section sht3a +.section sht3b +.section sht4a +.section sht4b +.section sht5a +.section sht5b +.section sht6a +.section sht6b +.section sht7a +.section sht7b +.section sht8a +.section sht8b +.section sht9a +.section sht9b +.section sht0a +.section sht0b +.section shuaa +.section shuab +.section shuba +.section shubb +.section shuca +.section shucb +.section shuda +.section shudb +.section shuea +.section shueb +.section shufa +.section shufb +.section shuga +.section shugb +.section shuha +.section shuhb +.section shuia +.section shuib +.section shuja +.section shujb +.section shuka +.section shukb +.section shula +.section shulb +.section shuma +.section shumb +.section shuna +.section shunb +.section shuoa +.section shuob +.section shupa +.section shupb +.section shuqa +.section shuqb +.section shura +.section shurb +.section shusa +.section shusb +.section shuta +.section shutb +.section shuua +.section shuub +.section shuva +.section shuvb +.section shuwa +.section shuwb +.section shuxa +.section shuxb +.section shuya +.section shuyb +.section shuza +.section shuzb +.section shu1a +.section shu1b +.section shu2a +.section shu2b +.section shu3a +.section shu3b +.section shu4a +.section shu4b +.section shu5a +.section shu5b +.section shu6a +.section shu6b +.section shu7a +.section shu7b +.section shu8a +.section shu8b +.section shu9a +.section shu9b +.section shu0a +.section shu0b +.section shvaa +.section shvab +.section shvba +.section shvbb +.section shvca +.section shvcb +.section shvda +.section shvdb +.section shvea +.section shveb +.section shvfa +.section shvfb +.section shvga +.section shvgb +.section shvha +.section shvhb +.section shvia +.section shvib +.section shvja +.section shvjb +.section shvka +.section shvkb +.section shvla +.section shvlb +.section shvma +.section shvmb +.section shvna +.section shvnb +.section shvoa +.section shvob +.section shvpa +.section shvpb +.section shvqa +.section shvqb +.section shvra +.section shvrb +.section shvsa +.section shvsb +.section shvta +.section shvtb +.section shvua +.section shvub +.section shvva +.section shvvb +.section shvwa +.section shvwb +.section shvxa +.section shvxb +.section shvya +.section shvyb +.section shvza +.section shvzb +.section shv1a +.section shv1b +.section shv2a +.section shv2b +.section shv3a +.section shv3b +.section shv4a +.section shv4b +.section shv5a +.section shv5b +.section shv6a +.section shv6b +.section shv7a +.section shv7b +.section shv8a +.section shv8b +.section shv9a +.section shv9b +.section shv0a +.section shv0b +.section shwaa +.section shwab +.section shwba +.section shwbb +.section shwca +.section shwcb +.section shwda +.section shwdb +.section shwea +.section shweb +.section shwfa +.section shwfb +.section shwga +.section shwgb +.section shwha +.section shwhb +.section shwia +.section shwib +.section shwja +.section shwjb +.section shwka +.section shwkb +.section shwla +.section shwlb +.section shwma +.section shwmb +.section shwna +.section shwnb +.section shwoa +.section shwob +.section shwpa +.section shwpb +.section shwqa +.section shwqb +.section shwra +.section shwrb +.section shwsa +.section shwsb +.section shwta +.section shwtb +.section shwua +.section shwub +.section shwva +.section shwvb +.section shwwa +.section shwwb +.section shwxa +.section shwxb +.section shwya +.section shwyb +.section shwza +.section shwzb +.section shw1a +.section shw1b +.section shw2a +.section shw2b +.section shw3a +.section shw3b +.section shw4a +.section shw4b +.section shw5a +.section shw5b +.section shw6a +.section shw6b +.section shw7a +.section shw7b +.section shw8a +.section shw8b +.section shw9a +.section shw9b +.section shw0a +.section shw0b +.section shxaa +.section shxab +.section shxba +.section shxbb +.section shxca +.section shxcb +.section shxda +.section shxdb +.section shxea +.section shxeb +.section shxfa +.section shxfb +.section shxga +.section shxgb +.section shxha +.section shxhb +.section shxia +.section shxib +.section shxja +.section shxjb +.section shxka +.section shxkb +.section shxla +.section shxlb +.section shxma +.section shxmb +.section shxna +.section shxnb +.section shxoa +.section shxob +.section shxpa +.section shxpb +.section shxqa +.section shxqb +.section shxra +.section shxrb +.section shxsa +.section shxsb +.section shxta +.section shxtb +.section shxua +.section shxub +.section shxva +.section shxvb +.section shxwa +.section shxwb +.section shxxa +.section shxxb +.section shxya +.section shxyb +.section shxza +.section shxzb +.section shx1a +.section shx1b +.section shx2a +.section shx2b +.section shx3a +.section shx3b +.section shx4a +.section shx4b +.section shx5a +.section shx5b +.section shx6a +.section shx6b +.section shx7a +.section shx7b +.section shx8a +.section shx8b +.section shx9a +.section shx9b +.section shx0a +.section shx0b +.section shyaa +.section shyab +.section shyba +.section shybb +.section shyca +.section shycb +.section shyda +.section shydb +.section shyea +.section shyeb +.section shyfa +.section shyfb +.section shyga +.section shygb +.section shyha +.section shyhb +.section shyia +.section shyib +.section shyja +.section shyjb +.section shyka +.section shykb +.section shyla +.section shylb +.section shyma +.section shymb +.section shyna +.section shynb +.section shyoa +.section shyob +.section shypa +.section shypb +.section shyqa +.section shyqb +.section shyra +.section shyrb +.section shysa +.section shysb +.section shyta +.section shytb +.section shyua +.section shyub +.section shyva +.section shyvb +.section shywa +.section shywb +.section shyxa +.section shyxb +.section shyya +.section shyyb +.section shyza +.section shyzb +.section shy1a +.section shy1b +.section shy2a +.section shy2b +.section shy3a +.section shy3b +.section shy4a +.section shy4b +.section shy5a +.section shy5b +.section shy6a +.section shy6b +.section shy7a +.section shy7b +.section shy8a +.section shy8b +.section shy9a +.section shy9b +.section shy0a +.section shy0b +.section shzaa +.section shzab +.section shzba +.section shzbb +.section shzca +.section shzcb +.section shzda +.section shzdb +.section shzea +.section shzeb +.section shzfa +.section shzfb +.section shzga +.section shzgb +.section shzha +.section shzhb +.section shzia +.section shzib +.section shzja +.section shzjb +.section shzka +.section shzkb +.section shzla +.section shzlb +.section shzma +.section shzmb +.section shzna +.section shznb +.section shzoa +.section shzob +.section shzpa +.section shzpb +.section shzqa +.section shzqb +.section shzra +.section shzrb +.section shzsa +.section shzsb +.section shzta +.section shztb +.section shzua +.section shzub +.section shzva +.section shzvb +.section shzwa +.section shzwb +.section shzxa +.section shzxb +.section shzya +.section shzyb +.section shzza +.section shzzb +.section shz1a +.section shz1b +.section shz2a +.section shz2b +.section shz3a +.section shz3b +.section shz4a +.section shz4b +.section shz5a +.section shz5b +.section shz6a +.section shz6b +.section shz7a +.section shz7b +.section shz8a +.section shz8b +.section shz9a +.section shz9b +.section shz0a +.section shz0b +.section sh1aa +.section sh1ab +.section sh1ba +.section sh1bb +.section sh1ca +.section sh1cb +.section sh1da +.section sh1db +.section sh1ea +.section sh1eb +.section sh1fa +.section sh1fb +.section sh1ga +.section sh1gb +.section sh1ha +.section sh1hb +.section sh1ia +.section sh1ib +.section sh1ja +.section sh1jb +.section sh1ka +.section sh1kb +.section sh1la +.section sh1lb +.section sh1ma +.section sh1mb +.section sh1na +.section sh1nb +.section sh1oa +.section sh1ob +.section sh1pa +.section sh1pb +.section sh1qa +.section sh1qb +.section sh1ra +.section sh1rb +.section sh1sa +.section sh1sb +.section sh1ta +.section sh1tb +.section sh1ua +.section sh1ub +.section sh1va +.section sh1vb +.section sh1wa +.section sh1wb +.section sh1xa +.section sh1xb +.section sh1ya +.section sh1yb +.section sh1za +.section sh1zb +.section sh11a +.section sh11b +.section sh12a +.section sh12b +.section sh13a +.section sh13b +.section sh14a +.section sh14b +.section sh15a +.section sh15b +.section sh16a +.section sh16b +.section sh17a +.section sh17b +.section sh18a +.section sh18b +.section sh19a +.section sh19b +.section sh10a +.section sh10b +.section sh2aa +.section sh2ab +.section sh2ba +.section sh2bb +.section sh2ca +.section sh2cb +.section sh2da +.section sh2db +.section sh2ea +.section sh2eb +.section sh2fa +.section sh2fb +.section sh2ga +.section sh2gb +.section sh2ha +.section sh2hb +.section sh2ia +.section sh2ib +.section sh2ja +.section sh2jb +.section sh2ka +.section sh2kb +.section sh2la +.section sh2lb +.section sh2ma +.section sh2mb +.section sh2na +.section sh2nb +.section sh2oa +.section sh2ob +.section sh2pa +.section sh2pb +.section sh2qa +.section sh2qb +.section sh2ra +.section sh2rb +.section sh2sa +.section sh2sb +.section sh2ta +.section sh2tb +.section sh2ua +.section sh2ub +.section sh2va +.section sh2vb +.section sh2wa +.section sh2wb +.section sh2xa +.section sh2xb +.section sh2ya +.section sh2yb +.section sh2za +.section sh2zb +.section sh21a +.section sh21b +.section sh22a +.section sh22b +.section sh23a +.section sh23b +.section sh24a +.section sh24b +.section sh25a +.section sh25b +.section sh26a +.section sh26b +.section sh27a +.section sh27b +.section sh28a +.section sh28b +.section sh29a +.section sh29b +.section sh20a +.section sh20b +.section sh3aa +.section sh3ab +.section sh3ba +.section sh3bb +.section sh3ca +.section sh3cb +.section sh3da +.section sh3db +.section sh3ea +.section sh3eb +.section sh3fa +.section sh3fb +.section sh3ga +.section sh3gb +.section sh3ha +.section sh3hb +.section sh3ia +.section sh3ib +.section sh3ja +.section sh3jb +.section sh3ka +.section sh3kb +.section sh3la +.section sh3lb +.section sh3ma +.section sh3mb +.section sh3na +.section sh3nb +.section sh3oa +.section sh3ob +.section sh3pa +.section sh3pb +.section sh3qa +.section sh3qb +.section sh3ra +.section sh3rb +.section sh3sa +.section sh3sb +.section sh3ta +.section sh3tb +.section sh3ua +.section sh3ub +.section sh3va +.section sh3vb +.section sh3wa +.section sh3wb +.section sh3xa +.section sh3xb +.section sh3ya +.section sh3yb +.section sh3za +.section sh3zb +.section sh31a +.section sh31b +.section sh32a +.section sh32b +.section sh33a +.section sh33b +.section sh34a +.section sh34b +.section sh35a +.section sh35b +.section sh36a +.section sh36b +.section sh37a +.section sh37b +.section sh38a +.section sh38b +.section sh39a +.section sh39b +.section sh30a +.section sh30b +.section sh4aa +.section sh4ab +.section sh4ba +.section sh4bb +.section sh4ca +.section sh4cb +.section sh4da +.section sh4db +.section sh4ea +.section sh4eb +.section sh4fa +.section sh4fb +.section sh4ga +.section sh4gb +.section sh4ha +.section sh4hb +.section sh4ia +.section sh4ib +.section sh4ja +.section sh4jb +.section sh4ka +.section sh4kb +.section sh4la +.section sh4lb +.section sh4ma +.section sh4mb +.section sh4na +.section sh4nb +.section sh4oa +.section sh4ob +.section sh4pa +.section sh4pb +.section sh4qa +.section sh4qb +.section sh4ra +.section sh4rb +.section sh4sa +.section sh4sb +.section sh4ta +.section sh4tb +.section sh4ua +.section sh4ub +.section sh4va +.section sh4vb +.section sh4wa +.section sh4wb +.section sh4xa +.section sh4xb +.section sh4ya +.section sh4yb +.section sh4za +.section sh4zb +.section sh41a +.section sh41b +.section sh42a +.section sh42b +.section sh43a +.section sh43b +.section sh44a +.section sh44b +.section sh45a +.section sh45b +.section sh46a +.section sh46b +.section sh47a +.section sh47b +.section sh48a +.section sh48b +.section sh49a +.section sh49b +.section sh40a +.section sh40b +.section sh5aa +.section sh5ab +.section sh5ba +.section sh5bb +.section sh5ca +.section sh5cb +.section sh5da +.section sh5db +.section sh5ea +.section sh5eb +.section sh5fa +.section sh5fb +.section sh5ga +.section sh5gb +.section sh5ha +.section sh5hb +.section sh5ia +.section sh5ib +.section sh5ja +.section sh5jb +.section sh5ka +.section sh5kb +.section sh5la +.section sh5lb +.section sh5ma +.section sh5mb +.section sh5na +.section sh5nb +.section sh5oa +.section sh5ob +.section sh5pa +.section sh5pb +.section sh5qa +.section sh5qb +.section sh5ra +.section sh5rb +.section sh5sa +.section sh5sb +.section sh5ta +.section sh5tb +.section sh5ua +.section sh5ub +.section sh5va +.section sh5vb +.section sh5wa +.section sh5wb +.section sh5xa +.section sh5xb +.section sh5ya +.section sh5yb +.section sh5za +.section sh5zb +.section sh51a +.section sh51b +.section sh52a +.section sh52b +.section sh53a +.section sh53b +.section sh54a +.section sh54b +.section sh55a +.section sh55b +.section sh56a +.section sh56b +.section sh57a +.section sh57b +.section sh58a +.section sh58b +.section sh59a +.section sh59b +.section sh50a +.section sh50b +.section sh6aa +.section sh6ab +.section sh6ba +.section sh6bb +.section sh6ca +.section sh6cb +.section sh6da +.section sh6db +.section sh6ea +.section sh6eb +.section sh6fa +.section sh6fb +.section sh6ga +.section sh6gb +.section sh6ha +.section sh6hb +.section sh6ia +.section sh6ib +.section sh6ja +.section sh6jb +.section sh6ka +.section sh6kb +.section sh6la +.section sh6lb +.section sh6ma +.section sh6mb +.section sh6na +.section sh6nb +.section sh6oa +.section sh6ob +.section sh6pa +.section sh6pb +.section sh6qa +.section sh6qb +.section sh6ra +.section sh6rb +.section sh6sa +.section sh6sb +.section sh6ta +.section sh6tb +.section sh6ua +.section sh6ub +.section sh6va +.section sh6vb +.section sh6wa +.section sh6wb +.section sh6xa +.section sh6xb +.section sh6ya +.section sh6yb +.section sh6za +.section sh6zb +.section sh61a +.section sh61b +.section sh62a +.section sh62b +.section sh63a +.section sh63b +.section sh64a +.section sh64b +.section sh65a +.section sh65b +.section sh66a +.section sh66b +.section sh67a +.section sh67b +.section sh68a +.section sh68b +.section sh69a +.section sh69b +.section sh60a +.section sh60b +.section sh7aa +.section sh7ab +.section sh7ba +.section sh7bb +.section sh7ca +.section sh7cb +.section sh7da +.section sh7db +.section sh7ea +.section sh7eb +.section sh7fa +.section sh7fb +.section sh7ga +.section sh7gb +.section sh7ha +.section sh7hb +.section sh7ia +.section sh7ib +.section sh7ja +.section sh7jb +.section sh7ka +.section sh7kb +.section sh7la +.section sh7lb +.section sh7ma +.section sh7mb +.section sh7na +.section sh7nb +.section sh7oa +.section sh7ob +.section sh7pa +.section sh7pb +.section sh7qa +.section sh7qb +.section sh7ra +.section sh7rb +.section sh7sa +.section sh7sb +.section sh7ta +.section sh7tb +.section sh7ua +.section sh7ub +.section sh7va +.section sh7vb +.section sh7wa +.section sh7wb +.section sh7xa +.section sh7xb +.section sh7ya +.section sh7yb +.section sh7za +.section sh7zb +.section sh71a +.section sh71b +.section sh72a +.section sh72b +.section sh73a +.section sh73b +.section sh74a +.section sh74b +.section sh75a +.section sh75b +.section sh76a +.section sh76b +.section sh77a +.section sh77b +.section sh78a +.section sh78b +.section sh79a +.section sh79b +.section sh70a +.section sh70b +.section sh8aa +.section sh8ab +.section sh8ba +.section sh8bb +.section sh8ca +.section sh8cb +.section sh8da +.section sh8db +.section sh8ea +.section sh8eb +.section sh8fa +.section sh8fb +.section sh8ga +.section sh8gb +.section sh8ha +.section sh8hb +.section sh8ia +.section sh8ib +.section sh8ja +.section sh8jb +.section sh8ka +.section sh8kb +.section sh8la +.section sh8lb +.section sh8ma +.section sh8mb +.section sh8na +.section sh8nb +.section sh8oa +.section sh8ob +.section sh8pa +.section sh8pb +.section sh8qa +.section sh8qb +.section sh8ra +.section sh8rb +.section sh8sa +.section sh8sb +.section sh8ta +.section sh8tb +.section sh8ua +.section sh8ub +.section sh8va +.section sh8vb +.section sh8wa +.section sh8wb +.section sh8xa +.section sh8xb +.section sh8ya +.section sh8yb +.section sh8za +.section sh8zb +.section sh81a +.section sh81b +.section sh82a +.section sh82b +.section sh83a +.section sh83b +.section sh84a +.section sh84b +.section sh85a +.section sh85b +.section sh86a +.section sh86b +.section sh87a +.section sh87b +.section sh88a +.section sh88b +.section sh89a +.section sh89b +.section sh80a +.section sh80b +.section sh9aa +.section sh9ab +.section sh9ba +.section sh9bb +.section sh9ca +.section sh9cb +.section sh9da +.section sh9db +.section sh9ea +.section sh9eb +.section sh9fa +.section sh9fb +.section sh9ga +.section sh9gb +.section sh9ha +.section sh9hb +.section sh9ia +.section sh9ib +.section sh9ja +.section sh9jb +.section sh9ka +.section sh9kb +.section sh9la +.section sh9lb +.section sh9ma +.section sh9mb +.section sh9na +.section sh9nb +.section sh9oa +.section sh9ob +.section sh9pa +.section sh9pb +.section sh9qa +.section sh9qb +.section sh9ra +.section sh9rb +.section sh9sa +.section sh9sb +.section sh9ta +.section sh9tb +.section sh9ua +.section sh9ub +.section sh9va +.section sh9vb +.section sh9wa +.section sh9wb +.section sh9xa +.section sh9xb +.section sh9ya +.section sh9yb +.section sh9za +.section sh9zb +.section sh91a +.section sh91b +.section sh92a +.section sh92b +.section sh93a +.section sh93b +.section sh94a +.section sh94b +.section sh95a +.section sh95b +.section sh96a +.section sh96b +.section sh97a +.section sh97b +.section sh98a +.section sh98b +.section sh99a +.section sh99b +.section sh90a +.section sh90b +.section sh0aa +.section sh0ab +.section sh0ba +.section sh0bb +.section sh0ca +.section sh0cb +.section sh0da +.section sh0db +.section sh0ea +.section sh0eb +.section sh0fa +.section sh0fb +.section sh0ga +.section sh0gb +.section sh0ha +.section sh0hb +.section sh0ia +.section sh0ib +.section sh0ja +.section sh0jb +.section sh0ka +.section sh0kb +.section sh0la +.section sh0lb +.section sh0ma +.section sh0mb +.section sh0na +.section sh0nb +.section sh0oa +.section sh0ob +.section sh0pa +.section sh0pb +.section sh0qa +.section sh0qb +.section sh0ra +.section sh0rb +.section sh0sa +.section sh0sb +.section sh0ta +.section sh0tb +.section sh0ua +.section sh0ub +.section sh0va +.section sh0vb +.section sh0wa +.section sh0wb +.section sh0xa +.section sh0xb +.section sh0ya +.section sh0yb +.section sh0za +.section sh0zb +.section sh01a +.section sh01b +.section sh02a +.section sh02b +.section sh03a +.section sh03b +.section sh04a +.section sh04b +.section sh05a +.section sh05b +.section sh06a +.section sh06b +.section sh07a +.section sh07b +.section sh08a +.section sh08b +.section sh09a +.section sh09b +.section sh00a +.section sh00b +.section siaaa +.section siaab +.section siaba +.section siabb +.section siaca +.section siacb +.section siada +.section siadb +.section siaea +.section siaeb +.section siafa +.section siafb +.section siaga +.section siagb +.section siaha +.section siahb +.section siaia +.section siaib +.section siaja +.section siajb +.section siaka +.section siakb +.section siala +.section sialb +.section siama +.section siamb +.section siana +.section sianb +.section siaoa +.section siaob +.section siapa +.section siapb +.section siaqa +.section siaqb +.section siara +.section siarb +.section siasa +.section siasb +.section siata +.section siatb +.section siaua +.section siaub +.section siava +.section siavb +.section siawa +.section siawb +.section siaxa +.section siaxb +.section siaya +.section siayb +.section siaza +.section siazb +.section sia1a +.section sia1b +.section sia2a +.section sia2b +.section sia3a +.section sia3b +.section sia4a +.section sia4b +.section sia5a +.section sia5b +.section sia6a +.section sia6b +.section sia7a +.section sia7b +.section sia8a +.section sia8b +.section sia9a +.section sia9b +.section sia0a +.section sia0b +.section sibaa +.section sibab +.section sibba +.section sibbb +.section sibca +.section sibcb +.section sibda +.section sibdb +.section sibea +.section sibeb +.section sibfa +.section sibfb +.section sibga +.section sibgb +.section sibha +.section sibhb +.section sibia +.section sibib +.section sibja +.section sibjb +.section sibka +.section sibkb +.section sibla +.section siblb +.section sibma +.section sibmb +.section sibna +.section sibnb +.section siboa +.section sibob +.section sibpa +.section sibpb +.section sibqa +.section sibqb +.section sibra +.section sibrb +.section sibsa +.section sibsb +.section sibta +.section sibtb +.section sibua +.section sibub +.section sibva +.section sibvb +.section sibwa +.section sibwb +.section sibxa +.section sibxb +.section sibya +.section sibyb +.section sibza +.section sibzb +.section sib1a +.section sib1b +.section sib2a +.section sib2b +.section sib3a +.section sib3b +.section sib4a +.section sib4b +.section sib5a +.section sib5b +.section sib6a +.section sib6b +.section sib7a +.section sib7b +.section sib8a +.section sib8b +.section sib9a +.section sib9b +.section sib0a +.section sib0b +.section sicaa +.section sicab +.section sicba +.section sicbb +.section sicca +.section siccb +.section sicda +.section sicdb +.section sicea +.section siceb +.section sicfa +.section sicfb +.section sicga +.section sicgb +.section sicha +.section sichb +.section sicia +.section sicib +.section sicja +.section sicjb +.section sicka +.section sickb +.section sicla +.section siclb +.section sicma +.section sicmb +.section sicna +.section sicnb +.section sicoa +.section sicob +.section sicpa +.section sicpb +.section sicqa +.section sicqb +.section sicra +.section sicrb +.section sicsa +.section sicsb +.section sicta +.section sictb +.section sicua +.section sicub +.section sicva +.section sicvb +.section sicwa +.section sicwb +.section sicxa +.section sicxb +.section sicya +.section sicyb +.section sicza +.section siczb +.section sic1a +.section sic1b +.section sic2a +.section sic2b +.section sic3a +.section sic3b +.section sic4a +.section sic4b +.section sic5a +.section sic5b +.section sic6a +.section sic6b +.section sic7a +.section sic7b +.section sic8a +.section sic8b +.section sic9a +.section sic9b +.section sic0a +.section sic0b +.section sidaa +.section sidab +.section sidba +.section sidbb +.section sidca +.section sidcb +.section sidda +.section siddb +.section sidea +.section sideb +.section sidfa +.section sidfb +.section sidga +.section sidgb +.section sidha +.section sidhb +.section sidia +.section sidib +.section sidja +.section sidjb +.section sidka +.section sidkb +.section sidla +.section sidlb +.section sidma +.section sidmb +.section sidna +.section sidnb +.section sidoa +.section sidob +.section sidpa +.section sidpb +.section sidqa +.section sidqb +.section sidra +.section sidrb +.section sidsa +.section sidsb +.section sidta +.section sidtb +.section sidua +.section sidub +.section sidva +.section sidvb +.section sidwa +.section sidwb +.section sidxa +.section sidxb +.section sidya +.section sidyb +.section sidza +.section sidzb +.section sid1a +.section sid1b +.section sid2a +.section sid2b +.section sid3a +.section sid3b +.section sid4a +.section sid4b +.section sid5a +.section sid5b +.section sid6a +.section sid6b +.section sid7a +.section sid7b +.section sid8a +.section sid8b +.section sid9a +.section sid9b +.section sid0a +.section sid0b +.section sieaa +.section sieab +.section sieba +.section siebb +.section sieca +.section siecb +.section sieda +.section siedb +.section sieea +.section sieeb +.section siefa +.section siefb +.section siega +.section siegb +.section sieha +.section siehb +.section sieia +.section sieib +.section sieja +.section siejb +.section sieka +.section siekb +.section siela +.section sielb +.section siema +.section siemb +.section siena +.section sienb +.section sieoa +.section sieob +.section siepa +.section siepb +.section sieqa +.section sieqb +.section siera +.section sierb +.section siesa +.section siesb +.section sieta +.section sietb +.section sieua +.section sieub +.section sieva +.section sievb +.section siewa +.section siewb +.section siexa +.section siexb +.section sieya +.section sieyb +.section sieza +.section siezb +.section sie1a +.section sie1b +.section sie2a +.section sie2b +.section sie3a +.section sie3b +.section sie4a +.section sie4b +.section sie5a +.section sie5b +.section sie6a +.section sie6b +.section sie7a +.section sie7b +.section sie8a +.section sie8b +.section sie9a +.section sie9b +.section sie0a +.section sie0b +.section sifaa +.section sifab +.section sifba +.section sifbb +.section sifca +.section sifcb +.section sifda +.section sifdb +.section sifea +.section sifeb +.section siffa +.section siffb +.section sifga +.section sifgb +.section sifha +.section sifhb +.section sifia +.section sifib +.section sifja +.section sifjb +.section sifka +.section sifkb +.section sifla +.section siflb +.section sifma +.section sifmb +.section sifna +.section sifnb +.section sifoa +.section sifob +.section sifpa +.section sifpb +.section sifqa +.section sifqb +.section sifra +.section sifrb +.section sifsa +.section sifsb +.section sifta +.section siftb +.section sifua +.section sifub +.section sifva +.section sifvb +.section sifwa +.section sifwb +.section sifxa +.section sifxb +.section sifya +.section sifyb +.section sifza +.section sifzb +.section sif1a +.section sif1b +.section sif2a +.section sif2b +.section sif3a +.section sif3b +.section sif4a +.section sif4b +.section sif5a +.section sif5b +.section sif6a +.section sif6b +.section sif7a +.section sif7b +.section sif8a +.section sif8b +.section sif9a +.section sif9b +.section sif0a +.section sif0b +.section sigaa +.section sigab +.section sigba +.section sigbb +.section sigca +.section sigcb +.section sigda +.section sigdb +.section sigea +.section sigeb +.section sigfa +.section sigfb +.section sigga +.section siggb +.section sigha +.section sighb +.section sigia +.section sigib +.section sigja +.section sigjb +.section sigka +.section sigkb +.section sigla +.section siglb +.section sigma +.section sigmb +.section signa +.section signb +.section sigoa +.section sigob +.section sigpa +.section sigpb +.section sigqa +.section sigqb +.section sigra +.section sigrb +.section sigsa +.section sigsb +.section sigta +.section sigtb +.section sigua +.section sigub +.section sigva +.section sigvb +.section sigwa +.section sigwb +.section sigxa +.section sigxb +.section sigya +.section sigyb +.section sigza +.section sigzb +.section sig1a +.section sig1b +.section sig2a +.section sig2b +.section sig3a +.section sig3b +.section sig4a +.section sig4b +.section sig5a +.section sig5b +.section sig6a +.section sig6b +.section sig7a +.section sig7b +.section sig8a +.section sig8b +.section sig9a +.section sig9b +.section sig0a +.section sig0b +.section sihaa +.section sihab +.section sihba +.section sihbb +.section sihca +.section sihcb +.section sihda +.section sihdb +.section sihea +.section siheb +.section sihfa +.section sihfb +.section sihga +.section sihgb +.section sihha +.section sihhb +.section sihia +.section sihib +.section sihja +.section sihjb +.section sihka +.section sihkb +.section sihla +.section sihlb +.section sihma +.section sihmb +.section sihna +.section sihnb +.section sihoa +.section sihob +.section sihpa +.section sihpb +.section sihqa +.section sihqb +.section sihra +.section sihrb +.section sihsa +.section sihsb +.section sihta +.section sihtb +.section sihua +.section sihub +.section sihva +.section sihvb +.section sihwa +.section sihwb +.section sihxa +.section sihxb +.section sihya +.section sihyb +.section sihza +.section sihzb +.section sih1a +.section sih1b +.section sih2a +.section sih2b +.section sih3a +.section sih3b +.section sih4a +.section sih4b +.section sih5a +.section sih5b +.section sih6a +.section sih6b +.section sih7a +.section sih7b +.section sih8a +.section sih8b +.section sih9a +.section sih9b +.section sih0a +.section sih0b +.section siiaa +.section siiab +.section siiba +.section siibb +.section siica +.section siicb +.section siida +.section siidb +.section siiea +.section siieb +.section siifa +.section siifb +.section siiga +.section siigb +.section siiha +.section siihb +.section siiia +.section siiib +.section siija +.section siijb +.section siika +.section siikb +.section siila +.section siilb +.section siima +.section siimb +.section siina +.section siinb +.section siioa +.section siiob +.section siipa +.section siipb +.section siiqa +.section siiqb +.section siira +.section siirb +.section siisa +.section siisb +.section siita +.section siitb +.section siiua +.section siiub +.section siiva +.section siivb +.section siiwa +.section siiwb +.section siixa +.section siixb +.section siiya +.section siiyb +.section siiza +.section siizb +.section sii1a +.section sii1b +.section sii2a +.section sii2b +.section sii3a +.section sii3b +.section sii4a +.section sii4b +.section sii5a +.section sii5b +.section sii6a +.section sii6b +.section sii7a +.section sii7b +.section sii8a +.section sii8b +.section sii9a +.section sii9b +.section sii0a +.section sii0b +.section sijaa +.section sijab +.section sijba +.section sijbb +.section sijca +.section sijcb +.section sijda +.section sijdb +.section sijea +.section sijeb +.section sijfa +.section sijfb +.section sijga +.section sijgb +.section sijha +.section sijhb +.section sijia +.section sijib +.section sijja +.section sijjb +.section sijka +.section sijkb +.section sijla +.section sijlb +.section sijma +.section sijmb +.section sijna +.section sijnb +.section sijoa +.section sijob +.section sijpa +.section sijpb +.section sijqa +.section sijqb +.section sijra +.section sijrb +.section sijsa +.section sijsb +.section sijta +.section sijtb +.section sijua +.section sijub +.section sijva +.section sijvb +.section sijwa +.section sijwb +.section sijxa +.section sijxb +.section sijya +.section sijyb +.section sijza +.section sijzb +.section sij1a +.section sij1b +.section sij2a +.section sij2b +.section sij3a +.section sij3b +.section sij4a +.section sij4b +.section sij5a +.section sij5b +.section sij6a +.section sij6b +.section sij7a +.section sij7b +.section sij8a +.section sij8b +.section sij9a +.section sij9b +.section sij0a +.section sij0b +.section sikaa +.section sikab +.section sikba +.section sikbb +.section sikca +.section sikcb +.section sikda +.section sikdb +.section sikea +.section sikeb +.section sikfa +.section sikfb +.section sikga +.section sikgb +.section sikha +.section sikhb +.section sikia +.section sikib +.section sikja +.section sikjb +.section sikka +.section sikkb +.section sikla +.section siklb +.section sikma +.section sikmb +.section sikna +.section siknb +.section sikoa +.section sikob +.section sikpa +.section sikpb +.section sikqa +.section sikqb +.section sikra +.section sikrb +.section siksa +.section siksb +.section sikta +.section siktb +.section sikua +.section sikub +.section sikva +.section sikvb +.section sikwa +.section sikwb +.section sikxa +.section sikxb +.section sikya +.section sikyb +.section sikza +.section sikzb +.section sik1a +.section sik1b +.section sik2a +.section sik2b +.section sik3a +.section sik3b +.section sik4a +.section sik4b +.section sik5a +.section sik5b +.section sik6a +.section sik6b +.section sik7a +.section sik7b +.section sik8a +.section sik8b +.section sik9a +.section sik9b +.section sik0a +.section sik0b +.section silaa +.section silab +.section silba +.section silbb +.section silca +.section silcb +.section silda +.section sildb +.section silea +.section sileb +.section silfa +.section silfb +.section silga +.section silgb +.section silha +.section silhb +.section silia +.section silib +.section silja +.section siljb +.section silka +.section silkb +.section silla +.section sillb +.section silma +.section silmb +.section silna +.section silnb +.section siloa +.section silob +.section silpa +.section silpb +.section silqa +.section silqb +.section silra +.section silrb +.section silsa +.section silsb +.section silta +.section siltb +.section silua +.section silub +.section silva +.section silvb +.section silwa +.section silwb +.section silxa +.section silxb +.section silya +.section silyb +.section silza +.section silzb +.section sil1a +.section sil1b +.section sil2a +.section sil2b +.section sil3a +.section sil3b +.section sil4a +.section sil4b +.section sil5a +.section sil5b +.section sil6a +.section sil6b +.section sil7a +.section sil7b +.section sil8a +.section sil8b +.section sil9a +.section sil9b +.section sil0a +.section sil0b +.section simaa +.section simab +.section simba +.section simbb +.section simca +.section simcb +.section simda +.section simdb +.section simea +.section simeb +.section simfa +.section simfb +.section simga +.section simgb +.section simha +.section simhb +.section simia +.section simib +.section simja +.section simjb +.section simka +.section simkb +.section simla +.section simlb +.section simma +.section simmb +.section simna +.section simnb +.section simoa +.section simob +.section simpa +.section simpb +.section simqa +.section simqb +.section simra +.section simrb +.section simsa +.section simsb +.section simta +.section simtb +.section simua +.section simub +.section simva +.section simvb +.section simwa +.section simwb +.section simxa +.section simxb +.section simya +.section simyb +.section simza +.section simzb +.section sim1a +.section sim1b +.section sim2a +.section sim2b +.section sim3a +.section sim3b +.section sim4a +.section sim4b +.section sim5a +.section sim5b +.section sim6a +.section sim6b +.section sim7a +.section sim7b +.section sim8a +.section sim8b +.section sim9a +.section sim9b +.section sim0a +.section sim0b +.section sinaa +.section sinab +.section sinba +.section sinbb +.section sinca +.section sincb +.section sinda +.section sindb +.section sinea +.section sineb +.section sinfa +.section sinfb +.section singa +.section singb +.section sinha +.section sinhb +.section sinia +.section sinib +.section sinja +.section sinjb +.section sinka +.section sinkb +.section sinla +.section sinlb +.section sinma +.section sinmb +.section sinna +.section sinnb +.section sinoa +.section sinob +.section sinpa +.section sinpb +.section sinqa +.section sinqb +.section sinra +.section sinrb +.section sinsa +.section sinsb +.section sinta +.section sintb +.section sinua +.section sinub +.section sinva +.section sinvb +.section sinwa +.section sinwb +.section sinxa +.section sinxb +.section sinya +.section sinyb +.section sinza +.section sinzb +.section sin1a +.section sin1b +.section sin2a +.section sin2b +.section sin3a +.section sin3b +.section sin4a +.section sin4b +.section sin5a +.section sin5b +.section sin6a +.section sin6b +.section sin7a +.section sin7b +.section sin8a +.section sin8b +.section sin9a +.section sin9b +.section sin0a +.section sin0b +.section sioaa +.section sioab +.section sioba +.section siobb +.section sioca +.section siocb +.section sioda +.section siodb +.section sioea +.section sioeb +.section siofa +.section siofb +.section sioga +.section siogb +.section sioha +.section siohb +.section sioia +.section sioib +.section sioja +.section siojb +.section sioka +.section siokb +.section siola +.section siolb +.section sioma +.section siomb +.section siona +.section sionb +.section siooa +.section sioob +.section siopa +.section siopb +.section sioqa +.section sioqb +.section siora +.section siorb +.section siosa +.section siosb +.section siota +.section siotb +.section sioua +.section sioub +.section siova +.section siovb +.section siowa +.section siowb +.section sioxa +.section sioxb +.section sioya +.section sioyb +.section sioza +.section siozb +.section sio1a +.section sio1b +.section sio2a +.section sio2b +.section sio3a +.section sio3b +.section sio4a +.section sio4b +.section sio5a +.section sio5b +.section sio6a +.section sio6b +.section sio7a +.section sio7b +.section sio8a +.section sio8b +.section sio9a +.section sio9b +.section sio0a +.section sio0b +.section sipaa +.section sipab +.section sipba +.section sipbb +.section sipca +.section sipcb +.section sipda +.section sipdb +.section sipea +.section sipeb +.section sipfa +.section sipfb +.section sipga +.section sipgb +.section sipha +.section siphb +.section sipia +.section sipib +.section sipja +.section sipjb +.section sipka +.section sipkb +.section sipla +.section siplb +.section sipma +.section sipmb +.section sipna +.section sipnb +.section sipoa +.section sipob +.section sippa +.section sippb +.section sipqa +.section sipqb +.section sipra +.section siprb +.section sipsa +.section sipsb +.section sipta +.section siptb +.section sipua +.section sipub +.section sipva +.section sipvb +.section sipwa +.section sipwb +.section sipxa +.section sipxb +.section sipya +.section sipyb +.section sipza +.section sipzb +.section sip1a +.section sip1b +.section sip2a +.section sip2b +.section sip3a +.section sip3b +.section sip4a +.section sip4b +.section sip5a +.section sip5b +.section sip6a +.section sip6b +.section sip7a +.section sip7b +.section sip8a +.section sip8b +.section sip9a +.section sip9b +.section sip0a +.section sip0b +.section siqaa +.section siqab +.section siqba +.section siqbb +.section siqca +.section siqcb +.section siqda +.section siqdb +.section siqea +.section siqeb +.section siqfa +.section siqfb +.section siqga +.section siqgb +.section siqha +.section siqhb +.section siqia +.section siqib +.section siqja +.section siqjb +.section siqka +.section siqkb +.section siqla +.section siqlb +.section siqma +.section siqmb +.section siqna +.section siqnb +.section siqoa +.section siqob +.section siqpa +.section siqpb +.section siqqa +.section siqqb +.section siqra +.section siqrb +.section siqsa +.section siqsb +.section siqta +.section siqtb +.section siqua +.section siqub +.section siqva +.section siqvb +.section siqwa +.section siqwb +.section siqxa +.section siqxb +.section siqya +.section siqyb +.section siqza +.section siqzb +.section siq1a +.section siq1b +.section siq2a +.section siq2b +.section siq3a +.section siq3b +.section siq4a +.section siq4b +.section siq5a +.section siq5b +.section siq6a +.section siq6b +.section siq7a +.section siq7b +.section siq8a +.section siq8b +.section siq9a +.section siq9b +.section siq0a +.section siq0b +.section siraa +.section sirab +.section sirba +.section sirbb +.section sirca +.section sircb +.section sirda +.section sirdb +.section sirea +.section sireb +.section sirfa +.section sirfb +.section sirga +.section sirgb +.section sirha +.section sirhb +.section siria +.section sirib +.section sirja +.section sirjb +.section sirka +.section sirkb +.section sirla +.section sirlb +.section sirma +.section sirmb +.section sirna +.section sirnb +.section siroa +.section sirob +.section sirpa +.section sirpb +.section sirqa +.section sirqb +.section sirra +.section sirrb +.section sirsa +.section sirsb +.section sirta +.section sirtb +.section sirua +.section sirub +.section sirva +.section sirvb +.section sirwa +.section sirwb +.section sirxa +.section sirxb +.section sirya +.section siryb +.section sirza +.section sirzb +.section sir1a +.section sir1b +.section sir2a +.section sir2b +.section sir3a +.section sir3b +.section sir4a +.section sir4b +.section sir5a +.section sir5b +.section sir6a +.section sir6b +.section sir7a +.section sir7b +.section sir8a +.section sir8b +.section sir9a +.section sir9b +.section sir0a +.section sir0b +.section sisaa +.section sisab +.section sisba +.section sisbb +.section sisca +.section siscb +.section sisda +.section sisdb +.section sisea +.section siseb +.section sisfa +.section sisfb +.section sisga +.section sisgb +.section sisha +.section sishb +.section sisia +.section sisib +.section sisja +.section sisjb +.section siska +.section siskb +.section sisla +.section sislb +.section sisma +.section sismb +.section sisna +.section sisnb +.section sisoa +.section sisob +.section sispa +.section sispb +.section sisqa +.section sisqb +.section sisra +.section sisrb +.section sissa +.section sissb +.section sista +.section sistb +.section sisua +.section sisub +.section sisva +.section sisvb +.section siswa +.section siswb +.section sisxa +.section sisxb +.section sisya +.section sisyb +.section sisza +.section siszb +.section sis1a +.section sis1b +.section sis2a +.section sis2b +.section sis3a +.section sis3b +.section sis4a +.section sis4b +.section sis5a +.section sis5b +.section sis6a +.section sis6b +.section sis7a +.section sis7b +.section sis8a +.section sis8b +.section sis9a +.section sis9b +.section sis0a +.section sis0b +.section sitaa +.section sitab +.section sitba +.section sitbb +.section sitca +.section sitcb +.section sitda +.section sitdb +.section sitea +.section siteb +.section sitfa +.section sitfb +.section sitga +.section sitgb +.section sitha +.section sithb +.section sitia +.section sitib +.section sitja +.section sitjb +.section sitka +.section sitkb +.section sitla +.section sitlb +.section sitma +.section sitmb +.section sitna +.section sitnb +.section sitoa +.section sitob +.section sitpa +.section sitpb +.section sitqa +.section sitqb +.section sitra +.section sitrb +.section sitsa +.section sitsb +.section sitta +.section sittb +.section situa +.section situb +.section sitva +.section sitvb +.section sitwa +.section sitwb +.section sitxa +.section sitxb +.section sitya +.section sityb +.section sitza +.section sitzb +.section sit1a +.section sit1b +.section sit2a +.section sit2b +.section sit3a +.section sit3b +.section sit4a +.section sit4b +.section sit5a +.section sit5b +.section sit6a +.section sit6b +.section sit7a +.section sit7b +.section sit8a +.section sit8b +.section sit9a +.section sit9b +.section sit0a +.section sit0b +.section siuaa +.section siuab +.section siuba +.section siubb +.section siuca +.section siucb +.section siuda +.section siudb +.section siuea +.section siueb +.section siufa +.section siufb +.section siuga +.section siugb +.section siuha +.section siuhb +.section siuia +.section siuib +.section siuja +.section siujb +.section siuka +.section siukb +.section siula +.section siulb +.section siuma +.section siumb +.section siuna +.section siunb +.section siuoa +.section siuob +.section siupa +.section siupb +.section siuqa +.section siuqb +.section siura +.section siurb +.section siusa +.section siusb +.section siuta +.section siutb +.section siuua +.section siuub +.section siuva +.section siuvb +.section siuwa +.section siuwb +.section siuxa +.section siuxb +.section siuya +.section siuyb +.section siuza +.section siuzb +.section siu1a +.section siu1b +.section siu2a +.section siu2b +.section siu3a +.section siu3b +.section siu4a +.section siu4b +.section siu5a +.section siu5b +.section siu6a +.section siu6b +.section siu7a +.section siu7b +.section siu8a +.section siu8b +.section siu9a +.section siu9b +.section siu0a +.section siu0b +.section sivaa +.section sivab +.section sivba +.section sivbb +.section sivca +.section sivcb +.section sivda +.section sivdb +.section sivea +.section siveb +.section sivfa +.section sivfb +.section sivga +.section sivgb +.section sivha +.section sivhb +.section sivia +.section sivib +.section sivja +.section sivjb +.section sivka +.section sivkb +.section sivla +.section sivlb +.section sivma +.section sivmb +.section sivna +.section sivnb +.section sivoa +.section sivob +.section sivpa +.section sivpb +.section sivqa +.section sivqb +.section sivra +.section sivrb +.section sivsa +.section sivsb +.section sivta +.section sivtb +.section sivua +.section sivub +.section sivva +.section sivvb +.section sivwa +.section sivwb +.section sivxa +.section sivxb +.section sivya +.section sivyb +.section sivza +.section sivzb +.section siv1a +.section siv1b +.section siv2a +.section siv2b +.section siv3a +.section siv3b +.section siv4a +.section siv4b +.section siv5a +.section siv5b +.section siv6a +.section siv6b +.section siv7a +.section siv7b +.section siv8a +.section siv8b +.section siv9a +.section siv9b +.section siv0a +.section siv0b +.section siwaa +.section siwab +.section siwba +.section siwbb +.section siwca +.section siwcb +.section siwda +.section siwdb +.section siwea +.section siweb +.section siwfa +.section siwfb +.section siwga +.section siwgb +.section siwha +.section siwhb +.section siwia +.section siwib +.section siwja +.section siwjb +.section siwka +.section siwkb +.section siwla +.section siwlb +.section siwma +.section siwmb +.section siwna +.section siwnb +.section siwoa +.section siwob +.section siwpa +.section siwpb +.section siwqa +.section siwqb +.section siwra +.section siwrb +.section siwsa +.section siwsb +.section siwta +.section siwtb +.section siwua +.section siwub +.section siwva +.section siwvb +.section siwwa +.section siwwb +.section siwxa +.section siwxb +.section siwya +.section siwyb +.section siwza +.section siwzb +.section siw1a +.section siw1b +.section siw2a +.section siw2b +.section siw3a +.section siw3b +.section siw4a +.section siw4b +.section siw5a +.section siw5b +.section siw6a +.section siw6b +.section siw7a +.section siw7b +.section siw8a +.section siw8b +.section siw9a +.section siw9b +.section siw0a +.section siw0b +.section sixaa +.section sixab +.section sixba +.section sixbb +.section sixca +.section sixcb +.section sixda +.section sixdb +.section sixea +.section sixeb +.section sixfa +.section sixfb +.section sixga +.section sixgb +.section sixha +.section sixhb +.section sixia +.section sixib +.section sixja +.section sixjb +.section sixka +.section sixkb +.section sixla +.section sixlb +.section sixma +.section sixmb +.section sixna +.section sixnb +.section sixoa +.section sixob +.section sixpa +.section sixpb +.section sixqa +.section sixqb +.section sixra +.section sixrb +.section sixsa +.section sixsb +.section sixta +.section sixtb +.section sixua +.section sixub +.section sixva +.section sixvb +.section sixwa +.section sixwb +.section sixxa +.section sixxb +.section sixya +.section sixyb +.section sixza +.section sixzb +.section six1a +.section six1b +.section six2a +.section six2b +.section six3a +.section six3b +.section six4a +.section six4b +.section six5a +.section six5b +.section six6a +.section six6b +.section six7a +.section six7b +.section six8a +.section six8b +.section six9a +.section six9b +.section six0a +.section six0b +.section siyaa +.section siyab +.section siyba +.section siybb +.section siyca +.section siycb +.section siyda +.section siydb +.section siyea +.section siyeb +.section siyfa +.section siyfb +.section siyga +.section siygb +.section siyha +.section siyhb +.section siyia +.section siyib +.section siyja +.section siyjb +.section siyka +.section siykb +.section siyla +.section siylb +.section siyma +.section siymb +.section siyna +.section siynb +.section siyoa +.section siyob +.section siypa +.section siypb +.section siyqa +.section siyqb +.section siyra +.section siyrb +.section siysa +.section siysb +.section siyta +.section siytb +.section siyua +.section siyub +.section siyva +.section siyvb +.section siywa +.section siywb +.section siyxa +.section siyxb +.section siyya +.section siyyb +.section siyza +.section siyzb +.section siy1a +.section siy1b +.section siy2a +.section siy2b +.section siy3a +.section siy3b +.section siy4a +.section siy4b +.section siy5a +.section siy5b +.section siy6a +.section siy6b +.section siy7a +.section siy7b +.section siy8a +.section siy8b +.section siy9a +.section siy9b +.section siy0a +.section siy0b +.section sizaa +.section sizab +.section sizba +.section sizbb +.section sizca +.section sizcb +.section sizda +.section sizdb +.section sizea +.section sizeb +.section sizfa +.section sizfb +.section sizga +.section sizgb +.section sizha +.section sizhb +.section sizia +.section sizib +.section sizja +.section sizjb +.section sizka +.section sizkb +.section sizla +.section sizlb +.section sizma +.section sizmb +.section sizna +.section siznb +.section sizoa +.section sizob +.section sizpa +.section sizpb +.section sizqa +.section sizqb +.section sizra +.section sizrb +.section sizsa +.section sizsb +.section sizta +.section siztb +.section sizua +.section sizub +.section sizva +.section sizvb +.section sizwa +.section sizwb +.section sizxa +.section sizxb +.section sizya +.section sizyb +.section sizza +.section sizzb +.section siz1a +.section siz1b +.section siz2a +.section siz2b +.section siz3a +.section siz3b +.section siz4a +.section siz4b +.section siz5a +.section siz5b +.section siz6a +.section siz6b +.section siz7a +.section siz7b +.section siz8a +.section siz8b +.section siz9a +.section siz9b +.section siz0a +.section siz0b +.section si1aa +.section si1ab +.section si1ba +.section si1bb +.section si1ca +.section si1cb +.section si1da +.section si1db +.section si1ea +.section si1eb +.section si1fa +.section si1fb +.section si1ga +.section si1gb +.section si1ha +.section si1hb +.section si1ia +.section si1ib +.section si1ja +.section si1jb +.section si1ka +.section si1kb +.section si1la +.section si1lb +.section si1ma +.section si1mb +.section si1na +.section si1nb +.section si1oa +.section si1ob +.section si1pa +.section si1pb +.section si1qa +.section si1qb +.section si1ra +.section si1rb +.section si1sa +.section si1sb +.section si1ta +.section si1tb +.section si1ua +.section si1ub +.section si1va +.section si1vb +.section si1wa +.section si1wb +.section si1xa +.section si1xb +.section si1ya +.section si1yb +.section si1za +.section si1zb +.section si11a +.section si11b +.section si12a +.section si12b +.section si13a +.section si13b +.section si14a +.section si14b +.section si15a +.section si15b +.section si16a +.section si16b +.section si17a +.section si17b +.section si18a +.section si18b +.section si19a +.section si19b +.section si10a +.section si10b +.section si2aa +.section si2ab +.section si2ba +.section si2bb +.section si2ca +.section si2cb +.section si2da +.section si2db +.section si2ea +.section si2eb +.section si2fa +.section si2fb +.section si2ga +.section si2gb +.section si2ha +.section si2hb +.section si2ia +.section si2ib +.section si2ja +.section si2jb +.section si2ka +.section si2kb +.section si2la +.section si2lb +.section si2ma +.section si2mb +.section si2na +.section si2nb +.section si2oa +.section si2ob +.section si2pa +.section si2pb +.section si2qa +.section si2qb +.section si2ra +.section si2rb +.section si2sa +.section si2sb +.section si2ta +.section si2tb +.section si2ua +.section si2ub +.section si2va +.section si2vb +.section si2wa +.section si2wb +.section si2xa +.section si2xb +.section si2ya +.section si2yb +.section si2za +.section si2zb +.section si21a +.section si21b +.section si22a +.section si22b +.section si23a +.section si23b +.section si24a +.section si24b +.section si25a +.section si25b +.section si26a +.section si26b +.section si27a +.section si27b +.section si28a +.section si28b +.section si29a +.section si29b +.section si20a +.section si20b +.section si3aa +.section si3ab +.section si3ba +.section si3bb +.section si3ca +.section si3cb +.section si3da +.section si3db +.section si3ea +.section si3eb +.section si3fa +.section si3fb +.section si3ga +.section si3gb +.section si3ha +.section si3hb +.section si3ia +.section si3ib +.section si3ja +.section si3jb +.section si3ka +.section si3kb +.section si3la +.section si3lb +.section si3ma +.section si3mb +.section si3na +.section si3nb +.section si3oa +.section si3ob +.section si3pa +.section si3pb +.section si3qa +.section si3qb +.section si3ra +.section si3rb +.section si3sa +.section si3sb +.section si3ta +.section si3tb +.section si3ua +.section si3ub +.section si3va +.section si3vb +.section si3wa +.section si3wb +.section si3xa +.section si3xb +.section si3ya +.section si3yb +.section si3za +.section si3zb +.section si31a +.section si31b +.section si32a +.section si32b +.section si33a +.section si33b +.section si34a +.section si34b +.section si35a +.section si35b +.section si36a +.section si36b +.section si37a +.section si37b +.section si38a +.section si38b +.section si39a +.section si39b +.section si30a +.section si30b +.section si4aa +.section si4ab +.section si4ba +.section si4bb +.section si4ca +.section si4cb +.section si4da +.section si4db +.section si4ea +.section si4eb +.section si4fa +.section si4fb +.section si4ga +.section si4gb +.section si4ha +.section si4hb +.section si4ia +.section si4ib +.section si4ja +.section si4jb +.section si4ka +.section si4kb +.section si4la +.section si4lb +.section si4ma +.section si4mb +.section si4na +.section si4nb +.section si4oa +.section si4ob +.section si4pa +.section si4pb +.section si4qa +.section si4qb +.section si4ra +.section si4rb +.section si4sa +.section si4sb +.section si4ta +.section si4tb +.section si4ua +.section si4ub +.section si4va +.section si4vb +.section si4wa +.section si4wb +.section si4xa +.section si4xb +.section si4ya +.section si4yb +.section si4za +.section si4zb +.section si41a +.section si41b +.section si42a +.section si42b +.section si43a +.section si43b +.section si44a +.section si44b +.section si45a +.section si45b +.section si46a +.section si46b +.section si47a +.section si47b +.section si48a +.section si48b +.section si49a +.section si49b +.section si40a +.section si40b +.section si5aa +.section si5ab +.section si5ba +.section si5bb +.section si5ca +.section si5cb +.section si5da +.section si5db +.section si5ea +.section si5eb +.section si5fa +.section si5fb +.section si5ga +.section si5gb +.section si5ha +.section si5hb +.section si5ia +.section si5ib +.section si5ja +.section si5jb +.section si5ka +.section si5kb +.section si5la +.section si5lb +.section si5ma +.section si5mb +.section si5na +.section si5nb +.section si5oa +.section si5ob +.section si5pa +.section si5pb +.section si5qa +.section si5qb +.section si5ra +.section si5rb +.section si5sa +.section si5sb +.section si5ta +.section si5tb +.section si5ua +.section si5ub +.section si5va +.section si5vb +.section si5wa +.section si5wb +.section si5xa +.section si5xb +.section si5ya +.section si5yb +.section si5za +.section si5zb +.section si51a +.section si51b +.section si52a +.section si52b +.section si53a +.section si53b +.section si54a +.section si54b +.section si55a +.section si55b +.section si56a +.section si56b +.section si57a +.section si57b +.section si58a +.section si58b +.section si59a +.section si59b +.section si50a +.section si50b +.section si6aa +.section si6ab +.section si6ba +.section si6bb +.section si6ca +.section si6cb +.section si6da +.section si6db +.section si6ea +.section si6eb +.section si6fa +.section si6fb +.section si6ga +.section si6gb +.section si6ha +.section si6hb +.section si6ia +.section si6ib +.section si6ja +.section si6jb +.section si6ka +.section si6kb +.section si6la +.section si6lb +.section si6ma +.section si6mb +.section si6na +.section si6nb +.section si6oa +.section si6ob +.section si6pa +.section si6pb +.section si6qa +.section si6qb +.section si6ra +.section si6rb +.section si6sa +.section si6sb +.section si6ta +.section si6tb +.section si6ua +.section si6ub +.section si6va +.section si6vb +.section si6wa +.section si6wb +.section si6xa +.section si6xb +.section si6ya +.section si6yb +.section si6za +.section si6zb +.section si61a +.section si61b +.section si62a +.section si62b +.section si63a +.section si63b +.section si64a +.section si64b +.section si65a +.section si65b +.section si66a +.section si66b +.section si67a +.section si67b +.section si68a +.section si68b +.section si69a +.section si69b +.section si60a +.section si60b +.section si7aa +.section si7ab +.section si7ba +.section si7bb +.section si7ca +.section si7cb +.section si7da +.section si7db +.section si7ea +.section si7eb +.section si7fa +.section si7fb +.section si7ga +.section si7gb +.section si7ha +.section si7hb +.section si7ia +.section si7ib +.section si7ja +.section si7jb +.section si7ka +.section si7kb +.section si7la +.section si7lb +.section si7ma +.section si7mb +.section si7na +.section si7nb +.section si7oa +.section si7ob +.section si7pa +.section si7pb +.section si7qa +.section si7qb +.section si7ra +.section si7rb +.section si7sa +.section si7sb +.section si7ta +.section si7tb +.section si7ua +.section si7ub +.section si7va +.section si7vb +.section si7wa +.section si7wb +.section si7xa +.section si7xb +.section si7ya +.section si7yb +.section si7za +.section si7zb +.section si71a +.section si71b +.section si72a +.section si72b +.section si73a +.section si73b +.section si74a +.section si74b +.section si75a +.section si75b +.section si76a +.section si76b +.section si77a +.section si77b +.section si78a +.section si78b +.section si79a +.section si79b +.section si70a +.section si70b +.section si8aa +.section si8ab +.section si8ba +.section si8bb +.section si8ca +.section si8cb +.section si8da +.section si8db +.section si8ea +.section si8eb +.section si8fa +.section si8fb +.section si8ga +.section si8gb +.section si8ha +.section si8hb +.section si8ia +.section si8ib +.section si8ja +.section si8jb +.section si8ka +.section si8kb +.section si8la +.section si8lb +.section si8ma +.section si8mb +.section si8na +.section si8nb +.section si8oa +.section si8ob +.section si8pa +.section si8pb +.section si8qa +.section si8qb +.section si8ra +.section si8rb +.section si8sa +.section si8sb +.section si8ta +.section si8tb +.section si8ua +.section si8ub +.section si8va +.section si8vb +.section si8wa +.section si8wb +.section si8xa +.section si8xb +.section si8ya +.section si8yb +.section si8za +.section si8zb +.section si81a +.section si81b +.section si82a +.section si82b +.section si83a +.section si83b +.section si84a +.section si84b +.section si85a +.section si85b +.section si86a +.section si86b +.section si87a +.section si87b +.section si88a +.section si88b +.section si89a +.section si89b +.section si80a +.section si80b +.section si9aa +.section si9ab +.section si9ba +.section si9bb +.section si9ca +.section si9cb +.section si9da +.section si9db +.section si9ea +.section si9eb +.section si9fa +.section si9fb +.section si9ga +.section si9gb +.section si9ha +.section si9hb +.section si9ia +.section si9ib +.section si9ja +.section si9jb +.section si9ka +.section si9kb +.section si9la +.section si9lb +.section si9ma +.section si9mb +.section si9na +.section si9nb +.section si9oa +.section si9ob +.section si9pa +.section si9pb +.section si9qa +.section si9qb +.section si9ra +.section si9rb +.section si9sa +.section si9sb +.section si9ta +.section si9tb +.section si9ua +.section si9ub +.section si9va +.section si9vb +.section si9wa +.section si9wb +.section si9xa +.section si9xb +.section si9ya +.section si9yb +.section si9za +.section si9zb +.section si91a +.section si91b +.section si92a +.section si92b +.section si93a +.section si93b +.section si94a +.section si94b +.section si95a +.section si95b +.section si96a +.section si96b +.section si97a +.section si97b +.section si98a +.section si98b +.section si99a +.section si99b +.section si90a +.section si90b +.section si0aa +.section si0ab +.section si0ba +.section si0bb +.section si0ca +.section si0cb +.section si0da +.section si0db +.section si0ea +.section si0eb +.section si0fa +.section si0fb +.section si0ga +.section si0gb +.section si0ha +.section si0hb +.section si0ia +.section si0ib +.section si0ja +.section si0jb +.section si0ka +.section si0kb +.section si0la +.section si0lb +.section si0ma +.section si0mb +.section si0na +.section si0nb +.section si0oa +.section si0ob +.section si0pa +.section si0pb +.section si0qa +.section si0qb +.section si0ra +.section si0rb +.section si0sa +.section si0sb +.section si0ta +.section si0tb +.section si0ua +.section si0ub +.section si0va +.section si0vb +.section si0wa +.section si0wb +.section si0xa +.section si0xb +.section si0ya +.section si0yb +.section si0za +.section si0zb +.section si01a +.section si01b +.section si02a +.section si02b +.section si03a +.section si03b +.section si04a +.section si04b +.section si05a +.section si05b +.section si06a +.section si06b +.section si07a +.section si07b +.section si08a +.section si08b +.section si09a +.section si09b +.section si00a +.section si00b +.section sjaaa +.section sjaab +.section sjaba +.section sjabb +.section sjaca +.section sjacb +.section sjada +.section sjadb +.section sjaea +.section sjaeb +.section sjafa +.section sjafb +.section sjaga +.section sjagb +.section sjaha +.section sjahb +.section sjaia +.section sjaib +.section sjaja +.section sjajb +.section sjaka +.section sjakb +.section sjala +.section sjalb +.section sjama +.section sjamb +.section sjana +.section sjanb +.section sjaoa +.section sjaob +.section sjapa +.section sjapb +.section sjaqa +.section sjaqb +.section sjara +.section sjarb +.section sjasa +.section sjasb +.section sjata +.section sjatb +.section sjaua +.section sjaub +.section sjava +.section sjavb +.section sjawa +.section sjawb +.section sjaxa +.section sjaxb +.section sjaya +.section sjayb +.section sjaza +.section sjazb +.section sja1a +.section sja1b +.section sja2a +.section sja2b +.section sja3a +.section sja3b +.section sja4a +.section sja4b +.section sja5a +.section sja5b +.section sja6a +.section sja6b +.section sja7a +.section sja7b +.section sja8a +.section sja8b +.section sja9a +.section sja9b +.section sja0a +.section sja0b +.section sjbaa +.section sjbab +.section sjbba +.section sjbbb +.section sjbca +.section sjbcb +.section sjbda +.section sjbdb +.section sjbea +.section sjbeb +.section sjbfa +.section sjbfb +.section sjbga +.section sjbgb +.section sjbha +.section sjbhb +.section sjbia +.section sjbib +.section sjbja +.section sjbjb +.section sjbka +.section sjbkb +.section sjbla +.section sjblb +.section sjbma +.section sjbmb +.section sjbna +.section sjbnb +.section sjboa +.section sjbob +.section sjbpa +.section sjbpb +.section sjbqa +.section sjbqb +.section sjbra +.section sjbrb +.section sjbsa +.section sjbsb +.section sjbta +.section sjbtb +.section sjbua +.section sjbub +.section sjbva +.section sjbvb +.section sjbwa +.section sjbwb +.section sjbxa +.section sjbxb +.section sjbya +.section sjbyb +.section sjbza +.section sjbzb +.section sjb1a +.section sjb1b +.section sjb2a +.section sjb2b +.section sjb3a +.section sjb3b +.section sjb4a +.section sjb4b +.section sjb5a +.section sjb5b +.section sjb6a +.section sjb6b +.section sjb7a +.section sjb7b +.section sjb8a +.section sjb8b +.section sjb9a +.section sjb9b +.section sjb0a +.section sjb0b +.section sjcaa +.section sjcab +.section sjcba +.section sjcbb +.section sjcca +.section sjccb +.section sjcda +.section sjcdb +.section sjcea +.section sjceb +.section sjcfa +.section sjcfb +.section sjcga +.section sjcgb +.section sjcha +.section sjchb +.section sjcia +.section sjcib +.section sjcja +.section sjcjb +.section sjcka +.section sjckb +.section sjcla +.section sjclb +.section sjcma +.section sjcmb +.section sjcna +.section sjcnb +.section sjcoa +.section sjcob +.section sjcpa +.section sjcpb +.section sjcqa +.section sjcqb +.section sjcra +.section sjcrb +.section sjcsa +.section sjcsb +.section sjcta +.section sjctb +.section sjcua +.section sjcub +.section sjcva +.section sjcvb +.section sjcwa +.section sjcwb +.section sjcxa +.section sjcxb +.section sjcya +.section sjcyb +.section sjcza +.section sjczb +.section sjc1a +.section sjc1b +.section sjc2a +.section sjc2b +.section sjc3a +.section sjc3b +.section sjc4a +.section sjc4b +.section sjc5a +.section sjc5b +.section sjc6a +.section sjc6b +.section sjc7a +.section sjc7b +.section sjc8a +.section sjc8b +.section sjc9a +.section sjc9b +.section sjc0a +.section sjc0b +.section sjdaa +.section sjdab +.section sjdba +.section sjdbb +.section sjdca +.section sjdcb +.section sjdda +.section sjddb +.section sjdea +.section sjdeb +.section sjdfa +.section sjdfb +.section sjdga +.section sjdgb +.section sjdha +.section sjdhb +.section sjdia +.section sjdib +.section sjdja +.section sjdjb +.section sjdka +.section sjdkb +.section sjdla +.section sjdlb +.section sjdma +.section sjdmb +.section sjdna +.section sjdnb +.section sjdoa +.section sjdob +.section sjdpa +.section sjdpb +.section sjdqa +.section sjdqb +.section sjdra +.section sjdrb +.section sjdsa +.section sjdsb +.section sjdta +.section sjdtb +.section sjdua +.section sjdub +.section sjdva +.section sjdvb +.section sjdwa +.section sjdwb +.section sjdxa +.section sjdxb +.section sjdya +.section sjdyb +.section sjdza +.section sjdzb +.section sjd1a +.section sjd1b +.section sjd2a +.section sjd2b +.section sjd3a +.section sjd3b +.section sjd4a +.section sjd4b +.section sjd5a +.section sjd5b +.section sjd6a +.section sjd6b +.section sjd7a +.section sjd7b +.section sjd8a +.section sjd8b +.section sjd9a +.section sjd9b +.section sjd0a +.section sjd0b +.section sjeaa +.section sjeab +.section sjeba +.section sjebb +.section sjeca +.section sjecb +.section sjeda +.section sjedb +.section sjeea +.section sjeeb +.section sjefa +.section sjefb +.section sjega +.section sjegb +.section sjeha +.section sjehb +.section sjeia +.section sjeib +.section sjeja +.section sjejb +.section sjeka +.section sjekb +.section sjela +.section sjelb +.section sjema +.section sjemb +.section sjena +.section sjenb +.section sjeoa +.section sjeob +.section sjepa +.section sjepb +.section sjeqa +.section sjeqb +.section sjera +.section sjerb +.section sjesa +.section sjesb +.section sjeta +.section sjetb +.section sjeua +.section sjeub +.section sjeva +.section sjevb +.section sjewa +.section sjewb +.section sjexa +.section sjexb +.section sjeya +.section sjeyb +.section sjeza +.section sjezb +.section sje1a +.section sje1b +.section sje2a +.section sje2b +.section sje3a +.section sje3b +.section sje4a +.section sje4b +.section sje5a +.section sje5b +.section sje6a +.section sje6b +.section sje7a +.section sje7b +.section sje8a +.section sje8b +.section sje9a +.section sje9b +.section sje0a +.section sje0b +.section sjfaa +.section sjfab +.section sjfba +.section sjfbb +.section sjfca +.section sjfcb +.section sjfda +.section sjfdb +.section sjfea +.section sjfeb +.section sjffa +.section sjffb +.section sjfga +.section sjfgb +.section sjfha +.section sjfhb +.section sjfia +.section sjfib +.section sjfja +.section sjfjb +.section sjfka +.section sjfkb +.section sjfla +.section sjflb +.section sjfma +.section sjfmb +.section sjfna +.section sjfnb +.section sjfoa +.section sjfob +.section sjfpa +.section sjfpb +.section sjfqa +.section sjfqb +.section sjfra +.section sjfrb +.section sjfsa +.section sjfsb +.section sjfta +.section sjftb +.section sjfua +.section sjfub +.section sjfva +.section sjfvb +.section sjfwa +.section sjfwb +.section sjfxa +.section sjfxb +.section sjfya +.section sjfyb +.section sjfza +.section sjfzb +.section sjf1a +.section sjf1b +.section sjf2a +.section sjf2b +.section sjf3a +.section sjf3b +.section sjf4a +.section sjf4b +.section sjf5a +.section sjf5b +.section sjf6a +.section sjf6b +.section sjf7a +.section sjf7b +.section sjf8a +.section sjf8b +.section sjf9a +.section sjf9b +.section sjf0a +.section sjf0b +.section sjgaa +.section sjgab +.section sjgba +.section sjgbb +.section sjgca +.section sjgcb +.section sjgda +.section sjgdb +.section sjgea +.section sjgeb +.section sjgfa +.section sjgfb +.section sjgga +.section sjggb +.section sjgha +.section sjghb +.section sjgia +.section sjgib +.section sjgja +.section sjgjb +.section sjgka +.section sjgkb +.section sjgla +.section sjglb +.section sjgma +.section sjgmb +.section sjgna +.section sjgnb +.section sjgoa +.section sjgob +.section sjgpa +.section sjgpb +.section sjgqa +.section sjgqb +.section sjgra +.section sjgrb +.section sjgsa +.section sjgsb +.section sjgta +.section sjgtb +.section sjgua +.section sjgub +.section sjgva +.section sjgvb +.section sjgwa +.section sjgwb +.section sjgxa +.section sjgxb +.section sjgya +.section sjgyb +.section sjgza +.section sjgzb +.section sjg1a +.section sjg1b +.section sjg2a +.section sjg2b +.section sjg3a +.section sjg3b +.section sjg4a +.section sjg4b +.section sjg5a +.section sjg5b +.section sjg6a +.section sjg6b +.section sjg7a +.section sjg7b +.section sjg8a +.section sjg8b +.section sjg9a +.section sjg9b +.section sjg0a +.section sjg0b +.section sjhaa +.section sjhab +.section sjhba +.section sjhbb +.section sjhca +.section sjhcb +.section sjhda +.section sjhdb +.section sjhea +.section sjheb +.section sjhfa +.section sjhfb +.section sjhga +.section sjhgb +.section sjhha +.section sjhhb +.section sjhia +.section sjhib +.section sjhja +.section sjhjb +.section sjhka +.section sjhkb +.section sjhla +.section sjhlb +.section sjhma +.section sjhmb +.section sjhna +.section sjhnb +.section sjhoa +.section sjhob +.section sjhpa +.section sjhpb +.section sjhqa +.section sjhqb +.section sjhra +.section sjhrb +.section sjhsa +.section sjhsb +.section sjhta +.section sjhtb +.section sjhua +.section sjhub +.section sjhva +.section sjhvb +.section sjhwa +.section sjhwb +.section sjhxa +.section sjhxb +.section sjhya +.section sjhyb +.section sjhza +.section sjhzb +.section sjh1a +.section sjh1b +.section sjh2a +.section sjh2b +.section sjh3a +.section sjh3b +.section sjh4a +.section sjh4b +.section sjh5a +.section sjh5b +.section sjh6a +.section sjh6b +.section sjh7a +.section sjh7b +.section sjh8a +.section sjh8b +.section sjh9a +.section sjh9b +.section sjh0a +.section sjh0b +.section sjiaa +.section sjiab +.section sjiba +.section sjibb +.section sjica +.section sjicb +.section sjida +.section sjidb +.section sjiea +.section sjieb +.section sjifa +.section sjifb +.section sjiga +.section sjigb +.section sjiha +.section sjihb +.section sjiia +.section sjiib +.section sjija +.section sjijb +.section sjika +.section sjikb +.section sjila +.section sjilb +.section sjima +.section sjimb +.section sjina +.section sjinb +.section sjioa +.section sjiob +.section sjipa +.section sjipb +.section sjiqa +.section sjiqb +.section sjira +.section sjirb +.section sjisa +.section sjisb +.section sjita +.section sjitb +.section sjiua +.section sjiub +.section sjiva +.section sjivb +.section sjiwa +.section sjiwb +.section sjixa +.section sjixb +.section sjiya +.section sjiyb +.section sjiza +.section sjizb +.section sji1a +.section sji1b +.section sji2a +.section sji2b +.section sji3a +.section sji3b +.section sji4a +.section sji4b +.section sji5a +.section sji5b +.section sji6a +.section sji6b +.section sji7a +.section sji7b +.section sji8a +.section sji8b +.section sji9a +.section sji9b +.section sji0a +.section sji0b +.section sjjaa +.section sjjab +.section sjjba +.section sjjbb +.section sjjca +.section sjjcb +.section sjjda +.section sjjdb +.section sjjea +.section sjjeb +.section sjjfa +.section sjjfb +.section sjjga +.section sjjgb +.section sjjha +.section sjjhb +.section sjjia +.section sjjib +.section sjjja +.section sjjjb +.section sjjka +.section sjjkb +.section sjjla +.section sjjlb +.section sjjma +.section sjjmb +.section sjjna +.section sjjnb +.section sjjoa +.section sjjob +.section sjjpa +.section sjjpb +.section sjjqa +.section sjjqb +.section sjjra +.section sjjrb +.section sjjsa +.section sjjsb +.section sjjta +.section sjjtb +.section sjjua +.section sjjub +.section sjjva +.section sjjvb +.section sjjwa +.section sjjwb +.section sjjxa +.section sjjxb +.section sjjya +.section sjjyb +.section sjjza +.section sjjzb +.section sjj1a +.section sjj1b +.section sjj2a +.section sjj2b +.section sjj3a +.section sjj3b +.section sjj4a +.section sjj4b +.section sjj5a +.section sjj5b +.section sjj6a +.section sjj6b +.section sjj7a +.section sjj7b +.section sjj8a +.section sjj8b +.section sjj9a +.section sjj9b +.section sjj0a +.section sjj0b +.section sjkaa +.section sjkab +.section sjkba +.section sjkbb +.section sjkca +.section sjkcb +.section sjkda +.section sjkdb +.section sjkea +.section sjkeb +.section sjkfa +.section sjkfb +.section sjkga +.section sjkgb +.section sjkha +.section sjkhb +.section sjkia +.section sjkib +.section sjkja +.section sjkjb +.section sjkka +.section sjkkb +.section sjkla +.section sjklb +.section sjkma +.section sjkmb +.section sjkna +.section sjknb +.section sjkoa +.section sjkob +.section sjkpa +.section sjkpb +.section sjkqa +.section sjkqb +.section sjkra +.section sjkrb +.section sjksa +.section sjksb +.section sjkta +.section sjktb +.section sjkua +.section sjkub +.section sjkva +.section sjkvb +.section sjkwa +.section sjkwb +.section sjkxa +.section sjkxb +.section sjkya +.section sjkyb +.section sjkza +.section sjkzb +.section sjk1a +.section sjk1b +.section sjk2a +.section sjk2b +.section sjk3a +.section sjk3b +.section sjk4a +.section sjk4b +.section sjk5a +.section sjk5b +.section sjk6a +.section sjk6b +.section sjk7a +.section sjk7b +.section sjk8a +.section sjk8b +.section sjk9a +.section sjk9b +.section sjk0a +.section sjk0b +.section sjlaa +.section sjlab +.section sjlba +.section sjlbb +.section sjlca +.section sjlcb +.section sjlda +.section sjldb +.section sjlea +.section sjleb +.section sjlfa +.section sjlfb +.section sjlga +.section sjlgb +.section sjlha +.section sjlhb +.section sjlia +.section sjlib +.section sjlja +.section sjljb +.section sjlka +.section sjlkb +.section sjlla +.section sjllb +.section sjlma +.section sjlmb +.section sjlna +.section sjlnb +.section sjloa +.section sjlob +.section sjlpa +.section sjlpb +.section sjlqa +.section sjlqb +.section sjlra +.section sjlrb +.section sjlsa +.section sjlsb +.section sjlta +.section sjltb +.section sjlua +.section sjlub +.section sjlva +.section sjlvb +.section sjlwa +.section sjlwb +.section sjlxa +.section sjlxb +.section sjlya +.section sjlyb +.section sjlza +.section sjlzb +.section sjl1a +.section sjl1b +.section sjl2a +.section sjl2b +.section sjl3a +.section sjl3b +.section sjl4a +.section sjl4b +.section sjl5a +.section sjl5b +.section sjl6a +.section sjl6b +.section sjl7a +.section sjl7b +.section sjl8a +.section sjl8b +.section sjl9a +.section sjl9b +.section sjl0a +.section sjl0b +.section sjmaa +.section sjmab +.section sjmba +.section sjmbb +.section sjmca +.section sjmcb +.section sjmda +.section sjmdb +.section sjmea +.section sjmeb +.section sjmfa +.section sjmfb +.section sjmga +.section sjmgb +.section sjmha +.section sjmhb +.section sjmia +.section sjmib +.section sjmja +.section sjmjb +.section sjmka +.section sjmkb +.section sjmla +.section sjmlb +.section sjmma +.section sjmmb +.section sjmna +.section sjmnb +.section sjmoa +.section sjmob +.section sjmpa +.section sjmpb +.section sjmqa +.section sjmqb +.section sjmra +.section sjmrb +.section sjmsa +.section sjmsb +.section sjmta +.section sjmtb +.section sjmua +.section sjmub +.section sjmva +.section sjmvb +.section sjmwa +.section sjmwb +.section sjmxa +.section sjmxb +.section sjmya +.section sjmyb +.section sjmza +.section sjmzb +.section sjm1a +.section sjm1b +.section sjm2a +.section sjm2b +.section sjm3a +.section sjm3b +.section sjm4a +.section sjm4b +.section sjm5a +.section sjm5b +.section sjm6a +.section sjm6b +.section sjm7a +.section sjm7b +.section sjm8a +.section sjm8b +.section sjm9a +.section sjm9b +.section sjm0a +.section sjm0b +.section sjnaa +.section sjnab +.section sjnba +.section sjnbb +.section sjnca +.section sjncb +.section sjnda +.section sjndb +.section sjnea +.section sjneb +.section sjnfa +.section sjnfb +.section sjnga +.section sjngb +.section sjnha +.section sjnhb +.section sjnia +.section sjnib +.section sjnja +.section sjnjb +.section sjnka +.section sjnkb +.section sjnla +.section sjnlb +.section sjnma +.section sjnmb +.section sjnna +.section sjnnb +.section sjnoa +.section sjnob +.section sjnpa +.section sjnpb +.section sjnqa +.section sjnqb +.section sjnra +.section sjnrb +.section sjnsa +.section sjnsb +.section sjnta +.section sjntb +.section sjnua +.section sjnub +.section sjnva +.section sjnvb +.section sjnwa +.section sjnwb +.section sjnxa +.section sjnxb +.section sjnya +.section sjnyb +.section sjnza +.section sjnzb +.section sjn1a +.section sjn1b +.section sjn2a +.section sjn2b +.section sjn3a +.section sjn3b +.section sjn4a +.section sjn4b +.section sjn5a +.section sjn5b +.section sjn6a +.section sjn6b +.section sjn7a +.section sjn7b +.section sjn8a +.section sjn8b +.section sjn9a +.section sjn9b +.section sjn0a +.section sjn0b +.section sjoaa +.section sjoab +.section sjoba +.section sjobb +.section sjoca +.section sjocb +.section sjoda +.section sjodb +.section sjoea +.section sjoeb +.section sjofa +.section sjofb +.section sjoga +.section sjogb +.section sjoha +.section sjohb +.section sjoia +.section sjoib +.section sjoja +.section sjojb +.section sjoka +.section sjokb +.section sjola +.section sjolb +.section sjoma +.section sjomb +.section sjona +.section sjonb +.section sjooa +.section sjoob +.section sjopa +.section sjopb +.section sjoqa +.section sjoqb +.section sjora +.section sjorb +.section sjosa +.section sjosb +.section sjota +.section sjotb +.section sjoua +.section sjoub +.section sjova +.section sjovb +.section sjowa +.section sjowb +.section sjoxa +.section sjoxb +.section sjoya +.section sjoyb +.section sjoza +.section sjozb +.section sjo1a +.section sjo1b +.section sjo2a +.section sjo2b +.section sjo3a +.section sjo3b +.section sjo4a +.section sjo4b +.section sjo5a +.section sjo5b +.section sjo6a +.section sjo6b +.section sjo7a +.section sjo7b +.section sjo8a +.section sjo8b +.section sjo9a +.section sjo9b +.section sjo0a +.section sjo0b +.section sjpaa +.section sjpab +.section sjpba +.section sjpbb +.section sjpca +.section sjpcb +.section sjpda +.section sjpdb +.section sjpea +.section sjpeb +.section sjpfa +.section sjpfb +.section sjpga +.section sjpgb +.section sjpha +.section sjphb +.section sjpia +.section sjpib +.section sjpja +.section sjpjb +.section sjpka +.section sjpkb +.section sjpla +.section sjplb +.section sjpma +.section sjpmb +.section sjpna +.section sjpnb +.section sjpoa +.section sjpob +.section sjppa +.section sjppb +.section sjpqa +.section sjpqb +.section sjpra +.section sjprb +.section sjpsa +.section sjpsb +.section sjpta +.section sjptb +.section sjpua +.section sjpub +.section sjpva +.section sjpvb +.section sjpwa +.section sjpwb +.section sjpxa +.section sjpxb +.section sjpya +.section sjpyb +.section sjpza +.section sjpzb +.section sjp1a +.section sjp1b +.section sjp2a +.section sjp2b +.section sjp3a +.section sjp3b +.section sjp4a +.section sjp4b +.section sjp5a +.section sjp5b +.section sjp6a +.section sjp6b +.section sjp7a +.section sjp7b +.section sjp8a +.section sjp8b +.section sjp9a +.section sjp9b +.section sjp0a +.section sjp0b +.section sjqaa +.section sjqab +.section sjqba +.section sjqbb +.section sjqca +.section sjqcb +.section sjqda +.section sjqdb +.section sjqea +.section sjqeb +.section sjqfa +.section sjqfb +.section sjqga +.section sjqgb +.section sjqha +.section sjqhb +.section sjqia +.section sjqib +.section sjqja +.section sjqjb +.section sjqka +.section sjqkb +.section sjqla +.section sjqlb +.section sjqma +.section sjqmb +.section sjqna +.section sjqnb +.section sjqoa +.section sjqob +.section sjqpa +.section sjqpb +.section sjqqa +.section sjqqb +.section sjqra +.section sjqrb +.section sjqsa +.section sjqsb +.section sjqta +.section sjqtb +.section sjqua +.section sjqub +.section sjqva +.section sjqvb +.section sjqwa +.section sjqwb +.section sjqxa +.section sjqxb +.section sjqya +.section sjqyb +.section sjqza +.section sjqzb +.section sjq1a +.section sjq1b +.section sjq2a +.section sjq2b +.section sjq3a +.section sjq3b +.section sjq4a +.section sjq4b +.section sjq5a +.section sjq5b +.section sjq6a +.section sjq6b +.section sjq7a +.section sjq7b +.section sjq8a +.section sjq8b +.section sjq9a +.section sjq9b +.section sjq0a +.section sjq0b +.section sjraa +.section sjrab +.section sjrba +.section sjrbb +.section sjrca +.section sjrcb +.section sjrda +.section sjrdb +.section sjrea +.section sjreb +.section sjrfa +.section sjrfb +.section sjrga +.section sjrgb +.section sjrha +.section sjrhb +.section sjria +.section sjrib +.section sjrja +.section sjrjb +.section sjrka +.section sjrkb +.section sjrla +.section sjrlb +.section sjrma +.section sjrmb +.section sjrna +.section sjrnb +.section sjroa +.section sjrob +.section sjrpa +.section sjrpb +.section sjrqa +.section sjrqb +.section sjrra +.section sjrrb +.section sjrsa +.section sjrsb +.section sjrta +.section sjrtb +.section sjrua +.section sjrub +.section sjrva +.section sjrvb +.section sjrwa +.section sjrwb +.section sjrxa +.section sjrxb +.section sjrya +.section sjryb +.section sjrza +.section sjrzb +.section sjr1a +.section sjr1b +.section sjr2a +.section sjr2b +.section sjr3a +.section sjr3b +.section sjr4a +.section sjr4b +.section sjr5a +.section sjr5b +.section sjr6a +.section sjr6b +.section sjr7a +.section sjr7b +.section sjr8a +.section sjr8b +.section sjr9a +.section sjr9b +.section sjr0a +.section sjr0b +.section sjsaa +.section sjsab +.section sjsba +.section sjsbb +.section sjsca +.section sjscb +.section sjsda +.section sjsdb +.section sjsea +.section sjseb +.section sjsfa +.section sjsfb +.section sjsga +.section sjsgb +.section sjsha +.section sjshb +.section sjsia +.section sjsib +.section sjsja +.section sjsjb +.section sjska +.section sjskb +.section sjsla +.section sjslb +.section sjsma +.section sjsmb +.section sjsna +.section sjsnb +.section sjsoa +.section sjsob +.section sjspa +.section sjspb +.section sjsqa +.section sjsqb +.section sjsra +.section sjsrb +.section sjssa +.section sjssb +.section sjsta +.section sjstb +.section sjsua +.section sjsub +.section sjsva +.section sjsvb +.section sjswa +.section sjswb +.section sjsxa +.section sjsxb +.section sjsya +.section sjsyb +.section sjsza +.section sjszb +.section sjs1a +.section sjs1b +.section sjs2a +.section sjs2b +.section sjs3a +.section sjs3b +.section sjs4a +.section sjs4b +.section sjs5a +.section sjs5b +.section sjs6a +.section sjs6b +.section sjs7a +.section sjs7b +.section sjs8a +.section sjs8b +.section sjs9a +.section sjs9b +.section sjs0a +.section sjs0b +.section sjtaa +.section sjtab +.section sjtba +.section sjtbb +.section sjtca +.section sjtcb +.section sjtda +.section sjtdb +.section sjtea +.section sjteb +.section sjtfa +.section sjtfb +.section sjtga +.section sjtgb +.section sjtha +.section sjthb +.section sjtia +.section sjtib +.section sjtja +.section sjtjb +.section sjtka +.section sjtkb +.section sjtla +.section sjtlb +.section sjtma +.section sjtmb +.section sjtna +.section sjtnb +.section sjtoa +.section sjtob +.section sjtpa +.section sjtpb +.section sjtqa +.section sjtqb +.section sjtra +.section sjtrb +.section sjtsa +.section sjtsb +.section sjtta +.section sjttb +.section sjtua +.section sjtub +.section sjtva +.section sjtvb +.section sjtwa +.section sjtwb +.section sjtxa +.section sjtxb +.section sjtya +.section sjtyb +.section sjtza +.section sjtzb +.section sjt1a +.section sjt1b +.section sjt2a +.section sjt2b +.section sjt3a +.section sjt3b +.section sjt4a +.section sjt4b +.section sjt5a +.section sjt5b +.section sjt6a +.section sjt6b +.section sjt7a +.section sjt7b +.section sjt8a +.section sjt8b +.section sjt9a +.section sjt9b +.section sjt0a +.section sjt0b +.section sjuaa +.section sjuab +.section sjuba +.section sjubb +.section sjuca +.section sjucb +.section sjuda +.section sjudb +.section sjuea +.section sjueb +.section sjufa +.section sjufb +.section sjuga +.section sjugb +.section sjuha +.section sjuhb +.section sjuia +.section sjuib +.section sjuja +.section sjujb +.section sjuka +.section sjukb +.section sjula +.section sjulb +.section sjuma +.section sjumb +.section sjuna +.section sjunb +.section sjuoa +.section sjuob +.section sjupa +.section sjupb +.section sjuqa +.section sjuqb +.section sjura +.section sjurb +.section sjusa +.section sjusb +.section sjuta +.section sjutb +.section sjuua +.section sjuub +.section sjuva +.section sjuvb +.section sjuwa +.section sjuwb +.section sjuxa +.section sjuxb +.section sjuya +.section sjuyb +.section sjuza +.section sjuzb +.section sju1a +.section sju1b +.section sju2a +.section sju2b +.section sju3a +.section sju3b +.section sju4a +.section sju4b +.section sju5a +.section sju5b +.section sju6a +.section sju6b +.section sju7a +.section sju7b +.section sju8a +.section sju8b +.section sju9a +.section sju9b +.section sju0a +.section sju0b +.section sjvaa +.section sjvab +.section sjvba +.section sjvbb +.section sjvca +.section sjvcb +.section sjvda +.section sjvdb +.section sjvea +.section sjveb +.section sjvfa +.section sjvfb +.section sjvga +.section sjvgb +.section sjvha +.section sjvhb +.section sjvia +.section sjvib +.section sjvja +.section sjvjb +.section sjvka +.section sjvkb +.section sjvla +.section sjvlb +.section sjvma +.section sjvmb +.section sjvna +.section sjvnb +.section sjvoa +.section sjvob +.section sjvpa +.section sjvpb +.section sjvqa +.section sjvqb +.section sjvra +.section sjvrb +.section sjvsa +.section sjvsb +.section sjvta +.section sjvtb +.section sjvua +.section sjvub +.section sjvva +.section sjvvb +.section sjvwa +.section sjvwb +.section sjvxa +.section sjvxb +.section sjvya +.section sjvyb +.section sjvza +.section sjvzb +.section sjv1a +.section sjv1b +.section sjv2a +.section sjv2b +.section sjv3a +.section sjv3b +.section sjv4a +.section sjv4b +.section sjv5a +.section sjv5b +.section sjv6a +.section sjv6b +.section sjv7a +.section sjv7b +.section sjv8a +.section sjv8b +.section sjv9a +.section sjv9b +.section sjv0a +.section sjv0b +.section sjwaa +.section sjwab +.section sjwba +.section sjwbb +.section sjwca +.section sjwcb +.section sjwda +.section sjwdb +.section sjwea +.section sjweb +.section sjwfa +.section sjwfb +.section sjwga +.section sjwgb +.section sjwha +.section sjwhb +.section sjwia +.section sjwib +.section sjwja +.section sjwjb +.section sjwka +.section sjwkb +.section sjwla +.section sjwlb +.section sjwma +.section sjwmb +.section sjwna +.section sjwnb +.section sjwoa +.section sjwob +.section sjwpa +.section sjwpb +.section sjwqa +.section sjwqb +.section sjwra +.section sjwrb +.section sjwsa +.section sjwsb +.section sjwta +.section sjwtb +.section sjwua +.section sjwub +.section sjwva +.section sjwvb +.section sjwwa +.section sjwwb +.section sjwxa +.section sjwxb +.section sjwya +.section sjwyb +.section sjwza +.section sjwzb +.section sjw1a +.section sjw1b +.section sjw2a +.section sjw2b +.section sjw3a +.section sjw3b +.section sjw4a +.section sjw4b +.section sjw5a +.section sjw5b +.section sjw6a +.section sjw6b +.section sjw7a +.section sjw7b +.section sjw8a +.section sjw8b +.section sjw9a +.section sjw9b +.section sjw0a +.section sjw0b +.section sjxaa +.section sjxab +.section sjxba +.section sjxbb +.section sjxca +.section sjxcb +.section sjxda +.section sjxdb +.section sjxea +.section sjxeb +.section sjxfa +.section sjxfb +.section sjxga +.section sjxgb +.section sjxha +.section sjxhb +.section sjxia +.section sjxib +.section sjxja +.section sjxjb +.section sjxka +.section sjxkb +.section sjxla +.section sjxlb +.section sjxma +.section sjxmb +.section sjxna +.section sjxnb +.section sjxoa +.section sjxob +.section sjxpa +.section sjxpb +.section sjxqa +.section sjxqb +.section sjxra +.section sjxrb +.section sjxsa +.section sjxsb +.section sjxta +.section sjxtb +.section sjxua +.section sjxub +.section sjxva +.section sjxvb +.section sjxwa +.section sjxwb +.section sjxxa +.section sjxxb +.section sjxya +.section sjxyb +.section sjxza +.section sjxzb +.section sjx1a +.section sjx1b +.section sjx2a +.section sjx2b +.section sjx3a +.section sjx3b +.section sjx4a +.section sjx4b +.section sjx5a +.section sjx5b +.section sjx6a +.section sjx6b +.section sjx7a +.section sjx7b +.section sjx8a +.section sjx8b +.section sjx9a +.section sjx9b +.section sjx0a +.section sjx0b +.section sjyaa +.section sjyab +.section sjyba +.section sjybb +.section sjyca +.section sjycb +.section sjyda +.section sjydb +.section sjyea +.section sjyeb +.section sjyfa +.section sjyfb +.section sjyga +.section sjygb +.section sjyha +.section sjyhb +.section sjyia +.section sjyib +.section sjyja +.section sjyjb +.section sjyka +.section sjykb +.section sjyla +.section sjylb +.section sjyma +.section sjymb +.section sjyna +.section sjynb +.section sjyoa +.section sjyob +.section sjypa +.section sjypb +.section sjyqa +.section sjyqb +.section sjyra +.section sjyrb +.section sjysa +.section sjysb +.section sjyta +.section sjytb +.section sjyua +.section sjyub +.section sjyva +.section sjyvb +.section sjywa +.section sjywb +.section sjyxa +.section sjyxb +.section sjyya +.section sjyyb +.section sjyza +.section sjyzb +.section sjy1a +.section sjy1b +.section sjy2a +.section sjy2b +.section sjy3a +.section sjy3b +.section sjy4a +.section sjy4b +.section sjy5a +.section sjy5b +.section sjy6a +.section sjy6b +.section sjy7a +.section sjy7b +.section sjy8a +.section sjy8b +.section sjy9a +.section sjy9b +.section sjy0a +.section sjy0b +.section sjzaa +.section sjzab +.section sjzba +.section sjzbb +.section sjzca +.section sjzcb +.section sjzda +.section sjzdb +.section sjzea +.section sjzeb +.section sjzfa +.section sjzfb +.section sjzga +.section sjzgb +.section sjzha +.section sjzhb +.section sjzia +.section sjzib +.section sjzja +.section sjzjb +.section sjzka +.section sjzkb +.section sjzla +.section sjzlb +.section sjzma +.section sjzmb +.section sjzna +.section sjznb +.section sjzoa +.section sjzob +.section sjzpa +.section sjzpb +.section sjzqa +.section sjzqb +.section sjzra +.section sjzrb +.section sjzsa +.section sjzsb +.section sjzta +.section sjztb +.section sjzua +.section sjzub +.section sjzva +.section sjzvb +.section sjzwa +.section sjzwb +.section sjzxa +.section sjzxb +.section sjzya +.section sjzyb +.section sjzza +.section sjzzb +.section sjz1a +.section sjz1b +.section sjz2a +.section sjz2b +.section sjz3a +.section sjz3b +.section sjz4a +.section sjz4b +.section sjz5a +.section sjz5b +.section sjz6a +.section sjz6b +.section sjz7a +.section sjz7b +.section sjz8a +.section sjz8b +.section sjz9a +.section sjz9b +.section sjz0a +.section sjz0b +.section sj1aa +.section sj1ab +.section sj1ba +.section sj1bb +.section sj1ca +.section sj1cb +.section sj1da +.section sj1db +.section sj1ea +.section sj1eb +.section sj1fa +.section sj1fb +.section sj1ga +.section sj1gb +.section sj1ha +.section sj1hb +.section sj1ia +.section sj1ib +.section sj1ja +.section sj1jb +.section sj1ka +.section sj1kb +.section sj1la +.section sj1lb +.section sj1ma +.section sj1mb +.section sj1na +.section sj1nb +.section sj1oa +.section sj1ob +.section sj1pa +.section sj1pb +.section sj1qa +.section sj1qb +.section sj1ra +.section sj1rb +.section sj1sa +.section sj1sb +.section sj1ta +.section sj1tb +.section sj1ua +.section sj1ub +.section sj1va +.section sj1vb +.section sj1wa +.section sj1wb +.section sj1xa +.section sj1xb +.section sj1ya +.section sj1yb +.section sj1za +.section sj1zb +.section sj11a +.section sj11b +.section sj12a +.section sj12b +.section sj13a +.section sj13b +.section sj14a +.section sj14b +.section sj15a +.section sj15b +.section sj16a +.section sj16b +.section sj17a +.section sj17b +.section sj18a +.section sj18b +.section sj19a +.section sj19b +.section sj10a +.section sj10b +.section sj2aa +.section sj2ab +.section sj2ba +.section sj2bb +.section sj2ca +.section sj2cb +.section sj2da +.section sj2db +.section sj2ea +.section sj2eb +.section sj2fa +.section sj2fb +.section sj2ga +.section sj2gb +.section sj2ha +.section sj2hb +.section sj2ia +.section sj2ib +.section sj2ja +.section sj2jb +.section sj2ka +.section sj2kb +.section sj2la +.section sj2lb +.section sj2ma +.section sj2mb +.section sj2na +.section sj2nb +.section sj2oa +.section sj2ob +.section sj2pa +.section sj2pb +.section sj2qa +.section sj2qb +.section sj2ra +.section sj2rb +.section sj2sa +.section sj2sb +.section sj2ta +.section sj2tb +.section sj2ua +.section sj2ub +.section sj2va +.section sj2vb +.section sj2wa +.section sj2wb +.section sj2xa +.section sj2xb +.section sj2ya +.section sj2yb +.section sj2za +.section sj2zb +.section sj21a +.section sj21b +.section sj22a +.section sj22b +.section sj23a +.section sj23b +.section sj24a +.section sj24b +.section sj25a +.section sj25b +.section sj26a +.section sj26b +.section sj27a +.section sj27b +.section sj28a +.section sj28b +.section sj29a +.section sj29b +.section sj20a +.section sj20b +.section sj3aa +.section sj3ab +.section sj3ba +.section sj3bb +.section sj3ca +.section sj3cb +.section sj3da +.section sj3db +.section sj3ea +.section sj3eb +.section sj3fa +.section sj3fb +.section sj3ga +.section sj3gb +.section sj3ha +.section sj3hb +.section sj3ia +.section sj3ib +.section sj3ja +.section sj3jb +.section sj3ka +.section sj3kb +.section sj3la +.section sj3lb +.section sj3ma +.section sj3mb +.section sj3na +.section sj3nb +.section sj3oa +.section sj3ob +.section sj3pa +.section sj3pb +.section sj3qa +.section sj3qb +.section sj3ra +.section sj3rb +.section sj3sa +.section sj3sb +.section sj3ta +.section sj3tb +.section sj3ua +.section sj3ub +.section sj3va +.section sj3vb +.section sj3wa +.section sj3wb +.section sj3xa +.section sj3xb +.section sj3ya +.section sj3yb +.section sj3za +.section sj3zb +.section sj31a +.section sj31b +.section sj32a +.section sj32b +.section sj33a +.section sj33b +.section sj34a +.section sj34b +.section sj35a +.section sj35b +.section sj36a +.section sj36b +.section sj37a +.section sj37b +.section sj38a +.section sj38b +.section sj39a +.section sj39b +.section sj30a +.section sj30b +.section sj4aa +.section sj4ab +.section sj4ba +.section sj4bb +.section sj4ca +.section sj4cb +.section sj4da +.section sj4db +.section sj4ea +.section sj4eb +.section sj4fa +.section sj4fb +.section sj4ga +.section sj4gb +.section sj4ha +.section sj4hb +.section sj4ia +.section sj4ib +.section sj4ja +.section sj4jb +.section sj4ka +.section sj4kb +.section sj4la +.section sj4lb +.section sj4ma +.section sj4mb +.section sj4na +.section sj4nb +.section sj4oa +.section sj4ob +.section sj4pa +.section sj4pb +.section sj4qa +.section sj4qb +.section sj4ra +.section sj4rb +.section sj4sa +.section sj4sb +.section sj4ta +.section sj4tb +.section sj4ua +.section sj4ub +.section sj4va +.section sj4vb +.section sj4wa +.section sj4wb +.section sj4xa +.section sj4xb +.section sj4ya +.section sj4yb +.section sj4za +.section sj4zb +.section sj41a +.section sj41b +.section sj42a +.section sj42b +.section sj43a +.section sj43b +.section sj44a +.section sj44b +.section sj45a +.section sj45b +.section sj46a +.section sj46b +.section sj47a +.section sj47b +.section sj48a +.section sj48b +.section sj49a +.section sj49b +.section sj40a +.section sj40b +.section sj5aa +.section sj5ab +.section sj5ba +.section sj5bb +.section sj5ca +.section sj5cb +.section sj5da +.section sj5db +.section sj5ea +.section sj5eb +.section sj5fa +.section sj5fb +.section sj5ga +.section sj5gb +.section sj5ha +.section sj5hb +.section sj5ia +.section sj5ib +.section sj5ja +.section sj5jb +.section sj5ka +.section sj5kb +.section sj5la +.section sj5lb +.section sj5ma +.section sj5mb +.section sj5na +.section sj5nb +.section sj5oa +.section sj5ob +.section sj5pa +.section sj5pb +.section sj5qa +.section sj5qb +.section sj5ra +.section sj5rb +.section sj5sa +.section sj5sb +.section sj5ta +.section sj5tb +.section sj5ua +.section sj5ub +.section sj5va +.section sj5vb +.section sj5wa +.section sj5wb +.section sj5xa +.section sj5xb +.section sj5ya +.section sj5yb +.section sj5za +.section sj5zb +.section sj51a +.section sj51b +.section sj52a +.section sj52b +.section sj53a +.section sj53b +.section sj54a +.section sj54b +.section sj55a +.section sj55b +.section sj56a +.section sj56b +.section sj57a +.section sj57b +.section sj58a +.section sj58b +.section sj59a +.section sj59b +.section sj50a +.section sj50b +.section sj6aa +.section sj6ab +.section sj6ba +.section sj6bb +.section sj6ca +.section sj6cb +.section sj6da +.section sj6db +.section sj6ea +.section sj6eb +.section sj6fa +.section sj6fb +.section sj6ga +.section sj6gb +.section sj6ha +.section sj6hb +.section sj6ia +.section sj6ib +.section sj6ja +.section sj6jb +.section sj6ka +.section sj6kb +.section sj6la +.section sj6lb +.section sj6ma +.section sj6mb +.section sj6na +.section sj6nb +.section sj6oa +.section sj6ob +.section sj6pa +.section sj6pb +.section sj6qa +.section sj6qb +.section sj6ra +.section sj6rb +.section sj6sa +.section sj6sb +.section sj6ta +.section sj6tb +.section sj6ua +.section sj6ub +.section sj6va +.section sj6vb +.section sj6wa +.section sj6wb +.section sj6xa +.section sj6xb +.section sj6ya +.section sj6yb +.section sj6za +.section sj6zb +.section sj61a +.section sj61b +.section sj62a +.section sj62b +.section sj63a +.section sj63b +.section sj64a +.section sj64b +.section sj65a +.section sj65b +.section sj66a +.section sj66b +.section sj67a +.section sj67b +.section sj68a +.section sj68b +.section sj69a +.section sj69b +.section sj60a +.section sj60b +.section sj7aa +.section sj7ab +.section sj7ba +.section sj7bb +.section sj7ca +.section sj7cb +.section sj7da +.section sj7db +.section sj7ea +.section sj7eb +.section sj7fa +.section sj7fb +.section sj7ga +.section sj7gb +.section sj7ha +.section sj7hb +.section sj7ia +.section sj7ib +.section sj7ja +.section sj7jb +.section sj7ka +.section sj7kb +.section sj7la +.section sj7lb +.section sj7ma +.section sj7mb +.section sj7na +.section sj7nb +.section sj7oa +.section sj7ob +.section sj7pa +.section sj7pb +.section sj7qa +.section sj7qb +.section sj7ra +.section sj7rb +.section sj7sa +.section sj7sb +.section sj7ta +.section sj7tb +.section sj7ua +.section sj7ub +.section sj7va +.section sj7vb +.section sj7wa +.section sj7wb +.section sj7xa +.section sj7xb +.section sj7ya +.section sj7yb +.section sj7za +.section sj7zb +.section sj71a +.section sj71b +.section sj72a +.section sj72b +.section sj73a +.section sj73b +.section sj74a +.section sj74b +.section sj75a +.section sj75b +.section sj76a +.section sj76b +.section sj77a +.section sj77b +.section sj78a +.section sj78b +.section sj79a +.section sj79b +.section sj70a +.section sj70b +.section sj8aa +.section sj8ab +.section sj8ba +.section sj8bb +.section sj8ca +.section sj8cb +.section sj8da +.section sj8db +.section sj8ea +.section sj8eb +.section sj8fa +.section sj8fb +.section sj8ga +.section sj8gb +.section sj8ha +.section sj8hb +.section sj8ia +.section sj8ib +.section sj8ja +.section sj8jb +.section sj8ka +.section sj8kb +.section sj8la +.section sj8lb +.section sj8ma +.section sj8mb +.section sj8na +.section sj8nb +.section sj8oa +.section sj8ob +.section sj8pa +.section sj8pb +.section sj8qa +.section sj8qb +.section sj8ra +.section sj8rb +.section sj8sa +.section sj8sb +.section sj8ta +.section sj8tb +.section sj8ua +.section sj8ub +.section sj8va +.section sj8vb +.section sj8wa +.section sj8wb +.section sj8xa +.section sj8xb +.section sj8ya +.section sj8yb +.section sj8za +.section sj8zb +.section sj81a +.section sj81b +.section sj82a +.section sj82b +.section sj83a +.section sj83b +.section sj84a +.section sj84b +.section sj85a +.section sj85b +.section sj86a +.section sj86b +.section sj87a +.section sj87b +.section sj88a +.section sj88b +.section sj89a +.section sj89b +.section sj80a +.section sj80b +.section sj9aa +.section sj9ab +.section sj9ba +.section sj9bb +.section sj9ca +.section sj9cb +.section sj9da +.section sj9db +.section sj9ea +.section sj9eb +.section sj9fa +.section sj9fb +.section sj9ga +.section sj9gb +.section sj9ha +.section sj9hb +.section sj9ia +.section sj9ib +.section sj9ja +.section sj9jb +.section sj9ka +.section sj9kb +.section sj9la +.section sj9lb +.section sj9ma +.section sj9mb +.section sj9na +.section sj9nb +.section sj9oa +.section sj9ob +.section sj9pa +.section sj9pb +.section sj9qa +.section sj9qb +.section sj9ra +.section sj9rb +.section sj9sa +.section sj9sb +.section sj9ta +.section sj9tb +.section sj9ua +.section sj9ub +.section sj9va +.section sj9vb +.section sj9wa +.section sj9wb +.section sj9xa +.section sj9xb +.section sj9ya +.section sj9yb +.section sj9za +.section sj9zb +.section sj91a +.section sj91b +.section sj92a +.section sj92b +.section sj93a +.section sj93b +.section sj94a +.section sj94b +.section sj95a +.section sj95b +.section sj96a +.section sj96b +.section sj97a +.section sj97b +.section sj98a +.section sj98b +.section sj99a +.section sj99b +.section sj90a +.section sj90b +.section sj0aa +.section sj0ab +.section sj0ba +.section sj0bb +.section sj0ca +.section sj0cb +.section sj0da +.section sj0db +.section sj0ea +.section sj0eb +.section sj0fa +.section sj0fb +.section sj0ga +.section sj0gb +.section sj0ha +.section sj0hb +.section sj0ia +.section sj0ib +.section sj0ja +.section sj0jb +.section sj0ka +.section sj0kb +.section sj0la +.section sj0lb +.section sj0ma +.section sj0mb +.section sj0na +.section sj0nb +.section sj0oa +.section sj0ob +.section sj0pa +.section sj0pb +.section sj0qa +.section sj0qb +.section sj0ra +.section sj0rb +.section sj0sa +.section sj0sb +.section sj0ta +.section sj0tb +.section sj0ua +.section sj0ub +.section sj0va +.section sj0vb +.section sj0wa +.section sj0wb +.section sj0xa +.section sj0xb +.section sj0ya +.section sj0yb +.section sj0za +.section sj0zb +.section sj01a +.section sj01b +.section sj02a +.section sj02b +.section sj03a +.section sj03b +.section sj04a +.section sj04b +.section sj05a +.section sj05b +.section sj06a +.section sj06b +.section sj07a +.section sj07b +.section sj08a +.section sj08b +.section sj09a +.section sj09b +.section sj00a +.section sj00b +.section skaaa +.section skaab +.section skaba +.section skabb +.section skaca +.section skacb +.section skada +.section skadb +.section skaea +.section skaeb +.section skafa +.section skafb +.section skaga +.section skagb +.section skaha +.section skahb +.section skaia +.section skaib +.section skaja +.section skajb +.section skaka +.section skakb +.section skala +.section skalb +.section skama +.section skamb +.section skana +.section skanb +.section skaoa +.section skaob +.section skapa +.section skapb +.section skaqa +.section skaqb +.section skara +.section skarb +.section skasa +.section skasb +.section skata +.section skatb +.section skaua +.section skaub +.section skava +.section skavb +.section skawa +.section skawb +.section skaxa +.section skaxb +.section skaya +.section skayb +.section skaza +.section skazb +.section ska1a +.section ska1b +.section ska2a +.section ska2b +.section ska3a +.section ska3b +.section ska4a +.section ska4b +.section ska5a +.section ska5b +.section ska6a +.section ska6b +.section ska7a +.section ska7b +.section ska8a +.section ska8b +.section ska9a +.section ska9b +.section ska0a +.section ska0b +.section skbaa +.section skbab +.section skbba +.section skbbb +.section skbca +.section skbcb +.section skbda +.section skbdb +.section skbea +.section skbeb +.section skbfa +.section skbfb +.section skbga +.section skbgb +.section skbha +.section skbhb +.section skbia +.section skbib +.section skbja +.section skbjb +.section skbka +.section skbkb +.section skbla +.section skblb +.section skbma +.section skbmb +.section skbna +.section skbnb +.section skboa +.section skbob +.section skbpa +.section skbpb +.section skbqa +.section skbqb +.section skbra +.section skbrb +.section skbsa +.section skbsb +.section skbta +.section skbtb +.section skbua +.section skbub +.section skbva +.section skbvb +.section skbwa +.section skbwb +.section skbxa +.section skbxb +.section skbya +.section skbyb +.section skbza +.section skbzb +.section skb1a +.section skb1b +.section skb2a +.section skb2b +.section skb3a +.section skb3b +.section skb4a +.section skb4b +.section skb5a +.section skb5b +.section skb6a +.section skb6b +.section skb7a +.section skb7b +.section skb8a +.section skb8b +.section skb9a +.section skb9b +.section skb0a +.section skb0b +.section skcaa +.section skcab +.section skcba +.section skcbb +.section skcca +.section skccb +.section skcda +.section skcdb +.section skcea +.section skceb +.section skcfa +.section skcfb +.section skcga +.section skcgb +.section skcha +.section skchb +.section skcia +.section skcib +.section skcja +.section skcjb +.section skcka +.section skckb +.section skcla +.section skclb +.section skcma +.section skcmb +.section skcna +.section skcnb +.section skcoa +.section skcob +.section skcpa +.section skcpb +.section skcqa +.section skcqb +.section skcra +.section skcrb +.section skcsa +.section skcsb +.section skcta +.section skctb +.section skcua +.section skcub +.section skcva +.section skcvb +.section skcwa +.section skcwb +.section skcxa +.section skcxb +.section skcya +.section skcyb +.section skcza +.section skczb +.section skc1a +.section skc1b +.section skc2a +.section skc2b +.section skc3a +.section skc3b +.section skc4a +.section skc4b +.section skc5a +.section skc5b +.section skc6a +.section skc6b +.section skc7a +.section skc7b +.section skc8a +.section skc8b +.section skc9a +.section skc9b +.section skc0a +.section skc0b +.section skdaa +.section skdab +.section skdba +.section skdbb +.section skdca +.section skdcb +.section skdda +.section skddb +.section skdea +.section skdeb +.section skdfa +.section skdfb +.section skdga +.section skdgb +.section skdha +.section skdhb +.section skdia +.section skdib +.section skdja +.section skdjb +.section skdka +.section skdkb +.section skdla +.section skdlb +.section skdma +.section skdmb +.section skdna +.section skdnb +.section skdoa +.section skdob +.section skdpa +.section skdpb +.section skdqa +.section skdqb +.section skdra +.section skdrb +.section skdsa +.section skdsb +.section skdta +.section skdtb +.section skdua +.section skdub +.section skdva +.section skdvb +.section skdwa +.section skdwb +.section skdxa +.section skdxb +.section skdya +.section skdyb +.section skdza +.section skdzb +.section skd1a +.section skd1b +.section skd2a +.section skd2b +.section skd3a +.section skd3b +.section skd4a +.section skd4b +.section skd5a +.section skd5b +.section skd6a +.section skd6b +.section skd7a +.section skd7b +.section skd8a +.section skd8b +.section skd9a +.section skd9b +.section skd0a +.section skd0b +.section skeaa +.section skeab +.section skeba +.section skebb +.section skeca +.section skecb +.section skeda +.section skedb +.section skeea +.section skeeb +.section skefa +.section skefb +.section skega +.section skegb +.section skeha +.section skehb +.section skeia +.section skeib +.section skeja +.section skejb +.section skeka +.section skekb +.section skela +.section skelb +.section skema +.section skemb +.section skena +.section skenb +.section skeoa +.section skeob +.section skepa +.section skepb +.section skeqa +.section skeqb +.section skera +.section skerb +.section skesa +.section skesb +.section sketa +.section sketb +.section skeua +.section skeub +.section skeva +.section skevb +.section skewa +.section skewb +.section skexa +.section skexb +.section skeya +.section skeyb +.section skeza +.section skezb +.section ske1a +.section ske1b +.section ske2a +.section ske2b +.section ske3a +.section ske3b +.section ske4a +.section ske4b +.section ske5a +.section ske5b +.section ske6a +.section ske6b +.section ske7a +.section ske7b +.section ske8a +.section ske8b +.section ske9a +.section ske9b +.section ske0a +.section ske0b +.section skfaa +.section skfab +.section skfba +.section skfbb +.section skfca +.section skfcb +.section skfda +.section skfdb +.section skfea +.section skfeb +.section skffa +.section skffb +.section skfga +.section skfgb +.section skfha +.section skfhb +.section skfia +.section skfib +.section skfja +.section skfjb +.section skfka +.section skfkb +.section skfla +.section skflb +.section skfma +.section skfmb +.section skfna +.section skfnb +.section skfoa +.section skfob +.section skfpa +.section skfpb +.section skfqa +.section skfqb +.section skfra +.section skfrb +.section skfsa +.section skfsb +.section skfta +.section skftb +.section skfua +.section skfub +.section skfva +.section skfvb +.section skfwa +.section skfwb +.section skfxa +.section skfxb +.section skfya +.section skfyb +.section skfza +.section skfzb +.section skf1a +.section skf1b +.section skf2a +.section skf2b +.section skf3a +.section skf3b +.section skf4a +.section skf4b +.section skf5a +.section skf5b +.section skf6a +.section skf6b +.section skf7a +.section skf7b +.section skf8a +.section skf8b +.section skf9a +.section skf9b +.section skf0a +.section skf0b +.section skgaa +.section skgab +.section skgba +.section skgbb +.section skgca +.section skgcb +.section skgda +.section skgdb +.section skgea +.section skgeb +.section skgfa +.section skgfb +.section skgga +.section skggb +.section skgha +.section skghb +.section skgia +.section skgib +.section skgja +.section skgjb +.section skgka +.section skgkb +.section skgla +.section skglb +.section skgma +.section skgmb +.section skgna +.section skgnb +.section skgoa +.section skgob +.section skgpa +.section skgpb +.section skgqa +.section skgqb +.section skgra +.section skgrb +.section skgsa +.section skgsb +.section skgta +.section skgtb +.section skgua +.section skgub +.section skgva +.section skgvb +.section skgwa +.section skgwb +.section skgxa +.section skgxb +.section skgya +.section skgyb +.section skgza +.section skgzb +.section skg1a +.section skg1b +.section skg2a +.section skg2b +.section skg3a +.section skg3b +.section skg4a +.section skg4b +.section skg5a +.section skg5b +.section skg6a +.section skg6b +.section skg7a +.section skg7b +.section skg8a +.section skg8b +.section skg9a +.section skg9b +.section skg0a +.section skg0b +.section skhaa +.section skhab +.section skhba +.section skhbb +.section skhca +.section skhcb +.section skhda +.section skhdb +.section skhea +.section skheb +.section skhfa +.section skhfb +.section skhga +.section skhgb +.section skhha +.section skhhb +.section skhia +.section skhib +.section skhja +.section skhjb +.section skhka +.section skhkb +.section skhla +.section skhlb +.section skhma +.section skhmb +.section skhna +.section skhnb +.section skhoa +.section skhob +.section skhpa +.section skhpb +.section skhqa +.section skhqb +.section skhra +.section skhrb +.section skhsa +.section skhsb +.section skhta +.section skhtb +.section skhua +.section skhub +.section skhva +.section skhvb +.section skhwa +.section skhwb +.section skhxa +.section skhxb +.section skhya +.section skhyb +.section skhza +.section skhzb +.section skh1a +.section skh1b +.section skh2a +.section skh2b +.section skh3a +.section skh3b +.section skh4a +.section skh4b +.section skh5a +.section skh5b +.section skh6a +.section skh6b +.section skh7a +.section skh7b +.section skh8a +.section skh8b +.section skh9a +.section skh9b +.section skh0a +.section skh0b +.section skiaa +.section skiab +.section skiba +.section skibb +.section skica +.section skicb +.section skida +.section skidb +.section skiea +.section skieb +.section skifa +.section skifb +.section skiga +.section skigb +.section skiha +.section skihb +.section skiia +.section skiib +.section skija +.section skijb +.section skika +.section skikb +.section skila +.section skilb +.section skima +.section skimb +.section skina +.section skinb +.section skioa +.section skiob +.section skipa +.section skipb +.section skiqa +.section skiqb +.section skira +.section skirb +.section skisa +.section skisb +.section skita +.section skitb +.section skiua +.section skiub +.section skiva +.section skivb +.section skiwa +.section skiwb +.section skixa +.section skixb +.section skiya +.section skiyb +.section skiza +.section skizb +.section ski1a +.section ski1b +.section ski2a +.section ski2b +.section ski3a +.section ski3b +.section ski4a +.section ski4b +.section ski5a +.section ski5b +.section ski6a +.section ski6b +.section ski7a +.section ski7b +.section ski8a +.section ski8b +.section ski9a +.section ski9b +.section ski0a +.section ski0b +.section skjaa +.section skjab +.section skjba +.section skjbb +.section skjca +.section skjcb +.section skjda +.section skjdb +.section skjea +.section skjeb +.section skjfa +.section skjfb +.section skjga +.section skjgb +.section skjha +.section skjhb +.section skjia +.section skjib +.section skjja +.section skjjb +.section skjka +.section skjkb +.section skjla +.section skjlb +.section skjma +.section skjmb +.section skjna +.section skjnb +.section skjoa +.section skjob +.section skjpa +.section skjpb +.section skjqa +.section skjqb +.section skjra +.section skjrb +.section skjsa +.section skjsb +.section skjta +.section skjtb +.section skjua +.section skjub +.section skjva +.section skjvb +.section skjwa +.section skjwb +.section skjxa +.section skjxb +.section skjya +.section skjyb +.section skjza +.section skjzb +.section skj1a +.section skj1b +.section skj2a +.section skj2b +.section skj3a +.section skj3b +.section skj4a +.section skj4b +.section skj5a +.section skj5b +.section skj6a +.section skj6b +.section skj7a +.section skj7b +.section skj8a +.section skj8b +.section skj9a +.section skj9b +.section skj0a +.section skj0b +.section skkaa +.section skkab +.section skkba +.section skkbb +.section skkca +.section skkcb +.section skkda +.section skkdb +.section skkea +.section skkeb +.section skkfa +.section skkfb +.section skkga +.section skkgb +.section skkha +.section skkhb +.section skkia +.section skkib +.section skkja +.section skkjb +.section skkka +.section skkkb +.section skkla +.section skklb +.section skkma +.section skkmb +.section skkna +.section skknb +.section skkoa +.section skkob +.section skkpa +.section skkpb +.section skkqa +.section skkqb +.section skkra +.section skkrb +.section skksa +.section skksb +.section skkta +.section skktb +.section skkua +.section skkub +.section skkva +.section skkvb +.section skkwa +.section skkwb +.section skkxa +.section skkxb +.section skkya +.section skkyb +.section skkza +.section skkzb +.section skk1a +.section skk1b +.section skk2a +.section skk2b +.section skk3a +.section skk3b +.section skk4a +.section skk4b +.section skk5a +.section skk5b +.section skk6a +.section skk6b +.section skk7a +.section skk7b +.section skk8a +.section skk8b +.section skk9a +.section skk9b +.section skk0a +.section skk0b +.section sklaa +.section sklab +.section sklba +.section sklbb +.section sklca +.section sklcb +.section sklda +.section skldb +.section sklea +.section skleb +.section sklfa +.section sklfb +.section sklga +.section sklgb +.section sklha +.section sklhb +.section sklia +.section sklib +.section sklja +.section skljb +.section sklka +.section sklkb +.section sklla +.section skllb +.section sklma +.section sklmb +.section sklna +.section sklnb +.section skloa +.section sklob +.section sklpa +.section sklpb +.section sklqa +.section sklqb +.section sklra +.section sklrb +.section sklsa +.section sklsb +.section sklta +.section skltb +.section sklua +.section sklub +.section sklva +.section sklvb +.section sklwa +.section sklwb +.section sklxa +.section sklxb +.section sklya +.section sklyb +.section sklza +.section sklzb +.section skl1a +.section skl1b +.section skl2a +.section skl2b +.section skl3a +.section skl3b +.section skl4a +.section skl4b +.section skl5a +.section skl5b +.section skl6a +.section skl6b +.section skl7a +.section skl7b +.section skl8a +.section skl8b +.section skl9a +.section skl9b +.section skl0a +.section skl0b +.section skmaa +.section skmab +.section skmba +.section skmbb +.section skmca +.section skmcb +.section skmda +.section skmdb +.section skmea +.section skmeb +.section skmfa +.section skmfb +.section skmga +.section skmgb +.section skmha +.section skmhb +.section skmia +.section skmib +.section skmja +.section skmjb +.section skmka +.section skmkb +.section skmla +.section skmlb +.section skmma +.section skmmb +.section skmna +.section skmnb +.section skmoa +.section skmob +.section skmpa +.section skmpb +.section skmqa +.section skmqb +.section skmra +.section skmrb +.section skmsa +.section skmsb +.section skmta +.section skmtb +.section skmua +.section skmub +.section skmva +.section skmvb +.section skmwa +.section skmwb +.section skmxa +.section skmxb +.section skmya +.section skmyb +.section skmza +.section skmzb +.section skm1a +.section skm1b +.section skm2a +.section skm2b +.section skm3a +.section skm3b +.section skm4a +.section skm4b +.section skm5a +.section skm5b +.section skm6a +.section skm6b +.section skm7a +.section skm7b +.section skm8a +.section skm8b +.section skm9a +.section skm9b +.section skm0a +.section skm0b +.section sknaa +.section sknab +.section sknba +.section sknbb +.section sknca +.section skncb +.section sknda +.section skndb +.section sknea +.section skneb +.section sknfa +.section sknfb +.section sknga +.section skngb +.section sknha +.section sknhb +.section sknia +.section sknib +.section sknja +.section sknjb +.section sknka +.section sknkb +.section sknla +.section sknlb +.section sknma +.section sknmb +.section sknna +.section sknnb +.section sknoa +.section sknob +.section sknpa +.section sknpb +.section sknqa +.section sknqb +.section sknra +.section sknrb +.section sknsa +.section sknsb +.section sknta +.section skntb +.section sknua +.section sknub +.section sknva +.section sknvb +.section sknwa +.section sknwb +.section sknxa +.section sknxb +.section sknya +.section sknyb +.section sknza +.section sknzb +.section skn1a +.section skn1b +.section skn2a +.section skn2b +.section skn3a +.section skn3b +.section skn4a +.section skn4b +.section skn5a +.section skn5b +.section skn6a +.section skn6b +.section skn7a +.section skn7b +.section skn8a +.section skn8b +.section skn9a +.section skn9b +.section skn0a +.section skn0b +.section skoaa +.section skoab +.section skoba +.section skobb +.section skoca +.section skocb +.section skoda +.section skodb +.section skoea +.section skoeb +.section skofa +.section skofb +.section skoga +.section skogb +.section skoha +.section skohb +.section skoia +.section skoib +.section skoja +.section skojb +.section skoka +.section skokb +.section skola +.section skolb +.section skoma +.section skomb +.section skona +.section skonb +.section skooa +.section skoob +.section skopa +.section skopb +.section skoqa +.section skoqb +.section skora +.section skorb +.section skosa +.section skosb +.section skota +.section skotb +.section skoua +.section skoub +.section skova +.section skovb +.section skowa +.section skowb +.section skoxa +.section skoxb +.section skoya +.section skoyb +.section skoza +.section skozb +.section sko1a +.section sko1b +.section sko2a +.section sko2b +.section sko3a +.section sko3b +.section sko4a +.section sko4b +.section sko5a +.section sko5b +.section sko6a +.section sko6b +.section sko7a +.section sko7b +.section sko8a +.section sko8b +.section sko9a +.section sko9b +.section sko0a +.section sko0b +.section skpaa +.section skpab +.section skpba +.section skpbb +.section skpca +.section skpcb +.section skpda +.section skpdb +.section skpea +.section skpeb +.section skpfa +.section skpfb +.section skpga +.section skpgb +.section skpha +.section skphb +.section skpia +.section skpib +.section skpja +.section skpjb +.section skpka +.section skpkb +.section skpla +.section skplb +.section skpma +.section skpmb +.section skpna +.section skpnb +.section skpoa +.section skpob +.section skppa +.section skppb +.section skpqa +.section skpqb +.section skpra +.section skprb +.section skpsa +.section skpsb +.section skpta +.section skptb +.section skpua +.section skpub +.section skpva +.section skpvb +.section skpwa +.section skpwb +.section skpxa +.section skpxb +.section skpya +.section skpyb +.section skpza +.section skpzb +.section skp1a +.section skp1b +.section skp2a +.section skp2b +.section skp3a +.section skp3b +.section skp4a +.section skp4b +.section skp5a +.section skp5b +.section skp6a +.section skp6b +.section skp7a +.section skp7b +.section skp8a +.section skp8b +.section skp9a +.section skp9b +.section skp0a +.section skp0b +.section skqaa +.section skqab +.section skqba +.section skqbb +.section skqca +.section skqcb +.section skqda +.section skqdb +.section skqea +.section skqeb +.section skqfa +.section skqfb +.section skqga +.section skqgb +.section skqha +.section skqhb +.section skqia +.section skqib +.section skqja +.section skqjb +.section skqka +.section skqkb +.section skqla +.section skqlb +.section skqma +.section skqmb +.section skqna +.section skqnb +.section skqoa +.section skqob +.section skqpa +.section skqpb +.section skqqa +.section skqqb +.section skqra +.section skqrb +.section skqsa +.section skqsb +.section skqta +.section skqtb +.section skqua +.section skqub +.section skqva +.section skqvb +.section skqwa +.section skqwb +.section skqxa +.section skqxb +.section skqya +.section skqyb +.section skqza +.section skqzb +.section skq1a +.section skq1b +.section skq2a +.section skq2b +.section skq3a +.section skq3b +.section skq4a +.section skq4b +.section skq5a +.section skq5b +.section skq6a +.section skq6b +.section skq7a +.section skq7b +.section skq8a +.section skq8b +.section skq9a +.section skq9b +.section skq0a +.section skq0b +.section skraa +.section skrab +.section skrba +.section skrbb +.section skrca +.section skrcb +.section skrda +.section skrdb +.section skrea +.section skreb +.section skrfa +.section skrfb +.section skrga +.section skrgb +.section skrha +.section skrhb +.section skria +.section skrib +.section skrja +.section skrjb +.section skrka +.section skrkb +.section skrla +.section skrlb +.section skrma +.section skrmb +.section skrna +.section skrnb +.section skroa +.section skrob +.section skrpa +.section skrpb +.section skrqa +.section skrqb +.section skrra +.section skrrb +.section skrsa +.section skrsb +.section skrta +.section skrtb +.section skrua +.section skrub +.section skrva +.section skrvb +.section skrwa +.section skrwb +.section skrxa +.section skrxb +.section skrya +.section skryb +.section skrza +.section skrzb +.section skr1a +.section skr1b +.section skr2a +.section skr2b +.section skr3a +.section skr3b +.section skr4a +.section skr4b +.section skr5a +.section skr5b +.section skr6a +.section skr6b +.section skr7a +.section skr7b +.section skr8a +.section skr8b +.section skr9a +.section skr9b +.section skr0a +.section skr0b +.section sksaa +.section sksab +.section sksba +.section sksbb +.section sksca +.section skscb +.section sksda +.section sksdb +.section sksea +.section skseb +.section sksfa +.section sksfb +.section sksga +.section sksgb +.section sksha +.section skshb +.section sksia +.section sksib +.section sksja +.section sksjb +.section skska +.section skskb +.section sksla +.section skslb +.section sksma +.section sksmb +.section sksna +.section sksnb +.section sksoa +.section sksob +.section skspa +.section skspb +.section sksqa +.section sksqb +.section sksra +.section sksrb +.section skssa +.section skssb +.section sksta +.section skstb +.section sksua +.section sksub +.section sksva +.section sksvb +.section skswa +.section skswb +.section sksxa +.section sksxb +.section sksya +.section sksyb +.section sksza +.section skszb +.section sks1a +.section sks1b +.section sks2a +.section sks2b +.section sks3a +.section sks3b +.section sks4a +.section sks4b +.section sks5a +.section sks5b +.section sks6a +.section sks6b +.section sks7a +.section sks7b +.section sks8a +.section sks8b +.section sks9a +.section sks9b +.section sks0a +.section sks0b +.section sktaa +.section sktab +.section sktba +.section sktbb +.section sktca +.section sktcb +.section sktda +.section sktdb +.section sktea +.section skteb +.section sktfa +.section sktfb +.section sktga +.section sktgb +.section sktha +.section skthb +.section sktia +.section sktib +.section sktja +.section sktjb +.section sktka +.section sktkb +.section sktla +.section sktlb +.section sktma +.section sktmb +.section sktna +.section sktnb +.section sktoa +.section sktob +.section sktpa +.section sktpb +.section sktqa +.section sktqb +.section sktra +.section sktrb +.section sktsa +.section sktsb +.section sktta +.section skttb +.section sktua +.section sktub +.section sktva +.section sktvb +.section sktwa +.section sktwb +.section sktxa +.section sktxb +.section sktya +.section sktyb +.section sktza +.section sktzb +.section skt1a +.section skt1b +.section skt2a +.section skt2b +.section skt3a +.section skt3b +.section skt4a +.section skt4b +.section skt5a +.section skt5b +.section skt6a +.section skt6b +.section skt7a +.section skt7b +.section skt8a +.section skt8b +.section skt9a +.section skt9b +.section skt0a +.section skt0b +.section skuaa +.section skuab +.section skuba +.section skubb +.section skuca +.section skucb +.section skuda +.section skudb +.section skuea +.section skueb +.section skufa +.section skufb +.section skuga +.section skugb +.section skuha +.section skuhb +.section skuia +.section skuib +.section skuja +.section skujb +.section skuka +.section skukb +.section skula +.section skulb +.section skuma +.section skumb +.section skuna +.section skunb +.section skuoa +.section skuob +.section skupa +.section skupb +.section skuqa +.section skuqb +.section skura +.section skurb +.section skusa +.section skusb +.section skuta +.section skutb +.section skuua +.section skuub +.section skuva +.section skuvb +.section skuwa +.section skuwb +.section skuxa +.section skuxb +.section skuya +.section skuyb +.section skuza +.section skuzb +.section sku1a +.section sku1b +.section sku2a +.section sku2b +.section sku3a +.section sku3b +.section sku4a +.section sku4b +.section sku5a +.section sku5b +.section sku6a +.section sku6b +.section sku7a +.section sku7b +.section sku8a +.section sku8b +.section sku9a +.section sku9b +.section sku0a +.section sku0b +.section skvaa +.section skvab +.section skvba +.section skvbb +.section skvca +.section skvcb +.section skvda +.section skvdb +.section skvea +.section skveb +.section skvfa +.section skvfb +.section skvga +.section skvgb +.section skvha +.section skvhb +.section skvia +.section skvib +.section skvja +.section skvjb +.section skvka +.section skvkb +.section skvla +.section skvlb +.section skvma +.section skvmb +.section skvna +.section skvnb +.section skvoa +.section skvob +.section skvpa +.section skvpb +.section skvqa +.section skvqb +.section skvra +.section skvrb +.section skvsa +.section skvsb +.section skvta +.section skvtb +.section skvua +.section skvub +.section skvva +.section skvvb +.section skvwa +.section skvwb +.section skvxa +.section skvxb +.section skvya +.section skvyb +.section skvza +.section skvzb +.section skv1a +.section skv1b +.section skv2a +.section skv2b +.section skv3a +.section skv3b +.section skv4a +.section skv4b +.section skv5a +.section skv5b +.section skv6a +.section skv6b +.section skv7a +.section skv7b +.section skv8a +.section skv8b +.section skv9a +.section skv9b +.section skv0a +.section skv0b +.section skwaa +.section skwab +.section skwba +.section skwbb +.section skwca +.section skwcb +.section skwda +.section skwdb +.section skwea +.section skweb +.section skwfa +.section skwfb +.section skwga +.section skwgb +.section skwha +.section skwhb +.section skwia +.section skwib +.section skwja +.section skwjb +.section skwka +.section skwkb +.section skwla +.section skwlb +.section skwma +.section skwmb +.section skwna +.section skwnb +.section skwoa +.section skwob +.section skwpa +.section skwpb +.section skwqa +.section skwqb +.section skwra +.section skwrb +.section skwsa +.section skwsb +.section skwta +.section skwtb +.section skwua +.section skwub +.section skwva +.section skwvb +.section skwwa +.section skwwb +.section skwxa +.section skwxb +.section skwya +.section skwyb +.section skwza +.section skwzb +.section skw1a +.section skw1b +.section skw2a +.section skw2b +.section skw3a +.section skw3b +.section skw4a +.section skw4b +.section skw5a +.section skw5b +.section skw6a +.section skw6b +.section skw7a +.section skw7b +.section skw8a +.section skw8b +.section skw9a +.section skw9b +.section skw0a +.section skw0b +.section skxaa +.section skxab +.section skxba +.section skxbb +.section skxca +.section skxcb +.section skxda +.section skxdb +.section skxea +.section skxeb +.section skxfa +.section skxfb +.section skxga +.section skxgb +.section skxha +.section skxhb +.section skxia +.section skxib +.section skxja +.section skxjb +.section skxka +.section skxkb +.section skxla +.section skxlb +.section skxma +.section skxmb +.section skxna +.section skxnb +.section skxoa +.section skxob +.section skxpa +.section skxpb +.section skxqa +.section skxqb +.section skxra +.section skxrb +.section skxsa +.section skxsb +.section skxta +.section skxtb +.section skxua +.section skxub +.section skxva +.section skxvb +.section skxwa +.section skxwb +.section skxxa +.section skxxb +.section skxya +.section skxyb +.section skxza +.section skxzb +.section skx1a +.section skx1b +.section skx2a +.section skx2b +.section skx3a +.section skx3b +.section skx4a +.section skx4b +.section skx5a +.section skx5b +.section skx6a +.section skx6b +.section skx7a +.section skx7b +.section skx8a +.section skx8b +.section skx9a +.section skx9b +.section skx0a +.section skx0b +.section skyaa +.section skyab +.section skyba +.section skybb +.section skyca +.section skycb +.section skyda +.section skydb +.section skyea +.section skyeb +.section skyfa +.section skyfb +.section skyga +.section skygb +.section skyha +.section skyhb +.section skyia +.section skyib +.section skyja +.section skyjb +.section skyka +.section skykb +.section skyla +.section skylb +.section skyma +.section skymb +.section skyna +.section skynb +.section skyoa +.section skyob +.section skypa +.section skypb +.section skyqa +.section skyqb +.section skyra +.section skyrb +.section skysa +.section skysb +.section skyta +.section skytb +.section skyua +.section skyub +.section skyva +.section skyvb +.section skywa +.section skywb +.section skyxa +.section skyxb +.section skyya +.section skyyb +.section skyza +.section skyzb +.section sky1a +.section sky1b +.section sky2a +.section sky2b +.section sky3a +.section sky3b +.section sky4a +.section sky4b +.section sky5a +.section sky5b +.section sky6a +.section sky6b +.section sky7a +.section sky7b +.section sky8a +.section sky8b +.section sky9a +.section sky9b +.section sky0a +.section sky0b +.section skzaa +.section skzab +.section skzba +.section skzbb +.section skzca +.section skzcb +.section skzda +.section skzdb +.section skzea +.section skzeb +.section skzfa +.section skzfb +.section skzga +.section skzgb +.section skzha +.section skzhb +.section skzia +.section skzib +.section skzja +.section skzjb +.section skzka +.section skzkb +.section skzla +.section skzlb +.section skzma +.section skzmb +.section skzna +.section skznb +.section skzoa +.section skzob +.section skzpa +.section skzpb +.section skzqa +.section skzqb +.section skzra +.section skzrb +.section skzsa +.section skzsb +.section skzta +.section skztb +.section skzua +.section skzub +.section skzva +.section skzvb +.section skzwa +.section skzwb +.section skzxa +.section skzxb +.section skzya +.section skzyb +.section skzza +.section skzzb +.section skz1a +.section skz1b +.section skz2a +.section skz2b +.section skz3a +.section skz3b +.section skz4a +.section skz4b +.section skz5a +.section skz5b +.section skz6a +.section skz6b +.section skz7a +.section skz7b +.section skz8a +.section skz8b +.section skz9a +.section skz9b +.section skz0a +.section skz0b +.section sk1aa +.section sk1ab +.section sk1ba +.section sk1bb +.section sk1ca +.section sk1cb +.section sk1da +.section sk1db +.section sk1ea +.section sk1eb +.section sk1fa +.section sk1fb +.section sk1ga +.section sk1gb +.section sk1ha +.section sk1hb +.section sk1ia +.section sk1ib +.section sk1ja +.section sk1jb +.section sk1ka +.section sk1kb +.section sk1la +.section sk1lb +.section sk1ma +.section sk1mb +.section sk1na +.section sk1nb +.section sk1oa +.section sk1ob +.section sk1pa +.section sk1pb +.section sk1qa +.section sk1qb +.section sk1ra +.section sk1rb +.section sk1sa +.section sk1sb +.section sk1ta +.section sk1tb +.section sk1ua +.section sk1ub +.section sk1va +.section sk1vb +.section sk1wa +.section sk1wb +.section sk1xa +.section sk1xb +.section sk1ya +.section sk1yb +.section sk1za +.section sk1zb +.section sk11a +.section sk11b +.section sk12a +.section sk12b +.section sk13a +.section sk13b +.section sk14a +.section sk14b +.section sk15a +.section sk15b +.section sk16a +.section sk16b +.section sk17a +.section sk17b +.section sk18a +.section sk18b +.section sk19a +.section sk19b +.section sk10a +.section sk10b +.section sk2aa +.section sk2ab +.section sk2ba +.section sk2bb +.section sk2ca +.section sk2cb +.section sk2da +.section sk2db +.section sk2ea +.section sk2eb +.section sk2fa +.section sk2fb +.section sk2ga +.section sk2gb +.section sk2ha +.section sk2hb +.section sk2ia +.section sk2ib +.section sk2ja +.section sk2jb +.section sk2ka +.section sk2kb +.section sk2la +.section sk2lb +.section sk2ma +.section sk2mb +.section sk2na +.section sk2nb +.section sk2oa +.section sk2ob +.section sk2pa +.section sk2pb +.section sk2qa +.section sk2qb +.section sk2ra +.section sk2rb +.section sk2sa +.section sk2sb +.section sk2ta +.section sk2tb +.section sk2ua +.section sk2ub +.section sk2va +.section sk2vb +.section sk2wa +.section sk2wb +.section sk2xa +.section sk2xb +.section sk2ya +.section sk2yb +.section sk2za +.section sk2zb +.section sk21a +.section sk21b +.section sk22a +.section sk22b +.section sk23a +.section sk23b +.section sk24a +.section sk24b +.section sk25a +.section sk25b +.section sk26a +.section sk26b +.section sk27a +.section sk27b +.section sk28a +.section sk28b +.section sk29a +.section sk29b +.section sk20a +.section sk20b +.section sk3aa +.section sk3ab +.section sk3ba +.section sk3bb +.section sk3ca +.section sk3cb +.section sk3da +.section sk3db +.section sk3ea +.section sk3eb +.section sk3fa +.section sk3fb +.section sk3ga +.section sk3gb +.section sk3ha +.section sk3hb +.section sk3ia +.section sk3ib +.section sk3ja +.section sk3jb +.section sk3ka +.section sk3kb +.section sk3la +.section sk3lb +.section sk3ma +.section sk3mb +.section sk3na +.section sk3nb +.section sk3oa +.section sk3ob +.section sk3pa +.section sk3pb +.section sk3qa +.section sk3qb +.section sk3ra +.section sk3rb +.section sk3sa +.section sk3sb +.section sk3ta +.section sk3tb +.section sk3ua +.section sk3ub +.section sk3va +.section sk3vb +.section sk3wa +.section sk3wb +.section sk3xa +.section sk3xb +.section sk3ya +.section sk3yb +.section sk3za +.section sk3zb +.section sk31a +.section sk31b +.section sk32a +.section sk32b +.section sk33a +.section sk33b +.section sk34a +.section sk34b +.section sk35a +.section sk35b +.section sk36a +.section sk36b +.section sk37a +.section sk37b +.section sk38a +.section sk38b +.section sk39a +.section sk39b +.section sk30a +.section sk30b +.section sk4aa +.section sk4ab +.section sk4ba +.section sk4bb +.section sk4ca +.section sk4cb +.section sk4da +.section sk4db +.section sk4ea +.section sk4eb +.section sk4fa +.section sk4fb +.section sk4ga +.section sk4gb +.section sk4ha +.section sk4hb +.section sk4ia +.section sk4ib +.section sk4ja +.section sk4jb +.section sk4ka +.section sk4kb +.section sk4la +.section sk4lb +.section sk4ma +.section sk4mb +.section sk4na +.section sk4nb +.section sk4oa +.section sk4ob +.section sk4pa +.section sk4pb +.section sk4qa +.section sk4qb +.section sk4ra +.section sk4rb +.section sk4sa +.section sk4sb +.section sk4ta +.section sk4tb +.section sk4ua +.section sk4ub +.section sk4va +.section sk4vb +.section sk4wa +.section sk4wb +.section sk4xa +.section sk4xb +.section sk4ya +.section sk4yb +.section sk4za +.section sk4zb +.section sk41a +.section sk41b +.section sk42a +.section sk42b +.section sk43a +.section sk43b +.section sk44a +.section sk44b +.section sk45a +.section sk45b +.section sk46a +.section sk46b +.section sk47a +.section sk47b +.section sk48a +.section sk48b +.section sk49a +.section sk49b +.section sk40a +.section sk40b +.section sk5aa +.section sk5ab +.section sk5ba +.section sk5bb +.section sk5ca +.section sk5cb +.section sk5da +.section sk5db +.section sk5ea +.section sk5eb +.section sk5fa +.section sk5fb +.section sk5ga +.section sk5gb +.section sk5ha +.section sk5hb +.section sk5ia +.section sk5ib +.section sk5ja +.section sk5jb +.section sk5ka +.section sk5kb +.section sk5la +.section sk5lb +.section sk5ma +.section sk5mb +.section sk5na +.section sk5nb +.section sk5oa +.section sk5ob +.section sk5pa +.section sk5pb +.section sk5qa +.section sk5qb +.section sk5ra +.section sk5rb +.section sk5sa +.section sk5sb +.section sk5ta +.section sk5tb +.section sk5ua +.section sk5ub +.section sk5va +.section sk5vb +.section sk5wa +.section sk5wb +.section sk5xa +.section sk5xb +.section sk5ya +.section sk5yb +.section sk5za +.section sk5zb +.section sk51a +.section sk51b +.section sk52a +.section sk52b +.section sk53a +.section sk53b +.section sk54a +.section sk54b +.section sk55a +.section sk55b +.section sk56a +.section sk56b +.section sk57a +.section sk57b +.section sk58a +.section sk58b +.section sk59a +.section sk59b +.section sk50a +.section sk50b +.section sk6aa +.section sk6ab +.section sk6ba +.section sk6bb +.section sk6ca +.section sk6cb +.section sk6da +.section sk6db +.section sk6ea +.section sk6eb +.section sk6fa +.section sk6fb +.section sk6ga +.section sk6gb +.section sk6ha +.section sk6hb +.section sk6ia +.section sk6ib +.section sk6ja +.section sk6jb +.section sk6ka +.section sk6kb +.section sk6la +.section sk6lb +.section sk6ma +.section sk6mb +.section sk6na +.section sk6nb +.section sk6oa +.section sk6ob +.section sk6pa +.section sk6pb +.section sk6qa +.section sk6qb +.section sk6ra +.section sk6rb +.section sk6sa +.section sk6sb +.section sk6ta +.section sk6tb +.section sk6ua +.section sk6ub +.section sk6va +.section sk6vb +.section sk6wa +.section sk6wb +.section sk6xa +.section sk6xb +.section sk6ya +.section sk6yb +.section sk6za +.section sk6zb +.section sk61a +.section sk61b +.section sk62a +.section sk62b +.section sk63a +.section sk63b +.section sk64a +.section sk64b +.section sk65a +.section sk65b +.section sk66a +.section sk66b +.section sk67a +.section sk67b +.section sk68a +.section sk68b +.section sk69a +.section sk69b +.section sk60a +.section sk60b +.section sk7aa +.section sk7ab +.section sk7ba +.section sk7bb +.section sk7ca +.section sk7cb +.section sk7da +.section sk7db +.section sk7ea +.section sk7eb +.section sk7fa +.section sk7fb +.section sk7ga +.section sk7gb +.section sk7ha +.section sk7hb +.section sk7ia +.section sk7ib +.section sk7ja +.section sk7jb +.section sk7ka +.section sk7kb +.section sk7la +.section sk7lb +.section sk7ma +.section sk7mb +.section sk7na +.section sk7nb +.section sk7oa +.section sk7ob +.section sk7pa +.section sk7pb +.section sk7qa +.section sk7qb +.section sk7ra +.section sk7rb +.section sk7sa +.section sk7sb +.section sk7ta +.section sk7tb +.section sk7ua +.section sk7ub +.section sk7va +.section sk7vb +.section sk7wa +.section sk7wb +.section sk7xa +.section sk7xb +.section sk7ya +.section sk7yb +.section sk7za +.section sk7zb +.section sk71a +.section sk71b +.section sk72a +.section sk72b +.section sk73a +.section sk73b +.section sk74a +.section sk74b +.section sk75a +.section sk75b +.section sk76a +.section sk76b +.section sk77a +.section sk77b +.section sk78a +.section sk78b +.section sk79a +.section sk79b +.section sk70a +.section sk70b +.section sk8aa +.section sk8ab +.section sk8ba +.section sk8bb +.section sk8ca +.section sk8cb +.section sk8da +.section sk8db +.section sk8ea +.section sk8eb +.section sk8fa +.section sk8fb +.section sk8ga +.section sk8gb +.section sk8ha +.section sk8hb +.section sk8ia +.section sk8ib +.section sk8ja +.section sk8jb +.section sk8ka +.section sk8kb +.section sk8la +.section sk8lb +.section sk8ma +.section sk8mb +.section sk8na +.section sk8nb +.section sk8oa +.section sk8ob +.section sk8pa +.section sk8pb +.section sk8qa +.section sk8qb +.section sk8ra +.section sk8rb +.section sk8sa +.section sk8sb +.section sk8ta +.section sk8tb +.section sk8ua +.section sk8ub +.section sk8va +.section sk8vb +.section sk8wa +.section sk8wb +.section sk8xa +.section sk8xb +.section sk8ya +.section sk8yb +.section sk8za +.section sk8zb +.section sk81a +.section sk81b +.section sk82a +.section sk82b +.section sk83a +.section sk83b +.section sk84a +.section sk84b +.section sk85a +.section sk85b +.section sk86a +.section sk86b +.section sk87a +.section sk87b +.section sk88a +.section sk88b +.section sk89a +.section sk89b +.section sk80a +.section sk80b +.section sk9aa +.section sk9ab +.section sk9ba +.section sk9bb +.section sk9ca +.section sk9cb +.section sk9da +.section sk9db +.section sk9ea +.section sk9eb +.section sk9fa +.section sk9fb +.section sk9ga +.section sk9gb +.section sk9ha +.section sk9hb +.section sk9ia +.section sk9ib +.section sk9ja +.section sk9jb +.section sk9ka +.section sk9kb +.section sk9la +.section sk9lb +.section sk9ma +.section sk9mb +.section sk9na +.section sk9nb +.section sk9oa +.section sk9ob +.section sk9pa +.section sk9pb +.section sk9qa +.section sk9qb +.section sk9ra +.section sk9rb +.section sk9sa +.section sk9sb +.section sk9ta +.section sk9tb +.section sk9ua +.section sk9ub +.section sk9va +.section sk9vb +.section sk9wa +.section sk9wb +.section sk9xa +.section sk9xb +.section sk9ya +.section sk9yb +.section sk9za +.section sk9zb +.section sk91a +.section sk91b +.section sk92a +.section sk92b +.section sk93a +.section sk93b +.section sk94a +.section sk94b +.section sk95a +.section sk95b +.section sk96a +.section sk96b +.section sk97a +.section sk97b +.section sk98a +.section sk98b +.section sk99a +.section sk99b +.section sk90a +.section sk90b +.section sk0aa +.section sk0ab +.section sk0ba +.section sk0bb +.section sk0ca +.section sk0cb +.section sk0da +.section sk0db +.section sk0ea +.section sk0eb +.section sk0fa +.section sk0fb +.section sk0ga +.section sk0gb +.section sk0ha +.section sk0hb +.section sk0ia +.section sk0ib +.section sk0ja +.section sk0jb +.section sk0ka +.section sk0kb +.section sk0la +.section sk0lb +.section sk0ma +.section sk0mb +.section sk0na +.section sk0nb +.section sk0oa +.section sk0ob +.section sk0pa +.section sk0pb +.section sk0qa +.section sk0qb +.section sk0ra +.section sk0rb +.section sk0sa +.section sk0sb +.section sk0ta +.section sk0tb +.section sk0ua +.section sk0ub +.section sk0va +.section sk0vb +.section sk0wa +.section sk0wb +.section sk0xa +.section sk0xb +.section sk0ya +.section sk0yb +.section sk0za +.section sk0zb +.section sk01a +.section sk01b +.section sk02a +.section sk02b +.section sk03a +.section sk03b +.section sk04a +.section sk04b +.section sk05a +.section sk05b +.section sk06a +.section sk06b +.section sk07a +.section sk07b +.section sk08a +.section sk08b +.section sk09a +.section sk09b +.section sk00a +.section sk00b +.section slaaa +.section slaab +.section slaba +.section slabb +.section slaca +.section slacb +.section slada +.section sladb +.section slaea +.section slaeb +.section slafa +.section slafb +.section slaga +.section slagb +.section slaha +.section slahb +.section slaia +.section slaib +.section slaja +.section slajb +.section slaka +.section slakb +.section slala +.section slalb +.section slama +.section slamb +.section slana +.section slanb +.section slaoa +.section slaob +.section slapa +.section slapb +.section slaqa +.section slaqb +.section slara +.section slarb +.section slasa +.section slasb +.section slata +.section slatb +.section slaua +.section slaub +.section slava +.section slavb +.section slawa +.section slawb +.section slaxa +.section slaxb +.section slaya +.section slayb +.section slaza +.section slazb +.section sla1a +.section sla1b +.section sla2a +.section sla2b +.section sla3a +.section sla3b +.section sla4a +.section sla4b +.section sla5a +.section sla5b +.section sla6a +.section sla6b +.section sla7a +.section sla7b +.section sla8a +.section sla8b +.section sla9a +.section sla9b +.section sla0a +.section sla0b +.section slbaa +.section slbab +.section slbba +.section slbbb +.section slbca +.section slbcb +.section slbda +.section slbdb +.section slbea +.section slbeb +.section slbfa +.section slbfb +.section slbga +.section slbgb +.section slbha +.section slbhb +.section slbia +.section slbib +.section slbja +.section slbjb +.section slbka +.section slbkb +.section slbla +.section slblb +.section slbma +.section slbmb +.section slbna +.section slbnb +.section slboa +.section slbob +.section slbpa +.section slbpb +.section slbqa +.section slbqb +.section slbra +.section slbrb +.section slbsa +.section slbsb +.section slbta +.section slbtb +.section slbua +.section slbub +.section slbva +.section slbvb +.section slbwa +.section slbwb +.section slbxa +.section slbxb +.section slbya +.section slbyb +.section slbza +.section slbzb +.section slb1a +.section slb1b +.section slb2a +.section slb2b +.section slb3a +.section slb3b +.section slb4a +.section slb4b +.section slb5a +.section slb5b +.section slb6a +.section slb6b +.section slb7a +.section slb7b +.section slb8a +.section slb8b +.section slb9a +.section slb9b +.section slb0a +.section slb0b +.section slcaa +.section slcab +.section slcba +.section slcbb +.section slcca +.section slccb +.section slcda +.section slcdb +.section slcea +.section slceb +.section slcfa +.section slcfb +.section slcga +.section slcgb +.section slcha +.section slchb +.section slcia +.section slcib +.section slcja +.section slcjb +.section slcka +.section slckb +.section slcla +.section slclb +.section slcma +.section slcmb +.section slcna +.section slcnb +.section slcoa +.section slcob +.section slcpa +.section slcpb +.section slcqa +.section slcqb +.section slcra +.section slcrb +.section slcsa +.section slcsb +.section slcta +.section slctb +.section slcua +.section slcub +.section slcva +.section slcvb +.section slcwa +.section slcwb +.section slcxa +.section slcxb +.section slcya +.section slcyb +.section slcza +.section slczb +.section slc1a +.section slc1b +.section slc2a +.section slc2b +.section slc3a +.section slc3b +.section slc4a +.section slc4b +.section slc5a +.section slc5b +.section slc6a +.section slc6b +.section slc7a +.section slc7b +.section slc8a +.section slc8b +.section slc9a +.section slc9b +.section slc0a +.section slc0b +.section sldaa +.section sldab +.section sldba +.section sldbb +.section sldca +.section sldcb +.section sldda +.section slddb +.section sldea +.section sldeb +.section sldfa +.section sldfb +.section sldga +.section sldgb +.section sldha +.section sldhb +.section sldia +.section sldib +.section sldja +.section sldjb +.section sldka +.section sldkb +.section sldla +.section sldlb +.section sldma +.section sldmb +.section sldna +.section sldnb +.section sldoa +.section sldob +.section sldpa +.section sldpb +.section sldqa +.section sldqb +.section sldra +.section sldrb +.section sldsa +.section sldsb +.section sldta +.section sldtb +.section sldua +.section sldub +.section sldva +.section sldvb +.section sldwa +.section sldwb +.section sldxa +.section sldxb +.section sldya +.section sldyb +.section sldza +.section sldzb +.section sld1a +.section sld1b +.section sld2a +.section sld2b +.section sld3a +.section sld3b +.section sld4a +.section sld4b +.section sld5a +.section sld5b +.section sld6a +.section sld6b +.section sld7a +.section sld7b +.section sld8a +.section sld8b +.section sld9a +.section sld9b +.section sld0a +.section sld0b +.section sleaa +.section sleab +.section sleba +.section slebb +.section sleca +.section slecb +.section sleda +.section sledb +.section sleea +.section sleeb +.section slefa +.section slefb +.section slega +.section slegb +.section sleha +.section slehb +.section sleia +.section sleib +.section sleja +.section slejb +.section sleka +.section slekb +.section slela +.section slelb +.section slema +.section slemb +.section slena +.section slenb +.section sleoa +.section sleob +.section slepa +.section slepb +.section sleqa +.section sleqb +.section slera +.section slerb +.section slesa +.section slesb +.section sleta +.section sletb +.section sleua +.section sleub +.section sleva +.section slevb +.section slewa +.section slewb +.section slexa +.section slexb +.section sleya +.section sleyb +.section sleza +.section slezb +.section sle1a +.section sle1b +.section sle2a +.section sle2b +.section sle3a +.section sle3b +.section sle4a +.section sle4b +.section sle5a +.section sle5b +.section sle6a +.section sle6b +.section sle7a +.section sle7b +.section sle8a +.section sle8b +.section sle9a +.section sle9b +.section sle0a +.section sle0b +.section slfaa +.section slfab +.section slfba +.section slfbb +.section slfca +.section slfcb +.section slfda +.section slfdb +.section slfea +.section slfeb +.section slffa +.section slffb +.section slfga +.section slfgb +.section slfha +.section slfhb +.section slfia +.section slfib +.section slfja +.section slfjb +.section slfka +.section slfkb +.section slfla +.section slflb +.section slfma +.section slfmb +.section slfna +.section slfnb +.section slfoa +.section slfob +.section slfpa +.section slfpb +.section slfqa +.section slfqb +.section slfra +.section slfrb +.section slfsa +.section slfsb +.section slfta +.section slftb +.section slfua +.section slfub +.section slfva +.section slfvb +.section slfwa +.section slfwb +.section slfxa +.section slfxb +.section slfya +.section slfyb +.section slfza +.section slfzb +.section slf1a +.section slf1b +.section slf2a +.section slf2b +.section slf3a +.section slf3b +.section slf4a +.section slf4b +.section slf5a +.section slf5b +.section slf6a +.section slf6b +.section slf7a +.section slf7b +.section slf8a +.section slf8b +.section slf9a +.section slf9b +.section slf0a +.section slf0b +.section slgaa +.section slgab +.section slgba +.section slgbb +.section slgca +.section slgcb +.section slgda +.section slgdb +.section slgea +.section slgeb +.section slgfa +.section slgfb +.section slgga +.section slggb +.section slgha +.section slghb +.section slgia +.section slgib +.section slgja +.section slgjb +.section slgka +.section slgkb +.section slgla +.section slglb +.section slgma +.section slgmb +.section slgna +.section slgnb +.section slgoa +.section slgob +.section slgpa +.section slgpb +.section slgqa +.section slgqb +.section slgra +.section slgrb +.section slgsa +.section slgsb +.section slgta +.section slgtb +.section slgua +.section slgub +.section slgva +.section slgvb +.section slgwa +.section slgwb +.section slgxa +.section slgxb +.section slgya +.section slgyb +.section slgza +.section slgzb +.section slg1a +.section slg1b +.section slg2a +.section slg2b +.section slg3a +.section slg3b +.section slg4a +.section slg4b +.section slg5a +.section slg5b +.section slg6a +.section slg6b +.section slg7a +.section slg7b +.section slg8a +.section slg8b +.section slg9a +.section slg9b +.section slg0a +.section slg0b +.section slhaa +.section slhab +.section slhba +.section slhbb +.section slhca +.section slhcb +.section slhda +.section slhdb +.section slhea +.section slheb +.section slhfa +.section slhfb +.section slhga +.section slhgb +.section slhha +.section slhhb +.section slhia +.section slhib +.section slhja +.section slhjb +.section slhka +.section slhkb +.section slhla +.section slhlb +.section slhma +.section slhmb +.section slhna +.section slhnb +.section slhoa +.section slhob +.section slhpa +.section slhpb +.section slhqa +.section slhqb +.section slhra +.section slhrb +.section slhsa +.section slhsb +.section slhta +.section slhtb +.section slhua +.section slhub +.section slhva +.section slhvb +.section slhwa +.section slhwb +.section slhxa +.section slhxb +.section slhya +.section slhyb +.section slhza +.section slhzb +.section slh1a +.section slh1b +.section slh2a +.section slh2b +.section slh3a +.section slh3b +.section slh4a +.section slh4b +.section slh5a +.section slh5b +.section slh6a +.section slh6b +.section slh7a +.section slh7b +.section slh8a +.section slh8b +.section slh9a +.section slh9b +.section slh0a +.section slh0b +.section sliaa +.section sliab +.section sliba +.section slibb +.section slica +.section slicb +.section slida +.section slidb +.section sliea +.section slieb +.section slifa +.section slifb +.section sliga +.section sligb +.section sliha +.section slihb +.section sliia +.section sliib +.section slija +.section slijb +.section slika +.section slikb +.section slila +.section slilb +.section slima +.section slimb +.section slina +.section slinb +.section slioa +.section sliob +.section slipa +.section slipb +.section sliqa +.section sliqb +.section slira +.section slirb +.section slisa +.section slisb +.section slita +.section slitb +.section sliua +.section sliub +.section sliva +.section slivb +.section sliwa +.section sliwb +.section slixa +.section slixb +.section sliya +.section sliyb +.section sliza +.section slizb +.section sli1a +.section sli1b +.section sli2a +.section sli2b +.section sli3a +.section sli3b +.section sli4a +.section sli4b +.section sli5a +.section sli5b +.section sli6a +.section sli6b +.section sli7a +.section sli7b +.section sli8a +.section sli8b +.section sli9a +.section sli9b +.section sli0a +.section sli0b +.section sljaa +.section sljab +.section sljba +.section sljbb +.section sljca +.section sljcb +.section sljda +.section sljdb +.section sljea +.section sljeb +.section sljfa +.section sljfb +.section sljga +.section sljgb +.section sljha +.section sljhb +.section sljia +.section sljib +.section sljja +.section sljjb +.section sljka +.section sljkb +.section sljla +.section sljlb +.section sljma +.section sljmb +.section sljna +.section sljnb +.section sljoa +.section sljob +.section sljpa +.section sljpb +.section sljqa +.section sljqb +.section sljra +.section sljrb +.section sljsa +.section sljsb +.section sljta +.section sljtb +.section sljua +.section sljub +.section sljva +.section sljvb +.section sljwa +.section sljwb +.section sljxa +.section sljxb +.section sljya +.section sljyb +.section sljza +.section sljzb +.section slj1a +.section slj1b +.section slj2a +.section slj2b +.section slj3a +.section slj3b +.section slj4a +.section slj4b +.section slj5a +.section slj5b +.section slj6a +.section slj6b +.section slj7a +.section slj7b +.section slj8a +.section slj8b +.section slj9a +.section slj9b +.section slj0a +.section slj0b +.section slkaa +.section slkab +.section slkba +.section slkbb +.section slkca +.section slkcb +.section slkda +.section slkdb +.section slkea +.section slkeb +.section slkfa +.section slkfb +.section slkga +.section slkgb +.section slkha +.section slkhb +.section slkia +.section slkib +.section slkja +.section slkjb +.section slkka +.section slkkb +.section slkla +.section slklb +.section slkma +.section slkmb +.section slkna +.section slknb +.section slkoa +.section slkob +.section slkpa +.section slkpb +.section slkqa +.section slkqb +.section slkra +.section slkrb +.section slksa +.section slksb +.section slkta +.section slktb +.section slkua +.section slkub +.section slkva +.section slkvb +.section slkwa +.section slkwb +.section slkxa +.section slkxb +.section slkya +.section slkyb +.section slkza +.section slkzb +.section slk1a +.section slk1b +.section slk2a +.section slk2b +.section slk3a +.section slk3b +.section slk4a +.section slk4b +.section slk5a +.section slk5b +.section slk6a +.section slk6b +.section slk7a +.section slk7b +.section slk8a +.section slk8b +.section slk9a +.section slk9b +.section slk0a +.section slk0b +.section sllaa +.section sllab +.section sllba +.section sllbb +.section sllca +.section sllcb +.section sllda +.section slldb +.section sllea +.section slleb +.section sllfa +.section sllfb +.section sllga +.section sllgb +.section sllha +.section sllhb +.section sllia +.section sllib +.section sllja +.section slljb +.section sllka +.section sllkb +.section sllla +.section slllb +.section sllma +.section sllmb +.section sllna +.section sllnb +.section slloa +.section sllob +.section sllpa +.section sllpb +.section sllqa +.section sllqb +.section sllra +.section sllrb +.section sllsa +.section sllsb +.section sllta +.section slltb +.section sllua +.section sllub +.section sllva +.section sllvb +.section sllwa +.section sllwb +.section sllxa +.section sllxb +.section sllya +.section sllyb +.section sllza +.section sllzb +.section sll1a +.section sll1b +.section sll2a +.section sll2b +.section sll3a +.section sll3b +.section sll4a +.section sll4b +.section sll5a +.section sll5b +.section sll6a +.section sll6b +.section sll7a +.section sll7b +.section sll8a +.section sll8b +.section sll9a +.section sll9b +.section sll0a +.section sll0b +.section slmaa +.section slmab +.section slmba +.section slmbb +.section slmca +.section slmcb +.section slmda +.section slmdb +.section slmea +.section slmeb +.section slmfa +.section slmfb +.section slmga +.section slmgb +.section slmha +.section slmhb +.section slmia +.section slmib +.section slmja +.section slmjb +.section slmka +.section slmkb +.section slmla +.section slmlb +.section slmma +.section slmmb +.section slmna +.section slmnb +.section slmoa +.section slmob +.section slmpa +.section slmpb +.section slmqa +.section slmqb +.section slmra +.section slmrb +.section slmsa +.section slmsb +.section slmta +.section slmtb +.section slmua +.section slmub +.section slmva +.section slmvb +.section slmwa +.section slmwb +.section slmxa +.section slmxb +.section slmya +.section slmyb +.section slmza +.section slmzb +.section slm1a +.section slm1b +.section slm2a +.section slm2b +.section slm3a +.section slm3b +.section slm4a +.section slm4b +.section slm5a +.section slm5b +.section slm6a +.section slm6b +.section slm7a +.section slm7b +.section slm8a +.section slm8b +.section slm9a +.section slm9b +.section slm0a +.section slm0b +.section slnaa +.section slnab +.section slnba +.section slnbb +.section slnca +.section slncb +.section slnda +.section slndb +.section slnea +.section slneb +.section slnfa +.section slnfb +.section slnga +.section slngb +.section slnha +.section slnhb +.section slnia +.section slnib +.section slnja +.section slnjb +.section slnka +.section slnkb +.section slnla +.section slnlb +.section slnma +.section slnmb +.section slnna +.section slnnb +.section slnoa +.section slnob +.section slnpa +.section slnpb +.section slnqa +.section slnqb +.section slnra +.section slnrb +.section slnsa +.section slnsb +.section slnta +.section slntb +.section slnua +.section slnub +.section slnva +.section slnvb +.section slnwa +.section slnwb +.section slnxa +.section slnxb +.section slnya +.section slnyb +.section slnza +.section slnzb +.section sln1a +.section sln1b +.section sln2a +.section sln2b +.section sln3a +.section sln3b +.section sln4a +.section sln4b +.section sln5a +.section sln5b +.section sln6a +.section sln6b +.section sln7a +.section sln7b +.section sln8a +.section sln8b +.section sln9a +.section sln9b +.section sln0a +.section sln0b +.section sloaa +.section sloab +.section sloba +.section slobb +.section sloca +.section slocb +.section sloda +.section slodb +.section sloea +.section sloeb +.section slofa +.section slofb +.section sloga +.section slogb +.section sloha +.section slohb +.section sloia +.section sloib +.section sloja +.section slojb +.section sloka +.section slokb +.section slola +.section slolb +.section sloma +.section slomb +.section slona +.section slonb +.section slooa +.section sloob +.section slopa +.section slopb +.section sloqa +.section sloqb +.section slora +.section slorb +.section slosa +.section slosb +.section slota +.section slotb +.section sloua +.section sloub +.section slova +.section slovb +.section slowa +.section slowb +.section sloxa +.section sloxb +.section sloya +.section sloyb +.section sloza +.section slozb +.section slo1a +.section slo1b +.section slo2a +.section slo2b +.section slo3a +.section slo3b +.section slo4a +.section slo4b +.section slo5a +.section slo5b +.section slo6a +.section slo6b +.section slo7a +.section slo7b +.section slo8a +.section slo8b +.section slo9a +.section slo9b +.section slo0a +.section slo0b +.section slpaa +.section slpab +.section slpba +.section slpbb +.section slpca +.section slpcb +.section slpda +.section slpdb +.section slpea +.section slpeb +.section slpfa +.section slpfb +.section slpga +.section slpgb +.section slpha +.section slphb +.section slpia +.section slpib +.section slpja +.section slpjb +.section slpka +.section slpkb +.section slpla +.section slplb +.section slpma +.section slpmb +.section slpna +.section slpnb +.section slpoa +.section slpob +.section slppa +.section slppb +.section slpqa +.section slpqb +.section slpra +.section slprb +.section slpsa +.section slpsb +.section slpta +.section slptb +.section slpua +.section slpub +.section slpva +.section slpvb +.section slpwa +.section slpwb +.section slpxa +.section slpxb +.section slpya +.section slpyb +.section slpza +.section slpzb +.section slp1a +.section slp1b +.section slp2a +.section slp2b +.section slp3a +.section slp3b +.section slp4a +.section slp4b +.section slp5a +.section slp5b +.section slp6a +.section slp6b +.section slp7a +.section slp7b +.section slp8a +.section slp8b +.section slp9a +.section slp9b +.section slp0a +.section slp0b +.section slqaa +.section slqab +.section slqba +.section slqbb +.section slqca +.section slqcb +.section slqda +.section slqdb +.section slqea +.section slqeb +.section slqfa +.section slqfb +.section slqga +.section slqgb +.section slqha +.section slqhb +.section slqia +.section slqib +.section slqja +.section slqjb +.section slqka +.section slqkb +.section slqla +.section slqlb +.section slqma +.section slqmb +.section slqna +.section slqnb +.section slqoa +.section slqob +.section slqpa +.section slqpb +.section slqqa +.section slqqb +.section slqra +.section slqrb +.section slqsa +.section slqsb +.section slqta +.section slqtb +.section slqua +.section slqub +.section slqva +.section slqvb +.section slqwa +.section slqwb +.section slqxa +.section slqxb +.section slqya +.section slqyb +.section slqza +.section slqzb +.section slq1a +.section slq1b +.section slq2a +.section slq2b +.section slq3a +.section slq3b +.section slq4a +.section slq4b +.section slq5a +.section slq5b +.section slq6a +.section slq6b +.section slq7a +.section slq7b +.section slq8a +.section slq8b +.section slq9a +.section slq9b +.section slq0a +.section slq0b +.section slraa +.section slrab +.section slrba +.section slrbb +.section slrca +.section slrcb +.section slrda +.section slrdb +.section slrea +.section slreb +.section slrfa +.section slrfb +.section slrga +.section slrgb +.section slrha +.section slrhb +.section slria +.section slrib +.section slrja +.section slrjb +.section slrka +.section slrkb +.section slrla +.section slrlb +.section slrma +.section slrmb +.section slrna +.section slrnb +.section slroa +.section slrob +.section slrpa +.section slrpb +.section slrqa +.section slrqb +.section slrra +.section slrrb +.section slrsa +.section slrsb +.section slrta +.section slrtb +.section slrua +.section slrub +.section slrva +.section slrvb +.section slrwa +.section slrwb +.section slrxa +.section slrxb +.section slrya +.section slryb +.section slrza +.section slrzb +.section slr1a +.section slr1b +.section slr2a +.section slr2b +.section slr3a +.section slr3b +.section slr4a +.section slr4b +.section slr5a +.section slr5b +.section slr6a +.section slr6b +.section slr7a +.section slr7b +.section slr8a +.section slr8b +.section slr9a +.section slr9b +.section slr0a +.section slr0b +.section slsaa +.section slsab +.section slsba +.section slsbb +.section slsca +.section slscb +.section slsda +.section slsdb +.section slsea +.section slseb +.section slsfa +.section slsfb +.section slsga +.section slsgb +.section slsha +.section slshb +.section slsia +.section slsib +.section slsja +.section slsjb +.section slska +.section slskb +.section slsla +.section slslb +.section slsma +.section slsmb +.section slsna +.section slsnb +.section slsoa +.section slsob +.section slspa +.section slspb +.section slsqa +.section slsqb +.section slsra +.section slsrb +.section slssa +.section slssb +.section slsta +.section slstb +.section slsua +.section slsub +.section slsva +.section slsvb +.section slswa +.section slswb +.section slsxa +.section slsxb +.section slsya +.section slsyb +.section slsza +.section slszb +.section sls1a +.section sls1b +.section sls2a +.section sls2b +.section sls3a +.section sls3b +.section sls4a +.section sls4b +.section sls5a +.section sls5b +.section sls6a +.section sls6b +.section sls7a +.section sls7b +.section sls8a +.section sls8b +.section sls9a +.section sls9b +.section sls0a +.section sls0b +.section sltaa +.section sltab +.section sltba +.section sltbb +.section sltca +.section sltcb +.section sltda +.section sltdb +.section sltea +.section slteb +.section sltfa +.section sltfb +.section sltga +.section sltgb +.section sltha +.section slthb +.section sltia +.section sltib +.section sltja +.section sltjb +.section sltka +.section sltkb +.section sltla +.section sltlb +.section sltma +.section sltmb +.section sltna +.section sltnb +.section sltoa +.section sltob +.section sltpa +.section sltpb +.section sltqa +.section sltqb +.section sltra +.section sltrb +.section sltsa +.section sltsb +.section sltta +.section slttb +.section sltua +.section sltub +.section sltva +.section sltvb +.section sltwa +.section sltwb +.section sltxa +.section sltxb +.section sltya +.section sltyb +.section sltza +.section sltzb +.section slt1a +.section slt1b +.section slt2a +.section slt2b +.section slt3a +.section slt3b +.section slt4a +.section slt4b +.section slt5a +.section slt5b +.section slt6a +.section slt6b +.section slt7a +.section slt7b +.section slt8a +.section slt8b +.section slt9a +.section slt9b +.section slt0a +.section slt0b +.section sluaa +.section sluab +.section sluba +.section slubb +.section sluca +.section slucb +.section sluda +.section sludb +.section sluea +.section slueb +.section slufa +.section slufb +.section sluga +.section slugb +.section sluha +.section sluhb +.section sluia +.section sluib +.section sluja +.section slujb +.section sluka +.section slukb +.section slula +.section slulb +.section sluma +.section slumb +.section sluna +.section slunb +.section sluoa +.section sluob +.section slupa +.section slupb +.section sluqa +.section sluqb +.section slura +.section slurb +.section slusa +.section slusb +.section sluta +.section slutb +.section sluua +.section sluub +.section sluva +.section sluvb +.section sluwa +.section sluwb +.section sluxa +.section sluxb +.section sluya +.section sluyb +.section sluza +.section sluzb +.section slu1a +.section slu1b +.section slu2a +.section slu2b +.section slu3a +.section slu3b +.section slu4a +.section slu4b +.section slu5a +.section slu5b +.section slu6a +.section slu6b +.section slu7a +.section slu7b +.section slu8a +.section slu8b +.section slu9a +.section slu9b +.section slu0a +.section slu0b +.section slvaa +.section slvab +.section slvba +.section slvbb +.section slvca +.section slvcb +.section slvda +.section slvdb +.section slvea +.section slveb +.section slvfa +.section slvfb +.section slvga +.section slvgb +.section slvha +.section slvhb +.section slvia +.section slvib +.section slvja +.section slvjb +.section slvka +.section slvkb +.section slvla +.section slvlb +.section slvma +.section slvmb +.section slvna +.section slvnb +.section slvoa +.section slvob +.section slvpa +.section slvpb +.section slvqa +.section slvqb +.section slvra +.section slvrb +.section slvsa +.section slvsb +.section slvta +.section slvtb +.section slvua +.section slvub +.section slvva +.section slvvb +.section slvwa +.section slvwb +.section slvxa +.section slvxb +.section slvya +.section slvyb +.section slvza +.section slvzb +.section slv1a +.section slv1b +.section slv2a +.section slv2b +.section slv3a +.section slv3b +.section slv4a +.section slv4b +.section slv5a +.section slv5b +.section slv6a +.section slv6b +.section slv7a +.section slv7b +.section slv8a +.section slv8b +.section slv9a +.section slv9b +.section slv0a +.section slv0b +.section slwaa +.section slwab +.section slwba +.section slwbb +.section slwca +.section slwcb +.section slwda +.section slwdb +.section slwea +.section slweb +.section slwfa +.section slwfb +.section slwga +.section slwgb +.section slwha +.section slwhb +.section slwia +.section slwib +.section slwja +.section slwjb +.section slwka +.section slwkb +.section slwla +.section slwlb +.section slwma +.section slwmb +.section slwna +.section slwnb +.section slwoa +.section slwob +.section slwpa +.section slwpb +.section slwqa +.section slwqb +.section slwra +.section slwrb +.section slwsa +.section slwsb +.section slwta +.section slwtb +.section slwua +.section slwub +.section slwva +.section slwvb +.section slwwa +.section slwwb +.section slwxa +.section slwxb +.section slwya +.section slwyb +.section slwza +.section slwzb +.section slw1a +.section slw1b +.section slw2a +.section slw2b +.section slw3a +.section slw3b +.section slw4a +.section slw4b +.section slw5a +.section slw5b +.section slw6a +.section slw6b +.section slw7a +.section slw7b +.section slw8a +.section slw8b +.section slw9a +.section slw9b +.section slw0a +.section slw0b +.section slxaa +.section slxab +.section slxba +.section slxbb +.section slxca +.section slxcb +.section slxda +.section slxdb +.section slxea +.section slxeb +.section slxfa +.section slxfb +.section slxga +.section slxgb +.section slxha +.section slxhb +.section slxia +.section slxib +.section slxja +.section slxjb +.section slxka +.section slxkb +.section slxla +.section slxlb +.section slxma +.section slxmb +.section slxna +.section slxnb +.section slxoa +.section slxob +.section slxpa +.section slxpb +.section slxqa +.section slxqb +.section slxra +.section slxrb +.section slxsa +.section slxsb +.section slxta +.section slxtb +.section slxua +.section slxub +.section slxva +.section slxvb +.section slxwa +.section slxwb +.section slxxa +.section slxxb +.section slxya +.section slxyb +.section slxza +.section slxzb +.section slx1a +.section slx1b +.section slx2a +.section slx2b +.section slx3a +.section slx3b +.section slx4a +.section slx4b +.section slx5a +.section slx5b +.section slx6a +.section slx6b +.section slx7a +.section slx7b +.section slx8a +.section slx8b +.section slx9a +.section slx9b +.section slx0a +.section slx0b +.section slyaa +.section slyab +.section slyba +.section slybb +.section slyca +.section slycb +.section slyda +.section slydb +.section slyea +.section slyeb +.section slyfa +.section slyfb +.section slyga +.section slygb +.section slyha +.section slyhb +.section slyia +.section slyib +.section slyja +.section slyjb +.section slyka +.section slykb +.section slyla +.section slylb +.section slyma +.section slymb +.section slyna +.section slynb +.section slyoa +.section slyob +.section slypa +.section slypb +.section slyqa +.section slyqb +.section slyra +.section slyrb +.section slysa +.section slysb +.section slyta +.section slytb +.section slyua +.section slyub +.section slyva +.section slyvb +.section slywa +.section slywb +.section slyxa +.section slyxb +.section slyya +.section slyyb +.section slyza +.section slyzb +.section sly1a +.section sly1b +.section sly2a +.section sly2b +.section sly3a +.section sly3b +.section sly4a +.section sly4b +.section sly5a +.section sly5b +.section sly6a +.section sly6b +.section sly7a +.section sly7b +.section sly8a +.section sly8b +.section sly9a +.section sly9b +.section sly0a +.section sly0b +.section slzaa +.section slzab +.section slzba +.section slzbb +.section slzca +.section slzcb +.section slzda +.section slzdb +.section slzea +.section slzeb +.section slzfa +.section slzfb +.section slzga +.section slzgb +.section slzha +.section slzhb +.section slzia +.section slzib +.section slzja +.section slzjb +.section slzka +.section slzkb +.section slzla +.section slzlb +.section slzma +.section slzmb +.section slzna +.section slznb +.section slzoa +.section slzob +.section slzpa +.section slzpb +.section slzqa +.section slzqb +.section slzra +.section slzrb +.section slzsa +.section slzsb +.section slzta +.section slztb +.section slzua +.section slzub +.section slzva +.section slzvb +.section slzwa +.section slzwb +.section slzxa +.section slzxb +.section slzya +.section slzyb +.section slzza +.section slzzb +.section slz1a +.section slz1b +.section slz2a +.section slz2b +.section slz3a +.section slz3b +.section slz4a +.section slz4b +.section slz5a +.section slz5b +.section slz6a +.section slz6b +.section slz7a +.section slz7b +.section slz8a +.section slz8b +.section slz9a +.section slz9b +.section slz0a +.section slz0b +.section sl1aa +.section sl1ab +.section sl1ba +.section sl1bb +.section sl1ca +.section sl1cb +.section sl1da +.section sl1db +.section sl1ea +.section sl1eb +.section sl1fa +.section sl1fb +.section sl1ga +.section sl1gb +.section sl1ha +.section sl1hb +.section sl1ia +.section sl1ib +.section sl1ja +.section sl1jb +.section sl1ka +.section sl1kb +.section sl1la +.section sl1lb +.section sl1ma +.section sl1mb +.section sl1na +.section sl1nb +.section sl1oa +.section sl1ob +.section sl1pa +.section sl1pb +.section sl1qa +.section sl1qb +.section sl1ra +.section sl1rb +.section sl1sa +.section sl1sb +.section sl1ta +.section sl1tb +.section sl1ua +.section sl1ub +.section sl1va +.section sl1vb +.section sl1wa +.section sl1wb +.section sl1xa +.section sl1xb +.section sl1ya +.section sl1yb +.section sl1za +.section sl1zb +.section sl11a +.section sl11b +.section sl12a +.section sl12b +.section sl13a +.section sl13b +.section sl14a +.section sl14b +.section sl15a +.section sl15b +.section sl16a +.section sl16b +.section sl17a +.section sl17b +.section sl18a +.section sl18b +.section sl19a +.section sl19b +.section sl10a +.section sl10b +.section sl2aa +.section sl2ab +.section sl2ba +.section sl2bb +.section sl2ca +.section sl2cb +.section sl2da +.section sl2db +.section sl2ea +.section sl2eb +.section sl2fa +.section sl2fb +.section sl2ga +.section sl2gb +.section sl2ha +.section sl2hb +.section sl2ia +.section sl2ib +.section sl2ja +.section sl2jb +.section sl2ka +.section sl2kb +.section sl2la +.section sl2lb +.section sl2ma +.section sl2mb +.section sl2na +.section sl2nb +.section sl2oa +.section sl2ob +.section sl2pa +.section sl2pb +.section sl2qa +.section sl2qb +.section sl2ra +.section sl2rb +.section sl2sa +.section sl2sb +.section sl2ta +.section sl2tb +.section sl2ua +.section sl2ub +.section sl2va +.section sl2vb +.section sl2wa +.section sl2wb +.section sl2xa +.section sl2xb +.section sl2ya +.section sl2yb +.section sl2za +.section sl2zb +.section sl21a +.section sl21b +.section sl22a +.section sl22b +.section sl23a +.section sl23b +.section sl24a +.section sl24b +.section sl25a +.section sl25b +.section sl26a +.section sl26b +.section sl27a +.section sl27b +.section sl28a +.section sl28b +.section sl29a +.section sl29b +.section sl20a +.section sl20b +.section sl3aa +.section sl3ab +.section sl3ba +.section sl3bb +.section sl3ca +.section sl3cb +.section sl3da +.section sl3db +.section sl3ea +.section sl3eb +.section sl3fa +.section sl3fb +.section sl3ga +.section sl3gb +.section sl3ha +.section sl3hb +.section sl3ia +.section sl3ib +.section sl3ja +.section sl3jb +.section sl3ka +.section sl3kb +.section sl3la +.section sl3lb +.section sl3ma +.section sl3mb +.section sl3na +.section sl3nb +.section sl3oa +.section sl3ob +.section sl3pa +.section sl3pb +.section sl3qa +.section sl3qb +.section sl3ra +.section sl3rb +.section sl3sa +.section sl3sb +.section sl3ta +.section sl3tb +.section sl3ua +.section sl3ub +.section sl3va +.section sl3vb +.section sl3wa +.section sl3wb +.section sl3xa +.section sl3xb +.section sl3ya +.section sl3yb +.section sl3za +.section sl3zb +.section sl31a +.section sl31b +.section sl32a +.section sl32b +.section sl33a +.section sl33b +.section sl34a +.section sl34b +.section sl35a +.section sl35b +.section sl36a +.section sl36b +.section sl37a +.section sl37b +.section sl38a +.section sl38b +.section sl39a +.section sl39b +.section sl30a +.section sl30b +.section sl4aa +.section sl4ab +.section sl4ba +.section sl4bb +.section sl4ca +.section sl4cb +.section sl4da +.section sl4db +.section sl4ea +.section sl4eb +.section sl4fa +.section sl4fb +.section sl4ga +.section sl4gb +.section sl4ha +.section sl4hb +.section sl4ia +.section sl4ib +.section sl4ja +.section sl4jb +.section sl4ka +.section sl4kb +.section sl4la +.section sl4lb +.section sl4ma +.section sl4mb +.section sl4na +.section sl4nb +.section sl4oa +.section sl4ob +.section sl4pa +.section sl4pb +.section sl4qa +.section sl4qb +.section sl4ra +.section sl4rb +.section sl4sa +.section sl4sb +.section sl4ta +.section sl4tb +.section sl4ua +.section sl4ub +.section sl4va +.section sl4vb +.section sl4wa +.section sl4wb +.section sl4xa +.section sl4xb +.section sl4ya +.section sl4yb +.section sl4za +.section sl4zb +.section sl41a +.section sl41b +.section sl42a +.section sl42b +.section sl43a +.section sl43b +.section sl44a +.section sl44b +.section sl45a +.section sl45b +.section sl46a +.section sl46b +.section sl47a +.section sl47b +.section sl48a +.section sl48b +.section sl49a +.section sl49b +.section sl40a +.section sl40b +.section sl5aa +.section sl5ab +.section sl5ba +.section sl5bb +.section sl5ca +.section sl5cb +.section sl5da +.section sl5db +.section sl5ea +.section sl5eb +.section sl5fa +.section sl5fb +.section sl5ga +.section sl5gb +.section sl5ha +.section sl5hb +.section sl5ia +.section sl5ib +.section sl5ja +.section sl5jb +.section sl5ka +.section sl5kb +.section sl5la +.section sl5lb +.section sl5ma +.section sl5mb +.section sl5na +.section sl5nb +.section sl5oa +.section sl5ob +.section sl5pa +.section sl5pb +.section sl5qa +.section sl5qb +.section sl5ra +.section sl5rb +.section sl5sa +.section sl5sb +.section sl5ta +.section sl5tb +.section sl5ua +.section sl5ub +.section sl5va +.section sl5vb +.section sl5wa +.section sl5wb +.section sl5xa +.section sl5xb +.section sl5ya +.section sl5yb +.section sl5za +.section sl5zb +.section sl51a +.section sl51b +.section sl52a +.section sl52b +.section sl53a +.section sl53b +.section sl54a +.section sl54b +.section sl55a +.section sl55b +.section sl56a +.section sl56b +.section sl57a +.section sl57b +.section sl58a +.section sl58b +.section sl59a +.section sl59b +.section sl50a +.section sl50b +.section sl6aa +.section sl6ab +.section sl6ba +.section sl6bb +.section sl6ca +.section sl6cb +.section sl6da +.section sl6db +.section sl6ea +.section sl6eb +.section sl6fa +.section sl6fb +.section sl6ga +.section sl6gb +.section sl6ha +.section sl6hb +.section sl6ia +.section sl6ib +.section sl6ja +.section sl6jb +.section sl6ka +.section sl6kb +.section sl6la +.section sl6lb +.section sl6ma +.section sl6mb +.section sl6na +.section sl6nb +.section sl6oa +.section sl6ob +.section sl6pa +.section sl6pb +.section sl6qa +.section sl6qb +.section sl6ra +.section sl6rb +.section sl6sa +.section sl6sb +.section sl6ta +.section sl6tb +.section sl6ua +.section sl6ub +.section sl6va +.section sl6vb +.section sl6wa +.section sl6wb +.section sl6xa +.section sl6xb +.section sl6ya +.section sl6yb +.section sl6za +.section sl6zb +.section sl61a +.section sl61b +.section sl62a +.section sl62b +.section sl63a +.section sl63b +.section sl64a +.section sl64b +.section sl65a +.section sl65b +.section sl66a +.section sl66b +.section sl67a +.section sl67b +.section sl68a +.section sl68b +.section sl69a +.section sl69b +.section sl60a +.section sl60b +.section sl7aa +.section sl7ab +.section sl7ba +.section sl7bb +.section sl7ca +.section sl7cb +.section sl7da +.section sl7db +.section sl7ea +.section sl7eb +.section sl7fa +.section sl7fb +.section sl7ga +.section sl7gb +.section sl7ha +.section sl7hb +.section sl7ia +.section sl7ib +.section sl7ja +.section sl7jb +.section sl7ka +.section sl7kb +.section sl7la +.section sl7lb +.section sl7ma +.section sl7mb +.section sl7na +.section sl7nb +.section sl7oa +.section sl7ob +.section sl7pa +.section sl7pb +.section sl7qa +.section sl7qb +.section sl7ra +.section sl7rb +.section sl7sa +.section sl7sb +.section sl7ta +.section sl7tb +.section sl7ua +.section sl7ub +.section sl7va +.section sl7vb +.section sl7wa +.section sl7wb +.section sl7xa +.section sl7xb +.section sl7ya +.section sl7yb +.section sl7za +.section sl7zb +.section sl71a +.section sl71b +.section sl72a +.section sl72b +.section sl73a +.section sl73b +.section sl74a +.section sl74b +.section sl75a +.section sl75b +.section sl76a +.section sl76b +.section sl77a +.section sl77b +.section sl78a +.section sl78b +.section sl79a +.section sl79b +.section sl70a +.section sl70b +.section sl8aa +.section sl8ab +.section sl8ba +.section sl8bb +.section sl8ca +.section sl8cb +.section sl8da +.section sl8db +.section sl8ea +.section sl8eb +.section sl8fa +.section sl8fb +.section sl8ga +.section sl8gb +.section sl8ha +.section sl8hb +.section sl8ia +.section sl8ib +.section sl8ja +.section sl8jb +.section sl8ka +.section sl8kb +.section sl8la +.section sl8lb +.section sl8ma +.section sl8mb +.section sl8na +.section sl8nb +.section sl8oa +.section sl8ob +.section sl8pa +.section sl8pb +.section sl8qa +.section sl8qb +.section sl8ra +.section sl8rb +.section sl8sa +.section sl8sb +.section sl8ta +.section sl8tb +.section sl8ua +.section sl8ub +.section sl8va +.section sl8vb +.section sl8wa +.section sl8wb +.section sl8xa +.section sl8xb +.section sl8ya +.section sl8yb +.section sl8za +.section sl8zb +.section sl81a +.section sl81b +.section sl82a +.section sl82b +.section sl83a +.section sl83b +.section sl84a +.section sl84b +.section sl85a +.section sl85b +.section sl86a +.section sl86b +.section sl87a +.section sl87b +.section sl88a +.section sl88b +.section sl89a +.section sl89b +.section sl80a +.section sl80b +.section sl9aa +.section sl9ab +.section sl9ba +.section sl9bb +.section sl9ca +.section sl9cb +.section sl9da +.section sl9db +.section sl9ea +.section sl9eb +.section sl9fa +.section sl9fb +.section sl9ga +.section sl9gb +.section sl9ha +.section sl9hb +.section sl9ia +.section sl9ib +.section sl9ja +.section sl9jb +.section sl9ka +.section sl9kb +.section sl9la +.section sl9lb +.section sl9ma +.section sl9mb +.section sl9na +.section sl9nb +.section sl9oa +.section sl9ob +.section sl9pa +.section sl9pb +.section sl9qa +.section sl9qb +.section sl9ra +.section sl9rb +.section sl9sa +.section sl9sb +.section sl9ta +.section sl9tb +.section sl9ua +.section sl9ub +.section sl9va +.section sl9vb +.section sl9wa +.section sl9wb +.section sl9xa +.section sl9xb +.section sl9ya +.section sl9yb +.section sl9za +.section sl9zb +.section sl91a +.section sl91b +.section sl92a +.section sl92b +.section sl93a +.section sl93b +.section sl94a +.section sl94b +.section sl95a +.section sl95b +.section sl96a +.section sl96b +.section sl97a +.section sl97b +.section sl98a +.section sl98b +.section sl99a +.section sl99b +.section sl90a +.section sl90b +.section sl0aa +.section sl0ab +.section sl0ba +.section sl0bb +.section sl0ca +.section sl0cb +.section sl0da +.section sl0db +.section sl0ea +.section sl0eb +.section sl0fa +.section sl0fb +.section sl0ga +.section sl0gb +.section sl0ha +.section sl0hb +.section sl0ia +.section sl0ib +.section sl0ja +.section sl0jb +.section sl0ka +.section sl0kb +.section sl0la +.section sl0lb +.section sl0ma +.section sl0mb +.section sl0na +.section sl0nb +.section sl0oa +.section sl0ob +.section sl0pa +.section sl0pb +.section sl0qa +.section sl0qb +.section sl0ra +.section sl0rb +.section sl0sa +.section sl0sb +.section sl0ta +.section sl0tb +.section sl0ua +.section sl0ub +.section sl0va +.section sl0vb +.section sl0wa +.section sl0wb +.section sl0xa +.section sl0xb +.section sl0ya +.section sl0yb +.section sl0za +.section sl0zb +.section sl01a +.section sl01b +.section sl02a +.section sl02b +.section sl03a +.section sl03b +.section sl04a +.section sl04b +.section sl05a +.section sl05b +.section sl06a +.section sl06b +.section sl07a +.section sl07b +.section sl08a +.section sl08b +.section sl09a +.section sl09b +.section sl00a +.section sl00b +.section smaaa +.section smaab +.section smaba +.section smabb +.section smaca +.section smacb +.section smada +.section smadb +.section smaea +.section smaeb +.section smafa +.section smafb +.section smaga +.section smagb +.section smaha +.section smahb +.section smaia +.section smaib +.section smaja +.section smajb +.section smaka +.section smakb +.section smala +.section smalb +.section smama +.section smamb +.section smana +.section smanb +.section smaoa +.section smaob +.section smapa +.section smapb +.section smaqa +.section smaqb +.section smara +.section smarb +.section smasa +.section smasb +.section smata +.section smatb +.section smaua +.section smaub +.section smava +.section smavb +.section smawa +.section smawb +.section smaxa +.section smaxb +.section smaya +.section smayb +.section smaza +.section smazb +.section sma1a +.section sma1b +.section sma2a +.section sma2b +.section sma3a +.section sma3b +.section sma4a +.section sma4b +.section sma5a +.section sma5b +.section sma6a +.section sma6b +.section sma7a +.section sma7b +.section sma8a +.section sma8b +.section sma9a +.section sma9b +.section sma0a +.section sma0b +.section smbaa +.section smbab +.section smbba +.section smbbb +.section smbca +.section smbcb +.section smbda +.section smbdb +.section smbea +.section smbeb +.section smbfa +.section smbfb +.section smbga +.section smbgb +.section smbha +.section smbhb +.section smbia +.section smbib +.section smbja +.section smbjb +.section smbka +.section smbkb +.section smbla +.section smblb +.section smbma +.section smbmb +.section smbna +.section smbnb +.section smboa +.section smbob +.section smbpa +.section smbpb +.section smbqa +.section smbqb +.section smbra +.section smbrb +.section smbsa +.section smbsb +.section smbta +.section smbtb +.section smbua +.section smbub +.section smbva +.section smbvb +.section smbwa +.section smbwb +.section smbxa +.section smbxb +.section smbya +.section smbyb +.section smbza +.section smbzb +.section smb1a +.section smb1b +.section smb2a +.section smb2b +.section smb3a +.section smb3b +.section smb4a +.section smb4b +.section smb5a +.section smb5b +.section smb6a +.section smb6b +.section smb7a +.section smb7b +.section smb8a +.section smb8b +.section smb9a +.section smb9b +.section smb0a +.section smb0b +.section smcaa +.section smcab +.section smcba +.section smcbb +.section smcca +.section smccb +.section smcda +.section smcdb +.section smcea +.section smceb +.section smcfa +.section smcfb +.section smcga +.section smcgb +.section smcha +.section smchb +.section smcia +.section smcib +.section smcja +.section smcjb +.section smcka +.section smckb +.section smcla +.section smclb +.section smcma +.section smcmb +.section smcna +.section smcnb +.section smcoa +.section smcob +.section smcpa +.section smcpb +.section smcqa +.section smcqb +.section smcra +.section smcrb +.section smcsa +.section smcsb +.section smcta +.section smctb +.section smcua +.section smcub +.section smcva +.section smcvb +.section smcwa +.section smcwb +.section smcxa +.section smcxb +.section smcya +.section smcyb +.section smcza +.section smczb +.section smc1a +.section smc1b +.section smc2a +.section smc2b +.section smc3a +.section smc3b +.section smc4a +.section smc4b +.section smc5a +.section smc5b +.section smc6a +.section smc6b +.section smc7a +.section smc7b +.section smc8a +.section smc8b +.section smc9a +.section smc9b +.section smc0a +.section smc0b +.section smdaa +.section smdab +.section smdba +.section smdbb +.section smdca +.section smdcb +.section smdda +.section smddb +.section smdea +.section smdeb +.section smdfa +.section smdfb +.section smdga +.section smdgb +.section smdha +.section smdhb +.section smdia +.section smdib +.section smdja +.section smdjb +.section smdka +.section smdkb +.section smdla +.section smdlb +.section smdma +.section smdmb +.section smdna +.section smdnb +.section smdoa +.section smdob +.section smdpa +.section smdpb +.section smdqa +.section smdqb +.section smdra +.section smdrb +.section smdsa +.section smdsb +.section smdta +.section smdtb +.section smdua +.section smdub +.section smdva +.section smdvb +.section smdwa +.section smdwb +.section smdxa +.section smdxb +.section smdya +.section smdyb +.section smdza +.section smdzb +.section smd1a +.section smd1b +.section smd2a +.section smd2b +.section smd3a +.section smd3b +.section smd4a +.section smd4b +.section smd5a +.section smd5b +.section smd6a +.section smd6b +.section smd7a +.section smd7b +.section smd8a +.section smd8b +.section smd9a +.section smd9b +.section smd0a +.section smd0b +.section smeaa +.section smeab +.section smeba +.section smebb +.section smeca +.section smecb +.section smeda +.section smedb +.section smeea +.section smeeb +.section smefa +.section smefb +.section smega +.section smegb +.section smeha +.section smehb +.section smeia +.section smeib +.section smeja +.section smejb +.section smeka +.section smekb +.section smela +.section smelb +.section smema +.section smemb +.section smena +.section smenb +.section smeoa +.section smeob +.section smepa +.section smepb +.section smeqa +.section smeqb +.section smera +.section smerb +.section smesa +.section smesb +.section smeta +.section smetb +.section smeua +.section smeub +.section smeva +.section smevb +.section smewa +.section smewb +.section smexa +.section smexb +.section smeya +.section smeyb +.section smeza +.section smezb +.section sme1a +.section sme1b +.section sme2a +.section sme2b +.section sme3a +.section sme3b +.section sme4a +.section sme4b +.section sme5a +.section sme5b +.section sme6a +.section sme6b +.section sme7a +.section sme7b +.section sme8a +.section sme8b +.section sme9a +.section sme9b +.section sme0a +.section sme0b +.section smfaa +.section smfab +.section smfba +.section smfbb +.section smfca +.section smfcb +.section smfda +.section smfdb +.section smfea +.section smfeb +.section smffa +.section smffb +.section smfga +.section smfgb +.section smfha +.section smfhb +.section smfia +.section smfib +.section smfja +.section smfjb +.section smfka +.section smfkb +.section smfla +.section smflb +.section smfma +.section smfmb +.section smfna +.section smfnb +.section smfoa +.section smfob +.section smfpa +.section smfpb +.section smfqa +.section smfqb +.section smfra +.section smfrb +.section smfsa +.section smfsb +.section smfta +.section smftb +.section smfua +.section smfub +.section smfva +.section smfvb +.section smfwa +.section smfwb +.section smfxa +.section smfxb +.section smfya +.section smfyb +.section smfza +.section smfzb +.section smf1a +.section smf1b +.section smf2a +.section smf2b +.section smf3a +.section smf3b +.section smf4a +.section smf4b +.section smf5a +.section smf5b +.section smf6a +.section smf6b +.section smf7a +.section smf7b +.section smf8a +.section smf8b +.section smf9a +.section smf9b +.section smf0a +.section smf0b +.section smgaa +.section smgab +.section smgba +.section smgbb +.section smgca +.section smgcb +.section smgda +.section smgdb +.section smgea +.section smgeb +.section smgfa +.section smgfb +.section smgga +.section smggb +.section smgha +.section smghb +.section smgia +.section smgib +.section smgja +.section smgjb +.section smgka +.section smgkb +.section smgla +.section smglb +.section smgma +.section smgmb +.section smgna +.section smgnb +.section smgoa +.section smgob +.section smgpa +.section smgpb +.section smgqa +.section smgqb +.section smgra +.section smgrb +.section smgsa +.section smgsb +.section smgta +.section smgtb +.section smgua +.section smgub +.section smgva +.section smgvb +.section smgwa +.section smgwb +.section smgxa +.section smgxb +.section smgya +.section smgyb +.section smgza +.section smgzb +.section smg1a +.section smg1b +.section smg2a +.section smg2b +.section smg3a +.section smg3b +.section smg4a +.section smg4b +.section smg5a +.section smg5b +.section smg6a +.section smg6b +.section smg7a +.section smg7b +.section smg8a +.section smg8b +.section smg9a +.section smg9b +.section smg0a +.section smg0b +.section smhaa +.section smhab +.section smhba +.section smhbb +.section smhca +.section smhcb +.section smhda +.section smhdb +.section smhea +.section smheb +.section smhfa +.section smhfb +.section smhga +.section smhgb +.section smhha +.section smhhb +.section smhia +.section smhib +.section smhja +.section smhjb +.section smhka +.section smhkb +.section smhla +.section smhlb +.section smhma +.section smhmb +.section smhna +.section smhnb +.section smhoa +.section smhob +.section smhpa +.section smhpb +.section smhqa +.section smhqb +.section smhra +.section smhrb +.section smhsa +.section smhsb +.section smhta +.section smhtb +.section smhua +.section smhub +.section smhva +.section smhvb +.section smhwa +.section smhwb +.section smhxa +.section smhxb +.section smhya +.section smhyb +.section smhza +.section smhzb +.section smh1a +.section smh1b +.section smh2a +.section smh2b +.section smh3a +.section smh3b +.section smh4a +.section smh4b +.section smh5a +.section smh5b +.section smh6a +.section smh6b +.section smh7a +.section smh7b +.section smh8a +.section smh8b +.section smh9a +.section smh9b +.section smh0a +.section smh0b +.section smiaa +.section smiab +.section smiba +.section smibb +.section smica +.section smicb +.section smida +.section smidb +.section smiea +.section smieb +.section smifa +.section smifb +.section smiga +.section smigb +.section smiha +.section smihb +.section smiia +.section smiib +.section smija +.section smijb +.section smika +.section smikb +.section smila +.section smilb +.section smima +.section smimb +.section smina +.section sminb +.section smioa +.section smiob +.section smipa +.section smipb +.section smiqa +.section smiqb +.section smira +.section smirb +.section smisa +.section smisb +.section smita +.section smitb +.section smiua +.section smiub +.section smiva +.section smivb +.section smiwa +.section smiwb +.section smixa +.section smixb +.section smiya +.section smiyb +.section smiza +.section smizb +.section smi1a +.section smi1b +.section smi2a +.section smi2b +.section smi3a +.section smi3b +.section smi4a +.section smi4b +.section smi5a +.section smi5b +.section smi6a +.section smi6b +.section smi7a +.section smi7b +.section smi8a +.section smi8b +.section smi9a +.section smi9b +.section smi0a +.section smi0b +.section smjaa +.section smjab +.section smjba +.section smjbb +.section smjca +.section smjcb +.section smjda +.section smjdb +.section smjea +.section smjeb +.section smjfa +.section smjfb +.section smjga +.section smjgb +.section smjha +.section smjhb +.section smjia +.section smjib +.section smjja +.section smjjb +.section smjka +.section smjkb +.section smjla +.section smjlb +.section smjma +.section smjmb +.section smjna +.section smjnb +.section smjoa +.section smjob +.section smjpa +.section smjpb +.section smjqa +.section smjqb +.section smjra +.section smjrb +.section smjsa +.section smjsb +.section smjta +.section smjtb +.section smjua +.section smjub +.section smjva +.section smjvb +.section smjwa +.section smjwb +.section smjxa +.section smjxb +.section smjya +.section smjyb +.section smjza +.section smjzb +.section smj1a +.section smj1b +.section smj2a +.section smj2b +.section smj3a +.section smj3b +.section smj4a +.section smj4b +.section smj5a +.section smj5b +.section smj6a +.section smj6b +.section smj7a +.section smj7b +.section smj8a +.section smj8b +.section smj9a +.section smj9b +.section smj0a +.section smj0b +.section smkaa +.section smkab +.section smkba +.section smkbb +.section smkca +.section smkcb +.section smkda +.section smkdb +.section smkea +.section smkeb +.section smkfa +.section smkfb +.section smkga +.section smkgb +.section smkha +.section smkhb +.section smkia +.section smkib +.section smkja +.section smkjb +.section smkka +.section smkkb +.section smkla +.section smklb +.section smkma +.section smkmb +.section smkna +.section smknb +.section smkoa +.section smkob +.section smkpa +.section smkpb +.section smkqa +.section smkqb +.section smkra +.section smkrb +.section smksa +.section smksb +.section smkta +.section smktb +.section smkua +.section smkub +.section smkva +.section smkvb +.section smkwa +.section smkwb +.section smkxa +.section smkxb +.section smkya +.section smkyb +.section smkza +.section smkzb +.section smk1a +.section smk1b +.section smk2a +.section smk2b +.section smk3a +.section smk3b +.section smk4a +.section smk4b +.section smk5a +.section smk5b +.section smk6a +.section smk6b +.section smk7a +.section smk7b +.section smk8a +.section smk8b +.section smk9a +.section smk9b +.section smk0a +.section smk0b +.section smlaa +.section smlab +.section smlba +.section smlbb +.section smlca +.section smlcb +.section smlda +.section smldb +.section smlea +.section smleb +.section smlfa +.section smlfb +.section smlga +.section smlgb +.section smlha +.section smlhb +.section smlia +.section smlib +.section smlja +.section smljb +.section smlka +.section smlkb +.section smlla +.section smllb +.section smlma +.section smlmb +.section smlna +.section smlnb +.section smloa +.section smlob +.section smlpa +.section smlpb +.section smlqa +.section smlqb +.section smlra +.section smlrb +.section smlsa +.section smlsb +.section smlta +.section smltb +.section smlua +.section smlub +.section smlva +.section smlvb +.section smlwa +.section smlwb +.section smlxa +.section smlxb +.section smlya +.section smlyb +.section smlza +.section smlzb +.section sml1a +.section sml1b +.section sml2a +.section sml2b +.section sml3a +.section sml3b +.section sml4a +.section sml4b +.section sml5a +.section sml5b +.section sml6a +.section sml6b +.section sml7a +.section sml7b +.section sml8a +.section sml8b +.section sml9a +.section sml9b +.section sml0a +.section sml0b +.section smmaa +.section smmab +.section smmba +.section smmbb +.section smmca +.section smmcb +.section smmda +.section smmdb +.section smmea +.section smmeb +.section smmfa +.section smmfb +.section smmga +.section smmgb +.section smmha +.section smmhb +.section smmia +.section smmib +.section smmja +.section smmjb +.section smmka +.section smmkb +.section smmla +.section smmlb +.section smmma +.section smmmb +.section smmna +.section smmnb +.section smmoa +.section smmob +.section smmpa +.section smmpb +.section smmqa +.section smmqb +.section smmra +.section smmrb +.section smmsa +.section smmsb +.section smmta +.section smmtb +.section smmua +.section smmub +.section smmva +.section smmvb +.section smmwa +.section smmwb +.section smmxa +.section smmxb +.section smmya +.section smmyb +.section smmza +.section smmzb +.section smm1a +.section smm1b +.section smm2a +.section smm2b +.section smm3a +.section smm3b +.section smm4a +.section smm4b +.section smm5a +.section smm5b +.section smm6a +.section smm6b +.section smm7a +.section smm7b +.section smm8a +.section smm8b +.section smm9a +.section smm9b +.section smm0a +.section smm0b +.section smnaa +.section smnab +.section smnba +.section smnbb +.section smnca +.section smncb +.section smnda +.section smndb +.section smnea +.section smneb +.section smnfa +.section smnfb +.section smnga +.section smngb +.section smnha +.section smnhb +.section smnia +.section smnib +.section smnja +.section smnjb +.section smnka +.section smnkb +.section smnla +.section smnlb +.section smnma +.section smnmb +.section smnna +.section smnnb +.section smnoa +.section smnob +.section smnpa +.section smnpb +.section smnqa +.section smnqb +.section smnra +.section smnrb +.section smnsa +.section smnsb +.section smnta +.section smntb +.section smnua +.section smnub +.section smnva +.section smnvb +.section smnwa +.section smnwb +.section smnxa +.section smnxb +.section smnya +.section smnyb +.section smnza +.section smnzb +.section smn1a +.section smn1b +.section smn2a +.section smn2b +.section smn3a +.section smn3b +.section smn4a +.section smn4b +.section smn5a +.section smn5b +.section smn6a +.section smn6b +.section smn7a +.section smn7b +.section smn8a +.section smn8b +.section smn9a +.section smn9b +.section smn0a +.section smn0b +.section smoaa +.section smoab +.section smoba +.section smobb +.section smoca +.section smocb +.section smoda +.section smodb +.section smoea +.section smoeb +.section smofa +.section smofb +.section smoga +.section smogb +.section smoha +.section smohb +.section smoia +.section smoib +.section smoja +.section smojb +.section smoka +.section smokb +.section smola +.section smolb +.section smoma +.section smomb +.section smona +.section smonb +.section smooa +.section smoob +.section smopa +.section smopb +.section smoqa +.section smoqb +.section smora +.section smorb +.section smosa +.section smosb +.section smota +.section smotb +.section smoua +.section smoub +.section smova +.section smovb +.section smowa +.section smowb +.section smoxa +.section smoxb +.section smoya +.section smoyb +.section smoza +.section smozb +.section smo1a +.section smo1b +.section smo2a +.section smo2b +.section smo3a +.section smo3b +.section smo4a +.section smo4b +.section smo5a +.section smo5b +.section smo6a +.section smo6b +.section smo7a +.section smo7b +.section smo8a +.section smo8b +.section smo9a +.section smo9b +.section smo0a +.section smo0b +.section smpaa +.section smpab +.section smpba +.section smpbb +.section smpca +.section smpcb +.section smpda +.section smpdb +.section smpea +.section smpeb +.section smpfa +.section smpfb +.section smpga +.section smpgb +.section smpha +.section smphb +.section smpia +.section smpib +.section smpja +.section smpjb +.section smpka +.section smpkb +.section smpla +.section smplb +.section smpma +.section smpmb +.section smpna +.section smpnb +.section smpoa +.section smpob +.section smppa +.section smppb +.section smpqa +.section smpqb +.section smpra +.section smprb +.section smpsa +.section smpsb +.section smpta +.section smptb +.section smpua +.section smpub +.section smpva +.section smpvb +.section smpwa +.section smpwb +.section smpxa +.section smpxb +.section smpya +.section smpyb +.section smpza +.section smpzb +.section smp1a +.section smp1b +.section smp2a +.section smp2b +.section smp3a +.section smp3b +.section smp4a +.section smp4b +.section smp5a +.section smp5b +.section smp6a +.section smp6b +.section smp7a +.section smp7b +.section smp8a +.section smp8b +.section smp9a +.section smp9b +.section smp0a +.section smp0b +.section smqaa +.section smqab +.section smqba +.section smqbb +.section smqca +.section smqcb +.section smqda +.section smqdb +.section smqea +.section smqeb +.section smqfa +.section smqfb +.section smqga +.section smqgb +.section smqha +.section smqhb +.section smqia +.section smqib +.section smqja +.section smqjb +.section smqka +.section smqkb +.section smqla +.section smqlb +.section smqma +.section smqmb +.section smqna +.section smqnb +.section smqoa +.section smqob +.section smqpa +.section smqpb +.section smqqa +.section smqqb +.section smqra +.section smqrb +.section smqsa +.section smqsb +.section smqta +.section smqtb +.section smqua +.section smqub +.section smqva +.section smqvb +.section smqwa +.section smqwb +.section smqxa +.section smqxb +.section smqya +.section smqyb +.section smqza +.section smqzb +.section smq1a +.section smq1b +.section smq2a +.section smq2b +.section smq3a +.section smq3b +.section smq4a +.section smq4b +.section smq5a +.section smq5b +.section smq6a +.section smq6b +.section smq7a +.section smq7b +.section smq8a +.section smq8b +.section smq9a +.section smq9b +.section smq0a +.section smq0b +.section smraa +.section smrab +.section smrba +.section smrbb +.section smrca +.section smrcb +.section smrda +.section smrdb +.section smrea +.section smreb +.section smrfa +.section smrfb +.section smrga +.section smrgb +.section smrha +.section smrhb +.section smria +.section smrib +.section smrja +.section smrjb +.section smrka +.section smrkb +.section smrla +.section smrlb +.section smrma +.section smrmb +.section smrna +.section smrnb +.section smroa +.section smrob +.section smrpa +.section smrpb +.section smrqa +.section smrqb +.section smrra +.section smrrb +.section smrsa +.section smrsb +.section smrta +.section smrtb +.section smrua +.section smrub +.section smrva +.section smrvb +.section smrwa +.section smrwb +.section smrxa +.section smrxb +.section smrya +.section smryb +.section smrza +.section smrzb +.section smr1a +.section smr1b +.section smr2a +.section smr2b +.section smr3a +.section smr3b +.section smr4a +.section smr4b +.section smr5a +.section smr5b +.section smr6a +.section smr6b +.section smr7a +.section smr7b +.section smr8a +.section smr8b +.section smr9a +.section smr9b +.section smr0a +.section smr0b +.section smsaa +.section smsab +.section smsba +.section smsbb +.section smsca +.section smscb +.section smsda +.section smsdb +.section smsea +.section smseb +.section smsfa +.section smsfb +.section smsga +.section smsgb +.section smsha +.section smshb +.section smsia +.section smsib +.section smsja +.section smsjb +.section smska +.section smskb +.section smsla +.section smslb +.section smsma +.section smsmb +.section smsna +.section smsnb +.section smsoa +.section smsob +.section smspa +.section smspb +.section smsqa +.section smsqb +.section smsra +.section smsrb +.section smssa +.section smssb +.section smsta +.section smstb +.section smsua +.section smsub +.section smsva +.section smsvb +.section smswa +.section smswb +.section smsxa +.section smsxb +.section smsya +.section smsyb +.section smsza +.section smszb +.section sms1a +.section sms1b +.section sms2a +.section sms2b +.section sms3a +.section sms3b +.section sms4a +.section sms4b +.section sms5a +.section sms5b +.section sms6a +.section sms6b +.section sms7a +.section sms7b +.section sms8a +.section sms8b +.section sms9a +.section sms9b +.section sms0a +.section sms0b +.section smtaa +.section smtab +.section smtba +.section smtbb +.section smtca +.section smtcb +.section smtda +.section smtdb +.section smtea +.section smteb +.section smtfa +.section smtfb +.section smtga +.section smtgb +.section smtha +.section smthb +.section smtia +.section smtib +.section smtja +.section smtjb +.section smtka +.section smtkb +.section smtla +.section smtlb +.section smtma +.section smtmb +.section smtna +.section smtnb +.section smtoa +.section smtob +.section smtpa +.section smtpb +.section smtqa +.section smtqb +.section smtra +.section smtrb +.section smtsa +.section smtsb +.section smtta +.section smttb +.section smtua +.section smtub +.section smtva +.section smtvb +.section smtwa +.section smtwb +.section smtxa +.section smtxb +.section smtya +.section smtyb +.section smtza +.section smtzb +.section smt1a +.section smt1b +.section smt2a +.section smt2b +.section smt3a +.section smt3b +.section smt4a +.section smt4b +.section smt5a +.section smt5b +.section smt6a +.section smt6b +.section smt7a +.section smt7b +.section smt8a +.section smt8b +.section smt9a +.section smt9b +.section smt0a +.section smt0b +.section smuaa +.section smuab +.section smuba +.section smubb +.section smuca +.section smucb +.section smuda +.section smudb +.section smuea +.section smueb +.section smufa +.section smufb +.section smuga +.section smugb +.section smuha +.section smuhb +.section smuia +.section smuib +.section smuja +.section smujb +.section smuka +.section smukb +.section smula +.section smulb +.section smuma +.section smumb +.section smuna +.section smunb +.section smuoa +.section smuob +.section smupa +.section smupb +.section smuqa +.section smuqb +.section smura +.section smurb +.section smusa +.section smusb +.section smuta +.section smutb +.section smuua +.section smuub +.section smuva +.section smuvb +.section smuwa +.section smuwb +.section smuxa +.section smuxb +.section smuya +.section smuyb +.section smuza +.section smuzb +.section smu1a +.section smu1b +.section smu2a +.section smu2b +.section smu3a +.section smu3b +.section smu4a +.section smu4b +.section smu5a +.section smu5b +.section smu6a +.section smu6b +.section smu7a +.section smu7b +.section smu8a +.section smu8b +.section smu9a +.section smu9b +.section smu0a +.section smu0b +.section smvaa +.section smvab +.section smvba +.section smvbb +.section smvca +.section smvcb +.section smvda +.section smvdb +.section smvea +.section smveb +.section smvfa +.section smvfb +.section smvga +.section smvgb +.section smvha +.section smvhb +.section smvia +.section smvib +.section smvja +.section smvjb +.section smvka +.section smvkb +.section smvla +.section smvlb +.section smvma +.section smvmb +.section smvna +.section smvnb +.section smvoa +.section smvob +.section smvpa +.section smvpb +.section smvqa +.section smvqb +.section smvra +.section smvrb +.section smvsa +.section smvsb +.section smvta +.section smvtb +.section smvua +.section smvub +.section smvva +.section smvvb +.section smvwa +.section smvwb +.section smvxa +.section smvxb +.section smvya +.section smvyb +.section smvza +.section smvzb +.section smv1a +.section smv1b +.section smv2a +.section smv2b +.section smv3a +.section smv3b +.section smv4a +.section smv4b +.section smv5a +.section smv5b +.section smv6a +.section smv6b +.section smv7a +.section smv7b +.section smv8a +.section smv8b +.section smv9a +.section smv9b +.section smv0a +.section smv0b +.section smwaa +.section smwab +.section smwba +.section smwbb +.section smwca +.section smwcb +.section smwda +.section smwdb +.section smwea +.section smweb +.section smwfa +.section smwfb +.section smwga +.section smwgb +.section smwha +.section smwhb +.section smwia +.section smwib +.section smwja +.section smwjb +.section smwka +.section smwkb +.section smwla +.section smwlb +.section smwma +.section smwmb +.section smwna +.section smwnb +.section smwoa +.section smwob +.section smwpa +.section smwpb +.section smwqa +.section smwqb +.section smwra +.section smwrb +.section smwsa +.section smwsb +.section smwta +.section smwtb +.section smwua +.section smwub +.section smwva +.section smwvb +.section smwwa +.section smwwb +.section smwxa +.section smwxb +.section smwya +.section smwyb +.section smwza +.section smwzb +.section smw1a +.section smw1b +.section smw2a +.section smw2b +.section smw3a +.section smw3b +.section smw4a +.section smw4b +.section smw5a +.section smw5b +.section smw6a +.section smw6b +.section smw7a +.section smw7b +.section smw8a +.section smw8b +.section smw9a +.section smw9b +.section smw0a +.section smw0b +.section smxaa +.section smxab +.section smxba +.section smxbb +.section smxca +.section smxcb +.section smxda +.section smxdb +.section smxea +.section smxeb +.section smxfa +.section smxfb +.section smxga +.section smxgb +.section smxha +.section smxhb +.section smxia +.section smxib +.section smxja +.section smxjb +.section smxka +.section smxkb +.section smxla +.section smxlb +.section smxma +.section smxmb +.section smxna +.section smxnb +.section smxoa +.section smxob +.section smxpa +.section smxpb +.section smxqa +.section smxqb +.section smxra +.section smxrb +.section smxsa +.section smxsb +.section smxta +.section smxtb +.section smxua +.section smxub +.section smxva +.section smxvb +.section smxwa +.section smxwb +.section smxxa +.section smxxb +.section smxya +.section smxyb +.section smxza +.section smxzb +.section smx1a +.section smx1b +.section smx2a +.section smx2b +.section smx3a +.section smx3b +.section smx4a +.section smx4b +.section smx5a +.section smx5b +.section smx6a +.section smx6b +.section smx7a +.section smx7b +.section smx8a +.section smx8b +.section smx9a +.section smx9b +.section smx0a +.section smx0b +.section smyaa +.section smyab +.section smyba +.section smybb +.section smyca +.section smycb +.section smyda +.section smydb +.section smyea +.section smyeb +.section smyfa +.section smyfb +.section smyga +.section smygb +.section smyha +.section smyhb +.section smyia +.section smyib +.section smyja +.section smyjb +.section smyka +.section smykb +.section smyla +.section smylb +.section smyma +.section smymb +.section smyna +.section smynb +.section smyoa +.section smyob +.section smypa +.section smypb +.section smyqa +.section smyqb +.section smyra +.section smyrb +.section smysa +.section smysb +.section smyta +.section smytb +.section smyua +.section smyub +.section smyva +.section smyvb +.section smywa +.section smywb +.section smyxa +.section smyxb +.section smyya +.section smyyb +.section smyza +.section smyzb +.section smy1a +.section smy1b +.section smy2a +.section smy2b +.section smy3a +.section smy3b +.section smy4a +.section smy4b +.section smy5a +.section smy5b +.section smy6a +.section smy6b +.section smy7a +.section smy7b +.section smy8a +.section smy8b +.section smy9a +.section smy9b +.section smy0a +.section smy0b +.section smzaa +.section smzab +.section smzba +.section smzbb +.section smzca +.section smzcb +.section smzda +.section smzdb +.section smzea +.section smzeb +.section smzfa +.section smzfb +.section smzga +.section smzgb +.section smzha +.section smzhb +.section smzia +.section smzib +.section smzja +.section smzjb +.section smzka +.section smzkb +.section smzla +.section smzlb +.section smzma +.section smzmb +.section smzna +.section smznb +.section smzoa +.section smzob +.section smzpa +.section smzpb +.section smzqa +.section smzqb +.section smzra +.section smzrb +.section smzsa +.section smzsb +.section smzta +.section smztb +.section smzua +.section smzub +.section smzva +.section smzvb +.section smzwa +.section smzwb +.section smzxa +.section smzxb +.section smzya +.section smzyb +.section smzza +.section smzzb +.section smz1a +.section smz1b +.section smz2a +.section smz2b +.section smz3a +.section smz3b +.section smz4a +.section smz4b +.section smz5a +.section smz5b +.section smz6a +.section smz6b +.section smz7a +.section smz7b +.section smz8a +.section smz8b +.section smz9a +.section smz9b +.section smz0a +.section smz0b +.section sm1aa +.section sm1ab +.section sm1ba +.section sm1bb +.section sm1ca +.section sm1cb +.section sm1da +.section sm1db +.section sm1ea +.section sm1eb +.section sm1fa +.section sm1fb +.section sm1ga +.section sm1gb +.section sm1ha +.section sm1hb +.section sm1ia +.section sm1ib +.section sm1ja +.section sm1jb +.section sm1ka +.section sm1kb +.section sm1la +.section sm1lb +.section sm1ma +.section sm1mb +.section sm1na +.section sm1nb +.section sm1oa +.section sm1ob +.section sm1pa +.section sm1pb +.section sm1qa +.section sm1qb +.section sm1ra +.section sm1rb +.section sm1sa +.section sm1sb +.section sm1ta +.section sm1tb +.section sm1ua +.section sm1ub +.section sm1va +.section sm1vb +.section sm1wa +.section sm1wb +.section sm1xa +.section sm1xb +.section sm1ya +.section sm1yb +.section sm1za +.section sm1zb +.section sm11a +.section sm11b +.section sm12a +.section sm12b +.section sm13a +.section sm13b +.section sm14a +.section sm14b +.section sm15a +.section sm15b +.section sm16a +.section sm16b +.section sm17a +.section sm17b +.section sm18a +.section sm18b +.section sm19a +.section sm19b +.section sm10a +.section sm10b +.section sm2aa +.section sm2ab +.section sm2ba +.section sm2bb +.section sm2ca +.section sm2cb +.section sm2da +.section sm2db +.section sm2ea +.section sm2eb +.section sm2fa +.section sm2fb +.section sm2ga +.section sm2gb +.section sm2ha +.section sm2hb +.section sm2ia +.section sm2ib +.section sm2ja +.section sm2jb +.section sm2ka +.section sm2kb +.section sm2la +.section sm2lb +.section sm2ma +.section sm2mb +.section sm2na +.section sm2nb +.section sm2oa +.section sm2ob +.section sm2pa +.section sm2pb +.section sm2qa +.section sm2qb +.section sm2ra +.section sm2rb +.section sm2sa +.section sm2sb +.section sm2ta +.section sm2tb +.section sm2ua +.section sm2ub +.section sm2va +.section sm2vb +.section sm2wa +.section sm2wb +.section sm2xa +.section sm2xb +.section sm2ya +.section sm2yb +.section sm2za +.section sm2zb +.section sm21a +.section sm21b +.section sm22a +.section sm22b +.section sm23a +.section sm23b +.section sm24a +.section sm24b +.section sm25a +.section sm25b +.section sm26a +.section sm26b +.section sm27a +.section sm27b +.section sm28a +.section sm28b +.section sm29a +.section sm29b +.section sm20a +.section sm20b +.section sm3aa +.section sm3ab +.section sm3ba +.section sm3bb +.section sm3ca +.section sm3cb +.section sm3da +.section sm3db +.section sm3ea +.section sm3eb +.section sm3fa +.section sm3fb +.section sm3ga +.section sm3gb +.section sm3ha +.section sm3hb +.section sm3ia +.section sm3ib +.section sm3ja +.section sm3jb +.section sm3ka +.section sm3kb +.section sm3la +.section sm3lb +.section sm3ma +.section sm3mb +.section sm3na +.section sm3nb +.section sm3oa +.section sm3ob +.section sm3pa +.section sm3pb +.section sm3qa +.section sm3qb +.section sm3ra +.section sm3rb +.section sm3sa +.section sm3sb +.section sm3ta +.section sm3tb +.section sm3ua +.section sm3ub +.section sm3va +.section sm3vb +.section sm3wa +.section sm3wb +.section sm3xa +.section sm3xb +.section sm3ya +.section sm3yb +.section sm3za +.section sm3zb +.section sm31a +.section sm31b +.section sm32a +.section sm32b +.section sm33a +.section sm33b +.section sm34a +.section sm34b +.section sm35a +.section sm35b +.section sm36a +.section sm36b +.section sm37a +.section sm37b +.section sm38a +.section sm38b +.section sm39a +.section sm39b +.section sm30a +.section sm30b +.section sm4aa +.section sm4ab +.section sm4ba +.section sm4bb +.section sm4ca +.section sm4cb +.section sm4da +.section sm4db +.section sm4ea +.section sm4eb +.section sm4fa +.section sm4fb +.section sm4ga +.section sm4gb +.section sm4ha +.section sm4hb +.section sm4ia +.section sm4ib +.section sm4ja +.section sm4jb +.section sm4ka +.section sm4kb +.section sm4la +.section sm4lb +.section sm4ma +.section sm4mb +.section sm4na +.section sm4nb +.section sm4oa +.section sm4ob +.section sm4pa +.section sm4pb +.section sm4qa +.section sm4qb +.section sm4ra +.section sm4rb +.section sm4sa +.section sm4sb +.section sm4ta +.section sm4tb +.section sm4ua +.section sm4ub +.section sm4va +.section sm4vb +.section sm4wa +.section sm4wb +.section sm4xa +.section sm4xb +.section sm4ya +.section sm4yb +.section sm4za +.section sm4zb +.section sm41a +.section sm41b +.section sm42a +.section sm42b +.section sm43a +.section sm43b +.section sm44a +.section sm44b +.section sm45a +.section sm45b +.section sm46a +.section sm46b +.section sm47a +.section sm47b +.section sm48a +.section sm48b +.section sm49a +.section sm49b +.section sm40a +.section sm40b +.section sm5aa +.section sm5ab +.section sm5ba +.section sm5bb +.section sm5ca +.section sm5cb +.section sm5da +.section sm5db +.section sm5ea +.section sm5eb +.section sm5fa +.section sm5fb +.section sm5ga +.section sm5gb +.section sm5ha +.section sm5hb +.section sm5ia +.section sm5ib +.section sm5ja +.section sm5jb +.section sm5ka +.section sm5kb +.section sm5la +.section sm5lb +.section sm5ma +.section sm5mb +.section sm5na +.section sm5nb +.section sm5oa +.section sm5ob +.section sm5pa +.section sm5pb +.section sm5qa +.section sm5qb +.section sm5ra +.section sm5rb +.section sm5sa +.section sm5sb +.section sm5ta +.section sm5tb +.section sm5ua +.section sm5ub +.section sm5va +.section sm5vb +.section sm5wa +.section sm5wb +.section sm5xa +.section sm5xb +.section sm5ya +.section sm5yb +.section sm5za +.section sm5zb +.section sm51a +.section sm51b +.section sm52a +.section sm52b +.section sm53a +.section sm53b +.section sm54a +.section sm54b +.section sm55a +.section sm55b +.section sm56a +.section sm56b +.section sm57a +.section sm57b +.section sm58a +.section sm58b +.section sm59a +.section sm59b +.section sm50a +.section sm50b +.section sm6aa +.section sm6ab +.section sm6ba +.section sm6bb +.section sm6ca +.section sm6cb +.section sm6da +.section sm6db +.section sm6ea +.section sm6eb +.section sm6fa +.section sm6fb +.section sm6ga +.section sm6gb +.section sm6ha +.section sm6hb +.section sm6ia +.section sm6ib +.section sm6ja +.section sm6jb +.section sm6ka +.section sm6kb +.section sm6la +.section sm6lb +.section sm6ma +.section sm6mb +.section sm6na +.section sm6nb +.section sm6oa +.section sm6ob +.section sm6pa +.section sm6pb +.section sm6qa +.section sm6qb +.section sm6ra +.section sm6rb +.section sm6sa +.section sm6sb +.section sm6ta +.section sm6tb +.section sm6ua +.section sm6ub +.section sm6va +.section sm6vb +.section sm6wa +.section sm6wb +.section sm6xa +.section sm6xb +.section sm6ya +.section sm6yb +.section sm6za +.section sm6zb +.section sm61a +.section sm61b +.section sm62a +.section sm62b +.section sm63a +.section sm63b +.section sm64a +.section sm64b +.section sm65a +.section sm65b +.section sm66a +.section sm66b +.section sm67a +.section sm67b +.section sm68a +.section sm68b +.section sm69a +.section sm69b +.section sm60a +.section sm60b +.section sm7aa +.section sm7ab +.section sm7ba +.section sm7bb +.section sm7ca +.section sm7cb +.section sm7da +.section sm7db +.section sm7ea +.section sm7eb +.section sm7fa +.section sm7fb +.section sm7ga +.section sm7gb +.section sm7ha +.section sm7hb +.section sm7ia +.section sm7ib +.section sm7ja +.section sm7jb +.section sm7ka +.section sm7kb +.section sm7la +.section sm7lb +.section sm7ma +.section sm7mb +.section sm7na +.section sm7nb +.section sm7oa +.section sm7ob +.section sm7pa +.section sm7pb +.section sm7qa +.section sm7qb +.section sm7ra +.section sm7rb +.section sm7sa +.section sm7sb +.section sm7ta +.section sm7tb +.section sm7ua +.section sm7ub +.section sm7va +.section sm7vb +.section sm7wa +.section sm7wb +.section sm7xa +.section sm7xb +.section sm7ya +.section sm7yb +.section sm7za +.section sm7zb +.section sm71a +.section sm71b +.section sm72a +.section sm72b +.section sm73a +.section sm73b +.section sm74a +.section sm74b +.section sm75a +.section sm75b +.section sm76a +.section sm76b +.section sm77a +.section sm77b +.section sm78a +.section sm78b +.section sm79a +.section sm79b +.section sm70a +.section sm70b +.section sm8aa +.section sm8ab +.section sm8ba +.section sm8bb +.section sm8ca +.section sm8cb +.section sm8da +.section sm8db +.section sm8ea +.section sm8eb +.section sm8fa +.section sm8fb +.section sm8ga +.section sm8gb +.section sm8ha +.section sm8hb +.section sm8ia +.section sm8ib +.section sm8ja +.section sm8jb +.section sm8ka +.section sm8kb +.section sm8la +.section sm8lb +.section sm8ma +.section sm8mb +.section sm8na +.section sm8nb +.section sm8oa +.section sm8ob +.section sm8pa +.section sm8pb +.section sm8qa +.section sm8qb +.section sm8ra +.section sm8rb +.section sm8sa +.section sm8sb +.section sm8ta +.section sm8tb +.section sm8ua +.section sm8ub +.section sm8va +.section sm8vb +.section sm8wa +.section sm8wb +.section sm8xa +.section sm8xb +.section sm8ya +.section sm8yb +.section sm8za +.section sm8zb +.section sm81a +.section sm81b +.section sm82a +.section sm82b +.section sm83a +.section sm83b +.section sm84a +.section sm84b +.section sm85a +.section sm85b +.section sm86a +.section sm86b +.section sm87a +.section sm87b +.section sm88a +.section sm88b +.section sm89a +.section sm89b +.section sm80a +.section sm80b +.section sm9aa +.section sm9ab +.section sm9ba +.section sm9bb +.section sm9ca +.section sm9cb +.section sm9da +.section sm9db +.section sm9ea +.section sm9eb +.section sm9fa +.section sm9fb +.section sm9ga +.section sm9gb +.section sm9ha +.section sm9hb +.section sm9ia +.section sm9ib +.section sm9ja +.section sm9jb +.section sm9ka +.section sm9kb +.section sm9la +.section sm9lb +.section sm9ma +.section sm9mb +.section sm9na +.section sm9nb +.section sm9oa +.section sm9ob +.section sm9pa +.section sm9pb +.section sm9qa +.section sm9qb +.section sm9ra +.section sm9rb +.section sm9sa +.section sm9sb +.section sm9ta +.section sm9tb +.section sm9ua +.section sm9ub +.section sm9va +.section sm9vb +.section sm9wa +.section sm9wb +.section sm9xa +.section sm9xb +.section sm9ya +.section sm9yb +.section sm9za +.section sm9zb +.section sm91a +.section sm91b +.section sm92a +.section sm92b +.section sm93a +.section sm93b +.section sm94a +.section sm94b +.section sm95a +.section sm95b +.section sm96a +.section sm96b +.section sm97a +.section sm97b +.section sm98a +.section sm98b +.section sm99a +.section sm99b +.section sm90a +.section sm90b +.section sm0aa +.section sm0ab +.section sm0ba +.section sm0bb +.section sm0ca +.section sm0cb +.section sm0da +.section sm0db +.section sm0ea +.section sm0eb +.section sm0fa +.section sm0fb +.section sm0ga +.section sm0gb +.section sm0ha +.section sm0hb +.section sm0ia +.section sm0ib +.section sm0ja +.section sm0jb +.section sm0ka +.section sm0kb +.section sm0la +.section sm0lb +.section sm0ma +.section sm0mb +.section sm0na +.section sm0nb +.section sm0oa +.section sm0ob +.section sm0pa +.section sm0pb +.section sm0qa +.section sm0qb +.section sm0ra +.section sm0rb +.section sm0sa +.section sm0sb +.section sm0ta +.section sm0tb +.section sm0ua +.section sm0ub +.section sm0va +.section sm0vb +.section sm0wa +.section sm0wb +.section sm0xa +.section sm0xb +.section sm0ya +.section sm0yb +.section sm0za +.section sm0zb +.section sm01a +.section sm01b +.section sm02a +.section sm02b +.section sm03a +.section sm03b +.section sm04a +.section sm04b +.section sm05a +.section sm05b +.section sm06a +.section sm06b +.section sm07a +.section sm07b +.section sm08a +.section sm08b +.section sm09a +.section sm09b +.section sm00a +.section sm00b +.section snaaa +.section snaab +.section snaba +.section snabb +.section snaca +.section snacb +.section snada +.section snadb +.section snaea +.section snaeb +.section snafa +.section snafb +.section snaga +.section snagb +.section snaha +.section snahb +.section snaia +.section snaib +.section snaja +.section snajb +.section snaka +.section snakb +.section snala +.section snalb +.section snama +.section snamb +.section snana +.section snanb +.section snaoa +.section snaob +.section snapa +.section snapb +.section snaqa +.section snaqb +.section snara +.section snarb +.section snasa +.section snasb +.section snata +.section snatb +.section snaua +.section snaub +.section snava +.section snavb +.section snawa +.section snawb +.section snaxa +.section snaxb +.section snaya +.section snayb +.section snaza +.section snazb +.section sna1a +.section sna1b +.section sna2a +.section sna2b +.section sna3a +.section sna3b +.section sna4a +.section sna4b +.section sna5a +.section sna5b +.section sna6a +.section sna6b +.section sna7a +.section sna7b +.section sna8a +.section sna8b +.section sna9a +.section sna9b +.section sna0a +.section sna0b +.section snbaa +.section snbab +.section snbba +.section snbbb +.section snbca +.section snbcb +.section snbda +.section snbdb +.section snbea +.section snbeb +.section snbfa +.section snbfb +.section snbga +.section snbgb +.section snbha +.section snbhb +.section snbia +.section snbib +.section snbja +.section snbjb +.section snbka +.section snbkb +.section snbla +.section snblb +.section snbma +.section snbmb +.section snbna +.section snbnb +.section snboa +.section snbob +.section snbpa +.section snbpb +.section snbqa +.section snbqb +.section snbra +.section snbrb +.section snbsa +.section snbsb +.section snbta +.section snbtb +.section snbua +.section snbub +.section snbva +.section snbvb +.section snbwa +.section snbwb +.section snbxa +.section snbxb +.section snbya +.section snbyb +.section snbza +.section snbzb +.section snb1a +.section snb1b +.section snb2a +.section snb2b +.section snb3a +.section snb3b +.section snb4a +.section snb4b +.section snb5a +.section snb5b +.section snb6a +.section snb6b +.section snb7a +.section snb7b +.section snb8a +.section snb8b +.section snb9a +.section snb9b +.section snb0a +.section snb0b +.section sncaa +.section sncab +.section sncba +.section sncbb +.section sncca +.section snccb +.section sncda +.section sncdb +.section sncea +.section snceb +.section sncfa +.section sncfb +.section sncga +.section sncgb +.section sncha +.section snchb +.section sncia +.section sncib +.section sncja +.section sncjb +.section sncka +.section snckb +.section sncla +.section snclb +.section sncma +.section sncmb +.section sncna +.section sncnb +.section sncoa +.section sncob +.section sncpa +.section sncpb +.section sncqa +.section sncqb +.section sncra +.section sncrb +.section sncsa +.section sncsb +.section sncta +.section snctb +.section sncua +.section sncub +.section sncva +.section sncvb +.section sncwa +.section sncwb +.section sncxa +.section sncxb +.section sncya +.section sncyb +.section sncza +.section snczb +.section snc1a +.section snc1b +.section snc2a +.section snc2b +.section snc3a +.section snc3b +.section snc4a +.section snc4b +.section snc5a +.section snc5b +.section snc6a +.section snc6b +.section snc7a +.section snc7b +.section snc8a +.section snc8b +.section snc9a +.section snc9b +.section snc0a +.section snc0b +.section sndaa +.section sndab +.section sndba +.section sndbb +.section sndca +.section sndcb +.section sndda +.section snddb +.section sndea +.section sndeb +.section sndfa +.section sndfb +.section sndga +.section sndgb +.section sndha +.section sndhb +.section sndia +.section sndib +.section sndja +.section sndjb +.section sndka +.section sndkb +.section sndla +.section sndlb +.section sndma +.section sndmb +.section sndna +.section sndnb +.section sndoa +.section sndob +.section sndpa +.section sndpb +.section sndqa +.section sndqb +.section sndra +.section sndrb +.section sndsa +.section sndsb +.section sndta +.section sndtb +.section sndua +.section sndub +.section sndva +.section sndvb +.section sndwa +.section sndwb +.section sndxa +.section sndxb +.section sndya +.section sndyb +.section sndza +.section sndzb +.section snd1a +.section snd1b +.section snd2a +.section snd2b +.section snd3a +.section snd3b +.section snd4a +.section snd4b +.section snd5a +.section snd5b +.section snd6a +.section snd6b +.section snd7a +.section snd7b +.section snd8a +.section snd8b +.section snd9a +.section snd9b +.section snd0a +.section snd0b +.section sneaa +.section sneab +.section sneba +.section snebb +.section sneca +.section snecb +.section sneda +.section snedb +.section sneea +.section sneeb +.section snefa +.section snefb +.section snega +.section snegb +.section sneha +.section snehb +.section sneia +.section sneib +.section sneja +.section snejb +.section sneka +.section snekb +.section snela +.section snelb +.section snema +.section snemb +.section snena +.section snenb +.section sneoa +.section sneob +.section snepa +.section snepb +.section sneqa +.section sneqb +.section snera +.section snerb +.section snesa +.section snesb +.section sneta +.section snetb +.section sneua +.section sneub +.section sneva +.section snevb +.section snewa +.section snewb +.section snexa +.section snexb +.section sneya +.section sneyb +.section sneza +.section snezb +.section sne1a +.section sne1b +.section sne2a +.section sne2b +.section sne3a +.section sne3b +.section sne4a +.section sne4b +.section sne5a +.section sne5b +.section sne6a +.section sne6b +.section sne7a +.section sne7b +.section sne8a +.section sne8b +.section sne9a +.section sne9b +.section sne0a +.section sne0b +.section snfaa +.section snfab +.section snfba +.section snfbb +.section snfca +.section snfcb +.section snfda +.section snfdb +.section snfea +.section snfeb +.section snffa +.section snffb +.section snfga +.section snfgb +.section snfha +.section snfhb +.section snfia +.section snfib +.section snfja +.section snfjb +.section snfka +.section snfkb +.section snfla +.section snflb +.section snfma +.section snfmb +.section snfna +.section snfnb +.section snfoa +.section snfob +.section snfpa +.section snfpb +.section snfqa +.section snfqb +.section snfra +.section snfrb +.section snfsa +.section snfsb +.section snfta +.section snftb +.section snfua +.section snfub +.section snfva +.section snfvb +.section snfwa +.section snfwb +.section snfxa +.section snfxb +.section snfya +.section snfyb +.section snfza +.section snfzb +.section snf1a +.section snf1b +.section snf2a +.section snf2b +.section snf3a +.section snf3b +.section snf4a +.section snf4b +.section snf5a +.section snf5b +.section snf6a +.section snf6b +.section snf7a +.section snf7b +.section snf8a +.section snf8b +.section snf9a +.section snf9b +.section snf0a +.section snf0b +.section sngaa +.section sngab +.section sngba +.section sngbb +.section sngca +.section sngcb +.section sngda +.section sngdb +.section sngea +.section sngeb +.section sngfa +.section sngfb +.section sngga +.section snggb +.section sngha +.section snghb +.section sngia +.section sngib +.section sngja +.section sngjb +.section sngka +.section sngkb +.section sngla +.section snglb +.section sngma +.section sngmb +.section sngna +.section sngnb +.section sngoa +.section sngob +.section sngpa +.section sngpb +.section sngqa +.section sngqb +.section sngra +.section sngrb +.section sngsa +.section sngsb +.section sngta +.section sngtb +.section sngua +.section sngub +.section sngva +.section sngvb +.section sngwa +.section sngwb +.section sngxa +.section sngxb +.section sngya +.section sngyb +.section sngza +.section sngzb +.section sng1a +.section sng1b +.section sng2a +.section sng2b +.section sng3a +.section sng3b +.section sng4a +.section sng4b +.section sng5a +.section sng5b +.section sng6a +.section sng6b +.section sng7a +.section sng7b +.section sng8a +.section sng8b +.section sng9a +.section sng9b +.section sng0a +.section sng0b +.section snhaa +.section snhab +.section snhba +.section snhbb +.section snhca +.section snhcb +.section snhda +.section snhdb +.section snhea +.section snheb +.section snhfa +.section snhfb +.section snhga +.section snhgb +.section snhha +.section snhhb +.section snhia +.section snhib +.section snhja +.section snhjb +.section snhka +.section snhkb +.section snhla +.section snhlb +.section snhma +.section snhmb +.section snhna +.section snhnb +.section snhoa +.section snhob +.section snhpa +.section snhpb +.section snhqa +.section snhqb +.section snhra +.section snhrb +.section snhsa +.section snhsb +.section snhta +.section snhtb +.section snhua +.section snhub +.section snhva +.section snhvb +.section snhwa +.section snhwb +.section snhxa +.section snhxb +.section snhya +.section snhyb +.section snhza +.section snhzb +.section snh1a +.section snh1b +.section snh2a +.section snh2b +.section snh3a +.section snh3b +.section snh4a +.section snh4b +.section snh5a +.section snh5b +.section snh6a +.section snh6b +.section snh7a +.section snh7b +.section snh8a +.section snh8b +.section snh9a +.section snh9b +.section snh0a +.section snh0b +.section sniaa +.section sniab +.section sniba +.section snibb +.section snica +.section snicb +.section snida +.section snidb +.section sniea +.section snieb +.section snifa +.section snifb +.section sniga +.section snigb +.section sniha +.section snihb +.section sniia +.section sniib +.section snija +.section snijb +.section snika +.section snikb +.section snila +.section snilb +.section snima +.section snimb +.section snina +.section sninb +.section snioa +.section sniob +.section snipa +.section snipb +.section sniqa +.section sniqb +.section snira +.section snirb +.section snisa +.section snisb +.section snita +.section snitb +.section sniua +.section sniub +.section sniva +.section snivb +.section sniwa +.section sniwb +.section snixa +.section snixb +.section sniya +.section sniyb +.section sniza +.section snizb +.section sni1a +.section sni1b +.section sni2a +.section sni2b +.section sni3a +.section sni3b +.section sni4a +.section sni4b +.section sni5a +.section sni5b +.section sni6a +.section sni6b +.section sni7a +.section sni7b +.section sni8a +.section sni8b +.section sni9a +.section sni9b +.section sni0a +.section sni0b +.section snjaa +.section snjab +.section snjba +.section snjbb +.section snjca +.section snjcb +.section snjda +.section snjdb +.section snjea +.section snjeb +.section snjfa +.section snjfb +.section snjga +.section snjgb +.section snjha +.section snjhb +.section snjia +.section snjib +.section snjja +.section snjjb +.section snjka +.section snjkb +.section snjla +.section snjlb +.section snjma +.section snjmb +.section snjna +.section snjnb +.section snjoa +.section snjob +.section snjpa +.section snjpb +.section snjqa +.section snjqb +.section snjra +.section snjrb +.section snjsa +.section snjsb +.section snjta +.section snjtb +.section snjua +.section snjub +.section snjva +.section snjvb +.section snjwa +.section snjwb +.section snjxa +.section snjxb +.section snjya +.section snjyb +.section snjza +.section snjzb +.section snj1a +.section snj1b +.section snj2a +.section snj2b +.section snj3a +.section snj3b +.section snj4a +.section snj4b +.section snj5a +.section snj5b +.section snj6a +.section snj6b +.section snj7a +.section snj7b +.section snj8a +.section snj8b +.section snj9a +.section snj9b +.section snj0a +.section snj0b +.section snkaa +.section snkab +.section snkba +.section snkbb +.section snkca +.section snkcb +.section snkda +.section snkdb +.section snkea +.section snkeb +.section snkfa +.section snkfb +.section snkga +.section snkgb +.section snkha +.section snkhb +.section snkia +.section snkib +.section snkja +.section snkjb +.section snkka +.section snkkb +.section snkla +.section snklb +.section snkma +.section snkmb +.section snkna +.section snknb +.section snkoa +.section snkob +.section snkpa +.section snkpb +.section snkqa +.section snkqb +.section snkra +.section snkrb +.section snksa +.section snksb +.section snkta +.section snktb +.section snkua +.section snkub +.section snkva +.section snkvb +.section snkwa +.section snkwb +.section snkxa +.section snkxb +.section snkya +.section snkyb +.section snkza +.section snkzb +.section snk1a +.section snk1b +.section snk2a +.section snk2b +.section snk3a +.section snk3b +.section snk4a +.section snk4b +.section snk5a +.section snk5b +.section snk6a +.section snk6b +.section snk7a +.section snk7b +.section snk8a +.section snk8b +.section snk9a +.section snk9b +.section snk0a +.section snk0b +.section snlaa +.section snlab +.section snlba +.section snlbb +.section snlca +.section snlcb +.section snlda +.section snldb +.section snlea +.section snleb +.section snlfa +.section snlfb +.section snlga +.section snlgb +.section snlha +.section snlhb +.section snlia +.section snlib +.section snlja +.section snljb +.section snlka +.section snlkb +.section snlla +.section snllb +.section snlma +.section snlmb +.section snlna +.section snlnb +.section snloa +.section snlob +.section snlpa +.section snlpb +.section snlqa +.section snlqb +.section snlra +.section snlrb +.section snlsa +.section snlsb +.section snlta +.section snltb +.section snlua +.section snlub +.section snlva +.section snlvb +.section snlwa +.section snlwb +.section snlxa +.section snlxb +.section snlya +.section snlyb +.section snlza +.section snlzb +.section snl1a +.section snl1b +.section snl2a +.section snl2b +.section snl3a +.section snl3b +.section snl4a +.section snl4b +.section snl5a +.section snl5b +.section snl6a +.section snl6b +.section snl7a +.section snl7b +.section snl8a +.section snl8b +.section snl9a +.section snl9b +.section snl0a +.section snl0b +.section snmaa +.section snmab +.section snmba +.section snmbb +.section snmca +.section snmcb +.section snmda +.section snmdb +.section snmea +.section snmeb +.section snmfa +.section snmfb +.section snmga +.section snmgb +.section snmha +.section snmhb +.section snmia +.section snmib +.section snmja +.section snmjb +.section snmka +.section snmkb +.section snmla +.section snmlb +.section snmma +.section snmmb +.section snmna +.section snmnb +.section snmoa +.section snmob +.section snmpa +.section snmpb +.section snmqa +.section snmqb +.section snmra +.section snmrb +.section snmsa +.section snmsb +.section snmta +.section snmtb +.section snmua +.section snmub +.section snmva +.section snmvb +.section snmwa +.section snmwb +.section snmxa +.section snmxb +.section snmya +.section snmyb +.section snmza +.section snmzb +.section snm1a +.section snm1b +.section snm2a +.section snm2b +.section snm3a +.section snm3b +.section snm4a +.section snm4b +.section snm5a +.section snm5b +.section snm6a +.section snm6b +.section snm7a +.section snm7b +.section snm8a +.section snm8b +.section snm9a +.section snm9b +.section snm0a +.section snm0b +.section snnaa +.section snnab +.section snnba +.section snnbb +.section snnca +.section snncb +.section snnda +.section snndb +.section snnea +.section snneb +.section snnfa +.section snnfb +.section snnga +.section snngb +.section snnha +.section snnhb +.section snnia +.section snnib +.section snnja +.section snnjb +.section snnka +.section snnkb +.section snnla +.section snnlb +.section snnma +.section snnmb +.section snnna +.section snnnb +.section snnoa +.section snnob +.section snnpa +.section snnpb +.section snnqa +.section snnqb +.section snnra +.section snnrb +.section snnsa +.section snnsb +.section snnta +.section snntb +.section snnua +.section snnub +.section snnva +.section snnvb +.section snnwa +.section snnwb +.section snnxa +.section snnxb +.section snnya +.section snnyb +.section snnza +.section snnzb +.section snn1a +.section snn1b +.section snn2a +.section snn2b +.section snn3a +.section snn3b +.section snn4a +.section snn4b +.section snn5a +.section snn5b +.section snn6a +.section snn6b +.section snn7a +.section snn7b +.section snn8a +.section snn8b +.section snn9a +.section snn9b +.section snn0a +.section snn0b +.section snoaa +.section snoab +.section snoba +.section snobb +.section snoca +.section snocb +.section snoda +.section snodb +.section snoea +.section snoeb +.section snofa +.section snofb +.section snoga +.section snogb +.section snoha +.section snohb +.section snoia +.section snoib +.section snoja +.section snojb +.section snoka +.section snokb +.section snola +.section snolb +.section snoma +.section snomb +.section snona +.section snonb +.section snooa +.section snoob +.section snopa +.section snopb +.section snoqa +.section snoqb +.section snora +.section snorb +.section snosa +.section snosb +.section snota +.section snotb +.section snoua +.section snoub +.section snova +.section snovb +.section snowa +.section snowb +.section snoxa +.section snoxb +.section snoya +.section snoyb +.section snoza +.section snozb +.section sno1a +.section sno1b +.section sno2a +.section sno2b +.section sno3a +.section sno3b +.section sno4a +.section sno4b +.section sno5a +.section sno5b +.section sno6a +.section sno6b +.section sno7a +.section sno7b +.section sno8a +.section sno8b +.section sno9a +.section sno9b +.section sno0a +.section sno0b +.section snpaa +.section snpab +.section snpba +.section snpbb +.section snpca +.section snpcb +.section snpda +.section snpdb +.section snpea +.section snpeb +.section snpfa +.section snpfb +.section snpga +.section snpgb +.section snpha +.section snphb +.section snpia +.section snpib +.section snpja +.section snpjb +.section snpka +.section snpkb +.section snpla +.section snplb +.section snpma +.section snpmb +.section snpna +.section snpnb +.section snpoa +.section snpob +.section snppa +.section snppb +.section snpqa +.section snpqb +.section snpra +.section snprb +.section snpsa +.section snpsb +.section snpta +.section snptb +.section snpua +.section snpub +.section snpva +.section snpvb +.section snpwa +.section snpwb +.section snpxa +.section snpxb +.section snpya +.section snpyb +.section snpza +.section snpzb +.section snp1a +.section snp1b +.section snp2a +.section snp2b +.section snp3a +.section snp3b +.section snp4a +.section snp4b +.section snp5a +.section snp5b +.section snp6a +.section snp6b +.section snp7a +.section snp7b +.section snp8a +.section snp8b +.section snp9a +.section snp9b +.section snp0a +.section snp0b +.section snqaa +.section snqab +.section snqba +.section snqbb +.section snqca +.section snqcb +.section snqda +.section snqdb +.section snqea +.section snqeb +.section snqfa +.section snqfb +.section snqga +.section snqgb +.section snqha +.section snqhb +.section snqia +.section snqib +.section snqja +.section snqjb +.section snqka +.section snqkb +.section snqla +.section snqlb +.section snqma +.section snqmb +.section snqna +.section snqnb +.section snqoa +.section snqob +.section snqpa +.section snqpb +.section snqqa +.section snqqb +.section snqra +.section snqrb +.section snqsa +.section snqsb +.section snqta +.section snqtb +.section snqua +.section snqub +.section snqva +.section snqvb +.section snqwa +.section snqwb +.section snqxa +.section snqxb +.section snqya +.section snqyb +.section snqza +.section snqzb +.section snq1a +.section snq1b +.section snq2a +.section snq2b +.section snq3a +.section snq3b +.section snq4a +.section snq4b +.section snq5a +.section snq5b +.section snq6a +.section snq6b +.section snq7a +.section snq7b +.section snq8a +.section snq8b +.section snq9a +.section snq9b +.section snq0a +.section snq0b +.section snraa +.section snrab +.section snrba +.section snrbb +.section snrca +.section snrcb +.section snrda +.section snrdb +.section snrea +.section snreb +.section snrfa +.section snrfb +.section snrga +.section snrgb +.section snrha +.section snrhb +.section snria +.section snrib +.section snrja +.section snrjb +.section snrka +.section snrkb +.section snrla +.section snrlb +.section snrma +.section snrmb +.section snrna +.section snrnb +.section snroa +.section snrob +.section snrpa +.section snrpb +.section snrqa +.section snrqb +.section snrra +.section snrrb +.section snrsa +.section snrsb +.section snrta +.section snrtb +.section snrua +.section snrub +.section snrva +.section snrvb +.section snrwa +.section snrwb +.section snrxa +.section snrxb +.section snrya +.section snryb +.section snrza +.section snrzb +.section snr1a +.section snr1b +.section snr2a +.section snr2b +.section snr3a +.section snr3b +.section snr4a +.section snr4b +.section snr5a +.section snr5b +.section snr6a +.section snr6b +.section snr7a +.section snr7b +.section snr8a +.section snr8b +.section snr9a +.section snr9b +.section snr0a +.section snr0b +.section snsaa +.section snsab +.section snsba +.section snsbb +.section snsca +.section snscb +.section snsda +.section snsdb +.section snsea +.section snseb +.section snsfa +.section snsfb +.section snsga +.section snsgb +.section snsha +.section snshb +.section snsia +.section snsib +.section snsja +.section snsjb +.section snska +.section snskb +.section snsla +.section snslb +.section snsma +.section snsmb +.section snsna +.section snsnb +.section snsoa +.section snsob +.section snspa +.section snspb +.section snsqa +.section snsqb +.section snsra +.section snsrb +.section snssa +.section snssb +.section snsta +.section snstb +.section snsua +.section snsub +.section snsva +.section snsvb +.section snswa +.section snswb +.section snsxa +.section snsxb +.section snsya +.section snsyb +.section snsza +.section snszb +.section sns1a +.section sns1b +.section sns2a +.section sns2b +.section sns3a +.section sns3b +.section sns4a +.section sns4b +.section sns5a +.section sns5b +.section sns6a +.section sns6b +.section sns7a +.section sns7b +.section sns8a +.section sns8b +.section sns9a +.section sns9b +.section sns0a +.section sns0b +.section sntaa +.section sntab +.section sntba +.section sntbb +.section sntca +.section sntcb +.section sntda +.section sntdb +.section sntea +.section snteb +.section sntfa +.section sntfb +.section sntga +.section sntgb +.section sntha +.section snthb +.section sntia +.section sntib +.section sntja +.section sntjb +.section sntka +.section sntkb +.section sntla +.section sntlb +.section sntma +.section sntmb +.section sntna +.section sntnb +.section sntoa +.section sntob +.section sntpa +.section sntpb +.section sntqa +.section sntqb +.section sntra +.section sntrb +.section sntsa +.section sntsb +.section sntta +.section snttb +.section sntua +.section sntub +.section sntva +.section sntvb +.section sntwa +.section sntwb +.section sntxa +.section sntxb +.section sntya +.section sntyb +.section sntza +.section sntzb +.section snt1a +.section snt1b +.section snt2a +.section snt2b +.section snt3a +.section snt3b +.section snt4a +.section snt4b +.section snt5a +.section snt5b +.section snt6a +.section snt6b +.section snt7a +.section snt7b +.section snt8a +.section snt8b +.section snt9a +.section snt9b +.section snt0a +.section snt0b +.section snuaa +.section snuab +.section snuba +.section snubb +.section snuca +.section snucb +.section snuda +.section snudb +.section snuea +.section snueb +.section snufa +.section snufb +.section snuga +.section snugb +.section snuha +.section snuhb +.section snuia +.section snuib +.section snuja +.section snujb +.section snuka +.section snukb +.section snula +.section snulb +.section snuma +.section snumb +.section snuna +.section snunb +.section snuoa +.section snuob +.section snupa +.section snupb +.section snuqa +.section snuqb +.section snura +.section snurb +.section snusa +.section snusb +.section snuta +.section snutb +.section snuua +.section snuub +.section snuva +.section snuvb +.section snuwa +.section snuwb +.section snuxa +.section snuxb +.section snuya +.section snuyb +.section snuza +.section snuzb +.section snu1a +.section snu1b +.section snu2a +.section snu2b +.section snu3a +.section snu3b +.section snu4a +.section snu4b +.section snu5a +.section snu5b +.section snu6a +.section snu6b +.section snu7a +.section snu7b +.section snu8a +.section snu8b +.section snu9a +.section snu9b +.section snu0a +.section snu0b +.section snvaa +.section snvab +.section snvba +.section snvbb +.section snvca +.section snvcb +.section snvda +.section snvdb +.section snvea +.section snveb +.section snvfa +.section snvfb +.section snvga +.section snvgb +.section snvha +.section snvhb +.section snvia +.section snvib +.section snvja +.section snvjb +.section snvka +.section snvkb +.section snvla +.section snvlb +.section snvma +.section snvmb +.section snvna +.section snvnb +.section snvoa +.section snvob +.section snvpa +.section snvpb +.section snvqa +.section snvqb +.section snvra +.section snvrb +.section snvsa +.section snvsb +.section snvta +.section snvtb +.section snvua +.section snvub +.section snvva +.section snvvb +.section snvwa +.section snvwb +.section snvxa +.section snvxb +.section snvya +.section snvyb +.section snvza +.section snvzb +.section snv1a +.section snv1b +.section snv2a +.section snv2b +.section snv3a +.section snv3b +.section snv4a +.section snv4b +.section snv5a +.section snv5b +.section snv6a +.section snv6b +.section snv7a +.section snv7b +.section snv8a +.section snv8b +.section snv9a +.section snv9b +.section snv0a +.section snv0b +.section snwaa +.section snwab +.section snwba +.section snwbb +.section snwca +.section snwcb +.section snwda +.section snwdb +.section snwea +.section snweb +.section snwfa +.section snwfb +.section snwga +.section snwgb +.section snwha +.section snwhb +.section snwia +.section snwib +.section snwja +.section snwjb +.section snwka +.section snwkb +.section snwla +.section snwlb +.section snwma +.section snwmb +.section snwna +.section snwnb +.section snwoa +.section snwob +.section snwpa +.section snwpb +.section snwqa +.section snwqb +.section snwra +.section snwrb +.section snwsa +.section snwsb +.section snwta +.section snwtb +.section snwua +.section snwub +.section snwva +.section snwvb +.section snwwa +.section snwwb +.section snwxa +.section snwxb +.section snwya +.section snwyb +.section snwza +.section snwzb +.section snw1a +.section snw1b +.section snw2a +.section snw2b +.section snw3a +.section snw3b +.section snw4a +.section snw4b +.section snw5a +.section snw5b +.section snw6a +.section snw6b +.section snw7a +.section snw7b +.section snw8a +.section snw8b +.section snw9a +.section snw9b +.section snw0a +.section snw0b +.section snxaa +.section snxab +.section snxba +.section snxbb +.section snxca +.section snxcb +.section snxda +.section snxdb +.section snxea +.section snxeb +.section snxfa +.section snxfb +.section snxga +.section snxgb +.section snxha +.section snxhb +.section snxia +.section snxib +.section snxja +.section snxjb +.section snxka +.section snxkb +.section snxla +.section snxlb +.section snxma +.section snxmb +.section snxna +.section snxnb +.section snxoa +.section snxob +.section snxpa +.section snxpb +.section snxqa +.section snxqb +.section snxra +.section snxrb +.section snxsa +.section snxsb +.section snxta +.section snxtb +.section snxua +.section snxub +.section snxva +.section snxvb +.section snxwa +.section snxwb +.section snxxa +.section snxxb +.section snxya +.section snxyb +.section snxza +.section snxzb +.section snx1a +.section snx1b +.section snx2a +.section snx2b +.section snx3a +.section snx3b +.section snx4a +.section snx4b +.section snx5a +.section snx5b +.section snx6a +.section snx6b +.section snx7a +.section snx7b +.section snx8a +.section snx8b +.section snx9a +.section snx9b +.section snx0a +.section snx0b +.section snyaa +.section snyab +.section snyba +.section snybb +.section snyca +.section snycb +.section snyda +.section snydb +.section snyea +.section snyeb +.section snyfa +.section snyfb +.section snyga +.section snygb +.section snyha +.section snyhb +.section snyia +.section snyib +.section snyja +.section snyjb +.section snyka +.section snykb +.section snyla +.section snylb +.section snyma +.section snymb +.section snyna +.section snynb +.section snyoa +.section snyob +.section snypa +.section snypb +.section snyqa +.section snyqb +.section snyra +.section snyrb +.section snysa +.section snysb +.section snyta +.section snytb +.section snyua +.section snyub +.section snyva +.section snyvb +.section snywa +.section snywb +.section snyxa +.section snyxb +.section snyya +.section snyyb +.section snyza +.section snyzb +.section sny1a +.section sny1b +.section sny2a +.section sny2b +.section sny3a +.section sny3b +.section sny4a +.section sny4b +.section sny5a +.section sny5b +.section sny6a +.section sny6b +.section sny7a +.section sny7b +.section sny8a +.section sny8b +.section sny9a +.section sny9b +.section sny0a +.section sny0b +.section snzaa +.section snzab +.section snzba +.section snzbb +.section snzca +.section snzcb +.section snzda +.section snzdb +.section snzea +.section snzeb +.section snzfa +.section snzfb +.section snzga +.section snzgb +.section snzha +.section snzhb +.section snzia +.section snzib +.section snzja +.section snzjb +.section snzka +.section snzkb +.section snzla +.section snzlb +.section snzma +.section snzmb +.section snzna +.section snznb +.section snzoa +.section snzob +.section snzpa +.section snzpb +.section snzqa +.section snzqb +.section snzra +.section snzrb +.section snzsa +.section snzsb +.section snzta +.section snztb +.section snzua +.section snzub +.section snzva +.section snzvb +.section snzwa +.section snzwb +.section snzxa +.section snzxb +.section snzya +.section snzyb +.section snzza +.section snzzb +.section snz1a +.section snz1b +.section snz2a +.section snz2b +.section snz3a +.section snz3b +.section snz4a +.section snz4b +.section snz5a +.section snz5b +.section snz6a +.section snz6b +.section snz7a +.section snz7b +.section snz8a +.section snz8b +.section snz9a +.section snz9b +.section snz0a +.section snz0b +.section sn1aa +.section sn1ab +.section sn1ba +.section sn1bb +.section sn1ca +.section sn1cb +.section sn1da +.section sn1db +.section sn1ea +.section sn1eb +.section sn1fa +.section sn1fb +.section sn1ga +.section sn1gb +.section sn1ha +.section sn1hb +.section sn1ia +.section sn1ib +.section sn1ja +.section sn1jb +.section sn1ka +.section sn1kb +.section sn1la +.section sn1lb +.section sn1ma +.section sn1mb +.section sn1na +.section sn1nb +.section sn1oa +.section sn1ob +.section sn1pa +.section sn1pb +.section sn1qa +.section sn1qb +.section sn1ra +.section sn1rb +.section sn1sa +.section sn1sb +.section sn1ta +.section sn1tb +.section sn1ua +.section sn1ub +.section sn1va +.section sn1vb +.section sn1wa +.section sn1wb +.section sn1xa +.section sn1xb +.section sn1ya +.section sn1yb +.section sn1za +.section sn1zb +.section sn11a +.section sn11b +.section sn12a +.section sn12b +.section sn13a +.section sn13b +.section sn14a +.section sn14b +.section sn15a +.section sn15b +.section sn16a +.section sn16b +.section sn17a +.section sn17b +.section sn18a +.section sn18b +.section sn19a +.section sn19b +.section sn10a +.section sn10b +.section sn2aa +.section sn2ab +.section sn2ba +.section sn2bb +.section sn2ca +.section sn2cb +.section sn2da +.section sn2db +.section sn2ea +.section sn2eb +.section sn2fa +.section sn2fb +.section sn2ga +.section sn2gb +.section sn2ha +.section sn2hb +.section sn2ia +.section sn2ib +.section sn2ja +.section sn2jb +.section sn2ka +.section sn2kb +.section sn2la +.section sn2lb +.section sn2ma +.section sn2mb +.section sn2na +.section sn2nb +.section sn2oa +.section sn2ob +.section sn2pa +.section sn2pb +.section sn2qa +.section sn2qb +.section sn2ra +.section sn2rb +.section sn2sa +.section sn2sb +.section sn2ta +.section sn2tb +.section sn2ua +.section sn2ub +.section sn2va +.section sn2vb +.section sn2wa +.section sn2wb +.section sn2xa +.section sn2xb +.section sn2ya +.section sn2yb +.section sn2za +.section sn2zb +.section sn21a +.section sn21b +.section sn22a +.section sn22b +.section sn23a +.section sn23b +.section sn24a +.section sn24b +.section sn25a +.section sn25b +.section sn26a +.section sn26b +.section sn27a +.section sn27b +.section sn28a +.section sn28b +.section sn29a +.section sn29b +.section sn20a +.section sn20b +.section sn3aa +.section sn3ab +.section sn3ba +.section sn3bb +.section sn3ca +.section sn3cb +.section sn3da +.section sn3db +.section sn3ea +.section sn3eb +.section sn3fa +.section sn3fb +.section sn3ga +.section sn3gb +.section sn3ha +.section sn3hb +.section sn3ia +.section sn3ib +.section sn3ja +.section sn3jb +.section sn3ka +.section sn3kb +.section sn3la +.section sn3lb +.section sn3ma +.section sn3mb +.section sn3na +.section sn3nb +.section sn3oa +.section sn3ob +.section sn3pa +.section sn3pb +.section sn3qa +.section sn3qb +.section sn3ra +.section sn3rb +.section sn3sa +.section sn3sb +.section sn3ta +.section sn3tb +.section sn3ua +.section sn3ub +.section sn3va +.section sn3vb +.section sn3wa +.section sn3wb +.section sn3xa +.section sn3xb +.section sn3ya +.section sn3yb +.section sn3za +.section sn3zb +.section sn31a +.section sn31b +.section sn32a +.section sn32b +.section sn33a +.section sn33b +.section sn34a +.section sn34b +.section sn35a +.section sn35b +.section sn36a +.section sn36b +.section sn37a +.section sn37b +.section sn38a +.section sn38b +.section sn39a +.section sn39b +.section sn30a +.section sn30b +.section sn4aa +.section sn4ab +.section sn4ba +.section sn4bb +.section sn4ca +.section sn4cb +.section sn4da +.section sn4db +.section sn4ea +.section sn4eb +.section sn4fa +.section sn4fb +.section sn4ga +.section sn4gb +.section sn4ha +.section sn4hb +.section sn4ia +.section sn4ib +.section sn4ja +.section sn4jb +.section sn4ka +.section sn4kb +.section sn4la +.section sn4lb +.section sn4ma +.section sn4mb +.section sn4na +.section sn4nb +.section sn4oa +.section sn4ob +.section sn4pa +.section sn4pb +.section sn4qa +.section sn4qb +.section sn4ra +.section sn4rb +.section sn4sa +.section sn4sb +.section sn4ta +.section sn4tb +.section sn4ua +.section sn4ub +.section sn4va +.section sn4vb +.section sn4wa +.section sn4wb +.section sn4xa +.section sn4xb +.section sn4ya +.section sn4yb +.section sn4za +.section sn4zb +.section sn41a +.section sn41b +.section sn42a +.section sn42b +.section sn43a +.section sn43b +.section sn44a +.section sn44b +.section sn45a +.section sn45b +.section sn46a +.section sn46b +.section sn47a +.section sn47b +.section sn48a +.section sn48b +.section sn49a +.section sn49b +.section sn40a +.section sn40b +.section sn5aa +.section sn5ab +.section sn5ba +.section sn5bb +.section sn5ca +.section sn5cb +.section sn5da +.section sn5db +.section sn5ea +.section sn5eb +.section sn5fa +.section sn5fb +.section sn5ga +.section sn5gb +.section sn5ha +.section sn5hb +.section sn5ia +.section sn5ib +.section sn5ja +.section sn5jb +.section sn5ka +.section sn5kb +.section sn5la +.section sn5lb +.section sn5ma +.section sn5mb +.section sn5na +.section sn5nb +.section sn5oa +.section sn5ob +.section sn5pa +.section sn5pb +.section sn5qa +.section sn5qb +.section sn5ra +.section sn5rb +.section sn5sa +.section sn5sb +.section sn5ta +.section sn5tb +.section sn5ua +.section sn5ub +.section sn5va +.section sn5vb +.section sn5wa +.section sn5wb +.section sn5xa +.section sn5xb +.section sn5ya +.section sn5yb +.section sn5za +.section sn5zb +.section sn51a +.section sn51b +.section sn52a +.section sn52b +.section sn53a +.section sn53b +.section sn54a +.section sn54b +.section sn55a +.section sn55b +.section sn56a +.section sn56b +.section sn57a +.section sn57b +.section sn58a +.section sn58b +.section sn59a +.section sn59b +.section sn50a +.section sn50b +.section sn6aa +.section sn6ab +.section sn6ba +.section sn6bb +.section sn6ca +.section sn6cb +.section sn6da +.section sn6db +.section sn6ea +.section sn6eb +.section sn6fa +.section sn6fb +.section sn6ga +.section sn6gb +.section sn6ha +.section sn6hb +.section sn6ia +.section sn6ib +.section sn6ja +.section sn6jb +.section sn6ka +.section sn6kb +.section sn6la +.section sn6lb +.section sn6ma +.section sn6mb +.section sn6na +.section sn6nb +.section sn6oa +.section sn6ob +.section sn6pa +.section sn6pb +.section sn6qa +.section sn6qb +.section sn6ra +.section sn6rb +.section sn6sa +.section sn6sb +.section sn6ta +.section sn6tb +.section sn6ua +.section sn6ub +.section sn6va +.section sn6vb +.section sn6wa +.section sn6wb +.section sn6xa +.section sn6xb +.section sn6ya +.section sn6yb +.section sn6za +.section sn6zb +.section sn61a +.section sn61b +.section sn62a +.section sn62b +.section sn63a +.section sn63b +.section sn64a +.section sn64b +.section sn65a +.section sn65b +.section sn66a +.section sn66b +.section sn67a +.section sn67b +.section sn68a +.section sn68b +.section sn69a +.section sn69b +.section sn60a +.section sn60b +.section sn7aa +.section sn7ab +.section sn7ba +.section sn7bb +.section sn7ca +.section sn7cb +.section sn7da +.section sn7db +.section sn7ea +.section sn7eb +.section sn7fa +.section sn7fb +.section sn7ga +.section sn7gb +.section sn7ha +.section sn7hb +.section sn7ia +.section sn7ib +.section sn7ja +.section sn7jb +.section sn7ka +.section sn7kb +.section sn7la +.section sn7lb +.section sn7ma +.section sn7mb +.section sn7na +.section sn7nb +.section sn7oa +.section sn7ob +.section sn7pa +.section sn7pb +.section sn7qa +.section sn7qb +.section sn7ra +.section sn7rb +.section sn7sa +.section sn7sb +.section sn7ta +.section sn7tb +.section sn7ua +.section sn7ub +.section sn7va +.section sn7vb +.section sn7wa +.section sn7wb +.section sn7xa +.section sn7xb +.section sn7ya +.section sn7yb +.section sn7za +.section sn7zb +.section sn71a +.section sn71b +.section sn72a +.section sn72b +.section sn73a +.section sn73b +.section sn74a +.section sn74b +.section sn75a +.section sn75b +.section sn76a +.section sn76b +.section sn77a +.section sn77b +.section sn78a +.section sn78b +.section sn79a +.section sn79b +.section sn70a +.section sn70b +.section sn8aa +.section sn8ab +.section sn8ba +.section sn8bb +.section sn8ca +.section sn8cb +.section sn8da +.section sn8db +.section sn8ea +.section sn8eb +.section sn8fa +.section sn8fb +.section sn8ga +.section sn8gb +.section sn8ha +.section sn8hb +.section sn8ia +.section sn8ib +.section sn8ja +.section sn8jb +.section sn8ka +.section sn8kb +.section sn8la +.section sn8lb +.section sn8ma +.section sn8mb +.section sn8na +.section sn8nb +.section sn8oa +.section sn8ob +.section sn8pa +.section sn8pb +.section sn8qa +.section sn8qb +.section sn8ra +.section sn8rb +.section sn8sa +.section sn8sb +.section sn8ta +.section sn8tb +.section sn8ua +.section sn8ub +.section sn8va +.section sn8vb +.section sn8wa +.section sn8wb +.section sn8xa +.section sn8xb +.section sn8ya +.section sn8yb +.section sn8za +.section sn8zb +.section sn81a +.section sn81b +.section sn82a +.section sn82b +.section sn83a +.section sn83b +.section sn84a +.section sn84b +.section sn85a +.section sn85b +.section sn86a +.section sn86b +.section sn87a +.section sn87b +.section sn88a +.section sn88b +.section sn89a +.section sn89b +.section sn80a +.section sn80b +.section sn9aa +.section sn9ab +.section sn9ba +.section sn9bb +.section sn9ca +.section sn9cb +.section sn9da +.section sn9db +.section sn9ea +.section sn9eb +.section sn9fa +.section sn9fb +.section sn9ga +.section sn9gb +.section sn9ha +.section sn9hb +.section sn9ia +.section sn9ib +.section sn9ja +.section sn9jb +.section sn9ka +.section sn9kb +.section sn9la +.section sn9lb +.section sn9ma +.section sn9mb +.section sn9na +.section sn9nb +.section sn9oa +.section sn9ob +.section sn9pa +.section sn9pb +.section sn9qa +.section sn9qb +.section sn9ra +.section sn9rb +.section sn9sa +.section sn9sb +.section sn9ta +.section sn9tb +.section sn9ua +.section sn9ub +.section sn9va +.section sn9vb +.section sn9wa +.section sn9wb +.section sn9xa +.section sn9xb +.section sn9ya +.section sn9yb +.section sn9za +.section sn9zb +.section sn91a +.section sn91b +.section sn92a +.section sn92b +.section sn93a +.section sn93b +.section sn94a +.section sn94b +.section sn95a +.section sn95b +.section sn96a +.section sn96b +.section sn97a +.section sn97b +.section sn98a +.section sn98b +.section sn99a +.section sn99b +.section sn90a +.section sn90b +.section sn0aa +.section sn0ab +.section sn0ba +.section sn0bb +.section sn0ca +.section sn0cb +.section sn0da +.section sn0db +.section sn0ea +.section sn0eb +.section sn0fa +.section sn0fb +.section sn0ga +.section sn0gb +.section sn0ha +.section sn0hb +.section sn0ia +.section sn0ib +.section sn0ja +.section sn0jb +.section sn0ka +.section sn0kb +.section sn0la +.section sn0lb +.section sn0ma +.section sn0mb +.section sn0na +.section sn0nb +.section sn0oa +.section sn0ob +.section sn0pa +.section sn0pb +.section sn0qa +.section sn0qb +.section sn0ra +.section sn0rb +.section sn0sa +.section sn0sb +.section sn0ta +.section sn0tb +.section sn0ua +.section sn0ub +.section sn0va +.section sn0vb +.section sn0wa +.section sn0wb +.section sn0xa +.section sn0xb +.section sn0ya +.section sn0yb +.section sn0za +.section sn0zb +.section sn01a +.section sn01b +.section sn02a +.section sn02b +.section sn03a +.section sn03b +.section sn04a +.section sn04b +.section sn05a +.section sn05b +.section sn06a +.section sn06b +.section sn07a +.section sn07b +.section sn08a +.section sn08b +.section sn09a +.section sn09b +.section sn00a +.section sn00b +.section soaaa +.section soaab +.section soaba +.section soabb +.section soaca +.section soacb +.section soada +.section soadb +.section soaea +.section soaeb +.section soafa +.section soafb +.section soaga +.section soagb +.section soaha +.section soahb +.section soaia +.section soaib +.section soaja +.section soajb +.section soaka +.section soakb +.section soala +.section soalb +.section soama +.section soamb +.section soana +.section soanb +.section soaoa +.section soaob +.section soapa +.section soapb +.section soaqa +.section soaqb +.section soara +.section soarb +.section soasa +.section soasb +.section soata +.section soatb +.section soaua +.section soaub +.section soava +.section soavb +.section soawa +.section soawb +.section soaxa +.section soaxb +.section soaya +.section soayb +.section soaza +.section soazb +.section soa1a +.section soa1b +.section soa2a +.section soa2b +.section soa3a +.section soa3b +.section soa4a +.section soa4b +.section soa5a +.section soa5b +.section soa6a +.section soa6b +.section soa7a +.section soa7b +.section soa8a +.section soa8b +.section soa9a +.section soa9b +.section soa0a +.section soa0b +.section sobaa +.section sobab +.section sobba +.section sobbb +.section sobca +.section sobcb +.section sobda +.section sobdb +.section sobea +.section sobeb +.section sobfa +.section sobfb +.section sobga +.section sobgb +.section sobha +.section sobhb +.section sobia +.section sobib +.section sobja +.section sobjb +.section sobka +.section sobkb +.section sobla +.section soblb +.section sobma +.section sobmb +.section sobna +.section sobnb +.section soboa +.section sobob +.section sobpa +.section sobpb +.section sobqa +.section sobqb +.section sobra +.section sobrb +.section sobsa +.section sobsb +.section sobta +.section sobtb +.section sobua +.section sobub +.section sobva +.section sobvb +.section sobwa +.section sobwb +.section sobxa +.section sobxb +.section sobya +.section sobyb +.section sobza +.section sobzb +.section sob1a +.section sob1b +.section sob2a +.section sob2b +.section sob3a +.section sob3b +.section sob4a +.section sob4b +.section sob5a +.section sob5b +.section sob6a +.section sob6b +.section sob7a +.section sob7b +.section sob8a +.section sob8b +.section sob9a +.section sob9b +.section sob0a +.section sob0b +.section socaa +.section socab +.section socba +.section socbb +.section socca +.section soccb +.section socda +.section socdb +.section socea +.section soceb +.section socfa +.section socfb +.section socga +.section socgb +.section socha +.section sochb +.section socia +.section socib +.section socja +.section socjb +.section socka +.section sockb +.section socla +.section soclb +.section socma +.section socmb +.section socna +.section socnb +.section socoa +.section socob +.section socpa +.section socpb +.section socqa +.section socqb +.section socra +.section socrb +.section socsa +.section socsb +.section socta +.section soctb +.section socua +.section socub +.section socva +.section socvb +.section socwa +.section socwb +.section socxa +.section socxb +.section socya +.section socyb +.section socza +.section soczb +.section soc1a +.section soc1b +.section soc2a +.section soc2b +.section soc3a +.section soc3b +.section soc4a +.section soc4b +.section soc5a +.section soc5b +.section soc6a +.section soc6b +.section soc7a +.section soc7b +.section soc8a +.section soc8b +.section soc9a +.section soc9b +.section soc0a +.section soc0b +.section sodaa +.section sodab +.section sodba +.section sodbb +.section sodca +.section sodcb +.section sodda +.section soddb +.section sodea +.section sodeb +.section sodfa +.section sodfb +.section sodga +.section sodgb +.section sodha +.section sodhb +.section sodia +.section sodib +.section sodja +.section sodjb +.section sodka +.section sodkb +.section sodla +.section sodlb +.section sodma +.section sodmb +.section sodna +.section sodnb +.section sodoa +.section sodob +.section sodpa +.section sodpb +.section sodqa +.section sodqb +.section sodra +.section sodrb +.section sodsa +.section sodsb +.section sodta +.section sodtb +.section sodua +.section sodub +.section sodva +.section sodvb +.section sodwa +.section sodwb +.section sodxa +.section sodxb +.section sodya +.section sodyb +.section sodza +.section sodzb +.section sod1a +.section sod1b +.section sod2a +.section sod2b +.section sod3a +.section sod3b +.section sod4a +.section sod4b +.section sod5a +.section sod5b +.section sod6a +.section sod6b +.section sod7a +.section sod7b +.section sod8a +.section sod8b +.section sod9a +.section sod9b +.section sod0a +.section sod0b +.section soeaa +.section soeab +.section soeba +.section soebb +.section soeca +.section soecb +.section soeda +.section soedb +.section soeea +.section soeeb +.section soefa +.section soefb +.section soega +.section soegb +.section soeha +.section soehb +.section soeia +.section soeib +.section soeja +.section soejb +.section soeka +.section soekb +.section soela +.section soelb +.section soema +.section soemb +.section soena +.section soenb +.section soeoa +.section soeob +.section soepa +.section soepb +.section soeqa +.section soeqb +.section soera +.section soerb +.section soesa +.section soesb +.section soeta +.section soetb +.section soeua +.section soeub +.section soeva +.section soevb +.section soewa +.section soewb +.section soexa +.section soexb +.section soeya +.section soeyb +.section soeza +.section soezb +.section soe1a +.section soe1b +.section soe2a +.section soe2b +.section soe3a +.section soe3b +.section soe4a +.section soe4b +.section soe5a +.section soe5b +.section soe6a +.section soe6b +.section soe7a +.section soe7b +.section soe8a +.section soe8b +.section soe9a +.section soe9b +.section soe0a +.section soe0b +.section sofaa +.section sofab +.section sofba +.section sofbb +.section sofca +.section sofcb +.section sofda +.section sofdb +.section sofea +.section sofeb +.section soffa +.section soffb +.section sofga +.section sofgb +.section sofha +.section sofhb +.section sofia +.section sofib +.section sofja +.section sofjb +.section sofka +.section sofkb +.section sofla +.section soflb +.section sofma +.section sofmb +.section sofna +.section sofnb +.section sofoa +.section sofob +.section sofpa +.section sofpb +.section sofqa +.section sofqb +.section sofra +.section sofrb +.section sofsa +.section sofsb +.section softa +.section softb +.section sofua +.section sofub +.section sofva +.section sofvb +.section sofwa +.section sofwb +.section sofxa +.section sofxb +.section sofya +.section sofyb +.section sofza +.section sofzb +.section sof1a +.section sof1b +.section sof2a +.section sof2b +.section sof3a +.section sof3b +.section sof4a +.section sof4b +.section sof5a +.section sof5b +.section sof6a +.section sof6b +.section sof7a +.section sof7b +.section sof8a +.section sof8b +.section sof9a +.section sof9b +.section sof0a +.section sof0b +.section sogaa +.section sogab +.section sogba +.section sogbb +.section sogca +.section sogcb +.section sogda +.section sogdb +.section sogea +.section sogeb +.section sogfa +.section sogfb +.section sogga +.section soggb +.section sogha +.section soghb +.section sogia +.section sogib +.section sogja +.section sogjb +.section sogka +.section sogkb +.section sogla +.section soglb +.section sogma +.section sogmb +.section sogna +.section sognb +.section sogoa +.section sogob +.section sogpa +.section sogpb +.section sogqa +.section sogqb +.section sogra +.section sogrb +.section sogsa +.section sogsb +.section sogta +.section sogtb +.section sogua +.section sogub +.section sogva +.section sogvb +.section sogwa +.section sogwb +.section sogxa +.section sogxb +.section sogya +.section sogyb +.section sogza +.section sogzb +.section sog1a +.section sog1b +.section sog2a +.section sog2b +.section sog3a +.section sog3b +.section sog4a +.section sog4b +.section sog5a +.section sog5b +.section sog6a +.section sog6b +.section sog7a +.section sog7b +.section sog8a +.section sog8b +.section sog9a +.section sog9b +.section sog0a +.section sog0b +.section sohaa +.section sohab +.section sohba +.section sohbb +.section sohca +.section sohcb +.section sohda +.section sohdb +.section sohea +.section soheb +.section sohfa +.section sohfb +.section sohga +.section sohgb +.section sohha +.section sohhb +.section sohia +.section sohib +.section sohja +.section sohjb +.section sohka +.section sohkb +.section sohla +.section sohlb +.section sohma +.section sohmb +.section sohna +.section sohnb +.section sohoa +.section sohob +.section sohpa +.section sohpb +.section sohqa +.section sohqb +.section sohra +.section sohrb +.section sohsa +.section sohsb +.section sohta +.section sohtb +.section sohua +.section sohub +.section sohva +.section sohvb +.section sohwa +.section sohwb +.section sohxa +.section sohxb +.section sohya +.section sohyb +.section sohza +.section sohzb +.section soh1a +.section soh1b +.section soh2a +.section soh2b +.section soh3a +.section soh3b +.section soh4a +.section soh4b +.section soh5a +.section soh5b +.section soh6a +.section soh6b +.section soh7a +.section soh7b +.section soh8a +.section soh8b +.section soh9a +.section soh9b +.section soh0a +.section soh0b +.section soiaa +.section soiab +.section soiba +.section soibb +.section soica +.section soicb +.section soida +.section soidb +.section soiea +.section soieb +.section soifa +.section soifb +.section soiga +.section soigb +.section soiha +.section soihb +.section soiia +.section soiib +.section soija +.section soijb +.section soika +.section soikb +.section soila +.section soilb +.section soima +.section soimb +.section soina +.section soinb +.section soioa +.section soiob +.section soipa +.section soipb +.section soiqa +.section soiqb +.section soira +.section soirb +.section soisa +.section soisb +.section soita +.section soitb +.section soiua +.section soiub +.section soiva +.section soivb +.section soiwa +.section soiwb +.section soixa +.section soixb +.section soiya +.section soiyb +.section soiza +.section soizb +.section soi1a +.section soi1b +.section soi2a +.section soi2b +.section soi3a +.section soi3b +.section soi4a +.section soi4b +.section soi5a +.section soi5b +.section soi6a +.section soi6b +.section soi7a +.section soi7b +.section soi8a +.section soi8b +.section soi9a +.section soi9b +.section soi0a +.section soi0b +.section sojaa +.section sojab +.section sojba +.section sojbb +.section sojca +.section sojcb +.section sojda +.section sojdb +.section sojea +.section sojeb +.section sojfa +.section sojfb +.section sojga +.section sojgb +.section sojha +.section sojhb +.section sojia +.section sojib +.section sojja +.section sojjb +.section sojka +.section sojkb +.section sojla +.section sojlb +.section sojma +.section sojmb +.section sojna +.section sojnb +.section sojoa +.section sojob +.section sojpa +.section sojpb +.section sojqa +.section sojqb +.section sojra +.section sojrb +.section sojsa +.section sojsb +.section sojta +.section sojtb +.section sojua +.section sojub +.section sojva +.section sojvb +.section sojwa +.section sojwb +.section sojxa +.section sojxb +.section sojya +.section sojyb +.section sojza +.section sojzb +.section soj1a +.section soj1b +.section soj2a +.section soj2b +.section soj3a +.section soj3b +.section soj4a +.section soj4b +.section soj5a +.section soj5b +.section soj6a +.section soj6b +.section soj7a +.section soj7b +.section soj8a +.section soj8b +.section soj9a +.section soj9b +.section soj0a +.section soj0b +.section sokaa +.section sokab +.section sokba +.section sokbb +.section sokca +.section sokcb +.section sokda +.section sokdb +.section sokea +.section sokeb +.section sokfa +.section sokfb +.section sokga +.section sokgb +.section sokha +.section sokhb +.section sokia +.section sokib +.section sokja +.section sokjb +.section sokka +.section sokkb +.section sokla +.section soklb +.section sokma +.section sokmb +.section sokna +.section soknb +.section sokoa +.section sokob +.section sokpa +.section sokpb +.section sokqa +.section sokqb +.section sokra +.section sokrb +.section soksa +.section soksb +.section sokta +.section soktb +.section sokua +.section sokub +.section sokva +.section sokvb +.section sokwa +.section sokwb +.section sokxa +.section sokxb +.section sokya +.section sokyb +.section sokza +.section sokzb +.section sok1a +.section sok1b +.section sok2a +.section sok2b +.section sok3a +.section sok3b +.section sok4a +.section sok4b +.section sok5a +.section sok5b +.section sok6a +.section sok6b +.section sok7a +.section sok7b +.section sok8a +.section sok8b +.section sok9a +.section sok9b +.section sok0a +.section sok0b +.section solaa +.section solab +.section solba +.section solbb +.section solca +.section solcb +.section solda +.section soldb +.section solea +.section soleb +.section solfa +.section solfb +.section solga +.section solgb +.section solha +.section solhb +.section solia +.section solib +.section solja +.section soljb +.section solka +.section solkb +.section solla +.section sollb +.section solma +.section solmb +.section solna +.section solnb +.section soloa +.section solob +.section solpa +.section solpb +.section solqa +.section solqb +.section solra +.section solrb +.section solsa +.section solsb +.section solta +.section soltb +.section solua +.section solub +.section solva +.section solvb +.section solwa +.section solwb +.section solxa +.section solxb +.section solya +.section solyb +.section solza +.section solzb +.section sol1a +.section sol1b +.section sol2a +.section sol2b +.section sol3a +.section sol3b +.section sol4a +.section sol4b +.section sol5a +.section sol5b +.section sol6a +.section sol6b +.section sol7a +.section sol7b +.section sol8a +.section sol8b +.section sol9a +.section sol9b +.section sol0a +.section sol0b +.section somaa +.section somab +.section somba +.section sombb +.section somca +.section somcb +.section somda +.section somdb +.section somea +.section someb +.section somfa +.section somfb +.section somga +.section somgb +.section somha +.section somhb +.section somia +.section somib +.section somja +.section somjb +.section somka +.section somkb +.section somla +.section somlb +.section somma +.section sommb +.section somna +.section somnb +.section somoa +.section somob +.section sompa +.section sompb +.section somqa +.section somqb +.section somra +.section somrb +.section somsa +.section somsb +.section somta +.section somtb +.section somua +.section somub +.section somva +.section somvb +.section somwa +.section somwb +.section somxa +.section somxb +.section somya +.section somyb +.section somza +.section somzb +.section som1a +.section som1b +.section som2a +.section som2b +.section som3a +.section som3b +.section som4a +.section som4b +.section som5a +.section som5b +.section som6a +.section som6b +.section som7a +.section som7b +.section som8a +.section som8b +.section som9a +.section som9b +.section som0a +.section som0b +.section sonaa +.section sonab +.section sonba +.section sonbb +.section sonca +.section soncb +.section sonda +.section sondb +.section sonea +.section soneb +.section sonfa +.section sonfb +.section songa +.section songb +.section sonha +.section sonhb +.section sonia +.section sonib +.section sonja +.section sonjb +.section sonka +.section sonkb +.section sonla +.section sonlb +.section sonma +.section sonmb +.section sonna +.section sonnb +.section sonoa +.section sonob +.section sonpa +.section sonpb +.section sonqa +.section sonqb +.section sonra +.section sonrb +.section sonsa +.section sonsb +.section sonta +.section sontb +.section sonua +.section sonub +.section sonva +.section sonvb +.section sonwa +.section sonwb +.section sonxa +.section sonxb +.section sonya +.section sonyb +.section sonza +.section sonzb +.section son1a +.section son1b +.section son2a +.section son2b +.section son3a +.section son3b +.section son4a +.section son4b +.section son5a +.section son5b +.section son6a +.section son6b +.section son7a +.section son7b +.section son8a +.section son8b +.section son9a +.section son9b +.section son0a +.section son0b +.section sooaa +.section sooab +.section sooba +.section soobb +.section sooca +.section soocb +.section sooda +.section soodb +.section sooea +.section sooeb +.section soofa +.section soofb +.section sooga +.section soogb +.section sooha +.section soohb +.section sooia +.section sooib +.section sooja +.section soojb +.section sooka +.section sookb +.section soola +.section soolb +.section sooma +.section soomb +.section soona +.section soonb +.section soooa +.section sooob +.section soopa +.section soopb +.section sooqa +.section sooqb +.section soora +.section soorb +.section soosa +.section soosb +.section soota +.section sootb +.section sooua +.section sooub +.section soova +.section soovb +.section soowa +.section soowb +.section sooxa +.section sooxb +.section sooya +.section sooyb +.section sooza +.section soozb +.section soo1a +.section soo1b +.section soo2a +.section soo2b +.section soo3a +.section soo3b +.section soo4a +.section soo4b +.section soo5a +.section soo5b +.section soo6a +.section soo6b +.section soo7a +.section soo7b +.section soo8a +.section soo8b +.section soo9a +.section soo9b +.section soo0a +.section soo0b +.section sopaa +.section sopab +.section sopba +.section sopbb +.section sopca +.section sopcb +.section sopda +.section sopdb +.section sopea +.section sopeb +.section sopfa +.section sopfb +.section sopga +.section sopgb +.section sopha +.section sophb +.section sopia +.section sopib +.section sopja +.section sopjb +.section sopka +.section sopkb +.section sopla +.section soplb +.section sopma +.section sopmb +.section sopna +.section sopnb +.section sopoa +.section sopob +.section soppa +.section soppb +.section sopqa +.section sopqb +.section sopra +.section soprb +.section sopsa +.section sopsb +.section sopta +.section soptb +.section sopua +.section sopub +.section sopva +.section sopvb +.section sopwa +.section sopwb +.section sopxa +.section sopxb +.section sopya +.section sopyb +.section sopza +.section sopzb +.section sop1a +.section sop1b +.section sop2a +.section sop2b +.section sop3a +.section sop3b +.section sop4a +.section sop4b +.section sop5a +.section sop5b +.section sop6a +.section sop6b +.section sop7a +.section sop7b +.section sop8a +.section sop8b +.section sop9a +.section sop9b +.section sop0a +.section sop0b +.section soqaa +.section soqab +.section soqba +.section soqbb +.section soqca +.section soqcb +.section soqda +.section soqdb +.section soqea +.section soqeb +.section soqfa +.section soqfb +.section soqga +.section soqgb +.section soqha +.section soqhb +.section soqia +.section soqib +.section soqja +.section soqjb +.section soqka +.section soqkb +.section soqla +.section soqlb +.section soqma +.section soqmb +.section soqna +.section soqnb +.section soqoa +.section soqob +.section soqpa +.section soqpb +.section soqqa +.section soqqb +.section soqra +.section soqrb +.section soqsa +.section soqsb +.section soqta +.section soqtb +.section soqua +.section soqub +.section soqva +.section soqvb +.section soqwa +.section soqwb +.section soqxa +.section soqxb +.section soqya +.section soqyb +.section soqza +.section soqzb +.section soq1a +.section soq1b +.section soq2a +.section soq2b +.section soq3a +.section soq3b +.section soq4a +.section soq4b +.section soq5a +.section soq5b +.section soq6a +.section soq6b +.section soq7a +.section soq7b +.section soq8a +.section soq8b +.section soq9a +.section soq9b +.section soq0a +.section soq0b +.section soraa +.section sorab +.section sorba +.section sorbb +.section sorca +.section sorcb +.section sorda +.section sordb +.section sorea +.section soreb +.section sorfa +.section sorfb +.section sorga +.section sorgb +.section sorha +.section sorhb +.section soria +.section sorib +.section sorja +.section sorjb +.section sorka +.section sorkb +.section sorla +.section sorlb +.section sorma +.section sormb +.section sorna +.section sornb +.section soroa +.section sorob +.section sorpa +.section sorpb +.section sorqa +.section sorqb +.section sorra +.section sorrb +.section sorsa +.section sorsb +.section sorta +.section sortb +.section sorua +.section sorub +.section sorva +.section sorvb +.section sorwa +.section sorwb +.section sorxa +.section sorxb +.section sorya +.section soryb +.section sorza +.section sorzb +.section sor1a +.section sor1b +.section sor2a +.section sor2b +.section sor3a +.section sor3b +.section sor4a +.section sor4b +.section sor5a +.section sor5b +.section sor6a +.section sor6b +.section sor7a +.section sor7b +.section sor8a +.section sor8b +.section sor9a +.section sor9b +.section sor0a +.section sor0b +.section sosaa +.section sosab +.section sosba +.section sosbb +.section sosca +.section soscb +.section sosda +.section sosdb +.section sosea +.section soseb +.section sosfa +.section sosfb +.section sosga +.section sosgb +.section sosha +.section soshb +.section sosia +.section sosib +.section sosja +.section sosjb +.section soska +.section soskb +.section sosla +.section soslb +.section sosma +.section sosmb +.section sosna +.section sosnb +.section sosoa +.section sosob +.section sospa +.section sospb +.section sosqa +.section sosqb +.section sosra +.section sosrb +.section sossa +.section sossb +.section sosta +.section sostb +.section sosua +.section sosub +.section sosva +.section sosvb +.section soswa +.section soswb +.section sosxa +.section sosxb +.section sosya +.section sosyb +.section sosza +.section soszb +.section sos1a +.section sos1b +.section sos2a +.section sos2b +.section sos3a +.section sos3b +.section sos4a +.section sos4b +.section sos5a +.section sos5b +.section sos6a +.section sos6b +.section sos7a +.section sos7b +.section sos8a +.section sos8b +.section sos9a +.section sos9b +.section sos0a +.section sos0b +.section sotaa +.section sotab +.section sotba +.section sotbb +.section sotca +.section sotcb +.section sotda +.section sotdb +.section sotea +.section soteb +.section sotfa +.section sotfb +.section sotga +.section sotgb +.section sotha +.section sothb +.section sotia +.section sotib +.section sotja +.section sotjb +.section sotka +.section sotkb +.section sotla +.section sotlb +.section sotma +.section sotmb +.section sotna +.section sotnb +.section sotoa +.section sotob +.section sotpa +.section sotpb +.section sotqa +.section sotqb +.section sotra +.section sotrb +.section sotsa +.section sotsb +.section sotta +.section sottb +.section sotua +.section sotub +.section sotva +.section sotvb +.section sotwa +.section sotwb +.section sotxa +.section sotxb +.section sotya +.section sotyb +.section sotza +.section sotzb +.section sot1a +.section sot1b +.section sot2a +.section sot2b +.section sot3a +.section sot3b +.section sot4a +.section sot4b +.section sot5a +.section sot5b +.section sot6a +.section sot6b +.section sot7a +.section sot7b +.section sot8a +.section sot8b +.section sot9a +.section sot9b +.section sot0a +.section sot0b +.section souaa +.section souab +.section souba +.section soubb +.section souca +.section soucb +.section souda +.section soudb +.section souea +.section soueb +.section soufa +.section soufb +.section souga +.section sougb +.section souha +.section souhb +.section souia +.section souib +.section souja +.section soujb +.section souka +.section soukb +.section soula +.section soulb +.section souma +.section soumb +.section souna +.section sounb +.section souoa +.section souob +.section soupa +.section soupb +.section souqa +.section souqb +.section soura +.section sourb +.section sousa +.section sousb +.section souta +.section soutb +.section souua +.section souub +.section souva +.section souvb +.section souwa +.section souwb +.section souxa +.section souxb +.section souya +.section souyb +.section souza +.section souzb +.section sou1a +.section sou1b +.section sou2a +.section sou2b +.section sou3a +.section sou3b +.section sou4a +.section sou4b +.section sou5a +.section sou5b +.section sou6a +.section sou6b +.section sou7a +.section sou7b +.section sou8a +.section sou8b +.section sou9a +.section sou9b +.section sou0a +.section sou0b +.section sovaa +.section sovab +.section sovba +.section sovbb +.section sovca +.section sovcb +.section sovda +.section sovdb +.section sovea +.section soveb +.section sovfa +.section sovfb +.section sovga +.section sovgb +.section sovha +.section sovhb +.section sovia +.section sovib +.section sovja +.section sovjb +.section sovka +.section sovkb +.section sovla +.section sovlb +.section sovma +.section sovmb +.section sovna +.section sovnb +.section sovoa +.section sovob +.section sovpa +.section sovpb +.section sovqa +.section sovqb +.section sovra +.section sovrb +.section sovsa +.section sovsb +.section sovta +.section sovtb +.section sovua +.section sovub +.section sovva +.section sovvb +.section sovwa +.section sovwb +.section sovxa +.section sovxb +.section sovya +.section sovyb +.section sovza +.section sovzb +.section sov1a +.section sov1b +.section sov2a +.section sov2b +.section sov3a +.section sov3b +.section sov4a +.section sov4b +.section sov5a +.section sov5b +.section sov6a +.section sov6b +.section sov7a +.section sov7b +.section sov8a +.section sov8b +.section sov9a +.section sov9b +.section sov0a +.section sov0b +.section sowaa +.section sowab +.section sowba +.section sowbb +.section sowca +.section sowcb +.section sowda +.section sowdb +.section sowea +.section soweb +.section sowfa +.section sowfb +.section sowga +.section sowgb +.section sowha +.section sowhb +.section sowia +.section sowib +.section sowja +.section sowjb +.section sowka +.section sowkb +.section sowla +.section sowlb +.section sowma +.section sowmb +.section sowna +.section sownb +.section sowoa +.section sowob +.section sowpa +.section sowpb +.section sowqa +.section sowqb +.section sowra +.section sowrb +.section sowsa +.section sowsb +.section sowta +.section sowtb +.section sowua +.section sowub +.section sowva +.section sowvb +.section sowwa +.section sowwb +.section sowxa +.section sowxb +.section sowya +.section sowyb +.section sowza +.section sowzb +.section sow1a +.section sow1b +.section sow2a +.section sow2b +.section sow3a +.section sow3b +.section sow4a +.section sow4b +.section sow5a +.section sow5b +.section sow6a +.section sow6b +.section sow7a +.section sow7b +.section sow8a +.section sow8b +.section sow9a +.section sow9b +.section sow0a +.section sow0b +.section soxaa +.section soxab +.section soxba +.section soxbb +.section soxca +.section soxcb +.section soxda +.section soxdb +.section soxea +.section soxeb +.section soxfa +.section soxfb +.section soxga +.section soxgb +.section soxha +.section soxhb +.section soxia +.section soxib +.section soxja +.section soxjb +.section soxka +.section soxkb +.section soxla +.section soxlb +.section soxma +.section soxmb +.section soxna +.section soxnb +.section soxoa +.section soxob +.section soxpa +.section soxpb +.section soxqa +.section soxqb +.section soxra +.section soxrb +.section soxsa +.section soxsb +.section soxta +.section soxtb +.section soxua +.section soxub +.section soxva +.section soxvb +.section soxwa +.section soxwb +.section soxxa +.section soxxb +.section soxya +.section soxyb +.section soxza +.section soxzb +.section sox1a +.section sox1b +.section sox2a +.section sox2b +.section sox3a +.section sox3b +.section sox4a +.section sox4b +.section sox5a +.section sox5b +.section sox6a +.section sox6b +.section sox7a +.section sox7b +.section sox8a +.section sox8b +.section sox9a +.section sox9b +.section sox0a +.section sox0b +.section soyaa +.section soyab +.section soyba +.section soybb +.section soyca +.section soycb +.section soyda +.section soydb +.section soyea +.section soyeb +.section soyfa +.section soyfb +.section soyga +.section soygb +.section soyha +.section soyhb +.section soyia +.section soyib +.section soyja +.section soyjb +.section soyka +.section soykb +.section soyla +.section soylb +.section soyma +.section soymb +.section soyna +.section soynb +.section soyoa +.section soyob +.section soypa +.section soypb +.section soyqa +.section soyqb +.section soyra +.section soyrb +.section soysa +.section soysb +.section soyta +.section soytb +.section soyua +.section soyub +.section soyva +.section soyvb +.section soywa +.section soywb +.section soyxa +.section soyxb +.section soyya +.section soyyb +.section soyza +.section soyzb +.section soy1a +.section soy1b +.section soy2a +.section soy2b +.section soy3a +.section soy3b +.section soy4a +.section soy4b +.section soy5a +.section soy5b +.section soy6a +.section soy6b +.section soy7a +.section soy7b +.section soy8a +.section soy8b +.section soy9a +.section soy9b +.section soy0a +.section soy0b +.section sozaa +.section sozab +.section sozba +.section sozbb +.section sozca +.section sozcb +.section sozda +.section sozdb +.section sozea +.section sozeb +.section sozfa +.section sozfb +.section sozga +.section sozgb +.section sozha +.section sozhb +.section sozia +.section sozib +.section sozja +.section sozjb +.section sozka +.section sozkb +.section sozla +.section sozlb +.section sozma +.section sozmb +.section sozna +.section soznb +.section sozoa +.section sozob +.section sozpa +.section sozpb +.section sozqa +.section sozqb +.section sozra +.section sozrb +.section sozsa +.section sozsb +.section sozta +.section soztb +.section sozua +.section sozub +.section sozva +.section sozvb +.section sozwa +.section sozwb +.section sozxa +.section sozxb +.section sozya +.section sozyb +.section sozza +.section sozzb +.section soz1a +.section soz1b +.section soz2a +.section soz2b +.section soz3a +.section soz3b +.section soz4a +.section soz4b +.section soz5a +.section soz5b +.section soz6a +.section soz6b +.section soz7a +.section soz7b +.section soz8a +.section soz8b +.section soz9a +.section soz9b +.section soz0a +.section soz0b +.section so1aa +.section so1ab +.section so1ba +.section so1bb +.section so1ca +.section so1cb +.section so1da +.section so1db +.section so1ea +.section so1eb +.section so1fa +.section so1fb +.section so1ga +.section so1gb +.section so1ha +.section so1hb +.section so1ia +.section so1ib +.section so1ja +.section so1jb +.section so1ka +.section so1kb +.section so1la +.section so1lb +.section so1ma +.section so1mb +.section so1na +.section so1nb +.section so1oa +.section so1ob +.section so1pa +.section so1pb +.section so1qa +.section so1qb +.section so1ra +.section so1rb +.section so1sa +.section so1sb +.section so1ta +.section so1tb +.section so1ua +.section so1ub +.section so1va +.section so1vb +.section so1wa +.section so1wb +.section so1xa +.section so1xb +.section so1ya +.section so1yb +.section so1za +.section so1zb +.section so11a +.section so11b +.section so12a +.section so12b +.section so13a +.section so13b +.section so14a +.section so14b +.section so15a +.section so15b +.section so16a +.section so16b +.section so17a +.section so17b +.section so18a +.section so18b +.section so19a +.section so19b +.section so10a +.section so10b +.section so2aa +.section so2ab +.section so2ba +.section so2bb +.section so2ca +.section so2cb +.section so2da +.section so2db +.section so2ea +.section so2eb +.section so2fa +.section so2fb +.section so2ga +.section so2gb +.section so2ha +.section so2hb +.section so2ia +.section so2ib +.section so2ja +.section so2jb +.section so2ka +.section so2kb +.section so2la +.section so2lb +.section so2ma +.section so2mb +.section so2na +.section so2nb +.section so2oa +.section so2ob +.section so2pa +.section so2pb +.section so2qa +.section so2qb +.section so2ra +.section so2rb +.section so2sa +.section so2sb +.section so2ta +.section so2tb +.section so2ua +.section so2ub +.section so2va +.section so2vb +.section so2wa +.section so2wb +.section so2xa +.section so2xb +.section so2ya +.section so2yb +.section so2za +.section so2zb +.section so21a +.section so21b +.section so22a +.section so22b +.section so23a +.section so23b +.section so24a +.section so24b +.section so25a +.section so25b +.section so26a +.section so26b +.section so27a +.section so27b +.section so28a +.section so28b +.section so29a +.section so29b +.section so20a +.section so20b +.section so3aa +.section so3ab +.section so3ba +.section so3bb +.section so3ca +.section so3cb +.section so3da +.section so3db +.section so3ea +.section so3eb +.section so3fa +.section so3fb +.section so3ga +.section so3gb +.section so3ha +.section so3hb +.section so3ia +.section so3ib +.section so3ja +.section so3jb +.section so3ka +.section so3kb +.section so3la +.section so3lb +.section so3ma +.section so3mb +.section so3na +.section so3nb +.section so3oa +.section so3ob +.section so3pa +.section so3pb +.section so3qa +.section so3qb +.section so3ra +.section so3rb +.section so3sa +.section so3sb +.section so3ta +.section so3tb +.section so3ua +.section so3ub +.section so3va +.section so3vb +.section so3wa +.section so3wb +.section so3xa +.section so3xb +.section so3ya +.section so3yb +.section so3za +.section so3zb +.section so31a +.section so31b +.section so32a +.section so32b +.section so33a +.section so33b +.section so34a +.section so34b +.section so35a +.section so35b +.section so36a +.section so36b +.section so37a +.section so37b +.section so38a +.section so38b +.section so39a +.section so39b +.section so30a +.section so30b +.section so4aa +.section so4ab +.section so4ba +.section so4bb +.section so4ca +.section so4cb +.section so4da +.section so4db +.section so4ea +.section so4eb +.section so4fa +.section so4fb +.section so4ga +.section so4gb +.section so4ha +.section so4hb +.section so4ia +.section so4ib +.section so4ja +.section so4jb +.section so4ka +.section so4kb +.section so4la +.section so4lb +.section so4ma +.section so4mb +.section so4na +.section so4nb +.section so4oa +.section so4ob +.section so4pa +.section so4pb +.section so4qa +.section so4qb +.section so4ra +.section so4rb +.section so4sa +.section so4sb +.section so4ta +.section so4tb +.section so4ua +.section so4ub +.section so4va +.section so4vb +.section so4wa +.section so4wb +.section so4xa +.section so4xb +.section so4ya +.section so4yb +.section so4za +.section so4zb +.section so41a +.section so41b +.section so42a +.section so42b +.section so43a +.section so43b +.section so44a +.section so44b +.section so45a +.section so45b +.section so46a +.section so46b +.section so47a +.section so47b +.section so48a +.section so48b +.section so49a +.section so49b +.section so40a +.section so40b +.section so5aa +.section so5ab +.section so5ba +.section so5bb +.section so5ca +.section so5cb +.section so5da +.section so5db +.section so5ea +.section so5eb +.section so5fa +.section so5fb +.section so5ga +.section so5gb +.section so5ha +.section so5hb +.section so5ia +.section so5ib +.section so5ja +.section so5jb +.section so5ka +.section so5kb +.section so5la +.section so5lb +.section so5ma +.section so5mb +.section so5na +.section so5nb +.section so5oa +.section so5ob +.section so5pa +.section so5pb +.section so5qa +.section so5qb +.section so5ra +.section so5rb +.section so5sa +.section so5sb +.section so5ta +.section so5tb +.section so5ua +.section so5ub +.section so5va +.section so5vb +.section so5wa +.section so5wb +.section so5xa +.section so5xb +.section so5ya +.section so5yb +.section so5za +.section so5zb +.section so51a +.section so51b +.section so52a +.section so52b +.section so53a +.section so53b +.section so54a +.section so54b +.section so55a +.section so55b +.section so56a +.section so56b +.section so57a +.section so57b +.section so58a +.section so58b +.section so59a +.section so59b +.section so50a +.section so50b +.section so6aa +.section so6ab +.section so6ba +.section so6bb +.section so6ca +.section so6cb +.section so6da +.section so6db +.section so6ea +.section so6eb +.section so6fa +.section so6fb +.section so6ga +.section so6gb +.section so6ha +.section so6hb +.section so6ia +.section so6ib +.section so6ja +.section so6jb +.section so6ka +.section so6kb +.section so6la +.section so6lb +.section so6ma +.section so6mb +.section so6na +.section so6nb +.section so6oa +.section so6ob +.section so6pa +.section so6pb +.section so6qa +.section so6qb +.section so6ra +.section so6rb +.section so6sa +.section so6sb +.section so6ta +.section so6tb +.section so6ua +.section so6ub +.section so6va +.section so6vb +.section so6wa +.section so6wb +.section so6xa +.section so6xb +.section so6ya +.section so6yb +.section so6za +.section so6zb +.section so61a +.section so61b +.section so62a +.section so62b +.section so63a +.section so63b +.section so64a +.section so64b +.section so65a +.section so65b +.section so66a +.section so66b +.section so67a +.section so67b +.section so68a +.section so68b +.section so69a +.section so69b +.section so60a +.section so60b +.section so7aa +.section so7ab +.section so7ba +.section so7bb +.section so7ca +.section so7cb +.section so7da +.section so7db +.section so7ea +.section so7eb +.section so7fa +.section so7fb +.section so7ga +.section so7gb +.section so7ha +.section so7hb +.section so7ia +.section so7ib +.section so7ja +.section so7jb +.section so7ka +.section so7kb +.section so7la +.section so7lb +.section so7ma +.section so7mb +.section so7na +.section so7nb +.section so7oa +.section so7ob +.section so7pa +.section so7pb +.section so7qa +.section so7qb +.section so7ra +.section so7rb +.section so7sa +.section so7sb +.section so7ta +.section so7tb +.section so7ua +.section so7ub +.section so7va +.section so7vb +.section so7wa +.section so7wb +.section so7xa +.section so7xb +.section so7ya +.section so7yb +.section so7za +.section so7zb +.section so71a +.section so71b +.section so72a +.section so72b +.section so73a +.section so73b +.section so74a +.section so74b +.section so75a +.section so75b +.section so76a +.section so76b +.section so77a +.section so77b +.section so78a +.section so78b +.section so79a +.section so79b +.section so70a +.section so70b +.section so8aa +.section so8ab +.section so8ba +.section so8bb +.section so8ca +.section so8cb +.section so8da +.section so8db +.section so8ea +.section so8eb +.section so8fa +.section so8fb +.section so8ga +.section so8gb +.section so8ha +.section so8hb +.section so8ia +.section so8ib +.section so8ja +.section so8jb +.section so8ka +.section so8kb +.section so8la +.section so8lb +.section so8ma +.section so8mb +.section so8na +.section so8nb +.section so8oa +.section so8ob +.section so8pa +.section so8pb +.section so8qa +.section so8qb +.section so8ra +.section so8rb +.section so8sa +.section so8sb +.section so8ta +.section so8tb +.section so8ua +.section so8ub +.section so8va +.section so8vb +.section so8wa +.section so8wb +.section so8xa +.section so8xb +.section so8ya +.section so8yb +.section so8za +.section so8zb +.section so81a +.section so81b +.section so82a +.section so82b +.section so83a +.section so83b +.section so84a +.section so84b +.section so85a +.section so85b +.section so86a +.section so86b +.section so87a +.section so87b +.section so88a +.section so88b +.section so89a +.section so89b +.section so80a +.section so80b +.section so9aa +.section so9ab +.section so9ba +.section so9bb +.section so9ca +.section so9cb +.section so9da +.section so9db +.section so9ea +.section so9eb +.section so9fa +.section so9fb +.section so9ga +.section so9gb +.section so9ha +.section so9hb +.section so9ia +.section so9ib +.section so9ja +.section so9jb +.section so9ka +.section so9kb +.section so9la +.section so9lb +.section so9ma +.section so9mb +.section so9na +.section so9nb +.section so9oa +.section so9ob +.section so9pa +.section so9pb +.section so9qa +.section so9qb +.section so9ra +.section so9rb +.section so9sa +.section so9sb +.section so9ta +.section so9tb +.section so9ua +.section so9ub +.section so9va +.section so9vb +.section so9wa +.section so9wb +.section so9xa +.section so9xb +.section so9ya +.section so9yb +.section so9za +.section so9zb +.section so91a +.section so91b +.section so92a +.section so92b +.section so93a +.section so93b +.section so94a +.section so94b +.section so95a +.section so95b +.section so96a +.section so96b +.section so97a +.section so97b +.section so98a +.section so98b +.section so99a +.section so99b +.section so90a +.section so90b +.section so0aa +.section so0ab +.section so0ba +.section so0bb +.section so0ca +.section so0cb +.section so0da +.section so0db +.section so0ea +.section so0eb +.section so0fa +.section so0fb +.section so0ga +.section so0gb +.section so0ha +.section so0hb +.section so0ia +.section so0ib +.section so0ja +.section so0jb +.section so0ka +.section so0kb +.section so0la +.section so0lb +.section so0ma +.section so0mb +.section so0na +.section so0nb +.section so0oa +.section so0ob +.section so0pa +.section so0pb +.section so0qa +.section so0qb +.section so0ra +.section so0rb +.section so0sa +.section so0sb +.section so0ta +.section so0tb +.section so0ua +.section so0ub +.section so0va +.section so0vb +.section so0wa +.section so0wb +.section so0xa +.section so0xb +.section so0ya +.section so0yb +.section so0za +.section so0zb +.section so01a +.section so01b +.section so02a +.section so02b +.section so03a +.section so03b +.section so04a +.section so04b +.section so05a +.section so05b +.section so06a +.section so06b +.section so07a +.section so07b +.section so08a +.section so08b +.section so09a +.section so09b +.section so00a +.section so00b +.section spaaa +.section spaab +.section spaba +.section spabb +.section spaca +.section spacb +.section spada +.section spadb +.section spaea +.section spaeb +.section spafa +.section spafb +.section spaga +.section spagb +.section spaha +.section spahb +.section spaia +.section spaib +.section spaja +.section spajb +.section spaka +.section spakb +.section spala +.section spalb +.section spama +.section spamb +.section spana +.section spanb +.section spaoa +.section spaob +.section spapa +.section spapb +.section spaqa +.section spaqb +.section spara +.section sparb +.section spasa +.section spasb +.section spata +.section spatb +.section spaua +.section spaub +.section spava +.section spavb +.section spawa +.section spawb +.section spaxa +.section spaxb +.section spaya +.section spayb +.section spaza +.section spazb +.section spa1a +.section spa1b +.section spa2a +.section spa2b +.section spa3a +.section spa3b +.section spa4a +.section spa4b +.section spa5a +.section spa5b +.section spa6a +.section spa6b +.section spa7a +.section spa7b +.section spa8a +.section spa8b +.section spa9a +.section spa9b +.section spa0a +.section spa0b +.section spbaa +.section spbab +.section spbba +.section spbbb +.section spbca +.section spbcb +.section spbda +.section spbdb +.section spbea +.section spbeb +.section spbfa +.section spbfb +.section spbga +.section spbgb +.section spbha +.section spbhb +.section spbia +.section spbib +.section spbja +.section spbjb +.section spbka +.section spbkb +.section spbla +.section spblb +.section spbma +.section spbmb +.section spbna +.section spbnb +.section spboa +.section spbob +.section spbpa +.section spbpb +.section spbqa +.section spbqb +.section spbra +.section spbrb +.section spbsa +.section spbsb +.section spbta +.section spbtb +.section spbua +.section spbub +.section spbva +.section spbvb +.section spbwa +.section spbwb +.section spbxa +.section spbxb +.section spbya +.section spbyb +.section spbza +.section spbzb +.section spb1a +.section spb1b +.section spb2a +.section spb2b +.section spb3a +.section spb3b +.section spb4a +.section spb4b +.section spb5a +.section spb5b +.section spb6a +.section spb6b +.section spb7a +.section spb7b +.section spb8a +.section spb8b +.section spb9a +.section spb9b +.section spb0a +.section spb0b +.section spcaa +.section spcab +.section spcba +.section spcbb +.section spcca +.section spccb +.section spcda +.section spcdb +.section spcea +.section spceb +.section spcfa +.section spcfb +.section spcga +.section spcgb +.section spcha +.section spchb +.section spcia +.section spcib +.section spcja +.section spcjb +.section spcka +.section spckb +.section spcla +.section spclb +.section spcma +.section spcmb +.section spcna +.section spcnb +.section spcoa +.section spcob +.section spcpa +.section spcpb +.section spcqa +.section spcqb +.section spcra +.section spcrb +.section spcsa +.section spcsb +.section spcta +.section spctb +.section spcua +.section spcub +.section spcva +.section spcvb +.section spcwa +.section spcwb +.section spcxa +.section spcxb +.section spcya +.section spcyb +.section spcza +.section spczb +.section spc1a +.section spc1b +.section spc2a +.section spc2b +.section spc3a +.section spc3b +.section spc4a +.section spc4b +.section spc5a +.section spc5b +.section spc6a +.section spc6b +.section spc7a +.section spc7b +.section spc8a +.section spc8b +.section spc9a +.section spc9b +.section spc0a +.section spc0b +.section spdaa +.section spdab +.section spdba +.section spdbb +.section spdca +.section spdcb +.section spdda +.section spddb +.section spdea +.section spdeb +.section spdfa +.section spdfb +.section spdga +.section spdgb +.section spdha +.section spdhb +.section spdia +.section spdib +.section spdja +.section spdjb +.section spdka +.section spdkb +.section spdla +.section spdlb +.section spdma +.section spdmb +.section spdna +.section spdnb +.section spdoa +.section spdob +.section spdpa +.section spdpb +.section spdqa +.section spdqb +.section spdra +.section spdrb +.section spdsa +.section spdsb +.section spdta +.section spdtb +.section spdua +.section spdub +.section spdva +.section spdvb +.section spdwa +.section spdwb +.section spdxa +.section spdxb +.section spdya +.section spdyb +.section spdza +.section spdzb +.section spd1a +.section spd1b +.section spd2a +.section spd2b +.section spd3a +.section spd3b +.section spd4a +.section spd4b +.section spd5a +.section spd5b +.section spd6a +.section spd6b +.section spd7a +.section spd7b +.section spd8a +.section spd8b +.section spd9a +.section spd9b +.section spd0a +.section spd0b +.section speaa +.section speab +.section speba +.section spebb +.section speca +.section specb +.section speda +.section spedb +.section speea +.section speeb +.section spefa +.section spefb +.section spega +.section spegb +.section speha +.section spehb +.section speia +.section speib +.section speja +.section spejb +.section speka +.section spekb +.section spela +.section spelb +.section spema +.section spemb +.section spena +.section spenb +.section speoa +.section speob +.section spepa +.section spepb +.section speqa +.section speqb +.section spera +.section sperb +.section spesa +.section spesb +.section speta +.section spetb +.section speua +.section speub +.section speva +.section spevb +.section spewa +.section spewb +.section spexa +.section spexb +.section speya +.section speyb +.section speza +.section spezb +.section spe1a +.section spe1b +.section spe2a +.section spe2b +.section spe3a +.section spe3b +.section spe4a +.section spe4b +.section spe5a +.section spe5b +.section spe6a +.section spe6b +.section spe7a +.section spe7b +.section spe8a +.section spe8b +.section spe9a +.section spe9b +.section spe0a +.section spe0b +.section spfaa +.section spfab +.section spfba +.section spfbb +.section spfca +.section spfcb +.section spfda +.section spfdb +.section spfea +.section spfeb +.section spffa +.section spffb +.section spfga +.section spfgb +.section spfha +.section spfhb +.section spfia +.section spfib +.section spfja +.section spfjb +.section spfka +.section spfkb +.section spfla +.section spflb +.section spfma +.section spfmb +.section spfna +.section spfnb +.section spfoa +.section spfob +.section spfpa +.section spfpb +.section spfqa +.section spfqb +.section spfra +.section spfrb +.section spfsa +.section spfsb +.section spfta +.section spftb +.section spfua +.section spfub +.section spfva +.section spfvb +.section spfwa +.section spfwb +.section spfxa +.section spfxb +.section spfya +.section spfyb +.section spfza +.section spfzb +.section spf1a +.section spf1b +.section spf2a +.section spf2b +.section spf3a +.section spf3b +.section spf4a +.section spf4b +.section spf5a +.section spf5b +.section spf6a +.section spf6b +.section spf7a +.section spf7b +.section spf8a +.section spf8b +.section spf9a +.section spf9b +.section spf0a +.section spf0b +.section spgaa +.section spgab +.section spgba +.section spgbb +.section spgca +.section spgcb +.section spgda +.section spgdb +.section spgea +.section spgeb +.section spgfa +.section spgfb +.section spgga +.section spggb +.section spgha +.section spghb +.section spgia +.section spgib +.section spgja +.section spgjb +.section spgka +.section spgkb +.section spgla +.section spglb +.section spgma +.section spgmb +.section spgna +.section spgnb +.section spgoa +.section spgob +.section spgpa +.section spgpb +.section spgqa +.section spgqb +.section spgra +.section spgrb +.section spgsa +.section spgsb +.section spgta +.section spgtb +.section spgua +.section spgub +.section spgva +.section spgvb +.section spgwa +.section spgwb +.section spgxa +.section spgxb +.section spgya +.section spgyb +.section spgza +.section spgzb +.section spg1a +.section spg1b +.section spg2a +.section spg2b +.section spg3a +.section spg3b +.section spg4a +.section spg4b +.section spg5a +.section spg5b +.section spg6a +.section spg6b +.section spg7a +.section spg7b +.section spg8a +.section spg8b +.section spg9a +.section spg9b +.section spg0a +.section spg0b +.section sphaa +.section sphab +.section sphba +.section sphbb +.section sphca +.section sphcb +.section sphda +.section sphdb +.section sphea +.section spheb +.section sphfa +.section sphfb +.section sphga +.section sphgb +.section sphha +.section sphhb +.section sphia +.section sphib +.section sphja +.section sphjb +.section sphka +.section sphkb +.section sphla +.section sphlb +.section sphma +.section sphmb +.section sphna +.section sphnb +.section sphoa +.section sphob +.section sphpa +.section sphpb +.section sphqa +.section sphqb +.section sphra +.section sphrb +.section sphsa +.section sphsb +.section sphta +.section sphtb +.section sphua +.section sphub +.section sphva +.section sphvb +.section sphwa +.section sphwb +.section sphxa +.section sphxb +.section sphya +.section sphyb +.section sphza +.section sphzb +.section sph1a +.section sph1b +.section sph2a +.section sph2b +.section sph3a +.section sph3b +.section sph4a +.section sph4b +.section sph5a +.section sph5b +.section sph6a +.section sph6b +.section sph7a +.section sph7b +.section sph8a +.section sph8b +.section sph9a +.section sph9b +.section sph0a +.section sph0b +.section spiaa +.section spiab +.section spiba +.section spibb +.section spica +.section spicb +.section spida +.section spidb +.section spiea +.section spieb +.section spifa +.section spifb +.section spiga +.section spigb +.section spiha +.section spihb +.section spiia +.section spiib +.section spija +.section spijb +.section spika +.section spikb +.section spila +.section spilb +.section spima +.section spimb +.section spina +.section spinb +.section spioa +.section spiob +.section spipa +.section spipb +.section spiqa +.section spiqb +.section spira +.section spirb +.section spisa +.section spisb +.section spita +.section spitb +.section spiua +.section spiub +.section spiva +.section spivb +.section spiwa +.section spiwb +.section spixa +.section spixb +.section spiya +.section spiyb +.section spiza +.section spizb +.section spi1a +.section spi1b +.section spi2a +.section spi2b +.section spi3a +.section spi3b +.section spi4a +.section spi4b +.section spi5a +.section spi5b +.section spi6a +.section spi6b +.section spi7a +.section spi7b +.section spi8a +.section spi8b +.section spi9a +.section spi9b +.section spi0a +.section spi0b +.section spjaa +.section spjab +.section spjba +.section spjbb +.section spjca +.section spjcb +.section spjda +.section spjdb +.section spjea +.section spjeb +.section spjfa +.section spjfb +.section spjga +.section spjgb +.section spjha +.section spjhb +.section spjia +.section spjib +.section spjja +.section spjjb +.section spjka +.section spjkb +.section spjla +.section spjlb +.section spjma +.section spjmb +.section spjna +.section spjnb +.section spjoa +.section spjob +.section spjpa +.section spjpb +.section spjqa +.section spjqb +.section spjra +.section spjrb +.section spjsa +.section spjsb +.section spjta +.section spjtb +.section spjua +.section spjub +.section spjva +.section spjvb +.section spjwa +.section spjwb +.section spjxa +.section spjxb +.section spjya +.section spjyb +.section spjza +.section spjzb +.section spj1a +.section spj1b +.section spj2a +.section spj2b +.section spj3a +.section spj3b +.section spj4a +.section spj4b +.section spj5a +.section spj5b +.section spj6a +.section spj6b +.section spj7a +.section spj7b +.section spj8a +.section spj8b +.section spj9a +.section spj9b +.section spj0a +.section spj0b +.section spkaa +.section spkab +.section spkba +.section spkbb +.section spkca +.section spkcb +.section spkda +.section spkdb +.section spkea +.section spkeb +.section spkfa +.section spkfb +.section spkga +.section spkgb +.section spkha +.section spkhb +.section spkia +.section spkib +.section spkja +.section spkjb +.section spkka +.section spkkb +.section spkla +.section spklb +.section spkma +.section spkmb +.section spkna +.section spknb +.section spkoa +.section spkob +.section spkpa +.section spkpb +.section spkqa +.section spkqb +.section spkra +.section spkrb +.section spksa +.section spksb +.section spkta +.section spktb +.section spkua +.section spkub +.section spkva +.section spkvb +.section spkwa +.section spkwb +.section spkxa +.section spkxb +.section spkya +.section spkyb +.section spkza +.section spkzb +.section spk1a +.section spk1b +.section spk2a +.section spk2b +.section spk3a +.section spk3b +.section spk4a +.section spk4b +.section spk5a +.section spk5b +.section spk6a +.section spk6b +.section spk7a +.section spk7b +.section spk8a +.section spk8b +.section spk9a +.section spk9b +.section spk0a +.section spk0b +.section splaa +.section splab +.section splba +.section splbb +.section splca +.section splcb +.section splda +.section spldb +.section splea +.section spleb +.section splfa +.section splfb +.section splga +.section splgb +.section splha +.section splhb +.section splia +.section splib +.section splja +.section spljb +.section splka +.section splkb +.section splla +.section spllb +.section splma +.section splmb +.section splna +.section splnb +.section sploa +.section splob +.section splpa +.section splpb +.section splqa +.section splqb +.section splra +.section splrb +.section splsa +.section splsb +.section splta +.section spltb +.section splua +.section splub +.section splva +.section splvb +.section splwa +.section splwb +.section splxa +.section splxb +.section splya +.section splyb +.section splza +.section splzb +.section spl1a +.section spl1b +.section spl2a +.section spl2b +.section spl3a +.section spl3b +.section spl4a +.section spl4b +.section spl5a +.section spl5b +.section spl6a +.section spl6b +.section spl7a +.section spl7b +.section spl8a +.section spl8b +.section spl9a +.section spl9b +.section spl0a +.section spl0b +.section spmaa +.section spmab +.section spmba +.section spmbb +.section spmca +.section spmcb +.section spmda +.section spmdb +.section spmea +.section spmeb +.section spmfa +.section spmfb +.section spmga +.section spmgb +.section spmha +.section spmhb +.section spmia +.section spmib +.section spmja +.section spmjb +.section spmka +.section spmkb +.section spmla +.section spmlb +.section spmma +.section spmmb +.section spmna +.section spmnb +.section spmoa +.section spmob +.section spmpa +.section spmpb +.section spmqa +.section spmqb +.section spmra +.section spmrb +.section spmsa +.section spmsb +.section spmta +.section spmtb +.section spmua +.section spmub +.section spmva +.section spmvb +.section spmwa +.section spmwb +.section spmxa +.section spmxb +.section spmya +.section spmyb +.section spmza +.section spmzb +.section spm1a +.section spm1b +.section spm2a +.section spm2b +.section spm3a +.section spm3b +.section spm4a +.section spm4b +.section spm5a +.section spm5b +.section spm6a +.section spm6b +.section spm7a +.section spm7b +.section spm8a +.section spm8b +.section spm9a +.section spm9b +.section spm0a +.section spm0b +.section spnaa +.section spnab +.section spnba +.section spnbb +.section spnca +.section spncb +.section spnda +.section spndb +.section spnea +.section spneb +.section spnfa +.section spnfb +.section spnga +.section spngb +.section spnha +.section spnhb +.section spnia +.section spnib +.section spnja +.section spnjb +.section spnka +.section spnkb +.section spnla +.section spnlb +.section spnma +.section spnmb +.section spnna +.section spnnb +.section spnoa +.section spnob +.section spnpa +.section spnpb +.section spnqa +.section spnqb +.section spnra +.section spnrb +.section spnsa +.section spnsb +.section spnta +.section spntb +.section spnua +.section spnub +.section spnva +.section spnvb +.section spnwa +.section spnwb +.section spnxa +.section spnxb +.section spnya +.section spnyb +.section spnza +.section spnzb +.section spn1a +.section spn1b +.section spn2a +.section spn2b +.section spn3a +.section spn3b +.section spn4a +.section spn4b +.section spn5a +.section spn5b +.section spn6a +.section spn6b +.section spn7a +.section spn7b +.section spn8a +.section spn8b +.section spn9a +.section spn9b +.section spn0a +.section spn0b +.section spoaa +.section spoab +.section spoba +.section spobb +.section spoca +.section spocb +.section spoda +.section spodb +.section spoea +.section spoeb +.section spofa +.section spofb +.section spoga +.section spogb +.section spoha +.section spohb +.section spoia +.section spoib +.section spoja +.section spojb +.section spoka +.section spokb +.section spola +.section spolb +.section spoma +.section spomb +.section spona +.section sponb +.section spooa +.section spoob +.section spopa +.section spopb +.section spoqa +.section spoqb +.section spora +.section sporb +.section sposa +.section sposb +.section spota +.section spotb +.section spoua +.section spoub +.section spova +.section spovb +.section spowa +.section spowb +.section spoxa +.section spoxb +.section spoya +.section spoyb +.section spoza +.section spozb +.section spo1a +.section spo1b +.section spo2a +.section spo2b +.section spo3a +.section spo3b +.section spo4a +.section spo4b +.section spo5a +.section spo5b +.section spo6a +.section spo6b +.section spo7a +.section spo7b +.section spo8a +.section spo8b +.section spo9a +.section spo9b +.section spo0a +.section spo0b +.section sppaa +.section sppab +.section sppba +.section sppbb +.section sppca +.section sppcb +.section sppda +.section sppdb +.section sppea +.section sppeb +.section sppfa +.section sppfb +.section sppga +.section sppgb +.section sppha +.section spphb +.section sppia +.section sppib +.section sppja +.section sppjb +.section sppka +.section sppkb +.section sppla +.section spplb +.section sppma +.section sppmb +.section sppna +.section sppnb +.section sppoa +.section sppob +.section spppa +.section spppb +.section sppqa +.section sppqb +.section sppra +.section spprb +.section sppsa +.section sppsb +.section sppta +.section spptb +.section sppua +.section sppub +.section sppva +.section sppvb +.section sppwa +.section sppwb +.section sppxa +.section sppxb +.section sppya +.section sppyb +.section sppza +.section sppzb +.section spp1a +.section spp1b +.section spp2a +.section spp2b +.section spp3a +.section spp3b +.section spp4a +.section spp4b +.section spp5a +.section spp5b +.section spp6a +.section spp6b +.section spp7a +.section spp7b +.section spp8a +.section spp8b +.section spp9a +.section spp9b +.section spp0a +.section spp0b +.section spqaa +.section spqab +.section spqba +.section spqbb +.section spqca +.section spqcb +.section spqda +.section spqdb +.section spqea +.section spqeb +.section spqfa +.section spqfb +.section spqga +.section spqgb +.section spqha +.section spqhb +.section spqia +.section spqib +.section spqja +.section spqjb +.section spqka +.section spqkb +.section spqla +.section spqlb +.section spqma +.section spqmb +.section spqna +.section spqnb +.section spqoa +.section spqob +.section spqpa +.section spqpb +.section spqqa +.section spqqb +.section spqra +.section spqrb +.section spqsa +.section spqsb +.section spqta +.section spqtb +.section spqua +.section spqub +.section spqva +.section spqvb +.section spqwa +.section spqwb +.section spqxa +.section spqxb +.section spqya +.section spqyb +.section spqza +.section spqzb +.section spq1a +.section spq1b +.section spq2a +.section spq2b +.section spq3a +.section spq3b +.section spq4a +.section spq4b +.section spq5a +.section spq5b +.section spq6a +.section spq6b +.section spq7a +.section spq7b +.section spq8a +.section spq8b +.section spq9a +.section spq9b +.section spq0a +.section spq0b +.section spraa +.section sprab +.section sprba +.section sprbb +.section sprca +.section sprcb +.section sprda +.section sprdb +.section sprea +.section spreb +.section sprfa +.section sprfb +.section sprga +.section sprgb +.section sprha +.section sprhb +.section spria +.section sprib +.section sprja +.section sprjb +.section sprka +.section sprkb +.section sprla +.section sprlb +.section sprma +.section sprmb +.section sprna +.section sprnb +.section sproa +.section sprob +.section sprpa +.section sprpb +.section sprqa +.section sprqb +.section sprra +.section sprrb +.section sprsa +.section sprsb +.section sprta +.section sprtb +.section sprua +.section sprub +.section sprva +.section sprvb +.section sprwa +.section sprwb +.section sprxa +.section sprxb +.section sprya +.section spryb +.section sprza +.section sprzb +.section spr1a +.section spr1b +.section spr2a +.section spr2b +.section spr3a +.section spr3b +.section spr4a +.section spr4b +.section spr5a +.section spr5b +.section spr6a +.section spr6b +.section spr7a +.section spr7b +.section spr8a +.section spr8b +.section spr9a +.section spr9b +.section spr0a +.section spr0b +.section spsaa +.section spsab +.section spsba +.section spsbb +.section spsca +.section spscb +.section spsda +.section spsdb +.section spsea +.section spseb +.section spsfa +.section spsfb +.section spsga +.section spsgb +.section spsha +.section spshb +.section spsia +.section spsib +.section spsja +.section spsjb +.section spska +.section spskb +.section spsla +.section spslb +.section spsma +.section spsmb +.section spsna +.section spsnb +.section spsoa +.section spsob +.section spspa +.section spspb +.section spsqa +.section spsqb +.section spsra +.section spsrb +.section spssa +.section spssb +.section spsta +.section spstb +.section spsua +.section spsub +.section spsva +.section spsvb +.section spswa +.section spswb +.section spsxa +.section spsxb +.section spsya +.section spsyb +.section spsza +.section spszb +.section sps1a +.section sps1b +.section sps2a +.section sps2b +.section sps3a +.section sps3b +.section sps4a +.section sps4b +.section sps5a +.section sps5b +.section sps6a +.section sps6b +.section sps7a +.section sps7b +.section sps8a +.section sps8b +.section sps9a +.section sps9b +.section sps0a +.section sps0b +.section sptaa +.section sptab +.section sptba +.section sptbb +.section sptca +.section sptcb +.section sptda +.section sptdb +.section sptea +.section spteb +.section sptfa +.section sptfb +.section sptga +.section sptgb +.section sptha +.section spthb +.section sptia +.section sptib +.section sptja +.section sptjb +.section sptka +.section sptkb +.section sptla +.section sptlb +.section sptma +.section sptmb +.section sptna +.section sptnb +.section sptoa +.section sptob +.section sptpa +.section sptpb +.section sptqa +.section sptqb +.section sptra +.section sptrb +.section sptsa +.section sptsb +.section sptta +.section spttb +.section sptua +.section sptub +.section sptva +.section sptvb +.section sptwa +.section sptwb +.section sptxa +.section sptxb +.section sptya +.section sptyb +.section sptza +.section sptzb +.section spt1a +.section spt1b +.section spt2a +.section spt2b +.section spt3a +.section spt3b +.section spt4a +.section spt4b +.section spt5a +.section spt5b +.section spt6a +.section spt6b +.section spt7a +.section spt7b +.section spt8a +.section spt8b +.section spt9a +.section spt9b +.section spt0a +.section spt0b +.section spuaa +.section spuab +.section spuba +.section spubb +.section spuca +.section spucb +.section spuda +.section spudb +.section spuea +.section spueb +.section spufa +.section spufb +.section spuga +.section spugb +.section spuha +.section spuhb +.section spuia +.section spuib +.section spuja +.section spujb +.section spuka +.section spukb +.section spula +.section spulb +.section spuma +.section spumb +.section spuna +.section spunb +.section spuoa +.section spuob +.section spupa +.section spupb +.section spuqa +.section spuqb +.section spura +.section spurb +.section spusa +.section spusb +.section sputa +.section sputb +.section spuua +.section spuub +.section spuva +.section spuvb +.section spuwa +.section spuwb +.section spuxa +.section spuxb +.section spuya +.section spuyb +.section spuza +.section spuzb +.section spu1a +.section spu1b +.section spu2a +.section spu2b +.section spu3a +.section spu3b +.section spu4a +.section spu4b +.section spu5a +.section spu5b +.section spu6a +.section spu6b +.section spu7a +.section spu7b +.section spu8a +.section spu8b +.section spu9a +.section spu9b +.section spu0a +.section spu0b +.section spvaa +.section spvab +.section spvba +.section spvbb +.section spvca +.section spvcb +.section spvda +.section spvdb +.section spvea +.section spveb +.section spvfa +.section spvfb +.section spvga +.section spvgb +.section spvha +.section spvhb +.section spvia +.section spvib +.section spvja +.section spvjb +.section spvka +.section spvkb +.section spvla +.section spvlb +.section spvma +.section spvmb +.section spvna +.section spvnb +.section spvoa +.section spvob +.section spvpa +.section spvpb +.section spvqa +.section spvqb +.section spvra +.section spvrb +.section spvsa +.section spvsb +.section spvta +.section spvtb +.section spvua +.section spvub +.section spvva +.section spvvb +.section spvwa +.section spvwb +.section spvxa +.section spvxb +.section spvya +.section spvyb +.section spvza +.section spvzb +.section spv1a +.section spv1b +.section spv2a +.section spv2b +.section spv3a +.section spv3b +.section spv4a +.section spv4b +.section spv5a +.section spv5b +.section spv6a +.section spv6b +.section spv7a +.section spv7b +.section spv8a +.section spv8b +.section spv9a +.section spv9b +.section spv0a +.section spv0b +.section spwaa +.section spwab +.section spwba +.section spwbb +.section spwca +.section spwcb +.section spwda +.section spwdb +.section spwea +.section spweb +.section spwfa +.section spwfb +.section spwga +.section spwgb +.section spwha +.section spwhb +.section spwia +.section spwib +.section spwja +.section spwjb +.section spwka +.section spwkb +.section spwla +.section spwlb +.section spwma +.section spwmb +.section spwna +.section spwnb +.section spwoa +.section spwob +.section spwpa +.section spwpb +.section spwqa +.section spwqb +.section spwra +.section spwrb +.section spwsa +.section spwsb +.section spwta +.section spwtb +.section spwua +.section spwub +.section spwva +.section spwvb +.section spwwa +.section spwwb +.section spwxa +.section spwxb +.section spwya +.section spwyb +.section spwza +.section spwzb +.section spw1a +.section spw1b +.section spw2a +.section spw2b +.section spw3a +.section spw3b +.section spw4a +.section spw4b +.section spw5a +.section spw5b +.section spw6a +.section spw6b +.section spw7a +.section spw7b +.section spw8a +.section spw8b +.section spw9a +.section spw9b +.section spw0a +.section spw0b +.section spxaa +.section spxab +.section spxba +.section spxbb +.section spxca +.section spxcb +.section spxda +.section spxdb +.section spxea +.section spxeb +.section spxfa +.section spxfb +.section spxga +.section spxgb +.section spxha +.section spxhb +.section spxia +.section spxib +.section spxja +.section spxjb +.section spxka +.section spxkb +.section spxla +.section spxlb +.section spxma +.section spxmb +.section spxna +.section spxnb +.section spxoa +.section spxob +.section spxpa +.section spxpb +.section spxqa +.section spxqb +.section spxra +.section spxrb +.section spxsa +.section spxsb +.section spxta +.section spxtb +.section spxua +.section spxub +.section spxva +.section spxvb +.section spxwa +.section spxwb +.section spxxa +.section spxxb +.section spxya +.section spxyb +.section spxza +.section spxzb +.section spx1a +.section spx1b +.section spx2a +.section spx2b +.section spx3a +.section spx3b +.section spx4a +.section spx4b +.section spx5a +.section spx5b +.section spx6a +.section spx6b +.section spx7a +.section spx7b +.section spx8a +.section spx8b +.section spx9a +.section spx9b +.section spx0a +.section spx0b +.section spyaa +.section spyab +.section spyba +.section spybb +.section spyca +.section spycb +.section spyda +.section spydb +.section spyea +.section spyeb +.section spyfa +.section spyfb +.section spyga +.section spygb +.section spyha +.section spyhb +.section spyia +.section spyib +.section spyja +.section spyjb +.section spyka +.section spykb +.section spyla +.section spylb +.section spyma +.section spymb +.section spyna +.section spynb +.section spyoa +.section spyob +.section spypa +.section spypb +.section spyqa +.section spyqb +.section spyra +.section spyrb +.section spysa +.section spysb +.section spyta +.section spytb +.section spyua +.section spyub +.section spyva +.section spyvb +.section spywa +.section spywb +.section spyxa +.section spyxb +.section spyya +.section spyyb +.section spyza +.section spyzb +.section spy1a +.section spy1b +.section spy2a +.section spy2b +.section spy3a +.section spy3b +.section spy4a +.section spy4b +.section spy5a +.section spy5b +.section spy6a +.section spy6b +.section spy7a +.section spy7b +.section spy8a +.section spy8b +.section spy9a +.section spy9b +.section spy0a +.section spy0b +.section spzaa +.section spzab +.section spzba +.section spzbb +.section spzca +.section spzcb +.section spzda +.section spzdb +.section spzea +.section spzeb +.section spzfa +.section spzfb +.section spzga +.section spzgb +.section spzha +.section spzhb +.section spzia +.section spzib +.section spzja +.section spzjb +.section spzka +.section spzkb +.section spzla +.section spzlb +.section spzma +.section spzmb +.section spzna +.section spznb +.section spzoa +.section spzob +.section spzpa +.section spzpb +.section spzqa +.section spzqb +.section spzra +.section spzrb +.section spzsa +.section spzsb +.section spzta +.section spztb +.section spzua +.section spzub +.section spzva +.section spzvb +.section spzwa +.section spzwb +.section spzxa +.section spzxb +.section spzya +.section spzyb +.section spzza +.section spzzb +.section spz1a +.section spz1b +.section spz2a +.section spz2b +.section spz3a +.section spz3b +.section spz4a +.section spz4b +.section spz5a +.section spz5b +.section spz6a +.section spz6b +.section spz7a +.section spz7b +.section spz8a +.section spz8b +.section spz9a +.section spz9b +.section spz0a +.section spz0b +.section sp1aa +.section sp1ab +.section sp1ba +.section sp1bb +.section sp1ca +.section sp1cb +.section sp1da +.section sp1db +.section sp1ea +.section sp1eb +.section sp1fa +.section sp1fb +.section sp1ga +.section sp1gb +.section sp1ha +.section sp1hb +.section sp1ia +.section sp1ib +.section sp1ja +.section sp1jb +.section sp1ka +.section sp1kb +.section sp1la +.section sp1lb +.section sp1ma +.section sp1mb +.section sp1na +.section sp1nb +.section sp1oa +.section sp1ob +.section sp1pa +.section sp1pb +.section sp1qa +.section sp1qb +.section sp1ra +.section sp1rb +.section sp1sa +.section sp1sb +.section sp1ta +.section sp1tb +.section sp1ua +.section sp1ub +.section sp1va +.section sp1vb +.section sp1wa +.section sp1wb +.section sp1xa +.section sp1xb +.section sp1ya +.section sp1yb +.section sp1za +.section sp1zb +.section sp11a +.section sp11b +.section sp12a +.section sp12b +.section sp13a +.section sp13b +.section sp14a +.section sp14b +.section sp15a +.section sp15b +.section sp16a +.section sp16b +.section sp17a +.section sp17b +.section sp18a +.section sp18b +.section sp19a +.section sp19b +.section sp10a +.section sp10b +.section sp2aa +.section sp2ab +.section sp2ba +.section sp2bb +.section sp2ca +.section sp2cb +.section sp2da +.section sp2db +.section sp2ea +.section sp2eb +.section sp2fa +.section sp2fb +.section sp2ga +.section sp2gb +.section sp2ha +.section sp2hb +.section sp2ia +.section sp2ib +.section sp2ja +.section sp2jb +.section sp2ka +.section sp2kb +.section sp2la +.section sp2lb +.section sp2ma +.section sp2mb +.section sp2na +.section sp2nb +.section sp2oa +.section sp2ob +.section sp2pa +.section sp2pb +.section sp2qa +.section sp2qb +.section sp2ra +.section sp2rb +.section sp2sa +.section sp2sb +.section sp2ta +.section sp2tb +.section sp2ua +.section sp2ub +.section sp2va +.section sp2vb +.section sp2wa +.section sp2wb +.section sp2xa +.section sp2xb +.section sp2ya +.section sp2yb +.section sp2za +.section sp2zb +.section sp21a +.section sp21b +.section sp22a +.section sp22b +.section sp23a +.section sp23b +.section sp24a +.section sp24b +.section sp25a +.section sp25b +.section sp26a +.section sp26b +.section sp27a +.section sp27b +.section sp28a +.section sp28b +.section sp29a +.section sp29b +.section sp20a +.section sp20b +.section sp3aa +.section sp3ab +.section sp3ba +.section sp3bb +.section sp3ca +.section sp3cb +.section sp3da +.section sp3db +.section sp3ea +.section sp3eb +.section sp3fa +.section sp3fb +.section sp3ga +.section sp3gb +.section sp3ha +.section sp3hb +.section sp3ia +.section sp3ib +.section sp3ja +.section sp3jb +.section sp3ka +.section sp3kb +.section sp3la +.section sp3lb +.section sp3ma +.section sp3mb +.section sp3na +.section sp3nb +.section sp3oa +.section sp3ob +.section sp3pa +.section sp3pb +.section sp3qa +.section sp3qb +.section sp3ra +.section sp3rb +.section sp3sa +.section sp3sb +.section sp3ta +.section sp3tb +.section sp3ua +.section sp3ub +.section sp3va +.section sp3vb +.section sp3wa +.section sp3wb +.section sp3xa +.section sp3xb +.section sp3ya +.section sp3yb +.section sp3za +.section sp3zb +.section sp31a +.section sp31b +.section sp32a +.section sp32b +.section sp33a +.section sp33b +.section sp34a +.section sp34b +.section sp35a +.section sp35b +.section sp36a +.section sp36b +.section sp37a +.section sp37b +.section sp38a +.section sp38b +.section sp39a +.section sp39b +.section sp30a +.section sp30b +.section sp4aa +.section sp4ab +.section sp4ba +.section sp4bb +.section sp4ca +.section sp4cb +.section sp4da +.section sp4db +.section sp4ea +.section sp4eb +.section sp4fa +.section sp4fb +.section sp4ga +.section sp4gb +.section sp4ha +.section sp4hb +.section sp4ia +.section sp4ib +.section sp4ja +.section sp4jb +.section sp4ka +.section sp4kb +.section sp4la +.section sp4lb +.section sp4ma +.section sp4mb +.section sp4na +.section sp4nb +.section sp4oa +.section sp4ob +.section sp4pa +.section sp4pb +.section sp4qa +.section sp4qb +.section sp4ra +.section sp4rb +.section sp4sa +.section sp4sb +.section sp4ta +.section sp4tb +.section sp4ua +.section sp4ub +.section sp4va +.section sp4vb +.section sp4wa +.section sp4wb +.section sp4xa +.section sp4xb +.section sp4ya +.section sp4yb +.section sp4za +.section sp4zb +.section sp41a +.section sp41b +.section sp42a +.section sp42b +.section sp43a +.section sp43b +.section sp44a +.section sp44b +.section sp45a +.section sp45b +.section sp46a +.section sp46b +.section sp47a +.section sp47b +.section sp48a +.section sp48b +.section sp49a +.section sp49b +.section sp40a +.section sp40b +.section sp5aa +.section sp5ab +.section sp5ba +.section sp5bb +.section sp5ca +.section sp5cb +.section sp5da +.section sp5db +.section sp5ea +.section sp5eb +.section sp5fa +.section sp5fb +.section sp5ga +.section sp5gb +.section sp5ha +.section sp5hb +.section sp5ia +.section sp5ib +.section sp5ja +.section sp5jb +.section sp5ka +.section sp5kb +.section sp5la +.section sp5lb +.section sp5ma +.section sp5mb +.section sp5na +.section sp5nb +.section sp5oa +.section sp5ob +.section sp5pa +.section sp5pb +.section sp5qa +.section sp5qb +.section sp5ra +.section sp5rb +.section sp5sa +.section sp5sb +.section sp5ta +.section sp5tb +.section sp5ua +.section sp5ub +.section sp5va +.section sp5vb +.section sp5wa +.section sp5wb +.section sp5xa +.section sp5xb +.section sp5ya +.section sp5yb +.section sp5za +.section sp5zb +.section sp51a +.section sp51b +.section sp52a +.section sp52b +.section sp53a +.section sp53b +.section sp54a +.section sp54b +.section sp55a +.section sp55b +.section sp56a +.section sp56b +.section sp57a +.section sp57b +.section sp58a +.section sp58b +.section sp59a +.section sp59b +.section sp50a +.section sp50b +.section sp6aa +.section sp6ab +.section sp6ba +.section sp6bb +.section sp6ca +.section sp6cb +.section sp6da +.section sp6db +.section sp6ea +.section sp6eb +.section sp6fa +.section sp6fb +.section sp6ga +.section sp6gb +.section sp6ha +.section sp6hb +.section sp6ia +.section sp6ib +.section sp6ja +.section sp6jb +.section sp6ka +.section sp6kb +.section sp6la +.section sp6lb +.section sp6ma +.section sp6mb +.section sp6na +.section sp6nb +.section sp6oa +.section sp6ob +.section sp6pa +.section sp6pb +.section sp6qa +.section sp6qb +.section sp6ra +.section sp6rb +.section sp6sa +.section sp6sb +.section sp6ta +.section sp6tb +.section sp6ua +.section sp6ub +.section sp6va +.section sp6vb +.section sp6wa +.section sp6wb +.section sp6xa +.section sp6xb +.section sp6ya +.section sp6yb +.section sp6za +.section sp6zb +.section sp61a +.section sp61b +.section sp62a +.section sp62b +.section sp63a +.section sp63b +.section sp64a +.section sp64b +.section sp65a +.section sp65b +.section sp66a +.section sp66b +.section sp67a +.section sp67b +.section sp68a +.section sp68b +.section sp69a +.section sp69b +.section sp60a +.section sp60b +.section sp7aa +.section sp7ab +.section sp7ba +.section sp7bb +.section sp7ca +.section sp7cb +.section sp7da +.section sp7db +.section sp7ea +.section sp7eb +.section sp7fa +.section sp7fb +.section sp7ga +.section sp7gb +.section sp7ha +.section sp7hb +.section sp7ia +.section sp7ib +.section sp7ja +.section sp7jb +.section sp7ka +.section sp7kb +.section sp7la +.section sp7lb +.section sp7ma +.section sp7mb +.section sp7na +.section sp7nb +.section sp7oa +.section sp7ob +.section sp7pa +.section sp7pb +.section sp7qa +.section sp7qb +.section sp7ra +.section sp7rb +.section sp7sa +.section sp7sb +.section sp7ta +.section sp7tb +.section sp7ua +.section sp7ub +.section sp7va +.section sp7vb +.section sp7wa +.section sp7wb +.section sp7xa +.section sp7xb +.section sp7ya +.section sp7yb +.section sp7za +.section sp7zb +.section sp71a +.section sp71b +.section sp72a +.section sp72b +.section sp73a +.section sp73b +.section sp74a +.section sp74b +.section sp75a +.section sp75b +.section sp76a +.section sp76b +.section sp77a +.section sp77b +.section sp78a +.section sp78b +.section sp79a +.section sp79b +.section sp70a +.section sp70b +.section sp8aa +.section sp8ab +.section sp8ba +.section sp8bb +.section sp8ca +.section sp8cb +.section sp8da +.section sp8db +.section sp8ea +.section sp8eb +.section sp8fa +.section sp8fb +.section sp8ga +.section sp8gb +.section sp8ha +.section sp8hb +.section sp8ia +.section sp8ib +.section sp8ja +.section sp8jb +.section sp8ka +.section sp8kb +.section sp8la +.section sp8lb +.section sp8ma +.section sp8mb +.section sp8na +.section sp8nb +.section sp8oa +.section sp8ob +.section sp8pa +.section sp8pb +.section sp8qa +.section sp8qb +.section sp8ra +.section sp8rb +.section sp8sa +.section sp8sb +.section sp8ta +.section sp8tb +.section sp8ua +.section sp8ub +.section sp8va +.section sp8vb +.section sp8wa +.section sp8wb +.section sp8xa +.section sp8xb +.section sp8ya +.section sp8yb +.section sp8za +.section sp8zb +.section sp81a +.section sp81b +.section sp82a +.section sp82b +.section sp83a +.section sp83b +.section sp84a +.section sp84b +.section sp85a +.section sp85b +.section sp86a +.section sp86b +.section sp87a +.section sp87b +.section sp88a +.section sp88b +.section sp89a +.section sp89b +.section sp80a +.section sp80b +.section sp9aa +.section sp9ab +.section sp9ba +.section sp9bb +.section sp9ca +.section sp9cb +.section sp9da +.section sp9db +.section sp9ea +.section sp9eb +.section sp9fa +.section sp9fb +.section sp9ga +.section sp9gb +.section sp9ha +.section sp9hb +.section sp9ia +.section sp9ib +.section sp9ja +.section sp9jb +.section sp9ka +.section sp9kb +.section sp9la +.section sp9lb +.section sp9ma +.section sp9mb +.section sp9na +.section sp9nb +.section sp9oa +.section sp9ob +.section sp9pa +.section sp9pb +.section sp9qa +.section sp9qb +.section sp9ra +.section sp9rb +.section sp9sa +.section sp9sb +.section sp9ta +.section sp9tb +.section sp9ua +.section sp9ub +.section sp9va +.section sp9vb +.section sp9wa +.section sp9wb +.section sp9xa +.section sp9xb +.section sp9ya +.section sp9yb +.section sp9za +.section sp9zb +.section sp91a +.section sp91b +.section sp92a +.section sp92b +.section sp93a +.section sp93b +.section sp94a +.section sp94b +.section sp95a +.section sp95b +.section sp96a +.section sp96b +.section sp97a +.section sp97b +.section sp98a +.section sp98b +.section sp99a +.section sp99b +.section sp90a +.section sp90b +.section sp0aa +.section sp0ab +.section sp0ba +.section sp0bb +.section sp0ca +.section sp0cb +.section sp0da +.section sp0db +.section sp0ea +.section sp0eb +.section sp0fa +.section sp0fb +.section sp0ga +.section sp0gb +.section sp0ha +.section sp0hb +.section sp0ia +.section sp0ib +.section sp0ja +.section sp0jb +.section sp0ka +.section sp0kb +.section sp0la +.section sp0lb +.section sp0ma +.section sp0mb +.section sp0na +.section sp0nb +.section sp0oa +.section sp0ob +.section sp0pa +.section sp0pb +.section sp0qa +.section sp0qb +.section sp0ra +.section sp0rb +.section sp0sa +.section sp0sb +.section sp0ta +.section sp0tb +.section sp0ua +.section sp0ub +.section sp0va +.section sp0vb +.section sp0wa +.section sp0wb +.section sp0xa +.section sp0xb +.section sp0ya +.section sp0yb +.section sp0za +.section sp0zb +.section sp01a +.section sp01b +.section sp02a +.section sp02b +.section sp03a +.section sp03b +.section sp04a +.section sp04b +.section sp05a +.section sp05b +.section sp06a +.section sp06b +.section sp07a +.section sp07b +.section sp08a +.section sp08b +.section sp09a +.section sp09b +.section sp00a +.section sp00b +.section sqaaa +.section sqaab +.section sqaba +.section sqabb +.section sqaca +.section sqacb +.section sqada +.section sqadb +.section sqaea +.section sqaeb +.section sqafa +.section sqafb +.section sqaga +.section sqagb +.section sqaha +.section sqahb +.section sqaia +.section sqaib +.section sqaja +.section sqajb +.section sqaka +.section sqakb +.section sqala +.section sqalb +.section sqama +.section sqamb +.section sqana +.section sqanb +.section sqaoa +.section sqaob +.section sqapa +.section sqapb +.section sqaqa +.section sqaqb +.section sqara +.section sqarb +.section sqasa +.section sqasb +.section sqata +.section sqatb +.section sqaua +.section sqaub +.section sqava +.section sqavb +.section sqawa +.section sqawb +.section sqaxa +.section sqaxb +.section sqaya +.section sqayb +.section sqaza +.section sqazb +.section sqa1a +.section sqa1b +.section sqa2a +.section sqa2b +.section sqa3a +.section sqa3b +.section sqa4a +.section sqa4b +.section sqa5a +.section sqa5b +.section sqa6a +.section sqa6b +.section sqa7a +.section sqa7b +.section sqa8a +.section sqa8b +.section sqa9a +.section sqa9b +.section sqa0a +.section sqa0b +.section sqbaa +.section sqbab +.section sqbba +.section sqbbb +.section sqbca +.section sqbcb +.section sqbda +.section sqbdb +.section sqbea +.section sqbeb +.section sqbfa +.section sqbfb +.section sqbga +.section sqbgb +.section sqbha +.section sqbhb +.section sqbia +.section sqbib +.section sqbja +.section sqbjb +.section sqbka +.section sqbkb +.section sqbla +.section sqblb +.section sqbma +.section sqbmb +.section sqbna +.section sqbnb +.section sqboa +.section sqbob +.section sqbpa +.section sqbpb +.section sqbqa +.section sqbqb +.section sqbra +.section sqbrb +.section sqbsa +.section sqbsb +.section sqbta +.section sqbtb +.section sqbua +.section sqbub +.section sqbva +.section sqbvb +.section sqbwa +.section sqbwb +.section sqbxa +.section sqbxb +.section sqbya +.section sqbyb +.section sqbza +.section sqbzb +.section sqb1a +.section sqb1b +.section sqb2a +.section sqb2b +.section sqb3a +.section sqb3b +.section sqb4a +.section sqb4b +.section sqb5a +.section sqb5b +.section sqb6a +.section sqb6b +.section sqb7a +.section sqb7b +.section sqb8a +.section sqb8b +.section sqb9a +.section sqb9b +.section sqb0a +.section sqb0b +.section sqcaa +.section sqcab +.section sqcba +.section sqcbb +.section sqcca +.section sqccb +.section sqcda +.section sqcdb +.section sqcea +.section sqceb +.section sqcfa +.section sqcfb +.section sqcga +.section sqcgb +.section sqcha +.section sqchb +.section sqcia +.section sqcib +.section sqcja +.section sqcjb +.section sqcka +.section sqckb +.section sqcla +.section sqclb +.section sqcma +.section sqcmb +.section sqcna +.section sqcnb +.section sqcoa +.section sqcob +.section sqcpa +.section sqcpb +.section sqcqa +.section sqcqb +.section sqcra +.section sqcrb +.section sqcsa +.section sqcsb +.section sqcta +.section sqctb +.section sqcua +.section sqcub +.section sqcva +.section sqcvb +.section sqcwa +.section sqcwb +.section sqcxa +.section sqcxb +.section sqcya +.section sqcyb +.section sqcza +.section sqczb +.section sqc1a +.section sqc1b +.section sqc2a +.section sqc2b +.section sqc3a +.section sqc3b +.section sqc4a +.section sqc4b +.section sqc5a +.section sqc5b +.section sqc6a +.section sqc6b +.section sqc7a +.section sqc7b +.section sqc8a +.section sqc8b +.section sqc9a +.section sqc9b +.section sqc0a +.section sqc0b +.section sqdaa +.section sqdab +.section sqdba +.section sqdbb +.section sqdca +.section sqdcb +.section sqdda +.section sqddb +.section sqdea +.section sqdeb +.section sqdfa +.section sqdfb +.section sqdga +.section sqdgb +.section sqdha +.section sqdhb +.section sqdia +.section sqdib +.section sqdja +.section sqdjb +.section sqdka +.section sqdkb +.section sqdla +.section sqdlb +.section sqdma +.section sqdmb +.section sqdna +.section sqdnb +.section sqdoa +.section sqdob +.section sqdpa +.section sqdpb +.section sqdqa +.section sqdqb +.section sqdra +.section sqdrb +.section sqdsa +.section sqdsb +.section sqdta +.section sqdtb +.section sqdua +.section sqdub +.section sqdva +.section sqdvb +.section sqdwa +.section sqdwb +.section sqdxa +.section sqdxb +.section sqdya +.section sqdyb +.section sqdza +.section sqdzb +.section sqd1a +.section sqd1b +.section sqd2a +.section sqd2b +.section sqd3a +.section sqd3b +.section sqd4a +.section sqd4b +.section sqd5a +.section sqd5b +.section sqd6a +.section sqd6b +.section sqd7a +.section sqd7b +.section sqd8a +.section sqd8b +.section sqd9a +.section sqd9b +.section sqd0a +.section sqd0b +.section sqeaa +.section sqeab +.section sqeba +.section sqebb +.section sqeca +.section sqecb +.section sqeda +.section sqedb +.section sqeea +.section sqeeb +.section sqefa +.section sqefb +.section sqega +.section sqegb +.section sqeha +.section sqehb +.section sqeia +.section sqeib +.section sqeja +.section sqejb +.section sqeka +.section sqekb +.section sqela +.section sqelb +.section sqema +.section sqemb +.section sqena +.section sqenb +.section sqeoa +.section sqeob +.section sqepa +.section sqepb +.section sqeqa +.section sqeqb +.section sqera +.section sqerb +.section sqesa +.section sqesb +.section sqeta +.section sqetb +.section sqeua +.section sqeub +.section sqeva +.section sqevb +.section sqewa +.section sqewb +.section sqexa +.section sqexb +.section sqeya +.section sqeyb +.section sqeza +.section sqezb +.section sqe1a +.section sqe1b +.section sqe2a +.section sqe2b +.section sqe3a +.section sqe3b +.section sqe4a +.section sqe4b +.section sqe5a +.section sqe5b +.section sqe6a +.section sqe6b +.section sqe7a +.section sqe7b +.section sqe8a +.section sqe8b +.section sqe9a +.section sqe9b +.section sqe0a +.section sqe0b +.section sqfaa +.section sqfab +.section sqfba +.section sqfbb +.section sqfca +.section sqfcb +.section sqfda +.section sqfdb +.section sqfea +.section sqfeb +.section sqffa +.section sqffb +.section sqfga +.section sqfgb +.section sqfha +.section sqfhb +.section sqfia +.section sqfib +.section sqfja +.section sqfjb +.section sqfka +.section sqfkb +.section sqfla +.section sqflb +.section sqfma +.section sqfmb +.section sqfna +.section sqfnb +.section sqfoa +.section sqfob +.section sqfpa +.section sqfpb +.section sqfqa +.section sqfqb +.section sqfra +.section sqfrb +.section sqfsa +.section sqfsb +.section sqfta +.section sqftb +.section sqfua +.section sqfub +.section sqfva +.section sqfvb +.section sqfwa +.section sqfwb +.section sqfxa +.section sqfxb +.section sqfya +.section sqfyb +.section sqfza +.section sqfzb +.section sqf1a +.section sqf1b +.section sqf2a +.section sqf2b +.section sqf3a +.section sqf3b +.section sqf4a +.section sqf4b +.section sqf5a +.section sqf5b +.section sqf6a +.section sqf6b +.section sqf7a +.section sqf7b +.section sqf8a +.section sqf8b +.section sqf9a +.section sqf9b +.section sqf0a +.section sqf0b +.section sqgaa +.section sqgab +.section sqgba +.section sqgbb +.section sqgca +.section sqgcb +.section sqgda +.section sqgdb +.section sqgea +.section sqgeb +.section sqgfa +.section sqgfb +.section sqgga +.section sqggb +.section sqgha +.section sqghb +.section sqgia +.section sqgib +.section sqgja +.section sqgjb +.section sqgka +.section sqgkb +.section sqgla +.section sqglb +.section sqgma +.section sqgmb +.section sqgna +.section sqgnb +.section sqgoa +.section sqgob +.section sqgpa +.section sqgpb +.section sqgqa +.section sqgqb +.section sqgra +.section sqgrb +.section sqgsa +.section sqgsb +.section sqgta +.section sqgtb +.section sqgua +.section sqgub +.section sqgva +.section sqgvb +.section sqgwa +.section sqgwb +.section sqgxa +.section sqgxb +.section sqgya +.section sqgyb +.section sqgza +.section sqgzb +.section sqg1a +.section sqg1b +.section sqg2a +.section sqg2b +.section sqg3a +.section sqg3b +.section sqg4a +.section sqg4b +.section sqg5a +.section sqg5b +.section sqg6a +.section sqg6b +.section sqg7a +.section sqg7b +.section sqg8a +.section sqg8b +.section sqg9a +.section sqg9b +.section sqg0a +.section sqg0b +.section sqhaa +.section sqhab +.section sqhba +.section sqhbb +.section sqhca +.section sqhcb +.section sqhda +.section sqhdb +.section sqhea +.section sqheb +.section sqhfa +.section sqhfb +.section sqhga +.section sqhgb +.section sqhha +.section sqhhb +.section sqhia +.section sqhib +.section sqhja +.section sqhjb +.section sqhka +.section sqhkb +.section sqhla +.section sqhlb +.section sqhma +.section sqhmb +.section sqhna +.section sqhnb +.section sqhoa +.section sqhob +.section sqhpa +.section sqhpb +.section sqhqa +.section sqhqb +.section sqhra +.section sqhrb +.section sqhsa +.section sqhsb +.section sqhta +.section sqhtb +.section sqhua +.section sqhub +.section sqhva +.section sqhvb +.section sqhwa +.section sqhwb +.section sqhxa +.section sqhxb +.section sqhya +.section sqhyb +.section sqhza +.section sqhzb +.section sqh1a +.section sqh1b +.section sqh2a +.section sqh2b +.section sqh3a +.section sqh3b +.section sqh4a +.section sqh4b +.section sqh5a +.section sqh5b +.section sqh6a +.section sqh6b +.section sqh7a +.section sqh7b +.section sqh8a +.section sqh8b +.section sqh9a +.section sqh9b +.section sqh0a +.section sqh0b +.section sqiaa +.section sqiab +.section sqiba +.section sqibb +.section sqica +.section sqicb +.section sqida +.section sqidb +.section sqiea +.section sqieb +.section sqifa +.section sqifb +.section sqiga +.section sqigb +.section sqiha +.section sqihb +.section sqiia +.section sqiib +.section sqija +.section sqijb +.section sqika +.section sqikb +.section sqila +.section sqilb +.section sqima +.section sqimb +.section sqina +.section sqinb +.section sqioa +.section sqiob +.section sqipa +.section sqipb +.section sqiqa +.section sqiqb +.section sqira +.section sqirb +.section sqisa +.section sqisb +.section sqita +.section sqitb +.section sqiua +.section sqiub +.section sqiva +.section sqivb +.section sqiwa +.section sqiwb +.section sqixa +.section sqixb +.section sqiya +.section sqiyb +.section sqiza +.section sqizb +.section sqi1a +.section sqi1b +.section sqi2a +.section sqi2b +.section sqi3a +.section sqi3b +.section sqi4a +.section sqi4b +.section sqi5a +.section sqi5b +.section sqi6a +.section sqi6b +.section sqi7a +.section sqi7b +.section sqi8a +.section sqi8b +.section sqi9a +.section sqi9b +.section sqi0a +.section sqi0b +.section sqjaa +.section sqjab +.section sqjba +.section sqjbb +.section sqjca +.section sqjcb +.section sqjda +.section sqjdb +.section sqjea +.section sqjeb +.section sqjfa +.section sqjfb +.section sqjga +.section sqjgb +.section sqjha +.section sqjhb +.section sqjia +.section sqjib +.section sqjja +.section sqjjb +.section sqjka +.section sqjkb +.section sqjla +.section sqjlb +.section sqjma +.section sqjmb +.section sqjna +.section sqjnb +.section sqjoa +.section sqjob +.section sqjpa +.section sqjpb +.section sqjqa +.section sqjqb +.section sqjra +.section sqjrb +.section sqjsa +.section sqjsb +.section sqjta +.section sqjtb +.section sqjua +.section sqjub +.section sqjva +.section sqjvb +.section sqjwa +.section sqjwb +.section sqjxa +.section sqjxb +.section sqjya +.section sqjyb +.section sqjza +.section sqjzb +.section sqj1a +.section sqj1b +.section sqj2a +.section sqj2b +.section sqj3a +.section sqj3b +.section sqj4a +.section sqj4b +.section sqj5a +.section sqj5b +.section sqj6a +.section sqj6b +.section sqj7a +.section sqj7b +.section sqj8a +.section sqj8b +.section sqj9a +.section sqj9b +.section sqj0a +.section sqj0b +.section sqkaa +.section sqkab +.section sqkba +.section sqkbb +.section sqkca +.section sqkcb +.section sqkda +.section sqkdb +.section sqkea +.section sqkeb +.section sqkfa +.section sqkfb +.section sqkga +.section sqkgb +.section sqkha +.section sqkhb +.section sqkia +.section sqkib +.section sqkja +.section sqkjb +.section sqkka +.section sqkkb +.section sqkla +.section sqklb +.section sqkma +.section sqkmb +.section sqkna +.section sqknb +.section sqkoa +.section sqkob +.section sqkpa +.section sqkpb +.section sqkqa +.section sqkqb +.section sqkra +.section sqkrb +.section sqksa +.section sqksb +.section sqkta +.section sqktb +.section sqkua +.section sqkub +.section sqkva +.section sqkvb +.section sqkwa +.section sqkwb +.section sqkxa +.section sqkxb +.section sqkya +.section sqkyb +.section sqkza +.section sqkzb +.section sqk1a +.section sqk1b +.section sqk2a +.section sqk2b +.section sqk3a +.section sqk3b +.section sqk4a +.section sqk4b +.section sqk5a +.section sqk5b +.section sqk6a +.section sqk6b +.section sqk7a +.section sqk7b +.section sqk8a +.section sqk8b +.section sqk9a +.section sqk9b +.section sqk0a +.section sqk0b +.section sqlaa +.section sqlab +.section sqlba +.section sqlbb +.section sqlca +.section sqlcb +.section sqlda +.section sqldb +.section sqlea +.section sqleb +.section sqlfa +.section sqlfb +.section sqlga +.section sqlgb +.section sqlha +.section sqlhb +.section sqlia +.section sqlib +.section sqlja +.section sqljb +.section sqlka +.section sqlkb +.section sqlla +.section sqllb +.section sqlma +.section sqlmb +.section sqlna +.section sqlnb +.section sqloa +.section sqlob +.section sqlpa +.section sqlpb +.section sqlqa +.section sqlqb +.section sqlra +.section sqlrb +.section sqlsa +.section sqlsb +.section sqlta +.section sqltb +.section sqlua +.section sqlub +.section sqlva +.section sqlvb +.section sqlwa +.section sqlwb +.section sqlxa +.section sqlxb +.section sqlya +.section sqlyb +.section sqlza +.section sqlzb +.section sql1a +.section sql1b +.section sql2a +.section sql2b +.section sql3a +.section sql3b +.section sql4a +.section sql4b +.section sql5a +.section sql5b +.section sql6a +.section sql6b +.section sql7a +.section sql7b +.section sql8a +.section sql8b +.section sql9a +.section sql9b +.section sql0a +.section sql0b +.section sqmaa +.section sqmab +.section sqmba +.section sqmbb +.section sqmca +.section sqmcb +.section sqmda +.section sqmdb +.section sqmea +.section sqmeb +.section sqmfa +.section sqmfb +.section sqmga +.section sqmgb +.section sqmha +.section sqmhb +.section sqmia +.section sqmib +.section sqmja +.section sqmjb +.section sqmka +.section sqmkb +.section sqmla +.section sqmlb +.section sqmma +.section sqmmb +.section sqmna +.section sqmnb +.section sqmoa +.section sqmob +.section sqmpa +.section sqmpb +.section sqmqa +.section sqmqb +.section sqmra +.section sqmrb +.section sqmsa +.section sqmsb +.section sqmta +.section sqmtb +.section sqmua +.section sqmub +.section sqmva +.section sqmvb +.section sqmwa +.section sqmwb +.section sqmxa +.section sqmxb +.section sqmya +.section sqmyb +.section sqmza +.section sqmzb +.section sqm1a +.section sqm1b +.section sqm2a +.section sqm2b +.section sqm3a +.section sqm3b +.section sqm4a +.section sqm4b +.section sqm5a +.section sqm5b +.section sqm6a +.section sqm6b +.section sqm7a +.section sqm7b +.section sqm8a +.section sqm8b +.section sqm9a +.section sqm9b +.section sqm0a +.section sqm0b +.section sqnaa +.section sqnab +.section sqnba +.section sqnbb +.section sqnca +.section sqncb +.section sqnda +.section sqndb +.section sqnea +.section sqneb +.section sqnfa +.section sqnfb +.section sqnga +.section sqngb +.section sqnha +.section sqnhb +.section sqnia +.section sqnib +.section sqnja +.section sqnjb +.section sqnka +.section sqnkb +.section sqnla +.section sqnlb +.section sqnma +.section sqnmb +.section sqnna +.section sqnnb +.section sqnoa +.section sqnob +.section sqnpa +.section sqnpb +.section sqnqa +.section sqnqb +.section sqnra +.section sqnrb +.section sqnsa +.section sqnsb +.section sqnta +.section sqntb +.section sqnua +.section sqnub +.section sqnva +.section sqnvb +.section sqnwa +.section sqnwb +.section sqnxa +.section sqnxb +.section sqnya +.section sqnyb +.section sqnza +.section sqnzb +.section sqn1a +.section sqn1b +.section sqn2a +.section sqn2b +.section sqn3a +.section sqn3b +.section sqn4a +.section sqn4b +.section sqn5a +.section sqn5b +.section sqn6a +.section sqn6b +.section sqn7a +.section sqn7b +.section sqn8a +.section sqn8b +.section sqn9a +.section sqn9b +.section sqn0a +.section sqn0b +.section sqoaa +.section sqoab +.section sqoba +.section sqobb +.section sqoca +.section sqocb +.section sqoda +.section sqodb +.section sqoea +.section sqoeb +.section sqofa +.section sqofb +.section sqoga +.section sqogb +.section sqoha +.section sqohb +.section sqoia +.section sqoib +.section sqoja +.section sqojb +.section sqoka +.section sqokb +.section sqola +.section sqolb +.section sqoma +.section sqomb +.section sqona +.section sqonb +.section sqooa +.section sqoob +.section sqopa +.section sqopb +.section sqoqa +.section sqoqb +.section sqora +.section sqorb +.section sqosa +.section sqosb +.section sqota +.section sqotb +.section sqoua +.section sqoub +.section sqova +.section sqovb +.section sqowa +.section sqowb +.section sqoxa +.section sqoxb +.section sqoya +.section sqoyb +.section sqoza +.section sqozb +.section sqo1a +.section sqo1b +.section sqo2a +.section sqo2b +.section sqo3a +.section sqo3b +.section sqo4a +.section sqo4b +.section sqo5a +.section sqo5b +.section sqo6a +.section sqo6b +.section sqo7a +.section sqo7b +.section sqo8a +.section sqo8b +.section sqo9a +.section sqo9b +.section sqo0a +.section sqo0b +.section sqpaa +.section sqpab +.section sqpba +.section sqpbb +.section sqpca +.section sqpcb +.section sqpda +.section sqpdb +.section sqpea +.section sqpeb +.section sqpfa +.section sqpfb +.section sqpga +.section sqpgb +.section sqpha +.section sqphb +.section sqpia +.section sqpib +.section sqpja +.section sqpjb +.section sqpka +.section sqpkb +.section sqpla +.section sqplb +.section sqpma +.section sqpmb +.section sqpna +.section sqpnb +.section sqpoa +.section sqpob +.section sqppa +.section sqppb +.section sqpqa +.section sqpqb +.section sqpra +.section sqprb +.section sqpsa +.section sqpsb +.section sqpta +.section sqptb +.section sqpua +.section sqpub +.section sqpva +.section sqpvb +.section sqpwa +.section sqpwb +.section sqpxa +.section sqpxb +.section sqpya +.section sqpyb +.section sqpza +.section sqpzb +.section sqp1a +.section sqp1b +.section sqp2a +.section sqp2b +.section sqp3a +.section sqp3b +.section sqp4a +.section sqp4b +.section sqp5a +.section sqp5b +.section sqp6a +.section sqp6b +.section sqp7a +.section sqp7b +.section sqp8a +.section sqp8b +.section sqp9a +.section sqp9b +.section sqp0a +.section sqp0b +.section sqqaa +.section sqqab +.section sqqba +.section sqqbb +.section sqqca +.section sqqcb +.section sqqda +.section sqqdb +.section sqqea +.section sqqeb +.section sqqfa +.section sqqfb +.section sqqga +.section sqqgb +.section sqqha +.section sqqhb +.section sqqia +.section sqqib +.section sqqja +.section sqqjb +.section sqqka +.section sqqkb +.section sqqla +.section sqqlb +.section sqqma +.section sqqmb +.section sqqna +.section sqqnb +.section sqqoa +.section sqqob +.section sqqpa +.section sqqpb +.section sqqqa +.section sqqqb +.section sqqra +.section sqqrb +.section sqqsa +.section sqqsb +.section sqqta +.section sqqtb +.section sqqua +.section sqqub +.section sqqva +.section sqqvb +.section sqqwa +.section sqqwb +.section sqqxa +.section sqqxb +.section sqqya +.section sqqyb +.section sqqza +.section sqqzb +.section sqq1a +.section sqq1b +.section sqq2a +.section sqq2b +.section sqq3a +.section sqq3b +.section sqq4a +.section sqq4b +.section sqq5a +.section sqq5b +.section sqq6a +.section sqq6b +.section sqq7a +.section sqq7b +.section sqq8a +.section sqq8b +.section sqq9a +.section sqq9b +.section sqq0a +.section sqq0b +.section sqraa +.section sqrab +.section sqrba +.section sqrbb +.section sqrca +.section sqrcb +.section sqrda +.section sqrdb +.section sqrea +.section sqreb +.section sqrfa +.section sqrfb +.section sqrga +.section sqrgb +.section sqrha +.section sqrhb +.section sqria +.section sqrib +.section sqrja +.section sqrjb +.section sqrka +.section sqrkb +.section sqrla +.section sqrlb +.section sqrma +.section sqrmb +.section sqrna +.section sqrnb +.section sqroa +.section sqrob +.section sqrpa +.section sqrpb +.section sqrqa +.section sqrqb +.section sqrra +.section sqrrb +.section sqrsa +.section sqrsb +.section sqrta +.section sqrtb +.section sqrua +.section sqrub +.section sqrva +.section sqrvb +.section sqrwa +.section sqrwb +.section sqrxa +.section sqrxb +.section sqrya +.section sqryb +.section sqrza +.section sqrzb +.section sqr1a +.section sqr1b +.section sqr2a +.section sqr2b +.section sqr3a +.section sqr3b +.section sqr4a +.section sqr4b +.section sqr5a +.section sqr5b +.section sqr6a +.section sqr6b +.section sqr7a +.section sqr7b +.section sqr8a +.section sqr8b +.section sqr9a +.section sqr9b +.section sqr0a +.section sqr0b +.section sqsaa +.section sqsab +.section sqsba +.section sqsbb +.section sqsca +.section sqscb +.section sqsda +.section sqsdb +.section sqsea +.section sqseb +.section sqsfa +.section sqsfb +.section sqsga +.section sqsgb +.section sqsha +.section sqshb +.section sqsia +.section sqsib +.section sqsja +.section sqsjb +.section sqska +.section sqskb +.section sqsla +.section sqslb +.section sqsma +.section sqsmb +.section sqsna +.section sqsnb +.section sqsoa +.section sqsob +.section sqspa +.section sqspb +.section sqsqa +.section sqsqb +.section sqsra +.section sqsrb +.section sqssa +.section sqssb +.section sqsta +.section sqstb +.section sqsua +.section sqsub +.section sqsva +.section sqsvb +.section sqswa +.section sqswb +.section sqsxa +.section sqsxb +.section sqsya +.section sqsyb +.section sqsza +.section sqszb +.section sqs1a +.section sqs1b +.section sqs2a +.section sqs2b +.section sqs3a +.section sqs3b +.section sqs4a +.section sqs4b +.section sqs5a +.section sqs5b +.section sqs6a +.section sqs6b +.section sqs7a +.section sqs7b +.section sqs8a +.section sqs8b +.section sqs9a +.section sqs9b +.section sqs0a +.section sqs0b +.section sqtaa +.section sqtab +.section sqtba +.section sqtbb +.section sqtca +.section sqtcb +.section sqtda +.section sqtdb +.section sqtea +.section sqteb +.section sqtfa +.section sqtfb +.section sqtga +.section sqtgb +.section sqtha +.section sqthb +.section sqtia +.section sqtib +.section sqtja +.section sqtjb +.section sqtka +.section sqtkb +.section sqtla +.section sqtlb +.section sqtma +.section sqtmb +.section sqtna +.section sqtnb +.section sqtoa +.section sqtob +.section sqtpa +.section sqtpb +.section sqtqa +.section sqtqb +.section sqtra +.section sqtrb +.section sqtsa +.section sqtsb +.section sqtta +.section sqttb +.section sqtua +.section sqtub +.section sqtva +.section sqtvb +.section sqtwa +.section sqtwb +.section sqtxa +.section sqtxb +.section sqtya +.section sqtyb +.section sqtza +.section sqtzb +.section sqt1a +.section sqt1b +.section sqt2a +.section sqt2b +.section sqt3a +.section sqt3b +.section sqt4a +.section sqt4b +.section sqt5a +.section sqt5b +.section sqt6a +.section sqt6b +.section sqt7a +.section sqt7b +.section sqt8a +.section sqt8b +.section sqt9a +.section sqt9b +.section sqt0a +.section sqt0b +.section squaa +.section squab +.section squba +.section squbb +.section squca +.section squcb +.section squda +.section squdb +.section squea +.section squeb +.section squfa +.section squfb +.section squga +.section squgb +.section squha +.section squhb +.section squia +.section squib +.section squja +.section squjb +.section squka +.section squkb +.section squla +.section squlb +.section squma +.section squmb +.section squna +.section squnb +.section squoa +.section squob +.section squpa +.section squpb +.section squqa +.section squqb +.section squra +.section squrb +.section squsa +.section squsb +.section squta +.section squtb +.section squua +.section squub +.section squva +.section squvb +.section squwa +.section squwb +.section squxa +.section squxb +.section squya +.section squyb +.section squza +.section squzb +.section squ1a +.section squ1b +.section squ2a +.section squ2b +.section squ3a +.section squ3b +.section squ4a +.section squ4b +.section squ5a +.section squ5b +.section squ6a +.section squ6b +.section squ7a +.section squ7b +.section squ8a +.section squ8b +.section squ9a +.section squ9b +.section squ0a +.section squ0b +.section sqvaa +.section sqvab +.section sqvba +.section sqvbb +.section sqvca +.section sqvcb +.section sqvda +.section sqvdb +.section sqvea +.section sqveb +.section sqvfa +.section sqvfb +.section sqvga +.section sqvgb +.section sqvha +.section sqvhb +.section sqvia +.section sqvib +.section sqvja +.section sqvjb +.section sqvka +.section sqvkb +.section sqvla +.section sqvlb +.section sqvma +.section sqvmb +.section sqvna +.section sqvnb +.section sqvoa +.section sqvob +.section sqvpa +.section sqvpb +.section sqvqa +.section sqvqb +.section sqvra +.section sqvrb +.section sqvsa +.section sqvsb +.section sqvta +.section sqvtb +.section sqvua +.section sqvub +.section sqvva +.section sqvvb +.section sqvwa +.section sqvwb +.section sqvxa +.section sqvxb +.section sqvya +.section sqvyb +.section sqvza +.section sqvzb +.section sqv1a +.section sqv1b +.section sqv2a +.section sqv2b +.section sqv3a +.section sqv3b +.section sqv4a +.section sqv4b +.section sqv5a +.section sqv5b +.section sqv6a +.section sqv6b +.section sqv7a +.section sqv7b +.section sqv8a +.section sqv8b +.section sqv9a +.section sqv9b +.section sqv0a +.section sqv0b +.section sqwaa +.section sqwab +.section sqwba +.section sqwbb +.section sqwca +.section sqwcb +.section sqwda +.section sqwdb +.section sqwea +.section sqweb +.section sqwfa +.section sqwfb +.section sqwga +.section sqwgb +.section sqwha +.section sqwhb +.section sqwia +.section sqwib +.section sqwja +.section sqwjb +.section sqwka +.section sqwkb +.section sqwla +.section sqwlb +.section sqwma +.section sqwmb +.section sqwna +.section sqwnb +.section sqwoa +.section sqwob +.section sqwpa +.section sqwpb +.section sqwqa +.section sqwqb +.section sqwra +.section sqwrb +.section sqwsa +.section sqwsb +.section sqwta +.section sqwtb +.section sqwua +.section sqwub +.section sqwva +.section sqwvb +.section sqwwa +.section sqwwb +.section sqwxa +.section sqwxb +.section sqwya +.section sqwyb +.section sqwza +.section sqwzb +.section sqw1a +.section sqw1b +.section sqw2a +.section sqw2b +.section sqw3a +.section sqw3b +.section sqw4a +.section sqw4b +.section sqw5a +.section sqw5b +.section sqw6a +.section sqw6b +.section sqw7a +.section sqw7b +.section sqw8a +.section sqw8b +.section sqw9a +.section sqw9b +.section sqw0a +.section sqw0b +.section sqxaa +.section sqxab +.section sqxba +.section sqxbb +.section sqxca +.section sqxcb +.section sqxda +.section sqxdb +.section sqxea +.section sqxeb +.section sqxfa +.section sqxfb +.section sqxga +.section sqxgb +.section sqxha +.section sqxhb +.section sqxia +.section sqxib +.section sqxja +.section sqxjb +.section sqxka +.section sqxkb +.section sqxla +.section sqxlb +.section sqxma +.section sqxmb +.section sqxna +.section sqxnb +.section sqxoa +.section sqxob +.section sqxpa +.section sqxpb +.section sqxqa +.section sqxqb +.section sqxra +.section sqxrb +.section sqxsa +.section sqxsb +.section sqxta +.section sqxtb +.section sqxua +.section sqxub +.section sqxva +.section sqxvb +.section sqxwa +.section sqxwb +.section sqxxa +.section sqxxb +.section sqxya +.section sqxyb +.section sqxza +.section sqxzb +.section sqx1a +.section sqx1b +.section sqx2a +.section sqx2b +.section sqx3a +.section sqx3b +.section sqx4a +.section sqx4b +.section sqx5a +.section sqx5b +.section sqx6a +.section sqx6b +.section sqx7a +.section sqx7b +.section sqx8a +.section sqx8b +.section sqx9a +.section sqx9b +.section sqx0a +.section sqx0b +.section sqyaa +.section sqyab +.section sqyba +.section sqybb +.section sqyca +.section sqycb +.section sqyda +.section sqydb +.section sqyea +.section sqyeb +.section sqyfa +.section sqyfb +.section sqyga +.section sqygb +.section sqyha +.section sqyhb +.section sqyia +.section sqyib +.section sqyja +.section sqyjb +.section sqyka +.section sqykb +.section sqyla +.section sqylb +.section sqyma +.section sqymb +.section sqyna +.section sqynb +.section sqyoa +.section sqyob +.section sqypa +.section sqypb +.section sqyqa +.section sqyqb +.section sqyra +.section sqyrb +.section sqysa +.section sqysb +.section sqyta +.section sqytb +.section sqyua +.section sqyub +.section sqyva +.section sqyvb +.section sqywa +.section sqywb +.section sqyxa +.section sqyxb +.section sqyya +.section sqyyb +.section sqyza +.section sqyzb +.section sqy1a +.section sqy1b +.section sqy2a +.section sqy2b +.section sqy3a +.section sqy3b +.section sqy4a +.section sqy4b +.section sqy5a +.section sqy5b +.section sqy6a +.section sqy6b +.section sqy7a +.section sqy7b +.section sqy8a +.section sqy8b +.section sqy9a +.section sqy9b +.section sqy0a +.section sqy0b +.section sqzaa +.section sqzab +.section sqzba +.section sqzbb +.section sqzca +.section sqzcb +.section sqzda +.section sqzdb +.section sqzea +.section sqzeb +.section sqzfa +.section sqzfb +.section sqzga +.section sqzgb +.section sqzha +.section sqzhb +.section sqzia +.section sqzib +.section sqzja +.section sqzjb +.section sqzka +.section sqzkb +.section sqzla +.section sqzlb +.section sqzma +.section sqzmb +.section sqzna +.section sqznb +.section sqzoa +.section sqzob +.section sqzpa +.section sqzpb +.section sqzqa +.section sqzqb +.section sqzra +.section sqzrb +.section sqzsa +.section sqzsb +.section sqzta +.section sqztb +.section sqzua +.section sqzub +.section sqzva +.section sqzvb +.section sqzwa +.section sqzwb +.section sqzxa +.section sqzxb +.section sqzya +.section sqzyb +.section sqzza +.section sqzzb +.section sqz1a +.section sqz1b +.section sqz2a +.section sqz2b +.section sqz3a +.section sqz3b +.section sqz4a +.section sqz4b +.section sqz5a +.section sqz5b +.section sqz6a +.section sqz6b +.section sqz7a +.section sqz7b +.section sqz8a +.section sqz8b +.section sqz9a +.section sqz9b +.section sqz0a +.section sqz0b +.section sq1aa +.section sq1ab +.section sq1ba +.section sq1bb +.section sq1ca +.section sq1cb +.section sq1da +.section sq1db +.section sq1ea +.section sq1eb +.section sq1fa +.section sq1fb +.section sq1ga +.section sq1gb +.section sq1ha +.section sq1hb +.section sq1ia +.section sq1ib +.section sq1ja +.section sq1jb +.section sq1ka +.section sq1kb +.section sq1la +.section sq1lb +.section sq1ma +.section sq1mb +.section sq1na +.section sq1nb +.section sq1oa +.section sq1ob +.section sq1pa +.section sq1pb +.section sq1qa +.section sq1qb +.section sq1ra +.section sq1rb +.section sq1sa +.section sq1sb +.section sq1ta +.section sq1tb +.section sq1ua +.section sq1ub +.section sq1va +.section sq1vb +.section sq1wa +.section sq1wb +.section sq1xa +.section sq1xb +.section sq1ya +.section sq1yb +.section sq1za +.section sq1zb +.section sq11a +.section sq11b +.section sq12a +.section sq12b +.section sq13a +.section sq13b +.section sq14a +.section sq14b +.section sq15a +.section sq15b +.section sq16a +.section sq16b +.section sq17a +.section sq17b +.section sq18a +.section sq18b +.section sq19a +.section sq19b +.section sq10a +.section sq10b +.section sq2aa +.section sq2ab +.section sq2ba +.section sq2bb +.section sq2ca +.section sq2cb +.section sq2da +.section sq2db +.section sq2ea +.section sq2eb +.section sq2fa +.section sq2fb +.section sq2ga +.section sq2gb +.section sq2ha +.section sq2hb +.section sq2ia +.section sq2ib +.section sq2ja +.section sq2jb +.section sq2ka +.section sq2kb +.section sq2la +.section sq2lb +.section sq2ma +.section sq2mb +.section sq2na +.section sq2nb +.section sq2oa +.section sq2ob +.section sq2pa +.section sq2pb +.section sq2qa +.section sq2qb +.section sq2ra +.section sq2rb +.section sq2sa +.section sq2sb +.section sq2ta +.section sq2tb +.section sq2ua +.section sq2ub +.section sq2va +.section sq2vb +.section sq2wa +.section sq2wb +.section sq2xa +.section sq2xb +.section sq2ya +.section sq2yb +.section sq2za +.section sq2zb +.section sq21a +.section sq21b +.section sq22a +.section sq22b +.section sq23a +.section sq23b +.section sq24a +.section sq24b +.section sq25a +.section sq25b +.section sq26a +.section sq26b +.section sq27a +.section sq27b +.section sq28a +.section sq28b +.section sq29a +.section sq29b +.section sq20a +.section sq20b +.section sq3aa +.section sq3ab +.section sq3ba +.section sq3bb +.section sq3ca +.section sq3cb +.section sq3da +.section sq3db +.section sq3ea +.section sq3eb +.section sq3fa +.section sq3fb +.section sq3ga +.section sq3gb +.section sq3ha +.section sq3hb +.section sq3ia +.section sq3ib +.section sq3ja +.section sq3jb +.section sq3ka +.section sq3kb +.section sq3la +.section sq3lb +.section sq3ma +.section sq3mb +.section sq3na +.section sq3nb +.section sq3oa +.section sq3ob +.section sq3pa +.section sq3pb +.section sq3qa +.section sq3qb +.section sq3ra +.section sq3rb +.section sq3sa +.section sq3sb +.section sq3ta +.section sq3tb +.section sq3ua +.section sq3ub +.section sq3va +.section sq3vb +.section sq3wa +.section sq3wb +.section sq3xa +.section sq3xb +.section sq3ya +.section sq3yb +.section sq3za +.section sq3zb +.section sq31a +.section sq31b +.section sq32a +.section sq32b +.section sq33a +.section sq33b +.section sq34a +.section sq34b +.section sq35a +.section sq35b +.section sq36a +.section sq36b +.section sq37a +.section sq37b +.section sq38a +.section sq38b +.section sq39a +.section sq39b +.section sq30a +.section sq30b +.section sq4aa +.section sq4ab +.section sq4ba +.section sq4bb +.section sq4ca +.section sq4cb +.section sq4da +.section sq4db +.section sq4ea +.section sq4eb +.section sq4fa +.section sq4fb +.section sq4ga +.section sq4gb +.section sq4ha +.section sq4hb +.section sq4ia +.section sq4ib +.section sq4ja +.section sq4jb +.section sq4ka +.section sq4kb +.section sq4la +.section sq4lb +.section sq4ma +.section sq4mb +.section sq4na +.section sq4nb +.section sq4oa +.section sq4ob +.section sq4pa +.section sq4pb +.section sq4qa +.section sq4qb +.section sq4ra +.section sq4rb +.section sq4sa +.section sq4sb +.section sq4ta +.section sq4tb +.section sq4ua +.section sq4ub +.section sq4va +.section sq4vb +.section sq4wa +.section sq4wb +.section sq4xa +.section sq4xb +.section sq4ya +.section sq4yb +.section sq4za +.section sq4zb +.section sq41a +.section sq41b +.section sq42a +.section sq42b +.section sq43a +.section sq43b +.section sq44a +.section sq44b +.section sq45a +.section sq45b +.section sq46a +.section sq46b +.section sq47a +.section sq47b +.section sq48a +.section sq48b +.section sq49a +.section sq49b +.section sq40a +.section sq40b +.section sq5aa +.section sq5ab +.section sq5ba +.section sq5bb +.section sq5ca +.section sq5cb +.section sq5da +.section sq5db +.section sq5ea +.section sq5eb +.section sq5fa +.section sq5fb +.section sq5ga +.section sq5gb +.section sq5ha +.section sq5hb +.section sq5ia +.section sq5ib +.section sq5ja +.section sq5jb +.section sq5ka +.section sq5kb +.section sq5la +.section sq5lb +.section sq5ma +.section sq5mb +.section sq5na +.section sq5nb +.section sq5oa +.section sq5ob +.section sq5pa +.section sq5pb +.section sq5qa +.section sq5qb +.section sq5ra +.section sq5rb +.section sq5sa +.section sq5sb +.section sq5ta +.section sq5tb +.section sq5ua +.section sq5ub +.section sq5va +.section sq5vb +.section sq5wa +.section sq5wb +.section sq5xa +.section sq5xb +.section sq5ya +.section sq5yb +.section sq5za +.section sq5zb +.section sq51a +.section sq51b +.section sq52a +.section sq52b +.section sq53a +.section sq53b +.section sq54a +.section sq54b +.section sq55a +.section sq55b +.section sq56a +.section sq56b +.section sq57a +.section sq57b +.section sq58a +.section sq58b +.section sq59a +.section sq59b +.section sq50a +.section sq50b +.section sq6aa +.section sq6ab +.section sq6ba +.section sq6bb +.section sq6ca +.section sq6cb +.section sq6da +.section sq6db +.section sq6ea +.section sq6eb +.section sq6fa +.section sq6fb +.section sq6ga +.section sq6gb +.section sq6ha +.section sq6hb +.section sq6ia +.section sq6ib +.section sq6ja +.section sq6jb +.section sq6ka +.section sq6kb +.section sq6la +.section sq6lb +.section sq6ma +.section sq6mb +.section sq6na +.section sq6nb +.section sq6oa +.section sq6ob +.section sq6pa +.section sq6pb +.section sq6qa +.section sq6qb +.section sq6ra +.section sq6rb +.section sq6sa +.section sq6sb +.section sq6ta +.section sq6tb +.section sq6ua +.section sq6ub +.section sq6va +.section sq6vb +.section sq6wa +.section sq6wb +.section sq6xa +.section sq6xb +.section sq6ya +.section sq6yb +.section sq6za +.section sq6zb +.section sq61a +.section sq61b +.section sq62a +.section sq62b +.section sq63a +.section sq63b +.section sq64a +.section sq64b +.section sq65a +.section sq65b +.section sq66a +.section sq66b +.section sq67a +.section sq67b +.section sq68a +.section sq68b +.section sq69a +.section sq69b +.section sq60a +.section sq60b +.section sq7aa +.section sq7ab +.section sq7ba +.section sq7bb +.section sq7ca +.section sq7cb +.section sq7da +.section sq7db +.section sq7ea +.section sq7eb +.section sq7fa +.section sq7fb +.section sq7ga +.section sq7gb +.section sq7ha +.section sq7hb +.section sq7ia +.section sq7ib +.section sq7ja +.section sq7jb +.section sq7ka +.section sq7kb +.section sq7la +.section sq7lb +.section sq7ma +.section sq7mb +.section sq7na +.section sq7nb +.section sq7oa +.section sq7ob +.section sq7pa +.section sq7pb +.section sq7qa +.section sq7qb +.section sq7ra +.section sq7rb +.section sq7sa +.section sq7sb +.section sq7ta +.section sq7tb +.section sq7ua +.section sq7ub +.section sq7va +.section sq7vb +.section sq7wa +.section sq7wb +.section sq7xa +.section sq7xb +.section sq7ya +.section sq7yb +.section sq7za +.section sq7zb +.section sq71a +.section sq71b +.section sq72a +.section sq72b +.section sq73a +.section sq73b +.section sq74a +.section sq74b +.section sq75a +.section sq75b +.section sq76a +.section sq76b +.section sq77a +.section sq77b +.section sq78a +.section sq78b +.section sq79a +.section sq79b +.section sq70a +.section sq70b +.section sq8aa +.section sq8ab +.section sq8ba +.section sq8bb +.section sq8ca +.section sq8cb +.section sq8da +.section sq8db +.section sq8ea +.section sq8eb +.section sq8fa +.section sq8fb +.section sq8ga +.section sq8gb +.section sq8ha +.section sq8hb +.section sq8ia +.section sq8ib +.section sq8ja +.section sq8jb +.section sq8ka +.section sq8kb +.section sq8la +.section sq8lb +.section sq8ma +.section sq8mb +.section sq8na +.section sq8nb +.section sq8oa +.section sq8ob +.section sq8pa +.section sq8pb +.section sq8qa +.section sq8qb +.section sq8ra +.section sq8rb +.section sq8sa +.section sq8sb +.section sq8ta +.section sq8tb +.section sq8ua +.section sq8ub +.section sq8va +.section sq8vb +.section sq8wa +.section sq8wb +.section sq8xa +.section sq8xb +.section sq8ya +.section sq8yb +.section sq8za +.section sq8zb +.section sq81a +.section sq81b +.section sq82a +.section sq82b +.section sq83a +.section sq83b +.section sq84a +.section sq84b +.section sq85a +.section sq85b +.section sq86a +.section sq86b +.section sq87a +.section sq87b +.section sq88a +.section sq88b +.section sq89a +.section sq89b +.section sq80a +.section sq80b +.section sq9aa +.section sq9ab +.section sq9ba +.section sq9bb +.section sq9ca +.section sq9cb +.section sq9da +.section sq9db +.section sq9ea +.section sq9eb +.section sq9fa +.section sq9fb +.section sq9ga +.section sq9gb +.section sq9ha +.section sq9hb +.section sq9ia +.section sq9ib +.section sq9ja +.section sq9jb +.section sq9ka +.section sq9kb +.section sq9la +.section sq9lb +.section sq9ma +.section sq9mb +.section sq9na +.section sq9nb +.section sq9oa +.section sq9ob +.section sq9pa +.section sq9pb +.section sq9qa +.section sq9qb +.section sq9ra +.section sq9rb +.section sq9sa +.section sq9sb +.section sq9ta +.section sq9tb +.section sq9ua +.section sq9ub +.section sq9va +.section sq9vb +.section sq9wa +.section sq9wb +.section sq9xa +.section sq9xb +.section sq9ya +.section sq9yb +.section sq9za +.section sq9zb +.section sq91a +.section sq91b +.section sq92a +.section sq92b +.section sq93a +.section sq93b +.section sq94a +.section sq94b +.section sq95a +.section sq95b +.section sq96a +.section sq96b +.section sq97a +.section sq97b +.section sq98a +.section sq98b +.section sq99a +.section sq99b +.section sq90a +.section sq90b +.section sq0aa +.section sq0ab +.section sq0ba +.section sq0bb +.section sq0ca +.section sq0cb +.section sq0da +.section sq0db +.section sq0ea +.section sq0eb +.section sq0fa +.section sq0fb +.section sq0ga +.section sq0gb +.section sq0ha +.section sq0hb +.section sq0ia +.section sq0ib +.section sq0ja +.section sq0jb +.section sq0ka +.section sq0kb +.section sq0la +.section sq0lb +.section sq0ma +.section sq0mb +.section sq0na +.section sq0nb +.section sq0oa +.section sq0ob +.section sq0pa +.section sq0pb +.section sq0qa +.section sq0qb +.section sq0ra +.section sq0rb +.section sq0sa +.section sq0sb +.section sq0ta +.section sq0tb +.section sq0ua +.section sq0ub +.section sq0va +.section sq0vb +.section sq0wa +.section sq0wb +.section sq0xa +.section sq0xb +.section sq0ya +.section sq0yb +.section sq0za +.section sq0zb +.section sq01a +.section sq01b +.section sq02a +.section sq02b +.section sq03a +.section sq03b +.section sq04a +.section sq04b +.section sq05a +.section sq05b +.section sq06a +.section sq06b +.section sq07a +.section sq07b +.section sq08a +.section sq08b +.section sq09a +.section sq09b +.section sq00a +.section sq00b +.section sraaa +.section sraab +.section sraba +.section srabb +.section sraca +.section sracb +.section srada +.section sradb +.section sraea +.section sraeb +.section srafa +.section srafb +.section sraga +.section sragb +.section sraha +.section srahb +.section sraia +.section sraib +.section sraja +.section srajb +.section sraka +.section srakb +.section srala +.section sralb +.section srama +.section sramb +.section srana +.section sranb +.section sraoa +.section sraob +.section srapa +.section srapb +.section sraqa +.section sraqb +.section srara +.section srarb +.section srasa +.section srasb +.section srata +.section sratb +.section sraua +.section sraub +.section srava +.section sravb +.section srawa +.section srawb +.section sraxa +.section sraxb +.section sraya +.section srayb +.section sraza +.section srazb +.section sra1a +.section sra1b +.section sra2a +.section sra2b +.section sra3a +.section sra3b +.section sra4a +.section sra4b +.section sra5a +.section sra5b +.section sra6a +.section sra6b +.section sra7a +.section sra7b +.section sra8a +.section sra8b +.section sra9a +.section sra9b +.section sra0a +.section sra0b +.section srbaa +.section srbab +.section srbba +.section srbbb +.section srbca +.section srbcb +.section srbda +.section srbdb +.section srbea +.section srbeb +.section srbfa +.section srbfb +.section srbga +.section srbgb +.section srbha +.section srbhb +.section srbia +.section srbib +.section srbja +.section srbjb +.section srbka +.section srbkb +.section srbla +.section srblb +.section srbma +.section srbmb +.section srbna +.section srbnb +.section srboa +.section srbob +.section srbpa +.section srbpb +.section srbqa +.section srbqb +.section srbra +.section srbrb +.section srbsa +.section srbsb +.section srbta +.section srbtb +.section srbua +.section srbub +.section srbva +.section srbvb +.section srbwa +.section srbwb +.section srbxa +.section srbxb +.section srbya +.section srbyb +.section srbza +.section srbzb +.section srb1a +.section srb1b +.section srb2a +.section srb2b +.section srb3a +.section srb3b +.section srb4a +.section srb4b +.section srb5a +.section srb5b +.section srb6a +.section srb6b +.section srb7a +.section srb7b +.section srb8a +.section srb8b +.section srb9a +.section srb9b +.section srb0a +.section srb0b +.section srcaa +.section srcab +.section srcba +.section srcbb +.section srcca +.section srccb +.section srcda +.section srcdb +.section srcea +.section srceb +.section srcfa +.section srcfb +.section srcga +.section srcgb +.section srcha +.section srchb +.section srcia +.section srcib +.section srcja +.section srcjb +.section srcka +.section srckb +.section srcla +.section srclb +.section srcma +.section srcmb +.section srcna +.section srcnb +.section srcoa +.section srcob +.section srcpa +.section srcpb +.section srcqa +.section srcqb +.section srcra +.section srcrb +.section srcsa +.section srcsb +.section srcta +.section srctb +.section srcua +.section srcub +.section srcva +.section srcvb +.section srcwa +.section srcwb +.section srcxa +.section srcxb +.section srcya +.section srcyb +.section srcza +.section srczb +.section src1a +.section src1b +.section src2a +.section src2b +.section src3a +.section src3b +.section src4a +.section src4b +.section src5a +.section src5b +.section src6a +.section src6b +.section src7a +.section src7b +.section src8a +.section src8b +.section src9a +.section src9b +.section src0a +.section src0b +.section srdaa +.section srdab +.section srdba +.section srdbb +.section srdca +.section srdcb +.section srdda +.section srddb +.section srdea +.section srdeb +.section srdfa +.section srdfb +.section srdga +.section srdgb +.section srdha +.section srdhb +.section srdia +.section srdib +.section srdja +.section srdjb +.section srdka +.section srdkb +.section srdla +.section srdlb +.section srdma +.section srdmb +.section srdna +.section srdnb +.section srdoa +.section srdob +.section srdpa +.section srdpb +.section srdqa +.section srdqb +.section srdra +.section srdrb +.section srdsa +.section srdsb +.section srdta +.section srdtb +.section srdua +.section srdub +.section srdva +.section srdvb +.section srdwa +.section srdwb +.section srdxa +.section srdxb +.section srdya +.section srdyb +.section srdza +.section srdzb +.section srd1a +.section srd1b +.section srd2a +.section srd2b +.section srd3a +.section srd3b +.section srd4a +.section srd4b +.section srd5a +.section srd5b +.section srd6a +.section srd6b +.section srd7a +.section srd7b +.section srd8a +.section srd8b +.section srd9a +.section srd9b +.section srd0a +.section srd0b +.section sreaa +.section sreab +.section sreba +.section srebb +.section sreca +.section srecb +.section sreda +.section sredb +.section sreea +.section sreeb +.section srefa +.section srefb +.section srega +.section sregb +.section sreha +.section srehb +.section sreia +.section sreib +.section sreja +.section srejb +.section sreka +.section srekb +.section srela +.section srelb +.section srema +.section sremb +.section srena +.section srenb +.section sreoa +.section sreob +.section srepa +.section srepb +.section sreqa +.section sreqb +.section srera +.section srerb +.section sresa +.section sresb +.section sreta +.section sretb +.section sreua +.section sreub +.section sreva +.section srevb +.section srewa +.section srewb +.section srexa +.section srexb +.section sreya +.section sreyb +.section sreza +.section srezb +.section sre1a +.section sre1b +.section sre2a +.section sre2b +.section sre3a +.section sre3b +.section sre4a +.section sre4b +.section sre5a +.section sre5b +.section sre6a +.section sre6b +.section sre7a +.section sre7b +.section sre8a +.section sre8b +.section sre9a +.section sre9b +.section sre0a +.section sre0b +.section srfaa +.section srfab +.section srfba +.section srfbb +.section srfca +.section srfcb +.section srfda +.section srfdb +.section srfea +.section srfeb +.section srffa +.section srffb +.section srfga +.section srfgb +.section srfha +.section srfhb +.section srfia +.section srfib +.section srfja +.section srfjb +.section srfka +.section srfkb +.section srfla +.section srflb +.section srfma +.section srfmb +.section srfna +.section srfnb +.section srfoa +.section srfob +.section srfpa +.section srfpb +.section srfqa +.section srfqb +.section srfra +.section srfrb +.section srfsa +.section srfsb +.section srfta +.section srftb +.section srfua +.section srfub +.section srfva +.section srfvb +.section srfwa +.section srfwb +.section srfxa +.section srfxb +.section srfya +.section srfyb +.section srfza +.section srfzb +.section srf1a +.section srf1b +.section srf2a +.section srf2b +.section srf3a +.section srf3b +.section srf4a +.section srf4b +.section srf5a +.section srf5b +.section srf6a +.section srf6b +.section srf7a +.section srf7b +.section srf8a +.section srf8b +.section srf9a +.section srf9b +.section srf0a +.section srf0b +.section srgaa +.section srgab +.section srgba +.section srgbb +.section srgca +.section srgcb +.section srgda +.section srgdb +.section srgea +.section srgeb +.section srgfa +.section srgfb +.section srgga +.section srggb +.section srgha +.section srghb +.section srgia +.section srgib +.section srgja +.section srgjb +.section srgka +.section srgkb +.section srgla +.section srglb +.section srgma +.section srgmb +.section srgna +.section srgnb +.section srgoa +.section srgob +.section srgpa +.section srgpb +.section srgqa +.section srgqb +.section srgra +.section srgrb +.section srgsa +.section srgsb +.section srgta +.section srgtb +.section srgua +.section srgub +.section srgva +.section srgvb +.section srgwa +.section srgwb +.section srgxa +.section srgxb +.section srgya +.section srgyb +.section srgza +.section srgzb +.section srg1a +.section srg1b +.section srg2a +.section srg2b +.section srg3a +.section srg3b +.section srg4a +.section srg4b +.section srg5a +.section srg5b +.section srg6a +.section srg6b +.section srg7a +.section srg7b +.section srg8a +.section srg8b +.section srg9a +.section srg9b +.section srg0a +.section srg0b +.section srhaa +.section srhab +.section srhba +.section srhbb +.section srhca +.section srhcb +.section srhda +.section srhdb +.section srhea +.section srheb +.section srhfa +.section srhfb +.section srhga +.section srhgb +.section srhha +.section srhhb +.section srhia +.section srhib +.section srhja +.section srhjb +.section srhka +.section srhkb +.section srhla +.section srhlb +.section srhma +.section srhmb +.section srhna +.section srhnb +.section srhoa +.section srhob +.section srhpa +.section srhpb +.section srhqa +.section srhqb +.section srhra +.section srhrb +.section srhsa +.section srhsb +.section srhta +.section srhtb +.section srhua +.section srhub +.section srhva +.section srhvb +.section srhwa +.section srhwb +.section srhxa +.section srhxb +.section srhya +.section srhyb +.section srhza +.section srhzb +.section srh1a +.section srh1b +.section srh2a +.section srh2b +.section srh3a +.section srh3b +.section srh4a +.section srh4b +.section srh5a +.section srh5b +.section srh6a +.section srh6b +.section srh7a +.section srh7b +.section srh8a +.section srh8b +.section srh9a +.section srh9b +.section srh0a +.section srh0b +.section sriaa +.section sriab +.section sriba +.section sribb +.section srica +.section sricb +.section srida +.section sridb +.section sriea +.section srieb +.section srifa +.section srifb +.section sriga +.section srigb +.section sriha +.section srihb +.section sriia +.section sriib +.section srija +.section srijb +.section srika +.section srikb +.section srila +.section srilb +.section srima +.section srimb +.section srina +.section srinb +.section srioa +.section sriob +.section sripa +.section sripb +.section sriqa +.section sriqb +.section srira +.section srirb +.section srisa +.section srisb +.section srita +.section sritb +.section sriua +.section sriub +.section sriva +.section srivb +.section sriwa +.section sriwb +.section srixa +.section srixb +.section sriya +.section sriyb +.section sriza +.section srizb +.section sri1a +.section sri1b +.section sri2a +.section sri2b +.section sri3a +.section sri3b +.section sri4a +.section sri4b +.section sri5a +.section sri5b +.section sri6a +.section sri6b +.section sri7a +.section sri7b +.section sri8a +.section sri8b +.section sri9a +.section sri9b +.section sri0a +.section sri0b +.section srjaa +.section srjab +.section srjba +.section srjbb +.section srjca +.section srjcb +.section srjda +.section srjdb +.section srjea +.section srjeb +.section srjfa +.section srjfb +.section srjga +.section srjgb +.section srjha +.section srjhb +.section srjia +.section srjib +.section srjja +.section srjjb +.section srjka +.section srjkb +.section srjla +.section srjlb +.section srjma +.section srjmb +.section srjna +.section srjnb +.section srjoa +.section srjob +.section srjpa +.section srjpb +.section srjqa +.section srjqb +.section srjra +.section srjrb +.section srjsa +.section srjsb +.section srjta +.section srjtb +.section srjua +.section srjub +.section srjva +.section srjvb +.section srjwa +.section srjwb +.section srjxa +.section srjxb +.section srjya +.section srjyb +.section srjza +.section srjzb +.section srj1a +.section srj1b +.section srj2a +.section srj2b +.section srj3a +.section srj3b +.section srj4a +.section srj4b +.section srj5a +.section srj5b +.section srj6a +.section srj6b +.section srj7a +.section srj7b +.section srj8a +.section srj8b +.section srj9a +.section srj9b +.section srj0a +.section srj0b +.section srkaa +.section srkab +.section srkba +.section srkbb +.section srkca +.section srkcb +.section srkda +.section srkdb +.section srkea +.section srkeb +.section srkfa +.section srkfb +.section srkga +.section srkgb +.section srkha +.section srkhb +.section srkia +.section srkib +.section srkja +.section srkjb +.section srkka +.section srkkb +.section srkla +.section srklb +.section srkma +.section srkmb +.section srkna +.section srknb +.section srkoa +.section srkob +.section srkpa +.section srkpb +.section srkqa +.section srkqb +.section srkra +.section srkrb +.section srksa +.section srksb +.section srkta +.section srktb +.section srkua +.section srkub +.section srkva +.section srkvb +.section srkwa +.section srkwb +.section srkxa +.section srkxb +.section srkya +.section srkyb +.section srkza +.section srkzb +.section srk1a +.section srk1b +.section srk2a +.section srk2b +.section srk3a +.section srk3b +.section srk4a +.section srk4b +.section srk5a +.section srk5b +.section srk6a +.section srk6b +.section srk7a +.section srk7b +.section srk8a +.section srk8b +.section srk9a +.section srk9b +.section srk0a +.section srk0b +.section srlaa +.section srlab +.section srlba +.section srlbb +.section srlca +.section srlcb +.section srlda +.section srldb +.section srlea +.section srleb +.section srlfa +.section srlfb +.section srlga +.section srlgb +.section srlha +.section srlhb +.section srlia +.section srlib +.section srlja +.section srljb +.section srlka +.section srlkb +.section srlla +.section srllb +.section srlma +.section srlmb +.section srlna +.section srlnb +.section srloa +.section srlob +.section srlpa +.section srlpb +.section srlqa +.section srlqb +.section srlra +.section srlrb +.section srlsa +.section srlsb +.section srlta +.section srltb +.section srlua +.section srlub +.section srlva +.section srlvb +.section srlwa +.section srlwb +.section srlxa +.section srlxb +.section srlya +.section srlyb +.section srlza +.section srlzb +.section srl1a +.section srl1b +.section srl2a +.section srl2b +.section srl3a +.section srl3b +.section srl4a +.section srl4b +.section srl5a +.section srl5b +.section srl6a +.section srl6b +.section srl7a +.section srl7b +.section srl8a +.section srl8b +.section srl9a +.section srl9b +.section srl0a +.section srl0b +.section srmaa +.section srmab +.section srmba +.section srmbb +.section srmca +.section srmcb +.section srmda +.section srmdb +.section srmea +.section srmeb +.section srmfa +.section srmfb +.section srmga +.section srmgb +.section srmha +.section srmhb +.section srmia +.section srmib +.section srmja +.section srmjb +.section srmka +.section srmkb +.section srmla +.section srmlb +.section srmma +.section srmmb +.section srmna +.section srmnb +.section srmoa +.section srmob +.section srmpa +.section srmpb +.section srmqa +.section srmqb +.section srmra +.section srmrb +.section srmsa +.section srmsb +.section srmta +.section srmtb +.section srmua +.section srmub +.section srmva +.section srmvb +.section srmwa +.section srmwb +.section srmxa +.section srmxb +.section srmya +.section srmyb +.section srmza +.section srmzb +.section srm1a +.section srm1b +.section srm2a +.section srm2b +.section srm3a +.section srm3b +.section srm4a +.section srm4b +.section srm5a +.section srm5b +.section srm6a +.section srm6b +.section srm7a +.section srm7b +.section srm8a +.section srm8b +.section srm9a +.section srm9b +.section srm0a +.section srm0b +.section srnaa +.section srnab +.section srnba +.section srnbb +.section srnca +.section srncb +.section srnda +.section srndb +.section srnea +.section srneb +.section srnfa +.section srnfb +.section srnga +.section srngb +.section srnha +.section srnhb +.section srnia +.section srnib +.section srnja +.section srnjb +.section srnka +.section srnkb +.section srnla +.section srnlb +.section srnma +.section srnmb +.section srnna +.section srnnb +.section srnoa +.section srnob +.section srnpa +.section srnpb +.section srnqa +.section srnqb +.section srnra +.section srnrb +.section srnsa +.section srnsb +.section srnta +.section srntb +.section srnua +.section srnub +.section srnva +.section srnvb +.section srnwa +.section srnwb +.section srnxa +.section srnxb +.section srnya +.section srnyb +.section srnza +.section srnzb +.section srn1a +.section srn1b +.section srn2a +.section srn2b +.section srn3a +.section srn3b +.section srn4a +.section srn4b +.section srn5a +.section srn5b +.section srn6a +.section srn6b +.section srn7a +.section srn7b +.section srn8a +.section srn8b +.section srn9a +.section srn9b +.section srn0a +.section srn0b +.section sroaa +.section sroab +.section sroba +.section srobb +.section sroca +.section srocb +.section sroda +.section srodb +.section sroea +.section sroeb +.section srofa +.section srofb +.section sroga +.section srogb +.section sroha +.section srohb +.section sroia +.section sroib +.section sroja +.section srojb +.section sroka +.section srokb +.section srola +.section srolb +.section sroma +.section sromb +.section srona +.section sronb +.section srooa +.section sroob +.section sropa +.section sropb +.section sroqa +.section sroqb +.section srora +.section srorb +.section srosa +.section srosb +.section srota +.section srotb +.section sroua +.section sroub +.section srova +.section srovb +.section srowa +.section srowb +.section sroxa +.section sroxb +.section sroya +.section sroyb +.section sroza +.section srozb +.section sro1a +.section sro1b +.section sro2a +.section sro2b +.section sro3a +.section sro3b +.section sro4a +.section sro4b +.section sro5a +.section sro5b +.section sro6a +.section sro6b +.section sro7a +.section sro7b +.section sro8a +.section sro8b +.section sro9a +.section sro9b +.section sro0a +.section sro0b +.section srpaa +.section srpab +.section srpba +.section srpbb +.section srpca +.section srpcb +.section srpda +.section srpdb +.section srpea +.section srpeb +.section srpfa +.section srpfb +.section srpga +.section srpgb +.section srpha +.section srphb +.section srpia +.section srpib +.section srpja +.section srpjb +.section srpka +.section srpkb +.section srpla +.section srplb +.section srpma +.section srpmb +.section srpna +.section srpnb +.section srpoa +.section srpob +.section srppa +.section srppb +.section srpqa +.section srpqb +.section srpra +.section srprb +.section srpsa +.section srpsb +.section srpta +.section srptb +.section srpua +.section srpub +.section srpva +.section srpvb +.section srpwa +.section srpwb +.section srpxa +.section srpxb +.section srpya +.section srpyb +.section srpza +.section srpzb +.section srp1a +.section srp1b +.section srp2a +.section srp2b +.section srp3a +.section srp3b +.section srp4a +.section srp4b +.section srp5a +.section srp5b +.section srp6a +.section srp6b +.section srp7a +.section srp7b +.section srp8a +.section srp8b +.section srp9a +.section srp9b +.section srp0a +.section srp0b +.section srqaa +.section srqab +.section srqba +.section srqbb +.section srqca +.section srqcb +.section srqda +.section srqdb +.section srqea +.section srqeb +.section srqfa +.section srqfb +.section srqga +.section srqgb +.section srqha +.section srqhb +.section srqia +.section srqib +.section srqja +.section srqjb +.section srqka +.section srqkb +.section srqla +.section srqlb +.section srqma +.section srqmb +.section srqna +.section srqnb +.section srqoa +.section srqob +.section srqpa +.section srqpb +.section srqqa +.section srqqb +.section srqra +.section srqrb +.section srqsa +.section srqsb +.section srqta +.section srqtb +.section srqua +.section srqub +.section srqva +.section srqvb +.section srqwa +.section srqwb +.section srqxa +.section srqxb +.section srqya +.section srqyb +.section srqza +.section srqzb +.section srq1a +.section srq1b +.section srq2a +.section srq2b +.section srq3a +.section srq3b +.section srq4a +.section srq4b +.section srq5a +.section srq5b +.section srq6a +.section srq6b +.section srq7a +.section srq7b +.section srq8a +.section srq8b +.section srq9a +.section srq9b +.section srq0a +.section srq0b +.section srraa +.section srrab +.section srrba +.section srrbb +.section srrca +.section srrcb +.section srrda +.section srrdb +.section srrea +.section srreb +.section srrfa +.section srrfb +.section srrga +.section srrgb +.section srrha +.section srrhb +.section srria +.section srrib +.section srrja +.section srrjb +.section srrka +.section srrkb +.section srrla +.section srrlb +.section srrma +.section srrmb +.section srrna +.section srrnb +.section srroa +.section srrob +.section srrpa +.section srrpb +.section srrqa +.section srrqb +.section srrra +.section srrrb +.section srrsa +.section srrsb +.section srrta +.section srrtb +.section srrua +.section srrub +.section srrva +.section srrvb +.section srrwa +.section srrwb +.section srrxa +.section srrxb +.section srrya +.section srryb +.section srrza +.section srrzb +.section srr1a +.section srr1b +.section srr2a +.section srr2b +.section srr3a +.section srr3b +.section srr4a +.section srr4b +.section srr5a +.section srr5b +.section srr6a +.section srr6b +.section srr7a +.section srr7b +.section srr8a +.section srr8b +.section srr9a +.section srr9b +.section srr0a +.section srr0b +.section srsaa +.section srsab +.section srsba +.section srsbb +.section srsca +.section srscb +.section srsda +.section srsdb +.section srsea +.section srseb +.section srsfa +.section srsfb +.section srsga +.section srsgb +.section srsha +.section srshb +.section srsia +.section srsib +.section srsja +.section srsjb +.section srska +.section srskb +.section srsla +.section srslb +.section srsma +.section srsmb +.section srsna +.section srsnb +.section srsoa +.section srsob +.section srspa +.section srspb +.section srsqa +.section srsqb +.section srsra +.section srsrb +.section srssa +.section srssb +.section srsta +.section srstb +.section srsua +.section srsub +.section srsva +.section srsvb +.section srswa +.section srswb +.section srsxa +.section srsxb +.section srsya +.section srsyb +.section srsza +.section srszb +.section srs1a +.section srs1b +.section srs2a +.section srs2b +.section srs3a +.section srs3b +.section srs4a +.section srs4b +.section srs5a +.section srs5b +.section srs6a +.section srs6b +.section srs7a +.section srs7b +.section srs8a +.section srs8b +.section srs9a +.section srs9b +.section srs0a +.section srs0b +.section srtaa +.section srtab +.section srtba +.section srtbb +.section srtca +.section srtcb +.section srtda +.section srtdb +.section srtea +.section srteb +.section srtfa +.section srtfb +.section srtga +.section srtgb +.section srtha +.section srthb +.section srtia +.section srtib +.section srtja +.section srtjb +.section srtka +.section srtkb +.section srtla +.section srtlb +.section srtma +.section srtmb +.section srtna +.section srtnb +.section srtoa +.section srtob +.section srtpa +.section srtpb +.section srtqa +.section srtqb +.section srtra +.section srtrb +.section srtsa +.section srtsb +.section srtta +.section srttb +.section srtua +.section srtub +.section srtva +.section srtvb +.section srtwa +.section srtwb +.section srtxa +.section srtxb +.section srtya +.section srtyb +.section srtza +.section srtzb +.section srt1a +.section srt1b +.section srt2a +.section srt2b +.section srt3a +.section srt3b +.section srt4a +.section srt4b +.section srt5a +.section srt5b +.section srt6a +.section srt6b +.section srt7a +.section srt7b +.section srt8a +.section srt8b +.section srt9a +.section srt9b +.section srt0a +.section srt0b +.section sruaa +.section sruab +.section sruba +.section srubb +.section sruca +.section srucb +.section sruda +.section srudb +.section sruea +.section srueb +.section srufa +.section srufb +.section sruga +.section srugb +.section sruha +.section sruhb +.section sruia +.section sruib +.section sruja +.section srujb +.section sruka +.section srukb +.section srula +.section srulb +.section sruma +.section srumb +.section sruna +.section srunb +.section sruoa +.section sruob +.section srupa +.section srupb +.section sruqa +.section sruqb +.section srura +.section srurb +.section srusa +.section srusb +.section sruta +.section srutb +.section sruua +.section sruub +.section sruva +.section sruvb +.section sruwa +.section sruwb +.section sruxa +.section sruxb +.section sruya +.section sruyb +.section sruza +.section sruzb +.section sru1a +.section sru1b +.section sru2a +.section sru2b +.section sru3a +.section sru3b +.section sru4a +.section sru4b +.section sru5a +.section sru5b +.section sru6a +.section sru6b +.section sru7a +.section sru7b +.section sru8a +.section sru8b +.section sru9a +.section sru9b +.section sru0a +.section sru0b +.section srvaa +.section srvab +.section srvba +.section srvbb +.section srvca +.section srvcb +.section srvda +.section srvdb +.section srvea +.section srveb +.section srvfa +.section srvfb +.section srvga +.section srvgb +.section srvha +.section srvhb +.section srvia +.section srvib +.section srvja +.section srvjb +.section srvka +.section srvkb +.section srvla +.section srvlb +.section srvma +.section srvmb +.section srvna +.section srvnb +.section srvoa +.section srvob +.section srvpa +.section srvpb +.section srvqa +.section srvqb +.section srvra +.section srvrb +.section srvsa +.section srvsb +.section srvta +.section srvtb +.section srvua +.section srvub +.section srvva +.section srvvb +.section srvwa +.section srvwb +.section srvxa +.section srvxb +.section srvya +.section srvyb +.section srvza +.section srvzb +.section srv1a +.section srv1b +.section srv2a +.section srv2b +.section srv3a +.section srv3b +.section srv4a +.section srv4b +.section srv5a +.section srv5b +.section srv6a +.section srv6b +.section srv7a +.section srv7b +.section srv8a +.section srv8b +.section srv9a +.section srv9b +.section srv0a +.section srv0b +.section srwaa +.section srwab +.section srwba +.section srwbb +.section srwca +.section srwcb +.section srwda +.section srwdb +.section srwea +.section srweb +.section srwfa +.section srwfb +.section srwga +.section srwgb +.section srwha +.section srwhb +.section srwia +.section srwib +.section srwja +.section srwjb +.section srwka +.section srwkb +.section srwla +.section srwlb +.section srwma +.section srwmb +.section srwna +.section srwnb +.section srwoa +.section srwob +.section srwpa +.section srwpb +.section srwqa +.section srwqb +.section srwra +.section srwrb +.section srwsa +.section srwsb +.section srwta +.section srwtb +.section srwua +.section srwub +.section srwva +.section srwvb +.section srwwa +.section srwwb +.section srwxa +.section srwxb +.section srwya +.section srwyb +.section srwza +.section srwzb +.section srw1a +.section srw1b +.section srw2a +.section srw2b +.section srw3a +.section srw3b +.section srw4a +.section srw4b +.section srw5a +.section srw5b +.section srw6a +.section srw6b +.section srw7a +.section srw7b +.section srw8a +.section srw8b +.section srw9a +.section srw9b +.section srw0a +.section srw0b +.section srxaa +.section srxab +.section srxba +.section srxbb +.section srxca +.section srxcb +.section srxda +.section srxdb +.section srxea +.section srxeb +.section srxfa +.section srxfb +.section srxga +.section srxgb +.section srxha +.section srxhb +.section srxia +.section srxib +.section srxja +.section srxjb +.section srxka +.section srxkb +.section srxla +.section srxlb +.section srxma +.section srxmb +.section srxna +.section srxnb +.section srxoa +.section srxob +.section srxpa +.section srxpb +.section srxqa +.section srxqb +.section srxra +.section srxrb +.section srxsa +.section srxsb +.section srxta +.section srxtb +.section srxua +.section srxub +.section srxva +.section srxvb +.section srxwa +.section srxwb +.section srxxa +.section srxxb +.section srxya +.section srxyb +.section srxza +.section srxzb +.section srx1a +.section srx1b +.section srx2a +.section srx2b +.section srx3a +.section srx3b +.section srx4a +.section srx4b +.section srx5a +.section srx5b +.section srx6a +.section srx6b +.section srx7a +.section srx7b +.section srx8a +.section srx8b +.section srx9a +.section srx9b +.section srx0a +.section srx0b +.section sryaa +.section sryab +.section sryba +.section srybb +.section sryca +.section srycb +.section sryda +.section srydb +.section sryea +.section sryeb +.section sryfa +.section sryfb +.section sryga +.section srygb +.section sryha +.section sryhb +.section sryia +.section sryib +.section sryja +.section sryjb +.section sryka +.section srykb +.section sryla +.section srylb +.section sryma +.section srymb +.section sryna +.section srynb +.section sryoa +.section sryob +.section srypa +.section srypb +.section sryqa +.section sryqb +.section sryra +.section sryrb +.section srysa +.section srysb +.section sryta +.section srytb +.section sryua +.section sryub +.section sryva +.section sryvb +.section srywa +.section srywb +.section sryxa +.section sryxb +.section sryya +.section sryyb +.section sryza +.section sryzb +.section sry1a +.section sry1b +.section sry2a +.section sry2b +.section sry3a +.section sry3b +.section sry4a +.section sry4b +.section sry5a +.section sry5b +.section sry6a +.section sry6b +.section sry7a +.section sry7b +.section sry8a +.section sry8b +.section sry9a +.section sry9b +.section sry0a +.section sry0b +.section srzaa +.section srzab +.section srzba +.section srzbb +.section srzca +.section srzcb +.section srzda +.section srzdb +.section srzea +.section srzeb +.section srzfa +.section srzfb +.section srzga +.section srzgb +.section srzha +.section srzhb +.section srzia +.section srzib +.section srzja +.section srzjb +.section srzka +.section srzkb +.section srzla +.section srzlb +.section srzma +.section srzmb +.section srzna +.section srznb +.section srzoa +.section srzob +.section srzpa +.section srzpb +.section srzqa +.section srzqb +.section srzra +.section srzrb +.section srzsa +.section srzsb +.section srzta +.section srztb +.section srzua +.section srzub +.section srzva +.section srzvb +.section srzwa +.section srzwb +.section srzxa +.section srzxb +.section srzya +.section srzyb +.section srzza +.section srzzb +.section srz1a +.section srz1b +.section srz2a +.section srz2b +.section srz3a +.section srz3b +.section srz4a +.section srz4b +.section srz5a +.section srz5b +.section srz6a +.section srz6b +.section srz7a +.section srz7b +.section srz8a +.section srz8b +.section srz9a +.section srz9b +.section srz0a +.section srz0b +.section sr1aa +.section sr1ab +.section sr1ba +.section sr1bb +.section sr1ca +.section sr1cb +.section sr1da +.section sr1db +.section sr1ea +.section sr1eb +.section sr1fa +.section sr1fb +.section sr1ga +.section sr1gb +.section sr1ha +.section sr1hb +.section sr1ia +.section sr1ib +.section sr1ja +.section sr1jb +.section sr1ka +.section sr1kb +.section sr1la +.section sr1lb +.section sr1ma +.section sr1mb +.section sr1na +.section sr1nb +.section sr1oa +.section sr1ob +.section sr1pa +.section sr1pb +.section sr1qa +.section sr1qb +.section sr1ra +.section sr1rb +.section sr1sa +.section sr1sb +.section sr1ta +.section sr1tb +.section sr1ua +.section sr1ub +.section sr1va +.section sr1vb +.section sr1wa +.section sr1wb +.section sr1xa +.section sr1xb +.section sr1ya +.section sr1yb +.section sr1za +.section sr1zb +.section sr11a +.section sr11b +.section sr12a +.section sr12b +.section sr13a +.section sr13b +.section sr14a +.section sr14b +.section sr15a +.section sr15b +.section sr16a +.section sr16b +.section sr17a +.section sr17b +.section sr18a +.section sr18b +.section sr19a +.section sr19b +.section sr10a +.section sr10b +.section sr2aa +.section sr2ab +.section sr2ba +.section sr2bb +.section sr2ca +.section sr2cb +.section sr2da +.section sr2db +.section sr2ea +.section sr2eb +.section sr2fa +.section sr2fb +.section sr2ga +.section sr2gb +.section sr2ha +.section sr2hb +.section sr2ia +.section sr2ib +.section sr2ja +.section sr2jb +.section sr2ka +.section sr2kb +.section sr2la +.section sr2lb +.section sr2ma +.section sr2mb +.section sr2na +.section sr2nb +.section sr2oa +.section sr2ob +.section sr2pa +.section sr2pb +.section sr2qa +.section sr2qb +.section sr2ra +.section sr2rb +.section sr2sa +.section sr2sb +.section sr2ta +.section sr2tb +.section sr2ua +.section sr2ub +.section sr2va +.section sr2vb +.section sr2wa +.section sr2wb +.section sr2xa +.section sr2xb +.section sr2ya +.section sr2yb +.section sr2za +.section sr2zb +.section sr21a +.section sr21b +.section sr22a +.section sr22b +.section sr23a +.section sr23b +.section sr24a +.section sr24b +.section sr25a +.section sr25b +.section sr26a +.section sr26b +.section sr27a +.section sr27b +.section sr28a +.section sr28b +.section sr29a +.section sr29b +.section sr20a +.section sr20b +.section sr3aa +.section sr3ab +.section sr3ba +.section sr3bb +.section sr3ca +.section sr3cb +.section sr3da +.section sr3db +.section sr3ea +.section sr3eb +.section sr3fa +.section sr3fb +.section sr3ga +.section sr3gb +.section sr3ha +.section sr3hb +.section sr3ia +.section sr3ib +.section sr3ja +.section sr3jb +.section sr3ka +.section sr3kb +.section sr3la +.section sr3lb +.section sr3ma +.section sr3mb +.section sr3na +.section sr3nb +.section sr3oa +.section sr3ob +.section sr3pa +.section sr3pb +.section sr3qa +.section sr3qb +.section sr3ra +.section sr3rb +.section sr3sa +.section sr3sb +.section sr3ta +.section sr3tb +.section sr3ua +.section sr3ub +.section sr3va +.section sr3vb +.section sr3wa +.section sr3wb +.section sr3xa +.section sr3xb +.section sr3ya +.section sr3yb +.section sr3za +.section sr3zb +.section sr31a +.section sr31b +.section sr32a +.section sr32b +.section sr33a +.section sr33b +.section sr34a +.section sr34b +.section sr35a +.section sr35b +.section sr36a +.section sr36b +.section sr37a +.section sr37b +.section sr38a +.section sr38b +.section sr39a +.section sr39b +.section sr30a +.section sr30b +.section sr4aa +.section sr4ab +.section sr4ba +.section sr4bb +.section sr4ca +.section sr4cb +.section sr4da +.section sr4db +.section sr4ea +.section sr4eb +.section sr4fa +.section sr4fb +.section sr4ga +.section sr4gb +.section sr4ha +.section sr4hb +.section sr4ia +.section sr4ib +.section sr4ja +.section sr4jb +.section sr4ka +.section sr4kb +.section sr4la +.section sr4lb +.section sr4ma +.section sr4mb +.section sr4na +.section sr4nb +.section sr4oa +.section sr4ob +.section sr4pa +.section sr4pb +.section sr4qa +.section sr4qb +.section sr4ra +.section sr4rb +.section sr4sa +.section sr4sb +.section sr4ta +.section sr4tb +.section sr4ua +.section sr4ub +.section sr4va +.section sr4vb +.section sr4wa +.section sr4wb +.section sr4xa +.section sr4xb +.section sr4ya +.section sr4yb +.section sr4za +.section sr4zb +.section sr41a +.section sr41b +.section sr42a +.section sr42b +.section sr43a +.section sr43b +.section sr44a +.section sr44b +.section sr45a +.section sr45b +.section sr46a +.section sr46b +.section sr47a +.section sr47b +.section sr48a +.section sr48b +.section sr49a +.section sr49b +.section sr40a +.section sr40b +.section sr5aa +.section sr5ab +.section sr5ba +.section sr5bb +.section sr5ca +.section sr5cb +.section sr5da +.section sr5db +.section sr5ea +.section sr5eb +.section sr5fa +.section sr5fb +.section sr5ga +.section sr5gb +.section sr5ha +.section sr5hb +.section sr5ia +.section sr5ib +.section sr5ja +.section sr5jb +.section sr5ka +.section sr5kb +.section sr5la +.section sr5lb +.section sr5ma +.section sr5mb +.section sr5na +.section sr5nb +.section sr5oa +.section sr5ob +.section sr5pa +.section sr5pb +.section sr5qa +.section sr5qb +.section sr5ra +.section sr5rb +.section sr5sa +.section sr5sb +.section sr5ta +.section sr5tb +.section sr5ua +.section sr5ub +.section sr5va +.section sr5vb +.section sr5wa +.section sr5wb +.section sr5xa +.section sr5xb +.section sr5ya +.section sr5yb +.section sr5za +.section sr5zb +.section sr51a +.section sr51b +.section sr52a +.section sr52b +.section sr53a +.section sr53b +.section sr54a +.section sr54b +.section sr55a +.section sr55b +.section sr56a +.section sr56b +.section sr57a +.section sr57b +.section sr58a +.section sr58b +.section sr59a +.section sr59b +.section sr50a +.section sr50b +.section sr6aa +.section sr6ab +.section sr6ba +.section sr6bb +.section sr6ca +.section sr6cb +.section sr6da +.section sr6db +.section sr6ea +.section sr6eb +.section sr6fa +.section sr6fb +.section sr6ga +.section sr6gb +.section sr6ha +.section sr6hb +.section sr6ia +.section sr6ib +.section sr6ja +.section sr6jb +.section sr6ka +.section sr6kb +.section sr6la +.section sr6lb +.section sr6ma +.section sr6mb +.section sr6na +.section sr6nb +.section sr6oa +.section sr6ob +.section sr6pa +.section sr6pb +.section sr6qa +.section sr6qb +.section sr6ra +.section sr6rb +.section sr6sa +.section sr6sb +.section sr6ta +.section sr6tb +.section sr6ua +.section sr6ub +.section sr6va +.section sr6vb +.section sr6wa +.section sr6wb +.section sr6xa +.section sr6xb +.section sr6ya +.section sr6yb +.section sr6za +.section sr6zb +.section sr61a +.section sr61b +.section sr62a +.section sr62b +.section sr63a +.section sr63b +.section sr64a +.section sr64b +.section sr65a +.section sr65b +.section sr66a +.section sr66b +.section sr67a +.section sr67b +.section sr68a +.section sr68b +.section sr69a +.section sr69b +.section sr60a +.section sr60b +.section sr7aa +.section sr7ab +.section sr7ba +.section sr7bb +.section sr7ca +.section sr7cb +.section sr7da +.section sr7db +.section sr7ea +.section sr7eb +.section sr7fa +.section sr7fb +.section sr7ga +.section sr7gb +.section sr7ha +.section sr7hb +.section sr7ia +.section sr7ib +.section sr7ja +.section sr7jb +.section sr7ka +.section sr7kb +.section sr7la +.section sr7lb +.section sr7ma +.section sr7mb +.section sr7na +.section sr7nb +.section sr7oa +.section sr7ob +.section sr7pa +.section sr7pb +.section sr7qa +.section sr7qb +.section sr7ra +.section sr7rb +.section sr7sa +.section sr7sb +.section sr7ta +.section sr7tb +.section sr7ua +.section sr7ub +.section sr7va +.section sr7vb +.section sr7wa +.section sr7wb +.section sr7xa +.section sr7xb +.section sr7ya +.section sr7yb +.section sr7za +.section sr7zb +.section sr71a +.section sr71b +.section sr72a +.section sr72b +.section sr73a +.section sr73b +.section sr74a +.section sr74b +.section sr75a +.section sr75b +.section sr76a +.section sr76b +.section sr77a +.section sr77b +.section sr78a +.section sr78b +.section sr79a +.section sr79b +.section sr70a +.section sr70b +.section sr8aa +.section sr8ab +.section sr8ba +.section sr8bb +.section sr8ca +.section sr8cb +.section sr8da +.section sr8db +.section sr8ea +.section sr8eb +.section sr8fa +.section sr8fb +.section sr8ga +.section sr8gb +.section sr8ha +.section sr8hb +.section sr8ia +.section sr8ib +.section sr8ja +.section sr8jb +.section sr8ka +.section sr8kb +.section sr8la +.section sr8lb +.section sr8ma +.section sr8mb +.section sr8na +.section sr8nb +.section sr8oa +.section sr8ob +.section sr8pa +.section sr8pb +.section sr8qa +.section sr8qb +.section sr8ra +.section sr8rb +.section sr8sa +.section sr8sb +.section sr8ta +.section sr8tb +.section sr8ua +.section sr8ub +.section sr8va +.section sr8vb +.section sr8wa +.section sr8wb +.section sr8xa +.section sr8xb +.section sr8ya +.section sr8yb +.section sr8za +.section sr8zb +.section sr81a +.section sr81b +.section sr82a +.section sr82b +.section sr83a +.section sr83b +.section sr84a +.section sr84b +.section sr85a +.section sr85b +.section sr86a +.section sr86b +.section sr87a +.section sr87b +.section sr88a +.section sr88b +.section sr89a +.section sr89b +.section sr80a +.section sr80b +.section sr9aa +.section sr9ab +.section sr9ba +.section sr9bb +.section sr9ca +.section sr9cb +.section sr9da +.section sr9db +.section sr9ea +.section sr9eb +.section sr9fa +.section sr9fb +.section sr9ga +.section sr9gb +.section sr9ha +.section sr9hb +.section sr9ia +.section sr9ib +.section sr9ja +.section sr9jb +.section sr9ka +.section sr9kb +.section sr9la +.section sr9lb +.section sr9ma +.section sr9mb +.section sr9na +.section sr9nb +.section sr9oa +.section sr9ob +.section sr9pa +.section sr9pb +.section sr9qa +.section sr9qb +.section sr9ra +.section sr9rb +.section sr9sa +.section sr9sb +.section sr9ta +.section sr9tb +.section sr9ua +.section sr9ub +.section sr9va +.section sr9vb +.section sr9wa +.section sr9wb +.section sr9xa +.section sr9xb +.section sr9ya +.section sr9yb +.section sr9za +.section sr9zb +.section sr91a +.section sr91b +.section sr92a +.section sr92b +.section sr93a +.section sr93b +.section sr94a +.section sr94b +.section sr95a +.section sr95b +.section sr96a +.section sr96b +.section sr97a +.section sr97b +.section sr98a +.section sr98b +.section sr99a +.section sr99b +.section sr90a +.section sr90b +.section sr0aa +.section sr0ab +.section sr0ba +.section sr0bb +.section sr0ca +.section sr0cb +.section sr0da +.section sr0db +.section sr0ea +.section sr0eb +.section sr0fa +.section sr0fb +.section sr0ga +.section sr0gb +.section sr0ha +.section sr0hb +.section sr0ia +.section sr0ib +.section sr0ja +.section sr0jb +.section sr0ka +.section sr0kb +.section sr0la +.section sr0lb +.section sr0ma +.section sr0mb +.section sr0na +.section sr0nb +.section sr0oa +.section sr0ob +.section sr0pa +.section sr0pb +.section sr0qa +.section sr0qb +.section sr0ra +.section sr0rb +.section sr0sa +.section sr0sb +.section sr0ta +.section sr0tb +.section sr0ua +.section sr0ub +.section sr0va +.section sr0vb +.section sr0wa +.section sr0wb +.section sr0xa +.section sr0xb +.section sr0ya +.section sr0yb +.section sr0za +.section sr0zb +.section sr01a +.section sr01b +.section sr02a +.section sr02b +.section sr03a +.section sr03b +.section sr04a +.section sr04b +.section sr05a +.section sr05b +.section sr06a +.section sr06b +.section sr07a +.section sr07b +.section sr08a +.section sr08b +.section sr09a +.section sr09b +.section sr00a +.section sr00b +.section ssaaa +.section ssaab +.section ssaba +.section ssabb +.section ssaca +.section ssacb +.section ssada +.section ssadb +.section ssaea +.section ssaeb +.section ssafa +.section ssafb +.section ssaga +.section ssagb +.section ssaha +.section ssahb +.section ssaia +.section ssaib +.section ssaja +.section ssajb +.section ssaka +.section ssakb +.section ssala +.section ssalb +.section ssama +.section ssamb +.section ssana +.section ssanb +.section ssaoa +.section ssaob +.section ssapa +.section ssapb +.section ssaqa +.section ssaqb +.section ssara +.section ssarb +.section ssasa +.section ssasb +.section ssata +.section ssatb +.section ssaua +.section ssaub +.section ssava +.section ssavb +.section ssawa +.section ssawb +.section ssaxa +.section ssaxb +.section ssaya +.section ssayb +.section ssaza +.section ssazb +.section ssa1a +.section ssa1b +.section ssa2a +.section ssa2b +.section ssa3a +.section ssa3b +.section ssa4a +.section ssa4b +.section ssa5a +.section ssa5b +.section ssa6a +.section ssa6b +.section ssa7a +.section ssa7b +.section ssa8a +.section ssa8b +.section ssa9a +.section ssa9b +.section ssa0a +.section ssa0b +.section ssbaa +.section ssbab +.section ssbba +.section ssbbb +.section ssbca +.section ssbcb +.section ssbda +.section ssbdb +.section ssbea +.section ssbeb +.section ssbfa +.section ssbfb +.section ssbga +.section ssbgb +.section ssbha +.section ssbhb +.section ssbia +.section ssbib +.section ssbja +.section ssbjb +.section ssbka +.section ssbkb +.section ssbla +.section ssblb +.section ssbma +.section ssbmb +.section ssbna +.section ssbnb +.section ssboa +.section ssbob +.section ssbpa +.section ssbpb +.section ssbqa +.section ssbqb +.section ssbra +.section ssbrb +.section ssbsa +.section ssbsb +.section ssbta +.section ssbtb +.section ssbua +.section ssbub +.section ssbva +.section ssbvb +.section ssbwa +.section ssbwb +.section ssbxa +.section ssbxb +.section ssbya +.section ssbyb +.section ssbza +.section ssbzb +.section ssb1a +.section ssb1b +.section ssb2a +.section ssb2b +.section ssb3a +.section ssb3b +.section ssb4a +.section ssb4b +.section ssb5a +.section ssb5b +.section ssb6a +.section ssb6b +.section ssb7a +.section ssb7b +.section ssb8a +.section ssb8b +.section ssb9a +.section ssb9b +.section ssb0a +.section ssb0b +.section sscaa +.section sscab +.section sscba +.section sscbb +.section sscca +.section ssccb +.section sscda +.section sscdb +.section sscea +.section ssceb +.section sscfa +.section sscfb +.section sscga +.section sscgb +.section sscha +.section sschb +.section sscia +.section sscib +.section sscja +.section sscjb +.section sscka +.section ssckb +.section sscla +.section ssclb +.section sscma +.section sscmb +.section sscna +.section sscnb +.section sscoa +.section sscob +.section sscpa +.section sscpb +.section sscqa +.section sscqb +.section sscra +.section sscrb +.section sscsa +.section sscsb +.section sscta +.section ssctb +.section sscua +.section sscub +.section sscva +.section sscvb +.section sscwa +.section sscwb +.section sscxa +.section sscxb +.section sscya +.section sscyb +.section sscza +.section ssczb +.section ssc1a +.section ssc1b +.section ssc2a +.section ssc2b +.section ssc3a +.section ssc3b +.section ssc4a +.section ssc4b +.section ssc5a +.section ssc5b +.section ssc6a +.section ssc6b +.section ssc7a +.section ssc7b +.section ssc8a +.section ssc8b +.section ssc9a +.section ssc9b +.section ssc0a +.section ssc0b +.section ssdaa +.section ssdab +.section ssdba +.section ssdbb +.section ssdca +.section ssdcb +.section ssdda +.section ssddb +.section ssdea +.section ssdeb +.section ssdfa +.section ssdfb +.section ssdga +.section ssdgb +.section ssdha +.section ssdhb +.section ssdia +.section ssdib +.section ssdja +.section ssdjb +.section ssdka +.section ssdkb +.section ssdla +.section ssdlb +.section ssdma +.section ssdmb +.section ssdna +.section ssdnb +.section ssdoa +.section ssdob +.section ssdpa +.section ssdpb +.section ssdqa +.section ssdqb +.section ssdra +.section ssdrb +.section ssdsa +.section ssdsb +.section ssdta +.section ssdtb +.section ssdua +.section ssdub +.section ssdva +.section ssdvb +.section ssdwa +.section ssdwb +.section ssdxa +.section ssdxb +.section ssdya +.section ssdyb +.section ssdza +.section ssdzb +.section ssd1a +.section ssd1b +.section ssd2a +.section ssd2b +.section ssd3a +.section ssd3b +.section ssd4a +.section ssd4b +.section ssd5a +.section ssd5b +.section ssd6a +.section ssd6b +.section ssd7a +.section ssd7b +.section ssd8a +.section ssd8b +.section ssd9a +.section ssd9b +.section ssd0a +.section ssd0b +.section sseaa +.section sseab +.section sseba +.section ssebb +.section sseca +.section ssecb +.section sseda +.section ssedb +.section sseea +.section sseeb +.section ssefa +.section ssefb +.section ssega +.section ssegb +.section sseha +.section ssehb +.section sseia +.section sseib +.section sseja +.section ssejb +.section sseka +.section ssekb +.section ssela +.section sselb +.section ssema +.section ssemb +.section ssena +.section ssenb +.section sseoa +.section sseob +.section ssepa +.section ssepb +.section sseqa +.section sseqb +.section ssera +.section sserb +.section ssesa +.section ssesb +.section sseta +.section ssetb +.section sseua +.section sseub +.section sseva +.section ssevb +.section ssewa +.section ssewb +.section ssexa +.section ssexb +.section sseya +.section sseyb +.section sseza +.section ssezb +.section sse1a +.section sse1b +.section sse2a +.section sse2b +.section sse3a +.section sse3b +.section sse4a +.section sse4b +.section sse5a +.section sse5b +.section sse6a +.section sse6b +.section sse7a +.section sse7b +.section sse8a +.section sse8b +.section sse9a +.section sse9b +.section sse0a +.section sse0b +.section ssfaa +.section ssfab +.section ssfba +.section ssfbb +.section ssfca +.section ssfcb +.section ssfda +.section ssfdb +.section ssfea +.section ssfeb +.section ssffa +.section ssffb +.section ssfga +.section ssfgb +.section ssfha +.section ssfhb +.section ssfia +.section ssfib +.section ssfja +.section ssfjb +.section ssfka +.section ssfkb +.section ssfla +.section ssflb +.section ssfma +.section ssfmb +.section ssfna +.section ssfnb +.section ssfoa +.section ssfob +.section ssfpa +.section ssfpb +.section ssfqa +.section ssfqb +.section ssfra +.section ssfrb +.section ssfsa +.section ssfsb +.section ssfta +.section ssftb +.section ssfua +.section ssfub +.section ssfva +.section ssfvb +.section ssfwa +.section ssfwb +.section ssfxa +.section ssfxb +.section ssfya +.section ssfyb +.section ssfza +.section ssfzb +.section ssf1a +.section ssf1b +.section ssf2a +.section ssf2b +.section ssf3a +.section ssf3b +.section ssf4a +.section ssf4b +.section ssf5a +.section ssf5b +.section ssf6a +.section ssf6b +.section ssf7a +.section ssf7b +.section ssf8a +.section ssf8b +.section ssf9a +.section ssf9b +.section ssf0a +.section ssf0b +.section ssgaa +.section ssgab +.section ssgba +.section ssgbb +.section ssgca +.section ssgcb +.section ssgda +.section ssgdb +.section ssgea +.section ssgeb +.section ssgfa +.section ssgfb +.section ssgga +.section ssggb +.section ssgha +.section ssghb +.section ssgia +.section ssgib +.section ssgja +.section ssgjb +.section ssgka +.section ssgkb +.section ssgla +.section ssglb +.section ssgma +.section ssgmb +.section ssgna +.section ssgnb +.section ssgoa +.section ssgob +.section ssgpa +.section ssgpb +.section ssgqa +.section ssgqb +.section ssgra +.section ssgrb +.section ssgsa +.section ssgsb +.section ssgta +.section ssgtb +.section ssgua +.section ssgub +.section ssgva +.section ssgvb +.section ssgwa +.section ssgwb +.section ssgxa +.section ssgxb +.section ssgya +.section ssgyb +.section ssgza +.section ssgzb +.section ssg1a +.section ssg1b +.section ssg2a +.section ssg2b +.section ssg3a +.section ssg3b +.section ssg4a +.section ssg4b +.section ssg5a +.section ssg5b +.section ssg6a +.section ssg6b +.section ssg7a +.section ssg7b +.section ssg8a +.section ssg8b +.section ssg9a +.section ssg9b +.section ssg0a +.section ssg0b +.section sshaa +.section sshab +.section sshba +.section sshbb +.section sshca +.section sshcb +.section sshda +.section sshdb +.section sshea +.section ssheb +.section sshfa +.section sshfb +.section sshga +.section sshgb +.section sshha +.section sshhb +.section sshia +.section sshib +.section sshja +.section sshjb +.section sshka +.section sshkb +.section sshla +.section sshlb +.section sshma +.section sshmb +.section sshna +.section sshnb +.section sshoa +.section sshob +.section sshpa +.section sshpb +.section sshqa +.section sshqb +.section sshra +.section sshrb +.section sshsa +.section sshsb +.section sshta +.section sshtb +.section sshua +.section sshub +.section sshva +.section sshvb +.section sshwa +.section sshwb +.section sshxa +.section sshxb +.section sshya +.section sshyb +.section sshza +.section sshzb +.section ssh1a +.section ssh1b +.section ssh2a +.section ssh2b +.section ssh3a +.section ssh3b +.section ssh4a +.section ssh4b +.section ssh5a +.section ssh5b +.section ssh6a +.section ssh6b +.section ssh7a +.section ssh7b +.section ssh8a +.section ssh8b +.section ssh9a +.section ssh9b +.section ssh0a +.section ssh0b +.section ssiaa +.section ssiab +.section ssiba +.section ssibb +.section ssica +.section ssicb +.section ssida +.section ssidb +.section ssiea +.section ssieb +.section ssifa +.section ssifb +.section ssiga +.section ssigb +.section ssiha +.section ssihb +.section ssiia +.section ssiib +.section ssija +.section ssijb +.section ssika +.section ssikb +.section ssila +.section ssilb +.section ssima +.section ssimb +.section ssina +.section ssinb +.section ssioa +.section ssiob +.section ssipa +.section ssipb +.section ssiqa +.section ssiqb +.section ssira +.section ssirb +.section ssisa +.section ssisb +.section ssita +.section ssitb +.section ssiua +.section ssiub +.section ssiva +.section ssivb +.section ssiwa +.section ssiwb +.section ssixa +.section ssixb +.section ssiya +.section ssiyb +.section ssiza +.section ssizb +.section ssi1a +.section ssi1b +.section ssi2a +.section ssi2b +.section ssi3a +.section ssi3b +.section ssi4a +.section ssi4b +.section ssi5a +.section ssi5b +.section ssi6a +.section ssi6b +.section ssi7a +.section ssi7b +.section ssi8a +.section ssi8b +.section ssi9a +.section ssi9b +.section ssi0a +.section ssi0b +.section ssjaa +.section ssjab +.section ssjba +.section ssjbb +.section ssjca +.section ssjcb +.section ssjda +.section ssjdb +.section ssjea +.section ssjeb +.section ssjfa +.section ssjfb +.section ssjga +.section ssjgb +.section ssjha +.section ssjhb +.section ssjia +.section ssjib +.section ssjja +.section ssjjb +.section ssjka +.section ssjkb +.section ssjla +.section ssjlb +.section ssjma +.section ssjmb +.section ssjna +.section ssjnb +.section ssjoa +.section ssjob +.section ssjpa +.section ssjpb +.section ssjqa +.section ssjqb +.section ssjra +.section ssjrb +.section ssjsa +.section ssjsb +.section ssjta +.section ssjtb +.section ssjua +.section ssjub +.section ssjva +.section ssjvb +.section ssjwa +.section ssjwb +.section ssjxa +.section ssjxb +.section ssjya +.section ssjyb +.section ssjza +.section ssjzb +.section ssj1a +.section ssj1b +.section ssj2a +.section ssj2b +.section ssj3a +.section ssj3b +.section ssj4a +.section ssj4b +.section ssj5a +.section ssj5b +.section ssj6a +.section ssj6b +.section ssj7a +.section ssj7b +.section ssj8a +.section ssj8b +.section ssj9a +.section ssj9b +.section ssj0a +.section ssj0b +.section sskaa +.section sskab +.section sskba +.section sskbb +.section sskca +.section sskcb +.section sskda +.section sskdb +.section sskea +.section sskeb +.section sskfa +.section sskfb +.section sskga +.section sskgb +.section sskha +.section sskhb +.section sskia +.section sskib +.section sskja +.section sskjb +.section sskka +.section sskkb +.section sskla +.section ssklb +.section sskma +.section sskmb +.section sskna +.section ssknb +.section sskoa +.section sskob +.section sskpa +.section sskpb +.section sskqa +.section sskqb +.section sskra +.section sskrb +.section ssksa +.section ssksb +.section sskta +.section ssktb +.section sskua +.section sskub +.section sskva +.section sskvb +.section sskwa +.section sskwb +.section sskxa +.section sskxb +.section sskya +.section sskyb +.section sskza +.section sskzb +.section ssk1a +.section ssk1b +.section ssk2a +.section ssk2b +.section ssk3a +.section ssk3b +.section ssk4a +.section ssk4b +.section ssk5a +.section ssk5b +.section ssk6a +.section ssk6b +.section ssk7a +.section ssk7b +.section ssk8a +.section ssk8b +.section ssk9a +.section ssk9b +.section ssk0a +.section ssk0b +.section sslaa +.section sslab +.section sslba +.section sslbb +.section sslca +.section sslcb +.section sslda +.section ssldb +.section sslea +.section ssleb +.section sslfa +.section sslfb +.section sslga +.section sslgb +.section sslha +.section sslhb +.section sslia +.section sslib +.section sslja +.section ssljb +.section sslka +.section sslkb +.section sslla +.section ssllb +.section sslma +.section sslmb +.section sslna +.section sslnb +.section ssloa +.section sslob +.section sslpa +.section sslpb +.section sslqa +.section sslqb +.section sslra +.section sslrb +.section sslsa +.section sslsb +.section sslta +.section ssltb +.section sslua +.section sslub +.section sslva +.section sslvb +.section sslwa +.section sslwb +.section sslxa +.section sslxb +.section sslya +.section sslyb +.section sslza +.section sslzb +.section ssl1a +.section ssl1b +.section ssl2a +.section ssl2b +.section ssl3a +.section ssl3b +.section ssl4a +.section ssl4b +.section ssl5a +.section ssl5b +.section ssl6a +.section ssl6b +.section ssl7a +.section ssl7b +.section ssl8a +.section ssl8b +.section ssl9a +.section ssl9b +.section ssl0a +.section ssl0b +.section ssmaa +.section ssmab +.section ssmba +.section ssmbb +.section ssmca +.section ssmcb +.section ssmda +.section ssmdb +.section ssmea +.section ssmeb +.section ssmfa +.section ssmfb +.section ssmga +.section ssmgb +.section ssmha +.section ssmhb +.section ssmia +.section ssmib +.section ssmja +.section ssmjb +.section ssmka +.section ssmkb +.section ssmla +.section ssmlb +.section ssmma +.section ssmmb +.section ssmna +.section ssmnb +.section ssmoa +.section ssmob +.section ssmpa +.section ssmpb +.section ssmqa +.section ssmqb +.section ssmra +.section ssmrb +.section ssmsa +.section ssmsb +.section ssmta +.section ssmtb +.section ssmua +.section ssmub +.section ssmva +.section ssmvb +.section ssmwa +.section ssmwb +.section ssmxa +.section ssmxb +.section ssmya +.section ssmyb +.section ssmza +.section ssmzb +.section ssm1a +.section ssm1b +.section ssm2a +.section ssm2b +.section ssm3a +.section ssm3b +.section ssm4a +.section ssm4b +.section ssm5a +.section ssm5b +.section ssm6a +.section ssm6b +.section ssm7a +.section ssm7b +.section ssm8a +.section ssm8b +.section ssm9a +.section ssm9b +.section ssm0a +.section ssm0b +.section ssnaa +.section ssnab +.section ssnba +.section ssnbb +.section ssnca +.section ssncb +.section ssnda +.section ssndb +.section ssnea +.section ssneb +.section ssnfa +.section ssnfb +.section ssnga +.section ssngb +.section ssnha +.section ssnhb +.section ssnia +.section ssnib +.section ssnja +.section ssnjb +.section ssnka +.section ssnkb +.section ssnla +.section ssnlb +.section ssnma +.section ssnmb +.section ssnna +.section ssnnb +.section ssnoa +.section ssnob +.section ssnpa +.section ssnpb +.section ssnqa +.section ssnqb +.section ssnra +.section ssnrb +.section ssnsa +.section ssnsb +.section ssnta +.section ssntb +.section ssnua +.section ssnub +.section ssnva +.section ssnvb +.section ssnwa +.section ssnwb +.section ssnxa +.section ssnxb +.section ssnya +.section ssnyb +.section ssnza +.section ssnzb +.section ssn1a +.section ssn1b +.section ssn2a +.section ssn2b +.section ssn3a +.section ssn3b +.section ssn4a +.section ssn4b +.section ssn5a +.section ssn5b +.section ssn6a +.section ssn6b +.section ssn7a +.section ssn7b +.section ssn8a +.section ssn8b +.section ssn9a +.section ssn9b +.section ssn0a +.section ssn0b +.section ssoaa +.section ssoab +.section ssoba +.section ssobb +.section ssoca +.section ssocb +.section ssoda +.section ssodb +.section ssoea +.section ssoeb +.section ssofa +.section ssofb +.section ssoga +.section ssogb +.section ssoha +.section ssohb +.section ssoia +.section ssoib +.section ssoja +.section ssojb +.section ssoka +.section ssokb +.section ssola +.section ssolb +.section ssoma +.section ssomb +.section ssona +.section ssonb +.section ssooa +.section ssoob +.section ssopa +.section ssopb +.section ssoqa +.section ssoqb +.section ssora +.section ssorb +.section ssosa +.section ssosb +.section ssota +.section ssotb +.section ssoua +.section ssoub +.section ssova +.section ssovb +.section ssowa +.section ssowb +.section ssoxa +.section ssoxb +.section ssoya +.section ssoyb +.section ssoza +.section ssozb +.section sso1a +.section sso1b +.section sso2a +.section sso2b +.section sso3a +.section sso3b +.section sso4a +.section sso4b +.section sso5a +.section sso5b +.section sso6a +.section sso6b +.section sso7a +.section sso7b +.section sso8a +.section sso8b +.section sso9a +.section sso9b +.section sso0a +.section sso0b +.section sspaa +.section sspab +.section sspba +.section sspbb +.section sspca +.section sspcb +.section sspda +.section sspdb +.section sspea +.section sspeb +.section sspfa +.section sspfb +.section sspga +.section sspgb +.section sspha +.section ssphb +.section sspia +.section sspib +.section sspja +.section sspjb +.section sspka +.section sspkb +.section sspla +.section ssplb +.section sspma +.section sspmb +.section sspna +.section sspnb +.section sspoa +.section sspob +.section ssppa +.section ssppb +.section sspqa +.section sspqb +.section sspra +.section ssprb +.section sspsa +.section sspsb +.section sspta +.section ssptb +.section sspua +.section sspub +.section sspva +.section sspvb +.section sspwa +.section sspwb +.section sspxa +.section sspxb +.section sspya +.section sspyb +.section sspza +.section sspzb +.section ssp1a +.section ssp1b +.section ssp2a +.section ssp2b +.section ssp3a +.section ssp3b +.section ssp4a +.section ssp4b +.section ssp5a +.section ssp5b +.section ssp6a +.section ssp6b +.section ssp7a +.section ssp7b +.section ssp8a +.section ssp8b +.section ssp9a +.section ssp9b +.section ssp0a +.section ssp0b +.section ssqaa +.section ssqab +.section ssqba +.section ssqbb +.section ssqca +.section ssqcb +.section ssqda +.section ssqdb +.section ssqea +.section ssqeb +.section ssqfa +.section ssqfb +.section ssqga +.section ssqgb +.section ssqha +.section ssqhb +.section ssqia +.section ssqib +.section ssqja +.section ssqjb +.section ssqka +.section ssqkb +.section ssqla +.section ssqlb +.section ssqma +.section ssqmb +.section ssqna +.section ssqnb +.section ssqoa +.section ssqob +.section ssqpa +.section ssqpb +.section ssqqa +.section ssqqb +.section ssqra +.section ssqrb +.section ssqsa +.section ssqsb +.section ssqta +.section ssqtb +.section ssqua +.section ssqub +.section ssqva +.section ssqvb +.section ssqwa +.section ssqwb +.section ssqxa +.section ssqxb +.section ssqya +.section ssqyb +.section ssqza +.section ssqzb +.section ssq1a +.section ssq1b +.section ssq2a +.section ssq2b +.section ssq3a +.section ssq3b +.section ssq4a +.section ssq4b +.section ssq5a +.section ssq5b +.section ssq6a +.section ssq6b +.section ssq7a +.section ssq7b +.section ssq8a +.section ssq8b +.section ssq9a +.section ssq9b +.section ssq0a +.section ssq0b +.section ssraa +.section ssrab +.section ssrba +.section ssrbb +.section ssrca +.section ssrcb +.section ssrda +.section ssrdb +.section ssrea +.section ssreb +.section ssrfa +.section ssrfb +.section ssrga +.section ssrgb +.section ssrha +.section ssrhb +.section ssria +.section ssrib +.section ssrja +.section ssrjb +.section ssrka +.section ssrkb +.section ssrla +.section ssrlb +.section ssrma +.section ssrmb +.section ssrna +.section ssrnb +.section ssroa +.section ssrob +.section ssrpa +.section ssrpb +.section ssrqa +.section ssrqb +.section ssrra +.section ssrrb +.section ssrsa +.section ssrsb +.section ssrta +.section ssrtb +.section ssrua +.section ssrub +.section ssrva +.section ssrvb +.section ssrwa +.section ssrwb +.section ssrxa +.section ssrxb +.section ssrya +.section ssryb +.section ssrza +.section ssrzb +.section ssr1a +.section ssr1b +.section ssr2a +.section ssr2b +.section ssr3a +.section ssr3b +.section ssr4a +.section ssr4b +.section ssr5a +.section ssr5b +.section ssr6a +.section ssr6b +.section ssr7a +.section ssr7b +.section ssr8a +.section ssr8b +.section ssr9a +.section ssr9b +.section ssr0a +.section ssr0b +.section sssaa +.section sssab +.section sssba +.section sssbb +.section sssca +.section ssscb +.section sssda +.section sssdb +.section sssea +.section ssseb +.section sssfa +.section sssfb +.section sssga +.section sssgb +.section sssha +.section ssshb +.section sssia +.section sssib +.section sssja +.section sssjb +.section ssska +.section ssskb +.section sssla +.section ssslb +.section sssma +.section sssmb +.section sssna +.section sssnb +.section sssoa +.section sssob +.section ssspa +.section ssspb +.section sssqa +.section sssqb +.section sssra +.section sssrb +.section ssssa +.section ssssb +.section sssta +.section ssstb +.section sssua +.section sssub +.section sssva +.section sssvb +.section ssswa +.section ssswb +.section sssxa +.section sssxb +.section sssya +.section sssyb +.section sssza +.section ssszb +.section sss1a +.section sss1b +.section sss2a +.section sss2b +.section sss3a +.section sss3b +.section sss4a +.section sss4b +.section sss5a +.section sss5b +.section sss6a +.section sss6b +.section sss7a +.section sss7b +.section sss8a +.section sss8b +.section sss9a +.section sss9b +.section sss0a +.section sss0b +.section sstaa +.section sstab +.section sstba +.section sstbb +.section sstca +.section sstcb +.section sstda +.section sstdb +.section sstea +.section ssteb +.section sstfa +.section sstfb +.section sstga +.section sstgb +.section sstha +.section ssthb +.section sstia +.section sstib +.section sstja +.section sstjb +.section sstka +.section sstkb +.section sstla +.section sstlb +.section sstma +.section sstmb +.section sstna +.section sstnb +.section sstoa +.section sstob +.section sstpa +.section sstpb +.section sstqa +.section sstqb +.section sstra +.section sstrb +.section sstsa +.section sstsb +.section sstta +.section ssttb +.section sstua +.section sstub +.section sstva +.section sstvb +.section sstwa +.section sstwb +.section sstxa +.section sstxb +.section sstya +.section sstyb +.section sstza +.section sstzb +.section sst1a +.section sst1b +.section sst2a +.section sst2b +.section sst3a +.section sst3b +.section sst4a +.section sst4b +.section sst5a +.section sst5b +.section sst6a +.section sst6b +.section sst7a +.section sst7b +.section sst8a +.section sst8b +.section sst9a +.section sst9b +.section sst0a +.section sst0b +.section ssuaa +.section ssuab +.section ssuba +.section ssubb +.section ssuca +.section ssucb +.section ssuda +.section ssudb +.section ssuea +.section ssueb +.section ssufa +.section ssufb +.section ssuga +.section ssugb +.section ssuha +.section ssuhb +.section ssuia +.section ssuib +.section ssuja +.section ssujb +.section ssuka +.section ssukb +.section ssula +.section ssulb +.section ssuma +.section ssumb +.section ssuna +.section ssunb +.section ssuoa +.section ssuob +.section ssupa +.section ssupb +.section ssuqa +.section ssuqb +.section ssura +.section ssurb +.section ssusa +.section ssusb +.section ssuta +.section ssutb +.section ssuua +.section ssuub +.section ssuva +.section ssuvb +.section ssuwa +.section ssuwb +.section ssuxa +.section ssuxb +.section ssuya +.section ssuyb +.section ssuza +.section ssuzb +.section ssu1a +.section ssu1b +.section ssu2a +.section ssu2b +.section ssu3a +.section ssu3b +.section ssu4a +.section ssu4b +.section ssu5a +.section ssu5b +.section ssu6a +.section ssu6b +.section ssu7a +.section ssu7b +.section ssu8a +.section ssu8b +.section ssu9a +.section ssu9b +.section ssu0a +.section ssu0b +.section ssvaa +.section ssvab +.section ssvba +.section ssvbb +.section ssvca +.section ssvcb +.section ssvda +.section ssvdb +.section ssvea +.section ssveb +.section ssvfa +.section ssvfb +.section ssvga +.section ssvgb +.section ssvha +.section ssvhb +.section ssvia +.section ssvib +.section ssvja +.section ssvjb +.section ssvka +.section ssvkb +.section ssvla +.section ssvlb +.section ssvma +.section ssvmb +.section ssvna +.section ssvnb +.section ssvoa +.section ssvob +.section ssvpa +.section ssvpb +.section ssvqa +.section ssvqb +.section ssvra +.section ssvrb +.section ssvsa +.section ssvsb +.section ssvta +.section ssvtb +.section ssvua +.section ssvub +.section ssvva +.section ssvvb +.section ssvwa +.section ssvwb +.section ssvxa +.section ssvxb +.section ssvya +.section ssvyb +.section ssvza +.section ssvzb +.section ssv1a +.section ssv1b +.section ssv2a +.section ssv2b +.section ssv3a +.section ssv3b +.section ssv4a +.section ssv4b +.section ssv5a +.section ssv5b +.section ssv6a +.section ssv6b +.section ssv7a +.section ssv7b +.section ssv8a +.section ssv8b +.section ssv9a +.section ssv9b +.section ssv0a +.section ssv0b +.section sswaa +.section sswab +.section sswba +.section sswbb +.section sswca +.section sswcb +.section sswda +.section sswdb +.section sswea +.section ssweb +.section sswfa +.section sswfb +.section sswga +.section sswgb +.section sswha +.section sswhb +.section sswia +.section sswib +.section sswja +.section sswjb +.section sswka +.section sswkb +.section sswla +.section sswlb +.section sswma +.section sswmb +.section sswna +.section sswnb +.section sswoa +.section sswob +.section sswpa +.section sswpb +.section sswqa +.section sswqb +.section sswra +.section sswrb +.section sswsa +.section sswsb +.section sswta +.section sswtb +.section sswua +.section sswub +.section sswva +.section sswvb +.section sswwa +.section sswwb +.section sswxa +.section sswxb +.section sswya +.section sswyb +.section sswza +.section sswzb +.section ssw1a +.section ssw1b +.section ssw2a +.section ssw2b +.section ssw3a +.section ssw3b +.section ssw4a +.section ssw4b +.section ssw5a +.section ssw5b +.section ssw6a +.section ssw6b +.section ssw7a +.section ssw7b +.section ssw8a +.section ssw8b +.section ssw9a +.section ssw9b +.section ssw0a +.section ssw0b +.section ssxaa +.section ssxab +.section ssxba +.section ssxbb +.section ssxca +.section ssxcb +.section ssxda +.section ssxdb +.section ssxea +.section ssxeb +.section ssxfa +.section ssxfb +.section ssxga +.section ssxgb +.section ssxha +.section ssxhb +.section ssxia +.section ssxib +.section ssxja +.section ssxjb +.section ssxka +.section ssxkb +.section ssxla +.section ssxlb +.section ssxma +.section ssxmb +.section ssxna +.section ssxnb +.section ssxoa +.section ssxob +.section ssxpa +.section ssxpb +.section ssxqa +.section ssxqb +.section ssxra +.section ssxrb +.section ssxsa +.section ssxsb +.section ssxta +.section ssxtb +.section ssxua +.section ssxub +.section ssxva +.section ssxvb +.section ssxwa +.section ssxwb +.section ssxxa +.section ssxxb +.section ssxya +.section ssxyb +.section ssxza +.section ssxzb +.section ssx1a +.section ssx1b +.section ssx2a +.section ssx2b +.section ssx3a +.section ssx3b +.section ssx4a +.section ssx4b +.section ssx5a +.section ssx5b +.section ssx6a +.section ssx6b +.section ssx7a +.section ssx7b +.section ssx8a +.section ssx8b +.section ssx9a +.section ssx9b +.section ssx0a +.section ssx0b +.section ssyaa +.section ssyab +.section ssyba +.section ssybb +.section ssyca +.section ssycb +.section ssyda +.section ssydb +.section ssyea +.section ssyeb +.section ssyfa +.section ssyfb +.section ssyga +.section ssygb +.section ssyha +.section ssyhb +.section ssyia +.section ssyib +.section ssyja +.section ssyjb +.section ssyka +.section ssykb +.section ssyla +.section ssylb +.section ssyma +.section ssymb +.section ssyna +.section ssynb +.section ssyoa +.section ssyob +.section ssypa +.section ssypb +.section ssyqa +.section ssyqb +.section ssyra +.section ssyrb +.section ssysa +.section ssysb +.section ssyta +.section ssytb +.section ssyua +.section ssyub +.section ssyva +.section ssyvb +.section ssywa +.section ssywb +.section ssyxa +.section ssyxb +.section ssyya +.section ssyyb +.section ssyza +.section ssyzb +.section ssy1a +.section ssy1b +.section ssy2a +.section ssy2b +.section ssy3a +.section ssy3b +.section ssy4a +.section ssy4b +.section ssy5a +.section ssy5b +.section ssy6a +.section ssy6b +.section ssy7a +.section ssy7b +.section ssy8a +.section ssy8b +.section ssy9a +.section ssy9b +.section ssy0a +.section ssy0b +.section sszaa +.section sszab +.section sszba +.section sszbb +.section sszca +.section sszcb +.section sszda +.section sszdb +.section sszea +.section sszeb +.section sszfa +.section sszfb +.section sszga +.section sszgb +.section sszha +.section sszhb +.section sszia +.section sszib +.section sszja +.section sszjb +.section sszka +.section sszkb +.section sszla +.section sszlb +.section sszma +.section sszmb +.section sszna +.section ssznb +.section sszoa +.section sszob +.section sszpa +.section sszpb +.section sszqa +.section sszqb +.section sszra +.section sszrb +.section sszsa +.section sszsb +.section sszta +.section ssztb +.section sszua +.section sszub +.section sszva +.section sszvb +.section sszwa +.section sszwb +.section sszxa +.section sszxb +.section sszya +.section sszyb +.section sszza +.section sszzb +.section ssz1a +.section ssz1b +.section ssz2a +.section ssz2b +.section ssz3a +.section ssz3b +.section ssz4a +.section ssz4b +.section ssz5a +.section ssz5b +.section ssz6a +.section ssz6b +.section ssz7a +.section ssz7b +.section ssz8a +.section ssz8b +.section ssz9a +.section ssz9b +.section ssz0a +.section ssz0b +.section ss1aa +.section ss1ab +.section ss1ba +.section ss1bb +.section ss1ca +.section ss1cb +.section ss1da +.section ss1db +.section ss1ea +.section ss1eb +.section ss1fa +.section ss1fb +.section ss1ga +.section ss1gb +.section ss1ha +.section ss1hb +.section ss1ia +.section ss1ib +.section ss1ja +.section ss1jb +.section ss1ka +.section ss1kb +.section ss1la +.section ss1lb +.section ss1ma +.section ss1mb +.section ss1na +.section ss1nb +.section ss1oa +.section ss1ob +.section ss1pa +.section ss1pb +.section ss1qa +.section ss1qb +.section ss1ra +.section ss1rb +.section ss1sa +.section ss1sb +.section ss1ta +.section ss1tb +.section ss1ua +.section ss1ub +.section ss1va +.section ss1vb +.section ss1wa +.section ss1wb +.section ss1xa +.section ss1xb +.section ss1ya +.section ss1yb +.section ss1za +.section ss1zb +.section ss11a +.section ss11b +.section ss12a +.section ss12b +.section ss13a +.section ss13b +.section ss14a +.section ss14b +.section ss15a +.section ss15b +.section ss16a +.section ss16b +.section ss17a +.section ss17b +.section ss18a +.section ss18b +.section ss19a +.section ss19b +.section ss10a +.section ss10b +.section ss2aa +.section ss2ab +.section ss2ba +.section ss2bb +.section ss2ca +.section ss2cb +.section ss2da +.section ss2db +.section ss2ea +.section ss2eb +.section ss2fa +.section ss2fb +.section ss2ga +.section ss2gb +.section ss2ha +.section ss2hb +.section ss2ia +.section ss2ib +.section ss2ja +.section ss2jb +.section ss2ka +.section ss2kb +.section ss2la +.section ss2lb +.section ss2ma +.section ss2mb +.section ss2na +.section ss2nb +.section ss2oa +.section ss2ob +.section ss2pa +.section ss2pb +.section ss2qa +.section ss2qb +.section ss2ra +.section ss2rb +.section ss2sa +.section ss2sb +.section ss2ta +.section ss2tb +.section ss2ua +.section ss2ub +.section ss2va +.section ss2vb +.section ss2wa +.section ss2wb +.section ss2xa +.section ss2xb +.section ss2ya +.section ss2yb +.section ss2za +.section ss2zb +.section ss21a +.section ss21b +.section ss22a +.section ss22b +.section ss23a +.section ss23b +.section ss24a +.section ss24b +.section ss25a +.section ss25b +.section ss26a +.section ss26b +.section ss27a +.section ss27b +.section ss28a +.section ss28b +.section ss29a +.section ss29b +.section ss20a +.section ss20b +.section ss3aa +.section ss3ab +.section ss3ba +.section ss3bb +.section ss3ca +.section ss3cb +.section ss3da +.section ss3db +.section ss3ea +.section ss3eb +.section ss3fa +.section ss3fb +.section ss3ga +.section ss3gb +.section ss3ha +.section ss3hb +.section ss3ia +.section ss3ib +.section ss3ja +.section ss3jb +.section ss3ka +.section ss3kb +.section ss3la +.section ss3lb +.section ss3ma +.section ss3mb +.section ss3na +.section ss3nb +.section ss3oa +.section ss3ob +.section ss3pa +.section ss3pb +.section ss3qa +.section ss3qb +.section ss3ra +.section ss3rb +.section ss3sa +.section ss3sb +.section ss3ta +.section ss3tb +.section ss3ua +.section ss3ub +.section ss3va +.section ss3vb +.section ss3wa +.section ss3wb +.section ss3xa +.section ss3xb +.section ss3ya +.section ss3yb +.section ss3za +.section ss3zb +.section ss31a +.section ss31b +.section ss32a +.section ss32b +.section ss33a +.section ss33b +.section ss34a +.section ss34b +.section ss35a +.section ss35b +.section ss36a +.section ss36b +.section ss37a +.section ss37b +.section ss38a +.section ss38b +.section ss39a +.section ss39b +.section ss30a +.section ss30b +.section ss4aa +.section ss4ab +.section ss4ba +.section ss4bb +.section ss4ca +.section ss4cb +.section ss4da +.section ss4db +.section ss4ea +.section ss4eb +.section ss4fa +.section ss4fb +.section ss4ga +.section ss4gb +.section ss4ha +.section ss4hb +.section ss4ia +.section ss4ib +.section ss4ja +.section ss4jb +.section ss4ka +.section ss4kb +.section ss4la +.section ss4lb +.section ss4ma +.section ss4mb +.section ss4na +.section ss4nb +.section ss4oa +.section ss4ob +.section ss4pa +.section ss4pb +.section ss4qa +.section ss4qb +.section ss4ra +.section ss4rb +.section ss4sa +.section ss4sb +.section ss4ta +.section ss4tb +.section ss4ua +.section ss4ub +.section ss4va +.section ss4vb +.section ss4wa +.section ss4wb +.section ss4xa +.section ss4xb +.section ss4ya +.section ss4yb +.section ss4za +.section ss4zb +.section ss41a +.section ss41b +.section ss42a +.section ss42b +.section ss43a +.section ss43b +.section ss44a +.section ss44b +.section ss45a +.section ss45b +.section ss46a +.section ss46b +.section ss47a +.section ss47b +.section ss48a +.section ss48b +.section ss49a +.section ss49b +.section ss40a +.section ss40b +.section ss5aa +.section ss5ab +.section ss5ba +.section ss5bb +.section ss5ca +.section ss5cb +.section ss5da +.section ss5db +.section ss5ea +.section ss5eb +.section ss5fa +.section ss5fb +.section ss5ga +.section ss5gb +.section ss5ha +.section ss5hb +.section ss5ia +.section ss5ib +.section ss5ja +.section ss5jb +.section ss5ka +.section ss5kb +.section ss5la +.section ss5lb +.section ss5ma +.section ss5mb +.section ss5na +.section ss5nb +.section ss5oa +.section ss5ob +.section ss5pa +.section ss5pb +.section ss5qa +.section ss5qb +.section ss5ra +.section ss5rb +.section ss5sa +.section ss5sb +.section ss5ta +.section ss5tb +.section ss5ua +.section ss5ub +.section ss5va +.section ss5vb +.section ss5wa +.section ss5wb +.section ss5xa +.section ss5xb +.section ss5ya +.section ss5yb +.section ss5za +.section ss5zb +.section ss51a +.section ss51b +.section ss52a +.section ss52b +.section ss53a +.section ss53b +.section ss54a +.section ss54b +.section ss55a +.section ss55b +.section ss56a +.section ss56b +.section ss57a +.section ss57b +.section ss58a +.section ss58b +.section ss59a +.section ss59b +.section ss50a +.section ss50b +.section ss6aa +.section ss6ab +.section ss6ba +.section ss6bb +.section ss6ca +.section ss6cb +.section ss6da +.section ss6db +.section ss6ea +.section ss6eb +.section ss6fa +.section ss6fb +.section ss6ga +.section ss6gb +.section ss6ha +.section ss6hb +.section ss6ia +.section ss6ib +.section ss6ja +.section ss6jb +.section ss6ka +.section ss6kb +.section ss6la +.section ss6lb +.section ss6ma +.section ss6mb +.section ss6na +.section ss6nb +.section ss6oa +.section ss6ob +.section ss6pa +.section ss6pb +.section ss6qa +.section ss6qb +.section ss6ra +.section ss6rb +.section ss6sa +.section ss6sb +.section ss6ta +.section ss6tb +.section ss6ua +.section ss6ub +.section ss6va +.section ss6vb +.section ss6wa +.section ss6wb +.section ss6xa +.section ss6xb +.section ss6ya +.section ss6yb +.section ss6za +.section ss6zb +.section ss61a +.section ss61b +.section ss62a +.section ss62b +.section ss63a +.section ss63b +.section ss64a +.section ss64b +.section ss65a +.section ss65b +.section ss66a +.section ss66b +.section ss67a +.section ss67b +.section ss68a +.section ss68b +.section ss69a +.section ss69b +.section ss60a +.section ss60b +.section ss7aa +.section ss7ab +.section ss7ba +.section ss7bb +.section ss7ca +.section ss7cb +.section ss7da +.section ss7db +.section ss7ea +.section ss7eb +.section ss7fa +.section ss7fb +.section ss7ga +.section ss7gb +.section ss7ha +.section ss7hb +.section ss7ia +.section ss7ib +.section ss7ja +.section ss7jb +.section ss7ka +.section ss7kb +.section ss7la +.section ss7lb +.section ss7ma +.section ss7mb +.section ss7na +.section ss7nb +.section ss7oa +.section ss7ob +.section ss7pa +.section ss7pb +.section ss7qa +.section ss7qb +.section ss7ra +.section ss7rb +.section ss7sa +.section ss7sb +.section ss7ta +.section ss7tb +.section ss7ua +.section ss7ub +.section ss7va +.section ss7vb +.section ss7wa +.section ss7wb +.section ss7xa +.section ss7xb +.section ss7ya +.section ss7yb +.section ss7za +.section ss7zb +.section ss71a +.section ss71b +.section ss72a +.section ss72b +.section ss73a +.section ss73b +.section ss74a +.section ss74b +.section ss75a +.section ss75b +.section ss76a +.section ss76b +.section ss77a +.section ss77b +.section ss78a +.section ss78b +.section ss79a +.section ss79b +.section ss70a +.section ss70b +.section ss8aa +.section ss8ab +.section ss8ba +.section ss8bb +.section ss8ca +.section ss8cb +.section ss8da +.section ss8db +.section ss8ea +.section ss8eb +.section ss8fa +.section ss8fb +.section ss8ga +.section ss8gb +.section ss8ha +.section ss8hb +.section ss8ia +.section ss8ib +.section ss8ja +.section ss8jb +.section ss8ka +.section ss8kb +.section ss8la +.section ss8lb +.section ss8ma +.section ss8mb +.section ss8na +.section ss8nb +.section ss8oa +.section ss8ob +.section ss8pa +.section ss8pb +.section ss8qa +.section ss8qb +.section ss8ra +.section ss8rb +.section ss8sa +.section ss8sb +.section ss8ta +.section ss8tb +.section ss8ua +.section ss8ub +.section ss8va +.section ss8vb +.section ss8wa +.section ss8wb +.section ss8xa +.section ss8xb +.section ss8ya +.section ss8yb +.section ss8za +.section ss8zb +.section ss81a +.section ss81b +.section ss82a +.section ss82b +.section ss83a +.section ss83b +.section ss84a +.section ss84b +.section ss85a +.section ss85b +.section ss86a +.section ss86b +.section ss87a +.section ss87b +.section ss88a +.section ss88b +.section ss89a +.section ss89b +.section ss80a +.section ss80b +.section ss9aa +.section ss9ab +.section ss9ba +.section ss9bb +.section ss9ca +.section ss9cb +.section ss9da +.section ss9db +.section ss9ea +.section ss9eb +.section ss9fa +.section ss9fb +.section ss9ga +.section ss9gb +.section ss9ha +.section ss9hb +.section ss9ia +.section ss9ib +.section ss9ja +.section ss9jb +.section ss9ka +.section ss9kb +.section ss9la +.section ss9lb +.section ss9ma +.section ss9mb +.section ss9na +.section ss9nb +.section ss9oa +.section ss9ob +.section ss9pa +.section ss9pb +.section ss9qa +.section ss9qb +.section ss9ra +.section ss9rb +.section ss9sa +.section ss9sb +.section ss9ta +.section ss9tb +.section ss9ua +.section ss9ub +.section ss9va +.section ss9vb +.section ss9wa +.section ss9wb +.section ss9xa +.section ss9xb +.section ss9ya +.section ss9yb +.section ss9za +.section ss9zb +.section ss91a +.section ss91b +.section ss92a +.section ss92b +.section ss93a +.section ss93b +.section ss94a +.section ss94b +.section ss95a +.section ss95b +.section ss96a +.section ss96b +.section ss97a +.section ss97b +.section ss98a +.section ss98b +.section ss99a +.section ss99b +.section ss90a +.section ss90b +.section ss0aa +.section ss0ab +.section ss0ba +.section ss0bb +.section ss0ca +.section ss0cb +.section ss0da +.section ss0db +.section ss0ea +.section ss0eb +.section ss0fa +.section ss0fb +.section ss0ga +.section ss0gb +.section ss0ha +.section ss0hb +.section ss0ia +.section ss0ib +.section ss0ja +.section ss0jb +.section ss0ka +.section ss0kb +.section ss0la +.section ss0lb +.section ss0ma +.section ss0mb +.section ss0na +.section ss0nb +.section ss0oa +.section ss0ob +.section ss0pa +.section ss0pb +.section ss0qa +.section ss0qb +.section ss0ra +.section ss0rb +.section ss0sa +.section ss0sb +.section ss0ta +.section ss0tb +.section ss0ua +.section ss0ub +.section ss0va +.section ss0vb +.section ss0wa +.section ss0wb +.section ss0xa +.section ss0xb +.section ss0ya +.section ss0yb +.section ss0za +.section ss0zb +.section ss01a +.section ss01b +.section ss02a +.section ss02b +.section ss03a +.section ss03b +.section ss04a +.section ss04b +.section ss05a +.section ss05b +.section ss06a +.section ss06b +.section ss07a +.section ss07b +.section ss08a +.section ss08b +.section ss09a +.section ss09b +.section ss00a +.section ss00b +.section staaa +.section staab +.section staba +.section stabb +.section staca +.section stacb +.section stada +.section stadb +.section staea +.section staeb +.section stafa +.section stafb +.section staga +.section stagb +.section staha +.section stahb +.section staia +.section staib +.section staja +.section stajb +.section staka +.section stakb +.section stala +.section stalb +.section stama +.section stamb +.section stana +.section stanb +.section staoa +.section staob +.section stapa +.section stapb +.section staqa +.section staqb +.section stara +.section starb +.section stasa +.section stasb +.section stata +.section statb +.section staua +.section staub +.section stava +.section stavb +.section stawa +.section stawb +.section staxa +.section staxb +.section staya +.section stayb +.section staza +.section stazb +.section sta1a +.section sta1b +.section sta2a +.section sta2b +.section sta3a +.section sta3b +.section sta4a +.section sta4b +.section sta5a +.section sta5b +.section sta6a +.section sta6b +.section sta7a +.section sta7b +.section sta8a +.section sta8b +.section sta9a +.section sta9b +.section sta0a +.section sta0b +.section stbaa +.section stbab +.section stbba +.section stbbb +.section stbca +.section stbcb +.section stbda +.section stbdb +.section stbea +.section stbeb +.section stbfa +.section stbfb +.section stbga +.section stbgb +.section stbha +.section stbhb +.section stbia +.section stbib +.section stbja +.section stbjb +.section stbka +.section stbkb +.section stbla +.section stblb +.section stbma +.section stbmb +.section stbna +.section stbnb +.section stboa +.section stbob +.section stbpa +.section stbpb +.section stbqa +.section stbqb +.section stbra +.section stbrb +.section stbsa +.section stbsb +.section stbta +.section stbtb +.section stbua +.section stbub +.section stbva +.section stbvb +.section stbwa +.section stbwb +.section stbxa +.section stbxb +.section stbya +.section stbyb +.section stbza +.section stbzb +.section stb1a +.section stb1b +.section stb2a +.section stb2b +.section stb3a +.section stb3b +.section stb4a +.section stb4b +.section stb5a +.section stb5b +.section stb6a +.section stb6b +.section stb7a +.section stb7b +.section stb8a +.section stb8b +.section stb9a +.section stb9b +.section stb0a +.section stb0b +.section stcaa +.section stcab +.section stcba +.section stcbb +.section stcca +.section stccb +.section stcda +.section stcdb +.section stcea +.section stceb +.section stcfa +.section stcfb +.section stcga +.section stcgb +.section stcha +.section stchb +.section stcia +.section stcib +.section stcja +.section stcjb +.section stcka +.section stckb +.section stcla +.section stclb +.section stcma +.section stcmb +.section stcna +.section stcnb +.section stcoa +.section stcob +.section stcpa +.section stcpb +.section stcqa +.section stcqb +.section stcra +.section stcrb +.section stcsa +.section stcsb +.section stcta +.section stctb +.section stcua +.section stcub +.section stcva +.section stcvb +.section stcwa +.section stcwb +.section stcxa +.section stcxb +.section stcya +.section stcyb +.section stcza +.section stczb +.section stc1a +.section stc1b +.section stc2a +.section stc2b +.section stc3a +.section stc3b +.section stc4a +.section stc4b +.section stc5a +.section stc5b +.section stc6a +.section stc6b +.section stc7a +.section stc7b +.section stc8a +.section stc8b +.section stc9a +.section stc9b +.section stc0a +.section stc0b +.section stdaa +.section stdab +.section stdba +.section stdbb +.section stdca +.section stdcb +.section stdda +.section stddb +.section stdea +.section stdeb +.section stdfa +.section stdfb +.section stdga +.section stdgb +.section stdha +.section stdhb +.section stdia +.section stdib +.section stdja +.section stdjb +.section stdka +.section stdkb +.section stdla +.section stdlb +.section stdma +.section stdmb +.section stdna +.section stdnb +.section stdoa +.section stdob +.section stdpa +.section stdpb +.section stdqa +.section stdqb +.section stdra +.section stdrb +.section stdsa +.section stdsb +.section stdta +.section stdtb +.section stdua +.section stdub +.section stdva +.section stdvb +.section stdwa +.section stdwb +.section stdxa +.section stdxb +.section stdya +.section stdyb +.section stdza +.section stdzb +.section std1a +.section std1b +.section std2a +.section std2b +.section std3a +.section std3b +.section std4a +.section std4b +.section std5a +.section std5b +.section std6a +.section std6b +.section std7a +.section std7b +.section std8a +.section std8b +.section std9a +.section std9b +.section std0a +.section std0b +.section steaa +.section steab +.section steba +.section stebb +.section steca +.section stecb +.section steda +.section stedb +.section steea +.section steeb +.section stefa +.section stefb +.section stega +.section stegb +.section steha +.section stehb +.section steia +.section steib +.section steja +.section stejb +.section steka +.section stekb +.section stela +.section stelb +.section stema +.section stemb +.section stena +.section stenb +.section steoa +.section steob +.section stepa +.section stepb +.section steqa +.section steqb +.section stera +.section sterb +.section stesa +.section stesb +.section steta +.section stetb +.section steua +.section steub +.section steva +.section stevb +.section stewa +.section stewb +.section stexa +.section stexb +.section steya +.section steyb +.section steza +.section stezb +.section ste1a +.section ste1b +.section ste2a +.section ste2b +.section ste3a +.section ste3b +.section ste4a +.section ste4b +.section ste5a +.section ste5b +.section ste6a +.section ste6b +.section ste7a +.section ste7b +.section ste8a +.section ste8b +.section ste9a +.section ste9b +.section ste0a +.section ste0b +.section stfaa +.section stfab +.section stfba +.section stfbb +.section stfca +.section stfcb +.section stfda +.section stfdb +.section stfea +.section stfeb +.section stffa +.section stffb +.section stfga +.section stfgb +.section stfha +.section stfhb +.section stfia +.section stfib +.section stfja +.section stfjb +.section stfka +.section stfkb +.section stfla +.section stflb +.section stfma +.section stfmb +.section stfna +.section stfnb +.section stfoa +.section stfob +.section stfpa +.section stfpb +.section stfqa +.section stfqb +.section stfra +.section stfrb +.section stfsa +.section stfsb +.section stfta +.section stftb +.section stfua +.section stfub +.section stfva +.section stfvb +.section stfwa +.section stfwb +.section stfxa +.section stfxb +.section stfya +.section stfyb +.section stfza +.section stfzb +.section stf1a +.section stf1b +.section stf2a +.section stf2b +.section stf3a +.section stf3b +.section stf4a +.section stf4b +.section stf5a +.section stf5b +.section stf6a +.section stf6b +.section stf7a +.section stf7b +.section stf8a +.section stf8b +.section stf9a +.section stf9b +.section stf0a +.section stf0b +.section stgaa +.section stgab +.section stgba +.section stgbb +.section stgca +.section stgcb +.section stgda +.section stgdb +.section stgea +.section stgeb +.section stgfa +.section stgfb +.section stgga +.section stggb +.section stgha +.section stghb +.section stgia +.section stgib +.section stgja +.section stgjb +.section stgka +.section stgkb +.section stgla +.section stglb +.section stgma +.section stgmb +.section stgna +.section stgnb +.section stgoa +.section stgob +.section stgpa +.section stgpb +.section stgqa +.section stgqb +.section stgra +.section stgrb +.section stgsa +.section stgsb +.section stgta +.section stgtb +.section stgua +.section stgub +.section stgva +.section stgvb +.section stgwa +.section stgwb +.section stgxa +.section stgxb +.section stgya +.section stgyb +.section stgza +.section stgzb +.section stg1a +.section stg1b +.section stg2a +.section stg2b +.section stg3a +.section stg3b +.section stg4a +.section stg4b +.section stg5a +.section stg5b +.section stg6a +.section stg6b +.section stg7a +.section stg7b +.section stg8a +.section stg8b +.section stg9a +.section stg9b +.section stg0a +.section stg0b +.section sthaa +.section sthab +.section sthba +.section sthbb +.section sthca +.section sthcb +.section sthda +.section sthdb +.section sthea +.section stheb +.section sthfa +.section sthfb +.section sthga +.section sthgb +.section sthha +.section sthhb +.section sthia +.section sthib +.section sthja +.section sthjb +.section sthka +.section sthkb +.section sthla +.section sthlb +.section sthma +.section sthmb +.section sthna +.section sthnb +.section sthoa +.section sthob +.section sthpa +.section sthpb +.section sthqa +.section sthqb +.section sthra +.section sthrb +.section sthsa +.section sthsb +.section sthta +.section sthtb +.section sthua +.section sthub +.section sthva +.section sthvb +.section sthwa +.section sthwb +.section sthxa +.section sthxb +.section sthya +.section sthyb +.section sthza +.section sthzb +.section sth1a +.section sth1b +.section sth2a +.section sth2b +.section sth3a +.section sth3b +.section sth4a +.section sth4b +.section sth5a +.section sth5b +.section sth6a +.section sth6b +.section sth7a +.section sth7b +.section sth8a +.section sth8b +.section sth9a +.section sth9b +.section sth0a +.section sth0b +.section stiaa +.section stiab +.section stiba +.section stibb +.section stica +.section sticb +.section stida +.section stidb +.section stiea +.section stieb +.section stifa +.section stifb +.section stiga +.section stigb +.section stiha +.section stihb +.section stiia +.section stiib +.section stija +.section stijb +.section stika +.section stikb +.section stila +.section stilb +.section stima +.section stimb +.section stina +.section stinb +.section stioa +.section stiob +.section stipa +.section stipb +.section stiqa +.section stiqb +.section stira +.section stirb +.section stisa +.section stisb +.section stita +.section stitb +.section stiua +.section stiub +.section stiva +.section stivb +.section stiwa +.section stiwb +.section stixa +.section stixb +.section stiya +.section stiyb +.section stiza +.section stizb +.section sti1a +.section sti1b +.section sti2a +.section sti2b +.section sti3a +.section sti3b +.section sti4a +.section sti4b +.section sti5a +.section sti5b +.section sti6a +.section sti6b +.section sti7a +.section sti7b +.section sti8a +.section sti8b +.section sti9a +.section sti9b +.section sti0a +.section sti0b +.section stjaa +.section stjab +.section stjba +.section stjbb +.section stjca +.section stjcb +.section stjda +.section stjdb +.section stjea +.section stjeb +.section stjfa +.section stjfb +.section stjga +.section stjgb +.section stjha +.section stjhb +.section stjia +.section stjib +.section stjja +.section stjjb +.section stjka +.section stjkb +.section stjla +.section stjlb +.section stjma +.section stjmb +.section stjna +.section stjnb +.section stjoa +.section stjob +.section stjpa +.section stjpb +.section stjqa +.section stjqb +.section stjra +.section stjrb +.section stjsa +.section stjsb +.section stjta +.section stjtb +.section stjua +.section stjub +.section stjva +.section stjvb +.section stjwa +.section stjwb +.section stjxa +.section stjxb +.section stjya +.section stjyb +.section stjza +.section stjzb +.section stj1a +.section stj1b +.section stj2a +.section stj2b +.section stj3a +.section stj3b +.section stj4a +.section stj4b +.section stj5a +.section stj5b +.section stj6a +.section stj6b +.section stj7a +.section stj7b +.section stj8a +.section stj8b +.section stj9a +.section stj9b +.section stj0a +.section stj0b +.section stkaa +.section stkab +.section stkba +.section stkbb +.section stkca +.section stkcb +.section stkda +.section stkdb +.section stkea +.section stkeb +.section stkfa +.section stkfb +.section stkga +.section stkgb +.section stkha +.section stkhb +.section stkia +.section stkib +.section stkja +.section stkjb +.section stkka +.section stkkb +.section stkla +.section stklb +.section stkma +.section stkmb +.section stkna +.section stknb +.section stkoa +.section stkob +.section stkpa +.section stkpb +.section stkqa +.section stkqb +.section stkra +.section stkrb +.section stksa +.section stksb +.section stkta +.section stktb +.section stkua +.section stkub +.section stkva +.section stkvb +.section stkwa +.section stkwb +.section stkxa +.section stkxb +.section stkya +.section stkyb +.section stkza +.section stkzb +.section stk1a +.section stk1b +.section stk2a +.section stk2b +.section stk3a +.section stk3b +.section stk4a +.section stk4b +.section stk5a +.section stk5b +.section stk6a +.section stk6b +.section stk7a +.section stk7b +.section stk8a +.section stk8b +.section stk9a +.section stk9b +.section stk0a +.section stk0b +.section stlaa +.section stlab +.section stlba +.section stlbb +.section stlca +.section stlcb +.section stlda +.section stldb +.section stlea +.section stleb +.section stlfa +.section stlfb +.section stlga +.section stlgb +.section stlha +.section stlhb +.section stlia +.section stlib +.section stlja +.section stljb +.section stlka +.section stlkb +.section stlla +.section stllb +.section stlma +.section stlmb +.section stlna +.section stlnb +.section stloa +.section stlob +.section stlpa +.section stlpb +.section stlqa +.section stlqb +.section stlra +.section stlrb +.section stlsa +.section stlsb +.section stlta +.section stltb +.section stlua +.section stlub +.section stlva +.section stlvb +.section stlwa +.section stlwb +.section stlxa +.section stlxb +.section stlya +.section stlyb +.section stlza +.section stlzb +.section stl1a +.section stl1b +.section stl2a +.section stl2b +.section stl3a +.section stl3b +.section stl4a +.section stl4b +.section stl5a +.section stl5b +.section stl6a +.section stl6b +.section stl7a +.section stl7b +.section stl8a +.section stl8b +.section stl9a +.section stl9b +.section stl0a +.section stl0b +.section stmaa +.section stmab +.section stmba +.section stmbb +.section stmca +.section stmcb +.section stmda +.section stmdb +.section stmea +.section stmeb +.section stmfa +.section stmfb +.section stmga +.section stmgb +.section stmha +.section stmhb +.section stmia +.section stmib +.section stmja +.section stmjb +.section stmka +.section stmkb +.section stmla +.section stmlb +.section stmma +.section stmmb +.section stmna +.section stmnb +.section stmoa +.section stmob +.section stmpa +.section stmpb +.section stmqa +.section stmqb +.section stmra +.section stmrb +.section stmsa +.section stmsb +.section stmta +.section stmtb +.section stmua +.section stmub +.section stmva +.section stmvb +.section stmwa +.section stmwb +.section stmxa +.section stmxb +.section stmya +.section stmyb +.section stmza +.section stmzb +.section stm1a +.section stm1b +.section stm2a +.section stm2b +.section stm3a +.section stm3b +.section stm4a +.section stm4b +.section stm5a +.section stm5b +.section stm6a +.section stm6b +.section stm7a +.section stm7b +.section stm8a +.section stm8b +.section stm9a +.section stm9b +.section stm0a +.section stm0b +.section stnaa +.section stnab +.section stnba +.section stnbb +.section stnca +.section stncb +.section stnda +.section stndb +.section stnea +.section stneb +.section stnfa +.section stnfb +.section stnga +.section stngb +.section stnha +.section stnhb +.section stnia +.section stnib +.section stnja +.section stnjb +.section stnka +.section stnkb +.section stnla +.section stnlb +.section stnma +.section stnmb +.section stnna +.section stnnb +.section stnoa +.section stnob +.section stnpa +.section stnpb +.section stnqa +.section stnqb +.section stnra +.section stnrb +.section stnsa +.section stnsb +.section stnta +.section stntb +.section stnua +.section stnub +.section stnva +.section stnvb +.section stnwa +.section stnwb +.section stnxa +.section stnxb +.section stnya +.section stnyb +.section stnza +.section stnzb +.section stn1a +.section stn1b +.section stn2a +.section stn2b +.section stn3a +.section stn3b +.section stn4a +.section stn4b +.section stn5a +.section stn5b +.section stn6a +.section stn6b +.section stn7a +.section stn7b +.section stn8a +.section stn8b +.section stn9a +.section stn9b +.section stn0a +.section stn0b +.section stoaa +.section stoab +.section stoba +.section stobb +.section stoca +.section stocb +.section stoda +.section stodb +.section stoea +.section stoeb +.section stofa +.section stofb +.section stoga +.section stogb +.section stoha +.section stohb +.section stoia +.section stoib +.section stoja +.section stojb +.section stoka +.section stokb +.section stola +.section stolb +.section stoma +.section stomb +.section stona +.section stonb +.section stooa +.section stoob +.section stopa +.section stopb +.section stoqa +.section stoqb +.section stora +.section storb +.section stosa +.section stosb +.section stota +.section stotb +.section stoua +.section stoub +.section stova +.section stovb +.section stowa +.section stowb +.section stoxa +.section stoxb +.section stoya +.section stoyb +.section stoza +.section stozb +.section sto1a +.section sto1b +.section sto2a +.section sto2b +.section sto3a +.section sto3b +.section sto4a +.section sto4b +.section sto5a +.section sto5b +.section sto6a +.section sto6b +.section sto7a +.section sto7b +.section sto8a +.section sto8b +.section sto9a +.section sto9b +.section sto0a +.section sto0b +.section stpaa +.section stpab +.section stpba +.section stpbb +.section stpca +.section stpcb +.section stpda +.section stpdb +.section stpea +.section stpeb +.section stpfa +.section stpfb +.section stpga +.section stpgb +.section stpha +.section stphb +.section stpia +.section stpib +.section stpja +.section stpjb +.section stpka +.section stpkb +.section stpla +.section stplb +.section stpma +.section stpmb +.section stpna +.section stpnb +.section stpoa +.section stpob +.section stppa +.section stppb +.section stpqa +.section stpqb +.section stpra +.section stprb +.section stpsa +.section stpsb +.section stpta +.section stptb +.section stpua +.section stpub +.section stpva +.section stpvb +.section stpwa +.section stpwb +.section stpxa +.section stpxb +.section stpya +.section stpyb +.section stpza +.section stpzb +.section stp1a +.section stp1b +.section stp2a +.section stp2b +.section stp3a +.section stp3b +.section stp4a +.section stp4b +.section stp5a +.section stp5b +.section stp6a +.section stp6b +.section stp7a +.section stp7b +.section stp8a +.section stp8b +.section stp9a +.section stp9b +.section stp0a +.section stp0b +.section stqaa +.section stqab +.section stqba +.section stqbb +.section stqca +.section stqcb +.section stqda +.section stqdb +.section stqea +.section stqeb +.section stqfa +.section stqfb +.section stqga +.section stqgb +.section stqha +.section stqhb +.section stqia +.section stqib +.section stqja +.section stqjb +.section stqka +.section stqkb +.section stqla +.section stqlb +.section stqma +.section stqmb +.section stqna +.section stqnb +.section stqoa +.section stqob +.section stqpa +.section stqpb +.section stqqa +.section stqqb +.section stqra +.section stqrb +.section stqsa +.section stqsb +.section stqta +.section stqtb +.section stqua +.section stqub +.section stqva +.section stqvb +.section stqwa +.section stqwb +.section stqxa +.section stqxb +.section stqya +.section stqyb +.section stqza +.section stqzb +.section stq1a +.section stq1b +.section stq2a +.section stq2b +.section stq3a +.section stq3b +.section stq4a +.section stq4b +.section stq5a +.section stq5b +.section stq6a +.section stq6b +.section stq7a +.section stq7b +.section stq8a +.section stq8b +.section stq9a +.section stq9b +.section stq0a +.section stq0b +.section straa +.section strab +.section strba +.section strbb +.section strca +.section strcb +.section strda +.section strdb +.section strea +.section streb +.section strfa +.section strfb +.section strga +.section strgb +.section strha +.section strhb +.section stria +.section strib +.section strja +.section strjb +.section strka +.section strkb +.section strla +.section strlb +.section strma +.section strmb +.section strna +.section strnb +.section stroa +.section strob +.section strpa +.section strpb +.section strqa +.section strqb +.section strra +.section strrb +.section strsa +.section strsb +.section strta +.section strtb +.section strua +.section strub +.section strva +.section strvb +.section strwa +.section strwb +.section strxa +.section strxb +.section strya +.section stryb +.section strza +.section strzb +.section str1a +.section str1b +.section str2a +.section str2b +.section str3a +.section str3b +.section str4a +.section str4b +.section str5a +.section str5b +.section str6a +.section str6b +.section str7a +.section str7b +.section str8a +.section str8b +.section str9a +.section str9b +.section str0a +.section str0b +.section stsaa +.section stsab +.section stsba +.section stsbb +.section stsca +.section stscb +.section stsda +.section stsdb +.section stsea +.section stseb +.section stsfa +.section stsfb +.section stsga +.section stsgb +.section stsha +.section stshb +.section stsia +.section stsib +.section stsja +.section stsjb +.section stska +.section stskb +.section stsla +.section stslb +.section stsma +.section stsmb +.section stsna +.section stsnb +.section stsoa +.section stsob +.section stspa +.section stspb +.section stsqa +.section stsqb +.section stsra +.section stsrb +.section stssa +.section stssb +.section ststa +.section ststb +.section stsua +.section stsub +.section stsva +.section stsvb +.section stswa +.section stswb +.section stsxa +.section stsxb +.section stsya +.section stsyb +.section stsza +.section stszb +.section sts1a +.section sts1b +.section sts2a +.section sts2b +.section sts3a +.section sts3b +.section sts4a +.section sts4b +.section sts5a +.section sts5b +.section sts6a +.section sts6b +.section sts7a +.section sts7b +.section sts8a +.section sts8b +.section sts9a +.section sts9b +.section sts0a +.section sts0b +.section sttaa +.section sttab +.section sttba +.section sttbb +.section sttca +.section sttcb +.section sttda +.section sttdb +.section sttea +.section stteb +.section sttfa +.section sttfb +.section sttga +.section sttgb +.section sttha +.section stthb +.section sttia +.section sttib +.section sttja +.section sttjb +.section sttka +.section sttkb +.section sttla +.section sttlb +.section sttma +.section sttmb +.section sttna +.section sttnb +.section sttoa +.section sttob +.section sttpa +.section sttpb +.section sttqa +.section sttqb +.section sttra +.section sttrb +.section sttsa +.section sttsb +.section sttta +.section stttb +.section sttua +.section sttub +.section sttva +.section sttvb +.section sttwa +.section sttwb +.section sttxa +.section sttxb +.section sttya +.section sttyb +.section sttza +.section sttzb +.section stt1a +.section stt1b +.section stt2a +.section stt2b +.section stt3a +.section stt3b +.section stt4a +.section stt4b +.section stt5a +.section stt5b +.section stt6a +.section stt6b +.section stt7a +.section stt7b +.section stt8a +.section stt8b +.section stt9a +.section stt9b +.section stt0a +.section stt0b +.section stuaa +.section stuab +.section stuba +.section stubb +.section stuca +.section stucb +.section studa +.section studb +.section stuea +.section stueb +.section stufa +.section stufb +.section stuga +.section stugb +.section stuha +.section stuhb +.section stuia +.section stuib +.section stuja +.section stujb +.section stuka +.section stukb +.section stula +.section stulb +.section stuma +.section stumb +.section stuna +.section stunb +.section stuoa +.section stuob +.section stupa +.section stupb +.section stuqa +.section stuqb +.section stura +.section sturb +.section stusa +.section stusb +.section stuta +.section stutb +.section stuua +.section stuub +.section stuva +.section stuvb +.section stuwa +.section stuwb +.section stuxa +.section stuxb +.section stuya +.section stuyb +.section stuza +.section stuzb +.section stu1a +.section stu1b +.section stu2a +.section stu2b +.section stu3a +.section stu3b +.section stu4a +.section stu4b +.section stu5a +.section stu5b +.section stu6a +.section stu6b +.section stu7a +.section stu7b +.section stu8a +.section stu8b +.section stu9a +.section stu9b +.section stu0a +.section stu0b +.section stvaa +.section stvab +.section stvba +.section stvbb +.section stvca +.section stvcb +.section stvda +.section stvdb +.section stvea +.section stveb +.section stvfa +.section stvfb +.section stvga +.section stvgb +.section stvha +.section stvhb +.section stvia +.section stvib +.section stvja +.section stvjb +.section stvka +.section stvkb +.section stvla +.section stvlb +.section stvma +.section stvmb +.section stvna +.section stvnb +.section stvoa +.section stvob +.section stvpa +.section stvpb +.section stvqa +.section stvqb +.section stvra +.section stvrb +.section stvsa +.section stvsb +.section stvta +.section stvtb +.section stvua +.section stvub +.section stvva +.section stvvb +.section stvwa +.section stvwb +.section stvxa +.section stvxb +.section stvya +.section stvyb +.section stvza +.section stvzb +.section stv1a +.section stv1b +.section stv2a +.section stv2b +.section stv3a +.section stv3b +.section stv4a +.section stv4b +.section stv5a +.section stv5b +.section stv6a +.section stv6b +.section stv7a +.section stv7b +.section stv8a +.section stv8b +.section stv9a +.section stv9b +.section stv0a +.section stv0b +.section stwaa +.section stwab +.section stwba +.section stwbb +.section stwca +.section stwcb +.section stwda +.section stwdb +.section stwea +.section stweb +.section stwfa +.section stwfb +.section stwga +.section stwgb +.section stwha +.section stwhb +.section stwia +.section stwib +.section stwja +.section stwjb +.section stwka +.section stwkb +.section stwla +.section stwlb +.section stwma +.section stwmb +.section stwna +.section stwnb +.section stwoa +.section stwob +.section stwpa +.section stwpb +.section stwqa +.section stwqb +.section stwra +.section stwrb +.section stwsa +.section stwsb +.section stwta +.section stwtb +.section stwua +.section stwub +.section stwva +.section stwvb +.section stwwa +.section stwwb +.section stwxa +.section stwxb +.section stwya +.section stwyb +.section stwza +.section stwzb +.section stw1a +.section stw1b +.section stw2a +.section stw2b +.section stw3a +.section stw3b +.section stw4a +.section stw4b +.section stw5a +.section stw5b +.section stw6a +.section stw6b +.section stw7a +.section stw7b +.section stw8a +.section stw8b +.section stw9a +.section stw9b +.section stw0a +.section stw0b +.section stxaa +.section stxab +.section stxba +.section stxbb +.section stxca +.section stxcb +.section stxda +.section stxdb +.section stxea +.section stxeb +.section stxfa +.section stxfb +.section stxga +.section stxgb +.section stxha +.section stxhb +.section stxia +.section stxib +.section stxja +.section stxjb +.section stxka +.section stxkb +.section stxla +.section stxlb +.section stxma +.section stxmb +.section stxna +.section stxnb +.section stxoa +.section stxob +.section stxpa +.section stxpb +.section stxqa +.section stxqb +.section stxra +.section stxrb +.section stxsa +.section stxsb +.section stxta +.section stxtb +.section stxua +.section stxub +.section stxva +.section stxvb +.section stxwa +.section stxwb +.section stxxa +.section stxxb +.section stxya +.section stxyb +.section stxza +.section stxzb +.section stx1a +.section stx1b +.section stx2a +.section stx2b +.section stx3a +.section stx3b +.section stx4a +.section stx4b +.section stx5a +.section stx5b +.section stx6a +.section stx6b +.section stx7a +.section stx7b +.section stx8a +.section stx8b +.section stx9a +.section stx9b +.section stx0a +.section stx0b +.section styaa +.section styab +.section styba +.section stybb +.section styca +.section stycb +.section styda +.section stydb +.section styea +.section styeb +.section styfa +.section styfb +.section styga +.section stygb +.section styha +.section styhb +.section styia +.section styib +.section styja +.section styjb +.section styka +.section stykb +.section styla +.section stylb +.section styma +.section stymb +.section styna +.section stynb +.section styoa +.section styob +.section stypa +.section stypb +.section styqa +.section styqb +.section styra +.section styrb +.section stysa +.section stysb +.section styta +.section stytb +.section styua +.section styub +.section styva +.section styvb +.section stywa +.section stywb +.section styxa +.section styxb +.section styya +.section styyb +.section styza +.section styzb +.section sty1a +.section sty1b +.section sty2a +.section sty2b +.section sty3a +.section sty3b +.section sty4a +.section sty4b +.section sty5a +.section sty5b +.section sty6a +.section sty6b +.section sty7a +.section sty7b +.section sty8a +.section sty8b +.section sty9a +.section sty9b +.section sty0a +.section sty0b +.section stzaa +.section stzab +.section stzba +.section stzbb +.section stzca +.section stzcb +.section stzda +.section stzdb +.section stzea +.section stzeb +.section stzfa +.section stzfb +.section stzga +.section stzgb +.section stzha +.section stzhb +.section stzia +.section stzib +.section stzja +.section stzjb +.section stzka +.section stzkb +.section stzla +.section stzlb +.section stzma +.section stzmb +.section stzna +.section stznb +.section stzoa +.section stzob +.section stzpa +.section stzpb +.section stzqa +.section stzqb +.section stzra +.section stzrb +.section stzsa +.section stzsb +.section stzta +.section stztb +.section stzua +.section stzub +.section stzva +.section stzvb +.section stzwa +.section stzwb +.section stzxa +.section stzxb +.section stzya +.section stzyb +.section stzza +.section stzzb +.section stz1a +.section stz1b +.section stz2a +.section stz2b +.section stz3a +.section stz3b +.section stz4a +.section stz4b +.section stz5a +.section stz5b +.section stz6a +.section stz6b +.section stz7a +.section stz7b +.section stz8a +.section stz8b +.section stz9a +.section stz9b +.section stz0a +.section stz0b +.section st1aa +.section st1ab +.section st1ba +.section st1bb +.section st1ca +.section st1cb +.section st1da +.section st1db +.section st1ea +.section st1eb +.section st1fa +.section st1fb +.section st1ga +.section st1gb +.section st1ha +.section st1hb +.section st1ia +.section st1ib +.section st1ja +.section st1jb +.section st1ka +.section st1kb +.section st1la +.section st1lb +.section st1ma +.section st1mb +.section st1na +.section st1nb +.section st1oa +.section st1ob +.section st1pa +.section st1pb +.section st1qa +.section st1qb +.section st1ra +.section st1rb +.section st1sa +.section st1sb +.section st1ta +.section st1tb +.section st1ua +.section st1ub +.section st1va +.section st1vb +.section st1wa +.section st1wb +.section st1xa +.section st1xb +.section st1ya +.section st1yb +.section st1za +.section st1zb +.section st11a +.section st11b +.section st12a +.section st12b +.section st13a +.section st13b +.section st14a +.section st14b +.section st15a +.section st15b +.section st16a +.section st16b +.section st17a +.section st17b +.section st18a +.section st18b +.section st19a +.section st19b +.section st10a +.section st10b +.section st2aa +.section st2ab +.section st2ba +.section st2bb +.section st2ca +.section st2cb +.section st2da +.section st2db +.section st2ea +.section st2eb +.section st2fa +.section st2fb +.section st2ga +.section st2gb +.section st2ha +.section st2hb +.section st2ia +.section st2ib +.section st2ja +.section st2jb +.section st2ka +.section st2kb +.section st2la +.section st2lb +.section st2ma +.section st2mb +.section st2na +.section st2nb +.section st2oa +.section st2ob +.section st2pa +.section st2pb +.section st2qa +.section st2qb +.section st2ra +.section st2rb +.section st2sa +.section st2sb +.section st2ta +.section st2tb +.section st2ua +.section st2ub +.section st2va +.section st2vb +.section st2wa +.section st2wb +.section st2xa +.section st2xb +.section st2ya +.section st2yb +.section st2za +.section st2zb +.section st21a +.section st21b +.section st22a +.section st22b +.section st23a +.section st23b +.section st24a +.section st24b +.section st25a +.section st25b +.section st26a +.section st26b +.section st27a +.section st27b +.section st28a +.section st28b +.section st29a +.section st29b +.section st20a +.section st20b +.section st3aa +.section st3ab +.section st3ba +.section st3bb +.section st3ca +.section st3cb +.section st3da +.section st3db +.section st3ea +.section st3eb +.section st3fa +.section st3fb +.section st3ga +.section st3gb +.section st3ha +.section st3hb +.section st3ia +.section st3ib +.section st3ja +.section st3jb +.section st3ka +.section st3kb +.section st3la +.section st3lb +.section st3ma +.section st3mb +.section st3na +.section st3nb +.section st3oa +.section st3ob +.section st3pa +.section st3pb +.section st3qa +.section st3qb +.section st3ra +.section st3rb +.section st3sa +.section st3sb +.section st3ta +.section st3tb +.section st3ua +.section st3ub +.section st3va +.section st3vb +.section st3wa +.section st3wb +.section st3xa +.section st3xb +.section st3ya +.section st3yb +.section st3za +.section st3zb +.section st31a +.section st31b +.section st32a +.section st32b +.section st33a +.section st33b +.section st34a +.section st34b +.section st35a +.section st35b +.section st36a +.section st36b +.section st37a +.section st37b +.section st38a +.section st38b +.section st39a +.section st39b +.section st30a +.section st30b +.section st4aa +.section st4ab +.section st4ba +.section st4bb +.section st4ca +.section st4cb +.section st4da +.section st4db +.section st4ea +.section st4eb +.section st4fa +.section st4fb +.section st4ga +.section st4gb +.section st4ha +.section st4hb +.section st4ia +.section st4ib +.section st4ja +.section st4jb +.section st4ka +.section st4kb +.section st4la +.section st4lb +.section st4ma +.section st4mb +.section st4na +.section st4nb +.section st4oa +.section st4ob +.section st4pa +.section st4pb +.section st4qa +.section st4qb +.section st4ra +.section st4rb +.section st4sa +.section st4sb +.section st4ta +.section st4tb +.section st4ua +.section st4ub +.section st4va +.section st4vb +.section st4wa +.section st4wb +.section st4xa +.section st4xb +.section st4ya +.section st4yb +.section st4za +.section st4zb +.section st41a +.section st41b +.section st42a +.section st42b +.section st43a +.section st43b +.section st44a +.section st44b +.section st45a +.section st45b +.section st46a +.section st46b +.section st47a +.section st47b +.section st48a +.section st48b +.section st49a +.section st49b +.section st40a +.section st40b +.section st5aa +.section st5ab +.section st5ba +.section st5bb +.section st5ca +.section st5cb +.section st5da +.section st5db +.section st5ea +.section st5eb +.section st5fa +.section st5fb +.section st5ga +.section st5gb +.section st5ha +.section st5hb +.section st5ia +.section st5ib +.section st5ja +.section st5jb +.section st5ka +.section st5kb +.section st5la +.section st5lb +.section st5ma +.section st5mb +.section st5na +.section st5nb +.section st5oa +.section st5ob +.section st5pa +.section st5pb +.section st5qa +.section st5qb +.section st5ra +.section st5rb +.section st5sa +.section st5sb +.section st5ta +.section st5tb +.section st5ua +.section st5ub +.section st5va +.section st5vb +.section st5wa +.section st5wb +.section st5xa +.section st5xb +.section st5ya +.section st5yb +.section st5za +.section st5zb +.section st51a +.section st51b +.section st52a +.section st52b +.section st53a +.section st53b +.section st54a +.section st54b +.section st55a +.section st55b +.section st56a +.section st56b +.section st57a +.section st57b +.section st58a +.section st58b +.section st59a +.section st59b +.section st50a +.section st50b +.section st6aa +.section st6ab +.section st6ba +.section st6bb +.section st6ca +.section st6cb +.section st6da +.section st6db +.section st6ea +.section st6eb +.section st6fa +.section st6fb +.section st6ga +.section st6gb +.section st6ha +.section st6hb +.section st6ia +.section st6ib +.section st6ja +.section st6jb +.section st6ka +.section st6kb +.section st6la +.section st6lb +.section st6ma +.section st6mb +.section st6na +.section st6nb +.section st6oa +.section st6ob +.section st6pa +.section st6pb +.section st6qa +.section st6qb +.section st6ra +.section st6rb +.section st6sa +.section st6sb +.section st6ta +.section st6tb +.section st6ua +.section st6ub +.section st6va +.section st6vb +.section st6wa +.section st6wb +.section st6xa +.section st6xb +.section st6ya +.section st6yb +.section st6za +.section st6zb +.section st61a +.section st61b +.section st62a +.section st62b +.section st63a +.section st63b +.section st64a +.section st64b +.section st65a +.section st65b +.section st66a +.section st66b +.section st67a +.section st67b +.section st68a +.section st68b +.section st69a +.section st69b +.section st60a +.section st60b +.section st7aa +.section st7ab +.section st7ba +.section st7bb +.section st7ca +.section st7cb +.section st7da +.section st7db +.section st7ea +.section st7eb +.section st7fa +.section st7fb +.section st7ga +.section st7gb +.section st7ha +.section st7hb +.section st7ia +.section st7ib +.section st7ja +.section st7jb +.section st7ka +.section st7kb +.section st7la +.section st7lb +.section st7ma +.section st7mb +.section st7na +.section st7nb +.section st7oa +.section st7ob +.section st7pa +.section st7pb +.section st7qa +.section st7qb +.section st7ra +.section st7rb +.section st7sa +.section st7sb +.section st7ta +.section st7tb +.section st7ua +.section st7ub +.section st7va +.section st7vb +.section st7wa +.section st7wb +.section st7xa +.section st7xb +.section st7ya +.section st7yb +.section st7za +.section st7zb +.section st71a +.section st71b +.section st72a +.section st72b +.section st73a +.section st73b +.section st74a +.section st74b +.section st75a +.section st75b +.section st76a +.section st76b +.section st77a +.section st77b +.section st78a +.section st78b +.section st79a +.section st79b +.section st70a +.section st70b +.section st8aa +.section st8ab +.section st8ba +.section st8bb +.section st8ca +.section st8cb +.section st8da +.section st8db +.section st8ea +.section st8eb +.section st8fa +.section st8fb +.section st8ga +.section st8gb +.section st8ha +.section st8hb +.section st8ia +.section st8ib +.section st8ja +.section st8jb +.section st8ka +.section st8kb +.section st8la +.section st8lb +.section st8ma +.section st8mb +.section st8na +.section st8nb +.section st8oa +.section st8ob +.section st8pa +.section st8pb +.section st8qa +.section st8qb +.section st8ra +.section st8rb +.section st8sa +.section st8sb +.section st8ta +.section st8tb +.section st8ua +.section st8ub +.section st8va +.section st8vb +.section st8wa +.section st8wb +.section st8xa +.section st8xb +.section st8ya +.section st8yb +.section st8za +.section st8zb +.section st81a +.section st81b +.section st82a +.section st82b +.section st83a +.section st83b +.section st84a +.section st84b +.section st85a +.section st85b +.section st86a +.section st86b +.section st87a +.section st87b +.section st88a +.section st88b +.section st89a +.section st89b +.section st80a +.section st80b +.section st9aa +.section st9ab +.section st9ba +.section st9bb +.section st9ca +.section st9cb +.section st9da +.section st9db +.section st9ea +.section st9eb +.section st9fa +.section st9fb +.section st9ga +.section st9gb +.section st9ha +.section st9hb +.section st9ia +.section st9ib +.section st9ja +.section st9jb +.section st9ka +.section st9kb +.section st9la +.section st9lb +.section st9ma +.section st9mb +.section st9na +.section st9nb +.section st9oa +.section st9ob +.section st9pa +.section st9pb +.section st9qa +.section st9qb +.section st9ra +.section st9rb +.section st9sa +.section st9sb +.section st9ta +.section st9tb +.section st9ua +.section st9ub +.section st9va +.section st9vb +.section st9wa +.section st9wb +.section st9xa +.section st9xb +.section st9ya +.section st9yb +.section st9za +.section st9zb +.section st91a +.section st91b +.section st92a +.section st92b +.section st93a +.section st93b +.section st94a +.section st94b +.section st95a +.section st95b +.section st96a +.section st96b +.section st97a +.section st97b +.section st98a +.section st98b +.section st99a +.section st99b +.section st90a +.section st90b +.section st0aa +.section st0ab +.section st0ba +.section st0bb +.section st0ca +.section st0cb +.section st0da +.section st0db +.section st0ea +.section st0eb +.section st0fa +.section st0fb +.section st0ga +.section st0gb +.section st0ha +.section st0hb +.section st0ia +.section st0ib +.section st0ja +.section st0jb +.section st0ka +.section st0kb +.section st0la +.section st0lb +.section st0ma +.section st0mb +.section st0na +.section st0nb +.section st0oa +.section st0ob +.section st0pa +.section st0pb +.section st0qa +.section st0qb +.section st0ra +.section st0rb +.section st0sa +.section st0sb +.section st0ta +.section st0tb +.section st0ua +.section st0ub +.section st0va +.section st0vb +.section st0wa +.section st0wb +.section st0xa +.section st0xb +.section st0ya +.section st0yb +.section st0za +.section st0zb +.section st01a +.section st01b +.section st02a +.section st02b +.section st03a +.section st03b +.section st04a +.section st04b +.section st05a +.section st05b +.section st06a +.section st06b +.section st07a +.section st07b +.section st08a +.section st08b +.section st09a +.section st09b +.section st00a +.section st00b +.section suaaa +.section suaab +.section suaba +.section suabb +.section suaca +.section suacb +.section suada +.section suadb +.section suaea +.section suaeb +.section suafa +.section suafb +.section suaga +.section suagb +.section suaha +.section suahb +.section suaia +.section suaib +.section suaja +.section suajb +.section suaka +.section suakb +.section suala +.section sualb +.section suama +.section suamb +.section suana +.section suanb +.section suaoa +.section suaob +.section suapa +.section suapb +.section suaqa +.section suaqb +.section suara +.section suarb +.section suasa +.section suasb +.section suata +.section suatb +.section suaua +.section suaub +.section suava +.section suavb +.section suawa +.section suawb +.section suaxa +.section suaxb +.section suaya +.section suayb +.section suaza +.section suazb +.section sua1a +.section sua1b +.section sua2a +.section sua2b +.section sua3a +.section sua3b +.section sua4a +.section sua4b +.section sua5a +.section sua5b +.section sua6a +.section sua6b +.section sua7a +.section sua7b +.section sua8a +.section sua8b +.section sua9a +.section sua9b +.section sua0a +.section sua0b +.section subaa +.section subab +.section subba +.section subbb +.section subca +.section subcb +.section subda +.section subdb +.section subea +.section subeb +.section subfa +.section subfb +.section subga +.section subgb +.section subha +.section subhb +.section subia +.section subib +.section subja +.section subjb +.section subka +.section subkb +.section subla +.section sublb +.section subma +.section submb +.section subna +.section subnb +.section suboa +.section subob +.section subpa +.section subpb +.section subqa +.section subqb +.section subra +.section subrb +.section subsa +.section subsb +.section subta +.section subtb +.section subua +.section subub +.section subva +.section subvb +.section subwa +.section subwb +.section subxa +.section subxb +.section subya +.section subyb +.section subza +.section subzb +.section sub1a +.section sub1b +.section sub2a +.section sub2b +.section sub3a +.section sub3b +.section sub4a +.section sub4b +.section sub5a +.section sub5b +.section sub6a +.section sub6b +.section sub7a +.section sub7b +.section sub8a +.section sub8b +.section sub9a +.section sub9b +.section sub0a +.section sub0b +.section sucaa +.section sucab +.section sucba +.section sucbb +.section succa +.section succb +.section sucda +.section sucdb +.section sucea +.section suceb +.section sucfa +.section sucfb +.section sucga +.section sucgb +.section sucha +.section suchb +.section sucia +.section sucib +.section sucja +.section sucjb +.section sucka +.section suckb +.section sucla +.section suclb +.section sucma +.section sucmb +.section sucna +.section sucnb +.section sucoa +.section sucob +.section sucpa +.section sucpb +.section sucqa +.section sucqb +.section sucra +.section sucrb +.section sucsa +.section sucsb +.section sucta +.section suctb +.section sucua +.section sucub +.section sucva +.section sucvb +.section sucwa +.section sucwb +.section sucxa +.section sucxb +.section sucya +.section sucyb +.section sucza +.section suczb +.section suc1a +.section suc1b +.section suc2a +.section suc2b +.section suc3a +.section suc3b +.section suc4a +.section suc4b +.section suc5a +.section suc5b +.section suc6a +.section suc6b +.section suc7a +.section suc7b +.section suc8a +.section suc8b +.section suc9a +.section suc9b +.section suc0a +.section suc0b +.section sudaa +.section sudab +.section sudba +.section sudbb +.section sudca +.section sudcb +.section sudda +.section suddb +.section sudea +.section sudeb +.section sudfa +.section sudfb +.section sudga +.section sudgb +.section sudha +.section sudhb +.section sudia +.section sudib +.section sudja +.section sudjb +.section sudka +.section sudkb +.section sudla +.section sudlb +.section sudma +.section sudmb +.section sudna +.section sudnb +.section sudoa +.section sudob +.section sudpa +.section sudpb +.section sudqa +.section sudqb +.section sudra +.section sudrb +.section sudsa +.section sudsb +.section sudta +.section sudtb +.section sudua +.section sudub +.section sudva +.section sudvb +.section sudwa +.section sudwb +.section sudxa +.section sudxb +.section sudya +.section sudyb +.section sudza +.section sudzb +.section sud1a +.section sud1b +.section sud2a +.section sud2b +.section sud3a +.section sud3b +.section sud4a +.section sud4b +.section sud5a +.section sud5b +.section sud6a +.section sud6b +.section sud7a +.section sud7b +.section sud8a +.section sud8b +.section sud9a +.section sud9b +.section sud0a +.section sud0b +.section sueaa +.section sueab +.section sueba +.section suebb +.section sueca +.section suecb +.section sueda +.section suedb +.section sueea +.section sueeb +.section suefa +.section suefb +.section suega +.section suegb +.section sueha +.section suehb +.section sueia +.section sueib +.section sueja +.section suejb +.section sueka +.section suekb +.section suela +.section suelb +.section suema +.section suemb +.section suena +.section suenb +.section sueoa +.section sueob +.section suepa +.section suepb +.section sueqa +.section sueqb +.section suera +.section suerb +.section suesa +.section suesb +.section sueta +.section suetb +.section sueua +.section sueub +.section sueva +.section suevb +.section suewa +.section suewb +.section suexa +.section suexb +.section sueya +.section sueyb +.section sueza +.section suezb +.section sue1a +.section sue1b +.section sue2a +.section sue2b +.section sue3a +.section sue3b +.section sue4a +.section sue4b +.section sue5a +.section sue5b +.section sue6a +.section sue6b +.section sue7a +.section sue7b +.section sue8a +.section sue8b +.section sue9a +.section sue9b +.section sue0a +.section sue0b +.section sufaa +.section sufab +.section sufba +.section sufbb +.section sufca +.section sufcb +.section sufda +.section sufdb +.section sufea +.section sufeb +.section suffa +.section suffb +.section sufga +.section sufgb +.section sufha +.section sufhb +.section sufia +.section sufib +.section sufja +.section sufjb +.section sufka +.section sufkb +.section sufla +.section suflb +.section sufma +.section sufmb +.section sufna +.section sufnb +.section sufoa +.section sufob +.section sufpa +.section sufpb +.section sufqa +.section sufqb +.section sufra +.section sufrb +.section sufsa +.section sufsb +.section sufta +.section suftb +.section sufua +.section sufub +.section sufva +.section sufvb +.section sufwa +.section sufwb +.section sufxa +.section sufxb +.section sufya +.section sufyb +.section sufza +.section sufzb +.section suf1a +.section suf1b +.section suf2a +.section suf2b +.section suf3a +.section suf3b +.section suf4a +.section suf4b +.section suf5a +.section suf5b +.section suf6a +.section suf6b +.section suf7a +.section suf7b +.section suf8a +.section suf8b +.section suf9a +.section suf9b +.section suf0a +.section suf0b +.section sugaa +.section sugab +.section sugba +.section sugbb +.section sugca +.section sugcb +.section sugda +.section sugdb +.section sugea +.section sugeb +.section sugfa +.section sugfb +.section sugga +.section suggb +.section sugha +.section sughb +.section sugia +.section sugib +.section sugja +.section sugjb +.section sugka +.section sugkb +.section sugla +.section suglb +.section sugma +.section sugmb +.section sugna +.section sugnb +.section sugoa +.section sugob +.section sugpa +.section sugpb +.section sugqa +.section sugqb +.section sugra +.section sugrb +.section sugsa +.section sugsb +.section sugta +.section sugtb +.section sugua +.section sugub +.section sugva +.section sugvb +.section sugwa +.section sugwb +.section sugxa +.section sugxb +.section sugya +.section sugyb +.section sugza +.section sugzb +.section sug1a +.section sug1b +.section sug2a +.section sug2b +.section sug3a +.section sug3b +.section sug4a +.section sug4b +.section sug5a +.section sug5b +.section sug6a +.section sug6b +.section sug7a +.section sug7b +.section sug8a +.section sug8b +.section sug9a +.section sug9b +.section sug0a +.section sug0b +.section suhaa +.section suhab +.section suhba +.section suhbb +.section suhca +.section suhcb +.section suhda +.section suhdb +.section suhea +.section suheb +.section suhfa +.section suhfb +.section suhga +.section suhgb +.section suhha +.section suhhb +.section suhia +.section suhib +.section suhja +.section suhjb +.section suhka +.section suhkb +.section suhla +.section suhlb +.section suhma +.section suhmb +.section suhna +.section suhnb +.section suhoa +.section suhob +.section suhpa +.section suhpb +.section suhqa +.section suhqb +.section suhra +.section suhrb +.section suhsa +.section suhsb +.section suhta +.section suhtb +.section suhua +.section suhub +.section suhva +.section suhvb +.section suhwa +.section suhwb +.section suhxa +.section suhxb +.section suhya +.section suhyb +.section suhza +.section suhzb +.section suh1a +.section suh1b +.section suh2a +.section suh2b +.section suh3a +.section suh3b +.section suh4a +.section suh4b +.section suh5a +.section suh5b +.section suh6a +.section suh6b +.section suh7a +.section suh7b +.section suh8a +.section suh8b +.section suh9a +.section suh9b +.section suh0a +.section suh0b +.section suiaa +.section suiab +.section suiba +.section suibb +.section suica +.section suicb +.section suida +.section suidb +.section suiea +.section suieb +.section suifa +.section suifb +.section suiga +.section suigb +.section suiha +.section suihb +.section suiia +.section suiib +.section suija +.section suijb +.section suika +.section suikb +.section suila +.section suilb +.section suima +.section suimb +.section suina +.section suinb +.section suioa +.section suiob +.section suipa +.section suipb +.section suiqa +.section suiqb +.section suira +.section suirb +.section suisa +.section suisb +.section suita +.section suitb +.section suiua +.section suiub +.section suiva +.section suivb +.section suiwa +.section suiwb +.section suixa +.section suixb +.section suiya +.section suiyb +.section suiza +.section suizb +.section sui1a +.section sui1b +.section sui2a +.section sui2b +.section sui3a +.section sui3b +.section sui4a +.section sui4b +.section sui5a +.section sui5b +.section sui6a +.section sui6b +.section sui7a +.section sui7b +.section sui8a +.section sui8b +.section sui9a +.section sui9b +.section sui0a +.section sui0b +.section sujaa +.section sujab +.section sujba +.section sujbb +.section sujca +.section sujcb +.section sujda +.section sujdb +.section sujea +.section sujeb +.section sujfa +.section sujfb +.section sujga +.section sujgb +.section sujha +.section sujhb +.section sujia +.section sujib +.section sujja +.section sujjb +.section sujka +.section sujkb +.section sujla +.section sujlb +.section sujma +.section sujmb +.section sujna +.section sujnb +.section sujoa +.section sujob +.section sujpa +.section sujpb +.section sujqa +.section sujqb +.section sujra +.section sujrb +.section sujsa +.section sujsb +.section sujta +.section sujtb +.section sujua +.section sujub +.section sujva +.section sujvb +.section sujwa +.section sujwb +.section sujxa +.section sujxb +.section sujya +.section sujyb +.section sujza +.section sujzb +.section suj1a +.section suj1b +.section suj2a +.section suj2b +.section suj3a +.section suj3b +.section suj4a +.section suj4b +.section suj5a +.section suj5b +.section suj6a +.section suj6b +.section suj7a +.section suj7b +.section suj8a +.section suj8b +.section suj9a +.section suj9b +.section suj0a +.section suj0b +.section sukaa +.section sukab +.section sukba +.section sukbb +.section sukca +.section sukcb +.section sukda +.section sukdb +.section sukea +.section sukeb +.section sukfa +.section sukfb +.section sukga +.section sukgb +.section sukha +.section sukhb +.section sukia +.section sukib +.section sukja +.section sukjb +.section sukka +.section sukkb +.section sukla +.section suklb +.section sukma +.section sukmb +.section sukna +.section suknb +.section sukoa +.section sukob +.section sukpa +.section sukpb +.section sukqa +.section sukqb +.section sukra +.section sukrb +.section suksa +.section suksb +.section sukta +.section suktb +.section sukua +.section sukub +.section sukva +.section sukvb +.section sukwa +.section sukwb +.section sukxa +.section sukxb +.section sukya +.section sukyb +.section sukza +.section sukzb +.section suk1a +.section suk1b +.section suk2a +.section suk2b +.section suk3a +.section suk3b +.section suk4a +.section suk4b +.section suk5a +.section suk5b +.section suk6a +.section suk6b +.section suk7a +.section suk7b +.section suk8a +.section suk8b +.section suk9a +.section suk9b +.section suk0a +.section suk0b +.section sulaa +.section sulab +.section sulba +.section sulbb +.section sulca +.section sulcb +.section sulda +.section suldb +.section sulea +.section suleb +.section sulfa +.section sulfb +.section sulga +.section sulgb +.section sulha +.section sulhb +.section sulia +.section sulib +.section sulja +.section suljb +.section sulka +.section sulkb +.section sulla +.section sullb +.section sulma +.section sulmb +.section sulna +.section sulnb +.section suloa +.section sulob +.section sulpa +.section sulpb +.section sulqa +.section sulqb +.section sulra +.section sulrb +.section sulsa +.section sulsb +.section sulta +.section sultb +.section sulua +.section sulub +.section sulva +.section sulvb +.section sulwa +.section sulwb +.section sulxa +.section sulxb +.section sulya +.section sulyb +.section sulza +.section sulzb +.section sul1a +.section sul1b +.section sul2a +.section sul2b +.section sul3a +.section sul3b +.section sul4a +.section sul4b +.section sul5a +.section sul5b +.section sul6a +.section sul6b +.section sul7a +.section sul7b +.section sul8a +.section sul8b +.section sul9a +.section sul9b +.section sul0a +.section sul0b +.section sumaa +.section sumab +.section sumba +.section sumbb +.section sumca +.section sumcb +.section sumda +.section sumdb +.section sumea +.section sumeb +.section sumfa +.section sumfb +.section sumga +.section sumgb +.section sumha +.section sumhb +.section sumia +.section sumib +.section sumja +.section sumjb +.section sumka +.section sumkb +.section sumla +.section sumlb +.section summa +.section summb +.section sumna +.section sumnb +.section sumoa +.section sumob +.section sumpa +.section sumpb +.section sumqa +.section sumqb +.section sumra +.section sumrb +.section sumsa +.section sumsb +.section sumta +.section sumtb +.section sumua +.section sumub +.section sumva +.section sumvb +.section sumwa +.section sumwb +.section sumxa +.section sumxb +.section sumya +.section sumyb +.section sumza +.section sumzb +.section sum1a +.section sum1b +.section sum2a +.section sum2b +.section sum3a +.section sum3b +.section sum4a +.section sum4b +.section sum5a +.section sum5b +.section sum6a +.section sum6b +.section sum7a +.section sum7b +.section sum8a +.section sum8b +.section sum9a +.section sum9b +.section sum0a +.section sum0b +.section sunaa +.section sunab +.section sunba +.section sunbb +.section sunca +.section suncb +.section sunda +.section sundb +.section sunea +.section suneb +.section sunfa +.section sunfb +.section sunga +.section sungb +.section sunha +.section sunhb +.section sunia +.section sunib +.section sunja +.section sunjb +.section sunka +.section sunkb +.section sunla +.section sunlb +.section sunma +.section sunmb +.section sunna +.section sunnb +.section sunoa +.section sunob +.section sunpa +.section sunpb +.section sunqa +.section sunqb +.section sunra +.section sunrb +.section sunsa +.section sunsb +.section sunta +.section suntb +.section sunua +.section sunub +.section sunva +.section sunvb +.section sunwa +.section sunwb +.section sunxa +.section sunxb +.section sunya +.section sunyb +.section sunza +.section sunzb +.section sun1a +.section sun1b +.section sun2a +.section sun2b +.section sun3a +.section sun3b +.section sun4a +.section sun4b +.section sun5a +.section sun5b +.section sun6a +.section sun6b +.section sun7a +.section sun7b +.section sun8a +.section sun8b +.section sun9a +.section sun9b +.section sun0a +.section sun0b +.section suoaa +.section suoab +.section suoba +.section suobb +.section suoca +.section suocb +.section suoda +.section suodb +.section suoea +.section suoeb +.section suofa +.section suofb +.section suoga +.section suogb +.section suoha +.section suohb +.section suoia +.section suoib +.section suoja +.section suojb +.section suoka +.section suokb +.section suola +.section suolb +.section suoma +.section suomb +.section suona +.section suonb +.section suooa +.section suoob +.section suopa +.section suopb +.section suoqa +.section suoqb +.section suora +.section suorb +.section suosa +.section suosb +.section suota +.section suotb +.section suoua +.section suoub +.section suova +.section suovb +.section suowa +.section suowb +.section suoxa +.section suoxb +.section suoya +.section suoyb +.section suoza +.section suozb +.section suo1a +.section suo1b +.section suo2a +.section suo2b +.section suo3a +.section suo3b +.section suo4a +.section suo4b +.section suo5a +.section suo5b +.section suo6a +.section suo6b +.section suo7a +.section suo7b +.section suo8a +.section suo8b +.section suo9a +.section suo9b +.section suo0a +.section suo0b +.section supaa +.section supab +.section supba +.section supbb +.section supca +.section supcb +.section supda +.section supdb +.section supea +.section supeb +.section supfa +.section supfb +.section supga +.section supgb +.section supha +.section suphb +.section supia +.section supib +.section supja +.section supjb +.section supka +.section supkb +.section supla +.section suplb +.section supma +.section supmb +.section supna +.section supnb +.section supoa +.section supob +.section suppa +.section suppb +.section supqa +.section supqb +.section supra +.section suprb +.section supsa +.section supsb +.section supta +.section suptb +.section supua +.section supub +.section supva +.section supvb +.section supwa +.section supwb +.section supxa +.section supxb +.section supya +.section supyb +.section supza +.section supzb +.section sup1a +.section sup1b +.section sup2a +.section sup2b +.section sup3a +.section sup3b +.section sup4a +.section sup4b +.section sup5a +.section sup5b +.section sup6a +.section sup6b +.section sup7a +.section sup7b +.section sup8a +.section sup8b +.section sup9a +.section sup9b +.section sup0a +.section sup0b +.section suqaa +.section suqab +.section suqba +.section suqbb +.section suqca +.section suqcb +.section suqda +.section suqdb +.section suqea +.section suqeb +.section suqfa +.section suqfb +.section suqga +.section suqgb +.section suqha +.section suqhb +.section suqia +.section suqib +.section suqja +.section suqjb +.section suqka +.section suqkb +.section suqla +.section suqlb +.section suqma +.section suqmb +.section suqna +.section suqnb +.section suqoa +.section suqob +.section suqpa +.section suqpb +.section suqqa +.section suqqb +.section suqra +.section suqrb +.section suqsa +.section suqsb +.section suqta +.section suqtb +.section suqua +.section suqub +.section suqva +.section suqvb +.section suqwa +.section suqwb +.section suqxa +.section suqxb +.section suqya +.section suqyb +.section suqza +.section suqzb +.section suq1a +.section suq1b +.section suq2a +.section suq2b +.section suq3a +.section suq3b +.section suq4a +.section suq4b +.section suq5a +.section suq5b +.section suq6a +.section suq6b +.section suq7a +.section suq7b +.section suq8a +.section suq8b +.section suq9a +.section suq9b +.section suq0a +.section suq0b +.section suraa +.section surab +.section surba +.section surbb +.section surca +.section surcb +.section surda +.section surdb +.section surea +.section sureb +.section surfa +.section surfb +.section surga +.section surgb +.section surha +.section surhb +.section suria +.section surib +.section surja +.section surjb +.section surka +.section surkb +.section surla +.section surlb +.section surma +.section surmb +.section surna +.section surnb +.section suroa +.section surob +.section surpa +.section surpb +.section surqa +.section surqb +.section surra +.section surrb +.section sursa +.section sursb +.section surta +.section surtb +.section surua +.section surub +.section surva +.section survb +.section surwa +.section surwb +.section surxa +.section surxb +.section surya +.section suryb +.section surza +.section surzb +.section sur1a +.section sur1b +.section sur2a +.section sur2b +.section sur3a +.section sur3b +.section sur4a +.section sur4b +.section sur5a +.section sur5b +.section sur6a +.section sur6b +.section sur7a +.section sur7b +.section sur8a +.section sur8b +.section sur9a +.section sur9b +.section sur0a +.section sur0b +.section susaa +.section susab +.section susba +.section susbb +.section susca +.section suscb +.section susda +.section susdb +.section susea +.section suseb +.section susfa +.section susfb +.section susga +.section susgb +.section susha +.section sushb +.section susia +.section susib +.section susja +.section susjb +.section suska +.section suskb +.section susla +.section suslb +.section susma +.section susmb +.section susna +.section susnb +.section susoa +.section susob +.section suspa +.section suspb +.section susqa +.section susqb +.section susra +.section susrb +.section sussa +.section sussb +.section susta +.section sustb +.section susua +.section susub +.section susva +.section susvb +.section suswa +.section suswb +.section susxa +.section susxb +.section susya +.section susyb +.section susza +.section suszb +.section sus1a +.section sus1b +.section sus2a +.section sus2b +.section sus3a +.section sus3b +.section sus4a +.section sus4b +.section sus5a +.section sus5b +.section sus6a +.section sus6b +.section sus7a +.section sus7b +.section sus8a +.section sus8b +.section sus9a +.section sus9b +.section sus0a +.section sus0b +.section sutaa +.section sutab +.section sutba +.section sutbb +.section sutca +.section sutcb +.section sutda +.section sutdb +.section sutea +.section suteb +.section sutfa +.section sutfb +.section sutga +.section sutgb +.section sutha +.section suthb +.section sutia +.section sutib +.section sutja +.section sutjb +.section sutka +.section sutkb +.section sutla +.section sutlb +.section sutma +.section sutmb +.section sutna +.section sutnb +.section sutoa +.section sutob +.section sutpa +.section sutpb +.section sutqa +.section sutqb +.section sutra +.section sutrb +.section sutsa +.section sutsb +.section sutta +.section suttb +.section sutua +.section sutub +.section sutva +.section sutvb +.section sutwa +.section sutwb +.section sutxa +.section sutxb +.section sutya +.section sutyb +.section sutza +.section sutzb +.section sut1a +.section sut1b +.section sut2a +.section sut2b +.section sut3a +.section sut3b +.section sut4a +.section sut4b +.section sut5a +.section sut5b +.section sut6a +.section sut6b +.section sut7a +.section sut7b +.section sut8a +.section sut8b +.section sut9a +.section sut9b +.section sut0a +.section sut0b +.section suuaa +.section suuab +.section suuba +.section suubb +.section suuca +.section suucb +.section suuda +.section suudb +.section suuea +.section suueb +.section suufa +.section suufb +.section suuga +.section suugb +.section suuha +.section suuhb +.section suuia +.section suuib +.section suuja +.section suujb +.section suuka +.section suukb +.section suula +.section suulb +.section suuma +.section suumb +.section suuna +.section suunb +.section suuoa +.section suuob +.section suupa +.section suupb +.section suuqa +.section suuqb +.section suura +.section suurb +.section suusa +.section suusb +.section suuta +.section suutb +.section suuua +.section suuub +.section suuva +.section suuvb +.section suuwa +.section suuwb +.section suuxa +.section suuxb +.section suuya +.section suuyb +.section suuza +.section suuzb +.section suu1a +.section suu1b +.section suu2a +.section suu2b +.section suu3a +.section suu3b +.section suu4a +.section suu4b +.section suu5a +.section suu5b +.section suu6a +.section suu6b +.section suu7a +.section suu7b +.section suu8a +.section suu8b +.section suu9a +.section suu9b +.section suu0a +.section suu0b +.section suvaa +.section suvab +.section suvba +.section suvbb +.section suvca +.section suvcb +.section suvda +.section suvdb +.section suvea +.section suveb +.section suvfa +.section suvfb +.section suvga +.section suvgb +.section suvha +.section suvhb +.section suvia +.section suvib +.section suvja +.section suvjb +.section suvka +.section suvkb +.section suvla +.section suvlb +.section suvma +.section suvmb +.section suvna +.section suvnb +.section suvoa +.section suvob +.section suvpa +.section suvpb +.section suvqa +.section suvqb +.section suvra +.section suvrb +.section suvsa +.section suvsb +.section suvta +.section suvtb +.section suvua +.section suvub +.section suvva +.section suvvb +.section suvwa +.section suvwb +.section suvxa +.section suvxb +.section suvya +.section suvyb +.section suvza +.section suvzb +.section suv1a +.section suv1b +.section suv2a +.section suv2b +.section suv3a +.section suv3b +.section suv4a +.section suv4b +.section suv5a +.section suv5b +.section suv6a +.section suv6b +.section suv7a +.section suv7b +.section suv8a +.section suv8b +.section suv9a +.section suv9b +.section suv0a +.section suv0b +.section suwaa +.section suwab +.section suwba +.section suwbb +.section suwca +.section suwcb +.section suwda +.section suwdb +.section suwea +.section suweb +.section suwfa +.section suwfb +.section suwga +.section suwgb +.section suwha +.section suwhb +.section suwia +.section suwib +.section suwja +.section suwjb +.section suwka +.section suwkb +.section suwla +.section suwlb +.section suwma +.section suwmb +.section suwna +.section suwnb +.section suwoa +.section suwob +.section suwpa +.section suwpb +.section suwqa +.section suwqb +.section suwra +.section suwrb +.section suwsa +.section suwsb +.section suwta +.section suwtb +.section suwua +.section suwub +.section suwva +.section suwvb +.section suwwa +.section suwwb +.section suwxa +.section suwxb +.section suwya +.section suwyb +.section suwza +.section suwzb +.section suw1a +.section suw1b +.section suw2a +.section suw2b +.section suw3a +.section suw3b +.section suw4a +.section suw4b +.section suw5a +.section suw5b +.section suw6a +.section suw6b +.section suw7a +.section suw7b +.section suw8a +.section suw8b +.section suw9a +.section suw9b +.section suw0a +.section suw0b +.section suxaa +.section suxab +.section suxba +.section suxbb +.section suxca +.section suxcb +.section suxda +.section suxdb +.section suxea +.section suxeb +.section suxfa +.section suxfb +.section suxga +.section suxgb +.section suxha +.section suxhb +.section suxia +.section suxib +.section suxja +.section suxjb +.section suxka +.section suxkb +.section suxla +.section suxlb +.section suxma +.section suxmb +.section suxna +.section suxnb +.section suxoa +.section suxob +.section suxpa +.section suxpb +.section suxqa +.section suxqb +.section suxra +.section suxrb +.section suxsa +.section suxsb +.section suxta +.section suxtb +.section suxua +.section suxub +.section suxva +.section suxvb +.section suxwa +.section suxwb +.section suxxa +.section suxxb +.section suxya +.section suxyb +.section suxza +.section suxzb +.section sux1a +.section sux1b +.section sux2a +.section sux2b +.section sux3a +.section sux3b +.section sux4a +.section sux4b +.section sux5a +.section sux5b +.section sux6a +.section sux6b +.section sux7a +.section sux7b +.section sux8a +.section sux8b +.section sux9a +.section sux9b +.section sux0a +.section sux0b +.section suyaa +.section suyab +.section suyba +.section suybb +.section suyca +.section suycb +.section suyda +.section suydb +.section suyea +.section suyeb +.section suyfa +.section suyfb +.section suyga +.section suygb +.section suyha +.section suyhb +.section suyia +.section suyib +.section suyja +.section suyjb +.section suyka +.section suykb +.section suyla +.section suylb +.section suyma +.section suymb +.section suyna +.section suynb +.section suyoa +.section suyob +.section suypa +.section suypb +.section suyqa +.section suyqb +.section suyra +.section suyrb +.section suysa +.section suysb +.section suyta +.section suytb +.section suyua +.section suyub +.section suyva +.section suyvb +.section suywa +.section suywb +.section suyxa +.section suyxb +.section suyya +.section suyyb +.section suyza +.section suyzb +.section suy1a +.section suy1b +.section suy2a +.section suy2b +.section suy3a +.section suy3b +.section suy4a +.section suy4b +.section suy5a +.section suy5b +.section suy6a +.section suy6b +.section suy7a +.section suy7b +.section suy8a +.section suy8b +.section suy9a +.section suy9b +.section suy0a +.section suy0b +.section suzaa +.section suzab +.section suzba +.section suzbb +.section suzca +.section suzcb +.section suzda +.section suzdb +.section suzea +.section suzeb +.section suzfa +.section suzfb +.section suzga +.section suzgb +.section suzha +.section suzhb +.section suzia +.section suzib +.section suzja +.section suzjb +.section suzka +.section suzkb +.section suzla +.section suzlb +.section suzma +.section suzmb +.section suzna +.section suznb +.section suzoa +.section suzob +.section suzpa +.section suzpb +.section suzqa +.section suzqb +.section suzra +.section suzrb +.section suzsa +.section suzsb +.section suzta +.section suztb +.section suzua +.section suzub +.section suzva +.section suzvb +.section suzwa +.section suzwb +.section suzxa +.section suzxb +.section suzya +.section suzyb +.section suzza +.section suzzb +.section suz1a +.section suz1b +.section suz2a +.section suz2b +.section suz3a +.section suz3b +.section suz4a +.section suz4b +.section suz5a +.section suz5b +.section suz6a +.section suz6b +.section suz7a +.section suz7b +.section suz8a +.section suz8b +.section suz9a +.section suz9b +.section suz0a +.section suz0b +.section su1aa +.section su1ab +.section su1ba +.section su1bb +.section su1ca +.section su1cb +.section su1da +.section su1db +.section su1ea +.section su1eb +.section su1fa +.section su1fb +.section su1ga +.section su1gb +.section su1ha +.section su1hb +.section su1ia +.section su1ib +.section su1ja +.section su1jb +.section su1ka +.section su1kb +.section su1la +.section su1lb +.section su1ma +.section su1mb +.section su1na +.section su1nb +.section su1oa +.section su1ob +.section su1pa +.section su1pb +.section su1qa +.section su1qb +.section su1ra +.section su1rb +.section su1sa +.section su1sb +.section su1ta +.section su1tb +.section su1ua +.section su1ub +.section su1va +.section su1vb +.section su1wa +.section su1wb +.section su1xa +.section su1xb +.section su1ya +.section su1yb +.section su1za +.section su1zb +.section su11a +.section su11b +.section su12a +.section su12b +.section su13a +.section su13b +.section su14a +.section su14b +.section su15a +.section su15b +.section su16a +.section su16b +.section su17a +.section su17b +.section su18a +.section su18b +.section su19a +.section su19b +.section su10a +.section su10b +.section su2aa +.section su2ab +.section su2ba +.section su2bb +.section su2ca +.section su2cb +.section su2da +.section su2db +.section su2ea +.section su2eb +.section su2fa +.section su2fb +.section su2ga +.section su2gb +.section su2ha +.section su2hb +.section su2ia +.section su2ib +.section su2ja +.section su2jb +.section su2ka +.section su2kb +.section su2la +.section su2lb +.section su2ma +.section su2mb +.section su2na +.section su2nb +.section su2oa +.section su2ob +.section su2pa +.section su2pb +.section su2qa +.section su2qb +.section su2ra +.section su2rb +.section su2sa +.section su2sb +.section su2ta +.section su2tb +.section su2ua +.section su2ub +.section su2va +.section su2vb +.section su2wa +.section su2wb +.section su2xa +.section su2xb +.section su2ya +.section su2yb +.section su2za +.section su2zb +.section su21a +.section su21b +.section su22a +.section su22b +.section su23a +.section su23b +.section su24a +.section su24b +.section su25a +.section su25b +.section su26a +.section su26b +.section su27a +.section su27b +.section su28a +.section su28b +.section su29a +.section su29b +.section su20a +.section su20b +.section su3aa +.section su3ab +.section su3ba +.section su3bb +.section su3ca +.section su3cb +.section su3da +.section su3db +.section su3ea +.section su3eb +.section su3fa +.section su3fb +.section su3ga +.section su3gb +.section su3ha +.section su3hb +.section su3ia +.section su3ib +.section su3ja +.section su3jb +.section su3ka +.section su3kb +.section su3la +.section su3lb +.section su3ma +.section su3mb +.section su3na +.section su3nb +.section su3oa +.section su3ob +.section su3pa +.section su3pb +.section su3qa +.section su3qb +.section su3ra +.section su3rb +.section su3sa +.section su3sb +.section su3ta +.section su3tb +.section su3ua +.section su3ub +.section su3va +.section su3vb +.section su3wa +.section su3wb +.section su3xa +.section su3xb +.section su3ya +.section su3yb +.section su3za +.section su3zb +.section su31a +.section su31b +.section su32a +.section su32b +.section su33a +.section su33b +.section su34a +.section su34b +.section su35a +.section su35b +.section su36a +.section su36b +.section su37a +.section su37b +.section su38a +.section su38b +.section su39a +.section su39b +.section su30a +.section su30b +.section su4aa +.section su4ab +.section su4ba +.section su4bb +.section su4ca +.section su4cb +.section su4da +.section su4db +.section su4ea +.section su4eb +.section su4fa +.section su4fb +.section su4ga +.section su4gb +.section su4ha +.section su4hb +.section su4ia +.section su4ib +.section su4ja +.section su4jb +.section su4ka +.section su4kb +.section su4la +.section su4lb +.section su4ma +.section su4mb +.section su4na +.section su4nb +.section su4oa +.section su4ob +.section su4pa +.section su4pb +.section su4qa +.section su4qb +.section su4ra +.section su4rb +.section su4sa +.section su4sb +.section su4ta +.section su4tb +.section su4ua +.section su4ub +.section su4va +.section su4vb +.section su4wa +.section su4wb +.section su4xa +.section su4xb +.section su4ya +.section su4yb +.section su4za +.section su4zb +.section su41a +.section su41b +.section su42a +.section su42b +.section su43a +.section su43b +.section su44a +.section su44b +.section su45a +.section su45b +.section su46a +.section su46b +.section su47a +.section su47b +.section su48a +.section su48b +.section su49a +.section su49b +.section su40a +.section su40b +.section su5aa +.section su5ab +.section su5ba +.section su5bb +.section su5ca +.section su5cb +.section su5da +.section su5db +.section su5ea +.section su5eb +.section su5fa +.section su5fb +.section su5ga +.section su5gb +.section su5ha +.section su5hb +.section su5ia +.section su5ib +.section su5ja +.section su5jb +.section su5ka +.section su5kb +.section su5la +.section su5lb +.section su5ma +.section su5mb +.section su5na +.section su5nb +.section su5oa +.section su5ob +.section su5pa +.section su5pb +.section su5qa +.section su5qb +.section su5ra +.section su5rb +.section su5sa +.section su5sb +.section su5ta +.section su5tb +.section su5ua +.section su5ub +.section su5va +.section su5vb +.section su5wa +.section su5wb +.section su5xa +.section su5xb +.section su5ya +.section su5yb +.section su5za +.section su5zb +.section su51a +.section su51b +.section su52a +.section su52b +.section su53a +.section su53b +.section su54a +.section su54b +.section su55a +.section su55b +.section su56a +.section su56b +.section su57a +.section su57b +.section su58a +.section su58b +.section su59a +.section su59b +.section su50a +.section su50b +.section su6aa +.section su6ab +.section su6ba +.section su6bb +.section su6ca +.section su6cb +.section su6da +.section su6db +.section su6ea +.section su6eb +.section su6fa +.section su6fb +.section su6ga +.section su6gb +.section su6ha +.section su6hb +.section su6ia +.section su6ib +.section su6ja +.section su6jb +.section su6ka +.section su6kb +.section su6la +.section su6lb +.section su6ma +.section su6mb +.section su6na +.section su6nb +.section su6oa +.section su6ob +.section su6pa +.section su6pb +.section su6qa +.section su6qb +.section su6ra +.section su6rb +.section su6sa +.section su6sb +.section su6ta +.section su6tb +.section su6ua +.section su6ub +.section su6va +.section su6vb +.section su6wa +.section su6wb +.section su6xa +.section su6xb +.section su6ya +.section su6yb +.section su6za +.section su6zb +.section su61a +.section su61b +.section su62a +.section su62b +.section su63a +.section su63b +.section su64a +.section su64b +.section su65a +.section su65b +.section su66a +.section su66b +.section su67a +.section su67b +.section su68a +.section su68b +.section su69a +.section su69b +.section su60a +.section su60b +.section su7aa +.section su7ab +.section su7ba +.section su7bb +.section su7ca +.section su7cb +.section su7da +.section su7db +.section su7ea +.section su7eb +.section su7fa +.section su7fb +.section su7ga +.section su7gb +.section su7ha +.section su7hb +.section su7ia +.section su7ib +.section su7ja +.section su7jb +.section su7ka +.section su7kb +.section su7la +.section su7lb +.section su7ma +.section su7mb +.section su7na +.section su7nb +.section su7oa +.section su7ob +.section su7pa +.section su7pb +.section su7qa +.section su7qb +.section su7ra +.section su7rb +.section su7sa +.section su7sb +.section su7ta +.section su7tb +.section su7ua +.section su7ub +.section su7va +.section su7vb +.section su7wa +.section su7wb +.section su7xa +.section su7xb +.section su7ya +.section su7yb +.section su7za +.section su7zb +.section su71a +.section su71b +.section su72a +.section su72b +.section su73a +.section su73b +.section su74a +.section su74b +.section su75a +.section su75b +.section su76a +.section su76b +.section su77a +.section su77b +.section su78a +.section su78b +.section su79a +.section su79b +.section su70a +.section su70b +.section su8aa +.section su8ab +.section su8ba +.section su8bb +.section su8ca +.section su8cb +.section su8da +.section su8db +.section su8ea +.section su8eb +.section su8fa +.section su8fb +.section su8ga +.section su8gb +.section su8ha +.section su8hb +.section su8ia +.section su8ib +.section su8ja +.section su8jb +.section su8ka +.section su8kb +.section su8la +.section su8lb +.section su8ma +.section su8mb +.section su8na +.section su8nb +.section su8oa +.section su8ob +.section su8pa +.section su8pb +.section su8qa +.section su8qb +.section su8ra +.section su8rb +.section su8sa +.section su8sb +.section su8ta +.section su8tb +.section su8ua +.section su8ub +.section su8va +.section su8vb +.section su8wa +.section su8wb +.section su8xa +.section su8xb +.section su8ya +.section su8yb +.section su8za +.section su8zb +.section su81a +.section su81b +.section su82a +.section su82b +.section su83a +.section su83b +.section su84a +.section su84b +.section su85a +.section su85b +.section su86a +.section su86b +.section su87a +.section su87b +.section su88a +.section su88b +.section su89a +.section su89b +.section su80a +.section su80b +.section su9aa +.section su9ab +.section su9ba +.section su9bb +.section su9ca +.section su9cb +.section su9da +.section su9db +.section su9ea +.section su9eb +.section su9fa +.section su9fb +.section su9ga +.section su9gb +.section su9ha +.section su9hb +.section su9ia +.section su9ib +.section su9ja +.section su9jb +.section su9ka +.section su9kb +.section su9la +.section su9lb +.section su9ma +.section su9mb +.section su9na +.section su9nb +.section su9oa +.section su9ob +.section su9pa +.section su9pb +.section su9qa +.section su9qb +.section su9ra +.section su9rb +.section su9sa +.section su9sb +.section su9ta +.section su9tb +.section su9ua +.section su9ub +.section su9va +.section su9vb +.section su9wa +.section su9wb +.section su9xa +.section su9xb +.section su9ya +.section su9yb +.section su9za +.section su9zb +.section su91a +.section su91b +.section su92a +.section su92b +.section su93a +.section su93b +.section su94a +.section su94b +.section su95a +.section su95b +.section su96a +.section su96b +.section su97a +.section su97b +.section su98a +.section su98b +.section su99a +.section su99b +.section su90a +.section su90b +.section su0aa +.section su0ab +.section su0ba +.section su0bb +.section su0ca +.section su0cb +.section su0da +.section su0db +.section su0ea +.section su0eb +.section su0fa +.section su0fb +.section su0ga +.section su0gb +.section su0ha +.section su0hb +.section su0ia +.section su0ib +.section su0ja +.section su0jb +.section su0ka +.section su0kb +.section su0la +.section su0lb +.section su0ma +.section su0mb +.section su0na +.section su0nb +.section su0oa +.section su0ob +.section su0pa +.section su0pb +.section su0qa +.section su0qb +.section su0ra +.section su0rb +.section su0sa +.section su0sb +.section su0ta +.section su0tb +.section su0ua +.section su0ub +.section su0va +.section su0vb +.section su0wa +.section su0wb +.section su0xa +.section su0xb +.section su0ya +.section su0yb +.section su0za +.section su0zb +.section su01a +.section su01b +.section su02a +.section su02b +.section su03a +.section su03b +.section su04a +.section su04b +.section su05a +.section su05b +.section su06a +.section su06b +.section su07a +.section su07b +.section su08a +.section su08b +.section su09a +.section su09b +.section su00a +.section su00b +.section svaaa +.section svaab +.section svaba +.section svabb +.section svaca +.section svacb +.section svada +.section svadb +.section svaea +.section svaeb +.section svafa +.section svafb +.section svaga +.section svagb +.section svaha +.section svahb +.section svaia +.section svaib +.section svaja +.section svajb +.section svaka +.section svakb +.section svala +.section svalb +.section svama +.section svamb +.section svana +.section svanb +.section svaoa +.section svaob +.section svapa +.section svapb +.section svaqa +.section svaqb +.section svara +.section svarb +.section svasa +.section svasb +.section svata +.section svatb +.section svaua +.section svaub +.section svava +.section svavb +.section svawa +.section svawb +.section svaxa +.section svaxb +.section svaya +.section svayb +.section svaza +.section svazb +.section sva1a +.section sva1b +.section sva2a +.section sva2b +.section sva3a +.section sva3b +.section sva4a +.section sva4b +.section sva5a +.section sva5b +.section sva6a +.section sva6b +.section sva7a +.section sva7b +.section sva8a +.section sva8b +.section sva9a +.section sva9b +.section sva0a +.section sva0b +.section svbaa +.section svbab +.section svbba +.section svbbb +.section svbca +.section svbcb +.section svbda +.section svbdb +.section svbea +.section svbeb +.section svbfa +.section svbfb +.section svbga +.section svbgb +.section svbha +.section svbhb +.section svbia +.section svbib +.section svbja +.section svbjb +.section svbka +.section svbkb +.section svbla +.section svblb +.section svbma +.section svbmb +.section svbna +.section svbnb +.section svboa +.section svbob +.section svbpa +.section svbpb +.section svbqa +.section svbqb +.section svbra +.section svbrb +.section svbsa +.section svbsb +.section svbta +.section svbtb +.section svbua +.section svbub +.section svbva +.section svbvb +.section svbwa +.section svbwb +.section svbxa +.section svbxb +.section svbya +.section svbyb +.section svbza +.section svbzb +.section svb1a +.section svb1b +.section svb2a +.section svb2b +.section svb3a +.section svb3b +.section svb4a +.section svb4b +.section svb5a +.section svb5b +.section svb6a +.section svb6b +.section svb7a +.section svb7b +.section svb8a +.section svb8b +.section svb9a +.section svb9b +.section svb0a +.section svb0b +.section svcaa +.section svcab +.section svcba +.section svcbb +.section svcca +.section svccb +.section svcda +.section svcdb +.section svcea +.section svceb +.section svcfa +.section svcfb +.section svcga +.section svcgb +.section svcha +.section svchb +.section svcia +.section svcib +.section svcja +.section svcjb +.section svcka +.section svckb +.section svcla +.section svclb +.section svcma +.section svcmb +.section svcna +.section svcnb +.section svcoa +.section svcob +.section svcpa +.section svcpb +.section svcqa +.section svcqb +.section svcra +.section svcrb +.section svcsa +.section svcsb +.section svcta +.section svctb +.section svcua +.section svcub +.section svcva +.section svcvb +.section svcwa +.section svcwb +.section svcxa +.section svcxb +.section svcya +.section svcyb +.section svcza +.section svczb +.section svc1a +.section svc1b +.section svc2a +.section svc2b +.section svc3a +.section svc3b +.section svc4a +.section svc4b +.section svc5a +.section svc5b +.section svc6a +.section svc6b +.section svc7a +.section svc7b +.section svc8a +.section svc8b +.section svc9a +.section svc9b +.section svc0a +.section svc0b +.section svdaa +.section svdab +.section svdba +.section svdbb +.section svdca +.section svdcb +.section svdda +.section svddb +.section svdea +.section svdeb +.section svdfa +.section svdfb +.section svdga +.section svdgb +.section svdha +.section svdhb +.section svdia +.section svdib +.section svdja +.section svdjb +.section svdka +.section svdkb +.section svdla +.section svdlb +.section svdma +.section svdmb +.section svdna +.section svdnb +.section svdoa +.section svdob +.section svdpa +.section svdpb +.section svdqa +.section svdqb +.section svdra +.section svdrb +.section svdsa +.section svdsb +.section svdta +.section svdtb +.section svdua +.section svdub +.section svdva +.section svdvb +.section svdwa +.section svdwb +.section svdxa +.section svdxb +.section svdya +.section svdyb +.section svdza +.section svdzb +.section svd1a +.section svd1b +.section svd2a +.section svd2b +.section svd3a +.section svd3b +.section svd4a +.section svd4b +.section svd5a +.section svd5b +.section svd6a +.section svd6b +.section svd7a +.section svd7b +.section svd8a +.section svd8b +.section svd9a +.section svd9b +.section svd0a +.section svd0b +.section sveaa +.section sveab +.section sveba +.section svebb +.section sveca +.section svecb +.section sveda +.section svedb +.section sveea +.section sveeb +.section svefa +.section svefb +.section svega +.section svegb +.section sveha +.section svehb +.section sveia +.section sveib +.section sveja +.section svejb +.section sveka +.section svekb +.section svela +.section svelb +.section svema +.section svemb +.section svena +.section svenb +.section sveoa +.section sveob +.section svepa +.section svepb +.section sveqa +.section sveqb +.section svera +.section sverb +.section svesa +.section svesb +.section sveta +.section svetb +.section sveua +.section sveub +.section sveva +.section svevb +.section svewa +.section svewb +.section svexa +.section svexb +.section sveya +.section sveyb +.section sveza +.section svezb +.section sve1a +.section sve1b +.section sve2a +.section sve2b +.section sve3a +.section sve3b +.section sve4a +.section sve4b +.section sve5a +.section sve5b +.section sve6a +.section sve6b +.section sve7a +.section sve7b +.section sve8a +.section sve8b +.section sve9a +.section sve9b +.section sve0a +.section sve0b +.section svfaa +.section svfab +.section svfba +.section svfbb +.section svfca +.section svfcb +.section svfda +.section svfdb +.section svfea +.section svfeb +.section svffa +.section svffb +.section svfga +.section svfgb +.section svfha +.section svfhb +.section svfia +.section svfib +.section svfja +.section svfjb +.section svfka +.section svfkb +.section svfla +.section svflb +.section svfma +.section svfmb +.section svfna +.section svfnb +.section svfoa +.section svfob +.section svfpa +.section svfpb +.section svfqa +.section svfqb +.section svfra +.section svfrb +.section svfsa +.section svfsb +.section svfta +.section svftb +.section svfua +.section svfub +.section svfva +.section svfvb +.section svfwa +.section svfwb +.section svfxa +.section svfxb +.section svfya +.section svfyb +.section svfza +.section svfzb +.section svf1a +.section svf1b +.section svf2a +.section svf2b +.section svf3a +.section svf3b +.section svf4a +.section svf4b +.section svf5a +.section svf5b +.section svf6a +.section svf6b +.section svf7a +.section svf7b +.section svf8a +.section svf8b +.section svf9a +.section svf9b +.section svf0a +.section svf0b +.section svgaa +.section svgab +.section svgba +.section svgbb +.section svgca +.section svgcb +.section svgda +.section svgdb +.section svgea +.section svgeb +.section svgfa +.section svgfb +.section svgga +.section svggb +.section svgha +.section svghb +.section svgia +.section svgib +.section svgja +.section svgjb +.section svgka +.section svgkb +.section svgla +.section svglb +.section svgma +.section svgmb +.section svgna +.section svgnb +.section svgoa +.section svgob +.section svgpa +.section svgpb +.section svgqa +.section svgqb +.section svgra +.section svgrb +.section svgsa +.section svgsb +.section svgta +.section svgtb +.section svgua +.section svgub +.section svgva +.section svgvb +.section svgwa +.section svgwb +.section svgxa +.section svgxb +.section svgya +.section svgyb +.section svgza +.section svgzb +.section svg1a +.section svg1b +.section svg2a +.section svg2b +.section svg3a +.section svg3b +.section svg4a +.section svg4b +.section svg5a +.section svg5b +.section svg6a +.section svg6b +.section svg7a +.section svg7b +.section svg8a +.section svg8b +.section svg9a +.section svg9b +.section svg0a +.section svg0b +.section svhaa +.section svhab +.section svhba +.section svhbb +.section svhca +.section svhcb +.section svhda +.section svhdb +.section svhea +.section svheb +.section svhfa +.section svhfb +.section svhga +.section svhgb +.section svhha +.section svhhb +.section svhia +.section svhib +.section svhja +.section svhjb +.section svhka +.section svhkb +.section svhla +.section svhlb +.section svhma +.section svhmb +.section svhna +.section svhnb +.section svhoa +.section svhob +.section svhpa +.section svhpb +.section svhqa +.section svhqb +.section svhra +.section svhrb +.section svhsa +.section svhsb +.section svhta +.section svhtb +.section svhua +.section svhub +.section svhva +.section svhvb +.section svhwa +.section svhwb +.section svhxa +.section svhxb +.section svhya +.section svhyb +.section svhza +.section svhzb +.section svh1a +.section svh1b +.section svh2a +.section svh2b +.section svh3a +.section svh3b +.section svh4a +.section svh4b +.section svh5a +.section svh5b +.section svh6a +.section svh6b +.section svh7a +.section svh7b +.section svh8a +.section svh8b +.section svh9a +.section svh9b +.section svh0a +.section svh0b +.section sviaa +.section sviab +.section sviba +.section svibb +.section svica +.section svicb +.section svida +.section svidb +.section sviea +.section svieb +.section svifa +.section svifb +.section sviga +.section svigb +.section sviha +.section svihb +.section sviia +.section sviib +.section svija +.section svijb +.section svika +.section svikb +.section svila +.section svilb +.section svima +.section svimb +.section svina +.section svinb +.section svioa +.section sviob +.section svipa +.section svipb +.section sviqa +.section sviqb +.section svira +.section svirb +.section svisa +.section svisb +.section svita +.section svitb +.section sviua +.section sviub +.section sviva +.section svivb +.section sviwa +.section sviwb +.section svixa +.section svixb +.section sviya +.section sviyb +.section sviza +.section svizb +.section svi1a +.section svi1b +.section svi2a +.section svi2b +.section svi3a +.section svi3b +.section svi4a +.section svi4b +.section svi5a +.section svi5b +.section svi6a +.section svi6b +.section svi7a +.section svi7b +.section svi8a +.section svi8b +.section svi9a +.section svi9b +.section svi0a +.section svi0b +.section svjaa +.section svjab +.section svjba +.section svjbb +.section svjca +.section svjcb +.section svjda +.section svjdb +.section svjea +.section svjeb +.section svjfa +.section svjfb +.section svjga +.section svjgb +.section svjha +.section svjhb +.section svjia +.section svjib +.section svjja +.section svjjb +.section svjka +.section svjkb +.section svjla +.section svjlb +.section svjma +.section svjmb +.section svjna +.section svjnb +.section svjoa +.section svjob +.section svjpa +.section svjpb +.section svjqa +.section svjqb +.section svjra +.section svjrb +.section svjsa +.section svjsb +.section svjta +.section svjtb +.section svjua +.section svjub +.section svjva +.section svjvb +.section svjwa +.section svjwb +.section svjxa +.section svjxb +.section svjya +.section svjyb +.section svjza +.section svjzb +.section svj1a +.section svj1b +.section svj2a +.section svj2b +.section svj3a +.section svj3b +.section svj4a +.section svj4b +.section svj5a +.section svj5b +.section svj6a +.section svj6b +.section svj7a +.section svj7b +.section svj8a +.section svj8b +.section svj9a +.section svj9b +.section svj0a +.section svj0b +.section svkaa +.section svkab +.section svkba +.section svkbb +.section svkca +.section svkcb +.section svkda +.section svkdb +.section svkea +.section svkeb +.section svkfa +.section svkfb +.section svkga +.section svkgb +.section svkha +.section svkhb +.section svkia +.section svkib +.section svkja +.section svkjb +.section svkka +.section svkkb +.section svkla +.section svklb +.section svkma +.section svkmb +.section svkna +.section svknb +.section svkoa +.section svkob +.section svkpa +.section svkpb +.section svkqa +.section svkqb +.section svkra +.section svkrb +.section svksa +.section svksb +.section svkta +.section svktb +.section svkua +.section svkub +.section svkva +.section svkvb +.section svkwa +.section svkwb +.section svkxa +.section svkxb +.section svkya +.section svkyb +.section svkza +.section svkzb +.section svk1a +.section svk1b +.section svk2a +.section svk2b +.section svk3a +.section svk3b +.section svk4a +.section svk4b +.section svk5a +.section svk5b +.section svk6a +.section svk6b +.section svk7a +.section svk7b +.section svk8a +.section svk8b +.section svk9a +.section svk9b +.section svk0a +.section svk0b +.section svlaa +.section svlab +.section svlba +.section svlbb +.section svlca +.section svlcb +.section svlda +.section svldb +.section svlea +.section svleb +.section svlfa +.section svlfb +.section svlga +.section svlgb +.section svlha +.section svlhb +.section svlia +.section svlib +.section svlja +.section svljb +.section svlka +.section svlkb +.section svlla +.section svllb +.section svlma +.section svlmb +.section svlna +.section svlnb +.section svloa +.section svlob +.section svlpa +.section svlpb +.section svlqa +.section svlqb +.section svlra +.section svlrb +.section svlsa +.section svlsb +.section svlta +.section svltb +.section svlua +.section svlub +.section svlva +.section svlvb +.section svlwa +.section svlwb +.section svlxa +.section svlxb +.section svlya +.section svlyb +.section svlza +.section svlzb +.section svl1a +.section svl1b +.section svl2a +.section svl2b +.section svl3a +.section svl3b +.section svl4a +.section svl4b +.section svl5a +.section svl5b +.section svl6a +.section svl6b +.section svl7a +.section svl7b +.section svl8a +.section svl8b +.section svl9a +.section svl9b +.section svl0a +.section svl0b +.section svmaa +.section svmab +.section svmba +.section svmbb +.section svmca +.section svmcb +.section svmda +.section svmdb +.section svmea +.section svmeb +.section svmfa +.section svmfb +.section svmga +.section svmgb +.section svmha +.section svmhb +.section svmia +.section svmib +.section svmja +.section svmjb +.section svmka +.section svmkb +.section svmla +.section svmlb +.section svmma +.section svmmb +.section svmna +.section svmnb +.section svmoa +.section svmob +.section svmpa +.section svmpb +.section svmqa +.section svmqb +.section svmra +.section svmrb +.section svmsa +.section svmsb +.section svmta +.section svmtb +.section svmua +.section svmub +.section svmva +.section svmvb +.section svmwa +.section svmwb +.section svmxa +.section svmxb +.section svmya +.section svmyb +.section svmza +.section svmzb +.section svm1a +.section svm1b +.section svm2a +.section svm2b +.section svm3a +.section svm3b +.section svm4a +.section svm4b +.section svm5a +.section svm5b +.section svm6a +.section svm6b +.section svm7a +.section svm7b +.section svm8a +.section svm8b +.section svm9a +.section svm9b +.section svm0a +.section svm0b +.section svnaa +.section svnab +.section svnba +.section svnbb +.section svnca +.section svncb +.section svnda +.section svndb +.section svnea +.section svneb +.section svnfa +.section svnfb +.section svnga +.section svngb +.section svnha +.section svnhb +.section svnia +.section svnib +.section svnja +.section svnjb +.section svnka +.section svnkb +.section svnla +.section svnlb +.section svnma +.section svnmb +.section svnna +.section svnnb +.section svnoa +.section svnob +.section svnpa +.section svnpb +.section svnqa +.section svnqb +.section svnra +.section svnrb +.section svnsa +.section svnsb +.section svnta +.section svntb +.section svnua +.section svnub +.section svnva +.section svnvb +.section svnwa +.section svnwb +.section svnxa +.section svnxb +.section svnya +.section svnyb +.section svnza +.section svnzb +.section svn1a +.section svn1b +.section svn2a +.section svn2b +.section svn3a +.section svn3b +.section svn4a +.section svn4b +.section svn5a +.section svn5b +.section svn6a +.section svn6b +.section svn7a +.section svn7b +.section svn8a +.section svn8b +.section svn9a +.section svn9b +.section svn0a +.section svn0b +.section svoaa +.section svoab +.section svoba +.section svobb +.section svoca +.section svocb +.section svoda +.section svodb +.section svoea +.section svoeb +.section svofa +.section svofb +.section svoga +.section svogb +.section svoha +.section svohb +.section svoia +.section svoib +.section svoja +.section svojb +.section svoka +.section svokb +.section svola +.section svolb +.section svoma +.section svomb +.section svona +.section svonb +.section svooa +.section svoob +.section svopa +.section svopb +.section svoqa +.section svoqb +.section svora +.section svorb +.section svosa +.section svosb +.section svota +.section svotb +.section svoua +.section svoub +.section svova +.section svovb +.section svowa +.section svowb +.section svoxa +.section svoxb +.section svoya +.section svoyb +.section svoza +.section svozb +.section svo1a +.section svo1b +.section svo2a +.section svo2b +.section svo3a +.section svo3b +.section svo4a +.section svo4b +.section svo5a +.section svo5b +.section svo6a +.section svo6b +.section svo7a +.section svo7b +.section svo8a +.section svo8b +.section svo9a +.section svo9b +.section svo0a +.section svo0b +.section svpaa +.section svpab +.section svpba +.section svpbb +.section svpca +.section svpcb +.section svpda +.section svpdb +.section svpea +.section svpeb +.section svpfa +.section svpfb +.section svpga +.section svpgb +.section svpha +.section svphb +.section svpia +.section svpib +.section svpja +.section svpjb +.section svpka +.section svpkb +.section svpla +.section svplb +.section svpma +.section svpmb +.section svpna +.section svpnb +.section svpoa +.section svpob +.section svppa +.section svppb +.section svpqa +.section svpqb +.section svpra +.section svprb +.section svpsa +.section svpsb +.section svpta +.section svptb +.section svpua +.section svpub +.section svpva +.section svpvb +.section svpwa +.section svpwb +.section svpxa +.section svpxb +.section svpya +.section svpyb +.section svpza +.section svpzb +.section svp1a +.section svp1b +.section svp2a +.section svp2b +.section svp3a +.section svp3b +.section svp4a +.section svp4b +.section svp5a +.section svp5b +.section svp6a +.section svp6b +.section svp7a +.section svp7b +.section svp8a +.section svp8b +.section svp9a +.section svp9b +.section svp0a +.section svp0b +.section svqaa +.section svqab +.section svqba +.section svqbb +.section svqca +.section svqcb +.section svqda +.section svqdb +.section svqea +.section svqeb +.section svqfa +.section svqfb +.section svqga +.section svqgb +.section svqha +.section svqhb +.section svqia +.section svqib +.section svqja +.section svqjb +.section svqka +.section svqkb +.section svqla +.section svqlb +.section svqma +.section svqmb +.section svqna +.section svqnb +.section svqoa +.section svqob +.section svqpa +.section svqpb +.section svqqa +.section svqqb +.section svqra +.section svqrb +.section svqsa +.section svqsb +.section svqta +.section svqtb +.section svqua +.section svqub +.section svqva +.section svqvb +.section svqwa +.section svqwb +.section svqxa +.section svqxb +.section svqya +.section svqyb +.section svqza +.section svqzb +.section svq1a +.section svq1b +.section svq2a +.section svq2b +.section svq3a +.section svq3b +.section svq4a +.section svq4b +.section svq5a +.section svq5b +.section svq6a +.section svq6b +.section svq7a +.section svq7b +.section svq8a +.section svq8b +.section svq9a +.section svq9b +.section svq0a +.section svq0b +.section svraa +.section svrab +.section svrba +.section svrbb +.section svrca +.section svrcb +.section svrda +.section svrdb +.section svrea +.section svreb +.section svrfa +.section svrfb +.section svrga +.section svrgb +.section svrha +.section svrhb +.section svria +.section svrib +.section svrja +.section svrjb +.section svrka +.section svrkb +.section svrla +.section svrlb +.section svrma +.section svrmb +.section svrna +.section svrnb +.section svroa +.section svrob +.section svrpa +.section svrpb +.section svrqa +.section svrqb +.section svrra +.section svrrb +.section svrsa +.section svrsb +.section svrta +.section svrtb +.section svrua +.section svrub +.section svrva +.section svrvb +.section svrwa +.section svrwb +.section svrxa +.section svrxb +.section svrya +.section svryb +.section svrza +.section svrzb +.section svr1a +.section svr1b +.section svr2a +.section svr2b +.section svr3a +.section svr3b +.section svr4a +.section svr4b +.section svr5a +.section svr5b +.section svr6a +.section svr6b +.section svr7a +.section svr7b +.section svr8a +.section svr8b +.section svr9a +.section svr9b +.section svr0a +.section svr0b +.section svsaa +.section svsab +.section svsba +.section svsbb +.section svsca +.section svscb +.section svsda +.section svsdb +.section svsea +.section svseb +.section svsfa +.section svsfb +.section svsga +.section svsgb +.section svsha +.section svshb +.section svsia +.section svsib +.section svsja +.section svsjb +.section svska +.section svskb +.section svsla +.section svslb +.section svsma +.section svsmb +.section svsna +.section svsnb +.section svsoa +.section svsob +.section svspa +.section svspb +.section svsqa +.section svsqb +.section svsra +.section svsrb +.section svssa +.section svssb +.section svsta +.section svstb +.section svsua +.section svsub +.section svsva +.section svsvb +.section svswa +.section svswb +.section svsxa +.section svsxb +.section svsya +.section svsyb +.section svsza +.section svszb +.section svs1a +.section svs1b +.section svs2a +.section svs2b +.section svs3a +.section svs3b +.section svs4a +.section svs4b +.section svs5a +.section svs5b +.section svs6a +.section svs6b +.section svs7a +.section svs7b +.section svs8a +.section svs8b +.section svs9a +.section svs9b +.section svs0a +.section svs0b +.section svtaa +.section svtab +.section svtba +.section svtbb +.section svtca +.section svtcb +.section svtda +.section svtdb +.section svtea +.section svteb +.section svtfa +.section svtfb +.section svtga +.section svtgb +.section svtha +.section svthb +.section svtia +.section svtib +.section svtja +.section svtjb +.section svtka +.section svtkb +.section svtla +.section svtlb +.section svtma +.section svtmb +.section svtna +.section svtnb +.section svtoa +.section svtob +.section svtpa +.section svtpb +.section svtqa +.section svtqb +.section svtra +.section svtrb +.section svtsa +.section svtsb +.section svtta +.section svttb +.section svtua +.section svtub +.section svtva +.section svtvb +.section svtwa +.section svtwb +.section svtxa +.section svtxb +.section svtya +.section svtyb +.section svtza +.section svtzb +.section svt1a +.section svt1b +.section svt2a +.section svt2b +.section svt3a +.section svt3b +.section svt4a +.section svt4b +.section svt5a +.section svt5b +.section svt6a +.section svt6b +.section svt7a +.section svt7b +.section svt8a +.section svt8b +.section svt9a +.section svt9b +.section svt0a +.section svt0b +.section svuaa +.section svuab +.section svuba +.section svubb +.section svuca +.section svucb +.section svuda +.section svudb +.section svuea +.section svueb +.section svufa +.section svufb +.section svuga +.section svugb +.section svuha +.section svuhb +.section svuia +.section svuib +.section svuja +.section svujb +.section svuka +.section svukb +.section svula +.section svulb +.section svuma +.section svumb +.section svuna +.section svunb +.section svuoa +.section svuob +.section svupa +.section svupb +.section svuqa +.section svuqb +.section svura +.section svurb +.section svusa +.section svusb +.section svuta +.section svutb +.section svuua +.section svuub +.section svuva +.section svuvb +.section svuwa +.section svuwb +.section svuxa +.section svuxb +.section svuya +.section svuyb +.section svuza +.section svuzb +.section svu1a +.section svu1b +.section svu2a +.section svu2b +.section svu3a +.section svu3b +.section svu4a +.section svu4b +.section svu5a +.section svu5b +.section svu6a +.section svu6b +.section svu7a +.section svu7b +.section svu8a +.section svu8b +.section svu9a +.section svu9b +.section svu0a +.section svu0b +.section svvaa +.section svvab +.section svvba +.section svvbb +.section svvca +.section svvcb +.section svvda +.section svvdb +.section svvea +.section svveb +.section svvfa +.section svvfb +.section svvga +.section svvgb +.section svvha +.section svvhb +.section svvia +.section svvib +.section svvja +.section svvjb +.section svvka +.section svvkb +.section svvla +.section svvlb +.section svvma +.section svvmb +.section svvna +.section svvnb +.section svvoa +.section svvob +.section svvpa +.section svvpb +.section svvqa +.section svvqb +.section svvra +.section svvrb +.section svvsa +.section svvsb +.section svvta +.section svvtb +.section svvua +.section svvub +.section svvva +.section svvvb +.section svvwa +.section svvwb +.section svvxa +.section svvxb +.section svvya +.section svvyb +.section svvza +.section svvzb +.section svv1a +.section svv1b +.section svv2a +.section svv2b +.section svv3a +.section svv3b +.section svv4a +.section svv4b +.section svv5a +.section svv5b +.section svv6a +.section svv6b +.section svv7a +.section svv7b +.section svv8a +.section svv8b +.section svv9a +.section svv9b +.section svv0a +.section svv0b +.section svwaa +.section svwab +.section svwba +.section svwbb +.section svwca +.section svwcb +.section svwda +.section svwdb +.section svwea +.section svweb +.section svwfa +.section svwfb +.section svwga +.section svwgb +.section svwha +.section svwhb +.section svwia +.section svwib +.section svwja +.section svwjb +.section svwka +.section svwkb +.section svwla +.section svwlb +.section svwma +.section svwmb +.section svwna +.section svwnb +.section svwoa +.section svwob +.section svwpa +.section svwpb +.section svwqa +.section svwqb +.section svwra +.section svwrb +.section svwsa +.section svwsb +.section svwta +.section svwtb +.section svwua +.section svwub +.section svwva +.section svwvb +.section svwwa +.section svwwb +.section svwxa +.section svwxb +.section svwya +.section svwyb +.section svwza +.section svwzb +.section svw1a +.section svw1b +.section svw2a +.section svw2b +.section svw3a +.section svw3b +.section svw4a +.section svw4b +.section svw5a +.section svw5b +.section svw6a +.section svw6b +.section svw7a +.section svw7b +.section svw8a +.section svw8b +.section svw9a +.section svw9b +.section svw0a +.section svw0b +.section svxaa +.section svxab +.section svxba +.section svxbb +.section svxca +.section svxcb +.section svxda +.section svxdb +.section svxea +.section svxeb +.section svxfa +.section svxfb +.section svxga +.section svxgb +.section svxha +.section svxhb +.section svxia +.section svxib +.section svxja +.section svxjb +.section svxka +.section svxkb +.section svxla +.section svxlb +.section svxma +.section svxmb +.section svxna +.section svxnb +.section svxoa +.section svxob +.section svxpa +.section svxpb +.section svxqa +.section svxqb +.section svxra +.section svxrb +.section svxsa +.section svxsb +.section svxta +.section svxtb +.section svxua +.section svxub +.section svxva +.section svxvb +.section svxwa +.section svxwb +.section svxxa +.section svxxb +.section svxya +.section svxyb +.section svxza +.section svxzb +.section svx1a +.section svx1b +.section svx2a +.section svx2b +.section svx3a +.section svx3b +.section svx4a +.section svx4b +.section svx5a +.section svx5b +.section svx6a +.section svx6b +.section svx7a +.section svx7b +.section svx8a +.section svx8b +.section svx9a +.section svx9b +.section svx0a +.section svx0b +.section svyaa +.section svyab +.section svyba +.section svybb +.section svyca +.section svycb +.section svyda +.section svydb +.section svyea +.section svyeb +.section svyfa +.section svyfb +.section svyga +.section svygb +.section svyha +.section svyhb +.section svyia +.section svyib +.section svyja +.section svyjb +.section svyka +.section svykb +.section svyla +.section svylb +.section svyma +.section svymb +.section svyna +.section svynb +.section svyoa +.section svyob +.section svypa +.section svypb +.section svyqa +.section svyqb +.section svyra +.section svyrb +.section svysa +.section svysb +.section svyta +.section svytb +.section svyua +.section svyub +.section svyva +.section svyvb +.section svywa +.section svywb +.section svyxa +.section svyxb +.section svyya +.section svyyb +.section svyza +.section svyzb +.section svy1a +.section svy1b +.section svy2a +.section svy2b +.section svy3a +.section svy3b +.section svy4a +.section svy4b +.section svy5a +.section svy5b +.section svy6a +.section svy6b +.section svy7a +.section svy7b +.section svy8a +.section svy8b +.section svy9a +.section svy9b +.section svy0a +.section svy0b +.section svzaa +.section svzab +.section svzba +.section svzbb +.section svzca +.section svzcb +.section svzda +.section svzdb +.section svzea +.section svzeb +.section svzfa +.section svzfb +.section svzga +.section svzgb +.section svzha +.section svzhb +.section svzia +.section svzib +.section svzja +.section svzjb +.section svzka +.section svzkb +.section svzla +.section svzlb +.section svzma +.section svzmb +.section svzna +.section svznb +.section svzoa +.section svzob +.section svzpa +.section svzpb +.section svzqa +.section svzqb +.section svzra +.section svzrb +.section svzsa +.section svzsb +.section svzta +.section svztb +.section svzua +.section svzub +.section svzva +.section svzvb +.section svzwa +.section svzwb +.section svzxa +.section svzxb +.section svzya +.section svzyb +.section svzza +.section svzzb +.section svz1a +.section svz1b +.section svz2a +.section svz2b +.section svz3a +.section svz3b +.section svz4a +.section svz4b +.section svz5a +.section svz5b +.section svz6a +.section svz6b +.section svz7a +.section svz7b +.section svz8a +.section svz8b +.section svz9a +.section svz9b +.section svz0a +.section svz0b +.section sv1aa +.section sv1ab +.section sv1ba +.section sv1bb +.section sv1ca +.section sv1cb +.section sv1da +.section sv1db +.section sv1ea +.section sv1eb +.section sv1fa +.section sv1fb +.section sv1ga +.section sv1gb +.section sv1ha +.section sv1hb +.section sv1ia +.section sv1ib +.section sv1ja +.section sv1jb +.section sv1ka +.section sv1kb +.section sv1la +.section sv1lb +.section sv1ma +.section sv1mb +.section sv1na +.section sv1nb +.section sv1oa +.section sv1ob +.section sv1pa +.section sv1pb +.section sv1qa +.section sv1qb +.section sv1ra +.section sv1rb +.section sv1sa +.section sv1sb +.section sv1ta +.section sv1tb +.section sv1ua +.section sv1ub +.section sv1va +.section sv1vb +.section sv1wa +.section sv1wb +.section sv1xa +.section sv1xb +.section sv1ya +.section sv1yb +.section sv1za +.section sv1zb +.section sv11a +.section sv11b +.section sv12a +.section sv12b +.section sv13a +.section sv13b +.section sv14a +.section sv14b +.section sv15a +.section sv15b +.section sv16a +.section sv16b +.section sv17a +.section sv17b +.section sv18a +.section sv18b +.section sv19a +.section sv19b +.section sv10a +.section sv10b +.section sv2aa +.section sv2ab +.section sv2ba +.section sv2bb +.section sv2ca +.section sv2cb +.section sv2da +.section sv2db +.section sv2ea +.section sv2eb +.section sv2fa +.section sv2fb +.section sv2ga +.section sv2gb +.section sv2ha +.section sv2hb +.section sv2ia +.section sv2ib +.section sv2ja +.section sv2jb +.section sv2ka +.section sv2kb +.section sv2la +.section sv2lb +.section sv2ma +.section sv2mb +.section sv2na +.section sv2nb +.section sv2oa +.section sv2ob +.section sv2pa +.section sv2pb +.section sv2qa +.section sv2qb +.section sv2ra +.section sv2rb +.section sv2sa +.section sv2sb +.section sv2ta +.section sv2tb +.section sv2ua +.section sv2ub +.section sv2va +.section sv2vb +.section sv2wa +.section sv2wb +.section sv2xa +.section sv2xb +.section sv2ya +.section sv2yb +.section sv2za +.section sv2zb +.section sv21a +.section sv21b +.section sv22a +.section sv22b +.section sv23a +.section sv23b +.section sv24a +.section sv24b +.section sv25a +.section sv25b +.section sv26a +.section sv26b +.section sv27a +.section sv27b +.section sv28a +.section sv28b +.section sv29a +.section sv29b +.section sv20a +.section sv20b +.section sv3aa +.section sv3ab +.section sv3ba +.section sv3bb +.section sv3ca +.section sv3cb +.section sv3da +.section sv3db +.section sv3ea +.section sv3eb +.section sv3fa +.section sv3fb +.section sv3ga +.section sv3gb +.section sv3ha +.section sv3hb +.section sv3ia +.section sv3ib +.section sv3ja +.section sv3jb +.section sv3ka +.section sv3kb +.section sv3la +.section sv3lb +.section sv3ma +.section sv3mb +.section sv3na +.section sv3nb +.section sv3oa +.section sv3ob +.section sv3pa +.section sv3pb +.section sv3qa +.section sv3qb +.section sv3ra +.section sv3rb +.section sv3sa +.section sv3sb +.section sv3ta +.section sv3tb +.section sv3ua +.section sv3ub +.section sv3va +.section sv3vb +.section sv3wa +.section sv3wb +.section sv3xa +.section sv3xb +.section sv3ya +.section sv3yb +.section sv3za +.section sv3zb +.section sv31a +.section sv31b +.section sv32a +.section sv32b +.section sv33a +.section sv33b +.section sv34a +.section sv34b +.section sv35a +.section sv35b +.section sv36a +.section sv36b +.section sv37a +.section sv37b +.section sv38a +.section sv38b +.section sv39a +.section sv39b +.section sv30a +.section sv30b +.section sv4aa +.section sv4ab +.section sv4ba +.section sv4bb +.section sv4ca +.section sv4cb +.section sv4da +.section sv4db +.section sv4ea +.section sv4eb +.section sv4fa +.section sv4fb +.section sv4ga +.section sv4gb +.section sv4ha +.section sv4hb +.section sv4ia +.section sv4ib +.section sv4ja +.section sv4jb +.section sv4ka +.section sv4kb +.section sv4la +.section sv4lb +.section sv4ma +.section sv4mb +.section sv4na +.section sv4nb +.section sv4oa +.section sv4ob +.section sv4pa +.section sv4pb +.section sv4qa +.section sv4qb +.section sv4ra +.section sv4rb +.section sv4sa +.section sv4sb +.section sv4ta +.section sv4tb +.section sv4ua +.section sv4ub +.section sv4va +.section sv4vb +.section sv4wa +.section sv4wb +.section sv4xa +.section sv4xb +.section sv4ya +.section sv4yb +.section sv4za +.section sv4zb +.section sv41a +.section sv41b +.section sv42a +.section sv42b +.section sv43a +.section sv43b +.section sv44a +.section sv44b +.section sv45a +.section sv45b +.section sv46a +.section sv46b +.section sv47a +.section sv47b +.section sv48a +.section sv48b +.section sv49a +.section sv49b +.section sv40a +.section sv40b +.section sv5aa +.section sv5ab +.section sv5ba +.section sv5bb +.section sv5ca +.section sv5cb +.section sv5da +.section sv5db +.section sv5ea +.section sv5eb +.section sv5fa +.section sv5fb +.section sv5ga +.section sv5gb +.section sv5ha +.section sv5hb +.section sv5ia +.section sv5ib +.section sv5ja +.section sv5jb +.section sv5ka +.section sv5kb +.section sv5la +.section sv5lb +.section sv5ma +.section sv5mb +.section sv5na +.section sv5nb +.section sv5oa +.section sv5ob +.section sv5pa +.section sv5pb +.section sv5qa +.section sv5qb +.section sv5ra +.section sv5rb +.section sv5sa +.section sv5sb +.section sv5ta +.section sv5tb +.section sv5ua +.section sv5ub +.section sv5va +.section sv5vb +.section sv5wa +.section sv5wb +.section sv5xa +.section sv5xb +.section sv5ya +.section sv5yb +.section sv5za +.section sv5zb +.section sv51a +.section sv51b +.section sv52a +.section sv52b +.section sv53a +.section sv53b +.section sv54a +.section sv54b +.section sv55a +.section sv55b +.section sv56a +.section sv56b +.section sv57a +.section sv57b +.section sv58a +.section sv58b +.section sv59a +.section sv59b +.section sv50a +.section sv50b +.section sv6aa +.section sv6ab +.section sv6ba +.section sv6bb +.section sv6ca +.section sv6cb +.section sv6da +.section sv6db +.section sv6ea +.section sv6eb +.section sv6fa +.section sv6fb +.section sv6ga +.section sv6gb +.section sv6ha +.section sv6hb +.section sv6ia +.section sv6ib +.section sv6ja +.section sv6jb +.section sv6ka +.section sv6kb +.section sv6la +.section sv6lb +.section sv6ma +.section sv6mb +.section sv6na +.section sv6nb +.section sv6oa +.section sv6ob +.section sv6pa +.section sv6pb +.section sv6qa +.section sv6qb +.section sv6ra +.section sv6rb +.section sv6sa +.section sv6sb +.section sv6ta +.section sv6tb +.section sv6ua +.section sv6ub +.section sv6va +.section sv6vb +.section sv6wa +.section sv6wb +.section sv6xa +.section sv6xb +.section sv6ya +.section sv6yb +.section sv6za +.section sv6zb +.section sv61a +.section sv61b +.section sv62a +.section sv62b +.section sv63a +.section sv63b +.section sv64a +.section sv64b +.section sv65a +.section sv65b +.section sv66a +.section sv66b +.section sv67a +.section sv67b +.section sv68a +.section sv68b +.section sv69a +.section sv69b +.section sv60a +.section sv60b +.section sv7aa +.section sv7ab +.section sv7ba +.section sv7bb +.section sv7ca +.section sv7cb +.section sv7da +.section sv7db +.section sv7ea +.section sv7eb +.section sv7fa +.section sv7fb +.section sv7ga +.section sv7gb +.section sv7ha +.section sv7hb +.section sv7ia +.section sv7ib +.section sv7ja +.section sv7jb +.section sv7ka +.section sv7kb +.section sv7la +.section sv7lb +.section sv7ma +.section sv7mb +.section sv7na +.section sv7nb +.section sv7oa +.section sv7ob +.section sv7pa +.section sv7pb +.section sv7qa +.section sv7qb +.section sv7ra +.section sv7rb +.section sv7sa +.section sv7sb +.section sv7ta +.section sv7tb +.section sv7ua +.section sv7ub +.section sv7va +.section sv7vb +.section sv7wa +.section sv7wb +.section sv7xa +.section sv7xb +.section sv7ya +.section sv7yb +.section sv7za +.section sv7zb +.section sv71a +.section sv71b +.section sv72a +.section sv72b +.section sv73a +.section sv73b +.section sv74a +.section sv74b +.section sv75a +.section sv75b +.section sv76a +.section sv76b +.section sv77a +.section sv77b +.section sv78a +.section sv78b +.section sv79a +.section sv79b +.section sv70a +.section sv70b +.section sv8aa +.section sv8ab +.section sv8ba +.section sv8bb +.section sv8ca +.section sv8cb +.section sv8da +.section sv8db +.section sv8ea +.section sv8eb +.section sv8fa +.section sv8fb +.section sv8ga +.section sv8gb +.section sv8ha +.section sv8hb +.section sv8ia +.section sv8ib +.section sv8ja +.section sv8jb +.section sv8ka +.section sv8kb +.section sv8la +.section sv8lb +.section sv8ma +.section sv8mb +.section sv8na +.section sv8nb +.section sv8oa +.section sv8ob +.section sv8pa +.section sv8pb +.section sv8qa +.section sv8qb +.section sv8ra +.section sv8rb +.section sv8sa +.section sv8sb +.section sv8ta +.section sv8tb +.section sv8ua +.section sv8ub +.section sv8va +.section sv8vb +.section sv8wa +.section sv8wb +.section sv8xa +.section sv8xb +.section sv8ya +.section sv8yb +.section sv8za +.section sv8zb +.section sv81a +.section sv81b +.section sv82a +.section sv82b +.section sv83a +.section sv83b +.section sv84a +.section sv84b +.section sv85a +.section sv85b +.section sv86a +.section sv86b +.section sv87a +.section sv87b +.section sv88a +.section sv88b +.section sv89a +.section sv89b +.section sv80a +.section sv80b +.section sv9aa +.section sv9ab +.section sv9ba +.section sv9bb +.section sv9ca +.section sv9cb +.section sv9da +.section sv9db +.section sv9ea +.section sv9eb +.section sv9fa +.section sv9fb +.section sv9ga +.section sv9gb +.section sv9ha +.section sv9hb +.section sv9ia +.section sv9ib +.section sv9ja +.section sv9jb +.section sv9ka +.section sv9kb +.section sv9la +.section sv9lb +.section sv9ma +.section sv9mb +.section sv9na +.section sv9nb +.section sv9oa +.section sv9ob +.section sv9pa +.section sv9pb +.section sv9qa +.section sv9qb +.section sv9ra +.section sv9rb +.section sv9sa +.section sv9sb +.section sv9ta +.section sv9tb +.section sv9ua +.section sv9ub +.section sv9va +.section sv9vb +.section sv9wa +.section sv9wb +.section sv9xa +.section sv9xb +.section sv9ya +.section sv9yb +.section sv9za +.section sv9zb +.section sv91a +.section sv91b +.section sv92a +.section sv92b +.section sv93a +.section sv93b +.section sv94a +.section sv94b +.section sv95a +.section sv95b +.section sv96a +.section sv96b +.section sv97a +.section sv97b +.section sv98a +.section sv98b +.section sv99a +.section sv99b +.section sv90a +.section sv90b +.section sv0aa +.section sv0ab +.section sv0ba +.section sv0bb +.section sv0ca +.section sv0cb +.section sv0da +.section sv0db +.section sv0ea +.section sv0eb +.section sv0fa +.section sv0fb +.section sv0ga +.section sv0gb +.section sv0ha +.section sv0hb +.section sv0ia +.section sv0ib +.section sv0ja +.section sv0jb +.section sv0ka +.section sv0kb +.section sv0la +.section sv0lb +.section sv0ma +.section sv0mb +.section sv0na +.section sv0nb +.section sv0oa +.section sv0ob +.section sv0pa +.section sv0pb +.section sv0qa +.section sv0qb +.section sv0ra +.section sv0rb +.section sv0sa +.section sv0sb +.section sv0ta +.section sv0tb +.section sv0ua +.section sv0ub +.section sv0va +.section sv0vb +.section sv0wa +.section sv0wb +.section sv0xa +.section sv0xb +.section sv0ya +.section sv0yb +.section sv0za +.section sv0zb +.section sv01a +.section sv01b +.section sv02a +.section sv02b +.section sv03a +.section sv03b +.section sv04a +.section sv04b +.section sv05a +.section sv05b +.section sv06a +.section sv06b +.section sv07a +.section sv07b +.section sv08a +.section sv08b +.section sv09a +.section sv09b +.section sv00a +.section sv00b +.section swaaa +.section swaab +.section swaba +.section swabb +.section swaca +.section swacb +.section swada +.section swadb +.section swaea +.section swaeb +.section swafa +.section swafb +.section swaga +.section swagb +.section swaha +.section swahb +.section swaia +.section swaib +.section swaja +.section swajb +.section swaka +.section swakb +.section swala +.section swalb +.section swama +.section swamb +.section swana +.section swanb +.section swaoa +.section swaob +.section swapa +.section swapb +.section swaqa +.section swaqb +.section swara +.section swarb +.section swasa +.section swasb +.section swata +.section swatb +.section swaua +.section swaub +.section swava +.section swavb +.section swawa +.section swawb +.section swaxa +.section swaxb +.section swaya +.section swayb +.section swaza +.section swazb +.section swa1a +.section swa1b +.section swa2a +.section swa2b +.section swa3a +.section swa3b +.section swa4a +.section swa4b +.section swa5a +.section swa5b +.section swa6a +.section swa6b +.section swa7a +.section swa7b +.section swa8a +.section swa8b +.section swa9a +.section swa9b +.section swa0a +.section swa0b +.section swbaa +.section swbab +.section swbba +.section swbbb +.section swbca +.section swbcb +.section swbda +.section swbdb +.section swbea +.section swbeb +.section swbfa +.section swbfb +.section swbga +.section swbgb +.section swbha +.section swbhb +.section swbia +.section swbib +.section swbja +.section swbjb +.section swbka +.section swbkb +.section swbla +.section swblb +.section swbma +.section swbmb +.section swbna +.section swbnb +.section swboa +.section swbob +.section swbpa +.section swbpb +.section swbqa +.section swbqb +.section swbra +.section swbrb +.section swbsa +.section swbsb +.section swbta +.section swbtb +.section swbua +.section swbub +.section swbva +.section swbvb +.section swbwa +.section swbwb +.section swbxa +.section swbxb +.section swbya +.section swbyb +.section swbza +.section swbzb +.section swb1a +.section swb1b +.section swb2a +.section swb2b +.section swb3a +.section swb3b +.section swb4a +.section swb4b +.section swb5a +.section swb5b +.section swb6a +.section swb6b +.section swb7a +.section swb7b +.section swb8a +.section swb8b +.section swb9a +.section swb9b +.section swb0a +.section swb0b +.section swcaa +.section swcab +.section swcba +.section swcbb +.section swcca +.section swccb +.section swcda +.section swcdb +.section swcea +.section swceb +.section swcfa +.section swcfb +.section swcga +.section swcgb +.section swcha +.section swchb +.section swcia +.section swcib +.section swcja +.section swcjb +.section swcka +.section swckb +.section swcla +.section swclb +.section swcma +.section swcmb +.section swcna +.section swcnb +.section swcoa +.section swcob +.section swcpa +.section swcpb +.section swcqa +.section swcqb +.section swcra +.section swcrb +.section swcsa +.section swcsb +.section swcta +.section swctb +.section swcua +.section swcub +.section swcva +.section swcvb +.section swcwa +.section swcwb +.section swcxa +.section swcxb +.section swcya +.section swcyb +.section swcza +.section swczb +.section swc1a +.section swc1b +.section swc2a +.section swc2b +.section swc3a +.section swc3b +.section swc4a +.section swc4b +.section swc5a +.section swc5b +.section swc6a +.section swc6b +.section swc7a +.section swc7b +.section swc8a +.section swc8b +.section swc9a +.section swc9b +.section swc0a +.section swc0b +.section swdaa +.section swdab +.section swdba +.section swdbb +.section swdca +.section swdcb +.section swdda +.section swddb +.section swdea +.section swdeb +.section swdfa +.section swdfb +.section swdga +.section swdgb +.section swdha +.section swdhb +.section swdia +.section swdib +.section swdja +.section swdjb +.section swdka +.section swdkb +.section swdla +.section swdlb +.section swdma +.section swdmb +.section swdna +.section swdnb +.section swdoa +.section swdob +.section swdpa +.section swdpb +.section swdqa +.section swdqb +.section swdra +.section swdrb +.section swdsa +.section swdsb +.section swdta +.section swdtb +.section swdua +.section swdub +.section swdva +.section swdvb +.section swdwa +.section swdwb +.section swdxa +.section swdxb +.section swdya +.section swdyb +.section swdza +.section swdzb +.section swd1a +.section swd1b +.section swd2a +.section swd2b +.section swd3a +.section swd3b +.section swd4a +.section swd4b +.section swd5a +.section swd5b +.section swd6a +.section swd6b +.section swd7a +.section swd7b +.section swd8a +.section swd8b +.section swd9a +.section swd9b +.section swd0a +.section swd0b +.section sweaa +.section sweab +.section sweba +.section swebb +.section sweca +.section swecb +.section sweda +.section swedb +.section sweea +.section sweeb +.section swefa +.section swefb +.section swega +.section swegb +.section sweha +.section swehb +.section sweia +.section sweib +.section sweja +.section swejb +.section sweka +.section swekb +.section swela +.section swelb +.section swema +.section swemb +.section swena +.section swenb +.section sweoa +.section sweob +.section swepa +.section swepb +.section sweqa +.section sweqb +.section swera +.section swerb +.section swesa +.section swesb +.section sweta +.section swetb +.section sweua +.section sweub +.section sweva +.section swevb +.section swewa +.section swewb +.section swexa +.section swexb +.section sweya +.section sweyb +.section sweza +.section swezb +.section swe1a +.section swe1b +.section swe2a +.section swe2b +.section swe3a +.section swe3b +.section swe4a +.section swe4b +.section swe5a +.section swe5b +.section swe6a +.section swe6b +.section swe7a +.section swe7b +.section swe8a +.section swe8b +.section swe9a +.section swe9b +.section swe0a +.section swe0b +.section swfaa +.section swfab +.section swfba +.section swfbb +.section swfca +.section swfcb +.section swfda +.section swfdb +.section swfea +.section swfeb +.section swffa +.section swffb +.section swfga +.section swfgb +.section swfha +.section swfhb +.section swfia +.section swfib +.section swfja +.section swfjb +.section swfka +.section swfkb +.section swfla +.section swflb +.section swfma +.section swfmb +.section swfna +.section swfnb +.section swfoa +.section swfob +.section swfpa +.section swfpb +.section swfqa +.section swfqb +.section swfra +.section swfrb +.section swfsa +.section swfsb +.section swfta +.section swftb +.section swfua +.section swfub +.section swfva +.section swfvb +.section swfwa +.section swfwb +.section swfxa +.section swfxb +.section swfya +.section swfyb +.section swfza +.section swfzb +.section swf1a +.section swf1b +.section swf2a +.section swf2b +.section swf3a +.section swf3b +.section swf4a +.section swf4b +.section swf5a +.section swf5b +.section swf6a +.section swf6b +.section swf7a +.section swf7b +.section swf8a +.section swf8b +.section swf9a +.section swf9b +.section swf0a +.section swf0b +.section swgaa +.section swgab +.section swgba +.section swgbb +.section swgca +.section swgcb +.section swgda +.section swgdb +.section swgea +.section swgeb +.section swgfa +.section swgfb +.section swgga +.section swggb +.section swgha +.section swghb +.section swgia +.section swgib +.section swgja +.section swgjb +.section swgka +.section swgkb +.section swgla +.section swglb +.section swgma +.section swgmb +.section swgna +.section swgnb +.section swgoa +.section swgob +.section swgpa +.section swgpb +.section swgqa +.section swgqb +.section swgra +.section swgrb +.section swgsa +.section swgsb +.section swgta +.section swgtb +.section swgua +.section swgub +.section swgva +.section swgvb +.section swgwa +.section swgwb +.section swgxa +.section swgxb +.section swgya +.section swgyb +.section swgza +.section swgzb +.section swg1a +.section swg1b +.section swg2a +.section swg2b +.section swg3a +.section swg3b +.section swg4a +.section swg4b +.section swg5a +.section swg5b +.section swg6a +.section swg6b +.section swg7a +.section swg7b +.section swg8a +.section swg8b +.section swg9a +.section swg9b +.section swg0a +.section swg0b +.section swhaa +.section swhab +.section swhba +.section swhbb +.section swhca +.section swhcb +.section swhda +.section swhdb +.section swhea +.section swheb +.section swhfa +.section swhfb +.section swhga +.section swhgb +.section swhha +.section swhhb +.section swhia +.section swhib +.section swhja +.section swhjb +.section swhka +.section swhkb +.section swhla +.section swhlb +.section swhma +.section swhmb +.section swhna +.section swhnb +.section swhoa +.section swhob +.section swhpa +.section swhpb +.section swhqa +.section swhqb +.section swhra +.section swhrb +.section swhsa +.section swhsb +.section swhta +.section swhtb +.section swhua +.section swhub +.section swhva +.section swhvb +.section swhwa +.section swhwb +.section swhxa +.section swhxb +.section swhya +.section swhyb +.section swhza +.section swhzb +.section swh1a +.section swh1b +.section swh2a +.section swh2b +.section swh3a +.section swh3b +.section swh4a +.section swh4b +.section swh5a +.section swh5b +.section swh6a +.section swh6b +.section swh7a +.section swh7b +.section swh8a +.section swh8b +.section swh9a +.section swh9b +.section swh0a +.section swh0b +.section swiaa +.section swiab +.section swiba +.section swibb +.section swica +.section swicb +.section swida +.section swidb +.section swiea +.section swieb +.section swifa +.section swifb +.section swiga +.section swigb +.section swiha +.section swihb +.section swiia +.section swiib +.section swija +.section swijb +.section swika +.section swikb +.section swila +.section swilb +.section swima +.section swimb +.section swina +.section swinb +.section swioa +.section swiob +.section swipa +.section swipb +.section swiqa +.section swiqb +.section swira +.section swirb +.section swisa +.section swisb +.section swita +.section switb +.section swiua +.section swiub +.section swiva +.section swivb +.section swiwa +.section swiwb +.section swixa +.section swixb +.section swiya +.section swiyb +.section swiza +.section swizb +.section swi1a +.section swi1b +.section swi2a +.section swi2b +.section swi3a +.section swi3b +.section swi4a +.section swi4b +.section swi5a +.section swi5b +.section swi6a +.section swi6b +.section swi7a +.section swi7b +.section swi8a +.section swi8b +.section swi9a +.section swi9b +.section swi0a +.section swi0b +.section swjaa +.section swjab +.section swjba +.section swjbb +.section swjca +.section swjcb +.section swjda +.section swjdb +.section swjea +.section swjeb +.section swjfa +.section swjfb +.section swjga +.section swjgb +.section swjha +.section swjhb +.section swjia +.section swjib +.section swjja +.section swjjb +.section swjka +.section swjkb +.section swjla +.section swjlb +.section swjma +.section swjmb +.section swjna +.section swjnb +.section swjoa +.section swjob +.section swjpa +.section swjpb +.section swjqa +.section swjqb +.section swjra +.section swjrb +.section swjsa +.section swjsb +.section swjta +.section swjtb +.section swjua +.section swjub +.section swjva +.section swjvb +.section swjwa +.section swjwb +.section swjxa +.section swjxb +.section swjya +.section swjyb +.section swjza +.section swjzb +.section swj1a +.section swj1b +.section swj2a +.section swj2b +.section swj3a +.section swj3b +.section swj4a +.section swj4b +.section swj5a +.section swj5b +.section swj6a +.section swj6b +.section swj7a +.section swj7b +.section swj8a +.section swj8b +.section swj9a +.section swj9b +.section swj0a +.section swj0b +.section swkaa +.section swkab +.section swkba +.section swkbb +.section swkca +.section swkcb +.section swkda +.section swkdb +.section swkea +.section swkeb +.section swkfa +.section swkfb +.section swkga +.section swkgb +.section swkha +.section swkhb +.section swkia +.section swkib +.section swkja +.section swkjb +.section swkka +.section swkkb +.section swkla +.section swklb +.section swkma +.section swkmb +.section swkna +.section swknb +.section swkoa +.section swkob +.section swkpa +.section swkpb +.section swkqa +.section swkqb +.section swkra +.section swkrb +.section swksa +.section swksb +.section swkta +.section swktb +.section swkua +.section swkub +.section swkva +.section swkvb +.section swkwa +.section swkwb +.section swkxa +.section swkxb +.section swkya +.section swkyb +.section swkza +.section swkzb +.section swk1a +.section swk1b +.section swk2a +.section swk2b +.section swk3a +.section swk3b +.section swk4a +.section swk4b +.section swk5a +.section swk5b +.section swk6a +.section swk6b +.section swk7a +.section swk7b +.section swk8a +.section swk8b +.section swk9a +.section swk9b +.section swk0a +.section swk0b +.section swlaa +.section swlab +.section swlba +.section swlbb +.section swlca +.section swlcb +.section swlda +.section swldb +.section swlea +.section swleb +.section swlfa +.section swlfb +.section swlga +.section swlgb +.section swlha +.section swlhb +.section swlia +.section swlib +.section swlja +.section swljb +.section swlka +.section swlkb +.section swlla +.section swllb +.section swlma +.section swlmb +.section swlna +.section swlnb +.section swloa +.section swlob +.section swlpa +.section swlpb +.section swlqa +.section swlqb +.section swlra +.section swlrb +.section swlsa +.section swlsb +.section swlta +.section swltb +.section swlua +.section swlub +.section swlva +.section swlvb +.section swlwa +.section swlwb +.section swlxa +.section swlxb +.section swlya +.section swlyb +.section swlza +.section swlzb +.section swl1a +.section swl1b +.section swl2a +.section swl2b +.section swl3a +.section swl3b +.section swl4a +.section swl4b +.section swl5a +.section swl5b +.section swl6a +.section swl6b +.section swl7a +.section swl7b +.section swl8a +.section swl8b +.section swl9a +.section swl9b +.section swl0a +.section swl0b +.section swmaa +.section swmab +.section swmba +.section swmbb +.section swmca +.section swmcb +.section swmda +.section swmdb +.section swmea +.section swmeb +.section swmfa +.section swmfb +.section swmga +.section swmgb +.section swmha +.section swmhb +.section swmia +.section swmib +.section swmja +.section swmjb +.section swmka +.section swmkb +.section swmla +.section swmlb +.section swmma +.section swmmb +.section swmna +.section swmnb +.section swmoa +.section swmob +.section swmpa +.section swmpb +.section swmqa +.section swmqb +.section swmra +.section swmrb +.section swmsa +.section swmsb +.section swmta +.section swmtb +.section swmua +.section swmub +.section swmva +.section swmvb +.section swmwa +.section swmwb +.section swmxa +.section swmxb +.section swmya +.section swmyb +.section swmza +.section swmzb +.section swm1a +.section swm1b +.section swm2a +.section swm2b +.section swm3a +.section swm3b +.section swm4a +.section swm4b +.section swm5a +.section swm5b +.section swm6a +.section swm6b +.section swm7a +.section swm7b +.section swm8a +.section swm8b +.section swm9a +.section swm9b +.section swm0a +.section swm0b +.section swnaa +.section swnab +.section swnba +.section swnbb +.section swnca +.section swncb +.section swnda +.section swndb +.section swnea +.section swneb +.section swnfa +.section swnfb +.section swnga +.section swngb +.section swnha +.section swnhb +.section swnia +.section swnib +.section swnja +.section swnjb +.section swnka +.section swnkb +.section swnla +.section swnlb +.section swnma +.section swnmb +.section swnna +.section swnnb +.section swnoa +.section swnob +.section swnpa +.section swnpb +.section swnqa +.section swnqb +.section swnra +.section swnrb +.section swnsa +.section swnsb +.section swnta +.section swntb +.section swnua +.section swnub +.section swnva +.section swnvb +.section swnwa +.section swnwb +.section swnxa +.section swnxb +.section swnya +.section swnyb +.section swnza +.section swnzb +.section swn1a +.section swn1b +.section swn2a +.section swn2b +.section swn3a +.section swn3b +.section swn4a +.section swn4b +.section swn5a +.section swn5b +.section swn6a +.section swn6b +.section swn7a +.section swn7b +.section swn8a +.section swn8b +.section swn9a +.section swn9b +.section swn0a +.section swn0b +.section swoaa +.section swoab +.section swoba +.section swobb +.section swoca +.section swocb +.section swoda +.section swodb +.section swoea +.section swoeb +.section swofa +.section swofb +.section swoga +.section swogb +.section swoha +.section swohb +.section swoia +.section swoib +.section swoja +.section swojb +.section swoka +.section swokb +.section swola +.section swolb +.section swoma +.section swomb +.section swona +.section swonb +.section swooa +.section swoob +.section swopa +.section swopb +.section swoqa +.section swoqb +.section swora +.section sworb +.section swosa +.section swosb +.section swota +.section swotb +.section swoua +.section swoub +.section swova +.section swovb +.section swowa +.section swowb +.section swoxa +.section swoxb +.section swoya +.section swoyb +.section swoza +.section swozb +.section swo1a +.section swo1b +.section swo2a +.section swo2b +.section swo3a +.section swo3b +.section swo4a +.section swo4b +.section swo5a +.section swo5b +.section swo6a +.section swo6b +.section swo7a +.section swo7b +.section swo8a +.section swo8b +.section swo9a +.section swo9b +.section swo0a +.section swo0b +.section swpaa +.section swpab +.section swpba +.section swpbb +.section swpca +.section swpcb +.section swpda +.section swpdb +.section swpea +.section swpeb +.section swpfa +.section swpfb +.section swpga +.section swpgb +.section swpha +.section swphb +.section swpia +.section swpib +.section swpja +.section swpjb +.section swpka +.section swpkb +.section swpla +.section swplb +.section swpma +.section swpmb +.section swpna +.section swpnb +.section swpoa +.section swpob +.section swppa +.section swppb +.section swpqa +.section swpqb +.section swpra +.section swprb +.section swpsa +.section swpsb +.section swpta +.section swptb +.section swpua +.section swpub +.section swpva +.section swpvb +.section swpwa +.section swpwb +.section swpxa +.section swpxb +.section swpya +.section swpyb +.section swpza +.section swpzb +.section swp1a +.section swp1b +.section swp2a +.section swp2b +.section swp3a +.section swp3b +.section swp4a +.section swp4b +.section swp5a +.section swp5b +.section swp6a +.section swp6b +.section swp7a +.section swp7b +.section swp8a +.section swp8b +.section swp9a +.section swp9b +.section swp0a +.section swp0b +.section swqaa +.section swqab +.section swqba +.section swqbb +.section swqca +.section swqcb +.section swqda +.section swqdb +.section swqea +.section swqeb +.section swqfa +.section swqfb +.section swqga +.section swqgb +.section swqha +.section swqhb +.section swqia +.section swqib +.section swqja +.section swqjb +.section swqka +.section swqkb +.section swqla +.section swqlb +.section swqma +.section swqmb +.section swqna +.section swqnb +.section swqoa +.section swqob +.section swqpa +.section swqpb +.section swqqa +.section swqqb +.section swqra +.section swqrb +.section swqsa +.section swqsb +.section swqta +.section swqtb +.section swqua +.section swqub +.section swqva +.section swqvb +.section swqwa +.section swqwb +.section swqxa +.section swqxb +.section swqya +.section swqyb +.section swqza +.section swqzb +.section swq1a +.section swq1b +.section swq2a +.section swq2b +.section swq3a +.section swq3b +.section swq4a +.section swq4b +.section swq5a +.section swq5b +.section swq6a +.section swq6b +.section swq7a +.section swq7b +.section swq8a +.section swq8b +.section swq9a +.section swq9b +.section swq0a +.section swq0b +.section swraa +.section swrab +.section swrba +.section swrbb +.section swrca +.section swrcb +.section swrda +.section swrdb +.section swrea +.section swreb +.section swrfa +.section swrfb +.section swrga +.section swrgb +.section swrha +.section swrhb +.section swria +.section swrib +.section swrja +.section swrjb +.section swrka +.section swrkb +.section swrla +.section swrlb +.section swrma +.section swrmb +.section swrna +.section swrnb +.section swroa +.section swrob +.section swrpa +.section swrpb +.section swrqa +.section swrqb +.section swrra +.section swrrb +.section swrsa +.section swrsb +.section swrta +.section swrtb +.section swrua +.section swrub +.section swrva +.section swrvb +.section swrwa +.section swrwb +.section swrxa +.section swrxb +.section swrya +.section swryb +.section swrza +.section swrzb +.section swr1a +.section swr1b +.section swr2a +.section swr2b +.section swr3a +.section swr3b +.section swr4a +.section swr4b +.section swr5a +.section swr5b +.section swr6a +.section swr6b +.section swr7a +.section swr7b +.section swr8a +.section swr8b +.section swr9a +.section swr9b +.section swr0a +.section swr0b +.section swsaa +.section swsab +.section swsba +.section swsbb +.section swsca +.section swscb +.section swsda +.section swsdb +.section swsea +.section swseb +.section swsfa +.section swsfb +.section swsga +.section swsgb +.section swsha +.section swshb +.section swsia +.section swsib +.section swsja +.section swsjb +.section swska +.section swskb +.section swsla +.section swslb +.section swsma +.section swsmb +.section swsna +.section swsnb +.section swsoa +.section swsob +.section swspa +.section swspb +.section swsqa +.section swsqb +.section swsra +.section swsrb +.section swssa +.section swssb +.section swsta +.section swstb +.section swsua +.section swsub +.section swsva +.section swsvb +.section swswa +.section swswb +.section swsxa +.section swsxb +.section swsya +.section swsyb +.section swsza +.section swszb +.section sws1a +.section sws1b +.section sws2a +.section sws2b +.section sws3a +.section sws3b +.section sws4a +.section sws4b +.section sws5a +.section sws5b +.section sws6a +.section sws6b +.section sws7a +.section sws7b +.section sws8a +.section sws8b +.section sws9a +.section sws9b +.section sws0a +.section sws0b +.section swtaa +.section swtab +.section swtba +.section swtbb +.section swtca +.section swtcb +.section swtda +.section swtdb +.section swtea +.section swteb +.section swtfa +.section swtfb +.section swtga +.section swtgb +.section swtha +.section swthb +.section swtia +.section swtib +.section swtja +.section swtjb +.section swtka +.section swtkb +.section swtla +.section swtlb +.section swtma +.section swtmb +.section swtna +.section swtnb +.section swtoa +.section swtob +.section swtpa +.section swtpb +.section swtqa +.section swtqb +.section swtra +.section swtrb +.section swtsa +.section swtsb +.section swtta +.section swttb +.section swtua +.section swtub +.section swtva +.section swtvb +.section swtwa +.section swtwb +.section swtxa +.section swtxb +.section swtya +.section swtyb +.section swtza +.section swtzb +.section swt1a +.section swt1b +.section swt2a +.section swt2b +.section swt3a +.section swt3b +.section swt4a +.section swt4b +.section swt5a +.section swt5b +.section swt6a +.section swt6b +.section swt7a +.section swt7b +.section swt8a +.section swt8b +.section swt9a +.section swt9b +.section swt0a +.section swt0b +.section swuaa +.section swuab +.section swuba +.section swubb +.section swuca +.section swucb +.section swuda +.section swudb +.section swuea +.section swueb +.section swufa +.section swufb +.section swuga +.section swugb +.section swuha +.section swuhb +.section swuia +.section swuib +.section swuja +.section swujb +.section swuka +.section swukb +.section swula +.section swulb +.section swuma +.section swumb +.section swuna +.section swunb +.section swuoa +.section swuob +.section swupa +.section swupb +.section swuqa +.section swuqb +.section swura +.section swurb +.section swusa +.section swusb +.section swuta +.section swutb +.section swuua +.section swuub +.section swuva +.section swuvb +.section swuwa +.section swuwb +.section swuxa +.section swuxb +.section swuya +.section swuyb +.section swuza +.section swuzb +.section swu1a +.section swu1b +.section swu2a +.section swu2b +.section swu3a +.section swu3b +.section swu4a +.section swu4b +.section swu5a +.section swu5b +.section swu6a +.section swu6b +.section swu7a +.section swu7b +.section swu8a +.section swu8b +.section swu9a +.section swu9b +.section swu0a +.section swu0b +.section swvaa +.section swvab +.section swvba +.section swvbb +.section swvca +.section swvcb +.section swvda +.section swvdb +.section swvea +.section swveb +.section swvfa +.section swvfb +.section swvga +.section swvgb +.section swvha +.section swvhb +.section swvia +.section swvib +.section swvja +.section swvjb +.section swvka +.section swvkb +.section swvla +.section swvlb +.section swvma +.section swvmb +.section swvna +.section swvnb +.section swvoa +.section swvob +.section swvpa +.section swvpb +.section swvqa +.section swvqb +.section swvra +.section swvrb +.section swvsa +.section swvsb +.section swvta +.section swvtb +.section swvua +.section swvub +.section swvva +.section swvvb +.section swvwa +.section swvwb +.section swvxa +.section swvxb +.section swvya +.section swvyb +.section swvza +.section swvzb +.section swv1a +.section swv1b +.section swv2a +.section swv2b +.section swv3a +.section swv3b +.section swv4a +.section swv4b +.section swv5a +.section swv5b +.section swv6a +.section swv6b +.section swv7a +.section swv7b +.section swv8a +.section swv8b +.section swv9a +.section swv9b +.section swv0a +.section swv0b +.section swwaa +.section swwab +.section swwba +.section swwbb +.section swwca +.section swwcb +.section swwda +.section swwdb +.section swwea +.section swweb +.section swwfa +.section swwfb +.section swwga +.section swwgb +.section swwha +.section swwhb +.section swwia +.section swwib +.section swwja +.section swwjb +.section swwka +.section swwkb +.section swwla +.section swwlb +.section swwma +.section swwmb +.section swwna +.section swwnb +.section swwoa +.section swwob +.section swwpa +.section swwpb +.section swwqa +.section swwqb +.section swwra +.section swwrb +.section swwsa +.section swwsb +.section swwta +.section swwtb +.section swwua +.section swwub +.section swwva +.section swwvb +.section swwwa +.section swwwb +.section swwxa +.section swwxb +.section swwya +.section swwyb +.section swwza +.section swwzb +.section sww1a +.section sww1b +.section sww2a +.section sww2b +.section sww3a +.section sww3b +.section sww4a +.section sww4b +.section sww5a +.section sww5b +.section sww6a +.section sww6b +.section sww7a +.section sww7b +.section sww8a +.section sww8b +.section sww9a +.section sww9b +.section sww0a +.section sww0b +.section swxaa +.section swxab +.section swxba +.section swxbb +.section swxca +.section swxcb +.section swxda +.section swxdb +.section swxea +.section swxeb +.section swxfa +.section swxfb +.section swxga +.section swxgb +.section swxha +.section swxhb +.section swxia +.section swxib +.section swxja +.section swxjb +.section swxka +.section swxkb +.section swxla +.section swxlb +.section swxma +.section swxmb +.section swxna +.section swxnb +.section swxoa +.section swxob +.section swxpa +.section swxpb +.section swxqa +.section swxqb +.section swxra +.section swxrb +.section swxsa +.section swxsb +.section swxta +.section swxtb +.section swxua +.section swxub +.section swxva +.section swxvb +.section swxwa +.section swxwb +.section swxxa +.section swxxb +.section swxya +.section swxyb +.section swxza +.section swxzb +.section swx1a +.section swx1b +.section swx2a +.section swx2b +.section swx3a +.section swx3b +.section swx4a +.section swx4b +.section swx5a +.section swx5b +.section swx6a +.section swx6b +.section swx7a +.section swx7b +.section swx8a +.section swx8b +.section swx9a +.section swx9b +.section swx0a +.section swx0b +.section swyaa +.section swyab +.section swyba +.section swybb +.section swyca +.section swycb +.section swyda +.section swydb +.section swyea +.section swyeb +.section swyfa +.section swyfb +.section swyga +.section swygb +.section swyha +.section swyhb +.section swyia +.section swyib +.section swyja +.section swyjb +.section swyka +.section swykb +.section swyla +.section swylb +.section swyma +.section swymb +.section swyna +.section swynb +.section swyoa +.section swyob +.section swypa +.section swypb +.section swyqa +.section swyqb +.section swyra +.section swyrb +.section swysa +.section swysb +.section swyta +.section swytb +.section swyua +.section swyub +.section swyva +.section swyvb +.section swywa +.section swywb +.section swyxa +.section swyxb +.section swyya +.section swyyb +.section swyza +.section swyzb +.section swy1a +.section swy1b +.section swy2a +.section swy2b +.section swy3a +.section swy3b +.section swy4a +.section swy4b +.section swy5a +.section swy5b +.section swy6a +.section swy6b +.section swy7a +.section swy7b +.section swy8a +.section swy8b +.section swy9a +.section swy9b +.section swy0a +.section swy0b +.section swzaa +.section swzab +.section swzba +.section swzbb +.section swzca +.section swzcb +.section swzda +.section swzdb +.section swzea +.section swzeb +.section swzfa +.section swzfb +.section swzga +.section swzgb +.section swzha +.section swzhb +.section swzia +.section swzib +.section swzja +.section swzjb +.section swzka +.section swzkb +.section swzla +.section swzlb +.section swzma +.section swzmb +.section swzna +.section swznb +.section swzoa +.section swzob +.section swzpa +.section swzpb +.section swzqa +.section swzqb +.section swzra +.section swzrb +.section swzsa +.section swzsb +.section swzta +.section swztb +.section swzua +.section swzub +.section swzva +.section swzvb +.section swzwa +.section swzwb +.section swzxa +.section swzxb +.section swzya +.section swzyb +.section swzza +.section swzzb +.section swz1a +.section swz1b +.section swz2a +.section swz2b +.section swz3a +.section swz3b +.section swz4a +.section swz4b +.section swz5a +.section swz5b +.section swz6a +.section swz6b +.section swz7a +.section swz7b +.section swz8a +.section swz8b +.section swz9a +.section swz9b +.section swz0a +.section swz0b +.section sw1aa +.section sw1ab +.section sw1ba +.section sw1bb +.section sw1ca +.section sw1cb +.section sw1da +.section sw1db +.section sw1ea +.section sw1eb +.section sw1fa +.section sw1fb +.section sw1ga +.section sw1gb +.section sw1ha +.section sw1hb +.section sw1ia +.section sw1ib +.section sw1ja +.section sw1jb +.section sw1ka +.section sw1kb +.section sw1la +.section sw1lb +.section sw1ma +.section sw1mb +.section sw1na +.section sw1nb +.section sw1oa +.section sw1ob +.section sw1pa +.section sw1pb +.section sw1qa +.section sw1qb +.section sw1ra +.section sw1rb +.section sw1sa +.section sw1sb +.section sw1ta +.section sw1tb +.section sw1ua +.section sw1ub +.section sw1va +.section sw1vb +.section sw1wa +.section sw1wb +.section sw1xa +.section sw1xb +.section sw1ya +.section sw1yb +.section sw1za +.section sw1zb +.section sw11a +.section sw11b +.section sw12a +.section sw12b +.section sw13a +.section sw13b +.section sw14a +.section sw14b +.section sw15a +.section sw15b +.section sw16a +.section sw16b +.section sw17a +.section sw17b +.section sw18a +.section sw18b +.section sw19a +.section sw19b +.section sw10a +.section sw10b +.section sw2aa +.section sw2ab +.section sw2ba +.section sw2bb +.section sw2ca +.section sw2cb +.section sw2da +.section sw2db +.section sw2ea +.section sw2eb +.section sw2fa +.section sw2fb +.section sw2ga +.section sw2gb +.section sw2ha +.section sw2hb +.section sw2ia +.section sw2ib +.section sw2ja +.section sw2jb +.section sw2ka +.section sw2kb +.section sw2la +.section sw2lb +.section sw2ma +.section sw2mb +.section sw2na +.section sw2nb +.section sw2oa +.section sw2ob +.section sw2pa +.section sw2pb +.section sw2qa +.section sw2qb +.section sw2ra +.section sw2rb +.section sw2sa +.section sw2sb +.section sw2ta +.section sw2tb +.section sw2ua +.section sw2ub +.section sw2va +.section sw2vb +.section sw2wa +.section sw2wb +.section sw2xa +.section sw2xb +.section sw2ya +.section sw2yb +.section sw2za +.section sw2zb +.section sw21a +.section sw21b +.section sw22a +.section sw22b +.section sw23a +.section sw23b +.section sw24a +.section sw24b +.section sw25a +.section sw25b +.section sw26a +.section sw26b +.section sw27a +.section sw27b +.section sw28a +.section sw28b +.section sw29a +.section sw29b +.section sw20a +.section sw20b +.section sw3aa +.section sw3ab +.section sw3ba +.section sw3bb +.section sw3ca +.section sw3cb +.section sw3da +.section sw3db +.section sw3ea +.section sw3eb +.section sw3fa +.section sw3fb +.section sw3ga +.section sw3gb +.section sw3ha +.section sw3hb +.section sw3ia +.section sw3ib +.section sw3ja +.section sw3jb +.section sw3ka +.section sw3kb +.section sw3la +.section sw3lb +.section sw3ma +.section sw3mb +.section sw3na +.section sw3nb +.section sw3oa +.section sw3ob +.section sw3pa +.section sw3pb +.section sw3qa +.section sw3qb +.section sw3ra +.section sw3rb +.section sw3sa +.section sw3sb +.section sw3ta +.section sw3tb +.section sw3ua +.section sw3ub +.section sw3va +.section sw3vb +.section sw3wa +.section sw3wb +.section sw3xa +.section sw3xb +.section sw3ya +.section sw3yb +.section sw3za +.section sw3zb +.section sw31a +.section sw31b +.section sw32a +.section sw32b +.section sw33a +.section sw33b +.section sw34a +.section sw34b +.section sw35a +.section sw35b +.section sw36a +.section sw36b +.section sw37a +.section sw37b +.section sw38a +.section sw38b +.section sw39a +.section sw39b +.section sw30a +.section sw30b +.section sw4aa +.section sw4ab +.section sw4ba +.section sw4bb +.section sw4ca +.section sw4cb +.section sw4da +.section sw4db +.section sw4ea +.section sw4eb +.section sw4fa +.section sw4fb +.section sw4ga +.section sw4gb +.section sw4ha +.section sw4hb +.section sw4ia +.section sw4ib +.section sw4ja +.section sw4jb +.section sw4ka +.section sw4kb +.section sw4la +.section sw4lb +.section sw4ma +.section sw4mb +.section sw4na +.section sw4nb +.section sw4oa +.section sw4ob +.section sw4pa +.section sw4pb +.section sw4qa +.section sw4qb +.section sw4ra +.section sw4rb +.section sw4sa +.section sw4sb +.section sw4ta +.section sw4tb +.section sw4ua +.section sw4ub +.section sw4va +.section sw4vb +.section sw4wa +.section sw4wb +.section sw4xa +.section sw4xb +.section sw4ya +.section sw4yb +.section sw4za +.section sw4zb +.section sw41a +.section sw41b +.section sw42a +.section sw42b +.section sw43a +.section sw43b +.section sw44a +.section sw44b +.section sw45a +.section sw45b +.section sw46a +.section sw46b +.section sw47a +.section sw47b +.section sw48a +.section sw48b +.section sw49a +.section sw49b +.section sw40a +.section sw40b +.section sw5aa +.section sw5ab +.section sw5ba +.section sw5bb +.section sw5ca +.section sw5cb +.section sw5da +.section sw5db +.section sw5ea +.section sw5eb +.section sw5fa +.section sw5fb +.section sw5ga +.section sw5gb +.section sw5ha +.section sw5hb +.section sw5ia +.section sw5ib +.section sw5ja +.section sw5jb +.section sw5ka +.section sw5kb +.section sw5la +.section sw5lb +.section sw5ma +.section sw5mb +.section sw5na +.section sw5nb +.section sw5oa +.section sw5ob +.section sw5pa +.section sw5pb +.section sw5qa +.section sw5qb +.section sw5ra +.section sw5rb +.section sw5sa +.section sw5sb +.section sw5ta +.section sw5tb +.section sw5ua +.section sw5ub +.section sw5va +.section sw5vb +.section sw5wa +.section sw5wb +.section sw5xa +.section sw5xb +.section sw5ya +.section sw5yb +.section sw5za +.section sw5zb +.section sw51a +.section sw51b +.section sw52a +.section sw52b +.section sw53a +.section sw53b +.section sw54a +.section sw54b +.section sw55a +.section sw55b +.section sw56a +.section sw56b +.section sw57a +.section sw57b +.section sw58a +.section sw58b +.section sw59a +.section sw59b +.section sw50a +.section sw50b +.section sw6aa +.section sw6ab +.section sw6ba +.section sw6bb +.section sw6ca +.section sw6cb +.section sw6da +.section sw6db +.section sw6ea +.section sw6eb +.section sw6fa +.section sw6fb +.section sw6ga +.section sw6gb +.section sw6ha +.section sw6hb +.section sw6ia +.section sw6ib +.section sw6ja +.section sw6jb +.section sw6ka +.section sw6kb +.section sw6la +.section sw6lb +.section sw6ma +.section sw6mb +.section sw6na +.section sw6nb +.section sw6oa +.section sw6ob +.section sw6pa +.section sw6pb +.section sw6qa +.section sw6qb +.section sw6ra +.section sw6rb +.section sw6sa +.section sw6sb +.section sw6ta +.section sw6tb +.section sw6ua +.section sw6ub +.section sw6va +.section sw6vb +.section sw6wa +.section sw6wb +.section sw6xa +.section sw6xb +.section sw6ya +.section sw6yb +.section sw6za +.section sw6zb +.section sw61a +.section sw61b +.section sw62a +.section sw62b +.section sw63a +.section sw63b +.section sw64a +.section sw64b +.section sw65a +.section sw65b +.section sw66a +.section sw66b +.section sw67a +.section sw67b +.section sw68a +.section sw68b +.section sw69a +.section sw69b +.section sw60a +.section sw60b +.section sw7aa +.section sw7ab +.section sw7ba +.section sw7bb +.section sw7ca +.section sw7cb +.section sw7da +.section sw7db +.section sw7ea +.section sw7eb +.section sw7fa +.section sw7fb +.section sw7ga +.section sw7gb +.section sw7ha +.section sw7hb +.section sw7ia +.section sw7ib +.section sw7ja +.section sw7jb +.section sw7ka +.section sw7kb +.section sw7la +.section sw7lb +.section sw7ma +.section sw7mb +.section sw7na +.section sw7nb +.section sw7oa +.section sw7ob +.section sw7pa +.section sw7pb +.section sw7qa +.section sw7qb +.section sw7ra +.section sw7rb +.section sw7sa +.section sw7sb +.section sw7ta +.section sw7tb +.section sw7ua +.section sw7ub +.section sw7va +.section sw7vb +.section sw7wa +.section sw7wb +.section sw7xa +.section sw7xb +.section sw7ya +.section sw7yb +.section sw7za +.section sw7zb +.section sw71a +.section sw71b +.section sw72a +.section sw72b +.section sw73a +.section sw73b +.section sw74a +.section sw74b +.section sw75a +.section sw75b +.section sw76a +.section sw76b +.section sw77a +.section sw77b +.section sw78a +.section sw78b +.section sw79a +.section sw79b +.section sw70a +.section sw70b +.section sw8aa +.section sw8ab +.section sw8ba +.section sw8bb +.section sw8ca +.section sw8cb +.section sw8da +.section sw8db +.section sw8ea +.section sw8eb +.section sw8fa +.section sw8fb +.section sw8ga +.section sw8gb +.section sw8ha +.section sw8hb +.section sw8ia +.section sw8ib +.section sw8ja +.section sw8jb +.section sw8ka +.section sw8kb +.section sw8la +.section sw8lb +.section sw8ma +.section sw8mb +.section sw8na +.section sw8nb +.section sw8oa +.section sw8ob +.section sw8pa +.section sw8pb +.section sw8qa +.section sw8qb +.section sw8ra +.section sw8rb +.section sw8sa +.section sw8sb +.section sw8ta +.section sw8tb +.section sw8ua +.section sw8ub +.section sw8va +.section sw8vb +.section sw8wa +.section sw8wb +.section sw8xa +.section sw8xb +.section sw8ya +.section sw8yb +.section sw8za +.section sw8zb +.section sw81a +.section sw81b +.section sw82a +.section sw82b +.section sw83a +.section sw83b +.section sw84a +.section sw84b +.section sw85a +.section sw85b +.section sw86a +.section sw86b +.section sw87a +.section sw87b +.section sw88a +.section sw88b +.section sw89a +.section sw89b +.section sw80a +.section sw80b +.section sw9aa +.section sw9ab +.section sw9ba +.section sw9bb +.section sw9ca +.section sw9cb +.section sw9da +.section sw9db +.section sw9ea +.section sw9eb +.section sw9fa +.section sw9fb +.section sw9ga +.section sw9gb +.section sw9ha +.section sw9hb +.section sw9ia +.section sw9ib +.section sw9ja +.section sw9jb +.section sw9ka +.section sw9kb +.section sw9la +.section sw9lb +.section sw9ma +.section sw9mb +.section sw9na +.section sw9nb +.section sw9oa +.section sw9ob +.section sw9pa +.section sw9pb +.section sw9qa +.section sw9qb +.section sw9ra +.section sw9rb +.section sw9sa +.section sw9sb +.section sw9ta +.section sw9tb +.section sw9ua +.section sw9ub +.section sw9va +.section sw9vb +.section sw9wa +.section sw9wb +.section sw9xa +.section sw9xb +.section sw9ya +.section sw9yb +.section sw9za +.section sw9zb +.section sw91a +.section sw91b +.section sw92a +.section sw92b +.section sw93a +.section sw93b +.section sw94a +.section sw94b +.section sw95a +.section sw95b +.section sw96a +.section sw96b +.section sw97a +.section sw97b +.section sw98a +.section sw98b +.section sw99a +.section sw99b +.section sw90a +.section sw90b +.section sw0aa +.section sw0ab +.section sw0ba +.section sw0bb +.section sw0ca +.section sw0cb +.section sw0da +.section sw0db +.section sw0ea +.section sw0eb +.section sw0fa +.section sw0fb +.section sw0ga +.section sw0gb +.section sw0ha +.section sw0hb +.section sw0ia +.section sw0ib +.section sw0ja +.section sw0jb +.section sw0ka +.section sw0kb +.section sw0la +.section sw0lb +.section sw0ma +.section sw0mb +.section sw0na +.section sw0nb +.section sw0oa +.section sw0ob +.section sw0pa +.section sw0pb +.section sw0qa +.section sw0qb +.section sw0ra +.section sw0rb +.section sw0sa +.section sw0sb +.section sw0ta +.section sw0tb +.section sw0ua +.section sw0ub +.section sw0va +.section sw0vb +.section sw0wa +.section sw0wb +.section sw0xa +.section sw0xb +.section sw0ya +.section sw0yb +.section sw0za +.section sw0zb +.section sw01a +.section sw01b +.section sw02a +.section sw02b +.section sw03a +.section sw03b +.section sw04a +.section sw04b +.section sw05a +.section sw05b +.section sw06a +.section sw06b +.section sw07a +.section sw07b +.section sw08a +.section sw08b +.section sw09a +.section sw09b +.section sw00a +.section sw00b +.section sxaaa +.section sxaab +.section sxaba +.section sxabb +.section sxaca +.section sxacb +.section sxada +.section sxadb +.section sxaea +.section sxaeb +.section sxafa +.section sxafb +.section sxaga +.section sxagb +.section sxaha +.section sxahb +.section sxaia +.section sxaib +.section sxaja +.section sxajb +.section sxaka +.section sxakb +.section sxala +.section sxalb +.section sxama +.section sxamb +.section sxana +.section sxanb +.section sxaoa +.section sxaob +.section sxapa +.section sxapb +.section sxaqa +.section sxaqb +.section sxara +.section sxarb +.section sxasa +.section sxasb +.section sxata +.section sxatb +.section sxaua +.section sxaub +.section sxava +.section sxavb +.section sxawa +.section sxawb +.section sxaxa +.section sxaxb +.section sxaya +.section sxayb +.section sxaza +.section sxazb +.section sxa1a +.section sxa1b +.section sxa2a +.section sxa2b +.section sxa3a +.section sxa3b +.section sxa4a +.section sxa4b +.section sxa5a +.section sxa5b +.section sxa6a +.section sxa6b +.section sxa7a +.section sxa7b +.section sxa8a +.section sxa8b +.section sxa9a +.section sxa9b +.section sxa0a +.section sxa0b +.section sxbaa +.section sxbab +.section sxbba +.section sxbbb +.section sxbca +.section sxbcb +.section sxbda +.section sxbdb +.section sxbea +.section sxbeb +.section sxbfa +.section sxbfb +.section sxbga +.section sxbgb +.section sxbha +.section sxbhb +.section sxbia +.section sxbib +.section sxbja +.section sxbjb +.section sxbka +.section sxbkb +.section sxbla +.section sxblb +.section sxbma +.section sxbmb +.section sxbna +.section sxbnb +.section sxboa +.section sxbob +.section sxbpa +.section sxbpb +.section sxbqa +.section sxbqb +.section sxbra +.section sxbrb +.section sxbsa +.section sxbsb +.section sxbta +.section sxbtb +.section sxbua +.section sxbub +.section sxbva +.section sxbvb +.section sxbwa +.section sxbwb +.section sxbxa +.section sxbxb +.section sxbya +.section sxbyb +.section sxbza +.section sxbzb +.section sxb1a +.section sxb1b +.section sxb2a +.section sxb2b +.section sxb3a +.section sxb3b +.section sxb4a +.section sxb4b +.section sxb5a +.section sxb5b +.section sxb6a +.section sxb6b +.section sxb7a +.section sxb7b +.section sxb8a +.section sxb8b +.section sxb9a +.section sxb9b +.section sxb0a +.section sxb0b +.section sxcaa +.section sxcab +.section sxcba +.section sxcbb +.section sxcca +.section sxccb +.section sxcda +.section sxcdb +.section sxcea +.section sxceb +.section sxcfa +.section sxcfb +.section sxcga +.section sxcgb +.section sxcha +.section sxchb +.section sxcia +.section sxcib +.section sxcja +.section sxcjb +.section sxcka +.section sxckb +.section sxcla +.section sxclb +.section sxcma +.section sxcmb +.section sxcna +.section sxcnb +.section sxcoa +.section sxcob +.section sxcpa +.section sxcpb +.section sxcqa +.section sxcqb +.section sxcra +.section sxcrb +.section sxcsa +.section sxcsb +.section sxcta +.section sxctb +.section sxcua +.section sxcub +.section sxcva +.section sxcvb +.section sxcwa +.section sxcwb +.section sxcxa +.section sxcxb +.section sxcya +.section sxcyb +.section sxcza +.section sxczb +.section sxc1a +.section sxc1b +.section sxc2a +.section sxc2b +.section sxc3a +.section sxc3b +.section sxc4a +.section sxc4b +.section sxc5a +.section sxc5b +.section sxc6a +.section sxc6b +.section sxc7a +.section sxc7b +.section sxc8a +.section sxc8b +.section sxc9a +.section sxc9b +.section sxc0a +.section sxc0b +.section sxdaa +.section sxdab +.section sxdba +.section sxdbb +.section sxdca +.section sxdcb +.section sxdda +.section sxddb +.section sxdea +.section sxdeb +.section sxdfa +.section sxdfb +.section sxdga +.section sxdgb +.section sxdha +.section sxdhb +.section sxdia +.section sxdib +.section sxdja +.section sxdjb +.section sxdka +.section sxdkb +.section sxdla +.section sxdlb +.section sxdma +.section sxdmb +.section sxdna +.section sxdnb +.section sxdoa +.section sxdob +.section sxdpa +.section sxdpb +.section sxdqa +.section sxdqb +.section sxdra +.section sxdrb +.section sxdsa +.section sxdsb +.section sxdta +.section sxdtb +.section sxdua +.section sxdub +.section sxdva +.section sxdvb +.section sxdwa +.section sxdwb +.section sxdxa +.section sxdxb +.section sxdya +.section sxdyb +.section sxdza +.section sxdzb +.section sxd1a +.section sxd1b +.section sxd2a +.section sxd2b +.section sxd3a +.section sxd3b +.section sxd4a +.section sxd4b +.section sxd5a +.section sxd5b +.section sxd6a +.section sxd6b +.section sxd7a +.section sxd7b +.section sxd8a +.section sxd8b +.section sxd9a +.section sxd9b +.section sxd0a +.section sxd0b +.section sxeaa +.section sxeab +.section sxeba +.section sxebb +.section sxeca +.section sxecb +.section sxeda +.section sxedb +.section sxeea +.section sxeeb +.section sxefa +.section sxefb +.section sxega +.section sxegb +.section sxeha +.section sxehb +.section sxeia +.section sxeib +.section sxeja +.section sxejb +.section sxeka +.section sxekb +.section sxela +.section sxelb +.section sxema +.section sxemb +.section sxena +.section sxenb +.section sxeoa +.section sxeob +.section sxepa +.section sxepb +.section sxeqa +.section sxeqb +.section sxera +.section sxerb +.section sxesa +.section sxesb +.section sxeta +.section sxetb +.section sxeua +.section sxeub +.section sxeva +.section sxevb +.section sxewa +.section sxewb +.section sxexa +.section sxexb +.section sxeya +.section sxeyb +.section sxeza +.section sxezb +.section sxe1a +.section sxe1b +.section sxe2a +.section sxe2b +.section sxe3a +.section sxe3b +.section sxe4a +.section sxe4b +.section sxe5a +.section sxe5b +.section sxe6a +.section sxe6b +.section sxe7a +.section sxe7b +.section sxe8a +.section sxe8b +.section sxe9a +.section sxe9b +.section sxe0a +.section sxe0b +.section sxfaa +.section sxfab +.section sxfba +.section sxfbb +.section sxfca +.section sxfcb +.section sxfda +.section sxfdb +.section sxfea +.section sxfeb +.section sxffa +.section sxffb +.section sxfga +.section sxfgb +.section sxfha +.section sxfhb +.section sxfia +.section sxfib +.section sxfja +.section sxfjb +.section sxfka +.section sxfkb +.section sxfla +.section sxflb +.section sxfma +.section sxfmb +.section sxfna +.section sxfnb +.section sxfoa +.section sxfob +.section sxfpa +.section sxfpb +.section sxfqa +.section sxfqb +.section sxfra +.section sxfrb +.section sxfsa +.section sxfsb +.section sxfta +.section sxftb +.section sxfua +.section sxfub +.section sxfva +.section sxfvb +.section sxfwa +.section sxfwb +.section sxfxa +.section sxfxb +.section sxfya +.section sxfyb +.section sxfza +.section sxfzb +.section sxf1a +.section sxf1b +.section sxf2a +.section sxf2b +.section sxf3a +.section sxf3b +.section sxf4a +.section sxf4b +.section sxf5a +.section sxf5b +.section sxf6a +.section sxf6b +.section sxf7a +.section sxf7b +.section sxf8a +.section sxf8b +.section sxf9a +.section sxf9b +.section sxf0a +.section sxf0b +.section sxgaa +.section sxgab +.section sxgba +.section sxgbb +.section sxgca +.section sxgcb +.section sxgda +.section sxgdb +.section sxgea +.section sxgeb +.section sxgfa +.section sxgfb +.section sxgga +.section sxggb +.section sxgha +.section sxghb +.section sxgia +.section sxgib +.section sxgja +.section sxgjb +.section sxgka +.section sxgkb +.section sxgla +.section sxglb +.section sxgma +.section sxgmb +.section sxgna +.section sxgnb +.section sxgoa +.section sxgob +.section sxgpa +.section sxgpb +.section sxgqa +.section sxgqb +.section sxgra +.section sxgrb +.section sxgsa +.section sxgsb +.section sxgta +.section sxgtb +.section sxgua +.section sxgub +.section sxgva +.section sxgvb +.section sxgwa +.section sxgwb +.section sxgxa +.section sxgxb +.section sxgya +.section sxgyb +.section sxgza +.section sxgzb +.section sxg1a +.section sxg1b +.section sxg2a +.section sxg2b +.section sxg3a +.section sxg3b +.section sxg4a +.section sxg4b +.section sxg5a +.section sxg5b +.section sxg6a +.section sxg6b +.section sxg7a +.section sxg7b +.section sxg8a +.section sxg8b +.section sxg9a +.section sxg9b +.section sxg0a +.section sxg0b +.section sxhaa +.section sxhab +.section sxhba +.section sxhbb +.section sxhca +.section sxhcb +.section sxhda +.section sxhdb +.section sxhea +.section sxheb +.section sxhfa +.section sxhfb +.section sxhga +.section sxhgb +.section sxhha +.section sxhhb +.section sxhia +.section sxhib +.section sxhja +.section sxhjb +.section sxhka +.section sxhkb +.section sxhla +.section sxhlb +.section sxhma +.section sxhmb +.section sxhna +.section sxhnb +.section sxhoa +.section sxhob +.section sxhpa +.section sxhpb +.section sxhqa +.section sxhqb +.section sxhra +.section sxhrb +.section sxhsa +.section sxhsb +.section sxhta +.section sxhtb +.section sxhua +.section sxhub +.section sxhva +.section sxhvb +.section sxhwa +.section sxhwb +.section sxhxa +.section sxhxb +.section sxhya +.section sxhyb +.section sxhza +.section sxhzb +.section sxh1a +.section sxh1b +.section sxh2a +.section sxh2b +.section sxh3a +.section sxh3b +.section sxh4a +.section sxh4b +.section sxh5a +.section sxh5b +.section sxh6a +.section sxh6b +.section sxh7a +.section sxh7b +.section sxh8a +.section sxh8b +.section sxh9a +.section sxh9b +.section sxh0a +.section sxh0b +.section sxiaa +.section sxiab +.section sxiba +.section sxibb +.section sxica +.section sxicb +.section sxida +.section sxidb +.section sxiea +.section sxieb +.section sxifa +.section sxifb +.section sxiga +.section sxigb +.section sxiha +.section sxihb +.section sxiia +.section sxiib +.section sxija +.section sxijb +.section sxika +.section sxikb +.section sxila +.section sxilb +.section sxima +.section sximb +.section sxina +.section sxinb +.section sxioa +.section sxiob +.section sxipa +.section sxipb +.section sxiqa +.section sxiqb +.section sxira +.section sxirb +.section sxisa +.section sxisb +.section sxita +.section sxitb +.section sxiua +.section sxiub +.section sxiva +.section sxivb +.section sxiwa +.section sxiwb +.section sxixa +.section sxixb +.section sxiya +.section sxiyb +.section sxiza +.section sxizb +.section sxi1a +.section sxi1b +.section sxi2a +.section sxi2b +.section sxi3a +.section sxi3b +.section sxi4a +.section sxi4b +.section sxi5a +.section sxi5b +.section sxi6a +.section sxi6b +.section sxi7a +.section sxi7b +.section sxi8a +.section sxi8b +.section sxi9a +.section sxi9b +.section sxi0a +.section sxi0b +.section sxjaa +.section sxjab +.section sxjba +.section sxjbb +.section sxjca +.section sxjcb +.section sxjda +.section sxjdb +.section sxjea +.section sxjeb +.section sxjfa +.section sxjfb +.section sxjga +.section sxjgb +.section sxjha +.section sxjhb +.section sxjia +.section sxjib +.section sxjja +.section sxjjb +.section sxjka +.section sxjkb +.section sxjla +.section sxjlb +.section sxjma +.section sxjmb +.section sxjna +.section sxjnb +.section sxjoa +.section sxjob +.section sxjpa +.section sxjpb +.section sxjqa +.section sxjqb +.section sxjra +.section sxjrb +.section sxjsa +.section sxjsb +.section sxjta +.section sxjtb +.section sxjua +.section sxjub +.section sxjva +.section sxjvb +.section sxjwa +.section sxjwb +.section sxjxa +.section sxjxb +.section sxjya +.section sxjyb +.section sxjza +.section sxjzb +.section sxj1a +.section sxj1b +.section sxj2a +.section sxj2b +.section sxj3a +.section sxj3b +.section sxj4a +.section sxj4b +.section sxj5a +.section sxj5b +.section sxj6a +.section sxj6b +.section sxj7a +.section sxj7b +.section sxj8a +.section sxj8b +.section sxj9a +.section sxj9b +.section sxj0a +.section sxj0b +.section sxkaa +.section sxkab +.section sxkba +.section sxkbb +.section sxkca +.section sxkcb +.section sxkda +.section sxkdb +.section sxkea +.section sxkeb +.section sxkfa +.section sxkfb +.section sxkga +.section sxkgb +.section sxkha +.section sxkhb +.section sxkia +.section sxkib +.section sxkja +.section sxkjb +.section sxkka +.section sxkkb +.section sxkla +.section sxklb +.section sxkma +.section sxkmb +.section sxkna +.section sxknb +.section sxkoa +.section sxkob +.section sxkpa +.section sxkpb +.section sxkqa +.section sxkqb +.section sxkra +.section sxkrb +.section sxksa +.section sxksb +.section sxkta +.section sxktb +.section sxkua +.section sxkub +.section sxkva +.section sxkvb +.section sxkwa +.section sxkwb +.section sxkxa +.section sxkxb +.section sxkya +.section sxkyb +.section sxkza +.section sxkzb +.section sxk1a +.section sxk1b +.section sxk2a +.section sxk2b +.section sxk3a +.section sxk3b +.section sxk4a +.section sxk4b +.section sxk5a +.section sxk5b +.section sxk6a +.section sxk6b +.section sxk7a +.section sxk7b +.section sxk8a +.section sxk8b +.section sxk9a +.section sxk9b +.section sxk0a +.section sxk0b +.section sxlaa +.section sxlab +.section sxlba +.section sxlbb +.section sxlca +.section sxlcb +.section sxlda +.section sxldb +.section sxlea +.section sxleb +.section sxlfa +.section sxlfb +.section sxlga +.section sxlgb +.section sxlha +.section sxlhb +.section sxlia +.section sxlib +.section sxlja +.section sxljb +.section sxlka +.section sxlkb +.section sxlla +.section sxllb +.section sxlma +.section sxlmb +.section sxlna +.section sxlnb +.section sxloa +.section sxlob +.section sxlpa +.section sxlpb +.section sxlqa +.section sxlqb +.section sxlra +.section sxlrb +.section sxlsa +.section sxlsb +.section sxlta +.section sxltb +.section sxlua +.section sxlub +.section sxlva +.section sxlvb +.section sxlwa +.section sxlwb +.section sxlxa +.section sxlxb +.section sxlya +.section sxlyb +.section sxlza +.section sxlzb +.section sxl1a +.section sxl1b +.section sxl2a +.section sxl2b +.section sxl3a +.section sxl3b +.section sxl4a +.section sxl4b +.section sxl5a +.section sxl5b +.section sxl6a +.section sxl6b +.section sxl7a +.section sxl7b +.section sxl8a +.section sxl8b +.section sxl9a +.section sxl9b +.section sxl0a +.section sxl0b +.section sxmaa +.section sxmab +.section sxmba +.section sxmbb +.section sxmca +.section sxmcb +.section sxmda +.section sxmdb +.section sxmea +.section sxmeb +.section sxmfa +.section sxmfb +.section sxmga +.section sxmgb +.section sxmha +.section sxmhb +.section sxmia +.section sxmib +.section sxmja +.section sxmjb +.section sxmka +.section sxmkb +.section sxmla +.section sxmlb +.section sxmma +.section sxmmb +.section sxmna +.section sxmnb +.section sxmoa +.section sxmob +.section sxmpa +.section sxmpb +.section sxmqa +.section sxmqb +.section sxmra +.section sxmrb +.section sxmsa +.section sxmsb +.section sxmta +.section sxmtb +.section sxmua +.section sxmub +.section sxmva +.section sxmvb +.section sxmwa +.section sxmwb +.section sxmxa +.section sxmxb +.section sxmya +.section sxmyb +.section sxmza +.section sxmzb +.section sxm1a +.section sxm1b +.section sxm2a +.section sxm2b +.section sxm3a +.section sxm3b +.section sxm4a +.section sxm4b +.section sxm5a +.section sxm5b +.section sxm6a +.section sxm6b +.section sxm7a +.section sxm7b +.section sxm8a +.section sxm8b +.section sxm9a +.section sxm9b +.section sxm0a +.section sxm0b +.section sxnaa +.section sxnab +.section sxnba +.section sxnbb +.section sxnca +.section sxncb +.section sxnda +.section sxndb +.section sxnea +.section sxneb +.section sxnfa +.section sxnfb +.section sxnga +.section sxngb +.section sxnha +.section sxnhb +.section sxnia +.section sxnib +.section sxnja +.section sxnjb +.section sxnka +.section sxnkb +.section sxnla +.section sxnlb +.section sxnma +.section sxnmb +.section sxnna +.section sxnnb +.section sxnoa +.section sxnob +.section sxnpa +.section sxnpb +.section sxnqa +.section sxnqb +.section sxnra +.section sxnrb +.section sxnsa +.section sxnsb +.section sxnta +.section sxntb +.section sxnua +.section sxnub +.section sxnva +.section sxnvb +.section sxnwa +.section sxnwb +.section sxnxa +.section sxnxb +.section sxnya +.section sxnyb +.section sxnza +.section sxnzb +.section sxn1a +.section sxn1b +.section sxn2a +.section sxn2b +.section sxn3a +.section sxn3b +.section sxn4a +.section sxn4b +.section sxn5a +.section sxn5b +.section sxn6a +.section sxn6b +.section sxn7a +.section sxn7b +.section sxn8a +.section sxn8b +.section sxn9a +.section sxn9b +.section sxn0a +.section sxn0b +.section sxoaa +.section sxoab +.section sxoba +.section sxobb +.section sxoca +.section sxocb +.section sxoda +.section sxodb +.section sxoea +.section sxoeb +.section sxofa +.section sxofb +.section sxoga +.section sxogb +.section sxoha +.section sxohb +.section sxoia +.section sxoib +.section sxoja +.section sxojb +.section sxoka +.section sxokb +.section sxola +.section sxolb +.section sxoma +.section sxomb +.section sxona +.section sxonb +.section sxooa +.section sxoob +.section sxopa +.section sxopb +.section sxoqa +.section sxoqb +.section sxora +.section sxorb +.section sxosa +.section sxosb +.section sxota +.section sxotb +.section sxoua +.section sxoub +.section sxova +.section sxovb +.section sxowa +.section sxowb +.section sxoxa +.section sxoxb +.section sxoya +.section sxoyb +.section sxoza +.section sxozb +.section sxo1a +.section sxo1b +.section sxo2a +.section sxo2b +.section sxo3a +.section sxo3b +.section sxo4a +.section sxo4b +.section sxo5a +.section sxo5b +.section sxo6a +.section sxo6b +.section sxo7a +.section sxo7b +.section sxo8a +.section sxo8b +.section sxo9a +.section sxo9b +.section sxo0a +.section sxo0b +.section sxpaa +.section sxpab +.section sxpba +.section sxpbb +.section sxpca +.section sxpcb +.section sxpda +.section sxpdb +.section sxpea +.section sxpeb +.section sxpfa +.section sxpfb +.section sxpga +.section sxpgb +.section sxpha +.section sxphb +.section sxpia +.section sxpib +.section sxpja +.section sxpjb +.section sxpka +.section sxpkb +.section sxpla +.section sxplb +.section sxpma +.section sxpmb +.section sxpna +.section sxpnb +.section sxpoa +.section sxpob +.section sxppa +.section sxppb +.section sxpqa +.section sxpqb +.section sxpra +.section sxprb +.section sxpsa +.section sxpsb +.section sxpta +.section sxptb +.section sxpua +.section sxpub +.section sxpva +.section sxpvb +.section sxpwa +.section sxpwb +.section sxpxa +.section sxpxb +.section sxpya +.section sxpyb +.section sxpza +.section sxpzb +.section sxp1a +.section sxp1b +.section sxp2a +.section sxp2b +.section sxp3a +.section sxp3b +.section sxp4a +.section sxp4b +.section sxp5a +.section sxp5b +.section sxp6a +.section sxp6b +.section sxp7a +.section sxp7b +.section sxp8a +.section sxp8b +.section sxp9a +.section sxp9b +.section sxp0a +.section sxp0b +.section sxqaa +.section sxqab +.section sxqba +.section sxqbb +.section sxqca +.section sxqcb +.section sxqda +.section sxqdb +.section sxqea +.section sxqeb +.section sxqfa +.section sxqfb +.section sxqga +.section sxqgb +.section sxqha +.section sxqhb +.section sxqia +.section sxqib +.section sxqja +.section sxqjb +.section sxqka +.section sxqkb +.section sxqla +.section sxqlb +.section sxqma +.section sxqmb +.section sxqna +.section sxqnb +.section sxqoa +.section sxqob +.section sxqpa +.section sxqpb +.section sxqqa +.section sxqqb +.section sxqra +.section sxqrb +.section sxqsa +.section sxqsb +.section sxqta +.section sxqtb +.section sxqua +.section sxqub +.section sxqva +.section sxqvb +.section sxqwa +.section sxqwb +.section sxqxa +.section sxqxb +.section sxqya +.section sxqyb +.section sxqza +.section sxqzb +.section sxq1a +.section sxq1b +.section sxq2a +.section sxq2b +.section sxq3a +.section sxq3b +.section sxq4a +.section sxq4b +.section sxq5a +.section sxq5b +.section sxq6a +.section sxq6b +.section sxq7a +.section sxq7b +.section sxq8a +.section sxq8b +.section sxq9a +.section sxq9b +.section sxq0a +.section sxq0b +.section sxraa +.section sxrab +.section sxrba +.section sxrbb +.section sxrca +.section sxrcb +.section sxrda +.section sxrdb +.section sxrea +.section sxreb +.section sxrfa +.section sxrfb +.section sxrga +.section sxrgb +.section sxrha +.section sxrhb +.section sxria +.section sxrib +.section sxrja +.section sxrjb +.section sxrka +.section sxrkb +.section sxrla +.section sxrlb +.section sxrma +.section sxrmb +.section sxrna +.section sxrnb +.section sxroa +.section sxrob +.section sxrpa +.section sxrpb +.section sxrqa +.section sxrqb +.section sxrra +.section sxrrb +.section sxrsa +.section sxrsb +.section sxrta +.section sxrtb +.section sxrua +.section sxrub +.section sxrva +.section sxrvb +.section sxrwa +.section sxrwb +.section sxrxa +.section sxrxb +.section sxrya +.section sxryb +.section sxrza +.section sxrzb +.section sxr1a +.section sxr1b +.section sxr2a +.section sxr2b +.section sxr3a +.section sxr3b +.section sxr4a +.section sxr4b +.section sxr5a +.section sxr5b +.section sxr6a +.section sxr6b +.section sxr7a +.section sxr7b +.section sxr8a +.section sxr8b +.section sxr9a +.section sxr9b +.section sxr0a +.section sxr0b +.section sxsaa +.section sxsab +.section sxsba +.section sxsbb +.section sxsca +.section sxscb +.section sxsda +.section sxsdb +.section sxsea +.section sxseb +.section sxsfa +.section sxsfb +.section sxsga +.section sxsgb +.section sxsha +.section sxshb +.section sxsia +.section sxsib +.section sxsja +.section sxsjb +.section sxska +.section sxskb +.section sxsla +.section sxslb +.section sxsma +.section sxsmb +.section sxsna +.section sxsnb +.section sxsoa +.section sxsob +.section sxspa +.section sxspb +.section sxsqa +.section sxsqb +.section sxsra +.section sxsrb +.section sxssa +.section sxssb +.section sxsta +.section sxstb +.section sxsua +.section sxsub +.section sxsva +.section sxsvb +.section sxswa +.section sxswb +.section sxsxa +.section sxsxb +.section sxsya +.section sxsyb +.section sxsza +.section sxszb +.section sxs1a +.section sxs1b +.section sxs2a +.section sxs2b +.section sxs3a +.section sxs3b +.section sxs4a +.section sxs4b +.section sxs5a +.section sxs5b +.section sxs6a +.section sxs6b +.section sxs7a +.section sxs7b +.section sxs8a +.section sxs8b +.section sxs9a +.section sxs9b +.section sxs0a +.section sxs0b +.section sxtaa +.section sxtab +.section sxtba +.section sxtbb +.section sxtca +.section sxtcb +.section sxtda +.section sxtdb +.section sxtea +.section sxteb +.section sxtfa +.section sxtfb +.section sxtga +.section sxtgb +.section sxtha +.section sxthb +.section sxtia +.section sxtib +.section sxtja +.section sxtjb +.section sxtka +.section sxtkb +.section sxtla +.section sxtlb +.section sxtma +.section sxtmb +.section sxtna +.section sxtnb +.section sxtoa +.section sxtob +.section sxtpa +.section sxtpb +.section sxtqa +.section sxtqb +.section sxtra +.section sxtrb +.section sxtsa +.section sxtsb +.section sxtta +.section sxttb +.section sxtua +.section sxtub +.section sxtva +.section sxtvb +.section sxtwa +.section sxtwb +.section sxtxa +.section sxtxb +.section sxtya +.section sxtyb +.section sxtza +.section sxtzb +.section sxt1a +.section sxt1b +.section sxt2a +.section sxt2b +.section sxt3a +.section sxt3b +.section sxt4a +.section sxt4b +.section sxt5a +.section sxt5b +.section sxt6a +.section sxt6b +.section sxt7a +.section sxt7b +.section sxt8a +.section sxt8b +.section sxt9a +.section sxt9b +.section sxt0a +.section sxt0b +.section sxuaa +.section sxuab +.section sxuba +.section sxubb +.section sxuca +.section sxucb +.section sxuda +.section sxudb +.section sxuea +.section sxueb +.section sxufa +.section sxufb +.section sxuga +.section sxugb +.section sxuha +.section sxuhb +.section sxuia +.section sxuib +.section sxuja +.section sxujb +.section sxuka +.section sxukb +.section sxula +.section sxulb +.section sxuma +.section sxumb +.section sxuna +.section sxunb +.section sxuoa +.section sxuob +.section sxupa +.section sxupb +.section sxuqa +.section sxuqb +.section sxura +.section sxurb +.section sxusa +.section sxusb +.section sxuta +.section sxutb +.section sxuua +.section sxuub +.section sxuva +.section sxuvb +.section sxuwa +.section sxuwb +.section sxuxa +.section sxuxb +.section sxuya +.section sxuyb +.section sxuza +.section sxuzb +.section sxu1a +.section sxu1b +.section sxu2a +.section sxu2b +.section sxu3a +.section sxu3b +.section sxu4a +.section sxu4b +.section sxu5a +.section sxu5b +.section sxu6a +.section sxu6b +.section sxu7a +.section sxu7b +.section sxu8a +.section sxu8b +.section sxu9a +.section sxu9b +.section sxu0a +.section sxu0b +.section sxvaa +.section sxvab +.section sxvba +.section sxvbb +.section sxvca +.section sxvcb +.section sxvda +.section sxvdb +.section sxvea +.section sxveb +.section sxvfa +.section sxvfb +.section sxvga +.section sxvgb +.section sxvha +.section sxvhb +.section sxvia +.section sxvib +.section sxvja +.section sxvjb +.section sxvka +.section sxvkb +.section sxvla +.section sxvlb +.section sxvma +.section sxvmb +.section sxvna +.section sxvnb +.section sxvoa +.section sxvob +.section sxvpa +.section sxvpb +.section sxvqa +.section sxvqb +.section sxvra +.section sxvrb +.section sxvsa +.section sxvsb +.section sxvta +.section sxvtb +.section sxvua +.section sxvub +.section sxvva +.section sxvvb +.section sxvwa +.section sxvwb +.section sxvxa +.section sxvxb +.section sxvya +.section sxvyb +.section sxvza +.section sxvzb +.section sxv1a +.section sxv1b +.section sxv2a +.section sxv2b +.section sxv3a +.section sxv3b +.section sxv4a +.section sxv4b +.section sxv5a +.section sxv5b +.section sxv6a +.section sxv6b +.section sxv7a +.section sxv7b +.section sxv8a +.section sxv8b +.section sxv9a +.section sxv9b +.section sxv0a +.section sxv0b +.section sxwaa +.section sxwab +.section sxwba +.section sxwbb +.section sxwca +.section sxwcb +.section sxwda +.section sxwdb +.section sxwea +.section sxweb +.section sxwfa +.section sxwfb +.section sxwga +.section sxwgb +.section sxwha +.section sxwhb +.section sxwia +.section sxwib +.section sxwja +.section sxwjb +.section sxwka +.section sxwkb +.section sxwla +.section sxwlb +.section sxwma +.section sxwmb +.section sxwna +.section sxwnb +.section sxwoa +.section sxwob +.section sxwpa +.section sxwpb +.section sxwqa +.section sxwqb +.section sxwra +.section sxwrb +.section sxwsa +.section sxwsb +.section sxwta +.section sxwtb +.section sxwua +.section sxwub +.section sxwva +.section sxwvb +.section sxwwa +.section sxwwb +.section sxwxa +.section sxwxb +.section sxwya +.section sxwyb +.section sxwza +.section sxwzb +.section sxw1a +.section sxw1b +.section sxw2a +.section sxw2b +.section sxw3a +.section sxw3b +.section sxw4a +.section sxw4b +.section sxw5a +.section sxw5b +.section sxw6a +.section sxw6b +.section sxw7a +.section sxw7b +.section sxw8a +.section sxw8b +.section sxw9a +.section sxw9b +.section sxw0a +.section sxw0b +.section sxxaa +.section sxxab +.section sxxba +.section sxxbb +.section sxxca +.section sxxcb +.section sxxda +.section sxxdb +.section sxxea +.section sxxeb +.section sxxfa +.section sxxfb +.section sxxga +.section sxxgb +.section sxxha +.section sxxhb +.section sxxia +.section sxxib +.section sxxja +.section sxxjb +.section sxxka +.section sxxkb +.section sxxla +.section sxxlb +.section sxxma +.section sxxmb +.section sxxna +.section sxxnb +.section sxxoa +.section sxxob +.section sxxpa +.section sxxpb +.section sxxqa +.section sxxqb +.section sxxra +.section sxxrb +.section sxxsa +.section sxxsb +.section sxxta +.section sxxtb +.section sxxua +.section sxxub +.section sxxva +.section sxxvb +.section sxxwa +.section sxxwb +.section sxxxa +.section sxxxb +.section sxxya +.section sxxyb +.section sxxza +.section sxxzb +.section sxx1a +.section sxx1b +.section sxx2a +.section sxx2b +.section sxx3a +.section sxx3b +.section sxx4a +.section sxx4b +.section sxx5a +.section sxx5b +.section sxx6a +.section sxx6b +.section sxx7a +.section sxx7b +.section sxx8a +.section sxx8b +.section sxx9a +.section sxx9b +.section sxx0a +.section sxx0b +.section sxyaa +.section sxyab +.section sxyba +.section sxybb +.section sxyca +.section sxycb +.section sxyda +.section sxydb +.section sxyea +.section sxyeb +.section sxyfa +.section sxyfb +.section sxyga +.section sxygb +.section sxyha +.section sxyhb +.section sxyia +.section sxyib +.section sxyja +.section sxyjb +.section sxyka +.section sxykb +.section sxyla +.section sxylb +.section sxyma +.section sxymb +.section sxyna +.section sxynb +.section sxyoa +.section sxyob +.section sxypa +.section sxypb +.section sxyqa +.section sxyqb +.section sxyra +.section sxyrb +.section sxysa +.section sxysb +.section sxyta +.section sxytb +.section sxyua +.section sxyub +.section sxyva +.section sxyvb +.section sxywa +.section sxywb +.section sxyxa +.section sxyxb +.section sxyya +.section sxyyb +.section sxyza +.section sxyzb +.section sxy1a +.section sxy1b +.section sxy2a +.section sxy2b +.section sxy3a +.section sxy3b +.section sxy4a +.section sxy4b +.section sxy5a +.section sxy5b +.section sxy6a +.section sxy6b +.section sxy7a +.section sxy7b +.section sxy8a +.section sxy8b +.section sxy9a +.section sxy9b +.section sxy0a +.section sxy0b +.section sxzaa +.section sxzab +.section sxzba +.section sxzbb +.section sxzca +.section sxzcb +.section sxzda +.section sxzdb +.section sxzea +.section sxzeb +.section sxzfa +.section sxzfb +.section sxzga +.section sxzgb +.section sxzha +.section sxzhb +.section sxzia +.section sxzib +.section sxzja +.section sxzjb +.section sxzka +.section sxzkb +.section sxzla +.section sxzlb +.section sxzma +.section sxzmb +.section sxzna +.section sxznb +.section sxzoa +.section sxzob +.section sxzpa +.section sxzpb +.section sxzqa +.section sxzqb +.section sxzra +.section sxzrb +.section sxzsa +.section sxzsb +.section sxzta +.section sxztb +.section sxzua +.section sxzub +.section sxzva +.section sxzvb +.section sxzwa +.section sxzwb +.section sxzxa +.section sxzxb +.section sxzya +.section sxzyb +.section sxzza +.section sxzzb +.section sxz1a +.section sxz1b +.section sxz2a +.section sxz2b +.section sxz3a +.section sxz3b +.section sxz4a +.section sxz4b +.section sxz5a +.section sxz5b +.section sxz6a +.section sxz6b +.section sxz7a +.section sxz7b +.section sxz8a +.section sxz8b +.section sxz9a +.section sxz9b +.section sxz0a +.section sxz0b +.section sx1aa +.section sx1ab +.section sx1ba +.section sx1bb +.section sx1ca +.section sx1cb +.section sx1da +.section sx1db +.section sx1ea +.section sx1eb +.section sx1fa +.section sx1fb +.section sx1ga +.section sx1gb +.section sx1ha +.section sx1hb +.section sx1ia +.section sx1ib +.section sx1ja +.section sx1jb +.section sx1ka +.section sx1kb +.section sx1la +.section sx1lb +.section sx1ma +.section sx1mb +.section sx1na +.section sx1nb +.section sx1oa +.section sx1ob +.section sx1pa +.section sx1pb +.section sx1qa +.section sx1qb +.section sx1ra +.section sx1rb +.section sx1sa +.section sx1sb +.section sx1ta +.section sx1tb +.section sx1ua +.section sx1ub +.section sx1va +.section sx1vb +.section sx1wa +.section sx1wb +.section sx1xa +.section sx1xb +.section sx1ya +.section sx1yb +.section sx1za +.section sx1zb +.section sx11a +.section sx11b +.section sx12a +.section sx12b +.section sx13a +.section sx13b +.section sx14a +.section sx14b +.section sx15a +.section sx15b +.section sx16a +.section sx16b +.section sx17a +.section sx17b +.section sx18a +.section sx18b +.section sx19a +.section sx19b +.section sx10a +.section sx10b +.section sx2aa +.section sx2ab +.section sx2ba +.section sx2bb +.section sx2ca +.section sx2cb +.section sx2da +.section sx2db +.section sx2ea +.section sx2eb +.section sx2fa +.section sx2fb +.section sx2ga +.section sx2gb +.section sx2ha +.section sx2hb +.section sx2ia +.section sx2ib +.section sx2ja +.section sx2jb +.section sx2ka +.section sx2kb +.section sx2la +.section sx2lb +.section sx2ma +.section sx2mb +.section sx2na +.section sx2nb +.section sx2oa +.section sx2ob +.section sx2pa +.section sx2pb +.section sx2qa +.section sx2qb +.section sx2ra +.section sx2rb +.section sx2sa +.section sx2sb +.section sx2ta +.section sx2tb +.section sx2ua +.section sx2ub +.section sx2va +.section sx2vb +.section sx2wa +.section sx2wb +.section sx2xa +.section sx2xb +.section sx2ya +.section sx2yb +.section sx2za +.section sx2zb +.section sx21a +.section sx21b +.section sx22a +.section sx22b +.section sx23a +.section sx23b +.section sx24a +.section sx24b +.section sx25a +.section sx25b +.section sx26a +.section sx26b +.section sx27a +.section sx27b +.section sx28a +.section sx28b +.section sx29a +.section sx29b +.section sx20a +.section sx20b +.section sx3aa +.section sx3ab +.section sx3ba +.section sx3bb +.section sx3ca +.section sx3cb +.section sx3da +.section sx3db +.section sx3ea +.section sx3eb +.section sx3fa +.section sx3fb +.section sx3ga +.section sx3gb +.section sx3ha +.section sx3hb +.section sx3ia +.section sx3ib +.section sx3ja +.section sx3jb +.section sx3ka +.section sx3kb +.section sx3la +.section sx3lb +.section sx3ma +.section sx3mb +.section sx3na +.section sx3nb +.section sx3oa +.section sx3ob +.section sx3pa +.section sx3pb +.section sx3qa +.section sx3qb +.section sx3ra +.section sx3rb +.section sx3sa +.section sx3sb +.section sx3ta +.section sx3tb +.section sx3ua +.section sx3ub +.section sx3va +.section sx3vb +.section sx3wa +.section sx3wb +.section sx3xa +.section sx3xb +.section sx3ya +.section sx3yb +.section sx3za +.section sx3zb +.section sx31a +.section sx31b +.section sx32a +.section sx32b +.section sx33a +.section sx33b +.section sx34a +.section sx34b +.section sx35a +.section sx35b +.section sx36a +.section sx36b +.section sx37a +.section sx37b +.section sx38a +.section sx38b +.section sx39a +.section sx39b +.section sx30a +.section sx30b +.section sx4aa +.section sx4ab +.section sx4ba +.section sx4bb +.section sx4ca +.section sx4cb +.section sx4da +.section sx4db +.section sx4ea +.section sx4eb +.section sx4fa +.section sx4fb +.section sx4ga +.section sx4gb +.section sx4ha +.section sx4hb +.section sx4ia +.section sx4ib +.section sx4ja +.section sx4jb +.section sx4ka +.section sx4kb +.section sx4la +.section sx4lb +.section sx4ma +.section sx4mb +.section sx4na +.section sx4nb +.section sx4oa +.section sx4ob +.section sx4pa +.section sx4pb +.section sx4qa +.section sx4qb +.section sx4ra +.section sx4rb +.section sx4sa +.section sx4sb +.section sx4ta +.section sx4tb +.section sx4ua +.section sx4ub +.section sx4va +.section sx4vb +.section sx4wa +.section sx4wb +.section sx4xa +.section sx4xb +.section sx4ya +.section sx4yb +.section sx4za +.section sx4zb +.section sx41a +.section sx41b +.section sx42a +.section sx42b +.section sx43a +.section sx43b +.section sx44a +.section sx44b +.section sx45a +.section sx45b +.section sx46a +.section sx46b +.section sx47a +.section sx47b +.section sx48a +.section sx48b +.section sx49a +.section sx49b +.section sx40a +.section sx40b +.section sx5aa +.section sx5ab +.section sx5ba +.section sx5bb +.section sx5ca +.section sx5cb +.section sx5da +.section sx5db +.section sx5ea +.section sx5eb +.section sx5fa +.section sx5fb +.section sx5ga +.section sx5gb +.section sx5ha +.section sx5hb +.section sx5ia +.section sx5ib +.section sx5ja +.section sx5jb +.section sx5ka +.section sx5kb +.section sx5la +.section sx5lb +.section sx5ma +.section sx5mb +.section sx5na +.section sx5nb +.section sx5oa +.section sx5ob +.section sx5pa +.section sx5pb +.section sx5qa +.section sx5qb +.section sx5ra +.section sx5rb +.section sx5sa +.section sx5sb +.section sx5ta +.section sx5tb +.section sx5ua +.section sx5ub +.section sx5va +.section sx5vb +.section sx5wa +.section sx5wb +.section sx5xa +.section sx5xb +.section sx5ya +.section sx5yb +.section sx5za +.section sx5zb +.section sx51a +.section sx51b +.section sx52a +.section sx52b +.section sx53a +.section sx53b +.section sx54a +.section sx54b +.section sx55a +.section sx55b +.section sx56a +.section sx56b +.section sx57a +.section sx57b +.section sx58a +.section sx58b +.section sx59a +.section sx59b +.section sx50a +.section sx50b +.section sx6aa +.section sx6ab +.section sx6ba +.section sx6bb +.section sx6ca +.section sx6cb +.section sx6da +.section sx6db +.section sx6ea +.section sx6eb +.section sx6fa +.section sx6fb +.section sx6ga +.section sx6gb +.section sx6ha +.section sx6hb +.section sx6ia +.section sx6ib +.section sx6ja +.section sx6jb +.section sx6ka +.section sx6kb +.section sx6la +.section sx6lb +.section sx6ma +.section sx6mb +.section sx6na +.section sx6nb +.section sx6oa +.section sx6ob +.section sx6pa +.section sx6pb +.section sx6qa +.section sx6qb +.section sx6ra +.section sx6rb +.section sx6sa +.section sx6sb +.section sx6ta +.section sx6tb +.section sx6ua +.section sx6ub +.section sx6va +.section sx6vb +.section sx6wa +.section sx6wb +.section sx6xa +.section sx6xb +.section sx6ya +.section sx6yb +.section sx6za +.section sx6zb +.section sx61a +.section sx61b +.section sx62a +.section sx62b +.section sx63a +.section sx63b +.section sx64a +.section sx64b +.section sx65a +.section sx65b +.section sx66a +.section sx66b +.section sx67a +.section sx67b +.section sx68a +.section sx68b +.section sx69a +.section sx69b +.section sx60a +.section sx60b +.section sx7aa +.section sx7ab +.section sx7ba +.section sx7bb +.section sx7ca +.section sx7cb +.section sx7da +.section sx7db +.section sx7ea +.section sx7eb +.section sx7fa +.section sx7fb +.section sx7ga +.section sx7gb +.section sx7ha +.section sx7hb +.section sx7ia +.section sx7ib +.section sx7ja +.section sx7jb +.section sx7ka +.section sx7kb +.section sx7la +.section sx7lb +.section sx7ma +.section sx7mb +.section sx7na +.section sx7nb +.section sx7oa +.section sx7ob +.section sx7pa +.section sx7pb +.section sx7qa +.section sx7qb +.section sx7ra +.section sx7rb +.section sx7sa +.section sx7sb +.section sx7ta +.section sx7tb +.section sx7ua +.section sx7ub +.section sx7va +.section sx7vb +.section sx7wa +.section sx7wb +.section sx7xa +.section sx7xb +.section sx7ya +.section sx7yb +.section sx7za +.section sx7zb +.section sx71a +.section sx71b +.section sx72a +.section sx72b +.section sx73a +.section sx73b +.section sx74a +.section sx74b +.section sx75a +.section sx75b +.section sx76a +.section sx76b +.section sx77a +.section sx77b +.section sx78a +.section sx78b +.section sx79a +.section sx79b +.section sx70a +.section sx70b +.section sx8aa +.section sx8ab +.section sx8ba +.section sx8bb +.section sx8ca +.section sx8cb +.section sx8da +.section sx8db +.section sx8ea +.section sx8eb +.section sx8fa +.section sx8fb +.section sx8ga +.section sx8gb +.section sx8ha +.section sx8hb +.section sx8ia +.section sx8ib +.section sx8ja +.section sx8jb +.section sx8ka +.section sx8kb +.section sx8la +.section sx8lb +.section sx8ma +.section sx8mb +.section sx8na +.section sx8nb +.section sx8oa +.section sx8ob +.section sx8pa +.section sx8pb +.section sx8qa +.section sx8qb +.section sx8ra +.section sx8rb +.section sx8sa +.section sx8sb +.section sx8ta +.section sx8tb +.section sx8ua +.section sx8ub +.section sx8va +.section sx8vb +.section sx8wa +.section sx8wb +.section sx8xa +.section sx8xb +.section sx8ya +.section sx8yb +.section sx8za +.section sx8zb +.section sx81a +.section sx81b +.section sx82a +.section sx82b +.section sx83a +.section sx83b +.section sx84a +.section sx84b +.section sx85a +.section sx85b +.section sx86a +.section sx86b +.section sx87a +.section sx87b +.section sx88a +.section sx88b +.section sx89a +.section sx89b +.section sx80a +.section sx80b +.section sx9aa +.section sx9ab +.section sx9ba +.section sx9bb +.section sx9ca +.section sx9cb +.section sx9da +.section sx9db +.section sx9ea +.section sx9eb +.section sx9fa +.section sx9fb +.section sx9ga +.section sx9gb +.section sx9ha +.section sx9hb +.section sx9ia +.section sx9ib +.section sx9ja +.section sx9jb +.section sx9ka +.section sx9kb +.section sx9la +.section sx9lb +.section sx9ma +.section sx9mb +.section sx9na +.section sx9nb +.section sx9oa +.section sx9ob +.section sx9pa +.section sx9pb +.section sx9qa +.section sx9qb +.section sx9ra +.section sx9rb +.section sx9sa +.section sx9sb +.section sx9ta +.section sx9tb +.section sx9ua +.section sx9ub +.section sx9va +.section sx9vb +.section sx9wa +.section sx9wb +.section sx9xa +.section sx9xb +.section sx9ya +.section sx9yb +.section sx9za +.section sx9zb +.section sx91a +.section sx91b +.section sx92a +.section sx92b +.section sx93a +.section sx93b +.section sx94a +.section sx94b +.section sx95a +.section sx95b +.section sx96a +.section sx96b +.section sx97a +.section sx97b +.section sx98a +.section sx98b +.section sx99a +.section sx99b +.section sx90a +.section sx90b +.section sx0aa +.section sx0ab +.section sx0ba +.section sx0bb +.section sx0ca +.section sx0cb +.section sx0da +.section sx0db +.section sx0ea +.section sx0eb +.section sx0fa +.section sx0fb +.section sx0ga +.section sx0gb +.section sx0ha +.section sx0hb +.section sx0ia +.section sx0ib +.section sx0ja +.section sx0jb +.section sx0ka +.section sx0kb +.section sx0la +.section sx0lb +.section sx0ma +.section sx0mb +.section sx0na +.section sx0nb +.section sx0oa +.section sx0ob +.section sx0pa +.section sx0pb +.section sx0qa +.section sx0qb +.section sx0ra +.section sx0rb +.section sx0sa +.section sx0sb +.section sx0ta +.section sx0tb +.section sx0ua +.section sx0ub +.section sx0va +.section sx0vb +.section sx0wa +.section sx0wb +.section sx0xa +.section sx0xb +.section sx0ya +.section sx0yb +.section sx0za +.section sx0zb +.section sx01a +.section sx01b +.section sx02a +.section sx02b +.section sx03a +.section sx03b +.section sx04a +.section sx04b +.section sx05a +.section sx05b +.section sx06a +.section sx06b +.section sx07a +.section sx07b +.section sx08a +.section sx08b +.section sx09a +.section sx09b +.section sx00a +.section sx00b +.section syaaa +.section syaab +.section syaba +.section syabb +.section syaca +.section syacb +.section syada +.section syadb +.section syaea +.section syaeb +.section syafa +.section syafb +.section syaga +.section syagb +.section syaha +.section syahb +.section syaia +.section syaib +.section syaja +.section syajb +.section syaka +.section syakb +.section syala +.section syalb +.section syama +.section syamb +.section syana +.section syanb +.section syaoa +.section syaob +.section syapa +.section syapb +.section syaqa +.section syaqb +.section syara +.section syarb +.section syasa +.section syasb +.section syata +.section syatb +.section syaua +.section syaub +.section syava +.section syavb +.section syawa +.section syawb +.section syaxa +.section syaxb +.section syaya +.section syayb +.section syaza +.section syazb +.section sya1a +.section sya1b +.section sya2a +.section sya2b +.section sya3a +.section sya3b +.section sya4a +.section sya4b +.section sya5a +.section sya5b +.section sya6a +.section sya6b +.section sya7a +.section sya7b +.section sya8a +.section sya8b +.section sya9a +.section sya9b +.section sya0a +.section sya0b +.section sybaa +.section sybab +.section sybba +.section sybbb +.section sybca +.section sybcb +.section sybda +.section sybdb +.section sybea +.section sybeb +.section sybfa +.section sybfb +.section sybga +.section sybgb +.section sybha +.section sybhb +.section sybia +.section sybib +.section sybja +.section sybjb +.section sybka +.section sybkb +.section sybla +.section syblb +.section sybma +.section sybmb +.section sybna +.section sybnb +.section syboa +.section sybob +.section sybpa +.section sybpb +.section sybqa +.section sybqb +.section sybra +.section sybrb +.section sybsa +.section sybsb +.section sybta +.section sybtb +.section sybua +.section sybub +.section sybva +.section sybvb +.section sybwa +.section sybwb +.section sybxa +.section sybxb +.section sybya +.section sybyb +.section sybza +.section sybzb +.section syb1a +.section syb1b +.section syb2a +.section syb2b +.section syb3a +.section syb3b +.section syb4a +.section syb4b +.section syb5a +.section syb5b +.section syb6a +.section syb6b +.section syb7a +.section syb7b +.section syb8a +.section syb8b +.section syb9a +.section syb9b +.section syb0a +.section syb0b +.section sycaa +.section sycab +.section sycba +.section sycbb +.section sycca +.section syccb +.section sycda +.section sycdb +.section sycea +.section syceb +.section sycfa +.section sycfb +.section sycga +.section sycgb +.section sycha +.section sychb +.section sycia +.section sycib +.section sycja +.section sycjb +.section sycka +.section syckb +.section sycla +.section syclb +.section sycma +.section sycmb +.section sycna +.section sycnb +.section sycoa +.section sycob +.section sycpa +.section sycpb +.section sycqa +.section sycqb +.section sycra +.section sycrb +.section sycsa +.section sycsb +.section sycta +.section syctb +.section sycua +.section sycub +.section sycva +.section sycvb +.section sycwa +.section sycwb +.section sycxa +.section sycxb +.section sycya +.section sycyb +.section sycza +.section syczb +.section syc1a +.section syc1b +.section syc2a +.section syc2b +.section syc3a +.section syc3b +.section syc4a +.section syc4b +.section syc5a +.section syc5b +.section syc6a +.section syc6b +.section syc7a +.section syc7b +.section syc8a +.section syc8b +.section syc9a +.section syc9b +.section syc0a +.section syc0b +.section sydaa +.section sydab +.section sydba +.section sydbb +.section sydca +.section sydcb +.section sydda +.section syddb +.section sydea +.section sydeb +.section sydfa +.section sydfb +.section sydga +.section sydgb +.section sydha +.section sydhb +.section sydia +.section sydib +.section sydja +.section sydjb +.section sydka +.section sydkb +.section sydla +.section sydlb +.section sydma +.section sydmb +.section sydna +.section sydnb +.section sydoa +.section sydob +.section sydpa +.section sydpb +.section sydqa +.section sydqb +.section sydra +.section sydrb +.section sydsa +.section sydsb +.section sydta +.section sydtb +.section sydua +.section sydub +.section sydva +.section sydvb +.section sydwa +.section sydwb +.section sydxa +.section sydxb +.section sydya +.section sydyb +.section sydza +.section sydzb +.section syd1a +.section syd1b +.section syd2a +.section syd2b +.section syd3a +.section syd3b +.section syd4a +.section syd4b +.section syd5a +.section syd5b +.section syd6a +.section syd6b +.section syd7a +.section syd7b +.section syd8a +.section syd8b +.section syd9a +.section syd9b +.section syd0a +.section syd0b +.section syeaa +.section syeab +.section syeba +.section syebb +.section syeca +.section syecb +.section syeda +.section syedb +.section syeea +.section syeeb +.section syefa +.section syefb +.section syega +.section syegb +.section syeha +.section syehb +.section syeia +.section syeib +.section syeja +.section syejb +.section syeka +.section syekb +.section syela +.section syelb +.section syema +.section syemb +.section syena +.section syenb +.section syeoa +.section syeob +.section syepa +.section syepb +.section syeqa +.section syeqb +.section syera +.section syerb +.section syesa +.section syesb +.section syeta +.section syetb +.section syeua +.section syeub +.section syeva +.section syevb +.section syewa +.section syewb +.section syexa +.section syexb +.section syeya +.section syeyb +.section syeza +.section syezb +.section sye1a +.section sye1b +.section sye2a +.section sye2b +.section sye3a +.section sye3b +.section sye4a +.section sye4b +.section sye5a +.section sye5b +.section sye6a +.section sye6b +.section sye7a +.section sye7b +.section sye8a +.section sye8b +.section sye9a +.section sye9b +.section sye0a +.section sye0b +.section syfaa +.section syfab +.section syfba +.section syfbb +.section syfca +.section syfcb +.section syfda +.section syfdb +.section syfea +.section syfeb +.section syffa +.section syffb +.section syfga +.section syfgb +.section syfha +.section syfhb +.section syfia +.section syfib +.section syfja +.section syfjb +.section syfka +.section syfkb +.section syfla +.section syflb +.section syfma +.section syfmb +.section syfna +.section syfnb +.section syfoa +.section syfob +.section syfpa +.section syfpb +.section syfqa +.section syfqb +.section syfra +.section syfrb +.section syfsa +.section syfsb +.section syfta +.section syftb +.section syfua +.section syfub +.section syfva +.section syfvb +.section syfwa +.section syfwb +.section syfxa +.section syfxb +.section syfya +.section syfyb +.section syfza +.section syfzb +.section syf1a +.section syf1b +.section syf2a +.section syf2b +.section syf3a +.section syf3b +.section syf4a +.section syf4b +.section syf5a +.section syf5b +.section syf6a +.section syf6b +.section syf7a +.section syf7b +.section syf8a +.section syf8b +.section syf9a +.section syf9b +.section syf0a +.section syf0b +.section sygaa +.section sygab +.section sygba +.section sygbb +.section sygca +.section sygcb +.section sygda +.section sygdb +.section sygea +.section sygeb +.section sygfa +.section sygfb +.section sygga +.section syggb +.section sygha +.section syghb +.section sygia +.section sygib +.section sygja +.section sygjb +.section sygka +.section sygkb +.section sygla +.section syglb +.section sygma +.section sygmb +.section sygna +.section sygnb +.section sygoa +.section sygob +.section sygpa +.section sygpb +.section sygqa +.section sygqb +.section sygra +.section sygrb +.section sygsa +.section sygsb +.section sygta +.section sygtb +.section sygua +.section sygub +.section sygva +.section sygvb +.section sygwa +.section sygwb +.section sygxa +.section sygxb +.section sygya +.section sygyb +.section sygza +.section sygzb +.section syg1a +.section syg1b +.section syg2a +.section syg2b +.section syg3a +.section syg3b +.section syg4a +.section syg4b +.section syg5a +.section syg5b +.section syg6a +.section syg6b +.section syg7a +.section syg7b +.section syg8a +.section syg8b +.section syg9a +.section syg9b +.section syg0a +.section syg0b +.section syhaa +.section syhab +.section syhba +.section syhbb +.section syhca +.section syhcb +.section syhda +.section syhdb +.section syhea +.section syheb +.section syhfa +.section syhfb +.section syhga +.section syhgb +.section syhha +.section syhhb +.section syhia +.section syhib +.section syhja +.section syhjb +.section syhka +.section syhkb +.section syhla +.section syhlb +.section syhma +.section syhmb +.section syhna +.section syhnb +.section syhoa +.section syhob +.section syhpa +.section syhpb +.section syhqa +.section syhqb +.section syhra +.section syhrb +.section syhsa +.section syhsb +.section syhta +.section syhtb +.section syhua +.section syhub +.section syhva +.section syhvb +.section syhwa +.section syhwb +.section syhxa +.section syhxb +.section syhya +.section syhyb +.section syhza +.section syhzb +.section syh1a +.section syh1b +.section syh2a +.section syh2b +.section syh3a +.section syh3b +.section syh4a +.section syh4b +.section syh5a +.section syh5b +.section syh6a +.section syh6b +.section syh7a +.section syh7b +.section syh8a +.section syh8b +.section syh9a +.section syh9b +.section syh0a +.section syh0b +.section syiaa +.section syiab +.section syiba +.section syibb +.section syica +.section syicb +.section syida +.section syidb +.section syiea +.section syieb +.section syifa +.section syifb +.section syiga +.section syigb +.section syiha +.section syihb +.section syiia +.section syiib +.section syija +.section syijb +.section syika +.section syikb +.section syila +.section syilb +.section syima +.section syimb +.section syina +.section syinb +.section syioa +.section syiob +.section syipa +.section syipb +.section syiqa +.section syiqb +.section syira +.section syirb +.section syisa +.section syisb +.section syita +.section syitb +.section syiua +.section syiub +.section syiva +.section syivb +.section syiwa +.section syiwb +.section syixa +.section syixb +.section syiya +.section syiyb +.section syiza +.section syizb +.section syi1a +.section syi1b +.section syi2a +.section syi2b +.section syi3a +.section syi3b +.section syi4a +.section syi4b +.section syi5a +.section syi5b +.section syi6a +.section syi6b +.section syi7a +.section syi7b +.section syi8a +.section syi8b +.section syi9a +.section syi9b +.section syi0a +.section syi0b +.section syjaa +.section syjab +.section syjba +.section syjbb +.section syjca +.section syjcb +.section syjda +.section syjdb +.section syjea +.section syjeb +.section syjfa +.section syjfb +.section syjga +.section syjgb +.section syjha +.section syjhb +.section syjia +.section syjib +.section syjja +.section syjjb +.section syjka +.section syjkb +.section syjla +.section syjlb +.section syjma +.section syjmb +.section syjna +.section syjnb +.section syjoa +.section syjob +.section syjpa +.section syjpb +.section syjqa +.section syjqb +.section syjra +.section syjrb +.section syjsa +.section syjsb +.section syjta +.section syjtb +.section syjua +.section syjub +.section syjva +.section syjvb +.section syjwa +.section syjwb +.section syjxa +.section syjxb +.section syjya +.section syjyb +.section syjza +.section syjzb +.section syj1a +.section syj1b +.section syj2a +.section syj2b +.section syj3a +.section syj3b +.section syj4a +.section syj4b +.section syj5a +.section syj5b +.section syj6a +.section syj6b +.section syj7a +.section syj7b +.section syj8a +.section syj8b +.section syj9a +.section syj9b +.section syj0a +.section syj0b +.section sykaa +.section sykab +.section sykba +.section sykbb +.section sykca +.section sykcb +.section sykda +.section sykdb +.section sykea +.section sykeb +.section sykfa +.section sykfb +.section sykga +.section sykgb +.section sykha +.section sykhb +.section sykia +.section sykib +.section sykja +.section sykjb +.section sykka +.section sykkb +.section sykla +.section syklb +.section sykma +.section sykmb +.section sykna +.section syknb +.section sykoa +.section sykob +.section sykpa +.section sykpb +.section sykqa +.section sykqb +.section sykra +.section sykrb +.section syksa +.section syksb +.section sykta +.section syktb +.section sykua +.section sykub +.section sykva +.section sykvb +.section sykwa +.section sykwb +.section sykxa +.section sykxb +.section sykya +.section sykyb +.section sykza +.section sykzb +.section syk1a +.section syk1b +.section syk2a +.section syk2b +.section syk3a +.section syk3b +.section syk4a +.section syk4b +.section syk5a +.section syk5b +.section syk6a +.section syk6b +.section syk7a +.section syk7b +.section syk8a +.section syk8b +.section syk9a +.section syk9b +.section syk0a +.section syk0b +.section sylaa +.section sylab +.section sylba +.section sylbb +.section sylca +.section sylcb +.section sylda +.section syldb +.section sylea +.section syleb +.section sylfa +.section sylfb +.section sylga +.section sylgb +.section sylha +.section sylhb +.section sylia +.section sylib +.section sylja +.section syljb +.section sylka +.section sylkb +.section sylla +.section syllb +.section sylma +.section sylmb +.section sylna +.section sylnb +.section syloa +.section sylob +.section sylpa +.section sylpb +.section sylqa +.section sylqb +.section sylra +.section sylrb +.section sylsa +.section sylsb +.section sylta +.section syltb +.section sylua +.section sylub +.section sylva +.section sylvb +.section sylwa +.section sylwb +.section sylxa +.section sylxb +.section sylya +.section sylyb +.section sylza +.section sylzb +.section syl1a +.section syl1b +.section syl2a +.section syl2b +.section syl3a +.section syl3b +.section syl4a +.section syl4b +.section syl5a +.section syl5b +.section syl6a +.section syl6b +.section syl7a +.section syl7b +.section syl8a +.section syl8b +.section syl9a +.section syl9b +.section syl0a +.section syl0b +.section symaa +.section symab +.section symba +.section symbb +.section symca +.section symcb +.section symda +.section symdb +.section symea +.section symeb +.section symfa +.section symfb +.section symga +.section symgb +.section symha +.section symhb +.section symia +.section symib +.section symja +.section symjb +.section symka +.section symkb +.section symla +.section symlb +.section symma +.section symmb +.section symna +.section symnb +.section symoa +.section symob +.section sympa +.section sympb +.section symqa +.section symqb +.section symra +.section symrb +.section symsa +.section symsb +.section symta +.section symtb +.section symua +.section symub +.section symva +.section symvb +.section symwa +.section symwb +.section symxa +.section symxb +.section symya +.section symyb +.section symza +.section symzb +.section sym1a +.section sym1b +.section sym2a +.section sym2b +.section sym3a +.section sym3b +.section sym4a +.section sym4b +.section sym5a +.section sym5b +.section sym6a +.section sym6b +.section sym7a +.section sym7b +.section sym8a +.section sym8b +.section sym9a +.section sym9b +.section sym0a +.section sym0b +.section synaa +.section synab +.section synba +.section synbb +.section synca +.section syncb +.section synda +.section syndb +.section synea +.section syneb +.section synfa +.section synfb +.section synga +.section syngb +.section synha +.section synhb +.section synia +.section synib +.section synja +.section synjb +.section synka +.section synkb +.section synla +.section synlb +.section synma +.section synmb +.section synna +.section synnb +.section synoa +.section synob +.section synpa +.section synpb +.section synqa +.section synqb +.section synra +.section synrb +.section synsa +.section synsb +.section synta +.section syntb +.section synua +.section synub +.section synva +.section synvb +.section synwa +.section synwb +.section synxa +.section synxb +.section synya +.section synyb +.section synza +.section synzb +.section syn1a +.section syn1b +.section syn2a +.section syn2b +.section syn3a +.section syn3b +.section syn4a +.section syn4b +.section syn5a +.section syn5b +.section syn6a +.section syn6b +.section syn7a +.section syn7b +.section syn8a +.section syn8b +.section syn9a +.section syn9b +.section syn0a +.section syn0b +.section syoaa +.section syoab +.section syoba +.section syobb +.section syoca +.section syocb +.section syoda +.section syodb +.section syoea +.section syoeb +.section syofa +.section syofb +.section syoga +.section syogb +.section syoha +.section syohb +.section syoia +.section syoib +.section syoja +.section syojb +.section syoka +.section syokb +.section syola +.section syolb +.section syoma +.section syomb +.section syona +.section syonb +.section syooa +.section syoob +.section syopa +.section syopb +.section syoqa +.section syoqb +.section syora +.section syorb +.section syosa +.section syosb +.section syota +.section syotb +.section syoua +.section syoub +.section syova +.section syovb +.section syowa +.section syowb +.section syoxa +.section syoxb +.section syoya +.section syoyb +.section syoza +.section syozb +.section syo1a +.section syo1b +.section syo2a +.section syo2b +.section syo3a +.section syo3b +.section syo4a +.section syo4b +.section syo5a +.section syo5b +.section syo6a +.section syo6b +.section syo7a +.section syo7b +.section syo8a +.section syo8b +.section syo9a +.section syo9b +.section syo0a +.section syo0b +.section sypaa +.section sypab +.section sypba +.section sypbb +.section sypca +.section sypcb +.section sypda +.section sypdb +.section sypea +.section sypeb +.section sypfa +.section sypfb +.section sypga +.section sypgb +.section sypha +.section syphb +.section sypia +.section sypib +.section sypja +.section sypjb +.section sypka +.section sypkb +.section sypla +.section syplb +.section sypma +.section sypmb +.section sypna +.section sypnb +.section sypoa +.section sypob +.section syppa +.section syppb +.section sypqa +.section sypqb +.section sypra +.section syprb +.section sypsa +.section sypsb +.section sypta +.section syptb +.section sypua +.section sypub +.section sypva +.section sypvb +.section sypwa +.section sypwb +.section sypxa +.section sypxb +.section sypya +.section sypyb +.section sypza +.section sypzb +.section syp1a +.section syp1b +.section syp2a +.section syp2b +.section syp3a +.section syp3b +.section syp4a +.section syp4b +.section syp5a +.section syp5b +.section syp6a +.section syp6b +.section syp7a +.section syp7b +.section syp8a +.section syp8b +.section syp9a +.section syp9b +.section syp0a +.section syp0b +.section syqaa +.section syqab +.section syqba +.section syqbb +.section syqca +.section syqcb +.section syqda +.section syqdb +.section syqea +.section syqeb +.section syqfa +.section syqfb +.section syqga +.section syqgb +.section syqha +.section syqhb +.section syqia +.section syqib +.section syqja +.section syqjb +.section syqka +.section syqkb +.section syqla +.section syqlb +.section syqma +.section syqmb +.section syqna +.section syqnb +.section syqoa +.section syqob +.section syqpa +.section syqpb +.section syqqa +.section syqqb +.section syqra +.section syqrb +.section syqsa +.section syqsb +.section syqta +.section syqtb +.section syqua +.section syqub +.section syqva +.section syqvb +.section syqwa +.section syqwb +.section syqxa +.section syqxb +.section syqya +.section syqyb +.section syqza +.section syqzb +.section syq1a +.section syq1b +.section syq2a +.section syq2b +.section syq3a +.section syq3b +.section syq4a +.section syq4b +.section syq5a +.section syq5b +.section syq6a +.section syq6b +.section syq7a +.section syq7b +.section syq8a +.section syq8b +.section syq9a +.section syq9b +.section syq0a +.section syq0b +.section syraa +.section syrab +.section syrba +.section syrbb +.section syrca +.section syrcb +.section syrda +.section syrdb +.section syrea +.section syreb +.section syrfa +.section syrfb +.section syrga +.section syrgb +.section syrha +.section syrhb +.section syria +.section syrib +.section syrja +.section syrjb +.section syrka +.section syrkb +.section syrla +.section syrlb +.section syrma +.section syrmb +.section syrna +.section syrnb +.section syroa +.section syrob +.section syrpa +.section syrpb +.section syrqa +.section syrqb +.section syrra +.section syrrb +.section syrsa +.section syrsb +.section syrta +.section syrtb +.section syrua +.section syrub +.section syrva +.section syrvb +.section syrwa +.section syrwb +.section syrxa +.section syrxb +.section syrya +.section syryb +.section syrza +.section syrzb +.section syr1a +.section syr1b +.section syr2a +.section syr2b +.section syr3a +.section syr3b +.section syr4a +.section syr4b +.section syr5a +.section syr5b +.section syr6a +.section syr6b +.section syr7a +.section syr7b +.section syr8a +.section syr8b +.section syr9a +.section syr9b +.section syr0a +.section syr0b +.section sysaa +.section sysab +.section sysba +.section sysbb +.section sysca +.section syscb +.section sysda +.section sysdb +.section sysea +.section syseb +.section sysfa +.section sysfb +.section sysga +.section sysgb +.section sysha +.section syshb +.section sysia +.section sysib +.section sysja +.section sysjb +.section syska +.section syskb +.section sysla +.section syslb +.section sysma +.section sysmb +.section sysna +.section sysnb +.section sysoa +.section sysob +.section syspa +.section syspb +.section sysqa +.section sysqb +.section sysra +.section sysrb +.section syssa +.section syssb +.section systa +.section systb +.section sysua +.section sysub +.section sysva +.section sysvb +.section syswa +.section syswb +.section sysxa +.section sysxb +.section sysya +.section sysyb +.section sysza +.section syszb +.section sys1a +.section sys1b +.section sys2a +.section sys2b +.section sys3a +.section sys3b +.section sys4a +.section sys4b +.section sys5a +.section sys5b +.section sys6a +.section sys6b +.section sys7a +.section sys7b +.section sys8a +.section sys8b +.section sys9a +.section sys9b +.section sys0a +.section sys0b +.section sytaa +.section sytab +.section sytba +.section sytbb +.section sytca +.section sytcb +.section sytda +.section sytdb +.section sytea +.section syteb +.section sytfa +.section sytfb +.section sytga +.section sytgb +.section sytha +.section sythb +.section sytia +.section sytib +.section sytja +.section sytjb +.section sytka +.section sytkb +.section sytla +.section sytlb +.section sytma +.section sytmb +.section sytna +.section sytnb +.section sytoa +.section sytob +.section sytpa +.section sytpb +.section sytqa +.section sytqb +.section sytra +.section sytrb +.section sytsa +.section sytsb +.section sytta +.section syttb +.section sytua +.section sytub +.section sytva +.section sytvb +.section sytwa +.section sytwb +.section sytxa +.section sytxb +.section sytya +.section sytyb +.section sytza +.section sytzb +.section syt1a +.section syt1b +.section syt2a +.section syt2b +.section syt3a +.section syt3b +.section syt4a +.section syt4b +.section syt5a +.section syt5b +.section syt6a +.section syt6b +.section syt7a +.section syt7b +.section syt8a +.section syt8b +.section syt9a +.section syt9b +.section syt0a +.section syt0b +.section syuaa +.section syuab +.section syuba +.section syubb +.section syuca +.section syucb +.section syuda +.section syudb +.section syuea +.section syueb +.section syufa +.section syufb +.section syuga +.section syugb +.section syuha +.section syuhb +.section syuia +.section syuib +.section syuja +.section syujb +.section syuka +.section syukb +.section syula +.section syulb +.section syuma +.section syumb +.section syuna +.section syunb +.section syuoa +.section syuob +.section syupa +.section syupb +.section syuqa +.section syuqb +.section syura +.section syurb +.section syusa +.section syusb +.section syuta +.section syutb +.section syuua +.section syuub +.section syuva +.section syuvb +.section syuwa +.section syuwb +.section syuxa +.section syuxb +.section syuya +.section syuyb +.section syuza +.section syuzb +.section syu1a +.section syu1b +.section syu2a +.section syu2b +.section syu3a +.section syu3b +.section syu4a +.section syu4b +.section syu5a +.section syu5b +.section syu6a +.section syu6b +.section syu7a +.section syu7b +.section syu8a +.section syu8b +.section syu9a +.section syu9b +.section syu0a +.section syu0b +.section syvaa +.section syvab +.section syvba +.section syvbb +.section syvca +.section syvcb +.section syvda +.section syvdb +.section syvea +.section syveb +.section syvfa +.section syvfb +.section syvga +.section syvgb +.section syvha +.section syvhb +.section syvia +.section syvib +.section syvja +.section syvjb +.section syvka +.section syvkb +.section syvla +.section syvlb +.section syvma +.section syvmb +.section syvna +.section syvnb +.section syvoa +.section syvob +.section syvpa +.section syvpb +.section syvqa +.section syvqb +.section syvra +.section syvrb +.section syvsa +.section syvsb +.section syvta +.section syvtb +.section syvua +.section syvub +.section syvva +.section syvvb +.section syvwa +.section syvwb +.section syvxa +.section syvxb +.section syvya +.section syvyb +.section syvza +.section syvzb +.section syv1a +.section syv1b +.section syv2a +.section syv2b +.section syv3a +.section syv3b +.section syv4a +.section syv4b +.section syv5a +.section syv5b +.section syv6a +.section syv6b +.section syv7a +.section syv7b +.section syv8a +.section syv8b +.section syv9a +.section syv9b +.section syv0a +.section syv0b +.section sywaa +.section sywab +.section sywba +.section sywbb +.section sywca +.section sywcb +.section sywda +.section sywdb +.section sywea +.section syweb +.section sywfa +.section sywfb +.section sywga +.section sywgb +.section sywha +.section sywhb +.section sywia +.section sywib +.section sywja +.section sywjb +.section sywka +.section sywkb +.section sywla +.section sywlb +.section sywma +.section sywmb +.section sywna +.section sywnb +.section sywoa +.section sywob +.section sywpa +.section sywpb +.section sywqa +.section sywqb +.section sywra +.section sywrb +.section sywsa +.section sywsb +.section sywta +.section sywtb +.section sywua +.section sywub +.section sywva +.section sywvb +.section sywwa +.section sywwb +.section sywxa +.section sywxb +.section sywya +.section sywyb +.section sywza +.section sywzb +.section syw1a +.section syw1b +.section syw2a +.section syw2b +.section syw3a +.section syw3b +.section syw4a +.section syw4b +.section syw5a +.section syw5b +.section syw6a +.section syw6b +.section syw7a +.section syw7b +.section syw8a +.section syw8b +.section syw9a +.section syw9b +.section syw0a +.section syw0b +.section syxaa +.section syxab +.section syxba +.section syxbb +.section syxca +.section syxcb +.section syxda +.section syxdb +.section syxea +.section syxeb +.section syxfa +.section syxfb +.section syxga +.section syxgb +.section syxha +.section syxhb +.section syxia +.section syxib +.section syxja +.section syxjb +.section syxka +.section syxkb +.section syxla +.section syxlb +.section syxma +.section syxmb +.section syxna +.section syxnb +.section syxoa +.section syxob +.section syxpa +.section syxpb +.section syxqa +.section syxqb +.section syxra +.section syxrb +.section syxsa +.section syxsb +.section syxta +.section syxtb +.section syxua +.section syxub +.section syxva +.section syxvb +.section syxwa +.section syxwb +.section syxxa +.section syxxb +.section syxya +.section syxyb +.section syxza +.section syxzb +.section syx1a +.section syx1b +.section syx2a +.section syx2b +.section syx3a +.section syx3b +.section syx4a +.section syx4b +.section syx5a +.section syx5b +.section syx6a +.section syx6b +.section syx7a +.section syx7b +.section syx8a +.section syx8b +.section syx9a +.section syx9b +.section syx0a +.section syx0b +.section syyaa +.section syyab +.section syyba +.section syybb +.section syyca +.section syycb +.section syyda +.section syydb +.section syyea +.section syyeb +.section syyfa +.section syyfb +.section syyga +.section syygb +.section syyha +.section syyhb +.section syyia +.section syyib +.section syyja +.section syyjb +.section syyka +.section syykb +.section syyla +.section syylb +.section syyma +.section syymb +.section syyna +.section syynb +.section syyoa +.section syyob +.section syypa +.section syypb +.section syyqa +.section syyqb +.section syyra +.section syyrb +.section syysa +.section syysb +.section syyta +.section syytb +.section syyua +.section syyub +.section syyva +.section syyvb +.section syywa +.section syywb +.section syyxa +.section syyxb +.section syyya +.section syyyb +.section syyza +.section syyzb +.section syy1a +.section syy1b +.section syy2a +.section syy2b +.section syy3a +.section syy3b +.section syy4a +.section syy4b +.section syy5a +.section syy5b +.section syy6a +.section syy6b +.section syy7a +.section syy7b +.section syy8a +.section syy8b +.section syy9a +.section syy9b +.section syy0a +.section syy0b +.section syzaa +.section syzab +.section syzba +.section syzbb +.section syzca +.section syzcb +.section syzda +.section syzdb +.section syzea +.section syzeb +.section syzfa +.section syzfb +.section syzga +.section syzgb +.section syzha +.section syzhb +.section syzia +.section syzib +.section syzja +.section syzjb +.section syzka +.section syzkb +.section syzla +.section syzlb +.section syzma +.section syzmb +.section syzna +.section syznb +.section syzoa +.section syzob +.section syzpa +.section syzpb +.section syzqa +.section syzqb +.section syzra +.section syzrb +.section syzsa +.section syzsb +.section syzta +.section syztb +.section syzua +.section syzub +.section syzva +.section syzvb +.section syzwa +.section syzwb +.section syzxa +.section syzxb +.section syzya +.section syzyb +.section syzza +.section syzzb +.section syz1a +.section syz1b +.section syz2a +.section syz2b +.section syz3a +.section syz3b +.section syz4a +.section syz4b +.section syz5a +.section syz5b +.section syz6a +.section syz6b +.section syz7a +.section syz7b +.section syz8a +.section syz8b +.section syz9a +.section syz9b +.section syz0a +.section syz0b +.section sy1aa +.section sy1ab +.section sy1ba +.section sy1bb +.section sy1ca +.section sy1cb +.section sy1da +.section sy1db +.section sy1ea +.section sy1eb +.section sy1fa +.section sy1fb +.section sy1ga +.section sy1gb +.section sy1ha +.section sy1hb +.section sy1ia +.section sy1ib +.section sy1ja +.section sy1jb +.section sy1ka +.section sy1kb +.section sy1la +.section sy1lb +.section sy1ma +.section sy1mb +.section sy1na +.section sy1nb +.section sy1oa +.section sy1ob +.section sy1pa +.section sy1pb +.section sy1qa +.section sy1qb +.section sy1ra +.section sy1rb +.section sy1sa +.section sy1sb +.section sy1ta +.section sy1tb +.section sy1ua +.section sy1ub +.section sy1va +.section sy1vb +.section sy1wa +.section sy1wb +.section sy1xa +.section sy1xb +.section sy1ya +.section sy1yb +.section sy1za +.section sy1zb +.section sy11a +.section sy11b +.section sy12a +.section sy12b +.section sy13a +.section sy13b +.section sy14a +.section sy14b +.section sy15a +.section sy15b +.section sy16a +.section sy16b +.section sy17a +.section sy17b +.section sy18a +.section sy18b +.section sy19a +.section sy19b +.section sy10a +.section sy10b +.section sy2aa +.section sy2ab +.section sy2ba +.section sy2bb +.section sy2ca +.section sy2cb +.section sy2da +.section sy2db +.section sy2ea +.section sy2eb +.section sy2fa +.section sy2fb +.section sy2ga +.section sy2gb +.section sy2ha +.section sy2hb +.section sy2ia +.section sy2ib +.section sy2ja +.section sy2jb +.section sy2ka +.section sy2kb +.section sy2la +.section sy2lb +.section sy2ma +.section sy2mb +.section sy2na +.section sy2nb +.section sy2oa +.section sy2ob +.section sy2pa +.section sy2pb +.section sy2qa +.section sy2qb +.section sy2ra +.section sy2rb +.section sy2sa +.section sy2sb +.section sy2ta +.section sy2tb +.section sy2ua +.section sy2ub +.section sy2va +.section sy2vb +.section sy2wa +.section sy2wb +.section sy2xa +.section sy2xb +.section sy2ya +.section sy2yb +.section sy2za +.section sy2zb +.section sy21a +.section sy21b +.section sy22a +.section sy22b +.section sy23a +.section sy23b +.section sy24a +.section sy24b +.section sy25a +.section sy25b +.section sy26a +.section sy26b +.section sy27a +.section sy27b +.section sy28a +.section sy28b +.section sy29a +.section sy29b +.section sy20a +.section sy20b +.section sy3aa +.section sy3ab +.section sy3ba +.section sy3bb +.section sy3ca +.section sy3cb +.section sy3da +.section sy3db +.section sy3ea +.section sy3eb +.section sy3fa +.section sy3fb +.section sy3ga +.section sy3gb +.section sy3ha +.section sy3hb +.section sy3ia +.section sy3ib +.section sy3ja +.section sy3jb +.section sy3ka +.section sy3kb +.section sy3la +.section sy3lb +.section sy3ma +.section sy3mb +.section sy3na +.section sy3nb +.section sy3oa +.section sy3ob +.section sy3pa +.section sy3pb +.section sy3qa +.section sy3qb +.section sy3ra +.section sy3rb +.section sy3sa +.section sy3sb +.section sy3ta +.section sy3tb +.section sy3ua +.section sy3ub +.section sy3va +.section sy3vb +.section sy3wa +.section sy3wb +.section sy3xa +.section sy3xb +.section sy3ya +.section sy3yb +.section sy3za +.section sy3zb +.section sy31a +.section sy31b +.section sy32a +.section sy32b +.section sy33a +.section sy33b +.section sy34a +.section sy34b +.section sy35a +.section sy35b +.section sy36a +.section sy36b +.section sy37a +.section sy37b +.section sy38a +.section sy38b +.section sy39a +.section sy39b +.section sy30a +.section sy30b +.section sy4aa +.section sy4ab +.section sy4ba +.section sy4bb +.section sy4ca +.section sy4cb +.section sy4da +.section sy4db +.section sy4ea +.section sy4eb +.section sy4fa +.section sy4fb +.section sy4ga +.section sy4gb +.section sy4ha +.section sy4hb +.section sy4ia +.section sy4ib +.section sy4ja +.section sy4jb +.section sy4ka +.section sy4kb +.section sy4la +.section sy4lb +.section sy4ma +.section sy4mb +.section sy4na +.section sy4nb +.section sy4oa +.section sy4ob +.section sy4pa +.section sy4pb +.section sy4qa +.section sy4qb +.section sy4ra +.section sy4rb +.section sy4sa +.section sy4sb +.section sy4ta +.section sy4tb +.section sy4ua +.section sy4ub +.section sy4va +.section sy4vb +.section sy4wa +.section sy4wb +.section sy4xa +.section sy4xb +.section sy4ya +.section sy4yb +.section sy4za +.section sy4zb +.section sy41a +.section sy41b +.section sy42a +.section sy42b +.section sy43a +.section sy43b +.section sy44a +.section sy44b +.section sy45a +.section sy45b +.section sy46a +.section sy46b +.section sy47a +.section sy47b +.section sy48a +.section sy48b +.section sy49a +.section sy49b +.section sy40a +.section sy40b +.section sy5aa +.section sy5ab +.section sy5ba +.section sy5bb +.section sy5ca +.section sy5cb +.section sy5da +.section sy5db +.section sy5ea +.section sy5eb +.section sy5fa +.section sy5fb +.section sy5ga +.section sy5gb +.section sy5ha +.section sy5hb +.section sy5ia +.section sy5ib +.section sy5ja +.section sy5jb +.section sy5ka +.section sy5kb +.section sy5la +.section sy5lb +.section sy5ma +.section sy5mb +.section sy5na +.section sy5nb +.section sy5oa +.section sy5ob +.section sy5pa +.section sy5pb +.section sy5qa +.section sy5qb +.section sy5ra +.section sy5rb +.section sy5sa +.section sy5sb +.section sy5ta +.section sy5tb +.section sy5ua +.section sy5ub +.section sy5va +.section sy5vb +.section sy5wa +.section sy5wb +.section sy5xa +.section sy5xb +.section sy5ya +.section sy5yb +.section sy5za +.section sy5zb +.section sy51a +.section sy51b +.section sy52a +.section sy52b +.section sy53a +.section sy53b +.section sy54a +.section sy54b +.section sy55a +.section sy55b +.section sy56a +.section sy56b +.section sy57a +.section sy57b +.section sy58a +.section sy58b +.section sy59a +.section sy59b +.section sy50a +.section sy50b +.section sy6aa +.section sy6ab +.section sy6ba +.section sy6bb +.section sy6ca +.section sy6cb +.section sy6da +.section sy6db +.section sy6ea +.section sy6eb +.section sy6fa +.section sy6fb +.section sy6ga +.section sy6gb +.section sy6ha +.section sy6hb +.section sy6ia +.section sy6ib +.section sy6ja +.section sy6jb +.section sy6ka +.section sy6kb +.section sy6la +.section sy6lb +.section sy6ma +.section sy6mb +.section sy6na +.section sy6nb +.section sy6oa +.section sy6ob +.section sy6pa +.section sy6pb +.section sy6qa +.section sy6qb +.section sy6ra +.section sy6rb +.section sy6sa +.section sy6sb +.section sy6ta +.section sy6tb +.section sy6ua +.section sy6ub +.section sy6va +.section sy6vb +.section sy6wa +.section sy6wb +.section sy6xa +.section sy6xb +.section sy6ya +.section sy6yb +.section sy6za +.section sy6zb +.section sy61a +.section sy61b +.section sy62a +.section sy62b +.section sy63a +.section sy63b +.section sy64a +.section sy64b +.section sy65a +.section sy65b +.section sy66a +.section sy66b +.section sy67a +.section sy67b +.section sy68a +.section sy68b +.section sy69a +.section sy69b +.section sy60a +.section sy60b +.section sy7aa +.section sy7ab +.section sy7ba +.section sy7bb +.section sy7ca +.section sy7cb +.section sy7da +.section sy7db +.section sy7ea +.section sy7eb +.section sy7fa +.section sy7fb +.section sy7ga +.section sy7gb +.section sy7ha +.section sy7hb +.section sy7ia +.section sy7ib +.section sy7ja +.section sy7jb +.section sy7ka +.section sy7kb +.section sy7la +.section sy7lb +.section sy7ma +.section sy7mb +.section sy7na +.section sy7nb +.section sy7oa +.section sy7ob +.section sy7pa +.section sy7pb +.section sy7qa +.section sy7qb +.section sy7ra +.section sy7rb +.section sy7sa +.section sy7sb +.section sy7ta +.section sy7tb +.section sy7ua +.section sy7ub +.section sy7va +.section sy7vb +.section sy7wa +.section sy7wb +.section sy7xa +.section sy7xb +.section sy7ya +.section sy7yb +.section sy7za +.section sy7zb +.section sy71a +.section sy71b +.section sy72a +.section sy72b +.section sy73a +.section sy73b +.section sy74a +.section sy74b +.section sy75a +.section sy75b +.section sy76a +.section sy76b +.section sy77a +.section sy77b +.section sy78a +.section sy78b +.section sy79a +.section sy79b +.section sy70a +.section sy70b +.section sy8aa +.section sy8ab +.section sy8ba +.section sy8bb +.section sy8ca +.section sy8cb +.section sy8da +.section sy8db +.section sy8ea +.section sy8eb +.section sy8fa +.section sy8fb +.section sy8ga +.section sy8gb +.section sy8ha +.section sy8hb +.section sy8ia +.section sy8ib +.section sy8ja +.section sy8jb +.section sy8ka +.section sy8kb +.section sy8la +.section sy8lb +.section sy8ma +.section sy8mb +.section sy8na +.section sy8nb +.section sy8oa +.section sy8ob +.section sy8pa +.section sy8pb +.section sy8qa +.section sy8qb +.section sy8ra +.section sy8rb +.section sy8sa +.section sy8sb +.section sy8ta +.section sy8tb +.section sy8ua +.section sy8ub +.section sy8va +.section sy8vb +.section sy8wa +.section sy8wb +.section sy8xa +.section sy8xb +.section sy8ya +.section sy8yb +.section sy8za +.section sy8zb +.section sy81a +.section sy81b +.section sy82a +.section sy82b +.section sy83a +.section sy83b +.section sy84a +.section sy84b +.section sy85a +.section sy85b +.section sy86a +.section sy86b +.section sy87a +.section sy87b +.section sy88a +.section sy88b +.section sy89a +.section sy89b +.section sy80a +.section sy80b +.section sy9aa +.section sy9ab +.section sy9ba +.section sy9bb +.section sy9ca +.section sy9cb +.section sy9da +.section sy9db +.section sy9ea +.section sy9eb +.section sy9fa +.section sy9fb +.section sy9ga +.section sy9gb +.section sy9ha +.section sy9hb +.section sy9ia +.section sy9ib +.section sy9ja +.section sy9jb +.section sy9ka +.section sy9kb +.section sy9la +.section sy9lb +.section sy9ma +.section sy9mb +.section sy9na +.section sy9nb +.section sy9oa +.section sy9ob +.section sy9pa +.section sy9pb +.section sy9qa +.section sy9qb +.section sy9ra +.section sy9rb +.section sy9sa +.section sy9sb +.section sy9ta +.section sy9tb +.section sy9ua +.section sy9ub +.section sy9va +.section sy9vb +.section sy9wa +.section sy9wb +.section sy9xa +.section sy9xb +.section sy9ya +.section sy9yb +.section sy9za +.section sy9zb +.section sy91a +.section sy91b +.section sy92a +.section sy92b +.section sy93a +.section sy93b +.section sy94a +.section sy94b +.section sy95a +.section sy95b +.section sy96a +.section sy96b +.section sy97a +.section sy97b +.section sy98a +.section sy98b +.section sy99a +.section sy99b +.section sy90a +.section sy90b +.section sy0aa +.section sy0ab +.section sy0ba +.section sy0bb +.section sy0ca +.section sy0cb +.section sy0da +.section sy0db +.section sy0ea +.section sy0eb +.section sy0fa +.section sy0fb +.section sy0ga +.section sy0gb +.section sy0ha +.section sy0hb +.section sy0ia +.section sy0ib +.section sy0ja +.section sy0jb +.section sy0ka +.section sy0kb +.section sy0la +.section sy0lb +.section sy0ma +.section sy0mb +.section sy0na +.section sy0nb +.section sy0oa +.section sy0ob +.section sy0pa +.section sy0pb +.section sy0qa +.section sy0qb +.section sy0ra +.section sy0rb +.section sy0sa +.section sy0sb +.section sy0ta +.section sy0tb +.section sy0ua +.section sy0ub +.section sy0va +.section sy0vb +.section sy0wa +.section sy0wb +.section sy0xa +.section sy0xb +.section sy0ya +.section sy0yb +.section sy0za +.section sy0zb +.section sy01a +.section sy01b +.section sy02a +.section sy02b +.section sy03a +.section sy03b +.section sy04a +.section sy04b +.section sy05a +.section sy05b +.section sy06a +.section sy06b +.section sy07a +.section sy07b +.section sy08a +.section sy08b +.section sy09a +.section sy09b +.section sy00a +.section sy00b +.section szaaa +.section szaab +.section szaba +.section szabb +.section szaca +.section szacb +.section szada +.section szadb +.section szaea +.section szaeb +.section szafa +.section szafb +.section szaga +.section szagb +.section szaha +.section szahb +.section szaia +.section szaib +.section szaja +.section szajb +.section szaka +.section szakb +.section szala +.section szalb +.section szama +.section szamb +.section szana +.section szanb +.section szaoa +.section szaob +.section szapa +.section szapb +.section szaqa +.section szaqb +.section szara +.section szarb +.section szasa +.section szasb +.section szata +.section szatb +.section szaua +.section szaub +.section szava +.section szavb +.section szawa +.section szawb +.section szaxa +.section szaxb +.section szaya +.section szayb +.section szaza +.section szazb +.section sza1a +.section sza1b +.section sza2a +.section sza2b +.section sza3a +.section sza3b +.section sza4a +.section sza4b +.section sza5a +.section sza5b +.section sza6a +.section sza6b +.section sza7a +.section sza7b +.section sza8a +.section sza8b +.section sza9a +.section sza9b +.section sza0a +.section sza0b +.section szbaa +.section szbab +.section szbba +.section szbbb +.section szbca +.section szbcb +.section szbda +.section szbdb +.section szbea +.section szbeb +.section szbfa +.section szbfb +.section szbga +.section szbgb +.section szbha +.section szbhb +.section szbia +.section szbib +.section szbja +.section szbjb +.section szbka +.section szbkb +.section szbla +.section szblb +.section szbma +.section szbmb +.section szbna +.section szbnb +.section szboa +.section szbob +.section szbpa +.section szbpb +.section szbqa +.section szbqb +.section szbra +.section szbrb +.section szbsa +.section szbsb +.section szbta +.section szbtb +.section szbua +.section szbub +.section szbva +.section szbvb +.section szbwa +.section szbwb +.section szbxa +.section szbxb +.section szbya +.section szbyb +.section szbza +.section szbzb +.section szb1a +.section szb1b +.section szb2a +.section szb2b +.section szb3a +.section szb3b +.section szb4a +.section szb4b +.section szb5a +.section szb5b +.section szb6a +.section szb6b +.section szb7a +.section szb7b +.section szb8a +.section szb8b +.section szb9a +.section szb9b +.section szb0a +.section szb0b +.section szcaa +.section szcab +.section szcba +.section szcbb +.section szcca +.section szccb +.section szcda +.section szcdb +.section szcea +.section szceb +.section szcfa +.section szcfb +.section szcga +.section szcgb +.section szcha +.section szchb +.section szcia +.section szcib +.section szcja +.section szcjb +.section szcka +.section szckb +.section szcla +.section szclb +.section szcma +.section szcmb +.section szcna +.section szcnb +.section szcoa +.section szcob +.section szcpa +.section szcpb +.section szcqa +.section szcqb +.section szcra +.section szcrb +.section szcsa +.section szcsb +.section szcta +.section szctb +.section szcua +.section szcub +.section szcva +.section szcvb +.section szcwa +.section szcwb +.section szcxa +.section szcxb +.section szcya +.section szcyb +.section szcza +.section szczb +.section szc1a +.section szc1b +.section szc2a +.section szc2b +.section szc3a +.section szc3b +.section szc4a +.section szc4b +.section szc5a +.section szc5b +.section szc6a +.section szc6b +.section szc7a +.section szc7b +.section szc8a +.section szc8b +.section szc9a +.section szc9b +.section szc0a +.section szc0b +.section szdaa +.section szdab +.section szdba +.section szdbb +.section szdca +.section szdcb +.section szdda +.section szddb +.section szdea +.section szdeb +.section szdfa +.section szdfb +.section szdga +.section szdgb +.section szdha +.section szdhb +.section szdia +.section szdib +.section szdja +.section szdjb +.section szdka +.section szdkb +.section szdla +.section szdlb +.section szdma +.section szdmb +.section szdna +.section szdnb +.section szdoa +.section szdob +.section szdpa +.section szdpb +.section szdqa +.section szdqb +.section szdra +.section szdrb +.section szdsa +.section szdsb +.section szdta +.section szdtb +.section szdua +.section szdub +.section szdva +.section szdvb +.section szdwa +.section szdwb +.section szdxa +.section szdxb +.section szdya +.section szdyb +.section szdza +.section szdzb +.section szd1a +.section szd1b +.section szd2a +.section szd2b +.section szd3a +.section szd3b +.section szd4a +.section szd4b +.section szd5a +.section szd5b +.section szd6a +.section szd6b +.section szd7a +.section szd7b +.section szd8a +.section szd8b +.section szd9a +.section szd9b +.section szd0a +.section szd0b +.section szeaa +.section szeab +.section szeba +.section szebb +.section szeca +.section szecb +.section szeda +.section szedb +.section szeea +.section szeeb +.section szefa +.section szefb +.section szega +.section szegb +.section szeha +.section szehb +.section szeia +.section szeib +.section szeja +.section szejb +.section szeka +.section szekb +.section szela +.section szelb +.section szema +.section szemb +.section szena +.section szenb +.section szeoa +.section szeob +.section szepa +.section szepb +.section szeqa +.section szeqb +.section szera +.section szerb +.section szesa +.section szesb +.section szeta +.section szetb +.section szeua +.section szeub +.section szeva +.section szevb +.section szewa +.section szewb +.section szexa +.section szexb +.section szeya +.section szeyb +.section szeza +.section szezb +.section sze1a +.section sze1b +.section sze2a +.section sze2b +.section sze3a +.section sze3b +.section sze4a +.section sze4b +.section sze5a +.section sze5b +.section sze6a +.section sze6b +.section sze7a +.section sze7b +.section sze8a +.section sze8b +.section sze9a +.section sze9b +.section sze0a +.section sze0b +.section szfaa +.section szfab +.section szfba +.section szfbb +.section szfca +.section szfcb +.section szfda +.section szfdb +.section szfea +.section szfeb +.section szffa +.section szffb +.section szfga +.section szfgb +.section szfha +.section szfhb +.section szfia +.section szfib +.section szfja +.section szfjb +.section szfka +.section szfkb +.section szfla +.section szflb +.section szfma +.section szfmb +.section szfna +.section szfnb +.section szfoa +.section szfob +.section szfpa +.section szfpb +.section szfqa +.section szfqb +.section szfra +.section szfrb +.section szfsa +.section szfsb +.section szfta +.section szftb +.section szfua +.section szfub +.section szfva +.section szfvb +.section szfwa +.section szfwb +.section szfxa +.section szfxb +.section szfya +.section szfyb +.section szfza +.section szfzb +.section szf1a +.section szf1b +.section szf2a +.section szf2b +.section szf3a +.section szf3b +.section szf4a +.section szf4b +.section szf5a +.section szf5b +.section szf6a +.section szf6b +.section szf7a +.section szf7b +.section szf8a +.section szf8b +.section szf9a +.section szf9b +.section szf0a +.section szf0b +.section szgaa +.section szgab +.section szgba +.section szgbb +.section szgca +.section szgcb +.section szgda +.section szgdb +.section szgea +.section szgeb +.section szgfa +.section szgfb +.section szgga +.section szggb +.section szgha +.section szghb +.section szgia +.section szgib +.section szgja +.section szgjb +.section szgka +.section szgkb +.section szgla +.section szglb +.section szgma +.section szgmb +.section szgna +.section szgnb +.section szgoa +.section szgob +.section szgpa +.section szgpb +.section szgqa +.section szgqb +.section szgra +.section szgrb +.section szgsa +.section szgsb +.section szgta +.section szgtb +.section szgua +.section szgub +.section szgva +.section szgvb +.section szgwa +.section szgwb +.section szgxa +.section szgxb +.section szgya +.section szgyb +.section szgza +.section szgzb +.section szg1a +.section szg1b +.section szg2a +.section szg2b +.section szg3a +.section szg3b +.section szg4a +.section szg4b +.section szg5a +.section szg5b +.section szg6a +.section szg6b +.section szg7a +.section szg7b +.section szg8a +.section szg8b +.section szg9a +.section szg9b +.section szg0a +.section szg0b +.section szhaa +.section szhab +.section szhba +.section szhbb +.section szhca +.section szhcb +.section szhda +.section szhdb +.section szhea +.section szheb +.section szhfa +.section szhfb +.section szhga +.section szhgb +.section szhha +.section szhhb +.section szhia +.section szhib +.section szhja +.section szhjb +.section szhka +.section szhkb +.section szhla +.section szhlb +.section szhma +.section szhmb +.section szhna +.section szhnb +.section szhoa +.section szhob +.section szhpa +.section szhpb +.section szhqa +.section szhqb +.section szhra +.section szhrb +.section szhsa +.section szhsb +.section szhta +.section szhtb +.section szhua +.section szhub +.section szhva +.section szhvb +.section szhwa +.section szhwb +.section szhxa +.section szhxb +.section szhya +.section szhyb +.section szhza +.section szhzb +.section szh1a +.section szh1b +.section szh2a +.section szh2b +.section szh3a +.section szh3b +.section szh4a +.section szh4b +.section szh5a +.section szh5b +.section szh6a +.section szh6b +.section szh7a +.section szh7b +.section szh8a +.section szh8b +.section szh9a +.section szh9b +.section szh0a +.section szh0b +.section sziaa +.section sziab +.section sziba +.section szibb +.section szica +.section szicb +.section szida +.section szidb +.section sziea +.section szieb +.section szifa +.section szifb +.section sziga +.section szigb +.section sziha +.section szihb +.section sziia +.section sziib +.section szija +.section szijb +.section szika +.section szikb +.section szila +.section szilb +.section szima +.section szimb +.section szina +.section szinb +.section szioa +.section sziob +.section szipa +.section szipb +.section sziqa +.section sziqb +.section szira +.section szirb +.section szisa +.section szisb +.section szita +.section szitb +.section sziua +.section sziub +.section sziva +.section szivb +.section sziwa +.section sziwb +.section szixa +.section szixb +.section sziya +.section sziyb +.section sziza +.section szizb +.section szi1a +.section szi1b +.section szi2a +.section szi2b +.section szi3a +.section szi3b +.section szi4a +.section szi4b +.section szi5a +.section szi5b +.section szi6a +.section szi6b +.section szi7a +.section szi7b +.section szi8a +.section szi8b +.section szi9a +.section szi9b +.section szi0a +.section szi0b +.section szjaa +.section szjab +.section szjba +.section szjbb +.section szjca +.section szjcb +.section szjda +.section szjdb +.section szjea +.section szjeb +.section szjfa +.section szjfb +.section szjga +.section szjgb +.section szjha +.section szjhb +.section szjia +.section szjib +.section szjja +.section szjjb +.section szjka +.section szjkb +.section szjla +.section szjlb +.section szjma +.section szjmb +.section szjna +.section szjnb +.section szjoa +.section szjob +.section szjpa +.section szjpb +.section szjqa +.section szjqb +.section szjra +.section szjrb +.section szjsa +.section szjsb +.section szjta +.section szjtb +.section szjua +.section szjub +.section szjva +.section szjvb +.section szjwa +.section szjwb +.section szjxa +.section szjxb +.section szjya +.section szjyb +.section szjza +.section szjzb +.section szj1a +.section szj1b +.section szj2a +.section szj2b +.section szj3a +.section szj3b +.section szj4a +.section szj4b +.section szj5a +.section szj5b +.section szj6a +.section szj6b +.section szj7a +.section szj7b +.section szj8a +.section szj8b +.section szj9a +.section szj9b +.section szj0a +.section szj0b +.section szkaa +.section szkab +.section szkba +.section szkbb +.section szkca +.section szkcb +.section szkda +.section szkdb +.section szkea +.section szkeb +.section szkfa +.section szkfb +.section szkga +.section szkgb +.section szkha +.section szkhb +.section szkia +.section szkib +.section szkja +.section szkjb +.section szkka +.section szkkb +.section szkla +.section szklb +.section szkma +.section szkmb +.section szkna +.section szknb +.section szkoa +.section szkob +.section szkpa +.section szkpb +.section szkqa +.section szkqb +.section szkra +.section szkrb +.section szksa +.section szksb +.section szkta +.section szktb +.section szkua +.section szkub +.section szkva +.section szkvb +.section szkwa +.section szkwb +.section szkxa +.section szkxb +.section szkya +.section szkyb +.section szkza +.section szkzb +.section szk1a +.section szk1b +.section szk2a +.section szk2b +.section szk3a +.section szk3b +.section szk4a +.section szk4b +.section szk5a +.section szk5b +.section szk6a +.section szk6b +.section szk7a +.section szk7b +.section szk8a +.section szk8b +.section szk9a +.section szk9b +.section szk0a +.section szk0b +.section szlaa +.section szlab +.section szlba +.section szlbb +.section szlca +.section szlcb +.section szlda +.section szldb +.section szlea +.section szleb +.section szlfa +.section szlfb +.section szlga +.section szlgb +.section szlha +.section szlhb +.section szlia +.section szlib +.section szlja +.section szljb +.section szlka +.section szlkb +.section szlla +.section szllb +.section szlma +.section szlmb +.section szlna +.section szlnb +.section szloa +.section szlob +.section szlpa +.section szlpb +.section szlqa +.section szlqb +.section szlra +.section szlrb +.section szlsa +.section szlsb +.section szlta +.section szltb +.section szlua +.section szlub +.section szlva +.section szlvb +.section szlwa +.section szlwb +.section szlxa +.section szlxb +.section szlya +.section szlyb +.section szlza +.section szlzb +.section szl1a +.section szl1b +.section szl2a +.section szl2b +.section szl3a +.section szl3b +.section szl4a +.section szl4b +.section szl5a +.section szl5b +.section szl6a +.section szl6b +.section szl7a +.section szl7b +.section szl8a +.section szl8b +.section szl9a +.section szl9b +.section szl0a +.section szl0b +.section szmaa +.section szmab +.section szmba +.section szmbb +.section szmca +.section szmcb +.section szmda +.section szmdb +.section szmea +.section szmeb +.section szmfa +.section szmfb +.section szmga +.section szmgb +.section szmha +.section szmhb +.section szmia +.section szmib +.section szmja +.section szmjb +.section szmka +.section szmkb +.section szmla +.section szmlb +.section szmma +.section szmmb +.section szmna +.section szmnb +.section szmoa +.section szmob +.section szmpa +.section szmpb +.section szmqa +.section szmqb +.section szmra +.section szmrb +.section szmsa +.section szmsb +.section szmta +.section szmtb +.section szmua +.section szmub +.section szmva +.section szmvb +.section szmwa +.section szmwb +.section szmxa +.section szmxb +.section szmya +.section szmyb +.section szmza +.section szmzb +.section szm1a +.section szm1b +.section szm2a +.section szm2b +.section szm3a +.section szm3b +.section szm4a +.section szm4b +.section szm5a +.section szm5b +.section szm6a +.section szm6b +.section szm7a +.section szm7b +.section szm8a +.section szm8b +.section szm9a +.section szm9b +.section szm0a +.section szm0b +.section sznaa +.section sznab +.section sznba +.section sznbb +.section sznca +.section szncb +.section sznda +.section szndb +.section sznea +.section szneb +.section sznfa +.section sznfb +.section sznga +.section szngb +.section sznha +.section sznhb +.section sznia +.section sznib +.section sznja +.section sznjb +.section sznka +.section sznkb +.section sznla +.section sznlb +.section sznma +.section sznmb +.section sznna +.section sznnb +.section sznoa +.section sznob +.section sznpa +.section sznpb +.section sznqa +.section sznqb +.section sznra +.section sznrb +.section sznsa +.section sznsb +.section sznta +.section szntb +.section sznua +.section sznub +.section sznva +.section sznvb +.section sznwa +.section sznwb +.section sznxa +.section sznxb +.section sznya +.section sznyb +.section sznza +.section sznzb +.section szn1a +.section szn1b +.section szn2a +.section szn2b +.section szn3a +.section szn3b +.section szn4a +.section szn4b +.section szn5a +.section szn5b +.section szn6a +.section szn6b +.section szn7a +.section szn7b +.section szn8a +.section szn8b +.section szn9a +.section szn9b +.section szn0a +.section szn0b +.section szoaa +.section szoab +.section szoba +.section szobb +.section szoca +.section szocb +.section szoda +.section szodb +.section szoea +.section szoeb +.section szofa +.section szofb +.section szoga +.section szogb +.section szoha +.section szohb +.section szoia +.section szoib +.section szoja +.section szojb +.section szoka +.section szokb +.section szola +.section szolb +.section szoma +.section szomb +.section szona +.section szonb +.section szooa +.section szoob +.section szopa +.section szopb +.section szoqa +.section szoqb +.section szora +.section szorb +.section szosa +.section szosb +.section szota +.section szotb +.section szoua +.section szoub +.section szova +.section szovb +.section szowa +.section szowb +.section szoxa +.section szoxb +.section szoya +.section szoyb +.section szoza +.section szozb +.section szo1a +.section szo1b +.section szo2a +.section szo2b +.section szo3a +.section szo3b +.section szo4a +.section szo4b +.section szo5a +.section szo5b +.section szo6a +.section szo6b +.section szo7a +.section szo7b +.section szo8a +.section szo8b +.section szo9a +.section szo9b +.section szo0a +.section szo0b +.section szpaa +.section szpab +.section szpba +.section szpbb +.section szpca +.section szpcb +.section szpda +.section szpdb +.section szpea +.section szpeb +.section szpfa +.section szpfb +.section szpga +.section szpgb +.section szpha +.section szphb +.section szpia +.section szpib +.section szpja +.section szpjb +.section szpka +.section szpkb +.section szpla +.section szplb +.section szpma +.section szpmb +.section szpna +.section szpnb +.section szpoa +.section szpob +.section szppa +.section szppb +.section szpqa +.section szpqb +.section szpra +.section szprb +.section szpsa +.section szpsb +.section szpta +.section szptb +.section szpua +.section szpub +.section szpva +.section szpvb +.section szpwa +.section szpwb +.section szpxa +.section szpxb +.section szpya +.section szpyb +.section szpza +.section szpzb +.section szp1a +.section szp1b +.section szp2a +.section szp2b +.section szp3a +.section szp3b +.section szp4a +.section szp4b +.section szp5a +.section szp5b +.section szp6a +.section szp6b +.section szp7a +.section szp7b +.section szp8a +.section szp8b +.section szp9a +.section szp9b +.section szp0a +.section szp0b +.section szqaa +.section szqab +.section szqba +.section szqbb +.section szqca +.section szqcb +.section szqda +.section szqdb +.section szqea +.section szqeb +.section szqfa +.section szqfb +.section szqga +.section szqgb +.section szqha +.section szqhb +.section szqia +.section szqib +.section szqja +.section szqjb +.section szqka +.section szqkb +.section szqla +.section szqlb +.section szqma +.section szqmb +.section szqna +.section szqnb +.section szqoa +.section szqob +.section szqpa +.section szqpb +.section szqqa +.section szqqb +.section szqra +.section szqrb +.section szqsa +.section szqsb +.section szqta +.section szqtb +.section szqua +.section szqub +.section szqva +.section szqvb +.section szqwa +.section szqwb +.section szqxa +.section szqxb +.section szqya +.section szqyb +.section szqza +.section szqzb +.section szq1a +.section szq1b +.section szq2a +.section szq2b +.section szq3a +.section szq3b +.section szq4a +.section szq4b +.section szq5a +.section szq5b +.section szq6a +.section szq6b +.section szq7a +.section szq7b +.section szq8a +.section szq8b +.section szq9a +.section szq9b +.section szq0a +.section szq0b +.section szraa +.section szrab +.section szrba +.section szrbb +.section szrca +.section szrcb +.section szrda +.section szrdb +.section szrea +.section szreb +.section szrfa +.section szrfb +.section szrga +.section szrgb +.section szrha +.section szrhb +.section szria +.section szrib +.section szrja +.section szrjb +.section szrka +.section szrkb +.section szrla +.section szrlb +.section szrma +.section szrmb +.section szrna +.section szrnb +.section szroa +.section szrob +.section szrpa +.section szrpb +.section szrqa +.section szrqb +.section szrra +.section szrrb +.section szrsa +.section szrsb +.section szrta +.section szrtb +.section szrua +.section szrub +.section szrva +.section szrvb +.section szrwa +.section szrwb +.section szrxa +.section szrxb +.section szrya +.section szryb +.section szrza +.section szrzb +.section szr1a +.section szr1b +.section szr2a +.section szr2b +.section szr3a +.section szr3b +.section szr4a +.section szr4b +.section szr5a +.section szr5b +.section szr6a +.section szr6b +.section szr7a +.section szr7b +.section szr8a +.section szr8b +.section szr9a +.section szr9b +.section szr0a +.section szr0b +.section szsaa +.section szsab +.section szsba +.section szsbb +.section szsca +.section szscb +.section szsda +.section szsdb +.section szsea +.section szseb +.section szsfa +.section szsfb +.section szsga +.section szsgb +.section szsha +.section szshb +.section szsia +.section szsib +.section szsja +.section szsjb +.section szska +.section szskb +.section szsla +.section szslb +.section szsma +.section szsmb +.section szsna +.section szsnb +.section szsoa +.section szsob +.section szspa +.section szspb +.section szsqa +.section szsqb +.section szsra +.section szsrb +.section szssa +.section szssb +.section szsta +.section szstb +.section szsua +.section szsub +.section szsva +.section szsvb +.section szswa +.section szswb +.section szsxa +.section szsxb +.section szsya +.section szsyb +.section szsza +.section szszb +.section szs1a +.section szs1b +.section szs2a +.section szs2b +.section szs3a +.section szs3b +.section szs4a +.section szs4b +.section szs5a +.section szs5b +.section szs6a +.section szs6b +.section szs7a +.section szs7b +.section szs8a +.section szs8b +.section szs9a +.section szs9b +.section szs0a +.section szs0b +.section sztaa +.section sztab +.section sztba +.section sztbb +.section sztca +.section sztcb +.section sztda +.section sztdb +.section sztea +.section szteb +.section sztfa +.section sztfb +.section sztga +.section sztgb +.section sztha +.section szthb +.section sztia +.section sztib +.section sztja +.section sztjb +.section sztka +.section sztkb +.section sztla +.section sztlb +.section sztma +.section sztmb +.section sztna +.section sztnb +.section sztoa +.section sztob +.section sztpa +.section sztpb +.section sztqa +.section sztqb +.section sztra +.section sztrb +.section sztsa +.section sztsb +.section sztta +.section szttb +.section sztua +.section sztub +.section sztva +.section sztvb +.section sztwa +.section sztwb +.section sztxa +.section sztxb +.section sztya +.section sztyb +.section sztza +.section sztzb +.section szt1a +.section szt1b +.section szt2a +.section szt2b +.section szt3a +.section szt3b +.section szt4a +.section szt4b +.section szt5a +.section szt5b +.section szt6a +.section szt6b +.section szt7a +.section szt7b +.section szt8a +.section szt8b +.section szt9a +.section szt9b +.section szt0a +.section szt0b +.section szuaa +.section szuab +.section szuba +.section szubb +.section szuca +.section szucb +.section szuda +.section szudb +.section szuea +.section szueb +.section szufa +.section szufb +.section szuga +.section szugb +.section szuha +.section szuhb +.section szuia +.section szuib +.section szuja +.section szujb +.section szuka +.section szukb +.section szula +.section szulb +.section szuma +.section szumb +.section szuna +.section szunb +.section szuoa +.section szuob +.section szupa +.section szupb +.section szuqa +.section szuqb +.section szura +.section szurb +.section szusa +.section szusb +.section szuta +.section szutb +.section szuua +.section szuub +.section szuva +.section szuvb +.section szuwa +.section szuwb +.section szuxa +.section szuxb +.section szuya +.section szuyb +.section szuza +.section szuzb +.section szu1a +.section szu1b +.section szu2a +.section szu2b +.section szu3a +.section szu3b +.section szu4a +.section szu4b +.section szu5a +.section szu5b +.section szu6a +.section szu6b +.section szu7a +.section szu7b +.section szu8a +.section szu8b +.section szu9a +.section szu9b +.section szu0a +.section szu0b +.section szvaa +.section szvab +.section szvba +.section szvbb +.section szvca +.section szvcb +.section szvda +.section szvdb +.section szvea +.section szveb +.section szvfa +.section szvfb +.section szvga +.section szvgb +.section szvha +.section szvhb +.section szvia +.section szvib +.section szvja +.section szvjb +.section szvka +.section szvkb +.section szvla +.section szvlb +.section szvma +.section szvmb +.section szvna +.section szvnb +.section szvoa +.section szvob +.section szvpa +.section szvpb +.section szvqa +.section szvqb +.section szvra +.section szvrb +.section szvsa +.section szvsb +.section szvta +.section szvtb +.section szvua +.section szvub +.section szvva +.section szvvb +.section szvwa +.section szvwb +.section szvxa +.section szvxb +.section szvya +.section szvyb +.section szvza +.section szvzb +.section szv1a +.section szv1b +.section szv2a +.section szv2b +.section szv3a +.section szv3b +.section szv4a +.section szv4b +.section szv5a +.section szv5b +.section szv6a +.section szv6b +.section szv7a +.section szv7b +.section szv8a +.section szv8b +.section szv9a +.section szv9b +.section szv0a +.section szv0b +.section szwaa +.section szwab +.section szwba +.section szwbb +.section szwca +.section szwcb +.section szwda +.section szwdb +.section szwea +.section szweb +.section szwfa +.section szwfb +.section szwga +.section szwgb +.section szwha +.section szwhb +.section szwia +.section szwib +.section szwja +.section szwjb +.section szwka +.section szwkb +.section szwla +.section szwlb +.section szwma +.section szwmb +.section szwna +.section szwnb +.section szwoa +.section szwob +.section szwpa +.section szwpb +.section szwqa +.section szwqb +.section szwra +.section szwrb +.section szwsa +.section szwsb +.section szwta +.section szwtb +.section szwua +.section szwub +.section szwva +.section szwvb +.section szwwa +.section szwwb +.section szwxa +.section szwxb +.section szwya +.section szwyb +.section szwza +.section szwzb +.section szw1a +.section szw1b +.section szw2a +.section szw2b +.section szw3a +.section szw3b +.section szw4a +.section szw4b +.section szw5a +.section szw5b +.section szw6a +.section szw6b +.section szw7a +.section szw7b +.section szw8a +.section szw8b +.section szw9a +.section szw9b +.section szw0a +.section szw0b +.section szxaa +.section szxab +.section szxba +.section szxbb +.section szxca +.section szxcb +.section szxda +.section szxdb +.section szxea +.section szxeb +.section szxfa +.section szxfb +.section szxga +.section szxgb +.section szxha +.section szxhb +.section szxia +.section szxib +.section szxja +.section szxjb +.section szxka +.section szxkb +.section szxla +.section szxlb +.section szxma +.section szxmb +.section szxna +.section szxnb +.section szxoa +.section szxob +.section szxpa +.section szxpb +.section szxqa +.section szxqb +.section szxra +.section szxrb +.section szxsa +.section szxsb +.section szxta +.section szxtb +.section szxua +.section szxub +.section szxva +.section szxvb +.section szxwa +.section szxwb +.section szxxa +.section szxxb +.section szxya +.section szxyb +.section szxza +.section szxzb +.section szx1a +.section szx1b +.section szx2a +.section szx2b +.section szx3a +.section szx3b +.section szx4a +.section szx4b +.section szx5a +.section szx5b +.section szx6a +.section szx6b +.section szx7a +.section szx7b +.section szx8a +.section szx8b +.section szx9a +.section szx9b +.section szx0a +.section szx0b +.section szyaa +.section szyab +.section szyba +.section szybb +.section szyca +.section szycb +.section szyda +.section szydb +.section szyea +.section szyeb +.section szyfa +.section szyfb +.section szyga +.section szygb +.section szyha +.section szyhb +.section szyia +.section szyib +.section szyja +.section szyjb +.section szyka +.section szykb +.section szyla +.section szylb +.section szyma +.section szymb +.section szyna +.section szynb +.section szyoa +.section szyob +.section szypa +.section szypb +.section szyqa +.section szyqb +.section szyra +.section szyrb +.section szysa +.section szysb +.section szyta +.section szytb +.section szyua +.section szyub +.section szyva +.section szyvb +.section szywa +.section szywb +.section szyxa +.section szyxb +.section szyya +.section szyyb +.section szyza +.section szyzb +.section szy1a +.section szy1b +.section szy2a +.section szy2b +.section szy3a +.section szy3b +.section szy4a +.section szy4b +.section szy5a +.section szy5b +.section szy6a +.section szy6b +.section szy7a +.section szy7b +.section szy8a +.section szy8b +.section szy9a +.section szy9b +.section szy0a +.section szy0b +.section szzaa +.section szzab +.section szzba +.section szzbb +.section szzca +.section szzcb +.section szzda +.section szzdb +.section szzea +.section szzeb +.section szzfa +.section szzfb +.section szzga +.section szzgb +.section szzha +.section szzhb +.section szzia +.section szzib +.section szzja +.section szzjb +.section szzka +.section szzkb +.section szzla +.section szzlb +.section szzma +.section szzmb +.section szzna +.section szznb +.section szzoa +.section szzob +.section szzpa +.section szzpb +.section szzqa +.section szzqb +.section szzra +.section szzrb +.section szzsa +.section szzsb +.section szzta +.section szztb +.section szzua +.section szzub +.section szzva +.section szzvb +.section szzwa +.section szzwb +.section szzxa +.section szzxb +.section szzya +.section szzyb +.section szzza +.section szzzb +.section szz1a +.section szz1b +.section szz2a +.section szz2b +.section szz3a +.section szz3b +.section szz4a +.section szz4b +.section szz5a +.section szz5b +.section szz6a +.section szz6b +.section szz7a +.section szz7b +.section szz8a +.section szz8b +.section szz9a +.section szz9b +.section szz0a +.section szz0b +.section sz1aa +.section sz1ab +.section sz1ba +.section sz1bb +.section sz1ca +.section sz1cb +.section sz1da +.section sz1db +.section sz1ea +.section sz1eb +.section sz1fa +.section sz1fb +.section sz1ga +.section sz1gb +.section sz1ha +.section sz1hb +.section sz1ia +.section sz1ib +.section sz1ja +.section sz1jb +.section sz1ka +.section sz1kb +.section sz1la +.section sz1lb +.section sz1ma +.section sz1mb +.section sz1na +.section sz1nb +.section sz1oa +.section sz1ob +.section sz1pa +.section sz1pb +.section sz1qa +.section sz1qb +.section sz1ra +.section sz1rb +.section sz1sa +.section sz1sb +.section sz1ta +.section sz1tb +.section sz1ua +.section sz1ub +.section sz1va +.section sz1vb +.section sz1wa +.section sz1wb +.section sz1xa +.section sz1xb +.section sz1ya +.section sz1yb +.section sz1za +.section sz1zb +.section sz11a +.section sz11b +.section sz12a +.section sz12b +.section sz13a +.section sz13b +.section sz14a +.section sz14b +.section sz15a +.section sz15b +.section sz16a +.section sz16b +.section sz17a +.section sz17b +.section sz18a +.section sz18b +.section sz19a +.section sz19b +.section sz10a +.section sz10b +.section sz2aa +.section sz2ab +.section sz2ba +.section sz2bb +.section sz2ca +.section sz2cb +.section sz2da +.section sz2db +.section sz2ea +.section sz2eb +.section sz2fa +.section sz2fb +.section sz2ga +.section sz2gb +.section sz2ha +.section sz2hb +.section sz2ia +.section sz2ib +.section sz2ja +.section sz2jb +.section sz2ka +.section sz2kb +.section sz2la +.section sz2lb +.section sz2ma +.section sz2mb +.section sz2na +.section sz2nb +.section sz2oa +.section sz2ob +.section sz2pa +.section sz2pb +.section sz2qa +.section sz2qb +.section sz2ra +.section sz2rb +.section sz2sa +.section sz2sb +.section sz2ta +.section sz2tb +.section sz2ua +.section sz2ub +.section sz2va +.section sz2vb +.section sz2wa +.section sz2wb +.section sz2xa +.section sz2xb +.section sz2ya +.section sz2yb +.section sz2za +.section sz2zb +.section sz21a +.section sz21b +.section sz22a +.section sz22b +.section sz23a +.section sz23b +.section sz24a +.section sz24b +.section sz25a +.section sz25b +.section sz26a +.section sz26b +.section sz27a +.section sz27b +.section sz28a +.section sz28b +.section sz29a +.section sz29b +.section sz20a +.section sz20b +.section sz3aa +.section sz3ab +.section sz3ba +.section sz3bb +.section sz3ca +.section sz3cb +.section sz3da +.section sz3db +.section sz3ea +.section sz3eb +.section sz3fa +.section sz3fb +.section sz3ga +.section sz3gb +.section sz3ha +.section sz3hb +.section sz3ia +.section sz3ib +.section sz3ja +.section sz3jb +.section sz3ka +.section sz3kb +.section sz3la +.section sz3lb +.section sz3ma +.section sz3mb +.section sz3na +.section sz3nb +.section sz3oa +.section sz3ob +.section sz3pa +.section sz3pb +.section sz3qa +.section sz3qb +.section sz3ra +.section sz3rb +.section sz3sa +.section sz3sb +.section sz3ta +.section sz3tb +.section sz3ua +.section sz3ub +.section sz3va +.section sz3vb +.section sz3wa +.section sz3wb +.section sz3xa +.section sz3xb +.section sz3ya +.section sz3yb +.section sz3za +.section sz3zb +.section sz31a +.section sz31b +.section sz32a +.section sz32b +.section sz33a +.section sz33b +.section sz34a +.section sz34b +.section sz35a +.section sz35b +.section sz36a +.section sz36b +.section sz37a +.section sz37b +.section sz38a +.section sz38b +.section sz39a +.section sz39b +.section sz30a +.section sz30b +.section sz4aa +.section sz4ab +.section sz4ba +.section sz4bb +.section sz4ca +.section sz4cb +.section sz4da +.section sz4db +.section sz4ea +.section sz4eb +.section sz4fa +.section sz4fb +.section sz4ga +.section sz4gb +.section sz4ha +.section sz4hb +.section sz4ia +.section sz4ib +.section sz4ja +.section sz4jb +.section sz4ka +.section sz4kb +.section sz4la +.section sz4lb +.section sz4ma +.section sz4mb +.section sz4na +.section sz4nb +.section sz4oa +.section sz4ob +.section sz4pa +.section sz4pb +.section sz4qa +.section sz4qb +.section sz4ra +.section sz4rb +.section sz4sa +.section sz4sb +.section sz4ta +.section sz4tb +.section sz4ua +.section sz4ub +.section sz4va +.section sz4vb +.section sz4wa +.section sz4wb +.section sz4xa +.section sz4xb +.section sz4ya +.section sz4yb +.section sz4za +.section sz4zb +.section sz41a +.section sz41b +.section sz42a +.section sz42b +.section sz43a +.section sz43b +.section sz44a +.section sz44b +.section sz45a +.section sz45b +.section sz46a +.section sz46b +.section sz47a +.section sz47b +.section sz48a +.section sz48b +.section sz49a +.section sz49b +.section sz40a +.section sz40b +.section sz5aa +.section sz5ab +.section sz5ba +.section sz5bb +.section sz5ca +.section sz5cb +.section sz5da +.section sz5db +.section sz5ea +.section sz5eb +.section sz5fa +.section sz5fb +.section sz5ga +.section sz5gb +.section sz5ha +.section sz5hb +.section sz5ia +.section sz5ib +.section sz5ja +.section sz5jb +.section sz5ka +.section sz5kb +.section sz5la +.section sz5lb +.section sz5ma +.section sz5mb +.section sz5na +.section sz5nb +.section sz5oa +.section sz5ob +.section sz5pa +.section sz5pb +.section sz5qa +.section sz5qb +.section sz5ra +.section sz5rb +.section sz5sa +.section sz5sb +.section sz5ta +.section sz5tb +.section sz5ua +.section sz5ub +.section sz5va +.section sz5vb +.section sz5wa +.section sz5wb +.section sz5xa +.section sz5xb +.section sz5ya +.section sz5yb +.section sz5za +.section sz5zb +.section sz51a +.section sz51b +.section sz52a +.section sz52b +.section sz53a +.section sz53b +.section sz54a +.section sz54b +.section sz55a +.section sz55b +.section sz56a +.section sz56b +.section sz57a +.section sz57b +.section sz58a +.section sz58b +.section sz59a +.section sz59b +.section sz50a +.section sz50b +.section sz6aa +.section sz6ab +.section sz6ba +.section sz6bb +.section sz6ca +.section sz6cb +.section sz6da +.section sz6db +.section sz6ea +.section sz6eb +.section sz6fa +.section sz6fb +.section sz6ga +.section sz6gb +.section sz6ha +.section sz6hb +.section sz6ia +.section sz6ib +.section sz6ja +.section sz6jb +.section sz6ka +.section sz6kb +.section sz6la +.section sz6lb +.section sz6ma +.section sz6mb +.section sz6na +.section sz6nb +.section sz6oa +.section sz6ob +.section sz6pa +.section sz6pb +.section sz6qa +.section sz6qb +.section sz6ra +.section sz6rb +.section sz6sa +.section sz6sb +.section sz6ta +.section sz6tb +.section sz6ua +.section sz6ub +.section sz6va +.section sz6vb +.section sz6wa +.section sz6wb +.section sz6xa +.section sz6xb +.section sz6ya +.section sz6yb +.section sz6za +.section sz6zb +.section sz61a +.section sz61b +.section sz62a +.section sz62b +.section sz63a +.section sz63b +.section sz64a +.section sz64b +.section sz65a +.section sz65b +.section sz66a +.section sz66b +.section sz67a +.section sz67b +.section sz68a +.section sz68b +.section sz69a +.section sz69b +.section sz60a +.section sz60b +.section sz7aa +.section sz7ab +.section sz7ba +.section sz7bb +.section sz7ca +.section sz7cb +.section sz7da +.section sz7db +.section sz7ea +.section sz7eb +.section sz7fa +.section sz7fb +.section sz7ga +.section sz7gb +.section sz7ha +.section sz7hb +.section sz7ia +.section sz7ib +.section sz7ja +.section sz7jb +.section sz7ka +.section sz7kb +.section sz7la +.section sz7lb +.section sz7ma +.section sz7mb +.section sz7na +.section sz7nb +.section sz7oa +.section sz7ob +.section sz7pa +.section sz7pb +.section sz7qa +.section sz7qb +.section sz7ra +.section sz7rb +.section sz7sa +.section sz7sb +.section sz7ta +.section sz7tb +.section sz7ua +.section sz7ub +.section sz7va +.section sz7vb +.section sz7wa +.section sz7wb +.section sz7xa +.section sz7xb +.section sz7ya +.section sz7yb +.section sz7za +.section sz7zb +.section sz71a +.section sz71b +.section sz72a +.section sz72b +.section sz73a +.section sz73b +.section sz74a +.section sz74b +.section sz75a +.section sz75b +.section sz76a +.section sz76b +.section sz77a +.section sz77b +.section sz78a +.section sz78b +.section sz79a +.section sz79b +.section sz70a +.section sz70b +.section sz8aa +.section sz8ab +.section sz8ba +.section sz8bb +.section sz8ca +.section sz8cb +.section sz8da +.section sz8db +.section sz8ea +.section sz8eb +.section sz8fa +.section sz8fb +.section sz8ga +.section sz8gb +.section sz8ha +.section sz8hb +.section sz8ia +.section sz8ib +.section sz8ja +.section sz8jb +.section sz8ka +.section sz8kb +.section sz8la +.section sz8lb +.section sz8ma +.section sz8mb +.section sz8na +.section sz8nb +.section sz8oa +.section sz8ob +.section sz8pa +.section sz8pb +.section sz8qa +.section sz8qb +.section sz8ra +.section sz8rb +.section sz8sa +.section sz8sb +.section sz8ta +.section sz8tb +.section sz8ua +.section sz8ub +.section sz8va +.section sz8vb +.section sz8wa +.section sz8wb +.section sz8xa +.section sz8xb +.section sz8ya +.section sz8yb +.section sz8za +.section sz8zb +.section sz81a +.section sz81b +.section sz82a +.section sz82b +.section sz83a +.section sz83b +.section sz84a +.section sz84b +.section sz85a +.section sz85b +.section sz86a +.section sz86b +.section sz87a +.section sz87b +.section sz88a +.section sz88b +.section sz89a +.section sz89b +.section sz80a +.section sz80b +.section sz9aa +.section sz9ab +.section sz9ba +.section sz9bb +.section sz9ca +.section sz9cb +.section sz9da +.section sz9db +.section sz9ea +.section sz9eb +.section sz9fa +.section sz9fb +.section sz9ga +.section sz9gb +.section sz9ha +.section sz9hb +.section sz9ia +.section sz9ib +.section sz9ja +.section sz9jb +.section sz9ka +.section sz9kb +.section sz9la +.section sz9lb +.section sz9ma +.section sz9mb +.section sz9na +.section sz9nb +.section sz9oa +.section sz9ob +.section sz9pa +.section sz9pb +.section sz9qa +.section sz9qb +.section sz9ra +.section sz9rb +.section sz9sa +.section sz9sb +.section sz9ta +.section sz9tb +.section sz9ua +.section sz9ub +.section sz9va +.section sz9vb +.section sz9wa +.section sz9wb +.section sz9xa +.section sz9xb +.section sz9ya +.section sz9yb +.section sz9za +.section sz9zb +.section sz91a +.section sz91b +.section sz92a +.section sz92b +.section sz93a +.section sz93b +.section sz94a +.section sz94b +.section sz95a +.section sz95b +.section sz96a +.section sz96b +.section sz97a +.section sz97b +.section sz98a +.section sz98b +.section sz99a +.section sz99b +.section sz90a +.section sz90b +.section sz0aa +.section sz0ab +.section sz0ba +.section sz0bb +.section sz0ca +.section sz0cb +.section sz0da +.section sz0db +.section sz0ea +.section sz0eb +.section sz0fa +.section sz0fb +.section sz0ga +.section sz0gb +.section sz0ha +.section sz0hb +.section sz0ia +.section sz0ib +.section sz0ja +.section sz0jb +.section sz0ka +.section sz0kb +.section sz0la +.section sz0lb +.section sz0ma +.section sz0mb +.section sz0na +.section sz0nb +.section sz0oa +.section sz0ob +.section sz0pa +.section sz0pb +.section sz0qa +.section sz0qb +.section sz0ra +.section sz0rb +.section sz0sa +.section sz0sb +.section sz0ta +.section sz0tb +.section sz0ua +.section sz0ub +.section sz0va +.section sz0vb +.section sz0wa +.section sz0wb +.section sz0xa +.section sz0xb +.section sz0ya +.section sz0yb +.section sz0za +.section sz0zb +.section sz01a +.section sz01b +.section sz02a +.section sz02b +.section sz03a +.section sz03b +.section sz04a +.section sz04b +.section sz05a +.section sz05b +.section sz06a +.section sz06b +.section sz07a +.section sz07b +.section sz08a +.section sz08b +.section sz09a +.section sz09b +.section sz00a +.section sz00b +.section s1aaa +.section s1aab +.section s1aba +.section s1abb +.section s1aca +.section s1acb +.section s1ada +.section s1adb +.section s1aea +.section s1aeb +.section s1afa +.section s1afb +.section s1aga +.section s1agb +.section s1aha +.section s1ahb +.section s1aia +.section s1aib +.section s1aja +.section s1ajb +.section s1aka +.section s1akb +.section s1ala +.section s1alb +.section s1ama +.section s1amb +.section s1ana +.section s1anb +.section s1aoa +.section s1aob +.section s1apa +.section s1apb +.section s1aqa +.section s1aqb +.section s1ara +.section s1arb +.section s1asa +.section s1asb +.section s1ata +.section s1atb +.section s1aua +.section s1aub +.section s1ava +.section s1avb +.section s1awa +.section s1awb +.section s1axa +.section s1axb +.section s1aya +.section s1ayb +.section s1aza +.section s1azb +.section s1a1a +.section s1a1b +.section s1a2a +.section s1a2b +.section s1a3a +.section s1a3b +.section s1a4a +.section s1a4b +.section s1a5a +.section s1a5b +.section s1a6a +.section s1a6b +.section s1a7a +.section s1a7b +.section s1a8a +.section s1a8b +.section s1a9a +.section s1a9b +.section s1a0a +.section s1a0b +.section s1baa +.section s1bab +.section s1bba +.section s1bbb +.section s1bca +.section s1bcb +.section s1bda +.section s1bdb +.section s1bea +.section s1beb +.section s1bfa +.section s1bfb +.section s1bga +.section s1bgb +.section s1bha +.section s1bhb +.section s1bia +.section s1bib +.section s1bja +.section s1bjb +.section s1bka +.section s1bkb +.section s1bla +.section s1blb +.section s1bma +.section s1bmb +.section s1bna +.section s1bnb +.section s1boa +.section s1bob +.section s1bpa +.section s1bpb +.section s1bqa +.section s1bqb +.section s1bra +.section s1brb +.section s1bsa +.section s1bsb +.section s1bta +.section s1btb +.section s1bua +.section s1bub +.section s1bva +.section s1bvb +.section s1bwa +.section s1bwb +.section s1bxa +.section s1bxb +.section s1bya +.section s1byb +.section s1bza +.section s1bzb +.section s1b1a +.section s1b1b +.section s1b2a +.section s1b2b +.section s1b3a +.section s1b3b +.section s1b4a +.section s1b4b +.section s1b5a +.section s1b5b +.section s1b6a +.section s1b6b +.section s1b7a +.section s1b7b +.section s1b8a +.section s1b8b +.section s1b9a +.section s1b9b +.section s1b0a +.section s1b0b +.section s1caa +.section s1cab +.section s1cba +.section s1cbb +.section s1cca +.section s1ccb +.section s1cda +.section s1cdb +.section s1cea +.section s1ceb +.section s1cfa +.section s1cfb +.section s1cga +.section s1cgb +.section s1cha +.section s1chb +.section s1cia +.section s1cib +.section s1cja +.section s1cjb +.section s1cka +.section s1ckb +.section s1cla +.section s1clb +.section s1cma +.section s1cmb +.section s1cna +.section s1cnb +.section s1coa +.section s1cob +.section s1cpa +.section s1cpb +.section s1cqa +.section s1cqb +.section s1cra +.section s1crb +.section s1csa +.section s1csb +.section s1cta +.section s1ctb +.section s1cua +.section s1cub +.section s1cva +.section s1cvb +.section s1cwa +.section s1cwb +.section s1cxa +.section s1cxb +.section s1cya +.section s1cyb +.section s1cza +.section s1czb +.section s1c1a +.section s1c1b +.section s1c2a +.section s1c2b +.section s1c3a +.section s1c3b +.section s1c4a +.section s1c4b +.section s1c5a +.section s1c5b +.section s1c6a +.section s1c6b +.section s1c7a +.section s1c7b +.section s1c8a +.section s1c8b +.section s1c9a +.section s1c9b +.section s1c0a +.section s1c0b +.section s1daa +.section s1dab +.section s1dba +.section s1dbb +.section s1dca +.section s1dcb +.section s1dda +.section s1ddb +.section s1dea +.section s1deb +.section s1dfa +.section s1dfb +.section s1dga +.section s1dgb +.section s1dha +.section s1dhb +.section s1dia +.section s1dib +.section s1dja +.section s1djb +.section s1dka +.section s1dkb +.section s1dla +.section s1dlb +.section s1dma +.section s1dmb +.section s1dna +.section s1dnb +.section s1doa +.section s1dob +.section s1dpa +.section s1dpb +.section s1dqa +.section s1dqb +.section s1dra +.section s1drb +.section s1dsa +.section s1dsb +.section s1dta +.section s1dtb +.section s1dua +.section s1dub +.section s1dva +.section s1dvb +.section s1dwa +.section s1dwb +.section s1dxa +.section s1dxb +.section s1dya +.section s1dyb +.section s1dza +.section s1dzb +.section s1d1a +.section s1d1b +.section s1d2a +.section s1d2b +.section s1d3a +.section s1d3b +.section s1d4a +.section s1d4b +.section s1d5a +.section s1d5b +.section s1d6a +.section s1d6b +.section s1d7a +.section s1d7b +.section s1d8a +.section s1d8b +.section s1d9a +.section s1d9b +.section s1d0a +.section s1d0b +.section s1eaa +.section s1eab +.section s1eba +.section s1ebb +.section s1eca +.section s1ecb +.section s1eda +.section s1edb +.section s1eea +.section s1eeb +.section s1efa +.section s1efb +.section s1ega +.section s1egb +.section s1eha +.section s1ehb +.section s1eia +.section s1eib +.section s1eja +.section s1ejb +.section s1eka +.section s1ekb +.section s1ela +.section s1elb +.section s1ema +.section s1emb +.section s1ena +.section s1enb +.section s1eoa +.section s1eob +.section s1epa +.section s1epb +.section s1eqa +.section s1eqb +.section s1era +.section s1erb +.section s1esa +.section s1esb +.section s1eta +.section s1etb +.section s1eua +.section s1eub +.section s1eva +.section s1evb +.section s1ewa +.section s1ewb +.section s1exa +.section s1exb +.section s1eya +.section s1eyb +.section s1eza +.section s1ezb +.section s1e1a +.section s1e1b +.section s1e2a +.section s1e2b +.section s1e3a +.section s1e3b +.section s1e4a +.section s1e4b +.section s1e5a +.section s1e5b +.section s1e6a +.section s1e6b +.section s1e7a +.section s1e7b +.section s1e8a +.section s1e8b +.section s1e9a +.section s1e9b +.section s1e0a +.section s1e0b +.section s1faa +.section s1fab +.section s1fba +.section s1fbb +.section s1fca +.section s1fcb +.section s1fda +.section s1fdb +.section s1fea +.section s1feb +.section s1ffa +.section s1ffb +.section s1fga +.section s1fgb +.section s1fha +.section s1fhb +.section s1fia +.section s1fib +.section s1fja +.section s1fjb +.section s1fka +.section s1fkb +.section s1fla +.section s1flb +.section s1fma +.section s1fmb +.section s1fna +.section s1fnb +.section s1foa +.section s1fob +.section s1fpa +.section s1fpb +.section s1fqa +.section s1fqb +.section s1fra +.section s1frb +.section s1fsa +.section s1fsb +.section s1fta +.section s1ftb +.section s1fua +.section s1fub +.section s1fva +.section s1fvb +.section s1fwa +.section s1fwb +.section s1fxa +.section s1fxb +.section s1fya +.section s1fyb +.section s1fza +.section s1fzb +.section s1f1a +.section s1f1b +.section s1f2a +.section s1f2b +.section s1f3a +.section s1f3b +.section s1f4a +.section s1f4b +.section s1f5a +.section s1f5b +.section s1f6a +.section s1f6b +.section s1f7a +.section s1f7b +.section s1f8a +.section s1f8b +.section s1f9a +.section s1f9b +.section s1f0a +.section s1f0b +.section s1gaa +.section s1gab +.section s1gba +.section s1gbb +.section s1gca +.section s1gcb +.section s1gda +.section s1gdb +.section s1gea +.section s1geb +.section s1gfa +.section s1gfb +.section s1gga +.section s1ggb +.section s1gha +.section s1ghb +.section s1gia +.section s1gib +.section s1gja +.section s1gjb +.section s1gka +.section s1gkb +.section s1gla +.section s1glb +.section s1gma +.section s1gmb +.section s1gna +.section s1gnb +.section s1goa +.section s1gob +.section s1gpa +.section s1gpb +.section s1gqa +.section s1gqb +.section s1gra +.section s1grb +.section s1gsa +.section s1gsb +.section s1gta +.section s1gtb +.section s1gua +.section s1gub +.section s1gva +.section s1gvb +.section s1gwa +.section s1gwb +.section s1gxa +.section s1gxb +.section s1gya +.section s1gyb +.section s1gza +.section s1gzb +.section s1g1a +.section s1g1b +.section s1g2a +.section s1g2b +.section s1g3a +.section s1g3b +.section s1g4a +.section s1g4b +.section s1g5a +.section s1g5b +.section s1g6a +.section s1g6b +.section s1g7a +.section s1g7b +.section s1g8a +.section s1g8b +.section s1g9a +.section s1g9b +.section s1g0a +.section s1g0b +.section s1haa +.section s1hab +.section s1hba +.section s1hbb +.section s1hca +.section s1hcb +.section s1hda +.section s1hdb +.section s1hea +.section s1heb +.section s1hfa +.section s1hfb +.section s1hga +.section s1hgb +.section s1hha +.section s1hhb +.section s1hia +.section s1hib +.section s1hja +.section s1hjb +.section s1hka +.section s1hkb +.section s1hla +.section s1hlb +.section s1hma +.section s1hmb +.section s1hna +.section s1hnb +.section s1hoa +.section s1hob +.section s1hpa +.section s1hpb +.section s1hqa +.section s1hqb +.section s1hra +.section s1hrb +.section s1hsa +.section s1hsb +.section s1hta +.section s1htb +.section s1hua +.section s1hub +.section s1hva +.section s1hvb +.section s1hwa +.section s1hwb +.section s1hxa +.section s1hxb +.section s1hya +.section s1hyb +.section s1hza +.section s1hzb +.section s1h1a +.section s1h1b +.section s1h2a +.section s1h2b +.section s1h3a +.section s1h3b +.section s1h4a +.section s1h4b +.section s1h5a +.section s1h5b +.section s1h6a +.section s1h6b +.section s1h7a +.section s1h7b +.section s1h8a +.section s1h8b +.section s1h9a +.section s1h9b +.section s1h0a +.section s1h0b +.section s1iaa +.section s1iab +.section s1iba +.section s1ibb +.section s1ica +.section s1icb +.section s1ida +.section s1idb +.section s1iea +.section s1ieb +.section s1ifa +.section s1ifb +.section s1iga +.section s1igb +.section s1iha +.section s1ihb +.section s1iia +.section s1iib +.section s1ija +.section s1ijb +.section s1ika +.section s1ikb +.section s1ila +.section s1ilb +.section s1ima +.section s1imb +.section s1ina +.section s1inb +.section s1ioa +.section s1iob +.section s1ipa +.section s1ipb +.section s1iqa +.section s1iqb +.section s1ira +.section s1irb +.section s1isa +.section s1isb +.section s1ita +.section s1itb +.section s1iua +.section s1iub +.section s1iva +.section s1ivb +.section s1iwa +.section s1iwb +.section s1ixa +.section s1ixb +.section s1iya +.section s1iyb +.section s1iza +.section s1izb +.section s1i1a +.section s1i1b +.section s1i2a +.section s1i2b +.section s1i3a +.section s1i3b +.section s1i4a +.section s1i4b +.section s1i5a +.section s1i5b +.section s1i6a +.section s1i6b +.section s1i7a +.section s1i7b +.section s1i8a +.section s1i8b +.section s1i9a +.section s1i9b +.section s1i0a +.section s1i0b +.section s1jaa +.section s1jab +.section s1jba +.section s1jbb +.section s1jca +.section s1jcb +.section s1jda +.section s1jdb +.section s1jea +.section s1jeb +.section s1jfa +.section s1jfb +.section s1jga +.section s1jgb +.section s1jha +.section s1jhb +.section s1jia +.section s1jib +.section s1jja +.section s1jjb +.section s1jka +.section s1jkb +.section s1jla +.section s1jlb +.section s1jma +.section s1jmb +.section s1jna +.section s1jnb +.section s1joa +.section s1job +.section s1jpa +.section s1jpb +.section s1jqa +.section s1jqb +.section s1jra +.section s1jrb +.section s1jsa +.section s1jsb +.section s1jta +.section s1jtb +.section s1jua +.section s1jub +.section s1jva +.section s1jvb +.section s1jwa +.section s1jwb +.section s1jxa +.section s1jxb +.section s1jya +.section s1jyb +.section s1jza +.section s1jzb +.section s1j1a +.section s1j1b +.section s1j2a +.section s1j2b +.section s1j3a +.section s1j3b +.section s1j4a +.section s1j4b +.section s1j5a +.section s1j5b +.section s1j6a +.section s1j6b +.section s1j7a +.section s1j7b +.section s1j8a +.section s1j8b +.section s1j9a +.section s1j9b +.section s1j0a +.section s1j0b +.section s1kaa +.section s1kab +.section s1kba +.section s1kbb +.section s1kca +.section s1kcb +.section s1kda +.section s1kdb +.section s1kea +.section s1keb +.section s1kfa +.section s1kfb +.section s1kga +.section s1kgb +.section s1kha +.section s1khb +.section s1kia +.section s1kib +.section s1kja +.section s1kjb +.section s1kka +.section s1kkb +.section s1kla +.section s1klb +.section s1kma +.section s1kmb +.section s1kna +.section s1knb +.section s1koa +.section s1kob +.section s1kpa +.section s1kpb +.section s1kqa +.section s1kqb +.section s1kra +.section s1krb +.section s1ksa +.section s1ksb +.section s1kta +.section s1ktb +.section s1kua +.section s1kub +.section s1kva +.section s1kvb +.section s1kwa +.section s1kwb +.section s1kxa +.section s1kxb +.section s1kya +.section s1kyb +.section s1kza +.section s1kzb +.section s1k1a +.section s1k1b +.section s1k2a +.section s1k2b +.section s1k3a +.section s1k3b +.section s1k4a +.section s1k4b +.section s1k5a +.section s1k5b +.section s1k6a +.section s1k6b +.section s1k7a +.section s1k7b +.section s1k8a +.section s1k8b +.section s1k9a +.section s1k9b +.section s1k0a +.section s1k0b +.section s1laa +.section s1lab +.section s1lba +.section s1lbb +.section s1lca +.section s1lcb +.section s1lda +.section s1ldb +.section s1lea +.section s1leb +.section s1lfa +.section s1lfb +.section s1lga +.section s1lgb +.section s1lha +.section s1lhb +.section s1lia +.section s1lib +.section s1lja +.section s1ljb +.section s1lka +.section s1lkb +.section s1lla +.section s1llb +.section s1lma +.section s1lmb +.section s1lna +.section s1lnb +.section s1loa +.section s1lob +.section s1lpa +.section s1lpb +.section s1lqa +.section s1lqb +.section s1lra +.section s1lrb +.section s1lsa +.section s1lsb +.section s1lta +.section s1ltb +.section s1lua +.section s1lub +.section s1lva +.section s1lvb +.section s1lwa +.section s1lwb +.section s1lxa +.section s1lxb +.section s1lya +.section s1lyb +.section s1lza +.section s1lzb +.section s1l1a +.section s1l1b +.section s1l2a +.section s1l2b +.section s1l3a +.section s1l3b +.section s1l4a +.section s1l4b +.section s1l5a +.section s1l5b +.section s1l6a +.section s1l6b +.section s1l7a +.section s1l7b +.section s1l8a +.section s1l8b +.section s1l9a +.section s1l9b +.section s1l0a +.section s1l0b +.section s1maa +.section s1mab +.section s1mba +.section s1mbb +.section s1mca +.section s1mcb +.section s1mda +.section s1mdb +.section s1mea +.section s1meb +.section s1mfa +.section s1mfb +.section s1mga +.section s1mgb +.section s1mha +.section s1mhb +.section s1mia +.section s1mib +.section s1mja +.section s1mjb +.section s1mka +.section s1mkb +.section s1mla +.section s1mlb +.section s1mma +.section s1mmb +.section s1mna +.section s1mnb +.section s1moa +.section s1mob +.section s1mpa +.section s1mpb +.section s1mqa +.section s1mqb +.section s1mra +.section s1mrb +.section s1msa +.section s1msb +.section s1mta +.section s1mtb +.section s1mua +.section s1mub +.section s1mva +.section s1mvb +.section s1mwa +.section s1mwb +.section s1mxa +.section s1mxb +.section s1mya +.section s1myb +.section s1mza +.section s1mzb +.section s1m1a +.section s1m1b +.section s1m2a +.section s1m2b +.section s1m3a +.section s1m3b +.section s1m4a +.section s1m4b +.section s1m5a +.section s1m5b +.section s1m6a +.section s1m6b +.section s1m7a +.section s1m7b +.section s1m8a +.section s1m8b +.section s1m9a +.section s1m9b +.section s1m0a +.section s1m0b +.section s1naa +.section s1nab +.section s1nba +.section s1nbb +.section s1nca +.section s1ncb +.section s1nda +.section s1ndb +.section s1nea +.section s1neb +.section s1nfa +.section s1nfb +.section s1nga +.section s1ngb +.section s1nha +.section s1nhb +.section s1nia +.section s1nib +.section s1nja +.section s1njb +.section s1nka +.section s1nkb +.section s1nla +.section s1nlb +.section s1nma +.section s1nmb +.section s1nna +.section s1nnb +.section s1noa +.section s1nob +.section s1npa +.section s1npb +.section s1nqa +.section s1nqb +.section s1nra +.section s1nrb +.section s1nsa +.section s1nsb +.section s1nta +.section s1ntb +.section s1nua +.section s1nub +.section s1nva +.section s1nvb +.section s1nwa +.section s1nwb +.section s1nxa +.section s1nxb +.section s1nya +.section s1nyb +.section s1nza +.section s1nzb +.section s1n1a +.section s1n1b +.section s1n2a +.section s1n2b +.section s1n3a +.section s1n3b +.section s1n4a +.section s1n4b +.section s1n5a +.section s1n5b +.section s1n6a +.section s1n6b +.section s1n7a +.section s1n7b +.section s1n8a +.section s1n8b +.section s1n9a +.section s1n9b +.section s1n0a +.section s1n0b +.section s1oaa +.section s1oab +.section s1oba +.section s1obb +.section s1oca +.section s1ocb +.section s1oda +.section s1odb +.section s1oea +.section s1oeb +.section s1ofa +.section s1ofb +.section s1oga +.section s1ogb +.section s1oha +.section s1ohb +.section s1oia +.section s1oib +.section s1oja +.section s1ojb +.section s1oka +.section s1okb +.section s1ola +.section s1olb +.section s1oma +.section s1omb +.section s1ona +.section s1onb +.section s1ooa +.section s1oob +.section s1opa +.section s1opb +.section s1oqa +.section s1oqb +.section s1ora +.section s1orb +.section s1osa +.section s1osb +.section s1ota +.section s1otb +.section s1oua +.section s1oub +.section s1ova +.section s1ovb +.section s1owa +.section s1owb +.section s1oxa +.section s1oxb +.section s1oya +.section s1oyb +.section s1oza +.section s1ozb +.section s1o1a +.section s1o1b +.section s1o2a +.section s1o2b +.section s1o3a +.section s1o3b +.section s1o4a +.section s1o4b +.section s1o5a +.section s1o5b +.section s1o6a +.section s1o6b +.section s1o7a +.section s1o7b +.section s1o8a +.section s1o8b +.section s1o9a +.section s1o9b +.section s1o0a +.section s1o0b +.section s1paa +.section s1pab +.section s1pba +.section s1pbb +.section s1pca +.section s1pcb +.section s1pda +.section s1pdb +.section s1pea +.section s1peb +.section s1pfa +.section s1pfb +.section s1pga +.section s1pgb +.section s1pha +.section s1phb +.section s1pia +.section s1pib +.section s1pja +.section s1pjb +.section s1pka +.section s1pkb +.section s1pla +.section s1plb +.section s1pma +.section s1pmb +.section s1pna +.section s1pnb +.section s1poa +.section s1pob +.section s1ppa +.section s1ppb +.section s1pqa +.section s1pqb +.section s1pra +.section s1prb +.section s1psa +.section s1psb +.section s1pta +.section s1ptb +.section s1pua +.section s1pub +.section s1pva +.section s1pvb +.section s1pwa +.section s1pwb +.section s1pxa +.section s1pxb +.section s1pya +.section s1pyb +.section s1pza +.section s1pzb +.section s1p1a +.section s1p1b +.section s1p2a +.section s1p2b +.section s1p3a +.section s1p3b +.section s1p4a +.section s1p4b +.section s1p5a +.section s1p5b +.section s1p6a +.section s1p6b +.section s1p7a +.section s1p7b +.section s1p8a +.section s1p8b +.section s1p9a +.section s1p9b +.section s1p0a +.section s1p0b +.section s1qaa +.section s1qab +.section s1qba +.section s1qbb +.section s1qca +.section s1qcb +.section s1qda +.section s1qdb +.section s1qea +.section s1qeb +.section s1qfa +.section s1qfb +.section s1qga +.section s1qgb +.section s1qha +.section s1qhb +.section s1qia +.section s1qib +.section s1qja +.section s1qjb +.section s1qka +.section s1qkb +.section s1qla +.section s1qlb +.section s1qma +.section s1qmb +.section s1qna +.section s1qnb +.section s1qoa +.section s1qob +.section s1qpa +.section s1qpb +.section s1qqa +.section s1qqb +.section s1qra +.section s1qrb +.section s1qsa +.section s1qsb +.section s1qta +.section s1qtb +.section s1qua +.section s1qub +.section s1qva +.section s1qvb +.section s1qwa +.section s1qwb +.section s1qxa +.section s1qxb +.section s1qya +.section s1qyb +.section s1qza +.section s1qzb +.section s1q1a +.section s1q1b +.section s1q2a +.section s1q2b +.section s1q3a +.section s1q3b +.section s1q4a +.section s1q4b +.section s1q5a +.section s1q5b +.section s1q6a +.section s1q6b +.section s1q7a +.section s1q7b +.section s1q8a +.section s1q8b +.section s1q9a +.section s1q9b +.section s1q0a +.section s1q0b +.section s1raa +.section s1rab +.section s1rba +.section s1rbb +.section s1rca +.section s1rcb +.section s1rda +.section s1rdb +.section s1rea +.section s1reb +.section s1rfa +.section s1rfb +.section s1rga +.section s1rgb +.section s1rha +.section s1rhb +.section s1ria +.section s1rib +.section s1rja +.section s1rjb +.section s1rka +.section s1rkb +.section s1rla +.section s1rlb +.section s1rma +.section s1rmb +.section s1rna +.section s1rnb +.section s1roa +.section s1rob +.section s1rpa +.section s1rpb +.section s1rqa +.section s1rqb +.section s1rra +.section s1rrb +.section s1rsa +.section s1rsb +.section s1rta +.section s1rtb +.section s1rua +.section s1rub +.section s1rva +.section s1rvb +.section s1rwa +.section s1rwb +.section s1rxa +.section s1rxb +.section s1rya +.section s1ryb +.section s1rza +.section s1rzb +.section s1r1a +.section s1r1b +.section s1r2a +.section s1r2b +.section s1r3a +.section s1r3b +.section s1r4a +.section s1r4b +.section s1r5a +.section s1r5b +.section s1r6a +.section s1r6b +.section s1r7a +.section s1r7b +.section s1r8a +.section s1r8b +.section s1r9a +.section s1r9b +.section s1r0a +.section s1r0b +.section s1saa +.section s1sab +.section s1sba +.section s1sbb +.section s1sca +.section s1scb +.section s1sda +.section s1sdb +.section s1sea +.section s1seb +.section s1sfa +.section s1sfb +.section s1sga +.section s1sgb +.section s1sha +.section s1shb +.section s1sia +.section s1sib +.section s1sja +.section s1sjb +.section s1ska +.section s1skb +.section s1sla +.section s1slb +.section s1sma +.section s1smb +.section s1sna +.section s1snb +.section s1soa +.section s1sob +.section s1spa +.section s1spb +.section s1sqa +.section s1sqb +.section s1sra +.section s1srb +.section s1ssa +.section s1ssb +.section s1sta +.section s1stb +.section s1sua +.section s1sub +.section s1sva +.section s1svb +.section s1swa +.section s1swb +.section s1sxa +.section s1sxb +.section s1sya +.section s1syb +.section s1sza +.section s1szb +.section s1s1a +.section s1s1b +.section s1s2a +.section s1s2b +.section s1s3a +.section s1s3b +.section s1s4a +.section s1s4b +.section s1s5a +.section s1s5b +.section s1s6a +.section s1s6b +.section s1s7a +.section s1s7b +.section s1s8a +.section s1s8b +.section s1s9a +.section s1s9b +.section s1s0a +.section s1s0b +.section s1taa +.section s1tab +.section s1tba +.section s1tbb +.section s1tca +.section s1tcb +.section s1tda +.section s1tdb +.section s1tea +.section s1teb +.section s1tfa +.section s1tfb +.section s1tga +.section s1tgb +.section s1tha +.section s1thb +.section s1tia +.section s1tib +.section s1tja +.section s1tjb +.section s1tka +.section s1tkb +.section s1tla +.section s1tlb +.section s1tma +.section s1tmb +.section s1tna +.section s1tnb +.section s1toa +.section s1tob +.section s1tpa +.section s1tpb +.section s1tqa +.section s1tqb +.section s1tra +.section s1trb +.section s1tsa +.section s1tsb +.section s1tta +.section s1ttb +.section s1tua +.section s1tub +.section s1tva +.section s1tvb +.section s1twa +.section s1twb +.section s1txa +.section s1txb +.section s1tya +.section s1tyb +.section s1tza +.section s1tzb +.section s1t1a +.section s1t1b +.section s1t2a +.section s1t2b +.section s1t3a +.section s1t3b +.section s1t4a +.section s1t4b +.section s1t5a +.section s1t5b +.section s1t6a +.section s1t6b +.section s1t7a +.section s1t7b +.section s1t8a +.section s1t8b +.section s1t9a +.section s1t9b +.section s1t0a +.section s1t0b +.section s1uaa +.section s1uab +.section s1uba +.section s1ubb +.section s1uca +.section s1ucb +.section s1uda +.section s1udb +.section s1uea +.section s1ueb +.section s1ufa +.section s1ufb +.section s1uga +.section s1ugb +.section s1uha +.section s1uhb +.section s1uia +.section s1uib +.section s1uja +.section s1ujb +.section s1uka +.section s1ukb +.section s1ula +.section s1ulb +.section s1uma +.section s1umb +.section s1una +.section s1unb +.section s1uoa +.section s1uob +.section s1upa +.section s1upb +.section s1uqa +.section s1uqb +.section s1ura +.section s1urb +.section s1usa +.section s1usb +.section s1uta +.section s1utb +.section s1uua +.section s1uub +.section s1uva +.section s1uvb +.section s1uwa +.section s1uwb +.section s1uxa +.section s1uxb +.section s1uya +.section s1uyb +.section s1uza +.section s1uzb +.section s1u1a +.section s1u1b +.section s1u2a +.section s1u2b +.section s1u3a +.section s1u3b +.section s1u4a +.section s1u4b +.section s1u5a +.section s1u5b +.section s1u6a +.section s1u6b +.section s1u7a +.section s1u7b +.section s1u8a +.section s1u8b +.section s1u9a +.section s1u9b +.section s1u0a +.section s1u0b +.section s1vaa +.section s1vab +.section s1vba +.section s1vbb +.section s1vca +.section s1vcb +.section s1vda +.section s1vdb +.section s1vea +.section s1veb +.section s1vfa +.section s1vfb +.section s1vga +.section s1vgb +.section s1vha +.section s1vhb +.section s1via +.section s1vib +.section s1vja +.section s1vjb +.section s1vka +.section s1vkb +.section s1vla +.section s1vlb +.section s1vma +.section s1vmb +.section s1vna +.section s1vnb +.section s1voa +.section s1vob +.section s1vpa +.section s1vpb +.section s1vqa +.section s1vqb +.section s1vra +.section s1vrb +.section s1vsa +.section s1vsb +.section s1vta +.section s1vtb +.section s1vua +.section s1vub +.section s1vva +.section s1vvb +.section s1vwa +.section s1vwb +.section s1vxa +.section s1vxb +.section s1vya +.section s1vyb +.section s1vza +.section s1vzb +.section s1v1a +.section s1v1b +.section s1v2a +.section s1v2b +.section s1v3a +.section s1v3b +.section s1v4a +.section s1v4b +.section s1v5a +.section s1v5b +.section s1v6a +.section s1v6b +.section s1v7a +.section s1v7b +.section s1v8a +.section s1v8b +.section s1v9a +.section s1v9b +.section s1v0a +.section s1v0b +.section s1waa +.section s1wab +.section s1wba +.section s1wbb +.section s1wca +.section s1wcb +.section s1wda +.section s1wdb +.section s1wea +.section s1web +.section s1wfa +.section s1wfb +.section s1wga +.section s1wgb +.section s1wha +.section s1whb +.section s1wia +.section s1wib +.section s1wja +.section s1wjb +.section s1wka +.section s1wkb +.section s1wla +.section s1wlb +.section s1wma +.section s1wmb +.section s1wna +.section s1wnb +.section s1woa +.section s1wob +.section s1wpa +.section s1wpb +.section s1wqa +.section s1wqb +.section s1wra +.section s1wrb +.section s1wsa +.section s1wsb +.section s1wta +.section s1wtb +.section s1wua +.section s1wub +.section s1wva +.section s1wvb +.section s1wwa +.section s1wwb +.section s1wxa +.section s1wxb +.section s1wya +.section s1wyb +.section s1wza +.section s1wzb +.section s1w1a +.section s1w1b +.section s1w2a +.section s1w2b +.section s1w3a +.section s1w3b +.section s1w4a +.section s1w4b +.section s1w5a +.section s1w5b +.section s1w6a +.section s1w6b +.section s1w7a +.section s1w7b +.section s1w8a +.section s1w8b +.section s1w9a +.section s1w9b +.section s1w0a +.section s1w0b +.section s1xaa +.section s1xab +.section s1xba +.section s1xbb +.section s1xca +.section s1xcb +.section s1xda +.section s1xdb +.section s1xea +.section s1xeb +.section s1xfa +.section s1xfb +.section s1xga +.section s1xgb +.section s1xha +.section s1xhb +.section s1xia +.section s1xib +.section s1xja +.section s1xjb +.section s1xka +.section s1xkb +.section s1xla +.section s1xlb +.section s1xma +.section s1xmb +.section s1xna +.section s1xnb +.section s1xoa +.section s1xob +.section s1xpa +.section s1xpb +.section s1xqa +.section s1xqb +.section s1xra +.section s1xrb +.section s1xsa +.section s1xsb +.section s1xta +.section s1xtb +.section s1xua +.section s1xub +.section s1xva +.section s1xvb +.section s1xwa +.section s1xwb +.section s1xxa +.section s1xxb +.section s1xya +.section s1xyb +.section s1xza +.section s1xzb +.section s1x1a +.section s1x1b +.section s1x2a +.section s1x2b +.section s1x3a +.section s1x3b +.section s1x4a +.section s1x4b +.section s1x5a +.section s1x5b +.section s1x6a +.section s1x6b +.section s1x7a +.section s1x7b +.section s1x8a +.section s1x8b +.section s1x9a +.section s1x9b +.section s1x0a +.section s1x0b +.section s1yaa +.section s1yab +.section s1yba +.section s1ybb +.section s1yca +.section s1ycb +.section s1yda +.section s1ydb +.section s1yea +.section s1yeb +.section s1yfa +.section s1yfb +.section s1yga +.section s1ygb +.section s1yha +.section s1yhb +.section s1yia +.section s1yib +.section s1yja +.section s1yjb +.section s1yka +.section s1ykb +.section s1yla +.section s1ylb +.section s1yma +.section s1ymb +.section s1yna +.section s1ynb +.section s1yoa +.section s1yob +.section s1ypa +.section s1ypb +.section s1yqa +.section s1yqb +.section s1yra +.section s1yrb +.section s1ysa +.section s1ysb +.section s1yta +.section s1ytb +.section s1yua +.section s1yub +.section s1yva +.section s1yvb +.section s1ywa +.section s1ywb +.section s1yxa +.section s1yxb +.section s1yya +.section s1yyb +.section s1yza +.section s1yzb +.section s1y1a +.section s1y1b +.section s1y2a +.section s1y2b +.section s1y3a +.section s1y3b +.section s1y4a +.section s1y4b +.section s1y5a +.section s1y5b +.section s1y6a +.section s1y6b +.section s1y7a +.section s1y7b +.section s1y8a +.section s1y8b +.section s1y9a +.section s1y9b +.section s1y0a +.section s1y0b +.section s1zaa +.section s1zab +.section s1zba +.section s1zbb +.section s1zca +.section s1zcb +.section s1zda +.section s1zdb +.section s1zea +.section s1zeb +.section s1zfa +.section s1zfb +.section s1zga +.section s1zgb +.section s1zha +.section s1zhb +.section s1zia +.section s1zib +.section s1zja +.section s1zjb +.section s1zka +.section s1zkb +.section s1zla +.section s1zlb +.section s1zma +.section s1zmb +.section s1zna +.section s1znb +.section s1zoa +.section s1zob +.section s1zpa +.section s1zpb +.section s1zqa +.section s1zqb +.section s1zra +.section s1zrb +.section s1zsa +.section s1zsb +.section s1zta +.section s1ztb +.section s1zua +.section s1zub +.section s1zva +.section s1zvb +.section s1zwa +.section s1zwb +.section s1zxa +.section s1zxb +.section s1zya +.section s1zyb +.section s1zza +.section s1zzb +.section s1z1a +.section s1z1b +.section s1z2a +.section s1z2b +.section s1z3a +.section s1z3b +.section s1z4a +.section s1z4b +.section s1z5a +.section s1z5b +.section s1z6a +.section s1z6b +.section s1z7a +.section s1z7b +.section s1z8a +.section s1z8b +.section s1z9a +.section s1z9b +.section s1z0a +.section s1z0b +.section s11aa +.section s11ab +.section s11ba +.section s11bb +.section s11ca +.section s11cb +.section s11da +.section s11db +.section s11ea +.section s11eb +.section s11fa +.section s11fb +.section s11ga +.section s11gb +.section s11ha +.section s11hb +.section s11ia +.section s11ib +.section s11ja +.section s11jb +.section s11ka +.section s11kb +.section s11la +.section s11lb +.section s11ma +.section s11mb +.section s11na +.section s11nb +.section s11oa +.section s11ob +.section s11pa +.section s11pb +.section s11qa +.section s11qb +.section s11ra +.section s11rb +.section s11sa +.section s11sb +.section s11ta +.section s11tb +.section s11ua +.section s11ub +.section s11va +.section s11vb +.section s11wa +.section s11wb +.section s11xa +.section s11xb +.section s11ya +.section s11yb +.section s11za +.section s11zb +.section s111a +.section s111b +.section s112a +.section s112b +.section s113a +.section s113b +.section s114a +.section s114b +.section s115a +.section s115b +.section s116a +.section s116b +.section s117a +.section s117b +.section s118a +.section s118b +.section s119a +.section s119b +.section s110a +.section s110b +.section s12aa +.section s12ab +.section s12ba +.section s12bb +.section s12ca +.section s12cb +.section s12da +.section s12db +.section s12ea +.section s12eb +.section s12fa +.section s12fb +.section s12ga +.section s12gb +.section s12ha +.section s12hb +.section s12ia +.section s12ib +.section s12ja +.section s12jb +.section s12ka +.section s12kb +.section s12la +.section s12lb +.section s12ma +.section s12mb +.section s12na +.section s12nb +.section s12oa +.section s12ob +.section s12pa +.section s12pb +.section s12qa +.section s12qb +.section s12ra +.section s12rb +.section s12sa +.section s12sb +.section s12ta +.section s12tb +.section s12ua +.section s12ub +.section s12va +.section s12vb +.section s12wa +.section s12wb +.section s12xa +.section s12xb +.section s12ya +.section s12yb +.section s12za +.section s12zb +.section s121a +.section s121b +.section s122a +.section s122b +.section s123a +.section s123b +.section s124a +.section s124b +.section s125a +.section s125b +.section s126a +.section s126b +.section s127a +.section s127b +.section s128a +.section s128b +.section s129a +.section s129b +.section s120a +.section s120b +.section s13aa +.section s13ab +.section s13ba +.section s13bb +.section s13ca +.section s13cb +.section s13da +.section s13db +.section s13ea +.section s13eb +.section s13fa +.section s13fb +.section s13ga +.section s13gb +.section s13ha +.section s13hb +.section s13ia +.section s13ib +.section s13ja +.section s13jb +.section s13ka +.section s13kb +.section s13la +.section s13lb +.section s13ma +.section s13mb +.section s13na +.section s13nb +.section s13oa +.section s13ob +.section s13pa +.section s13pb +.section s13qa +.section s13qb +.section s13ra +.section s13rb +.section s13sa +.section s13sb +.section s13ta +.section s13tb +.section s13ua +.section s13ub +.section s13va +.section s13vb +.section s13wa +.section s13wb +.section s13xa +.section s13xb +.section s13ya +.section s13yb +.section s13za +.section s13zb +.section s131a +.section s131b +.section s132a +.section s132b +.section s133a +.section s133b +.section s134a +.section s134b +.section s135a +.section s135b +.section s136a +.section s136b +.section s137a +.section s137b +.section s138a +.section s138b +.section s139a +.section s139b +.section s130a +.section s130b +.section s14aa +.section s14ab +.section s14ba +.section s14bb +.section s14ca +.section s14cb +.section s14da +.section s14db +.section s14ea +.section s14eb +.section s14fa +.section s14fb +.section s14ga +.section s14gb +.section s14ha +.section s14hb +.section s14ia +.section s14ib +.section s14ja +.section s14jb +.section s14ka +.section s14kb +.section s14la +.section s14lb +.section s14ma +.section s14mb +.section s14na +.section s14nb +.section s14oa +.section s14ob +.section s14pa +.section s14pb +.section s14qa +.section s14qb +.section s14ra +.section s14rb +.section s14sa +.section s14sb +.section s14ta +.section s14tb +.section s14ua +.section s14ub +.section s14va +.section s14vb +.section s14wa +.section s14wb +.section s14xa +.section s14xb +.section s14ya +.section s14yb +.section s14za +.section s14zb +.section s141a +.section s141b +.section s142a +.section s142b +.section s143a +.section s143b +.section s144a +.section s144b +.section s145a +.section s145b +.section s146a +.section s146b +.section s147a +.section s147b +.section s148a +.section s148b +.section s149a +.section s149b +.section s140a +.section s140b +.section s15aa +.section s15ab +.section s15ba +.section s15bb +.section s15ca +.section s15cb +.section s15da +.section s15db +.section s15ea +.section s15eb +.section s15fa +.section s15fb +.section s15ga +.section s15gb +.section s15ha +.section s15hb +.section s15ia +.section s15ib +.section s15ja +.section s15jb +.section s15ka +.section s15kb +.section s15la +.section s15lb +.section s15ma +.section s15mb +.section s15na +.section s15nb +.section s15oa +.section s15ob +.section s15pa +.section s15pb +.section s15qa +.section s15qb +.section s15ra +.section s15rb +.section s15sa +.section s15sb +.section s15ta +.section s15tb +.section s15ua +.section s15ub +.section s15va +.section s15vb +.section s15wa +.section s15wb +.section s15xa +.section s15xb +.section s15ya +.section s15yb +.section s15za +.section s15zb +.section s151a +.section s151b +.section s152a +.section s152b +.section s153a +.section s153b +.section s154a +.section s154b +.section s155a +.section s155b +.section s156a +.section s156b +.section s157a +.section s157b +.section s158a +.section s158b +.section s159a +.section s159b +.section s150a +.section s150b +.section s16aa +.section s16ab +.section s16ba +.section s16bb +.section s16ca +.section s16cb +.section s16da +.section s16db +.section s16ea +.section s16eb +.section s16fa +.section s16fb +.section s16ga +.section s16gb +.section s16ha +.section s16hb +.section s16ia +.section s16ib +.section s16ja +.section s16jb +.section s16ka +.section s16kb +.section s16la +.section s16lb +.section s16ma +.section s16mb +.section s16na +.section s16nb +.section s16oa +.section s16ob +.section s16pa +.section s16pb +.section s16qa +.section s16qb +.section s16ra +.section s16rb +.section s16sa +.section s16sb +.section s16ta +.section s16tb +.section s16ua +.section s16ub +.section s16va +.section s16vb +.section s16wa +.section s16wb +.section s16xa +.section s16xb +.section s16ya +.section s16yb +.section s16za +.section s16zb +.section s161a +.section s161b +.section s162a +.section s162b +.section s163a +.section s163b +.section s164a +.section s164b +.section s165a +.section s165b +.section s166a +.section s166b +.section s167a +.section s167b +.section s168a +.section s168b +.section s169a +.section s169b +.section s160a +.section s160b +.section s17aa +.section s17ab +.section s17ba +.section s17bb +.section s17ca +.section s17cb +.section s17da +.section s17db +.section s17ea +.section s17eb +.section s17fa +.section s17fb +.section s17ga +.section s17gb +.section s17ha +.section s17hb +.section s17ia +.section s17ib +.section s17ja +.section s17jb +.section s17ka +.section s17kb +.section s17la +.section s17lb +.section s17ma +.section s17mb +.section s17na +.section s17nb +.section s17oa +.section s17ob +.section s17pa +.section s17pb +.section s17qa +.section s17qb +.section s17ra +.section s17rb +.section s17sa +.section s17sb +.section s17ta +.section s17tb +.section s17ua +.section s17ub +.section s17va +.section s17vb +.section s17wa +.section s17wb +.section s17xa +.section s17xb +.section s17ya +.section s17yb +.section s17za +.section s17zb +.section s171a +.section s171b +.section s172a +.section s172b +.section s173a +.section s173b +.section s174a +.section s174b +.section s175a +.section s175b +.section s176a +.section s176b +.section s177a +.section s177b +.section s178a +.section s178b +.section s179a +.section s179b +.section s170a +.section s170b +.section s18aa +.section s18ab +.section s18ba +.section s18bb +.section s18ca +.section s18cb +.section s18da +.section s18db +.section s18ea +.section s18eb +.section s18fa +.section s18fb +.section s18ga +.section s18gb +.section s18ha +.section s18hb +.section s18ia +.section s18ib +.section s18ja +.section s18jb +.section s18ka +.section s18kb +.section s18la +.section s18lb +.section s18ma +.section s18mb +.section s18na +.section s18nb +.section s18oa +.section s18ob +.section s18pa +.section s18pb +.section s18qa +.section s18qb +.section s18ra +.section s18rb +.section s18sa +.section s18sb +.section s18ta +.section s18tb +.section s18ua +.section s18ub +.section s18va +.section s18vb +.section s18wa +.section s18wb +.section s18xa +.section s18xb +.section s18ya +.section s18yb +.section s18za +.section s18zb +.section s181a +.section s181b +.section s182a +.section s182b +.section s183a +.section s183b +.section s184a +.section s184b +.section s185a +.section s185b +.section s186a +.section s186b +.section s187a +.section s187b +.section s188a +.section s188b +.section s189a +.section s189b +.section s180a +.section s180b +.section s19aa +.section s19ab +.section s19ba +.section s19bb +.section s19ca +.section s19cb +.section s19da +.section s19db +.section s19ea +.section s19eb +.section s19fa +.section s19fb +.section s19ga +.section s19gb +.section s19ha +.section s19hb +.section s19ia +.section s19ib +.section s19ja +.section s19jb +.section s19ka +.section s19kb +.section s19la +.section s19lb +.section s19ma +.section s19mb +.section s19na +.section s19nb +.section s19oa +.section s19ob +.section s19pa +.section s19pb +.section s19qa +.section s19qb +.section s19ra +.section s19rb +.section s19sa +.section s19sb +.section s19ta +.section s19tb +.section s19ua +.section s19ub +.section s19va +.section s19vb +.section s19wa +.section s19wb +.section s19xa +.section s19xb +.section s19ya +.section s19yb +.section s19za +.section s19zb +.section s191a +.section s191b +.section s192a +.section s192b +.section s193a +.section s193b +.section s194a +.section s194b +.section s195a +.section s195b +.section s196a +.section s196b +.section s197a +.section s197b +.section s198a +.section s198b +.section s199a +.section s199b +.section s190a +.section s190b +.section s10aa +.section s10ab +.section s10ba +.section s10bb +.section s10ca +.section s10cb +.section s10da +.section s10db +.section s10ea +.section s10eb +.section s10fa +.section s10fb +.section s10ga +.section s10gb +.section s10ha +.section s10hb +.section s10ia +.section s10ib +.section s10ja +.section s10jb +.section s10ka +.section s10kb +.section s10la +.section s10lb +.section s10ma +.section s10mb +.section s10na +.section s10nb +.section s10oa +.section s10ob +.section s10pa +.section s10pb +.section s10qa +.section s10qb +.section s10ra +.section s10rb +.section s10sa +.section s10sb +.section s10ta +.section s10tb +.section s10ua +.section s10ub +.section s10va +.section s10vb +.section s10wa +.section s10wb +.section s10xa +.section s10xb +.section s10ya +.section s10yb +.section s10za +.section s10zb +.section s101a +.section s101b +.section s102a +.section s102b +.section s103a +.section s103b +.section s104a +.section s104b +.section s105a +.section s105b +.section s106a +.section s106b +.section s107a +.section s107b +.section s108a +.section s108b +.section s109a +.section s109b +.section s100a +.section s100b +.section s2aaa +.section s2aab +.section s2aba +.section s2abb +.section s2aca +.section s2acb +.section s2ada +.section s2adb +.section s2aea +.section s2aeb +.section s2afa +.section s2afb +.section s2aga +.section s2agb +.section s2aha +.section s2ahb +.section s2aia +.section s2aib +.section s2aja +.section s2ajb +.section s2aka +.section s2akb +.section s2ala +.section s2alb +.section s2ama +.section s2amb +.section s2ana +.section s2anb +.section s2aoa +.section s2aob +.section s2apa +.section s2apb +.section s2aqa +.section s2aqb +.section s2ara +.section s2arb +.section s2asa +.section s2asb +.section s2ata +.section s2atb +.section s2aua +.section s2aub +.section s2ava +.section s2avb +.section s2awa +.section s2awb +.section s2axa +.section s2axb +.section s2aya +.section s2ayb +.section s2aza +.section s2azb +.section s2a1a +.section s2a1b +.section s2a2a +.section s2a2b +.section s2a3a +.section s2a3b +.section s2a4a +.section s2a4b +.section s2a5a +.section s2a5b +.section s2a6a +.section s2a6b +.section s2a7a +.section s2a7b +.section s2a8a +.section s2a8b +.section s2a9a +.section s2a9b +.section s2a0a +.section s2a0b +.section s2baa +.section s2bab +.section s2bba +.section s2bbb +.section s2bca +.section s2bcb +.section s2bda +.section s2bdb +.section s2bea +.section s2beb +.section s2bfa +.section s2bfb +.section s2bga +.section s2bgb +.section s2bha +.section s2bhb +.section s2bia +.section s2bib +.section s2bja +.section s2bjb +.section s2bka +.section s2bkb +.section s2bla +.section s2blb +.section s2bma +.section s2bmb +.section s2bna +.section s2bnb +.section s2boa +.section s2bob +.section s2bpa +.section s2bpb +.section s2bqa +.section s2bqb +.section s2bra +.section s2brb +.section s2bsa +.section s2bsb +.section s2bta +.section s2btb +.section s2bua +.section s2bub +.section s2bva +.section s2bvb +.section s2bwa +.section s2bwb +.section s2bxa +.section s2bxb +.section s2bya +.section s2byb +.section s2bza +.section s2bzb +.section s2b1a +.section s2b1b +.section s2b2a +.section s2b2b +.section s2b3a +.section s2b3b +.section s2b4a +.section s2b4b +.section s2b5a +.section s2b5b +.section s2b6a +.section s2b6b +.section s2b7a +.section s2b7b +.section s2b8a +.section s2b8b +.section s2b9a +.section s2b9b +.section s2b0a +.section s2b0b +.section s2caa +.section s2cab +.section s2cba +.section s2cbb +.section s2cca +.section s2ccb +.section s2cda +.section s2cdb +.section s2cea +.section s2ceb +.section s2cfa +.section s2cfb +.section s2cga +.section s2cgb +.section s2cha +.section s2chb +.section s2cia +.section s2cib +.section s2cja +.section s2cjb +.section s2cka +.section s2ckb +.section s2cla +.section s2clb +.section s2cma +.section s2cmb +.section s2cna +.section s2cnb +.section s2coa +.section s2cob +.section s2cpa +.section s2cpb +.section s2cqa +.section s2cqb +.section s2cra +.section s2crb +.section s2csa +.section s2csb +.section s2cta +.section s2ctb +.section s2cua +.section s2cub +.section s2cva +.section s2cvb +.section s2cwa +.section s2cwb +.section s2cxa +.section s2cxb +.section s2cya +.section s2cyb +.section s2cza +.section s2czb +.section s2c1a +.section s2c1b +.section s2c2a +.section s2c2b +.section s2c3a +.section s2c3b +.section s2c4a +.section s2c4b +.section s2c5a +.section s2c5b +.section s2c6a +.section s2c6b +.section s2c7a +.section s2c7b +.section s2c8a +.section s2c8b +.section s2c9a +.section s2c9b +.section s2c0a +.section s2c0b +.section s2daa +.section s2dab +.section s2dba +.section s2dbb +.section s2dca +.section s2dcb +.section s2dda +.section s2ddb +.section s2dea +.section s2deb +.section s2dfa +.section s2dfb +.section s2dga +.section s2dgb +.section s2dha +.section s2dhb +.section s2dia +.section s2dib +.section s2dja +.section s2djb +.section s2dka +.section s2dkb +.section s2dla +.section s2dlb +.section s2dma +.section s2dmb +.section s2dna +.section s2dnb +.section s2doa +.section s2dob +.section s2dpa +.section s2dpb +.section s2dqa +.section s2dqb +.section s2dra +.section s2drb +.section s2dsa +.section s2dsb +.section s2dta +.section s2dtb +.section s2dua +.section s2dub +.section s2dva +.section s2dvb +.section s2dwa +.section s2dwb +.section s2dxa +.section s2dxb +.section s2dya +.section s2dyb +.section s2dza +.section s2dzb +.section s2d1a +.section s2d1b +.section s2d2a +.section s2d2b +.section s2d3a +.section s2d3b +.section s2d4a +.section s2d4b +.section s2d5a +.section s2d5b +.section s2d6a +.section s2d6b +.section s2d7a +.section s2d7b +.section s2d8a +.section s2d8b +.section s2d9a +.section s2d9b +.section s2d0a +.section s2d0b +.section s2eaa +.section s2eab +.section s2eba +.section s2ebb +.section s2eca +.section s2ecb +.section s2eda +.section s2edb +.section s2eea +.section s2eeb +.section s2efa +.section s2efb +.section s2ega +.section s2egb +.section s2eha +.section s2ehb +.section s2eia +.section s2eib +.section s2eja +.section s2ejb +.section s2eka +.section s2ekb +.section s2ela +.section s2elb +.section s2ema +.section s2emb +.section s2ena +.section s2enb +.section s2eoa +.section s2eob +.section s2epa +.section s2epb +.section s2eqa +.section s2eqb +.section s2era +.section s2erb +.section s2esa +.section s2esb +.section s2eta +.section s2etb +.section s2eua +.section s2eub +.section s2eva +.section s2evb +.section s2ewa +.section s2ewb +.section s2exa +.section s2exb +.section s2eya +.section s2eyb +.section s2eza +.section s2ezb +.section s2e1a +.section s2e1b +.section s2e2a +.section s2e2b +.section s2e3a +.section s2e3b +.section s2e4a +.section s2e4b +.section s2e5a +.section s2e5b +.section s2e6a +.section s2e6b +.section s2e7a +.section s2e7b +.section s2e8a +.section s2e8b +.section s2e9a +.section s2e9b +.section s2e0a +.section s2e0b +.section s2faa +.section s2fab +.section s2fba +.section s2fbb +.section s2fca +.section s2fcb +.section s2fda +.section s2fdb +.section s2fea +.section s2feb +.section s2ffa +.section s2ffb +.section s2fga +.section s2fgb +.section s2fha +.section s2fhb +.section s2fia +.section s2fib +.section s2fja +.section s2fjb +.section s2fka +.section s2fkb +.section s2fla +.section s2flb +.section s2fma +.section s2fmb +.section s2fna +.section s2fnb +.section s2foa +.section s2fob +.section s2fpa +.section s2fpb +.section s2fqa +.section s2fqb +.section s2fra +.section s2frb +.section s2fsa +.section s2fsb +.section s2fta +.section s2ftb +.section s2fua +.section s2fub +.section s2fva +.section s2fvb +.section s2fwa +.section s2fwb +.section s2fxa +.section s2fxb +.section s2fya +.section s2fyb +.section s2fza +.section s2fzb +.section s2f1a +.section s2f1b +.section s2f2a +.section s2f2b +.section s2f3a +.section s2f3b +.section s2f4a +.section s2f4b +.section s2f5a +.section s2f5b +.section s2f6a +.section s2f6b +.section s2f7a +.section s2f7b +.section s2f8a +.section s2f8b +.section s2f9a +.section s2f9b +.section s2f0a +.section s2f0b +.section s2gaa +.section s2gab +.section s2gba +.section s2gbb +.section s2gca +.section s2gcb +.section s2gda +.section s2gdb +.section s2gea +.section s2geb +.section s2gfa +.section s2gfb +.section s2gga +.section s2ggb +.section s2gha +.section s2ghb +.section s2gia +.section s2gib +.section s2gja +.section s2gjb +.section s2gka +.section s2gkb +.section s2gla +.section s2glb +.section s2gma +.section s2gmb +.section s2gna +.section s2gnb +.section s2goa +.section s2gob +.section s2gpa +.section s2gpb +.section s2gqa +.section s2gqb +.section s2gra +.section s2grb +.section s2gsa +.section s2gsb +.section s2gta +.section s2gtb +.section s2gua +.section s2gub +.section s2gva +.section s2gvb +.section s2gwa +.section s2gwb +.section s2gxa +.section s2gxb +.section s2gya +.section s2gyb +.section s2gza +.section s2gzb +.section s2g1a +.section s2g1b +.section s2g2a +.section s2g2b +.section s2g3a +.section s2g3b +.section s2g4a +.section s2g4b +.section s2g5a +.section s2g5b +.section s2g6a +.section s2g6b +.section s2g7a +.section s2g7b +.section s2g8a +.section s2g8b +.section s2g9a +.section s2g9b +.section s2g0a +.section s2g0b +.section s2haa +.section s2hab +.section s2hba +.section s2hbb +.section s2hca +.section s2hcb +.section s2hda +.section s2hdb +.section s2hea +.section s2heb +.section s2hfa +.section s2hfb +.section s2hga +.section s2hgb +.section s2hha +.section s2hhb +.section s2hia +.section s2hib +.section s2hja +.section s2hjb +.section s2hka +.section s2hkb +.section s2hla +.section s2hlb +.section s2hma +.section s2hmb +.section s2hna +.section s2hnb +.section s2hoa +.section s2hob +.section s2hpa +.section s2hpb +.section s2hqa +.section s2hqb +.section s2hra +.section s2hrb +.section s2hsa +.section s2hsb +.section s2hta +.section s2htb +.section s2hua +.section s2hub +.section s2hva +.section s2hvb +.section s2hwa +.section s2hwb +.section s2hxa +.section s2hxb +.section s2hya +.section s2hyb +.section s2hza +.section s2hzb +.section s2h1a +.section s2h1b +.section s2h2a +.section s2h2b +.section s2h3a +.section s2h3b +.section s2h4a +.section s2h4b +.section s2h5a +.section s2h5b +.section s2h6a +.section s2h6b +.section s2h7a +.section s2h7b +.section s2h8a +.section s2h8b +.section s2h9a +.section s2h9b +.section s2h0a +.section s2h0b +.section s2iaa +.section s2iab +.section s2iba +.section s2ibb +.section s2ica +.section s2icb +.section s2ida +.section s2idb +.section s2iea +.section s2ieb +.section s2ifa +.section s2ifb +.section s2iga +.section s2igb +.section s2iha +.section s2ihb +.section s2iia +.section s2iib +.section s2ija +.section s2ijb +.section s2ika +.section s2ikb +.section s2ila +.section s2ilb +.section s2ima +.section s2imb +.section s2ina +.section s2inb +.section s2ioa +.section s2iob +.section s2ipa +.section s2ipb +.section s2iqa +.section s2iqb +.section s2ira +.section s2irb +.section s2isa +.section s2isb +.section s2ita +.section s2itb +.section s2iua +.section s2iub +.section s2iva +.section s2ivb +.section s2iwa +.section s2iwb +.section s2ixa +.section s2ixb +.section s2iya +.section s2iyb +.section s2iza +.section s2izb +.section s2i1a +.section s2i1b +.section s2i2a +.section s2i2b +.section s2i3a +.section s2i3b +.section s2i4a +.section s2i4b +.section s2i5a +.section s2i5b +.section s2i6a +.section s2i6b +.section s2i7a +.section s2i7b +.section s2i8a +.section s2i8b +.section s2i9a +.section s2i9b +.section s2i0a +.section s2i0b +.section s2jaa +.section s2jab +.section s2jba +.section s2jbb +.section s2jca +.section s2jcb +.section s2jda +.section s2jdb +.section s2jea +.section s2jeb +.section s2jfa +.section s2jfb +.section s2jga +.section s2jgb +.section s2jha +.section s2jhb +.section s2jia +.section s2jib +.section s2jja +.section s2jjb +.section s2jka +.section s2jkb +.section s2jla +.section s2jlb +.section s2jma +.section s2jmb +.section s2jna +.section s2jnb +.section s2joa +.section s2job +.section s2jpa +.section s2jpb +.section s2jqa +.section s2jqb +.section s2jra +.section s2jrb +.section s2jsa +.section s2jsb +.section s2jta +.section s2jtb +.section s2jua +.section s2jub +.section s2jva +.section s2jvb +.section s2jwa +.section s2jwb +.section s2jxa +.section s2jxb +.section s2jya +.section s2jyb +.section s2jza +.section s2jzb +.section s2j1a +.section s2j1b +.section s2j2a +.section s2j2b +.section s2j3a +.section s2j3b +.section s2j4a +.section s2j4b +.section s2j5a +.section s2j5b +.section s2j6a +.section s2j6b +.section s2j7a +.section s2j7b +.section s2j8a +.section s2j8b +.section s2j9a +.section s2j9b +.section s2j0a +.section s2j0b +.section s2kaa +.section s2kab +.section s2kba +.section s2kbb +.section s2kca +.section s2kcb +.section s2kda +.section s2kdb +.section s2kea +.section s2keb +.section s2kfa +.section s2kfb +.section s2kga +.section s2kgb +.section s2kha +.section s2khb +.section s2kia +.section s2kib +.section s2kja +.section s2kjb +.section s2kka +.section s2kkb +.section s2kla +.section s2klb +.section s2kma +.section s2kmb +.section s2kna +.section s2knb +.section s2koa +.section s2kob +.section s2kpa +.section s2kpb +.section s2kqa +.section s2kqb +.section s2kra +.section s2krb +.section s2ksa +.section s2ksb +.section s2kta +.section s2ktb +.section s2kua +.section s2kub +.section s2kva +.section s2kvb +.section s2kwa +.section s2kwb +.section s2kxa +.section s2kxb +.section s2kya +.section s2kyb +.section s2kza +.section s2kzb +.section s2k1a +.section s2k1b +.section s2k2a +.section s2k2b +.section s2k3a +.section s2k3b +.section s2k4a +.section s2k4b +.section s2k5a +.section s2k5b +.section s2k6a +.section s2k6b +.section s2k7a +.section s2k7b +.section s2k8a +.section s2k8b +.section s2k9a +.section s2k9b +.section s2k0a +.section s2k0b +.section s2laa +.section s2lab +.section s2lba +.section s2lbb +.section s2lca +.section s2lcb +.section s2lda +.section s2ldb +.section s2lea +.section s2leb +.section s2lfa +.section s2lfb +.section s2lga +.section s2lgb +.section s2lha +.section s2lhb +.section s2lia +.section s2lib +.section s2lja +.section s2ljb +.section s2lka +.section s2lkb +.section s2lla +.section s2llb +.section s2lma +.section s2lmb +.section s2lna +.section s2lnb +.section s2loa +.section s2lob +.section s2lpa +.section s2lpb +.section s2lqa +.section s2lqb +.section s2lra +.section s2lrb +.section s2lsa +.section s2lsb +.section s2lta +.section s2ltb +.section s2lua +.section s2lub +.section s2lva +.section s2lvb +.section s2lwa +.section s2lwb +.section s2lxa +.section s2lxb +.section s2lya +.section s2lyb +.section s2lza +.section s2lzb +.section s2l1a +.section s2l1b +.section s2l2a +.section s2l2b +.section s2l3a +.section s2l3b +.section s2l4a +.section s2l4b +.section s2l5a +.section s2l5b +.section s2l6a +.section s2l6b +.section s2l7a +.section s2l7b +.section s2l8a +.section s2l8b +.section s2l9a +.section s2l9b +.section s2l0a +.section s2l0b +.section s2maa +.section s2mab +.section s2mba +.section s2mbb +.section s2mca +.section s2mcb +.section s2mda +.section s2mdb +.section s2mea +.section s2meb +.section s2mfa +.section s2mfb +.section s2mga +.section s2mgb +.section s2mha +.section s2mhb +.section s2mia +.section s2mib +.section s2mja +.section s2mjb +.section s2mka +.section s2mkb +.section s2mla +.section s2mlb +.section s2mma +.section s2mmb +.section s2mna +.section s2mnb +.section s2moa +.section s2mob +.section s2mpa +.section s2mpb +.section s2mqa +.section s2mqb +.section s2mra +.section s2mrb +.section s2msa +.section s2msb +.section s2mta +.section s2mtb +.section s2mua +.section s2mub +.section s2mva +.section s2mvb +.section s2mwa +.section s2mwb +.section s2mxa +.section s2mxb +.section s2mya +.section s2myb +.section s2mza +.section s2mzb +.section s2m1a +.section s2m1b +.section s2m2a +.section s2m2b +.section s2m3a +.section s2m3b +.section s2m4a +.section s2m4b +.section s2m5a +.section s2m5b +.section s2m6a +.section s2m6b +.section s2m7a +.section s2m7b +.section s2m8a +.section s2m8b +.section s2m9a +.section s2m9b +.section s2m0a +.section s2m0b +.section s2naa +.section s2nab +.section s2nba +.section s2nbb +.section s2nca +.section s2ncb +.section s2nda +.section s2ndb +.section s2nea +.section s2neb +.section s2nfa +.section s2nfb +.section s2nga +.section s2ngb +.section s2nha +.section s2nhb +.section s2nia +.section s2nib +.section s2nja +.section s2njb +.section s2nka +.section s2nkb +.section s2nla +.section s2nlb +.section s2nma +.section s2nmb +.section s2nna +.section s2nnb +.section s2noa +.section s2nob +.section s2npa +.section s2npb +.section s2nqa +.section s2nqb +.section s2nra +.section s2nrb +.section s2nsa +.section s2nsb +.section s2nta +.section s2ntb +.section s2nua +.section s2nub +.section s2nva +.section s2nvb +.section s2nwa +.section s2nwb +.section s2nxa +.section s2nxb +.section s2nya +.section s2nyb +.section s2nza +.section s2nzb +.section s2n1a +.section s2n1b +.section s2n2a +.section s2n2b +.section s2n3a +.section s2n3b +.section s2n4a +.section s2n4b +.section s2n5a +.section s2n5b +.section s2n6a +.section s2n6b +.section s2n7a +.section s2n7b +.section s2n8a +.section s2n8b +.section s2n9a +.section s2n9b +.section s2n0a +.section s2n0b +.section s2oaa +.section s2oab +.section s2oba +.section s2obb +.section s2oca +.section s2ocb +.section s2oda +.section s2odb +.section s2oea +.section s2oeb +.section s2ofa +.section s2ofb +.section s2oga +.section s2ogb +.section s2oha +.section s2ohb +.section s2oia +.section s2oib +.section s2oja +.section s2ojb +.section s2oka +.section s2okb +.section s2ola +.section s2olb +.section s2oma +.section s2omb +.section s2ona +.section s2onb +.section s2ooa +.section s2oob +.section s2opa +.section s2opb +.section s2oqa +.section s2oqb +.section s2ora +.section s2orb +.section s2osa +.section s2osb +.section s2ota +.section s2otb +.section s2oua +.section s2oub +.section s2ova +.section s2ovb +.section s2owa +.section s2owb +.section s2oxa +.section s2oxb +.section s2oya +.section s2oyb +.section s2oza +.section s2ozb +.section s2o1a +.section s2o1b +.section s2o2a +.section s2o2b +.section s2o3a +.section s2o3b +.section s2o4a +.section s2o4b +.section s2o5a +.section s2o5b +.section s2o6a +.section s2o6b +.section s2o7a +.section s2o7b +.section s2o8a +.section s2o8b +.section s2o9a +.section s2o9b +.section s2o0a +.section s2o0b +.section s2paa +.section s2pab +.section s2pba +.section s2pbb +.section s2pca +.section s2pcb +.section s2pda +.section s2pdb +.section s2pea +.section s2peb +.section s2pfa +.section s2pfb +.section s2pga +.section s2pgb +.section s2pha +.section s2phb +.section s2pia +.section s2pib +.section s2pja +.section s2pjb +.section s2pka +.section s2pkb +.section s2pla +.section s2plb +.section s2pma +.section s2pmb +.section s2pna +.section s2pnb +.section s2poa +.section s2pob +.section s2ppa +.section s2ppb +.section s2pqa +.section s2pqb +.section s2pra +.section s2prb +.section s2psa +.section s2psb +.section s2pta +.section s2ptb +.section s2pua +.section s2pub +.section s2pva +.section s2pvb +.section s2pwa +.section s2pwb +.section s2pxa +.section s2pxb +.section s2pya +.section s2pyb +.section s2pza +.section s2pzb +.section s2p1a +.section s2p1b +.section s2p2a +.section s2p2b +.section s2p3a +.section s2p3b +.section s2p4a +.section s2p4b +.section s2p5a +.section s2p5b +.section s2p6a +.section s2p6b +.section s2p7a +.section s2p7b +.section s2p8a +.section s2p8b +.section s2p9a +.section s2p9b +.section s2p0a +.section s2p0b +.section s2qaa +.section s2qab +.section s2qba +.section s2qbb +.section s2qca +.section s2qcb +.section s2qda +.section s2qdb +.section s2qea +.section s2qeb +.section s2qfa +.section s2qfb +.section s2qga +.section s2qgb +.section s2qha +.section s2qhb +.section s2qia +.section s2qib +.section s2qja +.section s2qjb +.section s2qka +.section s2qkb +.section s2qla +.section s2qlb +.section s2qma +.section s2qmb +.section s2qna +.section s2qnb +.section s2qoa +.section s2qob +.section s2qpa +.section s2qpb +.section s2qqa +.section s2qqb +.section s2qra +.section s2qrb +.section s2qsa +.section s2qsb +.section s2qta +.section s2qtb +.section s2qua +.section s2qub +.section s2qva +.section s2qvb +.section s2qwa +.section s2qwb +.section s2qxa +.section s2qxb +.section s2qya +.section s2qyb +.section s2qza +.section s2qzb +.section s2q1a +.section s2q1b +.section s2q2a +.section s2q2b +.section s2q3a +.section s2q3b +.section s2q4a +.section s2q4b +.section s2q5a +.section s2q5b +.section s2q6a +.section s2q6b +.section s2q7a +.section s2q7b +.section s2q8a +.section s2q8b +.section s2q9a +.section s2q9b +.section s2q0a +.section s2q0b +.section s2raa +.section s2rab +.section s2rba +.section s2rbb +.section s2rca +.section s2rcb +.section s2rda +.section s2rdb +.section s2rea +.section s2reb +.section s2rfa +.section s2rfb +.section s2rga +.section s2rgb +.section s2rha +.section s2rhb +.section s2ria +.section s2rib +.section s2rja +.section s2rjb +.section s2rka +.section s2rkb +.section s2rla +.section s2rlb +.section s2rma +.section s2rmb +.section s2rna +.section s2rnb +.section s2roa +.section s2rob +.section s2rpa +.section s2rpb +.section s2rqa +.section s2rqb +.section s2rra +.section s2rrb +.section s2rsa +.section s2rsb +.section s2rta +.section s2rtb +.section s2rua +.section s2rub +.section s2rva +.section s2rvb +.section s2rwa +.section s2rwb +.section s2rxa +.section s2rxb +.section s2rya +.section s2ryb +.section s2rza +.section s2rzb +.section s2r1a +.section s2r1b +.section s2r2a +.section s2r2b +.section s2r3a +.section s2r3b +.section s2r4a +.section s2r4b +.section s2r5a +.section s2r5b +.section s2r6a +.section s2r6b +.section s2r7a +.section s2r7b +.section s2r8a +.section s2r8b +.section s2r9a +.section s2r9b +.section s2r0a +.section s2r0b +.section s2saa +.section s2sab +.section s2sba +.section s2sbb +.section s2sca +.section s2scb +.section s2sda +.section s2sdb +.section s2sea +.section s2seb +.section s2sfa +.section s2sfb +.section s2sga +.section s2sgb +.section s2sha +.section s2shb +.section s2sia +.section s2sib +.section s2sja +.section s2sjb +.section s2ska +.section s2skb +.section s2sla +.section s2slb +.section s2sma +.section s2smb +.section s2sna +.section s2snb +.section s2soa +.section s2sob +.section s2spa +.section s2spb +.section s2sqa +.section s2sqb +.section s2sra +.section s2srb +.section s2ssa +.section s2ssb +.section s2sta +.section s2stb +.section s2sua +.section s2sub +.section s2sva +.section s2svb +.section s2swa +.section s2swb +.section s2sxa +.section s2sxb +.section s2sya +.section s2syb +.section s2sza +.section s2szb +.section s2s1a +.section s2s1b +.section s2s2a +.section s2s2b +.section s2s3a +.section s2s3b +.section s2s4a +.section s2s4b +.section s2s5a +.section s2s5b +.section s2s6a +.section s2s6b +.section s2s7a +.section s2s7b +.section s2s8a +.section s2s8b +.section s2s9a +.section s2s9b +.section s2s0a +.section s2s0b +.section s2taa +.section s2tab +.section s2tba +.section s2tbb +.section s2tca +.section s2tcb +.section s2tda +.section s2tdb +.section s2tea +.section s2teb +.section s2tfa +.section s2tfb +.section s2tga +.section s2tgb +.section s2tha +.section s2thb +.section s2tia +.section s2tib +.section s2tja +.section s2tjb +.section s2tka +.section s2tkb +.section s2tla +.section s2tlb +.section s2tma +.section s2tmb +.section s2tna +.section s2tnb +.section s2toa +.section s2tob +.section s2tpa +.section s2tpb +.section s2tqa +.section s2tqb +.section s2tra +.section s2trb +.section s2tsa +.section s2tsb +.section s2tta +.section s2ttb +.section s2tua +.section s2tub +.section s2tva +.section s2tvb +.section s2twa +.section s2twb +.section s2txa +.section s2txb +.section s2tya +.section s2tyb +.section s2tza +.section s2tzb +.section s2t1a +.section s2t1b +.section s2t2a +.section s2t2b +.section s2t3a +.section s2t3b +.section s2t4a +.section s2t4b +.section s2t5a +.section s2t5b +.section s2t6a +.section s2t6b +.section s2t7a +.section s2t7b +.section s2t8a +.section s2t8b +.section s2t9a +.section s2t9b +.section s2t0a +.section s2t0b +.section s2uaa +.section s2uab +.section s2uba +.section s2ubb +.section s2uca +.section s2ucb +.section s2uda +.section s2udb +.section s2uea +.section s2ueb +.section s2ufa +.section s2ufb +.section s2uga +.section s2ugb +.section s2uha +.section s2uhb +.section s2uia +.section s2uib +.section s2uja +.section s2ujb +.section s2uka +.section s2ukb +.section s2ula +.section s2ulb +.section s2uma +.section s2umb +.section s2una +.section s2unb +.section s2uoa +.section s2uob +.section s2upa +.section s2upb +.section s2uqa +.section s2uqb +.section s2ura +.section s2urb +.section s2usa +.section s2usb +.section s2uta +.section s2utb +.section s2uua +.section s2uub +.section s2uva +.section s2uvb +.section s2uwa +.section s2uwb +.section s2uxa +.section s2uxb +.section s2uya +.section s2uyb +.section s2uza +.section s2uzb +.section s2u1a +.section s2u1b +.section s2u2a +.section s2u2b +.section s2u3a +.section s2u3b +.section s2u4a +.section s2u4b +.section s2u5a +.section s2u5b +.section s2u6a +.section s2u6b +.section s2u7a +.section s2u7b +.section s2u8a +.section s2u8b +.section s2u9a +.section s2u9b +.section s2u0a +.section s2u0b +.section s2vaa +.section s2vab +.section s2vba +.section s2vbb +.section s2vca +.section s2vcb +.section s2vda +.section s2vdb +.section s2vea +.section s2veb +.section s2vfa +.section s2vfb +.section s2vga +.section s2vgb +.section s2vha +.section s2vhb +.section s2via +.section s2vib +.section s2vja +.section s2vjb +.section s2vka +.section s2vkb +.section s2vla +.section s2vlb +.section s2vma +.section s2vmb +.section s2vna +.section s2vnb +.section s2voa +.section s2vob +.section s2vpa +.section s2vpb +.section s2vqa +.section s2vqb +.section s2vra +.section s2vrb +.section s2vsa +.section s2vsb +.section s2vta +.section s2vtb +.section s2vua +.section s2vub +.section s2vva +.section s2vvb +.section s2vwa +.section s2vwb +.section s2vxa +.section s2vxb +.section s2vya +.section s2vyb +.section s2vza +.section s2vzb +.section s2v1a +.section s2v1b +.section s2v2a +.section s2v2b +.section s2v3a +.section s2v3b +.section s2v4a +.section s2v4b +.section s2v5a +.section s2v5b +.section s2v6a +.section s2v6b +.section s2v7a +.section s2v7b +.section s2v8a +.section s2v8b +.section s2v9a +.section s2v9b +.section s2v0a +.section s2v0b +.section s2waa +.section s2wab +.section s2wba +.section s2wbb +.section s2wca +.section s2wcb +.section s2wda +.section s2wdb +.section s2wea +.section s2web +.section s2wfa +.section s2wfb +.section s2wga +.section s2wgb +.section s2wha +.section s2whb +.section s2wia +.section s2wib +.section s2wja +.section s2wjb +.section s2wka +.section s2wkb +.section s2wla +.section s2wlb +.section s2wma +.section s2wmb +.section s2wna +.section s2wnb +.section s2woa +.section s2wob +.section s2wpa +.section s2wpb +.section s2wqa +.section s2wqb +.section s2wra +.section s2wrb +.section s2wsa +.section s2wsb +.section s2wta +.section s2wtb +.section s2wua +.section s2wub +.section s2wva +.section s2wvb +.section s2wwa +.section s2wwb +.section s2wxa +.section s2wxb +.section s2wya +.section s2wyb +.section s2wza +.section s2wzb +.section s2w1a +.section s2w1b +.section s2w2a +.section s2w2b +.section s2w3a +.section s2w3b +.section s2w4a +.section s2w4b +.section s2w5a +.section s2w5b +.section s2w6a +.section s2w6b +.section s2w7a +.section s2w7b +.section s2w8a +.section s2w8b +.section s2w9a +.section s2w9b +.section s2w0a +.section s2w0b +.section s2xaa +.section s2xab +.section s2xba +.section s2xbb +.section s2xca +.section s2xcb +.section s2xda +.section s2xdb +.section s2xea +.section s2xeb +.section s2xfa +.section s2xfb +.section s2xga +.section s2xgb +.section s2xha +.section s2xhb +.section s2xia +.section s2xib +.section s2xja +.section s2xjb +.section s2xka +.section s2xkb +.section s2xla +.section s2xlb +.section s2xma +.section s2xmb +.section s2xna +.section s2xnb +.section s2xoa +.section s2xob +.section s2xpa +.section s2xpb +.section s2xqa +.section s2xqb +.section s2xra +.section s2xrb +.section s2xsa +.section s2xsb +.section s2xta +.section s2xtb +.section s2xua +.section s2xub +.section s2xva +.section s2xvb +.section s2xwa +.section s2xwb +.section s2xxa +.section s2xxb +.section s2xya +.section s2xyb +.section s2xza +.section s2xzb +.section s2x1a +.section s2x1b +.section s2x2a +.section s2x2b +.section s2x3a +.section s2x3b +.section s2x4a +.section s2x4b +.section s2x5a +.section s2x5b +.section s2x6a +.section s2x6b +.section s2x7a +.section s2x7b +.section s2x8a +.section s2x8b +.section s2x9a +.section s2x9b +.section s2x0a +.section s2x0b +.section s2yaa +.section s2yab +.section s2yba +.section s2ybb +.section s2yca +.section s2ycb +.section s2yda +.section s2ydb +.section s2yea +.section s2yeb +.section s2yfa +.section s2yfb +.section s2yga +.section s2ygb +.section s2yha +.section s2yhb +.section s2yia +.section s2yib +.section s2yja +.section s2yjb +.section s2yka +.section s2ykb +.section s2yla +.section s2ylb +.section s2yma +.section s2ymb +.section s2yna +.section s2ynb +.section s2yoa +.section s2yob +.section s2ypa +.section s2ypb +.section s2yqa +.section s2yqb +.section s2yra +.section s2yrb +.section s2ysa +.section s2ysb +.section s2yta +.section s2ytb +.section s2yua +.section s2yub +.section s2yva +.section s2yvb +.section s2ywa +.section s2ywb +.section s2yxa +.section s2yxb +.section s2yya +.section s2yyb +.section s2yza +.section s2yzb +.section s2y1a +.section s2y1b +.section s2y2a +.section s2y2b +.section s2y3a +.section s2y3b +.section s2y4a +.section s2y4b +.section s2y5a +.section s2y5b +.section s2y6a +.section s2y6b +.section s2y7a +.section s2y7b +.section s2y8a +.section s2y8b +.section s2y9a +.section s2y9b +.section s2y0a +.section s2y0b +.section s2zaa +.section s2zab +.section s2zba +.section s2zbb +.section s2zca +.section s2zcb +.section s2zda +.section s2zdb +.section s2zea +.section s2zeb +.section s2zfa +.section s2zfb +.section s2zga +.section s2zgb +.section s2zha +.section s2zhb +.section s2zia +.section s2zib +.section s2zja +.section s2zjb +.section s2zka +.section s2zkb +.section s2zla +.section s2zlb +.section s2zma +.section s2zmb +.section s2zna +.section s2znb +.section s2zoa +.section s2zob +.section s2zpa +.section s2zpb +.section s2zqa +.section s2zqb +.section s2zra +.section s2zrb +.section s2zsa +.section s2zsb +.section s2zta +.section s2ztb +.section s2zua +.section s2zub +.section s2zva +.section s2zvb +.section s2zwa +.section s2zwb +.section s2zxa +.section s2zxb +.section s2zya +.section s2zyb +.section s2zza +.section s2zzb +.section s2z1a +.section s2z1b +.section s2z2a +.section s2z2b +.section s2z3a +.section s2z3b +.section s2z4a +.section s2z4b +.section s2z5a +.section s2z5b +.section s2z6a +.section s2z6b +.section s2z7a +.section s2z7b +.section s2z8a +.section s2z8b +.section s2z9a +.section s2z9b +.section s2z0a +.section s2z0b +.section s21aa +.section s21ab +.section s21ba +.section s21bb +.section s21ca +.section s21cb +.section s21da +.section s21db +.section s21ea +.section s21eb +.section s21fa +.section s21fb +.section s21ga +.section s21gb +.section s21ha +.section s21hb +.section s21ia +.section s21ib +.section s21ja +.section s21jb +.section s21ka +.section s21kb +.section s21la +.section s21lb +.section s21ma +.section s21mb +.section s21na +.section s21nb +.section s21oa +.section s21ob +.section s21pa +.section s21pb +.section s21qa +.section s21qb +.section s21ra +.section s21rb +.section s21sa +.section s21sb +.section s21ta +.section s21tb +.section s21ua +.section s21ub +.section s21va +.section s21vb +.section s21wa +.section s21wb +.section s21xa +.section s21xb +.section s21ya +.section s21yb +.section s21za +.section s21zb +.section s211a +.section s211b +.section s212a +.section s212b +.section s213a +.section s213b +.section s214a +.section s214b +.section s215a +.section s215b +.section s216a +.section s216b +.section s217a +.section s217b +.section s218a +.section s218b +.section s219a +.section s219b +.section s210a +.section s210b +.section s22aa +.section s22ab +.section s22ba +.section s22bb +.section s22ca +.section s22cb +.section s22da +.section s22db +.section s22ea +.section s22eb +.section s22fa +.section s22fb +.section s22ga +.section s22gb +.section s22ha +.section s22hb +.section s22ia +.section s22ib +.section s22ja +.section s22jb +.section s22ka +.section s22kb +.section s22la +.section s22lb +.section s22ma +.section s22mb +.section s22na +.section s22nb +.section s22oa +.section s22ob +.section s22pa +.section s22pb +.section s22qa +.section s22qb +.section s22ra +.section s22rb +.section s22sa +.section s22sb +.section s22ta +.section s22tb +.section s22ua +.section s22ub +.section s22va +.section s22vb +.section s22wa +.section s22wb +.section s22xa +.section s22xb +.section s22ya +.section s22yb +.section s22za +.section s22zb +.section s221a +.section s221b +.section s222a +.section s222b +.section s223a +.section s223b +.section s224a +.section s224b +.section s225a +.section s225b +.section s226a +.section s226b +.section s227a +.section s227b +.section s228a +.section s228b +.section s229a +.section s229b +.section s220a +.section s220b +.section s23aa +.section s23ab +.section s23ba +.section s23bb +.section s23ca +.section s23cb +.section s23da +.section s23db +.section s23ea +.section s23eb +.section s23fa +.section s23fb +.section s23ga +.section s23gb +.section s23ha +.section s23hb +.section s23ia +.section s23ib +.section s23ja +.section s23jb +.section s23ka +.section s23kb +.section s23la +.section s23lb +.section s23ma +.section s23mb +.section s23na +.section s23nb +.section s23oa +.section s23ob +.section s23pa +.section s23pb +.section s23qa +.section s23qb +.section s23ra +.section s23rb +.section s23sa +.section s23sb +.section s23ta +.section s23tb +.section s23ua +.section s23ub +.section s23va +.section s23vb +.section s23wa +.section s23wb +.section s23xa +.section s23xb +.section s23ya +.section s23yb +.section s23za +.section s23zb +.section s231a +.section s231b +.section s232a +.section s232b +.section s233a +.section s233b +.section s234a +.section s234b +.section s235a +.section s235b +.section s236a +.section s236b +.section s237a +.section s237b +.section s238a +.section s238b +.section s239a +.section s239b +.section s230a +.section s230b +.section s24aa +.section s24ab +.section s24ba +.section s24bb +.section s24ca +.section s24cb +.section s24da +.section s24db +.section s24ea +.section s24eb +.section s24fa +.section s24fb +.section s24ga +.section s24gb +.section s24ha +.section s24hb +.section s24ia +.section s24ib +.section s24ja +.section s24jb +.section s24ka +.section s24kb +.section s24la +.section s24lb +.section s24ma +.section s24mb +.section s24na +.section s24nb +.section s24oa +.section s24ob +.section s24pa +.section s24pb +.section s24qa +.section s24qb +.section s24ra +.section s24rb +.section s24sa +.section s24sb +.section s24ta +.section s24tb +.section s24ua +.section s24ub +.section s24va +.section s24vb +.section s24wa +.section s24wb +.section s24xa +.section s24xb +.section s24ya +.section s24yb +.section s24za +.section s24zb +.section s241a +.section s241b +.section s242a +.section s242b +.section s243a +.section s243b +.section s244a +.section s244b +.section s245a +.section s245b +.section s246a +.section s246b +.section s247a +.section s247b +.section s248a +.section s248b +.section s249a +.section s249b +.section s240a +.section s240b +.section s25aa +.section s25ab +.section s25ba +.section s25bb +.section s25ca +.section s25cb +.section s25da +.section s25db +.section s25ea +.section s25eb +.section s25fa +.section s25fb +.section s25ga +.section s25gb +.section s25ha +.section s25hb +.section s25ia +.section s25ib +.section s25ja +.section s25jb +.section s25ka +.section s25kb +.section s25la +.section s25lb +.section s25ma +.section s25mb +.section s25na +.section s25nb +.section s25oa +.section s25ob +.section s25pa +.section s25pb +.section s25qa +.section s25qb +.section s25ra +.section s25rb +.section s25sa +.section s25sb +.section s25ta +.section s25tb +.section s25ua +.section s25ub +.section s25va +.section s25vb +.section s25wa +.section s25wb +.section s25xa +.section s25xb +.section s25ya +.section s25yb +.section s25za +.section s25zb +.section s251a +.section s251b +.section s252a +.section s252b +.section s253a +.section s253b +.section s254a +.section s254b +.section s255a +.section s255b +.section s256a +.section s256b +.section s257a +.section s257b +.section s258a +.section s258b +.section s259a +.section s259b +.section s250a +.section s250b +.section s26aa +.section s26ab +.section s26ba +.section s26bb +.section s26ca +.section s26cb +.section s26da +.section s26db +.section s26ea +.section s26eb +.section s26fa +.section s26fb +.section s26ga +.section s26gb +.section s26ha +.section s26hb +.section s26ia +.section s26ib +.section s26ja +.section s26jb +.section s26ka +.section s26kb +.section s26la +.section s26lb +.section s26ma +.section s26mb +.section s26na +.section s26nb +.section s26oa +.section s26ob +.section s26pa +.section s26pb +.section s26qa +.section s26qb +.section s26ra +.section s26rb +.section s26sa +.section s26sb +.section s26ta +.section s26tb +.section s26ua +.section s26ub +.section s26va +.section s26vb +.section s26wa +.section s26wb +.section s26xa +.section s26xb +.section s26ya +.section s26yb +.section s26za +.section s26zb +.section s261a +.section s261b +.section s262a +.section s262b +.section s263a +.section s263b +.section s264a +.section s264b +.section s265a +.section s265b +.section s266a +.section s266b +.section s267a +.section s267b +.section s268a +.section s268b +.section s269a +.section s269b +.section s260a +.section s260b +.section s27aa +.section s27ab +.section s27ba +.section s27bb +.section s27ca +.section s27cb +.section s27da +.section s27db +.section s27ea +.section s27eb +.section s27fa +.section s27fb +.section s27ga +.section s27gb +.section s27ha +.section s27hb +.section s27ia +.section s27ib +.section s27ja +.section s27jb +.section s27ka +.section s27kb +.section s27la +.section s27lb +.section s27ma +.section s27mb +.section s27na +.section s27nb +.section s27oa +.section s27ob +.section s27pa +.section s27pb +.section s27qa +.section s27qb +.section s27ra +.section s27rb +.section s27sa +.section s27sb +.section s27ta +.section s27tb +.section s27ua +.section s27ub +.section s27va +.section s27vb +.section s27wa +.section s27wb +.section s27xa +.section s27xb +.section s27ya +.section s27yb +.section s27za +.section s27zb +.section s271a +.section s271b +.section s272a +.section s272b +.section s273a +.section s273b +.section s274a +.section s274b +.section s275a +.section s275b +.section s276a +.section s276b +.section s277a +.section s277b +.section s278a +.section s278b +.section s279a +.section s279b +.section s270a +.section s270b +.section s28aa +.section s28ab +.section s28ba +.section s28bb +.section s28ca +.section s28cb +.section s28da +.section s28db +.section s28ea +.section s28eb +.section s28fa +.section s28fb +.section s28ga +.section s28gb +.section s28ha +.section s28hb +.section s28ia +.section s28ib +.section s28ja +.section s28jb +.section s28ka +.section s28kb +.section s28la +.section s28lb +.section s28ma +.section s28mb +.section s28na +.section s28nb +.section s28oa +.section s28ob +.section s28pa +.section s28pb +.section s28qa +.section s28qb +.section s28ra +.section s28rb +.section s28sa +.section s28sb +.section s28ta +.section s28tb +.section s28ua +.section s28ub +.section s28va +.section s28vb +.section s28wa +.section s28wb +.section s28xa +.section s28xb +.section s28ya +.section s28yb +.section s28za +.section s28zb +.section s281a +.section s281b +.section s282a +.section s282b +.section s283a +.section s283b +.section s284a +.section s284b +.section s285a +.section s285b +.section s286a +.section s286b +.section s287a +.section s287b +.section s288a +.section s288b +.section s289a +.section s289b +.section s280a +.section s280b +.section s29aa +.section s29ab +.section s29ba +.section s29bb +.section s29ca +.section s29cb +.section s29da +.section s29db +.section s29ea +.section s29eb +.section s29fa +.section s29fb +.section s29ga +.section s29gb +.section s29ha +.section s29hb +.section s29ia +.section s29ib +.section s29ja +.section s29jb +.section s29ka +.section s29kb +.section s29la +.section s29lb +.section s29ma +.section s29mb +.section s29na +.section s29nb +.section s29oa +.section s29ob +.section s29pa +.section s29pb +.section s29qa +.section s29qb +.section s29ra +.section s29rb +.section s29sa +.section s29sb +.section s29ta +.section s29tb +.section s29ua +.section s29ub +.section s29va +.section s29vb +.section s29wa +.section s29wb +.section s29xa +.section s29xb +.section s29ya +.section s29yb +.section s29za +.section s29zb +.section s291a +.section s291b +.section s292a +.section s292b +.section s293a +.section s293b +.section s294a +.section s294b +.section s295a +.section s295b +.section s296a +.section s296b +.section s297a +.section s297b +.section s298a +.section s298b +.section s299a +.section s299b +.section s290a +.section s290b +.section s20aa +.section s20ab +.section s20ba +.section s20bb +.section s20ca +.section s20cb +.section s20da +.section s20db +.section s20ea +.section s20eb +.section s20fa +.section s20fb +.section s20ga +.section s20gb +.section s20ha +.section s20hb +.section s20ia +.section s20ib +.section s20ja +.section s20jb +.section s20ka +.section s20kb +.section s20la +.section s20lb +.section s20ma +.section s20mb +.section s20na +.section s20nb +.section s20oa +.section s20ob +.section s20pa +.section s20pb +.section s20qa +.section s20qb +.section s20ra +.section s20rb +.section s20sa +.section s20sb +.section s20ta +.section s20tb +.section s20ua +.section s20ub +.section s20va +.section s20vb +.section s20wa +.section s20wb +.section s20xa +.section s20xb +.section s20ya +.section s20yb +.section s20za +.section s20zb +.section s201a +.section s201b +.section s202a +.section s202b +.section s203a +.section s203b +.section s204a +.section s204b +.section s205a +.section s205b +.section s206a +.section s206b +.section s207a +.section s207b +.section s208a +.section s208b +.section s209a +.section s209b +.section s200a +.section s200b +.section s3aaa +.section s3aab +.section s3aba +.section s3abb +.section s3aca +.section s3acb +.section s3ada +.section s3adb +.section s3aea +.section s3aeb +.section s3afa +.section s3afb +.section s3aga +.section s3agb +.section s3aha +.section s3ahb +.section s3aia +.section s3aib +.section s3aja +.section s3ajb +.section s3aka +.section s3akb +.section s3ala +.section s3alb +.section s3ama +.section s3amb +.section s3ana +.section s3anb +.section s3aoa +.section s3aob +.section s3apa +.section s3apb +.section s3aqa +.section s3aqb +.section s3ara +.section s3arb +.section s3asa +.section s3asb +.section s3ata +.section s3atb +.section s3aua +.section s3aub +.section s3ava +.section s3avb +.section s3awa +.section s3awb +.section s3axa +.section s3axb +.section s3aya +.section s3ayb +.section s3aza +.section s3azb +.section s3a1a +.section s3a1b +.section s3a2a +.section s3a2b +.section s3a3a +.section s3a3b +.section s3a4a +.section s3a4b +.section s3a5a +.section s3a5b +.section s3a6a +.section s3a6b +.section s3a7a +.section s3a7b +.section s3a8a +.section s3a8b +.section s3a9a +.section s3a9b +.section s3a0a +.section s3a0b +.section s3baa +.section s3bab +.section s3bba +.section s3bbb +.section s3bca +.section s3bcb +.section s3bda +.section s3bdb +.section s3bea +.section s3beb +.section s3bfa +.section s3bfb +.section s3bga +.section s3bgb +.section s3bha +.section s3bhb +.section s3bia +.section s3bib +.section s3bja +.section s3bjb +.section s3bka +.section s3bkb +.section s3bla +.section s3blb +.section s3bma +.section s3bmb +.section s3bna +.section s3bnb +.section s3boa +.section s3bob +.section s3bpa +.section s3bpb +.section s3bqa +.section s3bqb +.section s3bra +.section s3brb +.section s3bsa +.section s3bsb +.section s3bta +.section s3btb +.section s3bua +.section s3bub +.section s3bva +.section s3bvb +.section s3bwa +.section s3bwb +.section s3bxa +.section s3bxb +.section s3bya +.section s3byb +.section s3bza +.section s3bzb +.section s3b1a +.section s3b1b +.section s3b2a +.section s3b2b +.section s3b3a +.section s3b3b +.section s3b4a +.section s3b4b +.section s3b5a +.section s3b5b +.section s3b6a +.section s3b6b +.section s3b7a +.section s3b7b +.section s3b8a +.section s3b8b +.section s3b9a +.section s3b9b +.section s3b0a +.section s3b0b +.section s3caa +.section s3cab +.section s3cba +.section s3cbb +.section s3cca +.section s3ccb +.section s3cda +.section s3cdb +.section s3cea +.section s3ceb +.section s3cfa +.section s3cfb +.section s3cga +.section s3cgb +.section s3cha +.section s3chb +.section s3cia +.section s3cib +.section s3cja +.section s3cjb +.section s3cka +.section s3ckb +.section s3cla +.section s3clb +.section s3cma +.section s3cmb +.section s3cna +.section s3cnb +.section s3coa +.section s3cob +.section s3cpa +.section s3cpb +.section s3cqa +.section s3cqb +.section s3cra +.section s3crb +.section s3csa +.section s3csb +.section s3cta +.section s3ctb +.section s3cua +.section s3cub +.section s3cva +.section s3cvb +.section s3cwa +.section s3cwb +.section s3cxa +.section s3cxb +.section s3cya +.section s3cyb +.section s3cza +.section s3czb +.section s3c1a +.section s3c1b +.section s3c2a +.section s3c2b +.section s3c3a +.section s3c3b +.section s3c4a +.section s3c4b +.section s3c5a +.section s3c5b +.section s3c6a +.section s3c6b +.section s3c7a +.section s3c7b +.section s3c8a +.section s3c8b +.section s3c9a +.section s3c9b +.section s3c0a +.section s3c0b +.section s3daa +.section s3dab +.section s3dba +.section s3dbb +.section s3dca +.section s3dcb +.section s3dda +.section s3ddb +.section s3dea +.section s3deb +.section s3dfa +.section s3dfb +.section s3dga +.section s3dgb +.section s3dha +.section s3dhb +.section s3dia +.section s3dib +.section s3dja +.section s3djb +.section s3dka +.section s3dkb +.section s3dla +.section s3dlb +.section s3dma +.section s3dmb +.section s3dna +.section s3dnb +.section s3doa +.section s3dob +.section s3dpa +.section s3dpb +.section s3dqa +.section s3dqb +.section s3dra +.section s3drb +.section s3dsa +.section s3dsb +.section s3dta +.section s3dtb +.section s3dua +.section s3dub +.section s3dva +.section s3dvb +.section s3dwa +.section s3dwb +.section s3dxa +.section s3dxb +.section s3dya +.section s3dyb +.section s3dza +.section s3dzb +.section s3d1a +.section s3d1b +.section s3d2a +.section s3d2b +.section s3d3a +.section s3d3b +.section s3d4a +.section s3d4b +.section s3d5a +.section s3d5b +.section s3d6a +.section s3d6b +.section s3d7a +.section s3d7b +.section s3d8a +.section s3d8b +.section s3d9a +.section s3d9b +.section s3d0a +.section s3d0b +.section s3eaa +.section s3eab +.section s3eba +.section s3ebb +.section s3eca +.section s3ecb +.section s3eda +.section s3edb +.section s3eea +.section s3eeb +.section s3efa +.section s3efb +.section s3ega +.section s3egb +.section s3eha +.section s3ehb +.section s3eia +.section s3eib +.section s3eja +.section s3ejb +.section s3eka +.section s3ekb +.section s3ela +.section s3elb +.section s3ema +.section s3emb +.section s3ena +.section s3enb +.section s3eoa +.section s3eob +.section s3epa +.section s3epb +.section s3eqa +.section s3eqb +.section s3era +.section s3erb +.section s3esa +.section s3esb +.section s3eta +.section s3etb +.section s3eua +.section s3eub +.section s3eva +.section s3evb +.section s3ewa +.section s3ewb +.section s3exa +.section s3exb +.section s3eya +.section s3eyb +.section s3eza +.section s3ezb +.section s3e1a +.section s3e1b +.section s3e2a +.section s3e2b +.section s3e3a +.section s3e3b +.section s3e4a +.section s3e4b +.section s3e5a +.section s3e5b +.section s3e6a +.section s3e6b +.section s3e7a +.section s3e7b +.section s3e8a +.section s3e8b +.section s3e9a +.section s3e9b +.section s3e0a +.section s3e0b +.section s3faa +.section s3fab +.section s3fba +.section s3fbb +.section s3fca +.section s3fcb +.section s3fda +.section s3fdb +.section s3fea +.section s3feb +.section s3ffa +.section s3ffb +.section s3fga +.section s3fgb +.section s3fha +.section s3fhb +.section s3fia +.section s3fib +.section s3fja +.section s3fjb +.section s3fka +.section s3fkb +.section s3fla +.section s3flb +.section s3fma +.section s3fmb +.section s3fna +.section s3fnb +.section s3foa +.section s3fob +.section s3fpa +.section s3fpb +.section s3fqa +.section s3fqb +.section s3fra +.section s3frb +.section s3fsa +.section s3fsb +.section s3fta +.section s3ftb +.section s3fua +.section s3fub +.section s3fva +.section s3fvb +.section s3fwa +.section s3fwb +.section s3fxa +.section s3fxb +.section s3fya +.section s3fyb +.section s3fza +.section s3fzb +.section s3f1a +.section s3f1b +.section s3f2a +.section s3f2b +.section s3f3a +.section s3f3b +.section s3f4a +.section s3f4b +.section s3f5a +.section s3f5b +.section s3f6a +.section s3f6b +.section s3f7a +.section s3f7b +.section s3f8a +.section s3f8b +.section s3f9a +.section s3f9b +.section s3f0a +.section s3f0b +.section s3gaa +.section s3gab +.section s3gba +.section s3gbb +.section s3gca +.section s3gcb +.section s3gda +.section s3gdb +.section s3gea +.section s3geb +.section s3gfa +.section s3gfb +.section s3gga +.section s3ggb +.section s3gha +.section s3ghb +.section s3gia +.section s3gib +.section s3gja +.section s3gjb +.section s3gka +.section s3gkb +.section s3gla +.section s3glb +.section s3gma +.section s3gmb +.section s3gna +.section s3gnb +.section s3goa +.section s3gob +.section s3gpa +.section s3gpb +.section s3gqa +.section s3gqb +.section s3gra +.section s3grb +.section s3gsa +.section s3gsb +.section s3gta +.section s3gtb +.section s3gua +.section s3gub +.section s3gva +.section s3gvb +.section s3gwa +.section s3gwb +.section s3gxa +.section s3gxb +.section s3gya +.section s3gyb +.section s3gza +.section s3gzb +.section s3g1a +.section s3g1b +.section s3g2a +.section s3g2b +.section s3g3a +.section s3g3b +.section s3g4a +.section s3g4b +.section s3g5a +.section s3g5b +.section s3g6a +.section s3g6b +.section s3g7a +.section s3g7b +.section s3g8a +.section s3g8b +.section s3g9a +.section s3g9b +.section s3g0a +.section s3g0b +.section s3haa +.section s3hab +.section s3hba +.section s3hbb +.section s3hca +.section s3hcb +.section s3hda +.section s3hdb +.section s3hea +.section s3heb +.section s3hfa +.section s3hfb +.section s3hga +.section s3hgb +.section s3hha +.section s3hhb +.section s3hia +.section s3hib +.section s3hja +.section s3hjb +.section s3hka +.section s3hkb +.section s3hla +.section s3hlb +.section s3hma +.section s3hmb +.section s3hna +.section s3hnb +.section s3hoa +.section s3hob +.section s3hpa +.section s3hpb +.section s3hqa +.section s3hqb +.section s3hra +.section s3hrb +.section s3hsa +.section s3hsb +.section s3hta +.section s3htb +.section s3hua +.section s3hub +.section s3hva +.section s3hvb +.section s3hwa +.section s3hwb +.section s3hxa +.section s3hxb +.section s3hya +.section s3hyb +.section s3hza +.section s3hzb +.section s3h1a +.section s3h1b +.section s3h2a +.section s3h2b +.section s3h3a +.section s3h3b +.section s3h4a +.section s3h4b +.section s3h5a +.section s3h5b +.section s3h6a +.section s3h6b +.section s3h7a +.section s3h7b +.section s3h8a +.section s3h8b +.section s3h9a +.section s3h9b +.section s3h0a +.section s3h0b +.section s3iaa +.section s3iab +.section s3iba +.section s3ibb +.section s3ica +.section s3icb +.section s3ida +.section s3idb +.section s3iea +.section s3ieb +.section s3ifa +.section s3ifb +.section s3iga +.section s3igb +.section s3iha +.section s3ihb +.section s3iia +.section s3iib +.section s3ija +.section s3ijb +.section s3ika +.section s3ikb +.section s3ila +.section s3ilb +.section s3ima +.section s3imb +.section s3ina +.section s3inb +.section s3ioa +.section s3iob +.section s3ipa +.section s3ipb +.section s3iqa +.section s3iqb +.section s3ira +.section s3irb +.section s3isa +.section s3isb +.section s3ita +.section s3itb +.section s3iua +.section s3iub +.section s3iva +.section s3ivb +.section s3iwa +.section s3iwb +.section s3ixa +.section s3ixb +.section s3iya +.section s3iyb +.section s3iza +.section s3izb +.section s3i1a +.section s3i1b +.section s3i2a +.section s3i2b +.section s3i3a +.section s3i3b +.section s3i4a +.section s3i4b +.section s3i5a +.section s3i5b +.section s3i6a +.section s3i6b +.section s3i7a +.section s3i7b +.section s3i8a +.section s3i8b +.section s3i9a +.section s3i9b +.section s3i0a +.section s3i0b +.section s3jaa +.section s3jab +.section s3jba +.section s3jbb +.section s3jca +.section s3jcb +.section s3jda +.section s3jdb +.section s3jea +.section s3jeb +.section s3jfa +.section s3jfb +.section s3jga +.section s3jgb +.section s3jha +.section s3jhb +.section s3jia +.section s3jib +.section s3jja +.section s3jjb +.section s3jka +.section s3jkb +.section s3jla +.section s3jlb +.section s3jma +.section s3jmb +.section s3jna +.section s3jnb +.section s3joa +.section s3job +.section s3jpa +.section s3jpb +.section s3jqa +.section s3jqb +.section s3jra +.section s3jrb +.section s3jsa +.section s3jsb +.section s3jta +.section s3jtb +.section s3jua +.section s3jub +.section s3jva +.section s3jvb +.section s3jwa +.section s3jwb +.section s3jxa +.section s3jxb +.section s3jya +.section s3jyb +.section s3jza +.section s3jzb +.section s3j1a +.section s3j1b +.section s3j2a +.section s3j2b +.section s3j3a +.section s3j3b +.section s3j4a +.section s3j4b +.section s3j5a +.section s3j5b +.section s3j6a +.section s3j6b +.section s3j7a +.section s3j7b +.section s3j8a +.section s3j8b +.section s3j9a +.section s3j9b +.section s3j0a +.section s3j0b +.section s3kaa +.section s3kab +.section s3kba +.section s3kbb +.section s3kca +.section s3kcb +.section s3kda +.section s3kdb +.section s3kea +.section s3keb +.section s3kfa +.section s3kfb +.section s3kga +.section s3kgb +.section s3kha +.section s3khb +.section s3kia +.section s3kib +.section s3kja +.section s3kjb +.section s3kka +.section s3kkb +.section s3kla +.section s3klb +.section s3kma +.section s3kmb +.section s3kna +.section s3knb +.section s3koa +.section s3kob +.section s3kpa +.section s3kpb +.section s3kqa +.section s3kqb +.section s3kra +.section s3krb +.section s3ksa +.section s3ksb +.section s3kta +.section s3ktb +.section s3kua +.section s3kub +.section s3kva +.section s3kvb +.section s3kwa +.section s3kwb +.section s3kxa +.section s3kxb +.section s3kya +.section s3kyb +.section s3kza +.section s3kzb +.section s3k1a +.section s3k1b +.section s3k2a +.section s3k2b +.section s3k3a +.section s3k3b +.section s3k4a +.section s3k4b +.section s3k5a +.section s3k5b +.section s3k6a +.section s3k6b +.section s3k7a +.section s3k7b +.section s3k8a +.section s3k8b +.section s3k9a +.section s3k9b +.section s3k0a +.section s3k0b +.section s3laa +.section s3lab +.section s3lba +.section s3lbb +.section s3lca +.section s3lcb +.section s3lda +.section s3ldb +.section s3lea +.section s3leb +.section s3lfa +.section s3lfb +.section s3lga +.section s3lgb +.section s3lha +.section s3lhb +.section s3lia +.section s3lib +.section s3lja +.section s3ljb +.section s3lka +.section s3lkb +.section s3lla +.section s3llb +.section s3lma +.section s3lmb +.section s3lna +.section s3lnb +.section s3loa +.section s3lob +.section s3lpa +.section s3lpb +.section s3lqa +.section s3lqb +.section s3lra +.section s3lrb +.section s3lsa +.section s3lsb +.section s3lta +.section s3ltb +.section s3lua +.section s3lub +.section s3lva +.section s3lvb +.section s3lwa +.section s3lwb +.section s3lxa +.section s3lxb +.section s3lya +.section s3lyb +.section s3lza +.section s3lzb +.section s3l1a +.section s3l1b +.section s3l2a +.section s3l2b +.section s3l3a +.section s3l3b +.section s3l4a +.section s3l4b +.section s3l5a +.section s3l5b +.section s3l6a +.section s3l6b +.section s3l7a +.section s3l7b +.section s3l8a +.section s3l8b +.section s3l9a +.section s3l9b +.section s3l0a +.section s3l0b +.section s3maa +.section s3mab +.section s3mba +.section s3mbb +.section s3mca +.section s3mcb +.section s3mda +.section s3mdb +.section s3mea +.section s3meb +.section s3mfa +.section s3mfb +.section s3mga +.section s3mgb +.section s3mha +.section s3mhb +.section s3mia +.section s3mib +.section s3mja +.section s3mjb +.section s3mka +.section s3mkb +.section s3mla +.section s3mlb +.section s3mma +.section s3mmb +.section s3mna +.section s3mnb +.section s3moa +.section s3mob +.section s3mpa +.section s3mpb +.section s3mqa +.section s3mqb +.section s3mra +.section s3mrb +.section s3msa +.section s3msb +.section s3mta +.section s3mtb +.section s3mua +.section s3mub +.section s3mva +.section s3mvb +.section s3mwa +.section s3mwb +.section s3mxa +.section s3mxb +.section s3mya +.section s3myb +.section s3mza +.section s3mzb +.section s3m1a +.section s3m1b +.section s3m2a +.section s3m2b +.section s3m3a +.section s3m3b +.section s3m4a +.section s3m4b +.section s3m5a +.section s3m5b +.section s3m6a +.section s3m6b +.section s3m7a +.section s3m7b +.section s3m8a +.section s3m8b +.section s3m9a +.section s3m9b +.section s3m0a +.section s3m0b +.section s3naa +.section s3nab +.section s3nba +.section s3nbb +.section s3nca +.section s3ncb +.section s3nda +.section s3ndb +.section s3nea +.section s3neb +.section s3nfa +.section s3nfb +.section s3nga +.section s3ngb +.section s3nha +.section s3nhb +.section s3nia +.section s3nib +.section s3nja +.section s3njb +.section s3nka +.section s3nkb +.section s3nla +.section s3nlb +.section s3nma +.section s3nmb +.section s3nna +.section s3nnb +.section s3noa +.section s3nob +.section s3npa +.section s3npb +.section s3nqa +.section s3nqb +.section s3nra +.section s3nrb +.section s3nsa +.section s3nsb +.section s3nta +.section s3ntb +.section s3nua +.section s3nub +.section s3nva +.section s3nvb +.section s3nwa +.section s3nwb +.section s3nxa +.section s3nxb +.section s3nya +.section s3nyb +.section s3nza +.section s3nzb +.section s3n1a +.section s3n1b +.section s3n2a +.section s3n2b +.section s3n3a +.section s3n3b +.section s3n4a +.section s3n4b +.section s3n5a +.section s3n5b +.section s3n6a +.section s3n6b +.section s3n7a +.section s3n7b +.section s3n8a +.section s3n8b +.section s3n9a +.section s3n9b +.section s3n0a +.section s3n0b +.section s3oaa +.section s3oab +.section s3oba +.section s3obb +.section s3oca +.section s3ocb +.section s3oda +.section s3odb +.section s3oea +.section s3oeb +.section s3ofa +.section s3ofb +.section s3oga +.section s3ogb +.section s3oha +.section s3ohb +.section s3oia +.section s3oib +.section s3oja +.section s3ojb +.section s3oka +.section s3okb +.section s3ola +.section s3olb +.section s3oma +.section s3omb +.section s3ona +.section s3onb +.section s3ooa +.section s3oob +.section s3opa +.section s3opb +.section s3oqa +.section s3oqb +.section s3ora +.section s3orb +.section s3osa +.section s3osb +.section s3ota +.section s3otb +.section s3oua +.section s3oub +.section s3ova +.section s3ovb +.section s3owa +.section s3owb +.section s3oxa +.section s3oxb +.section s3oya +.section s3oyb +.section s3oza +.section s3ozb +.section s3o1a +.section s3o1b +.section s3o2a +.section s3o2b +.section s3o3a +.section s3o3b +.section s3o4a +.section s3o4b +.section s3o5a +.section s3o5b +.section s3o6a +.section s3o6b +.section s3o7a +.section s3o7b +.section s3o8a +.section s3o8b +.section s3o9a +.section s3o9b +.section s3o0a +.section s3o0b +.section s3paa +.section s3pab +.section s3pba +.section s3pbb +.section s3pca +.section s3pcb +.section s3pda +.section s3pdb +.section s3pea +.section s3peb +.section s3pfa +.section s3pfb +.section s3pga +.section s3pgb +.section s3pha +.section s3phb +.section s3pia +.section s3pib +.section s3pja +.section s3pjb +.section s3pka +.section s3pkb +.section s3pla +.section s3plb +.section s3pma +.section s3pmb +.section s3pna +.section s3pnb +.section s3poa +.section s3pob +.section s3ppa +.section s3ppb +.section s3pqa +.section s3pqb +.section s3pra +.section s3prb +.section s3psa +.section s3psb +.section s3pta +.section s3ptb +.section s3pua +.section s3pub +.section s3pva +.section s3pvb +.section s3pwa +.section s3pwb +.section s3pxa +.section s3pxb +.section s3pya +.section s3pyb +.section s3pza +.section s3pzb +.section s3p1a +.section s3p1b +.section s3p2a +.section s3p2b +.section s3p3a +.section s3p3b +.section s3p4a +.section s3p4b +.section s3p5a +.section s3p5b +.section s3p6a +.section s3p6b +.section s3p7a +.section s3p7b +.section s3p8a +.section s3p8b +.section s3p9a +.section s3p9b +.section s3p0a +.section s3p0b +.section s3qaa +.section s3qab +.section s3qba +.section s3qbb +.section s3qca +.section s3qcb +.section s3qda +.section s3qdb +.section s3qea +.section s3qeb +.section s3qfa +.section s3qfb +.section s3qga +.section s3qgb +.section s3qha +.section s3qhb +.section s3qia +.section s3qib +.section s3qja +.section s3qjb +.section s3qka +.section s3qkb +.section s3qla +.section s3qlb +.section s3qma +.section s3qmb +.section s3qna +.section s3qnb +.section s3qoa +.section s3qob +.section s3qpa +.section s3qpb +.section s3qqa +.section s3qqb +.section s3qra +.section s3qrb +.section s3qsa +.section s3qsb +.section s3qta +.section s3qtb +.section s3qua +.section s3qub +.section s3qva +.section s3qvb +.section s3qwa +.section s3qwb +.section s3qxa +.section s3qxb +.section s3qya +.section s3qyb +.section s3qza +.section s3qzb +.section s3q1a +.section s3q1b +.section s3q2a +.section s3q2b +.section s3q3a +.section s3q3b +.section s3q4a +.section s3q4b +.section s3q5a +.section s3q5b +.section s3q6a +.section s3q6b +.section s3q7a +.section s3q7b +.section s3q8a +.section s3q8b +.section s3q9a +.section s3q9b +.section s3q0a +.section s3q0b +.section s3raa +.section s3rab +.section s3rba +.section s3rbb +.section s3rca +.section s3rcb +.section s3rda +.section s3rdb +.section s3rea +.section s3reb +.section s3rfa +.section s3rfb +.section s3rga +.section s3rgb +.section s3rha +.section s3rhb +.section s3ria +.section s3rib +.section s3rja +.section s3rjb +.section s3rka +.section s3rkb +.section s3rla +.section s3rlb +.section s3rma +.section s3rmb +.section s3rna +.section s3rnb +.section s3roa +.section s3rob +.section s3rpa +.section s3rpb +.section s3rqa +.section s3rqb +.section s3rra +.section s3rrb +.section s3rsa +.section s3rsb +.section s3rta +.section s3rtb +.section s3rua +.section s3rub +.section s3rva +.section s3rvb +.section s3rwa +.section s3rwb +.section s3rxa +.section s3rxb +.section s3rya +.section s3ryb +.section s3rza +.section s3rzb +.section s3r1a +.section s3r1b +.section s3r2a +.section s3r2b +.section s3r3a +.section s3r3b +.section s3r4a +.section s3r4b +.section s3r5a +.section s3r5b +.section s3r6a +.section s3r6b +.section s3r7a +.section s3r7b +.section s3r8a +.section s3r8b +.section s3r9a +.section s3r9b +.section s3r0a +.section s3r0b +.section s3saa +.section s3sab +.section s3sba +.section s3sbb +.section s3sca +.section s3scb +.section s3sda +.section s3sdb +.section s3sea +.section s3seb +.section s3sfa +.section s3sfb +.section s3sga +.section s3sgb +.section s3sha +.section s3shb +.section s3sia +.section s3sib +.section s3sja +.section s3sjb +.section s3ska +.section s3skb +.section s3sla +.section s3slb +.section s3sma +.section s3smb +.section s3sna +.section s3snb +.section s3soa +.section s3sob +.section s3spa +.section s3spb +.section s3sqa +.section s3sqb +.section s3sra +.section s3srb +.section s3ssa +.section s3ssb +.section s3sta +.section s3stb +.section s3sua +.section s3sub +.section s3sva +.section s3svb +.section s3swa +.section s3swb +.section s3sxa +.section s3sxb +.section s3sya +.section s3syb +.section s3sza +.section s3szb +.section s3s1a +.section s3s1b +.section s3s2a +.section s3s2b +.section s3s3a +.section s3s3b +.section s3s4a +.section s3s4b +.section s3s5a +.section s3s5b +.section s3s6a +.section s3s6b +.section s3s7a +.section s3s7b +.section s3s8a +.section s3s8b +.section s3s9a +.section s3s9b +.section s3s0a +.section s3s0b +.section s3taa +.section s3tab +.section s3tba +.section s3tbb +.section s3tca +.section s3tcb +.section s3tda +.section s3tdb +.section s3tea +.section s3teb +.section s3tfa +.section s3tfb +.section s3tga +.section s3tgb +.section s3tha +.section s3thb +.section s3tia +.section s3tib +.section s3tja +.section s3tjb +.section s3tka +.section s3tkb +.section s3tla +.section s3tlb +.section s3tma +.section s3tmb +.section s3tna +.section s3tnb +.section s3toa +.section s3tob +.section s3tpa +.section s3tpb +.section s3tqa +.section s3tqb +.section s3tra +.section s3trb +.section s3tsa +.section s3tsb +.section s3tta +.section s3ttb +.section s3tua +.section s3tub +.section s3tva +.section s3tvb +.section s3twa +.section s3twb +.section s3txa +.section s3txb +.section s3tya +.section s3tyb +.section s3tza +.section s3tzb +.section s3t1a +.section s3t1b +.section s3t2a +.section s3t2b +.section s3t3a +.section s3t3b +.section s3t4a +.section s3t4b +.section s3t5a +.section s3t5b +.section s3t6a +.section s3t6b +.section s3t7a +.section s3t7b +.section s3t8a +.section s3t8b +.section s3t9a +.section s3t9b +.section s3t0a +.section s3t0b +.section s3uaa +.section s3uab +.section s3uba +.section s3ubb +.section s3uca +.section s3ucb +.section s3uda +.section s3udb +.section s3uea +.section s3ueb +.section s3ufa +.section s3ufb +.section s3uga +.section s3ugb +.section s3uha +.section s3uhb +.section s3uia +.section s3uib +.section s3uja +.section s3ujb +.section s3uka +.section s3ukb +.section s3ula +.section s3ulb +.section s3uma +.section s3umb +.section s3una +.section s3unb +.section s3uoa +.section s3uob +.section s3upa +.section s3upb +.section s3uqa +.section s3uqb +.section s3ura +.section s3urb +.section s3usa +.section s3usb +.section s3uta +.section s3utb +.section s3uua +.section s3uub +.section s3uva +.section s3uvb +.section s3uwa +.section s3uwb +.section s3uxa +.section s3uxb +.section s3uya +.section s3uyb +.section s3uza +.section s3uzb +.section s3u1a +.section s3u1b +.section s3u2a +.section s3u2b +.section s3u3a +.section s3u3b +.section s3u4a +.section s3u4b +.section s3u5a +.section s3u5b +.section s3u6a +.section s3u6b +.section s3u7a +.section s3u7b +.section s3u8a +.section s3u8b +.section s3u9a +.section s3u9b +.section s3u0a +.section s3u0b +.section s3vaa +.section s3vab +.section s3vba +.section s3vbb +.section s3vca +.section s3vcb +.section s3vda +.section s3vdb +.section s3vea +.section s3veb +.section s3vfa +.section s3vfb +.section s3vga +.section s3vgb +.section s3vha +.section s3vhb +.section s3via +.section s3vib +.section s3vja +.section s3vjb +.section s3vka +.section s3vkb +.section s3vla +.section s3vlb +.section s3vma +.section s3vmb +.section s3vna +.section s3vnb +.section s3voa +.section s3vob +.section s3vpa +.section s3vpb +.section s3vqa +.section s3vqb +.section s3vra +.section s3vrb +.section s3vsa +.section s3vsb +.section s3vta +.section s3vtb +.section s3vua +.section s3vub +.section s3vva +.section s3vvb +.section s3vwa +.section s3vwb +.section s3vxa +.section s3vxb +.section s3vya +.section s3vyb +.section s3vza +.section s3vzb +.section s3v1a +.section s3v1b +.section s3v2a +.section s3v2b +.section s3v3a +.section s3v3b +.section s3v4a +.section s3v4b +.section s3v5a +.section s3v5b +.section s3v6a +.section s3v6b +.section s3v7a +.section s3v7b +.section s3v8a +.section s3v8b +.section s3v9a +.section s3v9b +.section s3v0a +.section s3v0b +.section s3waa +.section s3wab +.section s3wba +.section s3wbb +.section s3wca +.section s3wcb +.section s3wda +.section s3wdb +.section s3wea +.section s3web +.section s3wfa +.section s3wfb +.section s3wga +.section s3wgb +.section s3wha +.section s3whb +.section s3wia +.section s3wib +.section s3wja +.section s3wjb +.section s3wka +.section s3wkb +.section s3wla +.section s3wlb +.section s3wma +.section s3wmb +.section s3wna +.section s3wnb +.section s3woa +.section s3wob +.section s3wpa +.section s3wpb +.section s3wqa +.section s3wqb +.section s3wra +.section s3wrb +.section s3wsa +.section s3wsb +.section s3wta +.section s3wtb +.section s3wua +.section s3wub +.section s3wva +.section s3wvb +.section s3wwa +.section s3wwb +.section s3wxa +.section s3wxb +.section s3wya +.section s3wyb +.section s3wza +.section s3wzb +.section s3w1a +.section s3w1b +.section s3w2a +.section s3w2b +.section s3w3a +.section s3w3b +.section s3w4a +.section s3w4b +.section s3w5a +.section s3w5b +.section s3w6a +.section s3w6b +.section s3w7a +.section s3w7b +.section s3w8a +.section s3w8b +.section s3w9a +.section s3w9b +.section s3w0a +.section s3w0b +.section s3xaa +.section s3xab +.section s3xba +.section s3xbb +.section s3xca +.section s3xcb +.section s3xda +.section s3xdb +.section s3xea +.section s3xeb +.section s3xfa +.section s3xfb +.section s3xga +.section s3xgb +.section s3xha +.section s3xhb +.section s3xia +.section s3xib +.section s3xja +.section s3xjb +.section s3xka +.section s3xkb +.section s3xla +.section s3xlb +.section s3xma +.section s3xmb +.section s3xna +.section s3xnb +.section s3xoa +.section s3xob +.section s3xpa +.section s3xpb +.section s3xqa +.section s3xqb +.section s3xra +.section s3xrb +.section s3xsa +.section s3xsb +.section s3xta +.section s3xtb +.section s3xua +.section s3xub +.section s3xva +.section s3xvb +.section s3xwa +.section s3xwb +.section s3xxa +.section s3xxb +.section s3xya +.section s3xyb +.section s3xza +.section s3xzb +.section s3x1a +.section s3x1b +.section s3x2a +.section s3x2b +.section s3x3a +.section s3x3b +.section s3x4a +.section s3x4b +.section s3x5a +.section s3x5b +.section s3x6a +.section s3x6b +.section s3x7a +.section s3x7b +.section s3x8a +.section s3x8b +.section s3x9a +.section s3x9b +.section s3x0a +.section s3x0b +.section s3yaa +.section s3yab +.section s3yba +.section s3ybb +.section s3yca +.section s3ycb +.section s3yda +.section s3ydb +.section s3yea +.section s3yeb +.section s3yfa +.section s3yfb +.section s3yga +.section s3ygb +.section s3yha +.section s3yhb +.section s3yia +.section s3yib +.section s3yja +.section s3yjb +.section s3yka +.section s3ykb +.section s3yla +.section s3ylb +.section s3yma +.section s3ymb +.section s3yna +.section s3ynb +.section s3yoa +.section s3yob +.section s3ypa +.section s3ypb +.section s3yqa +.section s3yqb +.section s3yra +.section s3yrb +.section s3ysa +.section s3ysb +.section s3yta +.section s3ytb +.section s3yua +.section s3yub +.section s3yva +.section s3yvb +.section s3ywa +.section s3ywb +.section s3yxa +.section s3yxb +.section s3yya +.section s3yyb +.section s3yza +.section s3yzb +.section s3y1a +.section s3y1b +.section s3y2a +.section s3y2b +.section s3y3a +.section s3y3b +.section s3y4a +.section s3y4b +.section s3y5a +.section s3y5b +.section s3y6a +.section s3y6b +.section s3y7a +.section s3y7b +.section s3y8a +.section s3y8b +.section s3y9a +.section s3y9b +.section s3y0a +.section s3y0b +.section s3zaa +.section s3zab +.section s3zba +.section s3zbb +.section s3zca +.section s3zcb +.section s3zda +.section s3zdb +.section s3zea +.section s3zeb +.section s3zfa +.section s3zfb +.section s3zga +.section s3zgb +.section s3zha +.section s3zhb +.section s3zia +.section s3zib +.section s3zja +.section s3zjb +.section s3zka +.section s3zkb +.section s3zla +.section s3zlb +.section s3zma +.section s3zmb +.section s3zna +.section s3znb +.section s3zoa +.section s3zob +.section s3zpa +.section s3zpb +.section s3zqa +.section s3zqb +.section s3zra +.section s3zrb +.section s3zsa +.section s3zsb +.section s3zta +.section s3ztb +.section s3zua +.section s3zub +.section s3zva +.section s3zvb +.section s3zwa +.section s3zwb +.section s3zxa +.section s3zxb +.section s3zya +.section s3zyb +.section s3zza +.section s3zzb +.section s3z1a +.section s3z1b +.section s3z2a +.section s3z2b +.section s3z3a +.section s3z3b +.section s3z4a +.section s3z4b +.section s3z5a +.section s3z5b +.section s3z6a +.section s3z6b +.section s3z7a +.section s3z7b +.section s3z8a +.section s3z8b +.section s3z9a +.section s3z9b +.section s3z0a +.section s3z0b +.section s31aa +.section s31ab +.section s31ba +.section s31bb +.section s31ca +.section s31cb +.section s31da +.section s31db +.section s31ea +.section s31eb +.section s31fa +.section s31fb +.section s31ga +.section s31gb +.section s31ha +.section s31hb +.section s31ia +.section s31ib +.section s31ja +.section s31jb +.section s31ka +.section s31kb +.section s31la +.section s31lb +.section s31ma +.section s31mb +.section s31na +.section s31nb +.section s31oa +.section s31ob +.section s31pa +.section s31pb +.section s31qa +.section s31qb +.section s31ra +.section s31rb +.section s31sa +.section s31sb +.section s31ta +.section s31tb +.section s31ua +.section s31ub +.section s31va +.section s31vb +.section s31wa +.section s31wb +.section s31xa +.section s31xb +.section s31ya +.section s31yb +.section s31za +.section s31zb +.section s311a +.section s311b +.section s312a +.section s312b +.section s313a +.section s313b +.section s314a +.section s314b +.section s315a +.section s315b +.section s316a +.section s316b +.section s317a +.section s317b +.section s318a +.section s318b +.section s319a +.section s319b +.section s310a +.section s310b +.section s32aa +.section s32ab +.section s32ba +.section s32bb +.section s32ca +.section s32cb +.section s32da +.section s32db +.section s32ea +.section s32eb +.section s32fa +.section s32fb +.section s32ga +.section s32gb +.section s32ha +.section s32hb +.section s32ia +.section s32ib +.section s32ja +.section s32jb +.section s32ka +.section s32kb +.section s32la +.section s32lb +.section s32ma +.section s32mb +.section s32na +.section s32nb +.section s32oa +.section s32ob +.section s32pa +.section s32pb +.section s32qa +.section s32qb +.section s32ra +.section s32rb +.section s32sa +.section s32sb +.section s32ta +.section s32tb +.section s32ua +.section s32ub +.section s32va +.section s32vb +.section s32wa +.section s32wb +.section s32xa +.section s32xb +.section s32ya +.section s32yb +.section s32za +.section s32zb +.section s321a +.section s321b +.section s322a +.section s322b +.section s323a +.section s323b +.section s324a +.section s324b +.section s325a +.section s325b +.section s326a +.section s326b +.section s327a +.section s327b +.section s328a +.section s328b +.section s329a +.section s329b +.section s320a +.section s320b +.section s33aa +.section s33ab +.section s33ba +.section s33bb +.section s33ca +.section s33cb +.section s33da +.section s33db +.section s33ea +.section s33eb +.section s33fa +.section s33fb +.section s33ga +.section s33gb +.section s33ha +.section s33hb +.section s33ia +.section s33ib +.section s33ja +.section s33jb +.section s33ka +.section s33kb +.section s33la +.section s33lb +.section s33ma +.section s33mb +.section s33na +.section s33nb +.section s33oa +.section s33ob +.section s33pa +.section s33pb +.section s33qa +.section s33qb +.section s33ra +.section s33rb +.section s33sa +.section s33sb +.section s33ta +.section s33tb +.section s33ua +.section s33ub +.section s33va +.section s33vb +.section s33wa +.section s33wb +.section s33xa +.section s33xb +.section s33ya +.section s33yb +.section s33za +.section s33zb +.section s331a +.section s331b +.section s332a +.section s332b +.section s333a +.section s333b +.section s334a +.section s334b +.section s335a +.section s335b +.section s336a +.section s336b +.section s337a +.section s337b +.section s338a +.section s338b +.section s339a +.section s339b +.section s330a +.section s330b +.section s34aa +.section s34ab +.section s34ba +.section s34bb +.section s34ca +.section s34cb +.section s34da +.section s34db +.section s34ea +.section s34eb +.section s34fa +.section s34fb +.section s34ga +.section s34gb +.section s34ha +.section s34hb +.section s34ia +.section s34ib +.section s34ja +.section s34jb +.section s34ka +.section s34kb +.section s34la +.section s34lb +.section s34ma +.section s34mb +.section s34na +.section s34nb +.section s34oa +.section s34ob +.section s34pa +.section s34pb +.section s34qa +.section s34qb +.section s34ra +.section s34rb +.section s34sa +.section s34sb +.section s34ta +.section s34tb +.section s34ua +.section s34ub +.section s34va +.section s34vb +.section s34wa +.section s34wb +.section s34xa +.section s34xb +.section s34ya +.section s34yb +.section s34za +.section s34zb +.section s341a +.section s341b +.section s342a +.section s342b +.section s343a +.section s343b +.section s344a +.section s344b +.section s345a +.section s345b +.section s346a +.section s346b +.section s347a +.section s347b +.section s348a +.section s348b +.section s349a +.section s349b +.section s340a +.section s340b +.section s35aa +.section s35ab +.section s35ba +.section s35bb +.section s35ca +.section s35cb +.section s35da +.section s35db +.section s35ea +.section s35eb +.section s35fa +.section s35fb +.section s35ga +.section s35gb +.section s35ha +.section s35hb +.section s35ia +.section s35ib +.section s35ja +.section s35jb +.section s35ka +.section s35kb +.section s35la +.section s35lb +.section s35ma +.section s35mb +.section s35na +.section s35nb +.section s35oa +.section s35ob +.section s35pa +.section s35pb +.section s35qa +.section s35qb +.section s35ra +.section s35rb +.section s35sa +.section s35sb +.section s35ta +.section s35tb +.section s35ua +.section s35ub +.section s35va +.section s35vb +.section s35wa +.section s35wb +.section s35xa +.section s35xb +.section s35ya +.section s35yb +.section s35za +.section s35zb +.section s351a +.section s351b +.section s352a +.section s352b +.section s353a +.section s353b +.section s354a +.section s354b +.section s355a +.section s355b +.section s356a +.section s356b +.section s357a +.section s357b +.section s358a +.section s358b +.section s359a +.section s359b +.section s350a +.section s350b +.section s36aa +.section s36ab +.section s36ba +.section s36bb +.section s36ca +.section s36cb +.section s36da +.section s36db +.section s36ea +.section s36eb +.section s36fa +.section s36fb +.section s36ga +.section s36gb +.section s36ha +.section s36hb +.section s36ia +.section s36ib +.section s36ja +.section s36jb +.section s36ka +.section s36kb +.section s36la +.section s36lb +.section s36ma +.section s36mb +.section s36na +.section s36nb +.section s36oa +.section s36ob +.section s36pa +.section s36pb +.section s36qa +.section s36qb +.section s36ra +.section s36rb +.section s36sa +.section s36sb +.section s36ta +.section s36tb +.section s36ua +.section s36ub +.section s36va +.section s36vb +.section s36wa +.section s36wb +.section s36xa +.section s36xb +.section s36ya +.section s36yb +.section s36za +.section s36zb +.section s361a +.section s361b +.section s362a +.section s362b +.section s363a +.section s363b +.section s364a +.section s364b +.section s365a +.section s365b +.section s366a +.section s366b +.section s367a +.section s367b +.section s368a +.section s368b +.section s369a +.section s369b +.section s360a +.section s360b +.section s37aa +.section s37ab +.section s37ba +.section s37bb +.section s37ca +.section s37cb +.section s37da +.section s37db +.section s37ea +.section s37eb +.section s37fa +.section s37fb +.section s37ga +.section s37gb +.section s37ha +.section s37hb +.section s37ia +.section s37ib +.section s37ja +.section s37jb +.section s37ka +.section s37kb +.section s37la +.section s37lb +.section s37ma +.section s37mb +.section s37na +.section s37nb +.section s37oa +.section s37ob +.section s37pa +.section s37pb +.section s37qa +.section s37qb +.section s37ra +.section s37rb +.section s37sa +.section s37sb +.section s37ta +.section s37tb +.section s37ua +.section s37ub +.section s37va +.section s37vb +.section s37wa +.section s37wb +.section s37xa +.section s37xb +.section s37ya +.section s37yb +.section s37za +.section s37zb +.section s371a +.section s371b +.section s372a +.section s372b +.section s373a +.section s373b +.section s374a +.section s374b +.section s375a +.section s375b +.section s376a +.section s376b +.section s377a +.section s377b +.section s378a +.section s378b +.section s379a +.section s379b +.section s370a +.section s370b +.section s38aa +.section s38ab +.section s38ba +.section s38bb +.section s38ca +.section s38cb +.section s38da +.section s38db +.section s38ea +.section s38eb +.section s38fa +.section s38fb +.section s38ga +.section s38gb +.section s38ha +.section s38hb +.section s38ia +.section s38ib +.section s38ja +.section s38jb +.section s38ka +.section s38kb +.section s38la +.section s38lb +.section s38ma +.section s38mb +.section s38na +.section s38nb +.section s38oa +.section s38ob +.section s38pa +.section s38pb +.section s38qa +.section s38qb +.section s38ra +.section s38rb +.section s38sa +.section s38sb +.section s38ta +.section s38tb +.section s38ua +.section s38ub +.section s38va +.section s38vb +.section s38wa +.section s38wb +.section s38xa +.section s38xb +.section s38ya +.section s38yb +.section s38za +.section s38zb +.section s381a +.section s381b +.section s382a +.section s382b +.section s383a +.section s383b +.section s384a +.section s384b +.section s385a +.section s385b +.section s386a +.section s386b +.section s387a +.section s387b +.section s388a +.section s388b +.section s389a +.section s389b +.section s380a +.section s380b +.section s39aa +.section s39ab +.section s39ba +.section s39bb +.section s39ca +.section s39cb +.section s39da +.section s39db +.section s39ea +.section s39eb +.section s39fa +.section s39fb +.section s39ga +.section s39gb +.section s39ha +.section s39hb +.section s39ia +.section s39ib +.section s39ja +.section s39jb +.section s39ka +.section s39kb +.section s39la +.section s39lb +.section s39ma +.section s39mb +.section s39na +.section s39nb +.section s39oa +.section s39ob +.section s39pa +.section s39pb +.section s39qa +.section s39qb +.section s39ra +.section s39rb +.section s39sa +.section s39sb +.section s39ta +.section s39tb +.section s39ua +.section s39ub +.section s39va +.section s39vb +.section s39wa +.section s39wb +.section s39xa +.section s39xb +.section s39ya +.section s39yb +.section s39za +.section s39zb +.section s391a +.section s391b +.section s392a +.section s392b +.section s393a +.section s393b +.section s394a +.section s394b +.section s395a +.section s395b +.section s396a +.section s396b +.section s397a +.section s397b +.section s398a +.section s398b +.section s399a +.section s399b +.section s390a +.section s390b +.section s30aa +.section s30ab +.section s30ba +.section s30bb +.section s30ca +.section s30cb +.section s30da +.section s30db +.section s30ea +.section s30eb +.section s30fa +.section s30fb +.section s30ga +.section s30gb +.section s30ha +.section s30hb +.section s30ia +.section s30ib +.section s30ja +.section s30jb +.section s30ka +.section s30kb +.section s30la +.section s30lb +.section s30ma +.section s30mb +.section s30na +.section s30nb +.section s30oa +.section s30ob +.section s30pa +.section s30pb +.section s30qa +.section s30qb +.section s30ra +.section s30rb +.section s30sa +.section s30sb +.section s30ta +.section s30tb +.section s30ua +.section s30ub +.section s30va +.section s30vb +.section s30wa +.section s30wb +.section s30xa +.section s30xb +.section s30ya +.section s30yb +.section s30za +.section s30zb +.section s301a +.section s301b +.section s302a +.section s302b +.section s303a +.section s303b +.section s304a +.section s304b +.section s305a +.section s305b +.section s306a +.section s306b +.section s307a +.section s307b +.section s308a +.section s308b +.section s309a +.section s309b +.section s300a +.section s300b +.section s4aaa +.section s4aab +.section s4aba +.section s4abb +.section s4aca +.section s4acb +.section s4ada +.section s4adb +.section s4aea +.section s4aeb +.section s4afa +.section s4afb +.section s4aga +.section s4agb +.section s4aha +.section s4ahb +.section s4aia +.section s4aib +.section s4aja +.section s4ajb +.section s4aka +.section s4akb +.section s4ala +.section s4alb +.section s4ama +.section s4amb +.section s4ana +.section s4anb +.section s4aoa +.section s4aob +.section s4apa +.section s4apb +.section s4aqa +.section s4aqb +.section s4ara +.section s4arb +.section s4asa +.section s4asb +.section s4ata +.section s4atb +.section s4aua +.section s4aub +.section s4ava +.section s4avb +.section s4awa +.section s4awb +.section s4axa +.section s4axb +.section s4aya +.section s4ayb +.section s4aza +.section s4azb +.section s4a1a +.section s4a1b +.section s4a2a +.section s4a2b +.section s4a3a +.section s4a3b +.section s4a4a +.section s4a4b +.section s4a5a +.section s4a5b +.section s4a6a +.section s4a6b +.section s4a7a +.section s4a7b +.section s4a8a +.section s4a8b +.section s4a9a +.section s4a9b +.section s4a0a +.section s4a0b +.section s4baa +.section s4bab +.section s4bba +.section s4bbb +.section s4bca +.section s4bcb +.section s4bda +.section s4bdb +.section s4bea +.section s4beb +.section s4bfa +.section s4bfb +.section s4bga +.section s4bgb +.section s4bha +.section s4bhb +.section s4bia +.section s4bib +.section s4bja +.section s4bjb +.section s4bka +.section s4bkb +.section s4bla +.section s4blb +.section s4bma +.section s4bmb +.section s4bna +.section s4bnb +.section s4boa +.section s4bob +.section s4bpa +.section s4bpb +.section s4bqa +.section s4bqb +.section s4bra +.section s4brb +.section s4bsa +.section s4bsb +.section s4bta +.section s4btb +.section s4bua +.section s4bub +.section s4bva +.section s4bvb +.section s4bwa +.section s4bwb +.section s4bxa +.section s4bxb +.section s4bya +.section s4byb +.section s4bza +.section s4bzb +.section s4b1a +.section s4b1b +.section s4b2a +.section s4b2b +.section s4b3a +.section s4b3b +.section s4b4a +.section s4b4b +.section s4b5a +.section s4b5b +.section s4b6a +.section s4b6b +.section s4b7a +.section s4b7b +.section s4b8a +.section s4b8b +.section s4b9a +.section s4b9b +.section s4b0a +.section s4b0b +.section s4caa +.section s4cab +.section s4cba +.section s4cbb +.section s4cca +.section s4ccb +.section s4cda +.section s4cdb +.section s4cea +.section s4ceb +.section s4cfa +.section s4cfb +.section s4cga +.section s4cgb +.section s4cha +.section s4chb +.section s4cia +.section s4cib +.section s4cja +.section s4cjb +.section s4cka +.section s4ckb +.section s4cla +.section s4clb +.section s4cma +.section s4cmb +.section s4cna +.section s4cnb +.section s4coa +.section s4cob +.section s4cpa +.section s4cpb +.section s4cqa +.section s4cqb +.section s4cra +.section s4crb +.section s4csa +.section s4csb +.section s4cta +.section s4ctb +.section s4cua +.section s4cub +.section s4cva +.section s4cvb +.section s4cwa +.section s4cwb +.section s4cxa +.section s4cxb +.section s4cya +.section s4cyb +.section s4cza +.section s4czb +.section s4c1a +.section s4c1b +.section s4c2a +.section s4c2b +.section s4c3a +.section s4c3b +.section s4c4a +.section s4c4b +.section s4c5a +.section s4c5b +.section s4c6a +.section s4c6b +.section s4c7a +.section s4c7b +.section s4c8a +.section s4c8b +.section s4c9a +.section s4c9b +.section s4c0a +.section s4c0b +.section s4daa +.section s4dab +.section s4dba +.section s4dbb +.section s4dca +.section s4dcb +.section s4dda +.section s4ddb +.section s4dea +.section s4deb +.section s4dfa +.section s4dfb +.section s4dga +.section s4dgb +.section s4dha +.section s4dhb +.section s4dia +.section s4dib +.section s4dja +.section s4djb +.section s4dka +.section s4dkb +.section s4dla +.section s4dlb +.section s4dma +.section s4dmb +.section s4dna +.section s4dnb +.section s4doa +.section s4dob +.section s4dpa +.section s4dpb +.section s4dqa +.section s4dqb +.section s4dra +.section s4drb +.section s4dsa +.section s4dsb +.section s4dta +.section s4dtb +.section s4dua +.section s4dub +.section s4dva +.section s4dvb +.section s4dwa +.section s4dwb +.section s4dxa +.section s4dxb +.section s4dya +.section s4dyb +.section s4dza +.section s4dzb +.section s4d1a +.section s4d1b +.section s4d2a +.section s4d2b +.section s4d3a +.section s4d3b +.section s4d4a +.section s4d4b +.section s4d5a +.section s4d5b +.section s4d6a +.section s4d6b +.section s4d7a +.section s4d7b +.section s4d8a +.section s4d8b +.section s4d9a +.section s4d9b +.section s4d0a +.section s4d0b +.section s4eaa +.section s4eab +.section s4eba +.section s4ebb +.section s4eca +.section s4ecb +.section s4eda +.section s4edb +.section s4eea +.section s4eeb +.section s4efa +.section s4efb +.section s4ega +.section s4egb +.section s4eha +.section s4ehb +.section s4eia +.section s4eib +.section s4eja +.section s4ejb +.section s4eka +.section s4ekb +.section s4ela +.section s4elb +.section s4ema +.section s4emb +.section s4ena +.section s4enb +.section s4eoa +.section s4eob +.section s4epa +.section s4epb +.section s4eqa +.section s4eqb +.section s4era +.section s4erb +.section s4esa +.section s4esb +.section s4eta +.section s4etb +.section s4eua +.section s4eub +.section s4eva +.section s4evb +.section s4ewa +.section s4ewb +.section s4exa +.section s4exb +.section s4eya +.section s4eyb +.section s4eza +.section s4ezb +.section s4e1a +.section s4e1b +.section s4e2a +.section s4e2b +.section s4e3a +.section s4e3b +.section s4e4a +.section s4e4b +.section s4e5a +.section s4e5b +.section s4e6a +.section s4e6b +.section s4e7a +.section s4e7b +.section s4e8a +.section s4e8b +.section s4e9a +.section s4e9b +.section s4e0a +.section s4e0b +.section s4faa +.section s4fab +.section s4fba +.section s4fbb +.section s4fca +.section s4fcb +.section s4fda +.section s4fdb +.section s4fea +.section s4feb +.section s4ffa +.section s4ffb +.section s4fga +.section s4fgb +.section s4fha +.section s4fhb +.section s4fia +.section s4fib +.section s4fja +.section s4fjb +.section s4fka +.section s4fkb +.section s4fla +.section s4flb +.section s4fma +.section s4fmb +.section s4fna +.section s4fnb +.section s4foa +.section s4fob +.section s4fpa +.section s4fpb +.section s4fqa +.section s4fqb +.section s4fra +.section s4frb +.section s4fsa +.section s4fsb +.section s4fta +.section s4ftb +.section s4fua +.section s4fub +.section s4fva +.section s4fvb +.section s4fwa +.section s4fwb +.section s4fxa +.section s4fxb +.section s4fya +.section s4fyb +.section s4fza +.section s4fzb +.section s4f1a +.section s4f1b +.section s4f2a +.section s4f2b +.section s4f3a +.section s4f3b +.section s4f4a +.section s4f4b +.section s4f5a +.section s4f5b +.section s4f6a +.section s4f6b +.section s4f7a +.section s4f7b +.section s4f8a +.section s4f8b +.section s4f9a +.section s4f9b +.section s4f0a +.section s4f0b +.section s4gaa +.section s4gab +.section s4gba +.section s4gbb +.section s4gca +.section s4gcb +.section s4gda +.section s4gdb +.section s4gea +.section s4geb +.section s4gfa +.section s4gfb +.section s4gga +.section s4ggb +.section s4gha +.section s4ghb +.section s4gia +.section s4gib +.section s4gja +.section s4gjb +.section s4gka +.section s4gkb +.section s4gla +.section s4glb +.section s4gma +.section s4gmb +.section s4gna +.section s4gnb +.section s4goa +.section s4gob +.section s4gpa +.section s4gpb +.section s4gqa +.section s4gqb +.section s4gra +.section s4grb +.section s4gsa +.section s4gsb +.section s4gta +.section s4gtb +.section s4gua +.section s4gub +.section s4gva +.section s4gvb +.section s4gwa +.section s4gwb +.section s4gxa +.section s4gxb +.section s4gya +.section s4gyb +.section s4gza +.section s4gzb +.section s4g1a +.section s4g1b +.section s4g2a +.section s4g2b +.section s4g3a +.section s4g3b +.section s4g4a +.section s4g4b +.section s4g5a +.section s4g5b +.section s4g6a +.section s4g6b +.section s4g7a +.section s4g7b +.section s4g8a +.section s4g8b +.section s4g9a +.section s4g9b +.section s4g0a +.section s4g0b +.section s4haa +.section s4hab +.section s4hba +.section s4hbb +.section s4hca +.section s4hcb +.section s4hda +.section s4hdb +.section s4hea +.section s4heb +.section s4hfa +.section s4hfb +.section s4hga +.section s4hgb +.section s4hha +.section s4hhb +.section s4hia +.section s4hib +.section s4hja +.section s4hjb +.section s4hka +.section s4hkb +.section s4hla +.section s4hlb +.section s4hma +.section s4hmb +.section s4hna +.section s4hnb +.section s4hoa +.section s4hob +.section s4hpa +.section s4hpb +.section s4hqa +.section s4hqb +.section s4hra +.section s4hrb +.section s4hsa +.section s4hsb +.section s4hta +.section s4htb +.section s4hua +.section s4hub +.section s4hva +.section s4hvb +.section s4hwa +.section s4hwb +.section s4hxa +.section s4hxb +.section s4hya +.section s4hyb +.section s4hza +.section s4hzb +.section s4h1a +.section s4h1b +.section s4h2a +.section s4h2b +.section s4h3a +.section s4h3b +.section s4h4a +.section s4h4b +.section s4h5a +.section s4h5b +.section s4h6a +.section s4h6b +.section s4h7a +.section s4h7b +.section s4h8a +.section s4h8b +.section s4h9a +.section s4h9b +.section s4h0a +.section s4h0b +.section s4iaa +.section s4iab +.section s4iba +.section s4ibb +.section s4ica +.section s4icb +.section s4ida +.section s4idb +.section s4iea +.section s4ieb +.section s4ifa +.section s4ifb +.section s4iga +.section s4igb +.section s4iha +.section s4ihb +.section s4iia +.section s4iib +.section s4ija +.section s4ijb +.section s4ika +.section s4ikb +.section s4ila +.section s4ilb +.section s4ima +.section s4imb +.section s4ina +.section s4inb +.section s4ioa +.section s4iob +.section s4ipa +.section s4ipb +.section s4iqa +.section s4iqb +.section s4ira +.section s4irb +.section s4isa +.section s4isb +.section s4ita +.section s4itb +.section s4iua +.section s4iub +.section s4iva +.section s4ivb +.section s4iwa +.section s4iwb +.section s4ixa +.section s4ixb +.section s4iya +.section s4iyb +.section s4iza +.section s4izb +.section s4i1a +.section s4i1b +.section s4i2a +.section s4i2b +.section s4i3a +.section s4i3b +.section s4i4a +.section s4i4b +.section s4i5a +.section s4i5b +.section s4i6a +.section s4i6b +.section s4i7a +.section s4i7b +.section s4i8a +.section s4i8b +.section s4i9a +.section s4i9b +.section s4i0a +.section s4i0b +.section s4jaa +.section s4jab +.section s4jba +.section s4jbb +.section s4jca +.section s4jcb +.section s4jda +.section s4jdb +.section s4jea +.section s4jeb +.section s4jfa +.section s4jfb +.section s4jga +.section s4jgb +.section s4jha +.section s4jhb +.section s4jia +.section s4jib +.section s4jja +.section s4jjb +.section s4jka +.section s4jkb +.section s4jla +.section s4jlb +.section s4jma +.section s4jmb +.section s4jna +.section s4jnb +.section s4joa +.section s4job +.section s4jpa +.section s4jpb +.section s4jqa +.section s4jqb +.section s4jra +.section s4jrb +.section s4jsa +.section s4jsb +.section s4jta +.section s4jtb +.section s4jua +.section s4jub +.section s4jva +.section s4jvb +.section s4jwa +.section s4jwb +.section s4jxa +.section s4jxb +.section s4jya +.section s4jyb +.section s4jza +.section s4jzb +.section s4j1a +.section s4j1b +.section s4j2a +.section s4j2b +.section s4j3a +.section s4j3b +.section s4j4a +.section s4j4b +.section s4j5a +.section s4j5b +.section s4j6a +.section s4j6b +.section s4j7a +.section s4j7b +.section s4j8a +.section s4j8b +.section s4j9a +.section s4j9b +.section s4j0a +.section s4j0b +.section s4kaa +.section s4kab +.section s4kba +.section s4kbb +.section s4kca +.section s4kcb +.section s4kda +.section s4kdb +.section s4kea +.section s4keb +.section s4kfa +.section s4kfb +.section s4kga +.section s4kgb +.section s4kha +.section s4khb +.section s4kia +.section s4kib +.section s4kja +.section s4kjb +.section s4kka +.section s4kkb +.section s4kla +.section s4klb +.section s4kma +.section s4kmb +.section s4kna +.section s4knb +.section s4koa +.section s4kob +.section s4kpa +.section s4kpb +.section s4kqa +.section s4kqb +.section s4kra +.section s4krb +.section s4ksa +.section s4ksb +.section s4kta +.section s4ktb +.section s4kua +.section s4kub +.section s4kva +.section s4kvb +.section s4kwa +.section s4kwb +.section s4kxa +.section s4kxb +.section s4kya +.section s4kyb +.section s4kza +.section s4kzb +.section s4k1a +.section s4k1b +.section s4k2a +.section s4k2b +.section s4k3a +.section s4k3b +.section s4k4a +.section s4k4b +.section s4k5a +.section s4k5b +.section s4k6a +.section s4k6b +.section s4k7a +.section s4k7b +.section s4k8a +.section s4k8b +.section s4k9a +.section s4k9b +.section s4k0a +.section s4k0b +.section s4laa +.section s4lab +.section s4lba +.section s4lbb +.section s4lca +.section s4lcb +.section s4lda +.section s4ldb +.section s4lea +.section s4leb +.section s4lfa +.section s4lfb +.section s4lga +.section s4lgb +.section s4lha +.section s4lhb +.section s4lia +.section s4lib +.section s4lja +.section s4ljb +.section s4lka +.section s4lkb +.section s4lla +.section s4llb +.section s4lma +.section s4lmb +.section s4lna +.section s4lnb +.section s4loa +.section s4lob +.section s4lpa +.section s4lpb +.section s4lqa +.section s4lqb +.section s4lra +.section s4lrb +.section s4lsa +.section s4lsb +.section s4lta +.section s4ltb +.section s4lua +.section s4lub +.section s4lva +.section s4lvb +.section s4lwa +.section s4lwb +.section s4lxa +.section s4lxb +.section s4lya +.section s4lyb +.section s4lza +.section s4lzb +.section s4l1a +.section s4l1b +.section s4l2a +.section s4l2b +.section s4l3a +.section s4l3b +.section s4l4a +.section s4l4b +.section s4l5a +.section s4l5b +.section s4l6a +.section s4l6b +.section s4l7a +.section s4l7b +.section s4l8a +.section s4l8b +.section s4l9a +.section s4l9b +.section s4l0a +.section s4l0b +.section s4maa +.section s4mab +.section s4mba +.section s4mbb +.section s4mca +.section s4mcb +.section s4mda +.section s4mdb +.section s4mea +.section s4meb +.section s4mfa +.section s4mfb +.section s4mga +.section s4mgb +.section s4mha +.section s4mhb +.section s4mia +.section s4mib +.section s4mja +.section s4mjb +.section s4mka +.section s4mkb +.section s4mla +.section s4mlb +.section s4mma +.section s4mmb +.section s4mna +.section s4mnb +.section s4moa +.section s4mob +.section s4mpa +.section s4mpb +.section s4mqa +.section s4mqb +.section s4mra +.section s4mrb +.section s4msa +.section s4msb +.section s4mta +.section s4mtb +.section s4mua +.section s4mub +.section s4mva +.section s4mvb +.section s4mwa +.section s4mwb +.section s4mxa +.section s4mxb +.section s4mya +.section s4myb +.section s4mza +.section s4mzb +.section s4m1a +.section s4m1b +.section s4m2a +.section s4m2b +.section s4m3a +.section s4m3b +.section s4m4a +.section s4m4b +.section s4m5a +.section s4m5b +.section s4m6a +.section s4m6b +.section s4m7a +.section s4m7b +.section s4m8a +.section s4m8b +.section s4m9a +.section s4m9b +.section s4m0a +.section s4m0b +.section s4naa +.section s4nab +.section s4nba +.section s4nbb +.section s4nca +.section s4ncb +.section s4nda +.section s4ndb +.section s4nea +.section s4neb +.section s4nfa +.section s4nfb +.section s4nga +.section s4ngb +.section s4nha +.section s4nhb +.section s4nia +.section s4nib +.section s4nja +.section s4njb +.section s4nka +.section s4nkb +.section s4nla +.section s4nlb +.section s4nma +.section s4nmb +.section s4nna +.section s4nnb +.section s4noa +.section s4nob +.section s4npa +.section s4npb +.section s4nqa +.section s4nqb +.section s4nra +.section s4nrb +.section s4nsa +.section s4nsb +.section s4nta +.section s4ntb +.section s4nua +.section s4nub +.section s4nva +.section s4nvb +.section s4nwa +.section s4nwb +.section s4nxa +.section s4nxb +.section s4nya +.section s4nyb +.section s4nza +.section s4nzb +.section s4n1a +.section s4n1b +.section s4n2a +.section s4n2b +.section s4n3a +.section s4n3b +.section s4n4a +.section s4n4b +.section s4n5a +.section s4n5b +.section s4n6a +.section s4n6b +.section s4n7a +.section s4n7b +.section s4n8a +.section s4n8b +.section s4n9a +.section s4n9b +.section s4n0a +.section s4n0b +.section s4oaa +.section s4oab +.section s4oba +.section s4obb +.section s4oca +.section s4ocb +.section s4oda +.section s4odb +.section s4oea +.section s4oeb +.section s4ofa +.section s4ofb +.section s4oga +.section s4ogb +.section s4oha +.section s4ohb +.section s4oia +.section s4oib +.section s4oja +.section s4ojb +.section s4oka +.section s4okb +.section s4ola +.section s4olb +.section s4oma +.section s4omb +.section s4ona +.section s4onb +.section s4ooa +.section s4oob +.section s4opa +.section s4opb +.section s4oqa +.section s4oqb +.section s4ora +.section s4orb +.section s4osa +.section s4osb +.section s4ota +.section s4otb +.section s4oua +.section s4oub +.section s4ova +.section s4ovb +.section s4owa +.section s4owb +.section s4oxa +.section s4oxb +.section s4oya +.section s4oyb +.section s4oza +.section s4ozb +.section s4o1a +.section s4o1b +.section s4o2a +.section s4o2b +.section s4o3a +.section s4o3b +.section s4o4a +.section s4o4b +.section s4o5a +.section s4o5b +.section s4o6a +.section s4o6b +.section s4o7a +.section s4o7b +.section s4o8a +.section s4o8b +.section s4o9a +.section s4o9b +.section s4o0a +.section s4o0b +.section s4paa +.section s4pab +.section s4pba +.section s4pbb +.section s4pca +.section s4pcb +.section s4pda +.section s4pdb +.section s4pea +.section s4peb +.section s4pfa +.section s4pfb +.section s4pga +.section s4pgb +.section s4pha +.section s4phb +.section s4pia +.section s4pib +.section s4pja +.section s4pjb +.section s4pka +.section s4pkb +.section s4pla +.section s4plb +.section s4pma +.section s4pmb +.section s4pna +.section s4pnb +.section s4poa +.section s4pob +.section s4ppa +.section s4ppb +.section s4pqa +.section s4pqb +.section s4pra +.section s4prb +.section s4psa +.section s4psb +.section s4pta +.section s4ptb +.section s4pua +.section s4pub +.section s4pva +.section s4pvb +.section s4pwa +.section s4pwb +.section s4pxa +.section s4pxb +.section s4pya +.section s4pyb +.section s4pza +.section s4pzb +.section s4p1a +.section s4p1b +.section s4p2a +.section s4p2b +.section s4p3a +.section s4p3b +.section s4p4a +.section s4p4b +.section s4p5a +.section s4p5b +.section s4p6a +.section s4p6b +.section s4p7a +.section s4p7b +.section s4p8a +.section s4p8b +.section s4p9a +.section s4p9b +.section s4p0a +.section s4p0b +.section s4qaa +.section s4qab +.section s4qba +.section s4qbb +.section s4qca +.section s4qcb +.section s4qda +.section s4qdb +.section s4qea +.section s4qeb +.section s4qfa +.section s4qfb +.section s4qga +.section s4qgb +.section s4qha +.section s4qhb +.section s4qia +.section s4qib +.section s4qja +.section s4qjb +.section s4qka +.section s4qkb +.section s4qla +.section s4qlb +.section s4qma +.section s4qmb +.section s4qna +.section s4qnb +.section s4qoa +.section s4qob +.section s4qpa +.section s4qpb +.section s4qqa +.section s4qqb +.section s4qra +.section s4qrb +.section s4qsa +.section s4qsb +.section s4qta +.section s4qtb +.section s4qua +.section s4qub +.section s4qva +.section s4qvb +.section s4qwa +.section s4qwb +.section s4qxa +.section s4qxb +.section s4qya +.section s4qyb +.section s4qza +.section s4qzb +.section s4q1a +.section s4q1b +.section s4q2a +.section s4q2b +.section s4q3a +.section s4q3b +.section s4q4a +.section s4q4b +.section s4q5a +.section s4q5b +.section s4q6a +.section s4q6b +.section s4q7a +.section s4q7b +.section s4q8a +.section s4q8b +.section s4q9a +.section s4q9b +.section s4q0a +.section s4q0b +.section s4raa +.section s4rab +.section s4rba +.section s4rbb +.section s4rca +.section s4rcb +.section s4rda +.section s4rdb +.section s4rea +.section s4reb +.section s4rfa +.section s4rfb +.section s4rga +.section s4rgb +.section s4rha +.section s4rhb +.section s4ria +.section s4rib +.section s4rja +.section s4rjb +.section s4rka +.section s4rkb +.section s4rla +.section s4rlb +.section s4rma +.section s4rmb +.section s4rna +.section s4rnb +.section s4roa +.section s4rob +.section s4rpa +.section s4rpb +.section s4rqa +.section s4rqb +.section s4rra +.section s4rrb +.section s4rsa +.section s4rsb +.section s4rta +.section s4rtb +.section s4rua +.section s4rub +.section s4rva +.section s4rvb +.section s4rwa +.section s4rwb +.section s4rxa +.section s4rxb +.section s4rya +.section s4ryb +.section s4rza +.section s4rzb +.section s4r1a +.section s4r1b +.section s4r2a +.section s4r2b +.section s4r3a +.section s4r3b +.section s4r4a +.section s4r4b +.section s4r5a +.section s4r5b +.section s4r6a +.section s4r6b +.section s4r7a +.section s4r7b +.section s4r8a +.section s4r8b +.section s4r9a +.section s4r9b +.section s4r0a +.section s4r0b +.section s4saa +.section s4sab +.section s4sba +.section s4sbb +.section s4sca +.section s4scb +.section s4sda +.section s4sdb +.section s4sea +.section s4seb +.section s4sfa +.section s4sfb +.section s4sga +.section s4sgb +.section s4sha +.section s4shb +.section s4sia +.section s4sib +.section s4sja +.section s4sjb +.section s4ska +.section s4skb +.section s4sla +.section s4slb +.section s4sma +.section s4smb +.section s4sna +.section s4snb +.section s4soa +.section s4sob +.section s4spa +.section s4spb +.section s4sqa +.section s4sqb +.section s4sra +.section s4srb +.section s4ssa +.section s4ssb +.section s4sta +.section s4stb +.section s4sua +.section s4sub +.section s4sva +.section s4svb +.section s4swa +.section s4swb +.section s4sxa +.section s4sxb +.section s4sya +.section s4syb +.section s4sza +.section s4szb +.section s4s1a +.section s4s1b +.section s4s2a +.section s4s2b +.section s4s3a +.section s4s3b +.section s4s4a +.section s4s4b +.section s4s5a +.section s4s5b +.section s4s6a +.section s4s6b +.section s4s7a +.section s4s7b +.section s4s8a +.section s4s8b +.section s4s9a +.section s4s9b +.section s4s0a +.section s4s0b +.section s4taa +.section s4tab +.section s4tba +.section s4tbb +.section s4tca +.section s4tcb +.section s4tda +.section s4tdb +.section s4tea +.section s4teb +.section s4tfa +.section s4tfb +.section s4tga +.section s4tgb +.section s4tha +.section s4thb +.section s4tia +.section s4tib +.section s4tja +.section s4tjb +.section s4tka +.section s4tkb +.section s4tla +.section s4tlb +.section s4tma +.section s4tmb +.section s4tna +.section s4tnb +.section s4toa +.section s4tob +.section s4tpa +.section s4tpb +.section s4tqa +.section s4tqb +.section s4tra +.section s4trb +.section s4tsa +.section s4tsb +.section s4tta +.section s4ttb +.section s4tua +.section s4tub +.section s4tva +.section s4tvb +.section s4twa +.section s4twb +.section s4txa +.section s4txb +.section s4tya +.section s4tyb +.section s4tza +.section s4tzb +.section s4t1a +.section s4t1b +.section s4t2a +.section s4t2b +.section s4t3a +.section s4t3b +.section s4t4a +.section s4t4b +.section s4t5a +.section s4t5b +.section s4t6a +.section s4t6b +.section s4t7a +.section s4t7b +.section s4t8a +.section s4t8b +.section s4t9a +.section s4t9b +.section s4t0a +.section s4t0b +.section s4uaa +.section s4uab +.section s4uba +.section s4ubb +.section s4uca +.section s4ucb +.section s4uda +.section s4udb +.section s4uea +.section s4ueb +.section s4ufa +.section s4ufb +.section s4uga +.section s4ugb +.section s4uha +.section s4uhb +.section s4uia +.section s4uib +.section s4uja +.section s4ujb +.section s4uka +.section s4ukb +.section s4ula +.section s4ulb +.section s4uma +.section s4umb +.section s4una +.section s4unb +.section s4uoa +.section s4uob +.section s4upa +.section s4upb +.section s4uqa +.section s4uqb +.section s4ura +.section s4urb +.section s4usa +.section s4usb +.section s4uta +.section s4utb +.section s4uua +.section s4uub +.section s4uva +.section s4uvb +.section s4uwa +.section s4uwb +.section s4uxa +.section s4uxb +.section s4uya +.section s4uyb +.section s4uza +.section s4uzb +.section s4u1a +.section s4u1b +.section s4u2a +.section s4u2b +.section s4u3a +.section s4u3b +.section s4u4a +.section s4u4b +.section s4u5a +.section s4u5b +.section s4u6a +.section s4u6b +.section s4u7a +.section s4u7b +.section s4u8a +.section s4u8b +.section s4u9a +.section s4u9b +.section s4u0a +.section s4u0b +.section s4vaa +.section s4vab +.section s4vba +.section s4vbb +.section s4vca +.section s4vcb +.section s4vda +.section s4vdb +.section s4vea +.section s4veb +.section s4vfa +.section s4vfb +.section s4vga +.section s4vgb +.section s4vha +.section s4vhb +.section s4via +.section s4vib +.section s4vja +.section s4vjb +.section s4vka +.section s4vkb +.section s4vla +.section s4vlb +.section s4vma +.section s4vmb +.section s4vna +.section s4vnb +.section s4voa +.section s4vob +.section s4vpa +.section s4vpb +.section s4vqa +.section s4vqb +.section s4vra +.section s4vrb +.section s4vsa +.section s4vsb +.section s4vta +.section s4vtb +.section s4vua +.section s4vub +.section s4vva +.section s4vvb +.section s4vwa +.section s4vwb +.section s4vxa +.section s4vxb +.section s4vya +.section s4vyb +.section s4vza +.section s4vzb +.section s4v1a +.section s4v1b +.section s4v2a +.section s4v2b +.section s4v3a +.section s4v3b +.section s4v4a +.section s4v4b +.section s4v5a +.section s4v5b +.section s4v6a +.section s4v6b +.section s4v7a +.section s4v7b +.section s4v8a +.section s4v8b +.section s4v9a +.section s4v9b +.section s4v0a +.section s4v0b +.section s4waa +.section s4wab +.section s4wba +.section s4wbb +.section s4wca +.section s4wcb +.section s4wda +.section s4wdb +.section s4wea +.section s4web +.section s4wfa +.section s4wfb +.section s4wga +.section s4wgb +.section s4wha +.section s4whb +.section s4wia +.section s4wib +.section s4wja +.section s4wjb +.section s4wka +.section s4wkb +.section s4wla +.section s4wlb +.section s4wma +.section s4wmb +.section s4wna +.section s4wnb +.section s4woa +.section s4wob +.section s4wpa +.section s4wpb +.section s4wqa +.section s4wqb +.section s4wra +.section s4wrb +.section s4wsa +.section s4wsb +.section s4wta +.section s4wtb +.section s4wua +.section s4wub +.section s4wva +.section s4wvb +.section s4wwa +.section s4wwb +.section s4wxa +.section s4wxb +.section s4wya +.section s4wyb +.section s4wza +.section s4wzb +.section s4w1a +.section s4w1b +.section s4w2a +.section s4w2b +.section s4w3a +.section s4w3b +.section s4w4a +.section s4w4b +.section s4w5a +.section s4w5b +.section s4w6a +.section s4w6b +.section s4w7a +.section s4w7b +.section s4w8a +.section s4w8b +.section s4w9a +.section s4w9b +.section s4w0a +.section s4w0b +.section s4xaa +.section s4xab +.section s4xba +.section s4xbb +.section s4xca +.section s4xcb +.section s4xda +.section s4xdb +.section s4xea +.section s4xeb +.section s4xfa +.section s4xfb +.section s4xga +.section s4xgb +.section s4xha +.section s4xhb +.section s4xia +.section s4xib +.section s4xja +.section s4xjb +.section s4xka +.section s4xkb +.section s4xla +.section s4xlb +.section s4xma +.section s4xmb +.section s4xna +.section s4xnb +.section s4xoa +.section s4xob +.section s4xpa +.section s4xpb +.section s4xqa +.section s4xqb +.section s4xra +.section s4xrb +.section s4xsa +.section s4xsb +.section s4xta +.section s4xtb +.section s4xua +.section s4xub +.section s4xva +.section s4xvb +.section s4xwa +.section s4xwb +.section s4xxa +.section s4xxb +.section s4xya +.section s4xyb +.section s4xza +.section s4xzb +.section s4x1a +.section s4x1b +.section s4x2a +.section s4x2b +.section s4x3a +.section s4x3b +.section s4x4a +.section s4x4b +.section s4x5a +.section s4x5b +.section s4x6a +.section s4x6b +.section s4x7a +.section s4x7b +.section s4x8a +.section s4x8b +.section s4x9a +.section s4x9b +.section s4x0a +.section s4x0b +.section s4yaa +.section s4yab +.section s4yba +.section s4ybb +.section s4yca +.section s4ycb +.section s4yda +.section s4ydb +.section s4yea +.section s4yeb +.section s4yfa +.section s4yfb +.section s4yga +.section s4ygb +.section s4yha +.section s4yhb +.section s4yia +.section s4yib +.section s4yja +.section s4yjb +.section s4yka +.section s4ykb +.section s4yla +.section s4ylb +.section s4yma +.section s4ymb +.section s4yna +.section s4ynb +.section s4yoa +.section s4yob +.section s4ypa +.section s4ypb +.section s4yqa +.section s4yqb +.section s4yra +.section s4yrb +.section s4ysa +.section s4ysb +.section s4yta +.section s4ytb +.section s4yua +.section s4yub +.section s4yva +.section s4yvb +.section s4ywa +.section s4ywb +.section s4yxa +.section s4yxb +.section s4yya +.section s4yyb +.section s4yza +.section s4yzb +.section s4y1a +.section s4y1b +.section s4y2a +.section s4y2b +.section s4y3a +.section s4y3b +.section s4y4a +.section s4y4b +.section s4y5a +.section s4y5b +.section s4y6a +.section s4y6b +.section s4y7a +.section s4y7b +.section s4y8a +.section s4y8b +.section s4y9a +.section s4y9b +.section s4y0a +.section s4y0b +.section s4zaa +.section s4zab +.section s4zba +.section s4zbb +.section s4zca +.section s4zcb +.section s4zda +.section s4zdb +.section s4zea +.section s4zeb +.section s4zfa +.section s4zfb +.section s4zga +.section s4zgb +.section s4zha +.section s4zhb +.section s4zia +.section s4zib +.section s4zja +.section s4zjb +.section s4zka +.section s4zkb +.section s4zla +.section s4zlb +.section s4zma +.section s4zmb +.section s4zna +.section s4znb +.section s4zoa +.section s4zob +.section s4zpa +.section s4zpb +.section s4zqa +.section s4zqb +.section s4zra +.section s4zrb +.section s4zsa +.section s4zsb +.section s4zta +.section s4ztb +.section s4zua +.section s4zub +.section s4zva +.section s4zvb +.section s4zwa +.section s4zwb +.section s4zxa +.section s4zxb +.section s4zya +.section s4zyb +.section s4zza +.section s4zzb +.section s4z1a +.section s4z1b +.section s4z2a +.section s4z2b +.section s4z3a +.section s4z3b +.section s4z4a +.section s4z4b +.section s4z5a +.section s4z5b +.section s4z6a +.section s4z6b +.section s4z7a +.section s4z7b +.section s4z8a +.section s4z8b +.section s4z9a +.section s4z9b +.section s4z0a +.section s4z0b +.section s41aa +.section s41ab +.section s41ba +.section s41bb +.section s41ca +.section s41cb +.section s41da +.section s41db +.section s41ea +.section s41eb +.section s41fa +.section s41fb +.section s41ga +.section s41gb +.section s41ha +.section s41hb +.section s41ia +.section s41ib +.section s41ja +.section s41jb +.section s41ka +.section s41kb +.section s41la +.section s41lb +.section s41ma +.section s41mb +.section s41na +.section s41nb +.section s41oa +.section s41ob +.section s41pa +.section s41pb +.section s41qa +.section s41qb +.section s41ra +.section s41rb +.section s41sa +.section s41sb +.section s41ta +.section s41tb +.section s41ua +.section s41ub +.section s41va +.section s41vb +.section s41wa +.section s41wb +.section s41xa +.section s41xb +.section s41ya +.section s41yb +.section s41za +.section s41zb +.section s411a +.section s411b +.section s412a +.section s412b +.section s413a +.section s413b +.section s414a +.section s414b +.section s415a +.section s415b +.section s416a +.section s416b +.section s417a +.section s417b +.section s418a +.section s418b +.section s419a +.section s419b +.section s410a +.section s410b +.section s42aa +.section s42ab +.section s42ba +.section s42bb +.section s42ca +.section s42cb +.section s42da +.section s42db +.section s42ea +.section s42eb +.section s42fa +.section s42fb +.section s42ga +.section s42gb +.section s42ha +.section s42hb +.section s42ia +.section s42ib +.section s42ja +.section s42jb +.section s42ka +.section s42kb +.section s42la +.section s42lb +.section s42ma +.section s42mb +.section s42na +.section s42nb +.section s42oa +.section s42ob +.section s42pa +.section s42pb +.section s42qa +.section s42qb +.section s42ra +.section s42rb +.section s42sa +.section s42sb +.section s42ta +.section s42tb +.section s42ua +.section s42ub +.section s42va +.section s42vb +.section s42wa +.section s42wb +.section s42xa +.section s42xb +.section s42ya +.section s42yb +.section s42za +.section s42zb +.section s421a +.section s421b +.section s422a +.section s422b +.section s423a +.section s423b +.section s424a +.section s424b +.section s425a +.section s425b +.section s426a +.section s426b +.section s427a +.section s427b +.section s428a +.section s428b +.section s429a +.section s429b +.section s420a +.section s420b +.section s43aa +.section s43ab +.section s43ba +.section s43bb +.section s43ca +.section s43cb +.section s43da +.section s43db +.section s43ea +.section s43eb +.section s43fa +.section s43fb +.section s43ga +.section s43gb +.section s43ha +.section s43hb +.section s43ia +.section s43ib +.section s43ja +.section s43jb +.section s43ka +.section s43kb +.section s43la +.section s43lb +.section s43ma +.section s43mb +.section s43na +.section s43nb +.section s43oa +.section s43ob +.section s43pa +.section s43pb +.section s43qa +.section s43qb +.section s43ra +.section s43rb +.section s43sa +.section s43sb +.section s43ta +.section s43tb +.section s43ua +.section s43ub +.section s43va +.section s43vb +.section s43wa +.section s43wb +.section s43xa +.section s43xb +.section s43ya +.section s43yb +.section s43za +.section s43zb +.section s431a +.section s431b +.section s432a +.section s432b +.section s433a +.section s433b +.section s434a +.section s434b +.section s435a +.section s435b +.section s436a +.section s436b +.section s437a +.section s437b +.section s438a +.section s438b +.section s439a +.section s439b +.section s430a +.section s430b +.section s44aa +.section s44ab +.section s44ba +.section s44bb +.section s44ca +.section s44cb +.section s44da +.section s44db +.section s44ea +.section s44eb +.section s44fa +.section s44fb +.section s44ga +.section s44gb +.section s44ha +.section s44hb +.section s44ia +.section s44ib +.section s44ja +.section s44jb +.section s44ka +.section s44kb +.section s44la +.section s44lb +.section s44ma +.section s44mb +.section s44na +.section s44nb +.section s44oa +.section s44ob +.section s44pa +.section s44pb +.section s44qa +.section s44qb +.section s44ra +.section s44rb +.section s44sa +.section s44sb +.section s44ta +.section s44tb +.section s44ua +.section s44ub +.section s44va +.section s44vb +.section s44wa +.section s44wb +.section s44xa +.section s44xb +.section s44ya +.section s44yb +.section s44za +.section s44zb +.section s441a +.section s441b +.section s442a +.section s442b +.section s443a +.section s443b +.section s444a +.section s444b +.section s445a +.section s445b +.section s446a +.section s446b +.section s447a +.section s447b +.section s448a +.section s448b +.section s449a +.section s449b +.section s440a +.section s440b +.section s45aa +.section s45ab +.section s45ba +.section s45bb +.section s45ca +.section s45cb +.section s45da +.section s45db +.section s45ea +.section s45eb +.section s45fa +.section s45fb +.section s45ga +.section s45gb +.section s45ha +.section s45hb +.section s45ia +.section s45ib +.section s45ja +.section s45jb +.section s45ka +.section s45kb +.section s45la +.section s45lb +.section s45ma +.section s45mb +.section s45na +.section s45nb +.section s45oa +.section s45ob +.section s45pa +.section s45pb +.section s45qa +.section s45qb +.section s45ra +.section s45rb +.section s45sa +.section s45sb +.section s45ta +.section s45tb +.section s45ua +.section s45ub +.section s45va +.section s45vb +.section s45wa +.section s45wb +.section s45xa +.section s45xb +.section s45ya +.section s45yb +.section s45za +.section s45zb +.section s451a +.section s451b +.section s452a +.section s452b +.section s453a +.section s453b +.section s454a +.section s454b +.section s455a +.section s455b +.section s456a +.section s456b +.section s457a +.section s457b +.section s458a +.section s458b +.section s459a +.section s459b +.section s450a +.section s450b +.section s46aa +.section s46ab +.section s46ba +.section s46bb +.section s46ca +.section s46cb +.section s46da +.section s46db +.section s46ea +.section s46eb +.section s46fa +.section s46fb +.section s46ga +.section s46gb +.section s46ha +.section s46hb +.section s46ia +.section s46ib +.section s46ja +.section s46jb +.section s46ka +.section s46kb +.section s46la +.section s46lb +.section s46ma +.section s46mb +.section s46na +.section s46nb +.section s46oa +.section s46ob +.section s46pa +.section s46pb +.section s46qa +.section s46qb +.section s46ra +.section s46rb +.section s46sa +.section s46sb +.section s46ta +.section s46tb +.section s46ua +.section s46ub +.section s46va +.section s46vb +.section s46wa +.section s46wb +.section s46xa +.section s46xb +.section s46ya +.section s46yb +.section s46za +.section s46zb +.section s461a +.section s461b +.section s462a +.section s462b +.section s463a +.section s463b +.section s464a +.section s464b +.section s465a +.section s465b +.section s466a +.section s466b +.section s467a +.section s467b +.section s468a +.section s468b +.section s469a +.section s469b +.section s460a +.section s460b +.section s47aa +.section s47ab +.section s47ba +.section s47bb +.section s47ca +.section s47cb +.section s47da +.section s47db +.section s47ea +.section s47eb +.section s47fa +.section s47fb +.section s47ga +.section s47gb +.section s47ha +.section s47hb +.section s47ia +.section s47ib +.section s47ja +.section s47jb +.section s47ka +.section s47kb +.section s47la +.section s47lb +.section s47ma +.section s47mb +.section s47na +.section s47nb +.section s47oa +.section s47ob +.section s47pa +.section s47pb +.section s47qa +.section s47qb +.section s47ra +.section s47rb +.section s47sa +.section s47sb +.section s47ta +.section s47tb +.section s47ua +.section s47ub +.section s47va +.section s47vb +.section s47wa +.section s47wb +.section s47xa +.section s47xb +.section s47ya +.section s47yb +.section s47za +.section s47zb +.section s471a +.section s471b +.section s472a +.section s472b +.section s473a +.section s473b +.section s474a +.section s474b +.section s475a +.section s475b +.section s476a +.section s476b +.section s477a +.section s477b +.section s478a +.section s478b +.section s479a +.section s479b +.section s470a +.section s470b +.section s48aa +.section s48ab +.section s48ba +.section s48bb +.section s48ca +.section s48cb +.section s48da +.section s48db +.section s48ea +.section s48eb +.section s48fa +.section s48fb +.section s48ga +.section s48gb +.section s48ha +.section s48hb +.section s48ia +.section s48ib +.section s48ja +.section s48jb +.section s48ka +.section s48kb +.section s48la +.section s48lb +.section s48ma +.section s48mb +.section s48na +.section s48nb +.section s48oa +.section s48ob +.section s48pa +.section s48pb +.section s48qa +.section s48qb +.section s48ra +.section s48rb +.section s48sa +.section s48sb +.section s48ta +.section s48tb +.section s48ua +.section s48ub +.section s48va +.section s48vb +.section s48wa +.section s48wb +.section s48xa +.section s48xb +.section s48ya +.section s48yb +.section s48za +.section s48zb +.section s481a +.section s481b +.section s482a +.section s482b +.section s483a +.section s483b +.section s484a +.section s484b +.section s485a +.section s485b +.section s486a +.section s486b +.section s487a +.section s487b +.section s488a +.section s488b +.section s489a +.section s489b +.section s480a +.section s480b +.section s49aa +.section s49ab +.section s49ba +.section s49bb +.section s49ca +.section s49cb +.section s49da +.section s49db +.section s49ea +.section s49eb +.section s49fa +.section s49fb +.section s49ga +.section s49gb +.section s49ha +.section s49hb +.section s49ia +.section s49ib +.section s49ja +.section s49jb +.section s49ka +.section s49kb +.section s49la +.section s49lb +.section s49ma +.section s49mb +.section s49na +.section s49nb +.section s49oa +.section s49ob +.section s49pa +.section s49pb +.section s49qa +.section s49qb +.section s49ra +.section s49rb +.section s49sa +.section s49sb +.section s49ta +.section s49tb +.section s49ua +.section s49ub +.section s49va +.section s49vb +.section s49wa +.section s49wb +.section s49xa +.section s49xb +.section s49ya +.section s49yb +.section s49za +.section s49zb +.section s491a +.section s491b +.section s492a +.section s492b +.section s493a +.section s493b +.section s494a +.section s494b +.section s495a +.section s495b +.section s496a +.section s496b +.section s497a +.section s497b +.section s498a +.section s498b +.section s499a +.section s499b +.section s490a +.section s490b +.section s40aa +.section s40ab +.section s40ba +.section s40bb +.section s40ca +.section s40cb +.section s40da +.section s40db +.section s40ea +.section s40eb +.section s40fa +.section s40fb +.section s40ga +.section s40gb +.section s40ha +.section s40hb +.section s40ia +.section s40ib +.section s40ja +.section s40jb +.section s40ka +.section s40kb +.section s40la +.section s40lb +.section s40ma +.section s40mb +.section s40na +.section s40nb +.section s40oa +.section s40ob +.section s40pa +.section s40pb +.section s40qa +.section s40qb +.section s40ra +.section s40rb +.section s40sa +.section s40sb +.section s40ta +.section s40tb +.section s40ua +.section s40ub +.section s40va +.section s40vb +.section s40wa +.section s40wb +.section s40xa +.section s40xb +.section s40ya +.section s40yb +.section s40za +.section s40zb +.section s401a +.section s401b +.section s402a +.section s402b +.section s403a +.section s403b +.section s404a +.section s404b +.section s405a +.section s405b +.section s406a +.section s406b +.section s407a +.section s407b +.section s408a +.section s408b +.section s409a +.section s409b +.section s400a +.section s400b +.section s5aaa +.section s5aab +.section s5aba +.section s5abb +.section s5aca +.section s5acb +.section s5ada +.section s5adb +.section s5aea +.section s5aeb +.section s5afa +.section s5afb +.section s5aga +.section s5agb +.section s5aha +.section s5ahb +.section s5aia +.section s5aib +.section s5aja +.section s5ajb +.section s5aka +.section s5akb +.section s5ala +.section s5alb +.section s5ama +.section s5amb +.section s5ana +.section s5anb +.section s5aoa +.section s5aob +.section s5apa +.section s5apb +.section s5aqa +.section s5aqb +.section s5ara +.section s5arb +.section s5asa +.section s5asb +.section s5ata +.section s5atb +.section s5aua +.section s5aub +.section s5ava +.section s5avb +.section s5awa +.section s5awb +.section s5axa +.section s5axb +.section s5aya +.section s5ayb +.section s5aza +.section s5azb +.section s5a1a +.section s5a1b +.section s5a2a +.section s5a2b +.section s5a3a +.section s5a3b +.section s5a4a +.section s5a4b +.section s5a5a +.section s5a5b +.section s5a6a +.section s5a6b +.section s5a7a +.section s5a7b +.section s5a8a +.section s5a8b +.section s5a9a +.section s5a9b +.section s5a0a +.section s5a0b +.section s5baa +.section s5bab +.section s5bba +.section s5bbb +.section s5bca +.section s5bcb +.section s5bda +.section s5bdb +.section s5bea +.section s5beb +.section s5bfa +.section s5bfb +.section s5bga +.section s5bgb +.section s5bha +.section s5bhb +.section s5bia +.section s5bib +.section s5bja +.section s5bjb +.section s5bka +.section s5bkb +.section s5bla +.section s5blb +.section s5bma +.section s5bmb +.section s5bna +.section s5bnb +.section s5boa +.section s5bob +.section s5bpa +.section s5bpb +.section s5bqa +.section s5bqb +.section s5bra +.section s5brb +.section s5bsa +.section s5bsb +.section s5bta +.section s5btb +.section s5bua +.section s5bub +.section s5bva +.section s5bvb +.section s5bwa +.section s5bwb +.section s5bxa +.section s5bxb +.section s5bya +.section s5byb +.section s5bza +.section s5bzb +.section s5b1a +.section s5b1b +.section s5b2a +.section s5b2b +.section s5b3a +.section s5b3b +.section s5b4a +.section s5b4b +.section s5b5a +.section s5b5b +.section s5b6a +.section s5b6b +.section s5b7a +.section s5b7b +.section s5b8a +.section s5b8b +.section s5b9a +.section s5b9b +.section s5b0a +.section s5b0b +.section s5caa +.section s5cab +.section s5cba +.section s5cbb +.section s5cca +.section s5ccb +.section s5cda +.section s5cdb +.section s5cea +.section s5ceb +.section s5cfa +.section s5cfb +.section s5cga +.section s5cgb +.section s5cha +.section s5chb +.section s5cia +.section s5cib +.section s5cja +.section s5cjb +.section s5cka +.section s5ckb +.section s5cla +.section s5clb +.section s5cma +.section s5cmb +.section s5cna +.section s5cnb +.section s5coa +.section s5cob +.section s5cpa +.section s5cpb +.section s5cqa +.section s5cqb +.section s5cra +.section s5crb +.section s5csa +.section s5csb +.section s5cta +.section s5ctb +.section s5cua +.section s5cub +.section s5cva +.section s5cvb +.section s5cwa +.section s5cwb +.section s5cxa +.section s5cxb +.section s5cya +.section s5cyb +.section s5cza +.section s5czb +.section s5c1a +.section s5c1b +.section s5c2a +.section s5c2b +.section s5c3a +.section s5c3b +.section s5c4a +.section s5c4b +.section s5c5a +.section s5c5b +.section s5c6a +.section s5c6b +.section s5c7a +.section s5c7b +.section s5c8a +.section s5c8b +.section s5c9a +.section s5c9b +.section s5c0a +.section s5c0b +.section s5daa +.section s5dab +.section s5dba +.section s5dbb +.section s5dca +.section s5dcb +.section s5dda +.section s5ddb +.section s5dea +.section s5deb +.section s5dfa +.section s5dfb +.section s5dga +.section s5dgb +.section s5dha +.section s5dhb +.section s5dia +.section s5dib +.section s5dja +.section s5djb +.section s5dka +.section s5dkb +.section s5dla +.section s5dlb +.section s5dma +.section s5dmb +.section s5dna +.section s5dnb +.section s5doa +.section s5dob +.section s5dpa +.section s5dpb +.section s5dqa +.section s5dqb +.section s5dra +.section s5drb +.section s5dsa +.section s5dsb +.section s5dta +.section s5dtb +.section s5dua +.section s5dub +.section s5dva +.section s5dvb +.section s5dwa +.section s5dwb +.section s5dxa +.section s5dxb +.section s5dya +.section s5dyb +.section s5dza +.section s5dzb +.section s5d1a +.section s5d1b +.section s5d2a +.section s5d2b +.section s5d3a +.section s5d3b +.section s5d4a +.section s5d4b +.section s5d5a +.section s5d5b +.section s5d6a +.section s5d6b +.section s5d7a +.section s5d7b +.section s5d8a +.section s5d8b +.section s5d9a +.section s5d9b +.section s5d0a +.section s5d0b +.section s5eaa +.section s5eab +.section s5eba +.section s5ebb +.section s5eca +.section s5ecb +.section s5eda +.section s5edb +.section s5eea +.section s5eeb +.section s5efa +.section s5efb +.section s5ega +.section s5egb +.section s5eha +.section s5ehb +.section s5eia +.section s5eib +.section s5eja +.section s5ejb +.section s5eka +.section s5ekb +.section s5ela +.section s5elb +.section s5ema +.section s5emb +.section s5ena +.section s5enb +.section s5eoa +.section s5eob +.section s5epa +.section s5epb +.section s5eqa +.section s5eqb +.section s5era +.section s5erb +.section s5esa +.section s5esb +.section s5eta +.section s5etb +.section s5eua +.section s5eub +.section s5eva +.section s5evb +.section s5ewa +.section s5ewb +.section s5exa +.section s5exb +.section s5eya +.section s5eyb +.section s5eza +.section s5ezb +.section s5e1a +.section s5e1b +.section s5e2a +.section s5e2b +.section s5e3a +.section s5e3b +.section s5e4a +.section s5e4b +.section s5e5a +.section s5e5b +.section s5e6a +.section s5e6b +.section s5e7a +.section s5e7b +.section s5e8a +.section s5e8b +.section s5e9a +.section s5e9b +.section s5e0a +.section s5e0b +.section s5faa +.section s5fab +.section s5fba +.section s5fbb +.section s5fca +.section s5fcb +.section s5fda +.section s5fdb +.section s5fea +.section s5feb +.section s5ffa +.section s5ffb +.section s5fga +.section s5fgb +.section s5fha +.section s5fhb +.section s5fia +.section s5fib +.section s5fja +.section s5fjb +.section s5fka +.section s5fkb +.section s5fla +.section s5flb +.section s5fma +.section s5fmb +.section s5fna +.section s5fnb +.section s5foa +.section s5fob +.section s5fpa +.section s5fpb +.section s5fqa +.section s5fqb +.section s5fra +.section s5frb +.section s5fsa +.section s5fsb +.section s5fta +.section s5ftb +.section s5fua +.section s5fub +.section s5fva +.section s5fvb +.section s5fwa +.section s5fwb +.section s5fxa +.section s5fxb +.section s5fya +.section s5fyb +.section s5fza +.section s5fzb +.section s5f1a +.section s5f1b +.section s5f2a +.section s5f2b +.section s5f3a +.section s5f3b +.section s5f4a +.section s5f4b +.section s5f5a +.section s5f5b +.section s5f6a +.section s5f6b +.section s5f7a +.section s5f7b +.section s5f8a +.section s5f8b +.section s5f9a +.section s5f9b +.section s5f0a +.section s5f0b +.section s5gaa +.section s5gab +.section s5gba +.section s5gbb +.section s5gca +.section s5gcb +.section s5gda +.section s5gdb +.section s5gea +.section s5geb +.section s5gfa +.section s5gfb +.section s5gga +.section s5ggb +.section s5gha +.section s5ghb +.section s5gia +.section s5gib +.section s5gja +.section s5gjb +.section s5gka +.section s5gkb +.section s5gla +.section s5glb +.section s5gma +.section s5gmb +.section s5gna +.section s5gnb +.section s5goa +.section s5gob +.section s5gpa +.section s5gpb +.section s5gqa +.section s5gqb +.section s5gra +.section s5grb +.section s5gsa +.section s5gsb +.section s5gta +.section s5gtb +.section s5gua +.section s5gub +.section s5gva +.section s5gvb +.section s5gwa +.section s5gwb +.section s5gxa +.section s5gxb +.section s5gya +.section s5gyb +.section s5gza +.section s5gzb +.section s5g1a +.section s5g1b +.section s5g2a +.section s5g2b +.section s5g3a +.section s5g3b +.section s5g4a +.section s5g4b +.section s5g5a +.section s5g5b +.section s5g6a +.section s5g6b +.section s5g7a +.section s5g7b +.section s5g8a +.section s5g8b +.section s5g9a +.section s5g9b +.section s5g0a +.section s5g0b +.section s5haa +.section s5hab +.section s5hba +.section s5hbb +.section s5hca +.section s5hcb +.section s5hda +.section s5hdb +.section s5hea +.section s5heb +.section s5hfa +.section s5hfb +.section s5hga +.section s5hgb +.section s5hha +.section s5hhb +.section s5hia +.section s5hib +.section s5hja +.section s5hjb +.section s5hka +.section s5hkb +.section s5hla +.section s5hlb +.section s5hma +.section s5hmb +.section s5hna +.section s5hnb +.section s5hoa +.section s5hob +.section s5hpa +.section s5hpb +.section s5hqa +.section s5hqb +.section s5hra +.section s5hrb +.section s5hsa +.section s5hsb +.section s5hta +.section s5htb +.section s5hua +.section s5hub +.section s5hva +.section s5hvb +.section s5hwa +.section s5hwb +.section s5hxa +.section s5hxb +.section s5hya +.section s5hyb +.section s5hza +.section s5hzb +.section s5h1a +.section s5h1b +.section s5h2a +.section s5h2b +.section s5h3a +.section s5h3b +.section s5h4a +.section s5h4b +.section s5h5a +.section s5h5b +.section s5h6a +.section s5h6b +.section s5h7a +.section s5h7b +.section s5h8a +.section s5h8b +.section s5h9a +.section s5h9b +.section s5h0a +.section s5h0b +.section s5iaa +.section s5iab +.section s5iba +.section s5ibb +.section s5ica +.section s5icb +.section s5ida +.section s5idb +.section s5iea +.section s5ieb +.section s5ifa +.section s5ifb +.section s5iga +.section s5igb +.section s5iha +.section s5ihb +.section s5iia +.section s5iib +.section s5ija +.section s5ijb +.section s5ika +.section s5ikb +.section s5ila +.section s5ilb +.section s5ima +.section s5imb +.section s5ina +.section s5inb +.section s5ioa +.section s5iob +.section s5ipa +.section s5ipb +.section s5iqa +.section s5iqb +.section s5ira +.section s5irb +.section s5isa +.section s5isb +.section s5ita +.section s5itb +.section s5iua +.section s5iub +.section s5iva +.section s5ivb +.section s5iwa +.section s5iwb +.section s5ixa +.section s5ixb +.section s5iya +.section s5iyb +.section s5iza +.section s5izb +.section s5i1a +.section s5i1b +.section s5i2a +.section s5i2b +.section s5i3a +.section s5i3b +.section s5i4a +.section s5i4b +.section s5i5a +.section s5i5b +.section s5i6a +.section s5i6b +.section s5i7a +.section s5i7b +.section s5i8a +.section s5i8b +.section s5i9a +.section s5i9b +.section s5i0a +.section s5i0b +.section s5jaa +.section s5jab +.section s5jba +.section s5jbb +.section s5jca +.section s5jcb +.section s5jda +.section s5jdb +.section s5jea +.section s5jeb +.section s5jfa +.section s5jfb +.section s5jga +.section s5jgb +.section s5jha +.section s5jhb +.section s5jia +.section s5jib +.section s5jja +.section s5jjb +.section s5jka +.section s5jkb +.section s5jla +.section s5jlb +.section s5jma +.section s5jmb +.section s5jna +.section s5jnb +.section s5joa +.section s5job +.section s5jpa +.section s5jpb +.section s5jqa +.section s5jqb +.section s5jra +.section s5jrb +.section s5jsa +.section s5jsb +.section s5jta +.section s5jtb +.section s5jua +.section s5jub +.section s5jva +.section s5jvb +.section s5jwa +.section s5jwb +.section s5jxa +.section s5jxb +.section s5jya +.section s5jyb +.section s5jza +.section s5jzb +.section s5j1a +.section s5j1b +.section s5j2a +.section s5j2b +.section s5j3a +.section s5j3b +.section s5j4a +.section s5j4b +.section s5j5a +.section s5j5b +.section s5j6a +.section s5j6b +.section s5j7a +.section s5j7b +.section s5j8a +.section s5j8b +.section s5j9a +.section s5j9b +.section s5j0a +.section s5j0b +.section s5kaa +.section s5kab +.section s5kba +.section s5kbb +.section s5kca +.section s5kcb +.section s5kda +.section s5kdb +.section s5kea +.section s5keb +.section s5kfa +.section s5kfb +.section s5kga +.section s5kgb +.section s5kha +.section s5khb +.section s5kia +.section s5kib +.section s5kja +.section s5kjb +.section s5kka +.section s5kkb +.section s5kla +.section s5klb +.section s5kma +.section s5kmb +.section s5kna +.section s5knb +.section s5koa +.section s5kob +.section s5kpa +.section s5kpb +.section s5kqa +.section s5kqb +.section s5kra +.section s5krb +.section s5ksa +.section s5ksb +.section s5kta +.section s5ktb +.section s5kua +.section s5kub +.section s5kva +.section s5kvb +.section s5kwa +.section s5kwb +.section s5kxa +.section s5kxb +.section s5kya +.section s5kyb +.section s5kza +.section s5kzb +.section s5k1a +.section s5k1b +.section s5k2a +.section s5k2b +.section s5k3a +.section s5k3b +.section s5k4a +.section s5k4b +.section s5k5a +.section s5k5b +.section s5k6a +.section s5k6b +.section s5k7a +.section s5k7b +.section s5k8a +.section s5k8b +.section s5k9a +.section s5k9b +.section s5k0a +.section s5k0b +.section s5laa +.section s5lab +.section s5lba +.section s5lbb +.section s5lca +.section s5lcb +.section s5lda +.section s5ldb +.section s5lea +.section s5leb +.section s5lfa +.section s5lfb +.section s5lga +.section s5lgb +.section s5lha +.section s5lhb +.section s5lia +.section s5lib +.section s5lja +.section s5ljb +.section s5lka +.section s5lkb +.section s5lla +.section s5llb +.section s5lma +.section s5lmb +.section s5lna +.section s5lnb +.section s5loa +.section s5lob +.section s5lpa +.section s5lpb +.section s5lqa +.section s5lqb +.section s5lra +.section s5lrb +.section s5lsa +.section s5lsb +.section s5lta +.section s5ltb +.section s5lua +.section s5lub +.section s5lva +.section s5lvb +.section s5lwa +.section s5lwb +.section s5lxa +.section s5lxb +.section s5lya +.section s5lyb +.section s5lza +.section s5lzb +.section s5l1a +.section s5l1b +.section s5l2a +.section s5l2b +.section s5l3a +.section s5l3b +.section s5l4a +.section s5l4b +.section s5l5a +.section s5l5b +.section s5l6a +.section s5l6b +.section s5l7a +.section s5l7b +.section s5l8a +.section s5l8b +.section s5l9a +.section s5l9b +.section s5l0a +.section s5l0b +.section s5maa +.section s5mab +.section s5mba +.section s5mbb +.section s5mca +.section s5mcb +.section s5mda +.section s5mdb +.section s5mea +.section s5meb +.section s5mfa +.section s5mfb +.section s5mga +.section s5mgb +.section s5mha +.section s5mhb +.section s5mia +.section s5mib +.section s5mja +.section s5mjb +.section s5mka +.section s5mkb +.section s5mla +.section s5mlb +.section s5mma +.section s5mmb +.section s5mna +.section s5mnb +.section s5moa +.section s5mob +.section s5mpa +.section s5mpb +.section s5mqa +.section s5mqb +.section s5mra +.section s5mrb +.section s5msa +.section s5msb +.section s5mta +.section s5mtb +.section s5mua +.section s5mub +.section s5mva +.section s5mvb +.section s5mwa +.section s5mwb +.section s5mxa +.section s5mxb +.section s5mya +.section s5myb +.section s5mza +.section s5mzb +.section s5m1a +.section s5m1b +.section s5m2a +.section s5m2b +.section s5m3a +.section s5m3b +.section s5m4a +.section s5m4b +.section s5m5a +.section s5m5b +.section s5m6a +.section s5m6b +.section s5m7a +.section s5m7b +.section s5m8a +.section s5m8b +.section s5m9a +.section s5m9b +.section s5m0a +.section s5m0b +.section s5naa +.section s5nab +.section s5nba +.section s5nbb +.section s5nca +.section s5ncb +.section s5nda +.section s5ndb +.section s5nea +.section s5neb +.section s5nfa +.section s5nfb +.section s5nga +.section s5ngb +.section s5nha +.section s5nhb +.section s5nia +.section s5nib +.section s5nja +.section s5njb +.section s5nka +.section s5nkb +.section s5nla +.section s5nlb +.section s5nma +.section s5nmb +.section s5nna +.section s5nnb +.section s5noa +.section s5nob +.section s5npa +.section s5npb +.section s5nqa +.section s5nqb +.section s5nra +.section s5nrb +.section s5nsa +.section s5nsb +.section s5nta +.section s5ntb +.section s5nua +.section s5nub +.section s5nva +.section s5nvb +.section s5nwa +.section s5nwb +.section s5nxa +.section s5nxb +.section s5nya +.section s5nyb +.section s5nza +.section s5nzb +.section s5n1a +.section s5n1b +.section s5n2a +.section s5n2b +.section s5n3a +.section s5n3b +.section s5n4a +.section s5n4b +.section s5n5a +.section s5n5b +.section s5n6a +.section s5n6b +.section s5n7a +.section s5n7b +.section s5n8a +.section s5n8b +.section s5n9a +.section s5n9b +.section s5n0a +.section s5n0b +.section s5oaa +.section s5oab +.section s5oba +.section s5obb +.section s5oca +.section s5ocb +.section s5oda +.section s5odb +.section s5oea +.section s5oeb +.section s5ofa +.section s5ofb +.section s5oga +.section s5ogb +.section s5oha +.section s5ohb +.section s5oia +.section s5oib +.section s5oja +.section s5ojb +.section s5oka +.section s5okb +.section s5ola +.section s5olb +.section s5oma +.section s5omb +.section s5ona +.section s5onb +.section s5ooa +.section s5oob +.section s5opa +.section s5opb +.section s5oqa +.section s5oqb +.section s5ora +.section s5orb +.section s5osa +.section s5osb +.section s5ota +.section s5otb +.section s5oua +.section s5oub +.section s5ova +.section s5ovb +.section s5owa +.section s5owb +.section s5oxa +.section s5oxb +.section s5oya +.section s5oyb +.section s5oza +.section s5ozb +.section s5o1a +.section s5o1b +.section s5o2a +.section s5o2b +.section s5o3a +.section s5o3b +.section s5o4a +.section s5o4b +.section s5o5a +.section s5o5b +.section s5o6a +.section s5o6b +.section s5o7a +.section s5o7b +.section s5o8a +.section s5o8b +.section s5o9a +.section s5o9b +.section s5o0a +.section s5o0b +.section s5paa +.section s5pab +.section s5pba +.section s5pbb +.section s5pca +.section s5pcb +.section s5pda +.section s5pdb +.section s5pea +.section s5peb +.section s5pfa +.section s5pfb +.section s5pga +.section s5pgb +.section s5pha +.section s5phb +.section s5pia +.section s5pib +.section s5pja +.section s5pjb +.section s5pka +.section s5pkb +.section s5pla +.section s5plb +.section s5pma +.section s5pmb +.section s5pna +.section s5pnb +.section s5poa +.section s5pob +.section s5ppa +.section s5ppb +.section s5pqa +.section s5pqb +.section s5pra +.section s5prb +.section s5psa +.section s5psb +.section s5pta +.section s5ptb +.section s5pua +.section s5pub +.section s5pva +.section s5pvb +.section s5pwa +.section s5pwb +.section s5pxa +.section s5pxb +.section s5pya +.section s5pyb +.section s5pza +.section s5pzb +.section s5p1a +.section s5p1b +.section s5p2a +.section s5p2b +.section s5p3a +.section s5p3b +.section s5p4a +.section s5p4b +.section s5p5a +.section s5p5b +.section s5p6a +.section s5p6b +.section s5p7a +.section s5p7b +.section s5p8a +.section s5p8b +.section s5p9a +.section s5p9b +.section s5p0a +.section s5p0b +.section s5qaa +.section s5qab +.section s5qba +.section s5qbb +.section s5qca +.section s5qcb +.section s5qda +.section s5qdb +.section s5qea +.section s5qeb +.section s5qfa +.section s5qfb +.section s5qga +.section s5qgb +.section s5qha +.section s5qhb +.section s5qia +.section s5qib +.section s5qja +.section s5qjb +.section s5qka +.section s5qkb +.section s5qla +.section s5qlb +.section s5qma +.section s5qmb +.section s5qna +.section s5qnb +.section s5qoa +.section s5qob +.section s5qpa +.section s5qpb +.section s5qqa +.section s5qqb +.section s5qra +.section s5qrb +.section s5qsa +.section s5qsb +.section s5qta +.section s5qtb +.section s5qua +.section s5qub +.section s5qva +.section s5qvb +.section s5qwa +.section s5qwb +.section s5qxa +.section s5qxb +.section s5qya +.section s5qyb +.section s5qza +.section s5qzb +.section s5q1a +.section s5q1b +.section s5q2a +.section s5q2b +.section s5q3a +.section s5q3b +.section s5q4a +.section s5q4b +.section s5q5a +.section s5q5b +.section s5q6a +.section s5q6b +.section s5q7a +.section s5q7b +.section s5q8a +.section s5q8b +.section s5q9a +.section s5q9b +.section s5q0a +.section s5q0b +.section s5raa +.section s5rab +.section s5rba +.section s5rbb +.section s5rca +.section s5rcb +.section s5rda +.section s5rdb +.section s5rea +.section s5reb +.section s5rfa +.section s5rfb +.section s5rga +.section s5rgb +.section s5rha +.section s5rhb +.section s5ria +.section s5rib +.section s5rja +.section s5rjb +.section s5rka +.section s5rkb +.section s5rla +.section s5rlb +.section s5rma +.section s5rmb +.section s5rna +.section s5rnb +.section s5roa +.section s5rob +.section s5rpa +.section s5rpb +.section s5rqa +.section s5rqb +.section s5rra +.section s5rrb +.section s5rsa +.section s5rsb +.section s5rta +.section s5rtb +.section s5rua +.section s5rub +.section s5rva +.section s5rvb +.section s5rwa +.section s5rwb +.section s5rxa +.section s5rxb +.section s5rya +.section s5ryb +.section s5rza +.section s5rzb +.section s5r1a +.section s5r1b +.section s5r2a +.section s5r2b +.section s5r3a +.section s5r3b +.section s5r4a +.section s5r4b +.section s5r5a +.section s5r5b +.section s5r6a +.section s5r6b +.section s5r7a +.section s5r7b +.section s5r8a +.section s5r8b +.section s5r9a +.section s5r9b +.section s5r0a +.section s5r0b +.section s5saa +.section s5sab +.section s5sba +.section s5sbb +.section s5sca +.section s5scb +.section s5sda +.section s5sdb +.section s5sea +.section s5seb +.section s5sfa +.section s5sfb +.section s5sga +.section s5sgb +.section s5sha +.section s5shb +.section s5sia +.section s5sib +.section s5sja +.section s5sjb +.section s5ska +.section s5skb +.section s5sla +.section s5slb +.section s5sma +.section s5smb +.section s5sna +.section s5snb +.section s5soa +.section s5sob +.section s5spa +.section s5spb +.section s5sqa +.section s5sqb +.section s5sra +.section s5srb +.section s5ssa +.section s5ssb +.section s5sta +.section s5stb +.section s5sua +.section s5sub +.section s5sva +.section s5svb +.section s5swa +.section s5swb +.section s5sxa +.section s5sxb +.section s5sya +.section s5syb +.section s5sza +.section s5szb +.section s5s1a +.section s5s1b +.section s5s2a +.section s5s2b +.section s5s3a +.section s5s3b +.section s5s4a +.section s5s4b +.section s5s5a +.section s5s5b +.section s5s6a +.section s5s6b +.section s5s7a +.section s5s7b +.section s5s8a +.section s5s8b +.section s5s9a +.section s5s9b +.section s5s0a +.section s5s0b +.section s5taa +.section s5tab +.section s5tba +.section s5tbb +.section s5tca +.section s5tcb +.section s5tda +.section s5tdb +.section s5tea +.section s5teb +.section s5tfa +.section s5tfb +.section s5tga +.section s5tgb +.section s5tha +.section s5thb +.section s5tia +.section s5tib +.section s5tja +.section s5tjb +.section s5tka +.section s5tkb +.section s5tla +.section s5tlb +.section s5tma +.section s5tmb +.section s5tna +.section s5tnb +.section s5toa +.section s5tob +.section s5tpa +.section s5tpb +.section s5tqa +.section s5tqb +.section s5tra +.section s5trb +.section s5tsa +.section s5tsb +.section s5tta +.section s5ttb +.section s5tua +.section s5tub +.section s5tva +.section s5tvb +.section s5twa +.section s5twb +.section s5txa +.section s5txb +.section s5tya +.section s5tyb +.section s5tza +.section s5tzb +.section s5t1a +.section s5t1b +.section s5t2a +.section s5t2b +.section s5t3a +.section s5t3b +.section s5t4a +.section s5t4b +.section s5t5a +.section s5t5b +.section s5t6a +.section s5t6b +.section s5t7a +.section s5t7b +.section s5t8a +.section s5t8b +.section s5t9a +.section s5t9b +.section s5t0a +.section s5t0b +.section s5uaa +.section s5uab +.section s5uba +.section s5ubb +.section s5uca +.section s5ucb +.section s5uda +.section s5udb +.section s5uea +.section s5ueb +.section s5ufa +.section s5ufb +.section s5uga +.section s5ugb +.section s5uha +.section s5uhb +.section s5uia +.section s5uib +.section s5uja +.section s5ujb +.section s5uka +.section s5ukb +.section s5ula +.section s5ulb +.section s5uma +.section s5umb +.section s5una +.section s5unb +.section s5uoa +.section s5uob +.section s5upa +.section s5upb +.section s5uqa +.section s5uqb +.section s5ura +.section s5urb +.section s5usa +.section s5usb +.section s5uta +.section s5utb +.section s5uua +.section s5uub +.section s5uva +.section s5uvb +.section s5uwa +.section s5uwb +.section s5uxa +.section s5uxb +.section s5uya +.section s5uyb +.section s5uza +.section s5uzb +.section s5u1a +.section s5u1b +.section s5u2a +.section s5u2b +.section s5u3a +.section s5u3b +.section s5u4a +.section s5u4b +.section s5u5a +.section s5u5b +.section s5u6a +.section s5u6b +.section s5u7a +.section s5u7b +.section s5u8a +.section s5u8b +.section s5u9a +.section s5u9b +.section s5u0a +.section s5u0b +.section s5vaa +.section s5vab +.section s5vba +.section s5vbb +.section s5vca +.section s5vcb +.section s5vda +.section s5vdb +.section s5vea +.section s5veb +.section s5vfa +.section s5vfb +.section s5vga +.section s5vgb +.section s5vha +.section s5vhb +.section s5via +.section s5vib +.section s5vja +.section s5vjb +.section s5vka +.section s5vkb +.section s5vla +.section s5vlb +.section s5vma +.section s5vmb +.section s5vna +.section s5vnb +.section s5voa +.section s5vob +.section s5vpa +.section s5vpb +.section s5vqa +.section s5vqb +.section s5vra +.section s5vrb +.section s5vsa +.section s5vsb +.section s5vta +.section s5vtb +.section s5vua +.section s5vub +.section s5vva +.section s5vvb +.section s5vwa +.section s5vwb +.section s5vxa +.section s5vxb +.section s5vya +.section s5vyb +.section s5vza +.section s5vzb +.section s5v1a +.section s5v1b +.section s5v2a +.section s5v2b +.section s5v3a +.section s5v3b +.section s5v4a +.section s5v4b +.section s5v5a +.section s5v5b +.section s5v6a +.section s5v6b +.section s5v7a +.section s5v7b +.section s5v8a +.section s5v8b +.section s5v9a +.section s5v9b +.section s5v0a +.section s5v0b +.section s5waa +.section s5wab +.section s5wba +.section s5wbb +.section s5wca +.section s5wcb +.section s5wda +.section s5wdb +.section s5wea +.section s5web +.section s5wfa +.section s5wfb +.section s5wga +.section s5wgb +.section s5wha +.section s5whb +.section s5wia +.section s5wib +.section s5wja +.section s5wjb +.section s5wka +.section s5wkb +.section s5wla +.section s5wlb +.section s5wma +.section s5wmb +.section s5wna +.section s5wnb +.section s5woa +.section s5wob +.section s5wpa +.section s5wpb +.section s5wqa +.section s5wqb +.section s5wra +.section s5wrb +.section s5wsa +.section s5wsb +.section s5wta +.section s5wtb +.section s5wua +.section s5wub +.section s5wva +.section s5wvb +.section s5wwa +.section s5wwb +.section s5wxa +.section s5wxb +.section s5wya +.section s5wyb +.section s5wza +.section s5wzb +.section s5w1a +.section s5w1b +.section s5w2a +.section s5w2b +.section s5w3a +.section s5w3b +.section s5w4a +.section s5w4b +.section s5w5a +.section s5w5b +.section s5w6a +.section s5w6b +.section s5w7a +.section s5w7b +.section s5w8a +.section s5w8b +.section s5w9a +.section s5w9b +.section s5w0a +.section s5w0b +.section s5xaa +.section s5xab +.section s5xba +.section s5xbb +.section s5xca +.section s5xcb +.section s5xda +.section s5xdb +.section s5xea +.section s5xeb +.section s5xfa +.section s5xfb +.section s5xga +.section s5xgb +.section s5xha +.section s5xhb +.section s5xia +.section s5xib +.section s5xja +.section s5xjb +.section s5xka +.section s5xkb +.section s5xla +.section s5xlb +.section s5xma +.section s5xmb +.section s5xna +.section s5xnb +.section s5xoa +.section s5xob +.section s5xpa +.section s5xpb +.section s5xqa +.section s5xqb +.section s5xra +.section s5xrb +.section s5xsa +.section s5xsb +.section s5xta +.section s5xtb +.section s5xua +.section s5xub +.section s5xva +.section s5xvb +.section s5xwa +.section s5xwb +.section s5xxa +.section s5xxb +.section s5xya +.section s5xyb +.section s5xza +.section s5xzb +.section s5x1a +.section s5x1b +.section s5x2a +.section s5x2b +.section s5x3a +.section s5x3b +.section s5x4a +.section s5x4b +.section s5x5a +.section s5x5b +.section s5x6a +.section s5x6b +.section s5x7a +.section s5x7b +.section s5x8a +.section s5x8b +.section s5x9a +.section s5x9b +.section s5x0a +.section s5x0b +.section s5yaa +.section s5yab +.section s5yba +.section s5ybb +.section s5yca +.section s5ycb +.section s5yda +.section s5ydb +.section s5yea +.section s5yeb +.section s5yfa +.section s5yfb +.section s5yga +.section s5ygb +.section s5yha +.section s5yhb +.section s5yia +.section s5yib +.section s5yja +.section s5yjb +.section s5yka +.section s5ykb +.section s5yla +.section s5ylb +.section s5yma +.section s5ymb +.section s5yna +.section s5ynb +.section s5yoa +.section s5yob +.section s5ypa +.section s5ypb +.section s5yqa +.section s5yqb +.section s5yra +.section s5yrb +.section s5ysa +.section s5ysb +.section s5yta +.section s5ytb +.section s5yua +.section s5yub +.section s5yva +.section s5yvb +.section s5ywa +.section s5ywb +.section s5yxa +.section s5yxb +.section s5yya +.section s5yyb +.section s5yza +.section s5yzb +.section s5y1a +.section s5y1b +.section s5y2a +.section s5y2b +.section s5y3a +.section s5y3b +.section s5y4a +.section s5y4b +.section s5y5a +.section s5y5b +.section s5y6a +.section s5y6b +.section s5y7a +.section s5y7b +.section s5y8a +.section s5y8b +.section s5y9a +.section s5y9b +.section s5y0a +.section s5y0b +.section s5zaa +.section s5zab +.section s5zba +.section s5zbb +.section s5zca +.section s5zcb +.section s5zda +.section s5zdb +.section s5zea +.section s5zeb +.section s5zfa +.section s5zfb +.section s5zga +.section s5zgb +.section s5zha +.section s5zhb +.section s5zia +.section s5zib +.section s5zja +.section s5zjb +.section s5zka +.section s5zkb +.section s5zla +.section s5zlb +.section s5zma +.section s5zmb +.section s5zna +.section s5znb +.section s5zoa +.section s5zob +.section s5zpa +.section s5zpb +.section s5zqa +.section s5zqb +.section s5zra +.section s5zrb +.section s5zsa +.section s5zsb +.section s5zta +.section s5ztb +.section s5zua +.section s5zub +.section s5zva +.section s5zvb +.section s5zwa +.section s5zwb +.section s5zxa +.section s5zxb +.section s5zya +.section s5zyb +.section s5zza +.section s5zzb +.section s5z1a +.section s5z1b +.section s5z2a +.section s5z2b +.section s5z3a +.section s5z3b +.section s5z4a +.section s5z4b +.section s5z5a +.section s5z5b +.section s5z6a +.section s5z6b +.section s5z7a +.section s5z7b +.section s5z8a +.section s5z8b +.section s5z9a +.section s5z9b +.section s5z0a +.section s5z0b +.section s51aa +.section s51ab +.section s51ba +.section s51bb +.section s51ca +.section s51cb +.section s51da +.section s51db +.section s51ea +.section s51eb +.section s51fa +.section s51fb +.section s51ga +.section s51gb +.section s51ha +.section s51hb +.section s51ia +.section s51ib +.section s51ja +.section s51jb +.section s51ka +.section s51kb +.section s51la +.section s51lb +.section s51ma +.section s51mb +.section s51na +.section s51nb +.section s51oa +.section s51ob +.section s51pa +.section s51pb +.section s51qa +.section s51qb +.section s51ra +.section s51rb +.section s51sa +.section s51sb +.section s51ta +.section s51tb +.section s51ua +.section s51ub +.section s51va +.section s51vb +.section s51wa +.section s51wb +.section s51xa +.section s51xb +.section s51ya +.section s51yb +.section s51za +.section s51zb +.section s511a +.section s511b +.section s512a +.section s512b +.section s513a +.section s513b +.section s514a +.section s514b +.section s515a +.section s515b +.section s516a +.section s516b +.section s517a +.section s517b +.section s518a +.section s518b +.section s519a +.section s519b +.section s510a +.section s510b +.section s52aa +.section s52ab +.section s52ba +.section s52bb +.section s52ca +.section s52cb +.section s52da +.section s52db +.section s52ea +.section s52eb +.section s52fa +.section s52fb +.section s52ga +.section s52gb +.section s52ha +.section s52hb +.section s52ia +.section s52ib +.section s52ja +.section s52jb +.section s52ka +.section s52kb +.section s52la +.section s52lb +.section s52ma +.section s52mb +.section s52na +.section s52nb +.section s52oa +.section s52ob +.section s52pa +.section s52pb +.section s52qa +.section s52qb +.section s52ra +.section s52rb +.section s52sa +.section s52sb +.section s52ta +.section s52tb +.section s52ua +.section s52ub +.section s52va +.section s52vb +.section s52wa +.section s52wb +.section s52xa +.section s52xb +.section s52ya +.section s52yb +.section s52za +.section s52zb +.section s521a +.section s521b +.section s522a +.section s522b +.section s523a +.section s523b +.section s524a +.section s524b +.section s525a +.section s525b +.section s526a +.section s526b +.section s527a +.section s527b +.section s528a +.section s528b +.section s529a +.section s529b +.section s520a +.section s520b +.section s53aa +.section s53ab +.section s53ba +.section s53bb +.section s53ca +.section s53cb +.section s53da +.section s53db +.section s53ea +.section s53eb +.section s53fa +.section s53fb +.section s53ga +.section s53gb +.section s53ha +.section s53hb +.section s53ia +.section s53ib +.section s53ja +.section s53jb +.section s53ka +.section s53kb +.section s53la +.section s53lb +.section s53ma +.section s53mb +.section s53na +.section s53nb +.section s53oa +.section s53ob +.section s53pa +.section s53pb +.section s53qa +.section s53qb +.section s53ra +.section s53rb +.section s53sa +.section s53sb +.section s53ta +.section s53tb +.section s53ua +.section s53ub +.section s53va +.section s53vb +.section s53wa +.section s53wb +.section s53xa +.section s53xb +.section s53ya +.section s53yb +.section s53za +.section s53zb +.section s531a +.section s531b +.section s532a +.section s532b +.section s533a +.section s533b +.section s534a +.section s534b +.section s535a +.section s535b +.section s536a +.section s536b +.section s537a +.section s537b +.section s538a +.section s538b +.section s539a +.section s539b +.section s530a +.section s530b +.section s54aa +.section s54ab +.section s54ba +.section s54bb +.section s54ca +.section s54cb +.section s54da +.section s54db +.section s54ea +.section s54eb +.section s54fa +.section s54fb +.section s54ga +.section s54gb +.section s54ha +.section s54hb +.section s54ia +.section s54ib +.section s54ja +.section s54jb +.section s54ka +.section s54kb +.section s54la +.section s54lb +.section s54ma +.section s54mb +.section s54na +.section s54nb +.section s54oa +.section s54ob +.section s54pa +.section s54pb +.section s54qa +.section s54qb +.section s54ra +.section s54rb +.section s54sa +.section s54sb +.section s54ta +.section s54tb +.section s54ua +.section s54ub +.section s54va +.section s54vb +.section s54wa +.section s54wb +.section s54xa +.section s54xb +.section s54ya +.section s54yb +.section s54za +.section s54zb +.section s541a +.section s541b +.section s542a +.section s542b +.section s543a +.section s543b +.section s544a +.section s544b +.section s545a +.section s545b +.section s546a +.section s546b +.section s547a +.section s547b +.section s548a +.section s548b +.section s549a +.section s549b +.section s540a +.section s540b +.section s55aa +.section s55ab +.section s55ba +.section s55bb +.section s55ca +.section s55cb +.section s55da +.section s55db +.section s55ea +.section s55eb +.section s55fa +.section s55fb +.section s55ga +.section s55gb +.section s55ha +.section s55hb +.section s55ia +.section s55ib +.section s55ja +.section s55jb +.section s55ka +.section s55kb +.section s55la +.section s55lb +.section s55ma +.section s55mb +.section s55na +.section s55nb +.section s55oa +.section s55ob +.section s55pa +.section s55pb +.section s55qa +.section s55qb +.section s55ra +.section s55rb +.section s55sa +.section s55sb +.section s55ta +.section s55tb +.section s55ua +.section s55ub +.section s55va +.section s55vb +.section s55wa +.section s55wb +.section s55xa +.section s55xb +.section s55ya +.section s55yb +.section s55za +.section s55zb +.section s551a +.section s551b +.section s552a +.section s552b +.section s553a +.section s553b +.section s554a +.section s554b +.section s555a +.section s555b +.section s556a +.section s556b +.section s557a +.section s557b +.section s558a +.section s558b +.section s559a +.section s559b +.section s550a +.section s550b +.section s56aa +.section s56ab +.section s56ba +.section s56bb +.section s56ca +.section s56cb +.section s56da +.section s56db +.section s56ea +.section s56eb +.section s56fa +.section s56fb +.section s56ga +.section s56gb +.section s56ha +.section s56hb +.section s56ia +.section s56ib +.section s56ja +.section s56jb +.section s56ka +.section s56kb +.section s56la +.section s56lb +.section s56ma +.section s56mb +.section s56na +.section s56nb +.section s56oa +.section s56ob +.section s56pa +.section s56pb +.section s56qa +.section s56qb +.section s56ra +.section s56rb +.section s56sa +.section s56sb +.section s56ta +.section s56tb +.section s56ua +.section s56ub +.section s56va +.section s56vb +.section s56wa +.section s56wb +.section s56xa +.section s56xb +.section s56ya +.section s56yb +.section s56za +.section s56zb +.section s561a +.section s561b +.section s562a +.section s562b +.section s563a +.section s563b +.section s564a +.section s564b +.section s565a +.section s565b +.section s566a +.section s566b +.section s567a +.section s567b +.section s568a +.section s568b +.section s569a +.section s569b +.section s560a +.section s560b +.section s57aa +.section s57ab +.section s57ba +.section s57bb +.section s57ca +.section s57cb +.section s57da +.section s57db +.section s57ea +.section s57eb +.section s57fa +.section s57fb +.section s57ga +.section s57gb +.section s57ha +.section s57hb +.section s57ia +.section s57ib +.section s57ja +.section s57jb +.section s57ka +.section s57kb +.section s57la +.section s57lb +.section s57ma +.section s57mb +.section s57na +.section s57nb +.section s57oa +.section s57ob +.section s57pa +.section s57pb +.section s57qa +.section s57qb +.section s57ra +.section s57rb +.section s57sa +.section s57sb +.section s57ta +.section s57tb +.section s57ua +.section s57ub +.section s57va +.section s57vb +.section s57wa +.section s57wb +.section s57xa +.section s57xb +.section s57ya +.section s57yb +.section s57za +.section s57zb +.section s571a +.section s571b +.section s572a +.section s572b +.section s573a +.section s573b +.section s574a +.section s574b +.section s575a +.section s575b +.section s576a +.section s576b +.section s577a +.section s577b +.section s578a +.section s578b +.section s579a +.section s579b +.section s570a +.section s570b +.section s58aa +.section s58ab +.section s58ba +.section s58bb +.section s58ca +.section s58cb +.section s58da +.section s58db +.section s58ea +.section s58eb +.section s58fa +.section s58fb +.section s58ga +.section s58gb +.section s58ha +.section s58hb +.section s58ia +.section s58ib +.section s58ja +.section s58jb +.section s58ka +.section s58kb +.section s58la +.section s58lb +.section s58ma +.section s58mb +.section s58na +.section s58nb +.section s58oa +.section s58ob +.section s58pa +.section s58pb +.section s58qa +.section s58qb +.section s58ra +.section s58rb +.section s58sa +.section s58sb +.section s58ta +.section s58tb +.section s58ua +.section s58ub +.section s58va +.section s58vb +.section s58wa +.section s58wb +.section s58xa +.section s58xb +.section s58ya +.section s58yb +.section s58za +.section s58zb +.section s581a +.section s581b +.section s582a +.section s582b +.section s583a +.section s583b +.section s584a +.section s584b +.section s585a +.section s585b +.section s586a +.section s586b +.section s587a +.section s587b +.section s588a +.section s588b +.section s589a +.section s589b +.section s580a +.section s580b +.section s59aa +.section s59ab +.section s59ba +.section s59bb +.section s59ca +.section s59cb +.section s59da +.section s59db +.section s59ea +.section s59eb +.section s59fa +.section s59fb +.section s59ga +.section s59gb +.section s59ha +.section s59hb +.section s59ia +.section s59ib +.section s59ja +.section s59jb +.section s59ka +.section s59kb +.section s59la +.section s59lb +.section s59ma +.section s59mb +.section s59na +.section s59nb +.section s59oa +.section s59ob +.section s59pa +.section s59pb +.section s59qa +.section s59qb +.section s59ra +.section s59rb +.section s59sa +.section s59sb +.section s59ta +.section s59tb +.section s59ua +.section s59ub +.section s59va +.section s59vb +.section s59wa +.section s59wb +.section s59xa +.section s59xb +.section s59ya +.section s59yb +.section s59za +.section s59zb +.section s591a +.section s591b +.section s592a +.section s592b +.section s593a +.section s593b +.section s594a +.section s594b +.section s595a +.section s595b +.section s596a +.section s596b +.section s597a +.section s597b +.section s598a +.section s598b +.section s599a +.section s599b +.section s590a +.section s590b +.section s50aa +.section s50ab +.section s50ba +.section s50bb +.section s50ca +.section s50cb +.section s50da +.section s50db +.section s50ea +.section s50eb +.section s50fa +.section s50fb +.section s50ga +.section s50gb +.section s50ha +.section s50hb +.section s50ia +.section s50ib +.section s50ja +.section s50jb +.section s50ka +.section s50kb +.section s50la +.section s50lb +.section s50ma +.section s50mb +.section s50na +.section s50nb +.section s50oa +.section s50ob +.section s50pa +.section s50pb +.section s50qa +.section s50qb +.section s50ra +.section s50rb +.section s50sa +.section s50sb +.section s50ta +.section s50tb +.section s50ua +.section s50ub +.section s50va +.section s50vb +.section s50wa +.section s50wb +.section s50xa +.section s50xb +.section s50ya +.section s50yb +.section s50za +.section s50zb +.section s501a +.section s501b +.section s502a +.section s502b +.section s503a +.section s503b +.section s504a +.section s504b +.section s505a +.section s505b +.section s506a +.section s506b +.section s507a +.section s507b +.section s508a +.section s508b +.section s509a +.section s509b +.section s500a +.section s500b +.section s6aaa +.section s6aab +.section s6aba +.section s6abb +.section s6aca +.section s6acb +.section s6ada +.section s6adb +.section s6aea +.section s6aeb +.section s6afa +.section s6afb +.section s6aga +.section s6agb +.section s6aha +.section s6ahb +.section s6aia +.section s6aib +.section s6aja +.section s6ajb +.section s6aka +.section s6akb +.section s6ala +.section s6alb +.section s6ama +.section s6amb +.section s6ana +.section s6anb +.section s6aoa +.section s6aob +.section s6apa +.section s6apb +.section s6aqa +.section s6aqb +.section s6ara +.section s6arb +.section s6asa +.section s6asb +.section s6ata +.section s6atb +.section s6aua +.section s6aub +.section s6ava +.section s6avb +.section s6awa +.section s6awb +.section s6axa +.section s6axb +.section s6aya +.section s6ayb +.section s6aza +.section s6azb +.section s6a1a +.section s6a1b +.section s6a2a +.section s6a2b +.section s6a3a +.section s6a3b +.section s6a4a +.section s6a4b +.section s6a5a +.section s6a5b +.section s6a6a +.section s6a6b +.section s6a7a +.section s6a7b +.section s6a8a +.section s6a8b +.section s6a9a +.section s6a9b +.section s6a0a +.section s6a0b +.section s6baa +.section s6bab +.section s6bba +.section s6bbb +.section s6bca +.section s6bcb +.section s6bda +.section s6bdb +.section s6bea +.section s6beb +.section s6bfa +.section s6bfb +.section s6bga +.section s6bgb +.section s6bha +.section s6bhb +.section s6bia +.section s6bib +.section s6bja +.section s6bjb +.section s6bka +.section s6bkb +.section s6bla +.section s6blb +.section s6bma +.section s6bmb +.section s6bna +.section s6bnb +.section s6boa +.section s6bob +.section s6bpa +.section s6bpb +.section s6bqa +.section s6bqb +.section s6bra +.section s6brb +.section s6bsa +.section s6bsb +.section s6bta +.section s6btb +.section s6bua +.section s6bub +.section s6bva +.section s6bvb +.section s6bwa +.section s6bwb +.section s6bxa +.section s6bxb +.section s6bya +.section s6byb +.section s6bza +.section s6bzb +.section s6b1a +.section s6b1b +.section s6b2a +.section s6b2b +.section s6b3a +.section s6b3b +.section s6b4a +.section s6b4b +.section s6b5a +.section s6b5b +.section s6b6a +.section s6b6b +.section s6b7a +.section s6b7b +.section s6b8a +.section s6b8b +.section s6b9a +.section s6b9b +.section s6b0a +.section s6b0b +.section s6caa +.section s6cab +.section s6cba +.section s6cbb +.section s6cca +.section s6ccb +.section s6cda +.section s6cdb +.section s6cea +.section s6ceb +.section s6cfa +.section s6cfb +.section s6cga +.section s6cgb +.section s6cha +.section s6chb +.section s6cia +.section s6cib +.section s6cja +.section s6cjb +.section s6cka +.section s6ckb +.section s6cla +.section s6clb +.section s6cma +.section s6cmb +.section s6cna +.section s6cnb +.section s6coa +.section s6cob +.section s6cpa +.section s6cpb +.section s6cqa +.section s6cqb +.section s6cra +.section s6crb +.section s6csa +.section s6csb +.section s6cta +.section s6ctb +.section s6cua +.section s6cub +.section s6cva +.section s6cvb +.section s6cwa +.section s6cwb +.section s6cxa +.section s6cxb +.section s6cya +.section s6cyb +.section s6cza +.section s6czb +.section s6c1a +.section s6c1b +.section s6c2a +.section s6c2b +.section s6c3a +.section s6c3b +.section s6c4a +.section s6c4b +.section s6c5a +.section s6c5b +.section s6c6a +.section s6c6b +.section s6c7a +.section s6c7b +.section s6c8a +.section s6c8b +.section s6c9a +.section s6c9b +.section s6c0a +.section s6c0b +.section s6daa +.section s6dab +.section s6dba +.section s6dbb +.section s6dca +.section s6dcb +.section s6dda +.section s6ddb +.section s6dea +.section s6deb +.section s6dfa +.section s6dfb +.section s6dga +.section s6dgb +.section s6dha +.section s6dhb +.section s6dia +.section s6dib +.section s6dja +.section s6djb +.section s6dka +.section s6dkb +.section s6dla +.section s6dlb +.section s6dma +.section s6dmb +.section s6dna +.section s6dnb +.section s6doa +.section s6dob +.section s6dpa +.section s6dpb +.section s6dqa +.section s6dqb +.section s6dra +.section s6drb +.section s6dsa +.section s6dsb +.section s6dta +.section s6dtb +.section s6dua +.section s6dub +.section s6dva +.section s6dvb +.section s6dwa +.section s6dwb +.section s6dxa +.section s6dxb +.section s6dya +.section s6dyb +.section s6dza +.section s6dzb +.section s6d1a +.section s6d1b +.section s6d2a +.section s6d2b +.section s6d3a +.section s6d3b +.section s6d4a +.section s6d4b +.section s6d5a +.section s6d5b +.section s6d6a +.section s6d6b +.section s6d7a +.section s6d7b +.section s6d8a +.section s6d8b +.section s6d9a +.section s6d9b +.section s6d0a +.section s6d0b +.section s6eaa +.section s6eab +.section s6eba +.section s6ebb +.section s6eca +.section s6ecb +.section s6eda +.section s6edb +.section s6eea +.section s6eeb +.section s6efa +.section s6efb +.section s6ega +.section s6egb +.section s6eha +.section s6ehb +.section s6eia +.section s6eib +.section s6eja +.section s6ejb +.section s6eka +.section s6ekb +.section s6ela +.section s6elb +.section s6ema +.section s6emb +.section s6ena +.section s6enb +.section s6eoa +.section s6eob +.section s6epa +.section s6epb +.section s6eqa +.section s6eqb +.section s6era +.section s6erb +.section s6esa +.section s6esb +.section s6eta +.section s6etb +.section s6eua +.section s6eub +.section s6eva +.section s6evb +.section s6ewa +.section s6ewb +.section s6exa +.section s6exb +.section s6eya +.section s6eyb +.section s6eza +.section s6ezb +.section s6e1a +.section s6e1b +.section s6e2a +.section s6e2b +.section s6e3a +.section s6e3b +.section s6e4a +.section s6e4b +.section s6e5a +.section s6e5b +.section s6e6a +.section s6e6b +.section s6e7a +.section s6e7b +.section s6e8a +.section s6e8b +.section s6e9a +.section s6e9b +.section s6e0a +.section s6e0b +.section s6faa +.section s6fab +.section s6fba +.section s6fbb +.section s6fca +.section s6fcb +.section s6fda +.section s6fdb +.section s6fea +.section s6feb +.section s6ffa +.section s6ffb +.section s6fga +.section s6fgb +.section s6fha +.section s6fhb +.section s6fia +.section s6fib +.section s6fja +.section s6fjb +.section s6fka +.section s6fkb +.section s6fla +.section s6flb +.section s6fma +.section s6fmb +.section s6fna +.section s6fnb +.section s6foa +.section s6fob +.section s6fpa +.section s6fpb +.section s6fqa +.section s6fqb +.section s6fra +.section s6frb +.section s6fsa +.section s6fsb +.section s6fta +.section s6ftb +.section s6fua +.section s6fub +.section s6fva +.section s6fvb +.section s6fwa +.section s6fwb +.section s6fxa +.section s6fxb +.section s6fya +.section s6fyb +.section s6fza +.section s6fzb +.section s6f1a +.section s6f1b +.section s6f2a +.section s6f2b +.section s6f3a +.section s6f3b +.section s6f4a +.section s6f4b +.section s6f5a +.section s6f5b +.section s6f6a +.section s6f6b +.section s6f7a +.section s6f7b +.section s6f8a +.section s6f8b +.section s6f9a +.section s6f9b +.section s6f0a +.section s6f0b +.section s6gaa +.section s6gab +.section s6gba +.section s6gbb +.section s6gca +.section s6gcb +.section s6gda +.section s6gdb +.section s6gea +.section s6geb +.section s6gfa +.section s6gfb +.section s6gga +.section s6ggb +.section s6gha +.section s6ghb +.section s6gia +.section s6gib +.section s6gja +.section s6gjb +.section s6gka +.section s6gkb +.section s6gla +.section s6glb +.section s6gma +.section s6gmb +.section s6gna +.section s6gnb +.section s6goa +.section s6gob +.section s6gpa +.section s6gpb +.section s6gqa +.section s6gqb +.section s6gra +.section s6grb +.section s6gsa +.section s6gsb +.section s6gta +.section s6gtb +.section s6gua +.section s6gub +.section s6gva +.section s6gvb +.section s6gwa +.section s6gwb +.section s6gxa +.section s6gxb +.section s6gya +.section s6gyb +.section s6gza +.section s6gzb +.section s6g1a +.section s6g1b +.section s6g2a +.section s6g2b +.section s6g3a +.section s6g3b +.section s6g4a +.section s6g4b +.section s6g5a +.section s6g5b +.section s6g6a +.section s6g6b +.section s6g7a +.section s6g7b +.section s6g8a +.section s6g8b +.section s6g9a +.section s6g9b +.section s6g0a +.section s6g0b +.section s6haa +.section s6hab +.section s6hba +.section s6hbb +.section s6hca +.section s6hcb +.section s6hda +.section s6hdb +.section s6hea +.section s6heb +.section s6hfa +.section s6hfb +.section s6hga +.section s6hgb +.section s6hha +.section s6hhb +.section s6hia +.section s6hib +.section s6hja +.section s6hjb +.section s6hka +.section s6hkb +.section s6hla +.section s6hlb +.section s6hma +.section s6hmb +.section s6hna +.section s6hnb +.section s6hoa +.section s6hob +.section s6hpa +.section s6hpb +.section s6hqa +.section s6hqb +.section s6hra +.section s6hrb +.section s6hsa +.section s6hsb +.section s6hta +.section s6htb +.section s6hua +.section s6hub +.section s6hva +.section s6hvb +.section s6hwa +.section s6hwb +.section s6hxa +.section s6hxb +.section s6hya +.section s6hyb +.section s6hza +.section s6hzb +.section s6h1a +.section s6h1b +.section s6h2a +.section s6h2b +.section s6h3a +.section s6h3b +.section s6h4a +.section s6h4b +.section s6h5a +.section s6h5b +.section s6h6a +.section s6h6b +.section s6h7a +.section s6h7b +.section s6h8a +.section s6h8b +.section s6h9a +.section s6h9b +.section s6h0a +.section s6h0b +.section s6iaa +.section s6iab +.section s6iba +.section s6ibb +.section s6ica +.section s6icb +.section s6ida +.section s6idb +.section s6iea +.section s6ieb +.section s6ifa +.section s6ifb +.section s6iga +.section s6igb +.section s6iha +.section s6ihb +.section s6iia +.section s6iib +.section s6ija +.section s6ijb +.section s6ika +.section s6ikb +.section s6ila +.section s6ilb +.section s6ima +.section s6imb +.section s6ina +.section s6inb +.section s6ioa +.section s6iob +.section s6ipa +.section s6ipb +.section s6iqa +.section s6iqb +.section s6ira +.section s6irb +.section s6isa +.section s6isb +.section s6ita +.section s6itb +.section s6iua +.section s6iub +.section s6iva +.section s6ivb +.section s6iwa +.section s6iwb +.section s6ixa +.section s6ixb +.section s6iya +.section s6iyb +.section s6iza +.section s6izb +.section s6i1a +.section s6i1b +.section s6i2a +.section s6i2b +.section s6i3a +.section s6i3b +.section s6i4a +.section s6i4b +.section s6i5a +.section s6i5b +.section s6i6a +.section s6i6b +.section s6i7a +.section s6i7b +.section s6i8a +.section s6i8b +.section s6i9a +.section s6i9b +.section s6i0a +.section s6i0b +.section s6jaa +.section s6jab +.section s6jba +.section s6jbb +.section s6jca +.section s6jcb +.section s6jda +.section s6jdb +.section s6jea +.section s6jeb +.section s6jfa +.section s6jfb +.section s6jga +.section s6jgb +.section s6jha +.section s6jhb +.section s6jia +.section s6jib +.section s6jja +.section s6jjb +.section s6jka +.section s6jkb +.section s6jla +.section s6jlb +.section s6jma +.section s6jmb +.section s6jna +.section s6jnb +.section s6joa +.section s6job +.section s6jpa +.section s6jpb +.section s6jqa +.section s6jqb +.section s6jra +.section s6jrb +.section s6jsa +.section s6jsb +.section s6jta +.section s6jtb +.section s6jua +.section s6jub +.section s6jva +.section s6jvb +.section s6jwa +.section s6jwb +.section s6jxa +.section s6jxb +.section s6jya +.section s6jyb +.section s6jza +.section s6jzb +.section s6j1a +.section s6j1b +.section s6j2a +.section s6j2b +.section s6j3a +.section s6j3b +.section s6j4a +.section s6j4b +.section s6j5a +.section s6j5b +.section s6j6a +.section s6j6b +.section s6j7a +.section s6j7b +.section s6j8a +.section s6j8b +.section s6j9a +.section s6j9b +.section s6j0a +.section s6j0b +.section s6kaa +.section s6kab +.section s6kba +.section s6kbb +.section s6kca +.section s6kcb +.section s6kda +.section s6kdb +.section s6kea +.section s6keb +.section s6kfa +.section s6kfb +.section s6kga +.section s6kgb +.section s6kha +.section s6khb +.section s6kia +.section s6kib +.section s6kja +.section s6kjb +.section s6kka +.section s6kkb +.section s6kla +.section s6klb +.section s6kma +.section s6kmb +.section s6kna +.section s6knb +.section s6koa +.section s6kob +.section s6kpa +.section s6kpb +.section s6kqa +.section s6kqb +.section s6kra +.section s6krb +.section s6ksa +.section s6ksb +.section s6kta +.section s6ktb +.section s6kua +.section s6kub +.section s6kva +.section s6kvb +.section s6kwa +.section s6kwb +.section s6kxa +.section s6kxb +.section s6kya +.section s6kyb +.section s6kza +.section s6kzb +.section s6k1a +.section s6k1b +.section s6k2a +.section s6k2b +.section s6k3a +.section s6k3b +.section s6k4a +.section s6k4b +.section s6k5a +.section s6k5b +.section s6k6a +.section s6k6b +.section s6k7a +.section s6k7b +.section s6k8a +.section s6k8b +.section s6k9a +.section s6k9b +.section s6k0a +.section s6k0b +.section s6laa +.section s6lab +.section s6lba +.section s6lbb +.section s6lca +.section s6lcb +.section s6lda +.section s6ldb +.section s6lea +.section s6leb +.section s6lfa +.section s6lfb +.section s6lga +.section s6lgb +.section s6lha +.section s6lhb +.section s6lia +.section s6lib +.section s6lja +.section s6ljb +.section s6lka +.section s6lkb +.section s6lla +.section s6llb +.section s6lma +.section s6lmb +.section s6lna +.section s6lnb +.section s6loa +.section s6lob +.section s6lpa +.section s6lpb +.section s6lqa +.section s6lqb +.section s6lra +.section s6lrb +.section s6lsa +.section s6lsb +.section s6lta +.section s6ltb +.section s6lua +.section s6lub +.section s6lva +.section s6lvb +.section s6lwa +.section s6lwb +.section s6lxa +.section s6lxb +.section s6lya +.section s6lyb +.section s6lza +.section s6lzb +.section s6l1a +.section s6l1b +.section s6l2a +.section s6l2b +.section s6l3a +.section s6l3b +.section s6l4a +.section s6l4b +.section s6l5a +.section s6l5b +.section s6l6a +.section s6l6b +.section s6l7a +.section s6l7b +.section s6l8a +.section s6l8b +.section s6l9a +.section s6l9b +.section s6l0a +.section s6l0b +.section s6maa +.section s6mab +.section s6mba +.section s6mbb +.section s6mca +.section s6mcb +.section s6mda +.section s6mdb +.section s6mea +.section s6meb +.section s6mfa +.section s6mfb +.section s6mga +.section s6mgb +.section s6mha +.section s6mhb +.section s6mia +.section s6mib +.section s6mja +.section s6mjb +.section s6mka +.section s6mkb +.section s6mla +.section s6mlb +.section s6mma +.section s6mmb +.section s6mna +.section s6mnb +.section s6moa +.section s6mob +.section s6mpa +.section s6mpb +.section s6mqa +.section s6mqb +.section s6mra +.section s6mrb +.section s6msa +.section s6msb +.section s6mta +.section s6mtb +.section s6mua +.section s6mub +.section s6mva +.section s6mvb +.section s6mwa +.section s6mwb +.section s6mxa +.section s6mxb +.section s6mya +.section s6myb +.section s6mza +.section s6mzb +.section s6m1a +.section s6m1b +.section s6m2a +.section s6m2b +.section s6m3a +.section s6m3b +.section s6m4a +.section s6m4b +.section s6m5a +.section s6m5b +.section s6m6a +.section s6m6b +.section s6m7a +.section s6m7b +.section s6m8a +.section s6m8b +.section s6m9a +.section s6m9b +.section s6m0a +.section s6m0b +.section s6naa +.section s6nab +.section s6nba +.section s6nbb +.section s6nca +.section s6ncb +.section s6nda +.section s6ndb +.section s6nea +.section s6neb +.section s6nfa +.section s6nfb +.section s6nga +.section s6ngb +.section s6nha +.section s6nhb +.section s6nia +.section s6nib +.section s6nja +.section s6njb +.section s6nka +.section s6nkb +.section s6nla +.section s6nlb +.section s6nma +.section s6nmb +.section s6nna +.section s6nnb +.section s6noa +.section s6nob +.section s6npa +.section s6npb +.section s6nqa +.section s6nqb +.section s6nra +.section s6nrb +.section s6nsa +.section s6nsb +.section s6nta +.section s6ntb +.section s6nua +.section s6nub +.section s6nva +.section s6nvb +.section s6nwa +.section s6nwb +.section s6nxa +.section s6nxb +.section s6nya +.section s6nyb +.section s6nza +.section s6nzb +.section s6n1a +.section s6n1b +.section s6n2a +.section s6n2b +.section s6n3a +.section s6n3b +.section s6n4a +.section s6n4b +.section s6n5a +.section s6n5b +.section s6n6a +.section s6n6b +.section s6n7a +.section s6n7b +.section s6n8a +.section s6n8b +.section s6n9a +.section s6n9b +.section s6n0a +.section s6n0b +.section s6oaa +.section s6oab +.section s6oba +.section s6obb +.section s6oca +.section s6ocb +.section s6oda +.section s6odb +.section s6oea +.section s6oeb +.section s6ofa +.section s6ofb +.section s6oga +.section s6ogb +.section s6oha +.section s6ohb +.section s6oia +.section s6oib +.section s6oja +.section s6ojb +.section s6oka +.section s6okb +.section s6ola +.section s6olb +.section s6oma +.section s6omb +.section s6ona +.section s6onb +.section s6ooa +.section s6oob +.section s6opa +.section s6opb +.section s6oqa +.section s6oqb +.section s6ora +.section s6orb +.section s6osa +.section s6osb +.section s6ota +.section s6otb +.section s6oua +.section s6oub +.section s6ova +.section s6ovb +.section s6owa +.section s6owb +.section s6oxa +.section s6oxb +.section s6oya +.section s6oyb +.section s6oza +.section s6ozb +.section s6o1a +.section s6o1b +.section s6o2a +.section s6o2b +.section s6o3a +.section s6o3b +.section s6o4a +.section s6o4b +.section s6o5a +.section s6o5b +.section s6o6a +.section s6o6b +.section s6o7a +.section s6o7b +.section s6o8a +.section s6o8b +.section s6o9a +.section s6o9b +.section s6o0a +.section s6o0b +.section s6paa +.section s6pab +.section s6pba +.section s6pbb +.section s6pca +.section s6pcb +.section s6pda +.section s6pdb +.section s6pea +.section s6peb +.section s6pfa +.section s6pfb +.section s6pga +.section s6pgb +.section s6pha +.section s6phb +.section s6pia +.section s6pib +.section s6pja +.section s6pjb +.section s6pka +.section s6pkb +.section s6pla +.section s6plb +.section s6pma +.section s6pmb +.section s6pna +.section s6pnb +.section s6poa +.section s6pob +.section s6ppa +.section s6ppb +.section s6pqa +.section s6pqb +.section s6pra +.section s6prb +.section s6psa +.section s6psb +.section s6pta +.section s6ptb +.section s6pua +.section s6pub +.section s6pva +.section s6pvb +.section s6pwa +.section s6pwb +.section s6pxa +.section s6pxb +.section s6pya +.section s6pyb +.section s6pza +.section s6pzb +.section s6p1a +.section s6p1b +.section s6p2a +.section s6p2b +.section s6p3a +.section s6p3b +.section s6p4a +.section s6p4b +.section s6p5a +.section s6p5b +.section s6p6a +.section s6p6b +.section s6p7a +.section s6p7b +.section s6p8a +.section s6p8b +.section s6p9a +.section s6p9b +.section s6p0a +.section s6p0b +.section s6qaa +.section s6qab +.section s6qba +.section s6qbb +.section s6qca +.section s6qcb +.section s6qda +.section s6qdb +.section s6qea +.section s6qeb +.section s6qfa +.section s6qfb +.section s6qga +.section s6qgb +.section s6qha +.section s6qhb +.section s6qia +.section s6qib +.section s6qja +.section s6qjb +.section s6qka +.section s6qkb +.section s6qla +.section s6qlb +.section s6qma +.section s6qmb +.section s6qna +.section s6qnb +.section s6qoa +.section s6qob +.section s6qpa +.section s6qpb +.section s6qqa +.section s6qqb +.section s6qra +.section s6qrb +.section s6qsa +.section s6qsb +.section s6qta +.section s6qtb +.section s6qua +.section s6qub +.section s6qva +.section s6qvb +.section s6qwa +.section s6qwb +.section s6qxa +.section s6qxb +.section s6qya +.section s6qyb +.section s6qza +.section s6qzb +.section s6q1a +.section s6q1b +.section s6q2a +.section s6q2b +.section s6q3a +.section s6q3b +.section s6q4a +.section s6q4b +.section s6q5a +.section s6q5b +.section s6q6a +.section s6q6b +.section s6q7a +.section s6q7b +.section s6q8a +.section s6q8b +.section s6q9a +.section s6q9b +.section s6q0a +.section s6q0b +.section s6raa +.section s6rab +.section s6rba +.section s6rbb +.section s6rca +.section s6rcb +.section s6rda +.section s6rdb +.section s6rea +.section s6reb +.section s6rfa +.section s6rfb +.section s6rga +.section s6rgb +.section s6rha +.section s6rhb +.section s6ria +.section s6rib +.section s6rja +.section s6rjb +.section s6rka +.section s6rkb +.section s6rla +.section s6rlb +.section s6rma +.section s6rmb +.section s6rna +.section s6rnb +.section s6roa +.section s6rob +.section s6rpa +.section s6rpb +.section s6rqa +.section s6rqb +.section s6rra +.section s6rrb +.section s6rsa +.section s6rsb +.section s6rta +.section s6rtb +.section s6rua +.section s6rub +.section s6rva +.section s6rvb +.section s6rwa +.section s6rwb +.section s6rxa +.section s6rxb +.section s6rya +.section s6ryb +.section s6rza +.section s6rzb +.section s6r1a +.section s6r1b +.section s6r2a +.section s6r2b +.section s6r3a +.section s6r3b +.section s6r4a +.section s6r4b +.section s6r5a +.section s6r5b +.section s6r6a +.section s6r6b +.section s6r7a +.section s6r7b +.section s6r8a +.section s6r8b +.section s6r9a +.section s6r9b +.section s6r0a +.section s6r0b +.section s6saa +.section s6sab +.section s6sba +.section s6sbb +.section s6sca +.section s6scb +.section s6sda +.section s6sdb +.section s6sea +.section s6seb +.section s6sfa +.section s6sfb +.section s6sga +.section s6sgb +.section s6sha +.section s6shb +.section s6sia +.section s6sib +.section s6sja +.section s6sjb +.section s6ska +.section s6skb +.section s6sla +.section s6slb +.section s6sma +.section s6smb +.section s6sna +.section s6snb +.section s6soa +.section s6sob +.section s6spa +.section s6spb +.section s6sqa +.section s6sqb +.section s6sra +.section s6srb +.section s6ssa +.section s6ssb +.section s6sta +.section s6stb +.section s6sua +.section s6sub +.section s6sva +.section s6svb +.section s6swa +.section s6swb +.section s6sxa +.section s6sxb +.section s6sya +.section s6syb +.section s6sza +.section s6szb +.section s6s1a +.section s6s1b +.section s6s2a +.section s6s2b +.section s6s3a +.section s6s3b +.section s6s4a +.section s6s4b +.section s6s5a +.section s6s5b +.section s6s6a +.section s6s6b +.section s6s7a +.section s6s7b +.section s6s8a +.section s6s8b +.section s6s9a +.section s6s9b +.section s6s0a +.section s6s0b +.section s6taa +.section s6tab +.section s6tba +.section s6tbb +.section s6tca +.section s6tcb +.section s6tda +.section s6tdb +.section s6tea +.section s6teb +.section s6tfa +.section s6tfb +.section s6tga +.section s6tgb +.section s6tha +.section s6thb +.section s6tia +.section s6tib +.section s6tja +.section s6tjb +.section s6tka +.section s6tkb +.section s6tla +.section s6tlb +.section s6tma +.section s6tmb +.section s6tna +.section s6tnb +.section s6toa +.section s6tob +.section s6tpa +.section s6tpb +.section s6tqa +.section s6tqb +.section s6tra +.section s6trb +.section s6tsa +.section s6tsb +.section s6tta +.section s6ttb +.section s6tua +.section s6tub +.section s6tva +.section s6tvb +.section s6twa +.section s6twb +.section s6txa +.section s6txb +.section s6tya +.section s6tyb +.section s6tza +.section s6tzb +.section s6t1a +.section s6t1b +.section s6t2a +.section s6t2b +.section s6t3a +.section s6t3b +.section s6t4a +.section s6t4b +.section s6t5a +.section s6t5b +.section s6t6a +.section s6t6b +.section s6t7a +.section s6t7b +.section s6t8a +.section s6t8b +.section s6t9a +.section s6t9b +.section s6t0a +.section s6t0b +.section s6uaa +.section s6uab +.section s6uba +.section s6ubb +.section s6uca +.section s6ucb +.section s6uda +.section s6udb +.section s6uea +.section s6ueb +.section s6ufa +.section s6ufb +.section s6uga +.section s6ugb +.section s6uha +.section s6uhb +.section s6uia +.section s6uib +.section s6uja +.section s6ujb +.section s6uka +.section s6ukb +.section s6ula +.section s6ulb +.section s6uma +.section s6umb +.section s6una +.section s6unb +.section s6uoa +.section s6uob +.section s6upa +.section s6upb +.section s6uqa +.section s6uqb +.section s6ura +.section s6urb +.section s6usa +.section s6usb +.section s6uta +.section s6utb +.section s6uua +.section s6uub +.section s6uva +.section s6uvb +.section s6uwa +.section s6uwb +.section s6uxa +.section s6uxb +.section s6uya +.section s6uyb +.section s6uza +.section s6uzb +.section s6u1a +.section s6u1b +.section s6u2a +.section s6u2b +.section s6u3a +.section s6u3b +.section s6u4a +.section s6u4b +.section s6u5a +.section s6u5b +.section s6u6a +.section s6u6b +.section s6u7a +.section s6u7b +.section s6u8a +.section s6u8b +.section s6u9a +.section s6u9b +.section s6u0a +.section s6u0b +.section s6vaa +.section s6vab +.section s6vba +.section s6vbb +.section s6vca +.section s6vcb +.section s6vda +.section s6vdb +.section s6vea +.section s6veb +.section s6vfa +.section s6vfb +.section s6vga +.section s6vgb +.section s6vha +.section s6vhb +.section s6via +.section s6vib +.section s6vja +.section s6vjb +.section s6vka +.section s6vkb +.section s6vla +.section s6vlb +.section s6vma +.section s6vmb +.section s6vna +.section s6vnb +.section s6voa +.section s6vob +.section s6vpa +.section s6vpb +.section s6vqa +.section s6vqb +.section s6vra +.section s6vrb +.section s6vsa +.section s6vsb +.section s6vta +.section s6vtb +.section s6vua +.section s6vub +.section s6vva +.section s6vvb +.section s6vwa +.section s6vwb +.section s6vxa +.section s6vxb +.section s6vya +.section s6vyb +.section s6vza +.section s6vzb +.section s6v1a +.section s6v1b +.section s6v2a +.section s6v2b +.section s6v3a +.section s6v3b +.section s6v4a +.section s6v4b +.section s6v5a +.section s6v5b +.section s6v6a +.section s6v6b +.section s6v7a +.section s6v7b +.section s6v8a +.section s6v8b +.section s6v9a +.section s6v9b +.section s6v0a +.section s6v0b +.section s6waa +.section s6wab +.section s6wba +.section s6wbb +.section s6wca +.section s6wcb +.section s6wda +.section s6wdb +.section s6wea +.section s6web +.section s6wfa +.section s6wfb +.section s6wga +.section s6wgb +.section s6wha +.section s6whb +.section s6wia +.section s6wib +.section s6wja +.section s6wjb +.section s6wka +.section s6wkb +.section s6wla +.section s6wlb +.section s6wma +.section s6wmb +.section s6wna +.section s6wnb +.section s6woa +.section s6wob +.section s6wpa +.section s6wpb +.section s6wqa +.section s6wqb +.section s6wra +.section s6wrb +.section s6wsa +.section s6wsb +.section s6wta +.section s6wtb +.section s6wua +.section s6wub +.section s6wva +.section s6wvb +.section s6wwa +.section s6wwb +.section s6wxa +.section s6wxb +.section s6wya +.section s6wyb +.section s6wza +.section s6wzb +.section s6w1a +.section s6w1b +.section s6w2a +.section s6w2b +.section s6w3a +.section s6w3b +.section s6w4a +.section s6w4b +.section s6w5a +.section s6w5b +.section s6w6a +.section s6w6b +.section s6w7a +.section s6w7b +.section s6w8a +.section s6w8b +.section s6w9a +.section s6w9b +.section s6w0a +.section s6w0b +.section s6xaa +.section s6xab +.section s6xba +.section s6xbb +.section s6xca +.section s6xcb +.section s6xda +.section s6xdb +.section s6xea +.section s6xeb +.section s6xfa +.section s6xfb +.section s6xga +.section s6xgb +.section s6xha +.section s6xhb +.section s6xia +.section s6xib +.section s6xja +.section s6xjb +.section s6xka +.section s6xkb +.section s6xla +.section s6xlb +.section s6xma +.section s6xmb +.section s6xna +.section s6xnb +.section s6xoa +.section s6xob +.section s6xpa +.section s6xpb +.section s6xqa +.section s6xqb +.section s6xra +.section s6xrb +.section s6xsa +.section s6xsb +.section s6xta +.section s6xtb +.section s6xua +.section s6xub +.section s6xva +.section s6xvb +.section s6xwa +.section s6xwb +.section s6xxa +.section s6xxb +.section s6xya +.section s6xyb +.section s6xza +.section s6xzb +.section s6x1a +.section s6x1b +.section s6x2a +.section s6x2b +.section s6x3a +.section s6x3b +.section s6x4a +.section s6x4b +.section s6x5a +.section s6x5b +.section s6x6a +.section s6x6b +.section s6x7a +.section s6x7b +.section s6x8a +.section s6x8b +.section s6x9a +.section s6x9b +.section s6x0a +.section s6x0b +.section s6yaa +.section s6yab +.section s6yba +.section s6ybb +.section s6yca +.section s6ycb +.section s6yda +.section s6ydb +.section s6yea +.section s6yeb +.section s6yfa +.section s6yfb +.section s6yga +.section s6ygb +.section s6yha +.section s6yhb +.section s6yia +.section s6yib +.section s6yja +.section s6yjb +.section s6yka +.section s6ykb +.section s6yla +.section s6ylb +.section s6yma +.section s6ymb +.section s6yna +.section s6ynb +.section s6yoa +.section s6yob +.section s6ypa +.section s6ypb +.section s6yqa +.section s6yqb +.section s6yra +.section s6yrb +.section s6ysa +.section s6ysb +.section s6yta +.section s6ytb +.section s6yua +.section s6yub +.section s6yva +.section s6yvb +.section s6ywa +.section s6ywb +.section s6yxa +.section s6yxb +.section s6yya +.section s6yyb +.section s6yza +.section s6yzb +.section s6y1a +.section s6y1b +.section s6y2a +.section s6y2b +.section s6y3a +.section s6y3b +.section s6y4a +.section s6y4b +.section s6y5a +.section s6y5b +.section s6y6a +.section s6y6b +.section s6y7a +.section s6y7b +.section s6y8a +.section s6y8b +.section s6y9a +.section s6y9b +.section s6y0a +.section s6y0b +.section s6zaa +.section s6zab +.section s6zba +.section s6zbb +.section s6zca +.section s6zcb +.section s6zda +.section s6zdb +.section s6zea +.section s6zeb +.section s6zfa +.section s6zfb +.section s6zga +.section s6zgb +.section s6zha +.section s6zhb +.section s6zia +.section s6zib +.section s6zja +.section s6zjb +.section s6zka +.section s6zkb +.section s6zla +.section s6zlb +.section s6zma +.section s6zmb +.section s6zna +.section s6znb +.section s6zoa +.section s6zob +.section s6zpa +.section s6zpb +.section s6zqa +.section s6zqb +.section s6zra +.section s6zrb +.section s6zsa +.section s6zsb +.section s6zta +.section s6ztb +.section s6zua +.section s6zub +.section s6zva +.section s6zvb +.section s6zwa +.section s6zwb +.section s6zxa +.section s6zxb +.section s6zya +.section s6zyb +.section s6zza +.section s6zzb +.section s6z1a +.section s6z1b +.section s6z2a +.section s6z2b +.section s6z3a +.section s6z3b +.section s6z4a +.section s6z4b +.section s6z5a +.section s6z5b +.section s6z6a +.section s6z6b +.section s6z7a +.section s6z7b +.section s6z8a +.section s6z8b +.section s6z9a +.section s6z9b +.section s6z0a +.section s6z0b +.section s61aa +.section s61ab +.section s61ba +.section s61bb +.section s61ca +.section s61cb +.section s61da +.section s61db +.section s61ea +.section s61eb +.section s61fa +.section s61fb +.section s61ga +.section s61gb +.section s61ha +.section s61hb +.section s61ia +.section s61ib +.section s61ja +.section s61jb +.section s61ka +.section s61kb +.section s61la +.section s61lb +.section s61ma +.section s61mb +.section s61na +.section s61nb +.section s61oa +.section s61ob +.section s61pa +.section s61pb +.section s61qa +.section s61qb +.section s61ra +.section s61rb +.section s61sa +.section s61sb +.section s61ta +.section s61tb +.section s61ua +.section s61ub +.section s61va +.section s61vb +.section s61wa +.section s61wb +.section s61xa +.section s61xb +.section s61ya +.section s61yb +.section s61za +.section s61zb +.section s611a +.section s611b +.section s612a +.section s612b +.section s613a +.section s613b +.section s614a +.section s614b +.section s615a +.section s615b +.section s616a +.section s616b +.section s617a +.section s617b +.section s618a +.section s618b +.section s619a +.section s619b +.section s610a +.section s610b +.section s62aa +.section s62ab +.section s62ba +.section s62bb +.section s62ca +.section s62cb +.section s62da +.section s62db +.section s62ea +.section s62eb +.section s62fa +.section s62fb +.section s62ga +.section s62gb +.section s62ha +.section s62hb +.section s62ia +.section s62ib +.section s62ja +.section s62jb +.section s62ka +.section s62kb +.section s62la +.section s62lb +.section s62ma +.section s62mb +.section s62na +.section s62nb +.section s62oa +.section s62ob +.section s62pa +.section s62pb +.section s62qa +.section s62qb +.section s62ra +.section s62rb +.section s62sa +.section s62sb +.section s62ta +.section s62tb +.section s62ua +.section s62ub +.section s62va +.section s62vb +.section s62wa +.section s62wb +.section s62xa +.section s62xb +.section s62ya +.section s62yb +.section s62za +.section s62zb +.section s621a +.section s621b +.section s622a +.section s622b +.section s623a +.section s623b +.section s624a +.section s624b +.section s625a +.section s625b +.section s626a +.section s626b +.section s627a +.section s627b +.section s628a +.section s628b +.section s629a +.section s629b +.section s620a +.section s620b +.section s63aa +.section s63ab +.section s63ba +.section s63bb +.section s63ca +.section s63cb +.section s63da +.section s63db +.section s63ea +.section s63eb +.section s63fa +.section s63fb +.section s63ga +.section s63gb +.section s63ha +.section s63hb +.section s63ia +.section s63ib +.section s63ja +.section s63jb +.section s63ka +.section s63kb +.section s63la +.section s63lb +.section s63ma +.section s63mb +.section s63na +.section s63nb +.section s63oa +.section s63ob +.section s63pa +.section s63pb +.section s63qa +.section s63qb +.section s63ra +.section s63rb +.section s63sa +.section s63sb +.section s63ta +.section s63tb +.section s63ua +.section s63ub +.section s63va +.section s63vb +.section s63wa +.section s63wb +.section s63xa +.section s63xb +.section s63ya +.section s63yb +.section s63za +.section s63zb +.section s631a +.section s631b +.section s632a +.section s632b +.section s633a +.section s633b +.section s634a +.section s634b +.section s635a +.section s635b +.section s636a +.section s636b +.section s637a +.section s637b +.section s638a +.section s638b +.section s639a +.section s639b +.section s630a +.section s630b +.section s64aa +.section s64ab +.section s64ba +.section s64bb +.section s64ca +.section s64cb +.section s64da +.section s64db +.section s64ea +.section s64eb +.section s64fa +.section s64fb +.section s64ga +.section s64gb +.section s64ha +.section s64hb +.section s64ia +.section s64ib +.section s64ja +.section s64jb +.section s64ka +.section s64kb +.section s64la +.section s64lb +.section s64ma +.section s64mb +.section s64na +.section s64nb +.section s64oa +.section s64ob +.section s64pa +.section s64pb +.section s64qa +.section s64qb +.section s64ra +.section s64rb +.section s64sa +.section s64sb +.section s64ta +.section s64tb +.section s64ua +.section s64ub +.section s64va +.section s64vb +.section s64wa +.section s64wb +.section s64xa +.section s64xb +.section s64ya +.section s64yb +.section s64za +.section s64zb +.section s641a +.section s641b +.section s642a +.section s642b +.section s643a +.section s643b +.section s644a +.section s644b +.section s645a +.section s645b +.section s646a +.section s646b +.section s647a +.section s647b +.section s648a +.section s648b +.section s649a +.section s649b +.section s640a +.section s640b +.section s65aa +.section s65ab +.section s65ba +.section s65bb +.section s65ca +.section s65cb +.section s65da +.section s65db +.section s65ea +.section s65eb +.section s65fa +.section s65fb +.section s65ga +.section s65gb +.section s65ha +.section s65hb +.section s65ia +.section s65ib +.section s65ja +.section s65jb +.section s65ka +.section s65kb +.section s65la +.section s65lb +.section s65ma +.section s65mb +.section s65na +.section s65nb +.section s65oa +.section s65ob +.section s65pa +.section s65pb +.section s65qa +.section s65qb +.section s65ra +.section s65rb +.section s65sa +.section s65sb +.section s65ta +.section s65tb +.section s65ua +.section s65ub +.section s65va +.section s65vb +.section s65wa +.section s65wb +.section s65xa +.section s65xb +.section s65ya +.section s65yb +.section s65za +.section s65zb +.section s651a +.section s651b +.section s652a +.section s652b +.section s653a +.section s653b +.section s654a +.section s654b +.section s655a +.section s655b +.section s656a +.section s656b +.section s657a +.section s657b +.section s658a +.section s658b +.section s659a +.section s659b +.section s650a +.section s650b +.section s66aa +.section s66ab +.section s66ba +.section s66bb +.section s66ca +.section s66cb +.section s66da +.section s66db +.section s66ea +.section s66eb +.section s66fa +.section s66fb +.section s66ga +.section s66gb +.section s66ha +.section s66hb +.section s66ia +.section s66ib +.section s66ja +.section s66jb +.section s66ka +.section s66kb +.section s66la +.section s66lb +.section s66ma +.section s66mb +.section s66na +.section s66nb +.section s66oa +.section s66ob +.section s66pa +.section s66pb +.section s66qa +.section s66qb +.section s66ra +.section s66rb +.section s66sa +.section s66sb +.section s66ta +.section s66tb +.section s66ua +.section s66ub +.section s66va +.section s66vb +.section s66wa +.section s66wb +.section s66xa +.section s66xb +.section s66ya +.section s66yb +.section s66za +.section s66zb +.section s661a +.section s661b +.section s662a +.section s662b +.section s663a +.section s663b +.section s664a +.section s664b +.section s665a +.section s665b +.section s666a +.section s666b +.section s667a +.section s667b +.section s668a +.section s668b +.section s669a +.section s669b +.section s660a +.section s660b +.section s67aa +.section s67ab +.section s67ba +.section s67bb +.section s67ca +.section s67cb +.section s67da +.section s67db +.section s67ea +.section s67eb +.section s67fa +.section s67fb +.section s67ga +.section s67gb +.section s67ha +.section s67hb +.section s67ia +.section s67ib +.section s67ja +.section s67jb +.section s67ka +.section s67kb +.section s67la +.section s67lb +.section s67ma +.section s67mb +.section s67na +.section s67nb +.section s67oa +.section s67ob +.section s67pa +.section s67pb +.section s67qa +.section s67qb +.section s67ra +.section s67rb +.section s67sa +.section s67sb +.section s67ta +.section s67tb +.section s67ua +.section s67ub +.section s67va +.section s67vb +.section s67wa +.section s67wb +.section s67xa +.section s67xb +.section s67ya +.section s67yb +.section s67za +.section s67zb +.section s671a +.section s671b +.section s672a +.section s672b +.section s673a +.section s673b +.section s674a +.section s674b +.section s675a +.section s675b +.section s676a +.section s676b +.section s677a +.section s677b +.section s678a +.section s678b +.section s679a +.section s679b +.section s670a +.section s670b +.section s68aa +.section s68ab +.section s68ba +.section s68bb +.section s68ca +.section s68cb +.section s68da +.section s68db +.section s68ea +.section s68eb +.section s68fa +.section s68fb +.section s68ga +.section s68gb +.section s68ha +.section s68hb +.section s68ia +.section s68ib +.section s68ja +.section s68jb +.section s68ka +.section s68kb +.section s68la +.section s68lb +.section s68ma +.section s68mb +.section s68na +.section s68nb +.section s68oa +.section s68ob +.section s68pa +.section s68pb +.section s68qa +.section s68qb +.section s68ra +.section s68rb +.section s68sa +.section s68sb +.section s68ta +.section s68tb +.section s68ua +.section s68ub +.section s68va +.section s68vb +.section s68wa +.section s68wb +.section s68xa +.section s68xb +.section s68ya +.section s68yb +.section s68za +.section s68zb +.section s681a +.section s681b +.section s682a +.section s682b +.section s683a +.section s683b +.section s684a +.section s684b +.section s685a +.section s685b +.section s686a +.section s686b +.section s687a +.section s687b +.section s688a +.section s688b +.section s689a +.section s689b +.section s680a +.section s680b +.section s69aa +.section s69ab +.section s69ba +.section s69bb +.section s69ca +.section s69cb +.section s69da +.section s69db +.section s69ea +.section s69eb +.section s69fa +.section s69fb +.section s69ga +.section s69gb +.section s69ha +.section s69hb +.section s69ia +.section s69ib +.section s69ja +.section s69jb +.section s69ka +.section s69kb +.section s69la +.section s69lb +.section s69ma +.section s69mb +.section s69na +.section s69nb +.section s69oa +.section s69ob +.section s69pa +.section s69pb +.section s69qa +.section s69qb +.section s69ra +.section s69rb +.section s69sa +.section s69sb +.section s69ta +.section s69tb +.section s69ua +.section s69ub +.section s69va +.section s69vb +.section s69wa +.section s69wb +.section s69xa +.section s69xb +.section s69ya +.section s69yb +.section s69za +.section s69zb +.section s691a +.section s691b +.section s692a +.section s692b +.section s693a +.section s693b +.section s694a +.section s694b +.section s695a +.section s695b +.section s696a +.section s696b +.section s697a +.section s697b +.section s698a +.section s698b +.section s699a +.section s699b +.section s690a +.section s690b +.section s60aa +.section s60ab +.section s60ba +.section s60bb +.section s60ca +.section s60cb +.section s60da +.section s60db +.section s60ea +.section s60eb +.section s60fa +.section s60fb +.section s60ga +.section s60gb +.section s60ha +.section s60hb +.section s60ia +.section s60ib +.section s60ja +.section s60jb +.section s60ka +.section s60kb +.section s60la +.section s60lb +.section s60ma +.section s60mb +.section s60na +.section s60nb +.section s60oa +.section s60ob +.section s60pa +.section s60pb +.section s60qa +.section s60qb +.section s60ra +.section s60rb +.section s60sa +.section s60sb +.section s60ta +.section s60tb +.section s60ua +.section s60ub +.section s60va +.section s60vb +.section s60wa +.section s60wb +.section s60xa +.section s60xb +.section s60ya +.section s60yb +.section s60za +.section s60zb +.section s601a +.section s601b +.section s602a +.section s602b +.section s603a +.section s603b +.section s604a +.section s604b +.section s605a +.section s605b +.section s606a +.section s606b +.section s607a +.section s607b +.section s608a +.section s608b +.section s609a +.section s609b +.section s600a +.section s600b +.section s7aaa +.section s7aab +.section s7aba +.section s7abb +.section s7aca +.section s7acb +.section s7ada +.section s7adb +.section s7aea +.section s7aeb +.section s7afa +.section s7afb +.section s7aga +.section s7agb +.section s7aha +.section s7ahb +.section s7aia +.section s7aib +.section s7aja +.section s7ajb +.section s7aka +.section s7akb +.section s7ala +.section s7alb +.section s7ama +.section s7amb +.section s7ana +.section s7anb +.section s7aoa +.section s7aob +.section s7apa +.section s7apb +.section s7aqa +.section s7aqb +.section s7ara +.section s7arb +.section s7asa +.section s7asb +.section s7ata +.section s7atb +.section s7aua +.section s7aub +.section s7ava +.section s7avb +.section s7awa +.section s7awb +.section s7axa +.section s7axb +.section s7aya +.section s7ayb +.section s7aza +.section s7azb +.section s7a1a +.section s7a1b +.section s7a2a +.section s7a2b +.section s7a3a +.section s7a3b +.section s7a4a +.section s7a4b +.section s7a5a +.section s7a5b +.section s7a6a +.section s7a6b +.section s7a7a +.section s7a7b +.section s7a8a +.section s7a8b +.section s7a9a +.section s7a9b +.section s7a0a +.section s7a0b +.section s7baa +.section s7bab +.section s7bba +.section s7bbb +.section s7bca +.section s7bcb +.section s7bda +.section s7bdb +.section s7bea +.section s7beb +.section s7bfa +.section s7bfb +.section s7bga +.section s7bgb +.section s7bha +.section s7bhb +.section s7bia +.section s7bib +.section s7bja +.section s7bjb +.section s7bka +.section s7bkb +.section s7bla +.section s7blb +.section s7bma +.section s7bmb +.section s7bna +.section s7bnb +.section s7boa +.section s7bob +.section s7bpa +.section s7bpb +.section s7bqa +.section s7bqb +.section s7bra +.section s7brb +.section s7bsa +.section s7bsb +.section s7bta +.section s7btb +.section s7bua +.section s7bub +.section s7bva +.section s7bvb +.section s7bwa +.section s7bwb +.section s7bxa +.section s7bxb +.section s7bya +.section s7byb +.section s7bza +.section s7bzb +.section s7b1a +.section s7b1b +.section s7b2a +.section s7b2b +.section s7b3a +.section s7b3b +.section s7b4a +.section s7b4b +.section s7b5a +.section s7b5b +.section s7b6a +.section s7b6b +.section s7b7a +.section s7b7b +.section s7b8a +.section s7b8b +.section s7b9a +.section s7b9b +.section s7b0a +.section s7b0b +.section s7caa +.section s7cab +.section s7cba +.section s7cbb +.section s7cca +.section s7ccb +.section s7cda +.section s7cdb +.section s7cea +.section s7ceb +.section s7cfa +.section s7cfb +.section s7cga +.section s7cgb +.section s7cha +.section s7chb +.section s7cia +.section s7cib +.section s7cja +.section s7cjb +.section s7cka +.section s7ckb +.section s7cla +.section s7clb +.section s7cma +.section s7cmb +.section s7cna +.section s7cnb +.section s7coa +.section s7cob +.section s7cpa +.section s7cpb +.section s7cqa +.section s7cqb +.section s7cra +.section s7crb +.section s7csa +.section s7csb +.section s7cta +.section s7ctb +.section s7cua +.section s7cub +.section s7cva +.section s7cvb +.section s7cwa +.section s7cwb +.section s7cxa +.section s7cxb +.section s7cya +.section s7cyb +.section s7cza +.section s7czb +.section s7c1a +.section s7c1b +.section s7c2a +.section s7c2b +.section s7c3a +.section s7c3b +.section s7c4a +.section s7c4b +.section s7c5a +.section s7c5b +.section s7c6a +.section s7c6b +.section s7c7a +.section s7c7b +.section s7c8a +.section s7c8b +.section s7c9a +.section s7c9b +.section s7c0a +.section s7c0b +.section s7daa +.section s7dab +.section s7dba +.section s7dbb +.section s7dca +.section s7dcb +.section s7dda +.section s7ddb +.section s7dea +.section s7deb +.section s7dfa +.section s7dfb +.section s7dga +.section s7dgb +.section s7dha +.section s7dhb +.section s7dia +.section s7dib +.section s7dja +.section s7djb +.section s7dka +.section s7dkb +.section s7dla +.section s7dlb +.section s7dma +.section s7dmb +.section s7dna +.section s7dnb +.section s7doa +.section s7dob +.section s7dpa +.section s7dpb +.section s7dqa +.section s7dqb +.section s7dra +.section s7drb +.section s7dsa +.section s7dsb +.section s7dta +.section s7dtb +.section s7dua +.section s7dub +.section s7dva +.section s7dvb +.section s7dwa +.section s7dwb +.section s7dxa +.section s7dxb +.section s7dya +.section s7dyb +.section s7dza +.section s7dzb +.section s7d1a +.section s7d1b +.section s7d2a +.section s7d2b +.section s7d3a +.section s7d3b +.section s7d4a +.section s7d4b +.section s7d5a +.section s7d5b +.section s7d6a +.section s7d6b +.section s7d7a +.section s7d7b +.section s7d8a +.section s7d8b +.section s7d9a +.section s7d9b +.section s7d0a +.section s7d0b +.section s7eaa +.section s7eab +.section s7eba +.section s7ebb +.section s7eca +.section s7ecb +.section s7eda +.section s7edb +.section s7eea +.section s7eeb +.section s7efa +.section s7efb +.section s7ega +.section s7egb +.section s7eha +.section s7ehb +.section s7eia +.section s7eib +.section s7eja +.section s7ejb +.section s7eka +.section s7ekb +.section s7ela +.section s7elb +.section s7ema +.section s7emb +.section s7ena +.section s7enb +.section s7eoa +.section s7eob +.section s7epa +.section s7epb +.section s7eqa +.section s7eqb +.section s7era +.section s7erb +.section s7esa +.section s7esb +.section s7eta +.section s7etb +.section s7eua +.section s7eub +.section s7eva +.section s7evb +.section s7ewa +.section s7ewb +.section s7exa +.section s7exb +.section s7eya +.section s7eyb +.section s7eza +.section s7ezb +.section s7e1a +.section s7e1b +.section s7e2a +.section s7e2b +.section s7e3a +.section s7e3b +.section s7e4a +.section s7e4b +.section s7e5a +.section s7e5b +.section s7e6a +.section s7e6b +.section s7e7a +.section s7e7b +.section s7e8a +.section s7e8b +.section s7e9a +.section s7e9b +.section s7e0a +.section s7e0b +.section s7faa +.section s7fab +.section s7fba +.section s7fbb +.section s7fca +.section s7fcb +.section s7fda +.section s7fdb +.section s7fea +.section s7feb +.section s7ffa +.section s7ffb +.section s7fga +.section s7fgb +.section s7fha +.section s7fhb +.section s7fia +.section s7fib +.section s7fja +.section s7fjb +.section s7fka +.section s7fkb +.section s7fla +.section s7flb +.section s7fma +.section s7fmb +.section s7fna +.section s7fnb +.section s7foa +.section s7fob +.section s7fpa +.section s7fpb +.section s7fqa +.section s7fqb +.section s7fra +.section s7frb +.section s7fsa +.section s7fsb +.section s7fta +.section s7ftb +.section s7fua +.section s7fub +.section s7fva +.section s7fvb +.section s7fwa +.section s7fwb +.section s7fxa +.section s7fxb +.section s7fya +.section s7fyb +.section s7fza +.section s7fzb +.section s7f1a +.section s7f1b +.section s7f2a +.section s7f2b +.section s7f3a +.section s7f3b +.section s7f4a +.section s7f4b +.section s7f5a +.section s7f5b +.section s7f6a +.section s7f6b +.section s7f7a +.section s7f7b +.section s7f8a +.section s7f8b +.section s7f9a +.section s7f9b +.section s7f0a +.section s7f0b +.section s7gaa +.section s7gab +.section s7gba +.section s7gbb +.section s7gca +.section s7gcb +.section s7gda +.section s7gdb +.section s7gea +.section s7geb +.section s7gfa +.section s7gfb +.section s7gga +.section s7ggb +.section s7gha +.section s7ghb +.section s7gia +.section s7gib +.section s7gja +.section s7gjb +.section s7gka +.section s7gkb +.section s7gla +.section s7glb +.section s7gma +.section s7gmb +.section s7gna +.section s7gnb +.section s7goa +.section s7gob +.section s7gpa +.section s7gpb +.section s7gqa +.section s7gqb +.section s7gra +.section s7grb +.section s7gsa +.section s7gsb +.section s7gta +.section s7gtb +.section s7gua +.section s7gub +.section s7gva +.section s7gvb +.section s7gwa +.section s7gwb +.section s7gxa +.section s7gxb +.section s7gya +.section s7gyb +.section s7gza +.section s7gzb +.section s7g1a +.section s7g1b +.section s7g2a +.section s7g2b +.section s7g3a +.section s7g3b +.section s7g4a +.section s7g4b +.section s7g5a +.section s7g5b +.section s7g6a +.section s7g6b +.section s7g7a +.section s7g7b +.section s7g8a +.section s7g8b +.section s7g9a +.section s7g9b +.section s7g0a +.section s7g0b +.section s7haa +.section s7hab +.section s7hba +.section s7hbb +.section s7hca +.section s7hcb +.section s7hda +.section s7hdb +.section s7hea +.section s7heb +.section s7hfa +.section s7hfb +.section s7hga +.section s7hgb +.section s7hha +.section s7hhb +.section s7hia +.section s7hib +.section s7hja +.section s7hjb +.section s7hka +.section s7hkb +.section s7hla +.section s7hlb +.section s7hma +.section s7hmb +.section s7hna +.section s7hnb +.section s7hoa +.section s7hob +.section s7hpa +.section s7hpb +.section s7hqa +.section s7hqb +.section s7hra +.section s7hrb +.section s7hsa +.section s7hsb +.section s7hta +.section s7htb +.section s7hua +.section s7hub +.section s7hva +.section s7hvb +.section s7hwa +.section s7hwb +.section s7hxa +.section s7hxb +.section s7hya +.section s7hyb +.section s7hza +.section s7hzb +.section s7h1a +.section s7h1b +.section s7h2a +.section s7h2b +.section s7h3a +.section s7h3b +.section s7h4a +.section s7h4b +.section s7h5a +.section s7h5b +.section s7h6a +.section s7h6b +.section s7h7a +.section s7h7b +.section s7h8a +.section s7h8b +.section s7h9a +.section s7h9b +.section s7h0a +.section s7h0b +.section s7iaa +.section s7iab +.section s7iba +.section s7ibb +.section s7ica +.section s7icb +.section s7ida +.section s7idb +.section s7iea +.section s7ieb +.section s7ifa +.section s7ifb +.section s7iga +.section s7igb +.section s7iha +.section s7ihb +.section s7iia +.section s7iib +.section s7ija +.section s7ijb +.section s7ika +.section s7ikb +.section s7ila +.section s7ilb +.section s7ima +.section s7imb +.section s7ina +.section s7inb +.section s7ioa +.section s7iob +.section s7ipa +.section s7ipb +.section s7iqa +.section s7iqb +.section s7ira +.section s7irb +.section s7isa +.section s7isb +.section s7ita +.section s7itb +.section s7iua +.section s7iub +.section s7iva +.section s7ivb +.section s7iwa +.section s7iwb +.section s7ixa +.section s7ixb +.section s7iya +.section s7iyb +.section s7iza +.section s7izb +.section s7i1a +.section s7i1b +.section s7i2a +.section s7i2b +.section s7i3a +.section s7i3b +.section s7i4a +.section s7i4b +.section s7i5a +.section s7i5b +.section s7i6a +.section s7i6b +.section s7i7a +.section s7i7b +.section s7i8a +.section s7i8b +.section s7i9a +.section s7i9b +.section s7i0a +.section s7i0b +.section s7jaa +.section s7jab +.section s7jba +.section s7jbb +.section s7jca +.section s7jcb +.section s7jda +.section s7jdb +.section s7jea +.section s7jeb +.section s7jfa +.section s7jfb +.section s7jga +.section s7jgb +.section s7jha +.section s7jhb +.section s7jia +.section s7jib +.section s7jja +.section s7jjb +.section s7jka +.section s7jkb +.section s7jla +.section s7jlb +.section s7jma +.section s7jmb +.section s7jna +.section s7jnb +.section s7joa +.section s7job +.section s7jpa +.section s7jpb +.section s7jqa +.section s7jqb +.section s7jra +.section s7jrb +.section s7jsa +.section s7jsb +.section s7jta +.section s7jtb +.section s7jua +.section s7jub +.section s7jva +.section s7jvb +.section s7jwa +.section s7jwb +.section s7jxa +.section s7jxb +.section s7jya +.section s7jyb +.section s7jza +.section s7jzb +.section s7j1a +.section s7j1b +.section s7j2a +.section s7j2b +.section s7j3a +.section s7j3b +.section s7j4a +.section s7j4b +.section s7j5a +.section s7j5b +.section s7j6a +.section s7j6b +.section s7j7a +.section s7j7b +.section s7j8a +.section s7j8b +.section s7j9a +.section s7j9b +.section s7j0a +.section s7j0b +.section s7kaa +.section s7kab +.section s7kba +.section s7kbb +.section s7kca +.section s7kcb +.section s7kda +.section s7kdb +.section s7kea +.section s7keb +.section s7kfa +.section s7kfb +.section s7kga +.section s7kgb +.section s7kha +.section s7khb +.section s7kia +.section s7kib +.section s7kja +.section s7kjb +.section s7kka +.section s7kkb +.section s7kla +.section s7klb +.section s7kma +.section s7kmb +.section s7kna +.section s7knb +.section s7koa +.section s7kob +.section s7kpa +.section s7kpb +.section s7kqa +.section s7kqb +.section s7kra +.section s7krb +.section s7ksa +.section s7ksb +.section s7kta +.section s7ktb +.section s7kua +.section s7kub +.section s7kva +.section s7kvb +.section s7kwa +.section s7kwb +.section s7kxa +.section s7kxb +.section s7kya +.section s7kyb +.section s7kza +.section s7kzb +.section s7k1a +.section s7k1b +.section s7k2a +.section s7k2b +.section s7k3a +.section s7k3b +.section s7k4a +.section s7k4b +.section s7k5a +.section s7k5b +.section s7k6a +.section s7k6b +.section s7k7a +.section s7k7b +.section s7k8a +.section s7k8b +.section s7k9a +.section s7k9b +.section s7k0a +.section s7k0b +.section s7laa +.section s7lab +.section s7lba +.section s7lbb +.section s7lca +.section s7lcb +.section s7lda +.section s7ldb +.section s7lea +.section s7leb +.section s7lfa +.section s7lfb +.section s7lga +.section s7lgb +.section s7lha +.section s7lhb +.section s7lia +.section s7lib +.section s7lja +.section s7ljb +.section s7lka +.section s7lkb +.section s7lla +.section s7llb +.section s7lma +.section s7lmb +.section s7lna +.section s7lnb +.section s7loa +.section s7lob +.section s7lpa +.section s7lpb +.section s7lqa +.section s7lqb +.section s7lra +.section s7lrb +.section s7lsa +.section s7lsb +.section s7lta +.section s7ltb +.section s7lua +.section s7lub +.section s7lva +.section s7lvb +.section s7lwa +.section s7lwb +.section s7lxa +.section s7lxb +.section s7lya +.section s7lyb +.section s7lza +.section s7lzb +.section s7l1a +.section s7l1b +.section s7l2a +.section s7l2b +.section s7l3a +.section s7l3b +.section s7l4a +.section s7l4b +.section s7l5a +.section s7l5b +.section s7l6a +.section s7l6b +.section s7l7a +.section s7l7b +.section s7l8a +.section s7l8b +.section s7l9a +.section s7l9b +.section s7l0a +.section s7l0b +.section s7maa +.section s7mab +.section s7mba +.section s7mbb +.section s7mca +.section s7mcb +.section s7mda +.section s7mdb +.section s7mea +.section s7meb +.section s7mfa +.section s7mfb +.section s7mga +.section s7mgb +.section s7mha +.section s7mhb +.section s7mia +.section s7mib +.section s7mja +.section s7mjb +.section s7mka +.section s7mkb +.section s7mla +.section s7mlb +.section s7mma +.section s7mmb +.section s7mna +.section s7mnb +.section s7moa +.section s7mob +.section s7mpa +.section s7mpb +.section s7mqa +.section s7mqb +.section s7mra +.section s7mrb +.section s7msa +.section s7msb +.section s7mta +.section s7mtb +.section s7mua +.section s7mub +.section s7mva +.section s7mvb +.section s7mwa +.section s7mwb +.section s7mxa +.section s7mxb +.section s7mya +.section s7myb +.section s7mza +.section s7mzb +.section s7m1a +.section s7m1b +.section s7m2a +.section s7m2b +.section s7m3a +.section s7m3b +.section s7m4a +.section s7m4b +.section s7m5a +.section s7m5b +.section s7m6a +.section s7m6b +.section s7m7a +.section s7m7b +.section s7m8a +.section s7m8b +.section s7m9a +.section s7m9b +.section s7m0a +.section s7m0b +.section s7naa +.section s7nab +.section s7nba +.section s7nbb +.section s7nca +.section s7ncb +.section s7nda +.section s7ndb +.section s7nea +.section s7neb +.section s7nfa +.section s7nfb +.section s7nga +.section s7ngb +.section s7nha +.section s7nhb +.section s7nia +.section s7nib +.section s7nja +.section s7njb +.section s7nka +.section s7nkb +.section s7nla +.section s7nlb +.section s7nma +.section s7nmb +.section s7nna +.section s7nnb +.section s7noa +.section s7nob +.section s7npa +.section s7npb +.section s7nqa +.section s7nqb +.section s7nra +.section s7nrb +.section s7nsa +.section s7nsb +.section s7nta +.section s7ntb +.section s7nua +.section s7nub +.section s7nva +.section s7nvb +.section s7nwa +.section s7nwb +.section s7nxa +.section s7nxb +.section s7nya +.section s7nyb +.section s7nza +.section s7nzb +.section s7n1a +.section s7n1b +.section s7n2a +.section s7n2b +.section s7n3a +.section s7n3b +.section s7n4a +.section s7n4b +.section s7n5a +.section s7n5b +.section s7n6a +.section s7n6b +.section s7n7a +.section s7n7b +.section s7n8a +.section s7n8b +.section s7n9a +.section s7n9b +.section s7n0a +.section s7n0b +.section s7oaa +.section s7oab +.section s7oba +.section s7obb +.section s7oca +.section s7ocb +.section s7oda +.section s7odb +.section s7oea +.section s7oeb +.section s7ofa +.section s7ofb +.section s7oga +.section s7ogb +.section s7oha +.section s7ohb +.section s7oia +.section s7oib +.section s7oja +.section s7ojb +.section s7oka +.section s7okb +.section s7ola +.section s7olb +.section s7oma +.section s7omb +.section s7ona +.section s7onb +.section s7ooa +.section s7oob +.section s7opa +.section s7opb +.section s7oqa +.section s7oqb +.section s7ora +.section s7orb +.section s7osa +.section s7osb +.section s7ota +.section s7otb +.section s7oua +.section s7oub +.section s7ova +.section s7ovb +.section s7owa +.section s7owb +.section s7oxa +.section s7oxb +.section s7oya +.section s7oyb +.section s7oza +.section s7ozb +.section s7o1a +.section s7o1b +.section s7o2a +.section s7o2b +.section s7o3a +.section s7o3b +.section s7o4a +.section s7o4b +.section s7o5a +.section s7o5b +.section s7o6a +.section s7o6b +.section s7o7a +.section s7o7b +.section s7o8a +.section s7o8b +.section s7o9a +.section s7o9b +.section s7o0a +.section s7o0b +.section s7paa +.section s7pab +.section s7pba +.section s7pbb +.section s7pca +.section s7pcb +.section s7pda +.section s7pdb +.section s7pea +.section s7peb +.section s7pfa +.section s7pfb +.section s7pga +.section s7pgb +.section s7pha +.section s7phb +.section s7pia +.section s7pib +.section s7pja +.section s7pjb +.section s7pka +.section s7pkb +.section s7pla +.section s7plb +.section s7pma +.section s7pmb +.section s7pna +.section s7pnb +.section s7poa +.section s7pob +.section s7ppa +.section s7ppb +.section s7pqa +.section s7pqb +.section s7pra +.section s7prb +.section s7psa +.section s7psb +.section s7pta +.section s7ptb +.section s7pua +.section s7pub +.section s7pva +.section s7pvb +.section s7pwa +.section s7pwb +.section s7pxa +.section s7pxb +.section s7pya +.section s7pyb +.section s7pza +.section s7pzb +.section s7p1a +.section s7p1b +.section s7p2a +.section s7p2b +.section s7p3a +.section s7p3b +.section s7p4a +.section s7p4b +.section s7p5a +.section s7p5b +.section s7p6a +.section s7p6b +.section s7p7a +.section s7p7b +.section s7p8a +.section s7p8b +.section s7p9a +.section s7p9b +.section s7p0a +.section s7p0b +.section s7qaa +.section s7qab +.section s7qba +.section s7qbb +.section s7qca +.section s7qcb +.section s7qda +.section s7qdb +.section s7qea +.section s7qeb +.section s7qfa +.section s7qfb +.section s7qga +.section s7qgb +.section s7qha +.section s7qhb +.section s7qia +.section s7qib +.section s7qja +.section s7qjb +.section s7qka +.section s7qkb +.section s7qla +.section s7qlb +.section s7qma +.section s7qmb +.section s7qna +.section s7qnb +.section s7qoa +.section s7qob +.section s7qpa +.section s7qpb +.section s7qqa +.section s7qqb +.section s7qra +.section s7qrb +.section s7qsa +.section s7qsb +.section s7qta +.section s7qtb +.section s7qua +.section s7qub +.section s7qva +.section s7qvb +.section s7qwa +.section s7qwb +.section s7qxa +.section s7qxb +.section s7qya +.section s7qyb +.section s7qza +.section s7qzb +.section s7q1a +.section s7q1b +.section s7q2a +.section s7q2b +.section s7q3a +.section s7q3b +.section s7q4a +.section s7q4b +.section s7q5a +.section s7q5b +.section s7q6a +.section s7q6b +.section s7q7a +.section s7q7b +.section s7q8a +.section s7q8b +.section s7q9a +.section s7q9b +.section s7q0a +.section s7q0b +.section s7raa +.section s7rab +.section s7rba +.section s7rbb +.section s7rca +.section s7rcb +.section s7rda +.section s7rdb +.section s7rea +.section s7reb +.section s7rfa +.section s7rfb +.section s7rga +.section s7rgb +.section s7rha +.section s7rhb +.section s7ria +.section s7rib +.section s7rja +.section s7rjb +.section s7rka +.section s7rkb +.section s7rla +.section s7rlb +.section s7rma +.section s7rmb +.section s7rna +.section s7rnb +.section s7roa +.section s7rob +.section s7rpa +.section s7rpb +.section s7rqa +.section s7rqb +.section s7rra +.section s7rrb +.section s7rsa +.section s7rsb +.section s7rta +.section s7rtb +.section s7rua +.section s7rub +.section s7rva +.section s7rvb +.section s7rwa +.section s7rwb +.section s7rxa +.section s7rxb +.section s7rya +.section s7ryb +.section s7rza +.section s7rzb +.section s7r1a +.section s7r1b +.section s7r2a +.section s7r2b +.section s7r3a +.section s7r3b +.section s7r4a +.section s7r4b +.section s7r5a +.section s7r5b +.section s7r6a +.section s7r6b +.section s7r7a +.section s7r7b +.section s7r8a +.section s7r8b +.section s7r9a +.section s7r9b +.section s7r0a +.section s7r0b +.section s7saa +.section s7sab +.section s7sba +.section s7sbb +.section s7sca +.section s7scb +.section s7sda +.section s7sdb +.section s7sea +.section s7seb +.section s7sfa +.section s7sfb +.section s7sga +.section s7sgb +.section s7sha +.section s7shb +.section s7sia +.section s7sib +.section s7sja +.section s7sjb +.section s7ska +.section s7skb +.section s7sla +.section s7slb +.section s7sma +.section s7smb +.section s7sna +.section s7snb +.section s7soa +.section s7sob +.section s7spa +.section s7spb +.section s7sqa +.section s7sqb +.section s7sra +.section s7srb +.section s7ssa +.section s7ssb +.section s7sta +.section s7stb +.section s7sua +.section s7sub +.section s7sva +.section s7svb +.section s7swa +.section s7swb +.section s7sxa +.section s7sxb +.section s7sya +.section s7syb +.section s7sza +.section s7szb +.section s7s1a +.section s7s1b +.section s7s2a +.section s7s2b +.section s7s3a +.section s7s3b +.section s7s4a +.section s7s4b +.section s7s5a +.section s7s5b +.section s7s6a +.section s7s6b +.section s7s7a +.section s7s7b +.section s7s8a +.section s7s8b +.section s7s9a +.section s7s9b +.section s7s0a +.section s7s0b +.section s7taa +.section s7tab +.section s7tba +.section s7tbb +.section s7tca +.section s7tcb +.section s7tda +.section s7tdb +.section s7tea +.section s7teb +.section s7tfa +.section s7tfb +.section s7tga +.section s7tgb +.section s7tha +.section s7thb +.section s7tia +.section s7tib +.section s7tja +.section s7tjb +.section s7tka +.section s7tkb +.section s7tla +.section s7tlb +.section s7tma +.section s7tmb +.section s7tna +.section s7tnb +.section s7toa +.section s7tob +.section s7tpa +.section s7tpb +.section s7tqa +.section s7tqb +.section s7tra +.section s7trb +.section s7tsa +.section s7tsb +.section s7tta +.section s7ttb +.section s7tua +.section s7tub +.section s7tva +.section s7tvb +.section s7twa +.section s7twb +.section s7txa +.section s7txb +.section s7tya +.section s7tyb +.section s7tza +.section s7tzb +.section s7t1a +.section s7t1b +.section s7t2a +.section s7t2b +.section s7t3a +.section s7t3b +.section s7t4a +.section s7t4b +.section s7t5a +.section s7t5b +.section s7t6a +.section s7t6b +.section s7t7a +.section s7t7b +.section s7t8a +.section s7t8b +.section s7t9a +.section s7t9b +.section s7t0a +.section s7t0b +.section s7uaa +.section s7uab +.section s7uba +.section s7ubb +.section s7uca +.section s7ucb +.section s7uda +.section s7udb +.section s7uea +.section s7ueb +.section s7ufa +.section s7ufb +.section s7uga +.section s7ugb +.section s7uha +.section s7uhb +.section s7uia +.section s7uib +.section s7uja +.section s7ujb +.section s7uka +.section s7ukb +.section s7ula +.section s7ulb +.section s7uma +.section s7umb +.section s7una +.section s7unb +.section s7uoa +.section s7uob +.section s7upa +.section s7upb +.section s7uqa +.section s7uqb +.section s7ura +.section s7urb +.section s7usa +.section s7usb +.section s7uta +.section s7utb +.section s7uua +.section s7uub +.section s7uva +.section s7uvb +.section s7uwa +.section s7uwb +.section s7uxa +.section s7uxb +.section s7uya +.section s7uyb +.section s7uza +.section s7uzb +.section s7u1a +.section s7u1b +.section s7u2a +.section s7u2b +.section s7u3a +.section s7u3b +.section s7u4a +.section s7u4b +.section s7u5a +.section s7u5b +.section s7u6a +.section s7u6b +.section s7u7a +.section s7u7b +.section s7u8a +.section s7u8b +.section s7u9a +.section s7u9b +.section s7u0a +.section s7u0b +.section s7vaa +.section s7vab +.section s7vba +.section s7vbb +.section s7vca +.section s7vcb +.section s7vda +.section s7vdb +.section s7vea +.section s7veb +.section s7vfa +.section s7vfb +.section s7vga +.section s7vgb +.section s7vha +.section s7vhb +.section s7via +.section s7vib +.section s7vja +.section s7vjb +.section s7vka +.section s7vkb +.section s7vla +.section s7vlb +.section s7vma +.section s7vmb +.section s7vna +.section s7vnb +.section s7voa +.section s7vob +.section s7vpa +.section s7vpb +.section s7vqa +.section s7vqb +.section s7vra +.section s7vrb +.section s7vsa +.section s7vsb +.section s7vta +.section s7vtb +.section s7vua +.section s7vub +.section s7vva +.section s7vvb +.section s7vwa +.section s7vwb +.section s7vxa +.section s7vxb +.section s7vya +.section s7vyb +.section s7vza +.section s7vzb +.section s7v1a +.section s7v1b +.section s7v2a +.section s7v2b +.section s7v3a +.section s7v3b +.section s7v4a +.section s7v4b +.section s7v5a +.section s7v5b +.section s7v6a +.section s7v6b +.section s7v7a +.section s7v7b +.section s7v8a +.section s7v8b +.section s7v9a +.section s7v9b +.section s7v0a +.section s7v0b +.section s7waa +.section s7wab +.section s7wba +.section s7wbb +.section s7wca +.section s7wcb +.section s7wda +.section s7wdb +.section s7wea +.section s7web +.section s7wfa +.section s7wfb +.section s7wga +.section s7wgb +.section s7wha +.section s7whb +.section s7wia +.section s7wib +.section s7wja +.section s7wjb +.section s7wka +.section s7wkb +.section s7wla +.section s7wlb +.section s7wma +.section s7wmb +.section s7wna +.section s7wnb +.section s7woa +.section s7wob +.section s7wpa +.section s7wpb +.section s7wqa +.section s7wqb +.section s7wra +.section s7wrb +.section s7wsa +.section s7wsb +.section s7wta +.section s7wtb +.section s7wua +.section s7wub +.section s7wva +.section s7wvb +.section s7wwa +.section s7wwb +.section s7wxa +.section s7wxb +.section s7wya +.section s7wyb +.section s7wza +.section s7wzb +.section s7w1a +.section s7w1b +.section s7w2a +.section s7w2b +.section s7w3a +.section s7w3b +.section s7w4a +.section s7w4b +.section s7w5a +.section s7w5b +.section s7w6a +.section s7w6b +.section s7w7a +.section s7w7b +.section s7w8a +.section s7w8b +.section s7w9a +.section s7w9b +.section s7w0a +.section s7w0b +.section s7xaa +.section s7xab +.section s7xba +.section s7xbb +.section s7xca +.section s7xcb +.section s7xda +.section s7xdb +.section s7xea +.section s7xeb +.section s7xfa +.section s7xfb +.section s7xga +.section s7xgb +.section s7xha +.section s7xhb +.section s7xia +.section s7xib +.section s7xja +.section s7xjb +.section s7xka +.section s7xkb +.section s7xla +.section s7xlb +.section s7xma +.section s7xmb +.section s7xna +.section s7xnb +.section s7xoa +.section s7xob +.section s7xpa +.section s7xpb +.section s7xqa +.section s7xqb +.section s7xra +.section s7xrb +.section s7xsa +.section s7xsb +.section s7xta +.section s7xtb +.section s7xua +.section s7xub +.section s7xva +.section s7xvb +.section s7xwa +.section s7xwb +.section s7xxa +.section s7xxb +.section s7xya +.section s7xyb +.section s7xza +.section s7xzb +.section s7x1a +.section s7x1b +.section s7x2a +.section s7x2b +.section s7x3a +.section s7x3b +.section s7x4a +.section s7x4b +.section s7x5a +.section s7x5b +.section s7x6a +.section s7x6b +.section s7x7a +.section s7x7b +.section s7x8a +.section s7x8b +.section s7x9a +.section s7x9b +.section s7x0a +.section s7x0b +.section s7yaa +.section s7yab +.section s7yba +.section s7ybb +.section s7yca +.section s7ycb +.section s7yda +.section s7ydb +.section s7yea +.section s7yeb +.section s7yfa +.section s7yfb +.section s7yga +.section s7ygb +.section s7yha +.section s7yhb +.section s7yia +.section s7yib +.section s7yja +.section s7yjb +.section s7yka +.section s7ykb +.section s7yla +.section s7ylb +.section s7yma +.section s7ymb +.section s7yna +.section s7ynb +.section s7yoa +.section s7yob +.section s7ypa +.section s7ypb +.section s7yqa +.section s7yqb +.section s7yra +.section s7yrb +.section s7ysa +.section s7ysb +.section s7yta +.section s7ytb +.section s7yua +.section s7yub +.section s7yva +.section s7yvb +.section s7ywa +.section s7ywb +.section s7yxa +.section s7yxb +.section s7yya +.section s7yyb +.section s7yza +.section s7yzb +.section s7y1a +.section s7y1b +.section s7y2a +.section s7y2b +.section s7y3a +.section s7y3b +.section s7y4a +.section s7y4b +.section s7y5a +.section s7y5b +.section s7y6a +.section s7y6b +.section s7y7a +.section s7y7b +.section s7y8a +.section s7y8b +.section s7y9a +.section s7y9b +.section s7y0a +.section s7y0b +.section s7zaa +.section s7zab +.section s7zba +.section s7zbb +.section s7zca +.section s7zcb +.section s7zda +.section s7zdb +.section s7zea +.section s7zeb +.section s7zfa +.section s7zfb +.section s7zga +.section s7zgb +.section s7zha +.section s7zhb +.section s7zia +.section s7zib +.section s7zja +.section s7zjb +.section s7zka +.section s7zkb +.section s7zla +.section s7zlb +.section s7zma +.section s7zmb +.section s7zna +.section s7znb +.section s7zoa +.section s7zob +.section s7zpa +.section s7zpb +.section s7zqa +.section s7zqb +.section s7zra +.section s7zrb +.section s7zsa +.section s7zsb +.section s7zta +.section s7ztb +.section s7zua +.section s7zub +.section s7zva +.section s7zvb +.section s7zwa +.section s7zwb +.section s7zxa +.section s7zxb +.section s7zya +.section s7zyb +.section s7zza +.section s7zzb +.section s7z1a +.section s7z1b +.section s7z2a +.section s7z2b +.section s7z3a +.section s7z3b +.section s7z4a +.section s7z4b +.section s7z5a +.section s7z5b +.section s7z6a +.section s7z6b +.section s7z7a +.section s7z7b +.section s7z8a +.section s7z8b +.section s7z9a +.section s7z9b +.section s7z0a +.section s7z0b +.section s71aa +.section s71ab +.section s71ba +.section s71bb +.section s71ca +.section s71cb +.section s71da +.section s71db +.section s71ea +.section s71eb +.section s71fa +.section s71fb +.section s71ga +.section s71gb +.section s71ha +.section s71hb +.section s71ia +.section s71ib +.section s71ja +.section s71jb +.section s71ka +.section s71kb +.section s71la +.section s71lb +.section s71ma +.section s71mb +.section s71na +.section s71nb +.section s71oa +.section s71ob +.section s71pa +.section s71pb +.section s71qa +.section s71qb +.section s71ra +.section s71rb +.section s71sa +.section s71sb +.section s71ta +.section s71tb +.section s71ua +.section s71ub +.section s71va +.section s71vb +.section s71wa +.section s71wb +.section s71xa +.section s71xb +.section s71ya +.section s71yb +.section s71za +.section s71zb +.section s711a +.section s711b +.section s712a +.section s712b +.section s713a +.section s713b +.section s714a +.section s714b +.section s715a +.section s715b +.section s716a +.section s716b +.section s717a +.section s717b +.section s718a +.section s718b +.section s719a +.section s719b +.section s710a +.section s710b +.section s72aa +.section s72ab +.section s72ba +.section s72bb +.section s72ca +.section s72cb +.section s72da +.section s72db +.section s72ea +.section s72eb +.section s72fa +.section s72fb +.section s72ga +.section s72gb +.section s72ha +.section s72hb +.section s72ia +.section s72ib +.section s72ja +.section s72jb +.section s72ka +.section s72kb +.section s72la +.section s72lb +.section s72ma +.section s72mb +.section s72na +.section s72nb +.section s72oa +.section s72ob +.section s72pa +.section s72pb +.section s72qa +.section s72qb +.section s72ra +.section s72rb +.section s72sa +.section s72sb +.section s72ta +.section s72tb +.section s72ua +.section s72ub +.section s72va +.section s72vb +.section s72wa +.section s72wb +.section s72xa +.section s72xb +.section s72ya +.section s72yb +.section s72za +.section s72zb +.section s721a +.section s721b +.section s722a +.section s722b +.section s723a +.section s723b +.section s724a +.section s724b +.section s725a +.section s725b +.section s726a +.section s726b +.section s727a +.section s727b +.section s728a +.section s728b +.section s729a +.section s729b +.section s720a +.section s720b +.section s73aa +.section s73ab +.section s73ba +.section s73bb +.section s73ca +.section s73cb +.section s73da +.section s73db +.section s73ea +.section s73eb +.section s73fa +.section s73fb +.section s73ga +.section s73gb +.section s73ha +.section s73hb +.section s73ia +.section s73ib +.section s73ja +.section s73jb +.section s73ka +.section s73kb +.section s73la +.section s73lb +.section s73ma +.section s73mb +.section s73na +.section s73nb +.section s73oa +.section s73ob +.section s73pa +.section s73pb +.section s73qa +.section s73qb +.section s73ra +.section s73rb +.section s73sa +.section s73sb +.section s73ta +.section s73tb +.section s73ua +.section s73ub +.section s73va +.section s73vb +.section s73wa +.section s73wb +.section s73xa +.section s73xb +.section s73ya +.section s73yb +.section s73za +.section s73zb +.section s731a +.section s731b +.section s732a +.section s732b +.section s733a +.section s733b +.section s734a +.section s734b +.section s735a +.section s735b +.section s736a +.section s736b +.section s737a +.section s737b +.section s738a +.section s738b +.section s739a +.section s739b +.section s730a +.section s730b +.section s74aa +.section s74ab +.section s74ba +.section s74bb +.section s74ca +.section s74cb +.section s74da +.section s74db +.section s74ea +.section s74eb +.section s74fa +.section s74fb +.section s74ga +.section s74gb +.section s74ha +.section s74hb +.section s74ia +.section s74ib +.section s74ja +.section s74jb +.section s74ka +.section s74kb +.section s74la +.section s74lb +.section s74ma +.section s74mb +.section s74na +.section s74nb +.section s74oa +.section s74ob +.section s74pa +.section s74pb +.section s74qa +.section s74qb +.section s74ra +.section s74rb +.section s74sa +.section s74sb +.section s74ta +.section s74tb +.section s74ua +.section s74ub +.section s74va +.section s74vb +.section s74wa +.section s74wb +.section s74xa +.section s74xb +.section s74ya +.section s74yb +.section s74za +.section s74zb +.section s741a +.section s741b +.section s742a +.section s742b +.section s743a +.section s743b +.section s744a +.section s744b +.section s745a +.section s745b +.section s746a +.section s746b +.section s747a +.section s747b +.section s748a +.section s748b +.section s749a +.section s749b +.section s740a +.section s740b +.section s75aa +.section s75ab +.section s75ba +.section s75bb +.section s75ca +.section s75cb +.section s75da +.section s75db +.section s75ea +.section s75eb +.section s75fa +.section s75fb +.section s75ga +.section s75gb +.section s75ha +.section s75hb +.section s75ia +.section s75ib +.section s75ja +.section s75jb +.section s75ka +.section s75kb +.section s75la +.section s75lb +.section s75ma +.section s75mb +.section s75na +.section s75nb +.section s75oa +.section s75ob +.section s75pa +.section s75pb +.section s75qa +.section s75qb +.section s75ra +.section s75rb +.section s75sa +.section s75sb +.section s75ta +.section s75tb +.section s75ua +.section s75ub +.section s75va +.section s75vb +.section s75wa +.section s75wb +.section s75xa +.section s75xb +.section s75ya +.section s75yb +.section s75za +.section s75zb +.section s751a +.section s751b +.section s752a +.section s752b +.section s753a +.section s753b +.section s754a +.section s754b +.section s755a +.section s755b +.section s756a +.section s756b +.section s757a +.section s757b +.section s758a +.section s758b +.section s759a +.section s759b +.section s750a +.section s750b +.section s76aa +.section s76ab +.section s76ba +.section s76bb +.section s76ca +.section s76cb +.section s76da +.section s76db +.section s76ea +.section s76eb +.section s76fa +.section s76fb +.section s76ga +.section s76gb +.section s76ha +.section s76hb +.section s76ia +.section s76ib +.section s76ja +.section s76jb +.section s76ka +.section s76kb +.section s76la +.section s76lb +.section s76ma +.section s76mb +.section s76na +.section s76nb +.section s76oa +.section s76ob +.section s76pa +.section s76pb +.section s76qa +.section s76qb +.section s76ra +.section s76rb +.section s76sa +.section s76sb +.section s76ta +.section s76tb +.section s76ua +.section s76ub +.section s76va +.section s76vb +.section s76wa +.section s76wb +.section s76xa +.section s76xb +.section s76ya +.section s76yb +.section s76za +.section s76zb +.section s761a +.section s761b +.section s762a +.section s762b +.section s763a +.section s763b +.section s764a +.section s764b +.section s765a +.section s765b +.section s766a +.section s766b +.section s767a +.section s767b +.section s768a +.section s768b +.section s769a +.section s769b +.section s760a +.section s760b +.section s77aa +.section s77ab +.section s77ba +.section s77bb +.section s77ca +.section s77cb +.section s77da +.section s77db +.section s77ea +.section s77eb +.section s77fa +.section s77fb +.section s77ga +.section s77gb +.section s77ha +.section s77hb +.section s77ia +.section s77ib +.section s77ja +.section s77jb +.section s77ka +.section s77kb +.section s77la +.section s77lb +.section s77ma +.section s77mb +.section s77na +.section s77nb +.section s77oa +.section s77ob +.section s77pa +.section s77pb +.section s77qa +.section s77qb +.section s77ra +.section s77rb +.section s77sa +.section s77sb +.section s77ta +.section s77tb +.section s77ua +.section s77ub +.section s77va +.section s77vb +.section s77wa +.section s77wb +.section s77xa +.section s77xb +.section s77ya +.section s77yb +.section s77za +.section s77zb +.section s771a +.section s771b +.section s772a +.section s772b +.section s773a +.section s773b +.section s774a +.section s774b +.section s775a +.section s775b +.section s776a +.section s776b +.section s777a +.section s777b +.section s778a +.section s778b +.section s779a +.section s779b +.section s770a +.section s770b +.section s78aa +.section s78ab +.section s78ba +.section s78bb +.section s78ca +.section s78cb +.section s78da +.section s78db +.section s78ea +.section s78eb +.section s78fa +.section s78fb +.section s78ga +.section s78gb +.section s78ha +.section s78hb +.section s78ia +.section s78ib +.section s78ja +.section s78jb +.section s78ka +.section s78kb +.section s78la +.section s78lb +.section s78ma +.section s78mb +.section s78na +.section s78nb +.section s78oa +.section s78ob +.section s78pa +.section s78pb +.section s78qa +.section s78qb +.section s78ra +.section s78rb +.section s78sa +.section s78sb +.section s78ta +.section s78tb +.section s78ua +.section s78ub +.section s78va +.section s78vb +.section s78wa +.section s78wb +.section s78xa +.section s78xb +.section s78ya +.section s78yb +.section s78za +.section s78zb +.section s781a +.section s781b +.section s782a +.section s782b +.section s783a +.section s783b +.section s784a +.section s784b +.section s785a +.section s785b +.section s786a +.section s786b +.section s787a +.section s787b +.section s788a +.section s788b +.section s789a +.section s789b +.section s780a +.section s780b +.section s79aa +.section s79ab +.section s79ba +.section s79bb +.section s79ca +.section s79cb +.section s79da +.section s79db +.section s79ea +.section s79eb +.section s79fa +.section s79fb +.section s79ga +.section s79gb +.section s79ha +.section s79hb +.section s79ia +.section s79ib +.section s79ja +.section s79jb +.section s79ka +.section s79kb +.section s79la +.section s79lb +.section s79ma +.section s79mb +.section s79na +.section s79nb +.section s79oa +.section s79ob +.section s79pa +.section s79pb +.section s79qa +.section s79qb +.section s79ra +.section s79rb +.section s79sa +.section s79sb +.section s79ta +.section s79tb +.section s79ua +.section s79ub +.section s79va +.section s79vb +.section s79wa +.section s79wb +.section s79xa +.section s79xb +.section s79ya +.section s79yb +.section s79za +.section s79zb +.section s791a +.section s791b +.section s792a +.section s792b +.section s793a +.section s793b +.section s794a +.section s794b +.section s795a +.section s795b +.section s796a +.section s796b +.section s797a +.section s797b +.section s798a +.section s798b +.section s799a +.section s799b +.section s790a +.section s790b +.section s70aa +.section s70ab +.section s70ba +.section s70bb +.section s70ca +.section s70cb +.section s70da +.section s70db +.section s70ea +.section s70eb +.section s70fa +.section s70fb +.section s70ga +.section s70gb +.section s70ha +.section s70hb +.section s70ia +.section s70ib +.section s70ja +.section s70jb +.section s70ka +.section s70kb +.section s70la +.section s70lb +.section s70ma +.section s70mb +.section s70na +.section s70nb +.section s70oa +.section s70ob +.section s70pa +.section s70pb +.section s70qa +.section s70qb +.section s70ra +.section s70rb +.section s70sa +.section s70sb +.section s70ta +.section s70tb +.section s70ua +.section s70ub +.section s70va +.section s70vb +.section s70wa +.section s70wb +.section s70xa +.section s70xb +.section s70ya +.section s70yb +.section s70za +.section s70zb +.section s701a +.section s701b +.section s702a +.section s702b +.section s703a +.section s703b +.section s704a +.section s704b +.section s705a +.section s705b +.section s706a +.section s706b +.section s707a +.section s707b +.section s708a +.section s708b +.section s709a +.section s709b +.section s700a +.section s700b +.section s8aaa +.section s8aab +.section s8aba +.section s8abb +.section s8aca +.section s8acb +.section s8ada +.section s8adb +.section s8aea +.section s8aeb +.section s8afa +.section s8afb +.section s8aga +.section s8agb +.section s8aha +.section s8ahb +.section s8aia +.section s8aib +.section s8aja +.section s8ajb +.section s8aka +.section s8akb +.section s8ala +.section s8alb +.section s8ama +.section s8amb +.section s8ana +.section s8anb +.section s8aoa +.section s8aob +.section s8apa +.section s8apb +.section s8aqa +.section s8aqb +.section s8ara +.section s8arb +.section s8asa +.section s8asb +.section s8ata +.section s8atb +.section s8aua +.section s8aub +.section s8ava +.section s8avb +.section s8awa +.section s8awb +.section s8axa +.section s8axb +.section s8aya +.section s8ayb +.section s8aza +.section s8azb +.section s8a1a +.section s8a1b +.section s8a2a +.section s8a2b +.section s8a3a +.section s8a3b +.section s8a4a +.section s8a4b +.section s8a5a +.section s8a5b +.section s8a6a +.section s8a6b +.section s8a7a +.section s8a7b +.section s8a8a +.section s8a8b +.section s8a9a +.section s8a9b +.section s8a0a +.section s8a0b +.section s8baa +.section s8bab +.section s8bba +.section s8bbb +.section s8bca +.section s8bcb +.section s8bda +.section s8bdb +.section s8bea +.section s8beb +.section s8bfa +.section s8bfb +.section s8bga +.section s8bgb +.section s8bha +.section s8bhb +.section s8bia +.section s8bib +.section s8bja +.section s8bjb +.section s8bka +.section s8bkb +.section s8bla +.section s8blb +.section s8bma +.section s8bmb +.section s8bna +.section s8bnb +.section s8boa +.section s8bob +.section s8bpa +.section s8bpb +.section s8bqa +.section s8bqb +.section s8bra +.section s8brb +.section s8bsa +.section s8bsb +.section s8bta +.section s8btb +.section s8bua +.section s8bub +.section s8bva +.section s8bvb +.section s8bwa +.section s8bwb +.section s8bxa +.section s8bxb +.section s8bya +.section s8byb +.section s8bza +.section s8bzb +.section s8b1a +.section s8b1b +.section s8b2a +.section s8b2b +.section s8b3a +.section s8b3b +.section s8b4a +.section s8b4b +.section s8b5a +.section s8b5b +.section s8b6a +.section s8b6b +.section s8b7a +.section s8b7b +.section s8b8a +.section s8b8b +.section s8b9a +.section s8b9b +.section s8b0a +.section s8b0b +.section s8caa +.section s8cab +.section s8cba +.section s8cbb +.section s8cca +.section s8ccb +.section s8cda +.section s8cdb +.section s8cea +.section s8ceb +.section s8cfa +.section s8cfb +.section s8cga +.section s8cgb +.section s8cha +.section s8chb +.section s8cia +.section s8cib +.section s8cja +.section s8cjb +.section s8cka +.section s8ckb +.section s8cla +.section s8clb +.section s8cma +.section s8cmb +.section s8cna +.section s8cnb +.section s8coa +.section s8cob +.section s8cpa +.section s8cpb +.section s8cqa +.section s8cqb +.section s8cra +.section s8crb +.section s8csa +.section s8csb +.section s8cta +.section s8ctb +.section s8cua +.section s8cub +.section s8cva +.section s8cvb +.section s8cwa +.section s8cwb +.section s8cxa +.section s8cxb +.section s8cya +.section s8cyb +.section s8cza +.section s8czb +.section s8c1a +.section s8c1b +.section s8c2a +.section s8c2b +.section s8c3a +.section s8c3b +.section s8c4a +.section s8c4b +.section s8c5a +.section s8c5b +.section s8c6a +.section s8c6b +.section s8c7a +.section s8c7b +.section s8c8a +.section s8c8b +.section s8c9a +.section s8c9b +.section s8c0a +.section s8c0b +.section s8daa +.section s8dab +.section s8dba +.section s8dbb +.section s8dca +.section s8dcb +.section s8dda +.section s8ddb +.section s8dea +.section s8deb +.section s8dfa +.section s8dfb +.section s8dga +.section s8dgb +.section s8dha +.section s8dhb +.section s8dia +.section s8dib +.section s8dja +.section s8djb +.section s8dka +.section s8dkb +.section s8dla +.section s8dlb +.section s8dma +.section s8dmb +.section s8dna +.section s8dnb +.section s8doa +.section s8dob +.section s8dpa +.section s8dpb +.section s8dqa +.section s8dqb +.section s8dra +.section s8drb +.section s8dsa +.section s8dsb +.section s8dta +.section s8dtb +.section s8dua +.section s8dub +.section s8dva +.section s8dvb +.section s8dwa +.section s8dwb +.section s8dxa +.section s8dxb +.section s8dya +.section s8dyb +.section s8dza +.section s8dzb +.section s8d1a +.section s8d1b +.section s8d2a +.section s8d2b +.section s8d3a +.section s8d3b +.section s8d4a +.section s8d4b +.section s8d5a +.section s8d5b +.section s8d6a +.section s8d6b +.section s8d7a +.section s8d7b +.section s8d8a +.section s8d8b +.section s8d9a +.section s8d9b +.section s8d0a +.section s8d0b +.section s8eaa +.section s8eab +.section s8eba +.section s8ebb +.section s8eca +.section s8ecb +.section s8eda +.section s8edb +.section s8eea +.section s8eeb +.section s8efa +.section s8efb +.section s8ega +.section s8egb +.section s8eha +.section s8ehb +.section s8eia +.section s8eib +.section s8eja +.section s8ejb +.section s8eka +.section s8ekb +.section s8ela +.section s8elb +.section s8ema +.section s8emb +.section s8ena +.section s8enb +.section s8eoa +.section s8eob +.section s8epa +.section s8epb +.section s8eqa +.section s8eqb +.section s8era +.section s8erb +.section s8esa +.section s8esb +.section s8eta +.section s8etb +.section s8eua +.section s8eub +.section s8eva +.section s8evb +.section s8ewa +.section s8ewb +.section s8exa +.section s8exb +.section s8eya +.section s8eyb +.section s8eza +.section s8ezb +.section s8e1a +.section s8e1b +.section s8e2a +.section s8e2b +.section s8e3a +.section s8e3b +.section s8e4a +.section s8e4b +.section s8e5a +.section s8e5b +.section s8e6a +.section s8e6b +.section s8e7a +.section s8e7b +.section s8e8a +.section s8e8b +.section s8e9a +.section s8e9b +.section s8e0a +.section s8e0b +.section s8faa +.section s8fab +.section s8fba +.section s8fbb +.section s8fca +.section s8fcb +.section s8fda +.section s8fdb +.section s8fea +.section s8feb +.section s8ffa +.section s8ffb +.section s8fga +.section s8fgb +.section s8fha +.section s8fhb +.section s8fia +.section s8fib +.section s8fja +.section s8fjb +.section s8fka +.section s8fkb +.section s8fla +.section s8flb +.section s8fma +.section s8fmb +.section s8fna +.section s8fnb +.section s8foa +.section s8fob +.section s8fpa +.section s8fpb +.section s8fqa +.section s8fqb +.section s8fra +.section s8frb +.section s8fsa +.section s8fsb +.section s8fta +.section s8ftb +.section s8fua +.section s8fub +.section s8fva +.section s8fvb +.section s8fwa +.section s8fwb +.section s8fxa +.section s8fxb +.section s8fya +.section s8fyb +.section s8fza +.section s8fzb +.section s8f1a +.section s8f1b +.section s8f2a +.section s8f2b +.section s8f3a +.section s8f3b +.section s8f4a +.section s8f4b +.section s8f5a +.section s8f5b +.section s8f6a +.section s8f6b +.section s8f7a +.section s8f7b +.section s8f8a +.section s8f8b +.section s8f9a +.section s8f9b +.section s8f0a +.section s8f0b +.section s8gaa +.section s8gab +.section s8gba +.section s8gbb +.section s8gca +.section s8gcb +.section s8gda +.section s8gdb +.section s8gea +.section s8geb +.section s8gfa +.section s8gfb +.section s8gga +.section s8ggb +.section s8gha +.section s8ghb +.section s8gia +.section s8gib +.section s8gja +.section s8gjb +.section s8gka +.section s8gkb +.section s8gla +.section s8glb +.section s8gma +.section s8gmb +.section s8gna +.section s8gnb +.section s8goa +.section s8gob +.section s8gpa +.section s8gpb +.section s8gqa +.section s8gqb +.section s8gra +.section s8grb +.section s8gsa +.section s8gsb +.section s8gta +.section s8gtb +.section s8gua +.section s8gub +.section s8gva +.section s8gvb +.section s8gwa +.section s8gwb +.section s8gxa +.section s8gxb +.section s8gya +.section s8gyb +.section s8gza +.section s8gzb +.section s8g1a +.section s8g1b +.section s8g2a +.section s8g2b +.section s8g3a +.section s8g3b +.section s8g4a +.section s8g4b +.section s8g5a +.section s8g5b +.section s8g6a +.section s8g6b +.section s8g7a +.section s8g7b +.section s8g8a +.section s8g8b +.section s8g9a +.section s8g9b +.section s8g0a +.section s8g0b +.section s8haa +.section s8hab +.section s8hba +.section s8hbb +.section s8hca +.section s8hcb +.section s8hda +.section s8hdb +.section s8hea +.section s8heb +.section s8hfa +.section s8hfb +.section s8hga +.section s8hgb +.section s8hha +.section s8hhb +.section s8hia +.section s8hib +.section s8hja +.section s8hjb +.section s8hka +.section s8hkb +.section s8hla +.section s8hlb +.section s8hma +.section s8hmb +.section s8hna +.section s8hnb +.section s8hoa +.section s8hob +.section s8hpa +.section s8hpb +.section s8hqa +.section s8hqb +.section s8hra +.section s8hrb +.section s8hsa +.section s8hsb +.section s8hta +.section s8htb +.section s8hua +.section s8hub +.section s8hva +.section s8hvb +.section s8hwa +.section s8hwb +.section s8hxa +.section s8hxb +.section s8hya +.section s8hyb +.section s8hza +.section s8hzb +.section s8h1a +.section s8h1b +.section s8h2a +.section s8h2b +.section s8h3a +.section s8h3b +.section s8h4a +.section s8h4b +.section s8h5a +.section s8h5b +.section s8h6a +.section s8h6b +.section s8h7a +.section s8h7b +.section s8h8a +.section s8h8b +.section s8h9a +.section s8h9b +.section s8h0a +.section s8h0b +.section s8iaa +.section s8iab +.section s8iba +.section s8ibb +.section s8ica +.section s8icb +.section s8ida +.section s8idb +.section s8iea +.section s8ieb +.section s8ifa +.section s8ifb +.section s8iga +.section s8igb +.section s8iha +.section s8ihb +.section s8iia +.section s8iib +.section s8ija +.section s8ijb +.section s8ika +.section s8ikb +.section s8ila +.section s8ilb +.section s8ima +.section s8imb +.section s8ina +.section s8inb +.section s8ioa +.section s8iob +.section s8ipa +.section s8ipb +.section s8iqa +.section s8iqb +.section s8ira +.section s8irb +.section s8isa +.section s8isb +.section s8ita +.section s8itb +.section s8iua +.section s8iub +.section s8iva +.section s8ivb +.section s8iwa +.section s8iwb +.section s8ixa +.section s8ixb +.section s8iya +.section s8iyb +.section s8iza +.section s8izb +.section s8i1a +.section s8i1b +.section s8i2a +.section s8i2b +.section s8i3a +.section s8i3b +.section s8i4a +.section s8i4b +.section s8i5a +.section s8i5b +.section s8i6a +.section s8i6b +.section s8i7a +.section s8i7b +.section s8i8a +.section s8i8b +.section s8i9a +.section s8i9b +.section s8i0a +.section s8i0b +.section s8jaa +.section s8jab +.section s8jba +.section s8jbb +.section s8jca +.section s8jcb +.section s8jda +.section s8jdb +.section s8jea +.section s8jeb +.section s8jfa +.section s8jfb +.section s8jga +.section s8jgb +.section s8jha +.section s8jhb +.section s8jia +.section s8jib +.section s8jja +.section s8jjb +.section s8jka +.section s8jkb +.section s8jla +.section s8jlb +.section s8jma +.section s8jmb +.section s8jna +.section s8jnb +.section s8joa +.section s8job +.section s8jpa +.section s8jpb +.section s8jqa +.section s8jqb +.section s8jra +.section s8jrb +.section s8jsa +.section s8jsb +.section s8jta +.section s8jtb +.section s8jua +.section s8jub +.section s8jva +.section s8jvb +.section s8jwa +.section s8jwb +.section s8jxa +.section s8jxb +.section s8jya +.section s8jyb +.section s8jza +.section s8jzb +.section s8j1a +.section s8j1b +.section s8j2a +.section s8j2b +.section s8j3a +.section s8j3b +.section s8j4a +.section s8j4b +.section s8j5a +.section s8j5b +.section s8j6a +.section s8j6b +.section s8j7a +.section s8j7b +.section s8j8a +.section s8j8b +.section s8j9a +.section s8j9b +.section s8j0a +.section s8j0b +.section s8kaa +.section s8kab +.section s8kba +.section s8kbb +.section s8kca +.section s8kcb +.section s8kda +.section s8kdb +.section s8kea +.section s8keb +.section s8kfa +.section s8kfb +.section s8kga +.section s8kgb +.section s8kha +.section s8khb +.section s8kia +.section s8kib +.section s8kja +.section s8kjb +.section s8kka +.section s8kkb +.section s8kla +.section s8klb +.section s8kma +.section s8kmb +.section s8kna +.section s8knb +.section s8koa +.section s8kob +.section s8kpa +.section s8kpb +.section s8kqa +.section s8kqb +.section s8kra +.section s8krb +.section s8ksa +.section s8ksb +.section s8kta +.section s8ktb +.section s8kua +.section s8kub +.section s8kva +.section s8kvb +.section s8kwa +.section s8kwb +.section s8kxa +.section s8kxb +.section s8kya +.section s8kyb +.section s8kza +.section s8kzb +.section s8k1a +.section s8k1b +.section s8k2a +.section s8k2b +.section s8k3a +.section s8k3b +.section s8k4a +.section s8k4b +.section s8k5a +.section s8k5b +.section s8k6a +.section s8k6b +.section s8k7a +.section s8k7b +.section s8k8a +.section s8k8b +.section s8k9a +.section s8k9b +.section s8k0a +.section s8k0b +.section s8laa +.section s8lab +.section s8lba +.section s8lbb +.section s8lca +.section s8lcb +.section s8lda +.section s8ldb +.section s8lea +.section s8leb +.section s8lfa +.section s8lfb +.section s8lga +.section s8lgb +.section s8lha +.section s8lhb +.section s8lia +.section s8lib +.section s8lja +.section s8ljb +.section s8lka +.section s8lkb +.section s8lla +.section s8llb +.section s8lma +.section s8lmb +.section s8lna +.section s8lnb +.section s8loa +.section s8lob +.section s8lpa +.section s8lpb +.section s8lqa +.section s8lqb +.section s8lra +.section s8lrb +.section s8lsa +.section s8lsb +.section s8lta +.section s8ltb +.section s8lua +.section s8lub +.section s8lva +.section s8lvb +.section s8lwa +.section s8lwb +.section s8lxa +.section s8lxb +.section s8lya +.section s8lyb +.section s8lza +.section s8lzb +.section s8l1a +.section s8l1b +.section s8l2a +.section s8l2b +.section s8l3a +.section s8l3b +.section s8l4a +.section s8l4b +.section s8l5a +.section s8l5b +.section s8l6a +.section s8l6b +.section s8l7a +.section s8l7b +.section s8l8a +.section s8l8b +.section s8l9a +.section s8l9b +.section s8l0a +.section s8l0b +.section s8maa +.section s8mab +.section s8mba +.section s8mbb +.section s8mca +.section s8mcb +.section s8mda +.section s8mdb +.section s8mea +.section s8meb +.section s8mfa +.section s8mfb +.section s8mga +.section s8mgb +.section s8mha +.section s8mhb +.section s8mia +.section s8mib +.section s8mja +.section s8mjb +.section s8mka +.section s8mkb +.section s8mla +.section s8mlb +.section s8mma +.section s8mmb +.section s8mna +.section s8mnb +.section s8moa +.section s8mob +.section s8mpa +.section s8mpb +.section s8mqa +.section s8mqb +.section s8mra +.section s8mrb +.section s8msa +.section s8msb +.section s8mta +.section s8mtb +.section s8mua +.section s8mub +.section s8mva +.section s8mvb +.section s8mwa +.section s8mwb +.section s8mxa +.section s8mxb +.section s8mya +.section s8myb +.section s8mza +.section s8mzb +.section s8m1a +.section s8m1b +.section s8m2a +.section s8m2b +.section s8m3a +.section s8m3b +.section s8m4a +.section s8m4b +.section s8m5a +.section s8m5b +.section s8m6a +.section s8m6b +.section s8m7a +.section s8m7b +.section s8m8a +.section s8m8b +.section s8m9a +.section s8m9b +.section s8m0a +.section s8m0b +.section s8naa +.section s8nab +.section s8nba +.section s8nbb +.section s8nca +.section s8ncb +.section s8nda +.section s8ndb +.section s8nea +.section s8neb +.section s8nfa +.section s8nfb +.section s8nga +.section s8ngb +.section s8nha +.section s8nhb +.section s8nia +.section s8nib +.section s8nja +.section s8njb +.section s8nka +.section s8nkb +.section s8nla +.section s8nlb +.section s8nma +.section s8nmb +.section s8nna +.section s8nnb +.section s8noa +.section s8nob +.section s8npa +.section s8npb +.section s8nqa +.section s8nqb +.section s8nra +.section s8nrb +.section s8nsa +.section s8nsb +.section s8nta +.section s8ntb +.section s8nua +.section s8nub +.section s8nva +.section s8nvb +.section s8nwa +.section s8nwb +.section s8nxa +.section s8nxb +.section s8nya +.section s8nyb +.section s8nza +.section s8nzb +.section s8n1a +.section s8n1b +.section s8n2a +.section s8n2b +.section s8n3a +.section s8n3b +.section s8n4a +.section s8n4b +.section s8n5a +.section s8n5b +.section s8n6a +.section s8n6b +.section s8n7a +.section s8n7b +.section s8n8a +.section s8n8b +.section s8n9a +.section s8n9b +.section s8n0a +.section s8n0b +.section s8oaa +.section s8oab +.section s8oba +.section s8obb +.section s8oca +.section s8ocb +.section s8oda +.section s8odb +.section s8oea +.section s8oeb +.section s8ofa +.section s8ofb +.section s8oga +.section s8ogb +.section s8oha +.section s8ohb +.section s8oia +.section s8oib +.section s8oja +.section s8ojb +.section s8oka +.section s8okb +.section s8ola +.section s8olb +.section s8oma +.section s8omb +.section s8ona +.section s8onb +.section s8ooa +.section s8oob +.section s8opa +.section s8opb +.section s8oqa +.section s8oqb +.section s8ora +.section s8orb +.section s8osa +.section s8osb +.section s8ota +.section s8otb +.section s8oua +.section s8oub +.section s8ova +.section s8ovb +.section s8owa +.section s8owb +.section s8oxa +.section s8oxb +.section s8oya +.section s8oyb +.section s8oza +.section s8ozb +.section s8o1a +.section s8o1b +.section s8o2a +.section s8o2b +.section s8o3a +.section s8o3b +.section s8o4a +.section s8o4b +.section s8o5a +.section s8o5b +.section s8o6a +.section s8o6b +.section s8o7a +.section s8o7b +.section s8o8a +.section s8o8b +.section s8o9a +.section s8o9b +.section s8o0a +.section s8o0b +.section s8paa +.section s8pab +.section s8pba +.section s8pbb +.section s8pca +.section s8pcb +.section s8pda +.section s8pdb +.section s8pea +.section s8peb +.section s8pfa +.section s8pfb +.section s8pga +.section s8pgb +.section s8pha +.section s8phb +.section s8pia +.section s8pib +.section s8pja +.section s8pjb +.section s8pka +.section s8pkb +.section s8pla +.section s8plb +.section s8pma +.section s8pmb +.section s8pna +.section s8pnb +.section s8poa +.section s8pob +.section s8ppa +.section s8ppb +.section s8pqa +.section s8pqb +.section s8pra +.section s8prb +.section s8psa +.section s8psb +.section s8pta +.section s8ptb +.section s8pua +.section s8pub +.section s8pva +.section s8pvb +.section s8pwa +.section s8pwb +.section s8pxa +.section s8pxb +.section s8pya +.section s8pyb +.section s8pza +.section s8pzb +.section s8p1a +.section s8p1b +.section s8p2a +.section s8p2b +.section s8p3a +.section s8p3b +.section s8p4a +.section s8p4b +.section s8p5a +.section s8p5b +.section s8p6a +.section s8p6b +.section s8p7a +.section s8p7b +.section s8p8a +.section s8p8b +.section s8p9a +.section s8p9b +.section s8p0a +.section s8p0b +.section s8qaa +.section s8qab +.section s8qba +.section s8qbb +.section s8qca +.section s8qcb +.section s8qda +.section s8qdb +.section s8qea +.section s8qeb +.section s8qfa +.section s8qfb +.section s8qga +.section s8qgb +.section s8qha +.section s8qhb +.section s8qia +.section s8qib +.section s8qja +.section s8qjb +.section s8qka +.section s8qkb +.section s8qla +.section s8qlb +.section s8qma +.section s8qmb +.section s8qna +.section s8qnb +.section s8qoa +.section s8qob +.section s8qpa +.section s8qpb +.section s8qqa +.section s8qqb +.section s8qra +.section s8qrb +.section s8qsa +.section s8qsb +.section s8qta +.section s8qtb +.section s8qua +.section s8qub +.section s8qva +.section s8qvb +.section s8qwa +.section s8qwb +.section s8qxa +.section s8qxb +.section s8qya +.section s8qyb +.section s8qza +.section s8qzb +.section s8q1a +.section s8q1b +.section s8q2a +.section s8q2b +.section s8q3a +.section s8q3b +.section s8q4a +.section s8q4b +.section s8q5a +.section s8q5b +.section s8q6a +.section s8q6b +.section s8q7a +.section s8q7b +.section s8q8a +.section s8q8b +.section s8q9a +.section s8q9b +.section s8q0a +.section s8q0b +.section s8raa +.section s8rab +.section s8rba +.section s8rbb +.section s8rca +.section s8rcb +.section s8rda +.section s8rdb +.section s8rea +.section s8reb +.section s8rfa +.section s8rfb +.section s8rga +.section s8rgb +.section s8rha +.section s8rhb +.section s8ria +.section s8rib +.section s8rja +.section s8rjb +.section s8rka +.section s8rkb +.section s8rla +.section s8rlb +.section s8rma +.section s8rmb +.section s8rna +.section s8rnb +.section s8roa +.section s8rob +.section s8rpa +.section s8rpb +.section s8rqa +.section s8rqb +.section s8rra +.section s8rrb +.section s8rsa +.section s8rsb +.section s8rta +.section s8rtb +.section s8rua +.section s8rub +.section s8rva +.section s8rvb +.section s8rwa +.section s8rwb +.section s8rxa +.section s8rxb +.section s8rya +.section s8ryb +.section s8rza +.section s8rzb +.section s8r1a +.section s8r1b +.section s8r2a +.section s8r2b +.section s8r3a +.section s8r3b +.section s8r4a +.section s8r4b +.section s8r5a +.section s8r5b +.section s8r6a +.section s8r6b +.section s8r7a +.section s8r7b +.section s8r8a +.section s8r8b +.section s8r9a +.section s8r9b +.section s8r0a +.section s8r0b +.section s8saa +.section s8sab +.section s8sba +.section s8sbb +.section s8sca +.section s8scb +.section s8sda +.section s8sdb +.section s8sea +.section s8seb +.section s8sfa +.section s8sfb +.section s8sga +.section s8sgb +.section s8sha +.section s8shb +.section s8sia +.section s8sib +.section s8sja +.section s8sjb +.section s8ska +.section s8skb +.section s8sla +.section s8slb +.section s8sma +.section s8smb +.section s8sna +.section s8snb +.section s8soa +.section s8sob +.section s8spa +.section s8spb +.section s8sqa +.section s8sqb +.section s8sra +.section s8srb +.section s8ssa +.section s8ssb +.section s8sta +.section s8stb +.section s8sua +.section s8sub +.section s8sva +.section s8svb +.section s8swa +.section s8swb +.section s8sxa +.section s8sxb +.section s8sya +.section s8syb +.section s8sza +.section s8szb +.section s8s1a +.section s8s1b +.section s8s2a +.section s8s2b +.section s8s3a +.section s8s3b +.section s8s4a +.section s8s4b +.section s8s5a +.section s8s5b +.section s8s6a +.section s8s6b +.section s8s7a +.section s8s7b +.section s8s8a +.section s8s8b +.section s8s9a +.section s8s9b +.section s8s0a +.section s8s0b +.section s8taa +.section s8tab +.section s8tba +.section s8tbb +.section s8tca +.section s8tcb +.section s8tda +.section s8tdb +.section s8tea +.section s8teb +.section s8tfa +.section s8tfb +.section s8tga +.section s8tgb +.section s8tha +.section s8thb +.section s8tia +.section s8tib +.section s8tja +.section s8tjb +.section s8tka +.section s8tkb +.section s8tla +.section s8tlb +.section s8tma +.section s8tmb +.section s8tna +.section s8tnb +.section s8toa +.section s8tob +.section s8tpa +.section s8tpb +.section s8tqa +.section s8tqb +.section s8tra +.section s8trb +.section s8tsa +.section s8tsb +.section s8tta +.section s8ttb +.section s8tua +.section s8tub +.section s8tva +.section s8tvb +.section s8twa +.section s8twb +.section s8txa +.section s8txb +.section s8tya +.section s8tyb +.section s8tza +.section s8tzb +.section s8t1a +.section s8t1b +.section s8t2a +.section s8t2b +.section s8t3a +.section s8t3b +.section s8t4a +.section s8t4b +.section s8t5a +.section s8t5b +.section s8t6a +.section s8t6b +.section s8t7a +.section s8t7b +.section s8t8a +.section s8t8b +.section s8t9a +.section s8t9b +.section s8t0a +.section s8t0b +.section s8uaa +.section s8uab +.section s8uba +.section s8ubb +.section s8uca +.section s8ucb +.section s8uda +.section s8udb +.section s8uea +.section s8ueb +.section s8ufa +.section s8ufb +.section s8uga +.section s8ugb +.section s8uha +.section s8uhb +.section s8uia +.section s8uib +.section s8uja +.section s8ujb +.section s8uka +.section s8ukb +.section s8ula +.section s8ulb +.section s8uma +.section s8umb +.section s8una +.section s8unb +.section s8uoa +.section s8uob +.section s8upa +.section s8upb +.section s8uqa +.section s8uqb +.section s8ura +.section s8urb +.section s8usa +.section s8usb +.section s8uta +.section s8utb +.section s8uua +.section s8uub +.section s8uva +.section s8uvb +.section s8uwa +.section s8uwb +.section s8uxa +.section s8uxb +.section s8uya +.section s8uyb +.section s8uza +.section s8uzb +.section s8u1a +.section s8u1b +.section s8u2a +.section s8u2b +.section s8u3a +.section s8u3b +.section s8u4a +.section s8u4b +.section s8u5a +.section s8u5b +.section s8u6a +.section s8u6b +.section s8u7a +.section s8u7b +.section s8u8a +.section s8u8b +.section s8u9a +.section s8u9b +.section s8u0a +.section s8u0b +.section s8vaa +.section s8vab +.section s8vba +.section s8vbb +.section s8vca +.section s8vcb +.section s8vda +.section s8vdb +.section s8vea +.section s8veb +.section s8vfa +.section s8vfb +.section s8vga +.section s8vgb +.section s8vha +.section s8vhb +.section s8via +.section s8vib +.section s8vja +.section s8vjb +.section s8vka +.section s8vkb +.section s8vla +.section s8vlb +.section s8vma +.section s8vmb +.section s8vna +.section s8vnb +.section s8voa +.section s8vob +.section s8vpa +.section s8vpb +.section s8vqa +.section s8vqb +.section s8vra +.section s8vrb +.section s8vsa +.section s8vsb +.section s8vta +.section s8vtb +.section s8vua +.section s8vub +.section s8vva +.section s8vvb +.section s8vwa +.section s8vwb +.section s8vxa +.section s8vxb +.section s8vya +.section s8vyb +.section s8vza +.section s8vzb +.section s8v1a +.section s8v1b +.section s8v2a +.section s8v2b +.section s8v3a +.section s8v3b +.section s8v4a +.section s8v4b +.section s8v5a +.section s8v5b +.section s8v6a +.section s8v6b +.section s8v7a +.section s8v7b +.section s8v8a +.section s8v8b +.section s8v9a +.section s8v9b +.section s8v0a +.section s8v0b +.section s8waa +.section s8wab +.section s8wba +.section s8wbb +.section s8wca +.section s8wcb +.section s8wda +.section s8wdb +.section s8wea +.section s8web +.section s8wfa +.section s8wfb +.section s8wga +.section s8wgb +.section s8wha +.section s8whb +.section s8wia +.section s8wib +.section s8wja +.section s8wjb +.section s8wka +.section s8wkb +.section s8wla +.section s8wlb +.section s8wma +.section s8wmb +.section s8wna +.section s8wnb +.section s8woa +.section s8wob +.section s8wpa +.section s8wpb +.section s8wqa +.section s8wqb +.section s8wra +.section s8wrb +.section s8wsa +.section s8wsb +.section s8wta +.section s8wtb +.section s8wua +.section s8wub +.section s8wva +.section s8wvb +.section s8wwa +.section s8wwb +.section s8wxa +.section s8wxb +.section s8wya +.section s8wyb +.section s8wza +.section s8wzb +.section s8w1a +.section s8w1b +.section s8w2a +.section s8w2b +.section s8w3a +.section s8w3b +.section s8w4a +.section s8w4b +.section s8w5a +.section s8w5b +.section s8w6a +.section s8w6b +.section s8w7a +.section s8w7b +.section s8w8a +.section s8w8b +.section s8w9a +.section s8w9b +.section s8w0a +.section s8w0b +.section s8xaa +.section s8xab +.section s8xba +.section s8xbb +.section s8xca +.section s8xcb +.section s8xda +.section s8xdb +.section s8xea +.section s8xeb +.section s8xfa +.section s8xfb +.section s8xga +.section s8xgb +.section s8xha +.section s8xhb +.section s8xia +.section s8xib +.section s8xja +.section s8xjb +.section s8xka +.section s8xkb +.section s8xla +.section s8xlb +.section s8xma +.section s8xmb +.section s8xna +.section s8xnb +.section s8xoa +.section s8xob +.section s8xpa +.section s8xpb +.section s8xqa +.section s8xqb +.section s8xra +.section s8xrb +.section s8xsa +.section s8xsb +.section s8xta +.section s8xtb +.section s8xua +.section s8xub +.section s8xva +.section s8xvb +.section s8xwa +.section s8xwb +.section s8xxa +.section s8xxb +.section s8xya +.section s8xyb +.section s8xza +.section s8xzb +.section s8x1a +.section s8x1b +.section s8x2a +.section s8x2b +.section s8x3a +.section s8x3b +.section s8x4a +.section s8x4b +.section s8x5a +.section s8x5b +.section s8x6a +.section s8x6b +.section s8x7a +.section s8x7b +.section s8x8a +.section s8x8b +.section s8x9a +.section s8x9b +.section s8x0a +.section s8x0b +.section s8yaa +.section s8yab +.section s8yba +.section s8ybb +.section s8yca +.section s8ycb +.section s8yda +.section s8ydb +.section s8yea +.section s8yeb +.section s8yfa +.section s8yfb +.section s8yga +.section s8ygb +.section s8yha +.section s8yhb +.section s8yia +.section s8yib +.section s8yja +.section s8yjb +.section s8yka +.section s8ykb +.section s8yla +.section s8ylb +.section s8yma +.section s8ymb +.section s8yna +.section s8ynb +.section s8yoa +.section s8yob +.section s8ypa +.section s8ypb +.section s8yqa +.section s8yqb +.section s8yra +.section s8yrb +.section s8ysa +.section s8ysb +.section s8yta +.section s8ytb +.section s8yua +.section s8yub +.section s8yva +.section s8yvb +.section s8ywa +.section s8ywb +.section s8yxa +.section s8yxb +.section s8yya +.section s8yyb +.section s8yza +.section s8yzb +.section s8y1a +.section s8y1b +.section s8y2a +.section s8y2b +.section s8y3a +.section s8y3b +.section s8y4a +.section s8y4b +.section s8y5a +.section s8y5b +.section s8y6a +.section s8y6b +.section s8y7a +.section s8y7b +.section s8y8a +.section s8y8b +.section s8y9a +.section s8y9b +.section s8y0a +.section s8y0b +.section s8zaa +.section s8zab +.section s8zba +.section s8zbb +.section s8zca +.section s8zcb +.section s8zda +.section s8zdb +.section s8zea +.section s8zeb +.section s8zfa +.section s8zfb +.section s8zga +.section s8zgb +.section s8zha +.section s8zhb +.section s8zia +.section s8zib +.section s8zja +.section s8zjb +.section s8zka +.section s8zkb +.section s8zla +.section s8zlb +.section s8zma +.section s8zmb +.section s8zna +.section s8znb +.section s8zoa +.section s8zob +.section s8zpa +.section s8zpb +.section s8zqa +.section s8zqb +.section s8zra +.section s8zrb +.section s8zsa +.section s8zsb +.section s8zta +.section s8ztb +.section s8zua +.section s8zub +.section s8zva +.section s8zvb +.section s8zwa +.section s8zwb +.section s8zxa +.section s8zxb +.section s8zya +.section s8zyb +.section s8zza +.section s8zzb +.section s8z1a +.section s8z1b +.section s8z2a +.section s8z2b +.section s8z3a +.section s8z3b +.section s8z4a +.section s8z4b +.section s8z5a +.section s8z5b +.section s8z6a +.section s8z6b +.section s8z7a +.section s8z7b +.section s8z8a +.section s8z8b +.section s8z9a +.section s8z9b +.section s8z0a +.section s8z0b +.section s81aa +.section s81ab +.section s81ba +.section s81bb +.section s81ca +.section s81cb +.section s81da +.section s81db +.section s81ea +.section s81eb +.section s81fa +.section s81fb +.section s81ga +.section s81gb +.section s81ha +.section s81hb +.section s81ia +.section s81ib +.section s81ja +.section s81jb +.section s81ka +.section s81kb +.section s81la +.section s81lb +.section s81ma +.section s81mb +.section s81na +.section s81nb +.section s81oa +.section s81ob +.section s81pa +.section s81pb +.section s81qa +.section s81qb +.section s81ra +.section s81rb +.section s81sa +.section s81sb +.section s81ta +.section s81tb +.section s81ua +.section s81ub +.section s81va +.section s81vb +.section s81wa +.section s81wb +.section s81xa +.section s81xb +.section s81ya +.section s81yb +.section s81za +.section s81zb +.section s811a +.section s811b +.section s812a +.section s812b +.section s813a +.section s813b +.section s814a +.section s814b +.section s815a +.section s815b +.section s816a +.section s816b +.section s817a +.section s817b +.section s818a +.section s818b +.section s819a +.section s819b +.section s810a +.section s810b +.section s82aa +.section s82ab +.section s82ba +.section s82bb +.section s82ca +.section s82cb +.section s82da +.section s82db +.section s82ea +.section s82eb +.section s82fa +.section s82fb +.section s82ga +.section s82gb +.section s82ha +.section s82hb +.section s82ia +.section s82ib +.section s82ja +.section s82jb +.section s82ka +.section s82kb +.section s82la +.section s82lb +.section s82ma +.section s82mb +.section s82na +.section s82nb +.section s82oa +.section s82ob +.section s82pa +.section s82pb +.section s82qa +.section s82qb +.section s82ra +.section s82rb +.section s82sa +.section s82sb +.section s82ta +.section s82tb +.section s82ua +.section s82ub +.section s82va +.section s82vb +.section s82wa +.section s82wb +.section s82xa +.section s82xb +.section s82ya +.section s82yb +.section s82za +.section s82zb +.section s821a +.section s821b +.section s822a +.section s822b +.section s823a +.section s823b +.section s824a +.section s824b +.section s825a +.section s825b +.section s826a +.section s826b +.section s827a +.section s827b +.section s828a +.section s828b +.section s829a +.section s829b +.section s820a +.section s820b +.section s83aa +.section s83ab +.section s83ba +.section s83bb +.section s83ca +.section s83cb +.section s83da +.section s83db +.section s83ea +.section s83eb +.section s83fa +.section s83fb +.section s83ga +.section s83gb +.section s83ha +.section s83hb +.section s83ia +.section s83ib +.section s83ja +.section s83jb +.section s83ka +.section s83kb +.section s83la +.section s83lb +.section s83ma +.section s83mb +.section s83na +.section s83nb +.section s83oa +.section s83ob +.section s83pa +.section s83pb +.section s83qa +.section s83qb +.section s83ra +.section s83rb +.section s83sa +.section s83sb +.section s83ta +.section s83tb +.section s83ua +.section s83ub +.section s83va +.section s83vb +.section s83wa +.section s83wb +.section s83xa +.section s83xb +.section s83ya +.section s83yb +.section s83za +.section s83zb +.section s831a +.section s831b +.section s832a +.section s832b +.section s833a +.section s833b +.section s834a +.section s834b +.section s835a +.section s835b +.section s836a +.section s836b +.section s837a +.section s837b +.section s838a +.section s838b +.section s839a +.section s839b +.section s830a +.section s830b +.section s84aa +.section s84ab +.section s84ba +.section s84bb +.section s84ca +.section s84cb +.section s84da +.section s84db +.section s84ea +.section s84eb +.section s84fa +.section s84fb +.section s84ga +.section s84gb +.section s84ha +.section s84hb +.section s84ia +.section s84ib +.section s84ja +.section s84jb +.section s84ka +.section s84kb +.section s84la +.section s84lb +.section s84ma +.section s84mb +.section s84na +.section s84nb +.section s84oa +.section s84ob +.section s84pa +.section s84pb +.section s84qa +.section s84qb +.section s84ra +.section s84rb +.section s84sa +.section s84sb +.section s84ta +.section s84tb +.section s84ua +.section s84ub +.section s84va +.section s84vb +.section s84wa +.section s84wb +.section s84xa +.section s84xb +.section s84ya +.section s84yb +.section s84za +.section s84zb +.section s841a +.section s841b +.section s842a +.section s842b +.section s843a +.section s843b +.section s844a +.section s844b +.section s845a +.section s845b +.section s846a +.section s846b +.section s847a +.section s847b +.section s848a +.section s848b +.section s849a +.section s849b +.section s840a +.section s840b +.section s85aa +.section s85ab +.section s85ba +.section s85bb +.section s85ca +.section s85cb +.section s85da +.section s85db +.section s85ea +.section s85eb +.section s85fa +.section s85fb +.section s85ga +.section s85gb +.section s85ha +.section s85hb +.section s85ia +.section s85ib +.section s85ja +.section s85jb +.section s85ka +.section s85kb +.section s85la +.section s85lb +.section s85ma +.section s85mb +.section s85na +.section s85nb +.section s85oa +.section s85ob +.section s85pa +.section s85pb +.section s85qa +.section s85qb +.section s85ra +.section s85rb +.section s85sa +.section s85sb +.section s85ta +.section s85tb +.section s85ua +.section s85ub +.section s85va +.section s85vb +.section s85wa +.section s85wb +.section s85xa +.section s85xb +.section s85ya +.section s85yb +.section s85za +.section s85zb +.section s851a +.section s851b +.section s852a +.section s852b +.section s853a +.section s853b +.section s854a +.section s854b +.section s855a +.section s855b +.section s856a +.section s856b +.section s857a +.section s857b +.section s858a +.section s858b +.section s859a +.section s859b +.section s850a +.section s850b +.section s86aa +.section s86ab +.section s86ba +.section s86bb +.section s86ca +.section s86cb +.section s86da +.section s86db +.section s86ea +.section s86eb +.section s86fa +.section s86fb +.section s86ga +.section s86gb +.section s86ha +.section s86hb +.section s86ia +.section s86ib +.section s86ja +.section s86jb +.section s86ka +.section s86kb +.section s86la +.section s86lb +.section s86ma +.section s86mb +.section s86na +.section s86nb +.section s86oa +.section s86ob +.section s86pa +.section s86pb +.section s86qa +.section s86qb +.section s86ra +.section s86rb +.section s86sa +.section s86sb +.section s86ta +.section s86tb +.section s86ua +.section s86ub +.section s86va +.section s86vb +.section s86wa +.section s86wb +.section s86xa +.section s86xb +.section s86ya +.section s86yb +.section s86za +.section s86zb +.section s861a +.section s861b +.section s862a +.section s862b +.section s863a +.section s863b +.section s864a +.section s864b +.section s865a +.section s865b +.section s866a +.section s866b +.section s867a +.section s867b +.section s868a +.section s868b +.section s869a +.section s869b +.section s860a +.section s860b +.section s87aa +.section s87ab +.section s87ba +.section s87bb +.section s87ca +.section s87cb +.section s87da +.section s87db +.section s87ea +.section s87eb +.section s87fa +.section s87fb +.section s87ga +.section s87gb +.section s87ha +.section s87hb +.section s87ia +.section s87ib +.section s87ja +.section s87jb +.section s87ka +.section s87kb +.section s87la +.section s87lb +.section s87ma +.section s87mb +.section s87na +.section s87nb +.section s87oa +.section s87ob +.section s87pa +.section s87pb +.section s87qa +.section s87qb +.section s87ra +.section s87rb +.section s87sa +.section s87sb +.section s87ta +.section s87tb +.section s87ua +.section s87ub +.section s87va +.section s87vb +.section s87wa +.section s87wb +.section s87xa +.section s87xb +.section s87ya +.section s87yb +.section s87za +.section s87zb +.section s871a +.section s871b +.section s872a +.section s872b +.section s873a +.section s873b +.section s874a +.section s874b +.section s875a +.section s875b +.section s876a +.section s876b +.section s877a +.section s877b +.section s878a +.section s878b +.section s879a +.section s879b +.section s870a +.section s870b +.section s88aa +.section s88ab +.section s88ba +.section s88bb +.section s88ca +.section s88cb +.section s88da +.section s88db +.section s88ea +.section s88eb +.section s88fa +.section s88fb +.section s88ga +.section s88gb +.section s88ha +.section s88hb +.section s88ia +.section s88ib +.section s88ja +.section s88jb +.section s88ka +.section s88kb +.section s88la +.section s88lb +.section s88ma +.section s88mb +.section s88na +.section s88nb +.section s88oa +.section s88ob +.section s88pa +.section s88pb +.section s88qa +.section s88qb +.section s88ra +.section s88rb +.section s88sa +.section s88sb +.section s88ta +.section s88tb +.section s88ua +.section s88ub +.section s88va +.section s88vb +.section s88wa +.section s88wb +.section s88xa +.section s88xb +.section s88ya +.section s88yb +.section s88za +.section s88zb +.section s881a +.section s881b +.section s882a +.section s882b +.section s883a +.section s883b +.section s884a +.section s884b +.section s885a +.section s885b +.section s886a +.section s886b +.section s887a +.section s887b +.section s888a +.section s888b +.section s889a +.section s889b +.section s880a +.section s880b +.section s89aa +.section s89ab +.section s89ba +.section s89bb +.section s89ca +.section s89cb +.section s89da +.section s89db +.section s89ea +.section s89eb +.section s89fa +.section s89fb +.section s89ga +.section s89gb +.section s89ha +.section s89hb +.section s89ia +.section s89ib +.section s89ja +.section s89jb +.section s89ka +.section s89kb +.section s89la +.section s89lb +.section s89ma +.section s89mb +.section s89na +.section s89nb +.section s89oa +.section s89ob +.section s89pa +.section s89pb +.section s89qa +.section s89qb +.section s89ra +.section s89rb +.section s89sa +.section s89sb +.section s89ta +.section s89tb +.section s89ua +.section s89ub +.section s89va +.section s89vb +.section s89wa +.section s89wb +.section s89xa +.section s89xb +.section s89ya +.section s89yb +.section s89za +.section s89zb +.section s891a +.section s891b +.section s892a +.section s892b +.section s893a +.section s893b +.section s894a +.section s894b +.section s895a +.section s895b +.section s896a +.section s896b +.section s897a +.section s897b +.section s898a +.section s898b +.section s899a +.section s899b +.section s890a +.section s890b +.section s80aa +.section s80ab +.section s80ba +.section s80bb +.section s80ca +.section s80cb +.section s80da +.section s80db +.section s80ea +.section s80eb +.section s80fa +.section s80fb +.section s80ga +.section s80gb +.section s80ha +.section s80hb +.section s80ia +.section s80ib +.section s80ja +.section s80jb +.section s80ka +.section s80kb +.section s80la +.section s80lb +.section s80ma +.section s80mb +.section s80na +.section s80nb +.section s80oa +.section s80ob +.section s80pa +.section s80pb +.section s80qa +.section s80qb +.section s80ra +.section s80rb +.section s80sa +.section s80sb +.section s80ta +.section s80tb +.section s80ua +.section s80ub +.section s80va +.section s80vb +.section s80wa +.section s80wb +.section s80xa +.section s80xb +.section s80ya +.section s80yb +.section s80za +.section s80zb +.section s801a +.section s801b +.section s802a +.section s802b +.section s803a +.section s803b +.section s804a +.section s804b +.section s805a +.section s805b +.section s806a +.section s806b +.section s807a +.section s807b +.section s808a +.section s808b +.section s809a +.section s809b +.section s800a +.section s800b +.section s9aaa +.section s9aab +.section s9aba +.section s9abb +.section s9aca +.section s9acb +.section s9ada +.section s9adb +.section s9aea +.section s9aeb +.section s9afa +.section s9afb +.section s9aga +.section s9agb +.section s9aha +.section s9ahb +.section s9aia +.section s9aib +.section s9aja +.section s9ajb +.section s9aka +.section s9akb +.section s9ala +.section s9alb +.section s9ama +.section s9amb +.section s9ana +.section s9anb +.section s9aoa +.section s9aob +.section s9apa +.section s9apb +.section s9aqa +.section s9aqb +.section s9ara +.section s9arb +.section s9asa +.section s9asb +.section s9ata +.section s9atb +.section s9aua +.section s9aub +.section s9ava +.section s9avb +.section s9awa +.section s9awb +.section s9axa +.section s9axb +.section s9aya +.section s9ayb +.section s9aza +.section s9azb +.section s9a1a +.section s9a1b +.section s9a2a +.section s9a2b +.section s9a3a +.section s9a3b +.section s9a4a +.section s9a4b +.section s9a5a +.section s9a5b +.section s9a6a +.section s9a6b +.section s9a7a +.section s9a7b +.section s9a8a +.section s9a8b +.section s9a9a +.section s9a9b +.section s9a0a +.section s9a0b +.section s9baa +.section s9bab +.section s9bba +.section s9bbb +.section s9bca +.section s9bcb +.section s9bda +.section s9bdb +.section s9bea +.section s9beb +.section s9bfa +.section s9bfb +.section s9bga +.section s9bgb +.section s9bha +.section s9bhb +.section s9bia +.section s9bib +.section s9bja +.section s9bjb +.section s9bka +.section s9bkb +.section s9bla +.section s9blb +.section s9bma +.section s9bmb +.section s9bna +.section s9bnb +.section s9boa +.section s9bob +.section s9bpa +.section s9bpb +.section s9bqa +.section s9bqb +.section s9bra +.section s9brb +.section s9bsa +.section s9bsb +.section s9bta +.section s9btb +.section s9bua +.section s9bub +.section s9bva +.section s9bvb +.section s9bwa +.section s9bwb +.section s9bxa +.section s9bxb +.section s9bya +.section s9byb +.section s9bza +.section s9bzb +.section s9b1a +.section s9b1b +.section s9b2a +.section s9b2b +.section s9b3a +.section s9b3b +.section s9b4a +.section s9b4b +.section s9b5a +.section s9b5b +.section s9b6a +.section s9b6b +.section s9b7a +.section s9b7b +.section s9b8a +.section s9b8b +.section s9b9a +.section s9b9b +.section s9b0a +.section s9b0b +.section s9caa +.section s9cab +.section s9cba +.section s9cbb +.section s9cca +.section s9ccb +.section s9cda +.section s9cdb +.section s9cea +.section s9ceb +.section s9cfa +.section s9cfb +.section s9cga +.section s9cgb +.section s9cha +.section s9chb +.section s9cia +.section s9cib +.section s9cja +.section s9cjb +.section s9cka +.section s9ckb +.section s9cla +.section s9clb +.section s9cma +.section s9cmb +.section s9cna +.section s9cnb +.section s9coa +.section s9cob +.section s9cpa +.section s9cpb +.section s9cqa +.section s9cqb +.section s9cra +.section s9crb +.section s9csa +.section s9csb +.section s9cta +.section s9ctb +.section s9cua +.section s9cub +.section s9cva +.section s9cvb +.section s9cwa +.section s9cwb +.section s9cxa +.section s9cxb +.section s9cya +.section s9cyb +.section s9cza +.section s9czb +.section s9c1a +.section s9c1b +.section s9c2a +.section s9c2b +.section s9c3a +.section s9c3b +.section s9c4a +.section s9c4b +.section s9c5a +.section s9c5b +.section s9c6a +.section s9c6b +.section s9c7a +.section s9c7b +.section s9c8a +.section s9c8b +.section s9c9a +.section s9c9b +.section s9c0a +.section s9c0b +.section s9daa +.section s9dab +.section s9dba +.section s9dbb +.section s9dca +.section s9dcb +.section s9dda +.section s9ddb +.section s9dea +.section s9deb +.section s9dfa +.section s9dfb +.section s9dga +.section s9dgb +.section s9dha +.section s9dhb +.section s9dia +.section s9dib +.section s9dja +.section s9djb +.section s9dka +.section s9dkb +.section s9dla +.section s9dlb +.section s9dma +.section s9dmb +.section s9dna +.section s9dnb +.section s9doa +.section s9dob +.section s9dpa +.section s9dpb +.section s9dqa +.section s9dqb +.section s9dra +.section s9drb +.section s9dsa +.section s9dsb +.section s9dta +.section s9dtb +.section s9dua +.section s9dub +.section s9dva +.section s9dvb +.section s9dwa +.section s9dwb +.section s9dxa +.section s9dxb +.section s9dya +.section s9dyb +.section s9dza +.section s9dzb +.section s9d1a +.section s9d1b +.section s9d2a +.section s9d2b +.section s9d3a +.section s9d3b +.section s9d4a +.section s9d4b +.section s9d5a +.section s9d5b +.section s9d6a +.section s9d6b +.section s9d7a +.section s9d7b +.section s9d8a +.section s9d8b +.section s9d9a +.section s9d9b +.section s9d0a +.section s9d0b +.section s9eaa +.section s9eab +.section s9eba +.section s9ebb +.section s9eca +.section s9ecb +.section s9eda +.section s9edb +.section s9eea +.section s9eeb +.section s9efa +.section s9efb +.section s9ega +.section s9egb +.section s9eha +.section s9ehb +.section s9eia +.section s9eib +.section s9eja +.section s9ejb +.section s9eka +.section s9ekb +.section s9ela +.section s9elb +.section s9ema +.section s9emb +.section s9ena +.section s9enb +.section s9eoa +.section s9eob +.section s9epa +.section s9epb +.section s9eqa +.section s9eqb +.section s9era +.section s9erb +.section s9esa +.section s9esb +.section s9eta +.section s9etb +.section s9eua +.section s9eub +.section s9eva +.section s9evb +.section s9ewa +.section s9ewb +.section s9exa +.section s9exb +.section s9eya +.section s9eyb +.section s9eza +.section s9ezb +.section s9e1a +.section s9e1b +.section s9e2a +.section s9e2b +.section s9e3a +.section s9e3b +.section s9e4a +.section s9e4b +.section s9e5a +.section s9e5b +.section s9e6a +.section s9e6b +.section s9e7a +.section s9e7b +.section s9e8a +.section s9e8b +.section s9e9a +.section s9e9b +.section s9e0a +.section s9e0b +.section s9faa +.section s9fab +.section s9fba +.section s9fbb +.section s9fca +.section s9fcb +.section s9fda +.section s9fdb +.section s9fea +.section s9feb +.section s9ffa +.section s9ffb +.section s9fga +.section s9fgb +.section s9fha +.section s9fhb +.section s9fia +.section s9fib +.section s9fja +.section s9fjb +.section s9fka +.section s9fkb +.section s9fla +.section s9flb +.section s9fma +.section s9fmb +.section s9fna +.section s9fnb +.section s9foa +.section s9fob +.section s9fpa +.section s9fpb +.section s9fqa +.section s9fqb +.section s9fra +.section s9frb +.section s9fsa +.section s9fsb +.section s9fta +.section s9ftb +.section s9fua +.section s9fub +.section s9fva +.section s9fvb +.section s9fwa +.section s9fwb +.section s9fxa +.section s9fxb +.section s9fya +.section s9fyb +.section s9fza +.section s9fzb +.section s9f1a +.section s9f1b +.section s9f2a +.section s9f2b +.section s9f3a +.section s9f3b +.section s9f4a +.section s9f4b +.section s9f5a +.section s9f5b +.section s9f6a +.section s9f6b +.section s9f7a +.section s9f7b +.section s9f8a +.section s9f8b +.section s9f9a +.section s9f9b +.section s9f0a +.section s9f0b +.section s9gaa +.section s9gab +.section s9gba +.section s9gbb +.section s9gca +.section s9gcb +.section s9gda +.section s9gdb +.section s9gea +.section s9geb +.section s9gfa +.section s9gfb +.section s9gga +.section s9ggb +.section s9gha +.section s9ghb +.section s9gia +.section s9gib +.section s9gja +.section s9gjb +.section s9gka +.section s9gkb +.section s9gla +.section s9glb +.section s9gma +.section s9gmb +.section s9gna +.section s9gnb +.section s9goa +.section s9gob +.section s9gpa +.section s9gpb +.section s9gqa +.section s9gqb +.section s9gra +.section s9grb +.section s9gsa +.section s9gsb +.section s9gta +.section s9gtb +.section s9gua +.section s9gub +.section s9gva +.section s9gvb +.section s9gwa +.section s9gwb +.section s9gxa +.section s9gxb +.section s9gya +.section s9gyb +.section s9gza +.section s9gzb +.section s9g1a +.section s9g1b +.section s9g2a +.section s9g2b +.section s9g3a +.section s9g3b +.section s9g4a +.section s9g4b +.section s9g5a +.section s9g5b +.section s9g6a +.section s9g6b +.section s9g7a +.section s9g7b +.section s9g8a +.section s9g8b +.section s9g9a +.section s9g9b +.section s9g0a +.section s9g0b +.section s9haa +.section s9hab +.section s9hba +.section s9hbb +.section s9hca +.section s9hcb +.section s9hda +.section s9hdb +.section s9hea +.section s9heb +.section s9hfa +.section s9hfb +.section s9hga +.section s9hgb +.section s9hha +.section s9hhb +.section s9hia +.section s9hib +.section s9hja +.section s9hjb +.section s9hka +.section s9hkb +.section s9hla +.section s9hlb +.section s9hma +.section s9hmb +.section s9hna +.section s9hnb +.section s9hoa +.section s9hob +.section s9hpa +.section s9hpb +.section s9hqa +.section s9hqb +.section s9hra +.section s9hrb +.section s9hsa +.section s9hsb +.section s9hta +.section s9htb +.section s9hua +.section s9hub +.section s9hva +.section s9hvb +.section s9hwa +.section s9hwb +.section s9hxa +.section s9hxb +.section s9hya +.section s9hyb +.section s9hza +.section s9hzb +.section s9h1a +.section s9h1b +.section s9h2a +.section s9h2b +.section s9h3a +.section s9h3b +.section s9h4a +.section s9h4b +.section s9h5a +.section s9h5b +.section s9h6a +.section s9h6b +.section s9h7a +.section s9h7b +.section s9h8a +.section s9h8b +.section s9h9a +.section s9h9b +.section s9h0a +.section s9h0b +.section s9iaa +.section s9iab +.section s9iba +.section s9ibb +.section s9ica +.section s9icb +.section s9ida +.section s9idb +.section s9iea +.section s9ieb +.section s9ifa +.section s9ifb +.section s9iga +.section s9igb +.section s9iha +.section s9ihb +.section s9iia +.section s9iib +.section s9ija +.section s9ijb +.section s9ika +.section s9ikb +.section s9ila +.section s9ilb +.section s9ima +.section s9imb +.section s9ina +.section s9inb +.section s9ioa +.section s9iob +.section s9ipa +.section s9ipb +.section s9iqa +.section s9iqb +.section s9ira +.section s9irb +.section s9isa +.section s9isb +.section s9ita +.section s9itb +.section s9iua +.section s9iub +.section s9iva +.section s9ivb +.section s9iwa +.section s9iwb +.section s9ixa +.section s9ixb +.section s9iya +.section s9iyb +.section s9iza +.section s9izb +.section s9i1a +.section s9i1b +.section s9i2a +.section s9i2b +.section s9i3a +.section s9i3b +.section s9i4a +.section s9i4b +.section s9i5a +.section s9i5b +.section s9i6a +.section s9i6b +.section s9i7a +.section s9i7b +.section s9i8a +.section s9i8b +.section s9i9a +.section s9i9b +.section s9i0a +.section s9i0b +.section s9jaa +.section s9jab +.section s9jba +.section s9jbb +.section s9jca +.section s9jcb +.section s9jda +.section s9jdb +.section s9jea +.section s9jeb +.section s9jfa +.section s9jfb +.section s9jga +.section s9jgb +.section s9jha +.section s9jhb +.section s9jia +.section s9jib +.section s9jja +.section s9jjb +.section s9jka +.section s9jkb +.section s9jla +.section s9jlb +.section s9jma +.section s9jmb +.section s9jna +.section s9jnb +.section s9joa +.section s9job +.section s9jpa +.section s9jpb +.section s9jqa +.section s9jqb +.section s9jra +.section s9jrb +.section s9jsa +.section s9jsb +.section s9jta +.section s9jtb +.section s9jua +.section s9jub +.section s9jva +.section s9jvb +.section s9jwa +.section s9jwb +.section s9jxa +.section s9jxb +.section s9jya +.section s9jyb +.section s9jza +.section s9jzb +.section s9j1a +.section s9j1b +.section s9j2a +.section s9j2b +.section s9j3a +.section s9j3b +.section s9j4a +.section s9j4b +.section s9j5a +.section s9j5b +.section s9j6a +.section s9j6b +.section s9j7a +.section s9j7b +.section s9j8a +.section s9j8b +.section s9j9a +.section s9j9b +.section s9j0a +.section s9j0b +.section s9kaa +.section s9kab +.section s9kba +.section s9kbb +.section s9kca +.section s9kcb +.section s9kda +.section s9kdb +.section s9kea +.section s9keb +.section s9kfa +.section s9kfb +.section s9kga +.section s9kgb +.section s9kha +.section s9khb +.section s9kia +.section s9kib +.section s9kja +.section s9kjb +.section s9kka +.section s9kkb +.section s9kla +.section s9klb +.section s9kma +.section s9kmb +.section s9kna +.section s9knb +.section s9koa +.section s9kob +.section s9kpa +.section s9kpb +.section s9kqa +.section s9kqb +.section s9kra +.section s9krb +.section s9ksa +.section s9ksb +.section s9kta +.section s9ktb +.section s9kua +.section s9kub +.section s9kva +.section s9kvb +.section s9kwa +.section s9kwb +.section s9kxa +.section s9kxb +.section s9kya +.section s9kyb +.section s9kza +.section s9kzb +.section s9k1a +.section s9k1b +.section s9k2a +.section s9k2b +.section s9k3a +.section s9k3b +.section s9k4a +.section s9k4b +.section s9k5a +.section s9k5b +.section s9k6a +.section s9k6b +.section s9k7a +.section s9k7b +.section s9k8a +.section s9k8b +.section s9k9a +.section s9k9b +.section s9k0a +.section s9k0b +.section s9laa +.section s9lab +.section s9lba +.section s9lbb +.section s9lca +.section s9lcb +.section s9lda +.section s9ldb +.section s9lea +.section s9leb +.section s9lfa +.section s9lfb +.section s9lga +.section s9lgb +.section s9lha +.section s9lhb +.section s9lia +.section s9lib +.section s9lja +.section s9ljb +.section s9lka +.section s9lkb +.section s9lla +.section s9llb +.section s9lma +.section s9lmb +.section s9lna +.section s9lnb +.section s9loa +.section s9lob +.section s9lpa +.section s9lpb +.section s9lqa +.section s9lqb +.section s9lra +.section s9lrb +.section s9lsa +.section s9lsb +.section s9lta +.section s9ltb +.section s9lua +.section s9lub +.section s9lva +.section s9lvb +.section s9lwa +.section s9lwb +.section s9lxa +.section s9lxb +.section s9lya +.section s9lyb +.section s9lza +.section s9lzb +.section s9l1a +.section s9l1b +.section s9l2a +.section s9l2b +.section s9l3a +.section s9l3b +.section s9l4a +.section s9l4b +.section s9l5a +.section s9l5b +.section s9l6a +.section s9l6b +.section s9l7a +.section s9l7b +.section s9l8a +.section s9l8b +.section s9l9a +.section s9l9b +.section s9l0a +.section s9l0b +.section s9maa +.section s9mab +.section s9mba +.section s9mbb +.section s9mca +.section s9mcb +.section s9mda +.section s9mdb +.section s9mea +.section s9meb +.section s9mfa +.section s9mfb +.section s9mga +.section s9mgb +.section s9mha +.section s9mhb +.section s9mia +.section s9mib +.section s9mja +.section s9mjb +.section s9mka +.section s9mkb +.section s9mla +.section s9mlb +.section s9mma +.section s9mmb +.section s9mna +.section s9mnb +.section s9moa +.section s9mob +.section s9mpa +.section s9mpb +.section s9mqa +.section s9mqb +.section s9mra +.section s9mrb +.section s9msa +.section s9msb +.section s9mta +.section s9mtb +.section s9mua +.section s9mub +.section s9mva +.section s9mvb +.section s9mwa +.section s9mwb +.section s9mxa +.section s9mxb +.section s9mya +.section s9myb +.section s9mza +.section s9mzb +.section s9m1a +.section s9m1b +.section s9m2a +.section s9m2b +.section s9m3a +.section s9m3b +.section s9m4a +.section s9m4b +.section s9m5a +.section s9m5b +.section s9m6a +.section s9m6b +.section s9m7a +.section s9m7b +.section s9m8a +.section s9m8b +.section s9m9a +.section s9m9b +.section s9m0a +.section s9m0b +.section s9naa +.section s9nab +.section s9nba +.section s9nbb +.section s9nca +.section s9ncb +.section s9nda +.section s9ndb +.section s9nea +.section s9neb +.section s9nfa +.section s9nfb +.section s9nga +.section s9ngb +.section s9nha +.section s9nhb +.section s9nia +.section s9nib +.section s9nja +.section s9njb +.section s9nka +.section s9nkb +.section s9nla +.section s9nlb +.section s9nma +.section s9nmb +.section s9nna +.section s9nnb +.section s9noa +.section s9nob +.section s9npa +.section s9npb +.section s9nqa +.section s9nqb +.section s9nra +.section s9nrb +.section s9nsa +.section s9nsb +.section s9nta +.section s9ntb +.section s9nua +.section s9nub +.section s9nva +.section s9nvb +.section s9nwa +.section s9nwb +.section s9nxa +.section s9nxb +.section s9nya +.section s9nyb +.section s9nza +.section s9nzb +.section s9n1a +.section s9n1b +.section s9n2a +.section s9n2b +.section s9n3a +.section s9n3b +.section s9n4a +.section s9n4b +.section s9n5a +.section s9n5b +.section s9n6a +.section s9n6b +.section s9n7a +.section s9n7b +.section s9n8a +.section s9n8b +.section s9n9a +.section s9n9b +.section s9n0a +.section s9n0b +.section s9oaa +.section s9oab +.section s9oba +.section s9obb +.section s9oca +.section s9ocb +.section s9oda +.section s9odb +.section s9oea +.section s9oeb +.section s9ofa +.section s9ofb +.section s9oga +.section s9ogb +.section s9oha +.section s9ohb +.section s9oia +.section s9oib +.section s9oja +.section s9ojb +.section s9oka +.section s9okb +.section s9ola +.section s9olb +.section s9oma +.section s9omb +.section s9ona +.section s9onb +.section s9ooa +.section s9oob +.section s9opa +.section s9opb +.section s9oqa +.section s9oqb +.section s9ora +.section s9orb +.section s9osa +.section s9osb +.section s9ota +.section s9otb +.section s9oua +.section s9oub +.section s9ova +.section s9ovb +.section s9owa +.section s9owb +.section s9oxa +.section s9oxb +.section s9oya +.section s9oyb +.section s9oza +.section s9ozb +.section s9o1a +.section s9o1b +.section s9o2a +.section s9o2b +.section s9o3a +.section s9o3b +.section s9o4a +.section s9o4b +.section s9o5a +.section s9o5b +.section s9o6a +.section s9o6b +.section s9o7a +.section s9o7b +.section s9o8a +.section s9o8b +.section s9o9a +.section s9o9b +.section s9o0a +.section s9o0b +.section s9paa +.section s9pab +.section s9pba +.section s9pbb +.section s9pca +.section s9pcb +.section s9pda +.section s9pdb +.section s9pea +.section s9peb +.section s9pfa +.section s9pfb +.section s9pga +.section s9pgb +.section s9pha +.section s9phb +.section s9pia +.section s9pib +.section s9pja +.section s9pjb +.section s9pka +.section s9pkb +.section s9pla +.section s9plb +.section s9pma +.section s9pmb +.section s9pna +.section s9pnb +.section s9poa +.section s9pob +.section s9ppa +.section s9ppb +.section s9pqa +.section s9pqb +.section s9pra +.section s9prb +.section s9psa +.section s9psb +.section s9pta +.section s9ptb +.section s9pua +.section s9pub +.section s9pva +.section s9pvb +.section s9pwa +.section s9pwb +.section s9pxa +.section s9pxb +.section s9pya +.section s9pyb +.section s9pza +.section s9pzb +.section s9p1a +.section s9p1b +.section s9p2a +.section s9p2b +.section s9p3a +.section s9p3b +.section s9p4a +.section s9p4b +.section s9p5a +.section s9p5b +.section s9p6a +.section s9p6b +.section s9p7a +.section s9p7b +.section s9p8a +.section s9p8b +.section s9p9a +.section s9p9b +.section s9p0a +.section s9p0b +.section s9qaa +.section s9qab +.section s9qba +.section s9qbb +.section s9qca +.section s9qcb +.section s9qda +.section s9qdb +.section s9qea +.section s9qeb +.section s9qfa +.section s9qfb +.section s9qga +.section s9qgb +.section s9qha +.section s9qhb +.section s9qia +.section s9qib +.section s9qja +.section s9qjb +.section s9qka +.section s9qkb +.section s9qla +.section s9qlb +.section s9qma +.section s9qmb +.section s9qna +.section s9qnb +.section s9qoa +.section s9qob +.section s9qpa +.section s9qpb +.section s9qqa +.section s9qqb +.section s9qra +.section s9qrb +.section s9qsa +.section s9qsb +.section s9qta +.section s9qtb +.section s9qua +.section s9qub +.section s9qva +.section s9qvb +.section s9qwa +.section s9qwb +.section s9qxa +.section s9qxb +.section s9qya +.section s9qyb +.section s9qza +.section s9qzb +.section s9q1a +.section s9q1b +.section s9q2a +.section s9q2b +.section s9q3a +.section s9q3b +.section s9q4a +.section s9q4b +.section s9q5a +.section s9q5b +.section s9q6a +.section s9q6b +.section s9q7a +.section s9q7b +.section s9q8a +.section s9q8b +.section s9q9a +.section s9q9b +.section s9q0a +.section s9q0b +.section s9raa +.section s9rab +.section s9rba +.section s9rbb +.section s9rca +.section s9rcb +.section s9rda +.section s9rdb +.section s9rea +.section s9reb +.section s9rfa +.section s9rfb +.section s9rga +.section s9rgb +.section s9rha +.section s9rhb +.section s9ria +.section s9rib +.section s9rja +.section s9rjb +.section s9rka +.section s9rkb +.section s9rla +.section s9rlb +.section s9rma +.section s9rmb +.section s9rna +.section s9rnb +.section s9roa +.section s9rob +.section s9rpa +.section s9rpb +.section s9rqa +.section s9rqb +.section s9rra +.section s9rrb +.section s9rsa +.section s9rsb +.section s9rta +.section s9rtb +.section s9rua +.section s9rub +.section s9rva +.section s9rvb +.section s9rwa +.section s9rwb +.section s9rxa +.section s9rxb +.section s9rya +.section s9ryb +.section s9rza +.section s9rzb +.section s9r1a +.section s9r1b +.section s9r2a +.section s9r2b +.section s9r3a +.section s9r3b +.section s9r4a +.section s9r4b +.section s9r5a +.section s9r5b +.section s9r6a +.section s9r6b +.section s9r7a +.section s9r7b +.section s9r8a +.section s9r8b +.section s9r9a +.section s9r9b +.section s9r0a +.section s9r0b +.section s9saa +.section s9sab +.section s9sba +.section s9sbb +.section s9sca +.section s9scb +.section s9sda +.section s9sdb +.section s9sea +.section s9seb +.section s9sfa +.section s9sfb +.section s9sga +.section s9sgb +.section s9sha +.section s9shb +.section s9sia +.section s9sib +.section s9sja +.section s9sjb +.section s9ska +.section s9skb +.section s9sla +.section s9slb +.section s9sma +.section s9smb +.section s9sna +.section s9snb +.section s9soa +.section s9sob +.section s9spa +.section s9spb +.section s9sqa +.section s9sqb +.section s9sra +.section s9srb +.section s9ssa +.section s9ssb +.section s9sta +.section s9stb +.section s9sua +.section s9sub +.section s9sva +.section s9svb +.section s9swa +.section s9swb +.section s9sxa +.section s9sxb +.section s9sya +.section s9syb +.section s9sza +.section s9szb +.section s9s1a +.section s9s1b +.section s9s2a +.section s9s2b +.section s9s3a +.section s9s3b +.section s9s4a +.section s9s4b +.section s9s5a +.section s9s5b +.section s9s6a +.section s9s6b +.section s9s7a +.section s9s7b +.section s9s8a +.section s9s8b +.section s9s9a +.section s9s9b +.section s9s0a +.section s9s0b +.section s9taa +.section s9tab +.section s9tba +.section s9tbb +.section s9tca +.section s9tcb +.section s9tda +.section s9tdb +.section s9tea +.section s9teb +.section s9tfa +.section s9tfb +.section s9tga +.section s9tgb +.section s9tha +.section s9thb +.section s9tia +.section s9tib +.section s9tja +.section s9tjb +.section s9tka +.section s9tkb +.section s9tla +.section s9tlb +.section s9tma +.section s9tmb +.section s9tna +.section s9tnb +.section s9toa +.section s9tob +.section s9tpa +.section s9tpb +.section s9tqa +.section s9tqb +.section s9tra +.section s9trb +.section s9tsa +.section s9tsb +.section s9tta +.section s9ttb +.section s9tua +.section s9tub +.section s9tva +.section s9tvb +.section s9twa +.section s9twb +.section s9txa +.section s9txb +.section s9tya +.section s9tyb +.section s9tza +.section s9tzb +.section s9t1a +.section s9t1b +.section s9t2a +.section s9t2b +.section s9t3a +.section s9t3b +.section s9t4a +.section s9t4b +.section s9t5a +.section s9t5b +.section s9t6a +.section s9t6b +.section s9t7a +.section s9t7b +.section s9t8a +.section s9t8b +.section s9t9a +.section s9t9b +.section s9t0a +.section s9t0b +.section s9uaa +.section s9uab +.section s9uba +.section s9ubb +.section s9uca +.section s9ucb +.section s9uda +.section s9udb +.section s9uea +.section s9ueb +.section s9ufa +.section s9ufb +.section s9uga +.section s9ugb +.section s9uha +.section s9uhb +.section s9uia +.section s9uib +.section s9uja +.section s9ujb +.section s9uka +.section s9ukb +.section s9ula +.section s9ulb +.section s9uma +.section s9umb +.section s9una +.section s9unb +.section s9uoa +.section s9uob +.section s9upa +.section s9upb +.section s9uqa +.section s9uqb +.section s9ura +.section s9urb +.section s9usa +.section s9usb +.section s9uta +.section s9utb +.section s9uua +.section s9uub +.section s9uva +.section s9uvb +.section s9uwa +.section s9uwb +.section s9uxa +.section s9uxb +.section s9uya +.section s9uyb +.section s9uza +.section s9uzb +.section s9u1a +.section s9u1b +.section s9u2a +.section s9u2b +.section s9u3a +.section s9u3b +.section s9u4a +.section s9u4b +.section s9u5a +.section s9u5b +.section s9u6a +.section s9u6b +.section s9u7a +.section s9u7b +.section s9u8a +.section s9u8b +.section s9u9a +.section s9u9b +.section s9u0a +.section s9u0b +.section s9vaa +.section s9vab +.section s9vba +.section s9vbb +.section s9vca +.section s9vcb +.section s9vda +.section s9vdb +.section s9vea +.section s9veb +.section s9vfa +.section s9vfb +.section s9vga +.section s9vgb +.section s9vha +.section s9vhb +.section s9via +.section s9vib +.section s9vja +.section s9vjb +.section s9vka +.section s9vkb +.section s9vla +.section s9vlb +.section s9vma +.section s9vmb +.section s9vna +.section s9vnb +.section s9voa +.section s9vob +.section s9vpa +.section s9vpb +.section s9vqa +.section s9vqb +.section s9vra +.section s9vrb +.section s9vsa +.section s9vsb +.section s9vta +.section s9vtb +.section s9vua +.section s9vub +.section s9vva +.section s9vvb +.section s9vwa +.section s9vwb +.section s9vxa +.section s9vxb +.section s9vya +.section s9vyb +.section s9vza +.section s9vzb +.section s9v1a +.section s9v1b +.section s9v2a +.section s9v2b +.section s9v3a +.section s9v3b +.section s9v4a +.section s9v4b +.section s9v5a +.section s9v5b +.section s9v6a +.section s9v6b +.section s9v7a +.section s9v7b +.section s9v8a +.section s9v8b +.section s9v9a +.section s9v9b +.section s9v0a +.section s9v0b +.section s9waa +.section s9wab +.section s9wba +.section s9wbb +.section s9wca +.section s9wcb +.section s9wda +.section s9wdb +.section s9wea +.section s9web +.section s9wfa +.section s9wfb +.section s9wga +.section s9wgb +.section s9wha +.section s9whb +.section s9wia +.section s9wib +.section s9wja +.section s9wjb +.section s9wka +.section s9wkb +.section s9wla +.section s9wlb +.section s9wma +.section s9wmb +.section s9wna +.section s9wnb +.section s9woa +.section s9wob +.section s9wpa +.section s9wpb +.section s9wqa +.section s9wqb +.section s9wra +.section s9wrb +.section s9wsa +.section s9wsb +.section s9wta +.section s9wtb +.section s9wua +.section s9wub +.section s9wva +.section s9wvb +.section s9wwa +.section s9wwb +.section s9wxa +.section s9wxb +.section s9wya +.section s9wyb +.section s9wza +.section s9wzb +.section s9w1a +.section s9w1b +.section s9w2a +.section s9w2b +.section s9w3a +.section s9w3b +.section s9w4a +.section s9w4b +.section s9w5a +.section s9w5b +.section s9w6a +.section s9w6b +.section s9w7a +.section s9w7b +.section s9w8a +.section s9w8b +.section s9w9a +.section s9w9b +.section s9w0a +.section s9w0b +.section s9xaa +.section s9xab +.section s9xba +.section s9xbb +.section s9xca +.section s9xcb +.section s9xda +.section s9xdb +.section s9xea +.section s9xeb +.section s9xfa +.section s9xfb +.section s9xga +.section s9xgb +.section s9xha +.section s9xhb +.section s9xia +.section s9xib +.section s9xja +.section s9xjb +.section s9xka +.section s9xkb +.section s9xla +.section s9xlb +.section s9xma +.section s9xmb +.section s9xna +.section s9xnb +.section s9xoa +.section s9xob +.section s9xpa +.section s9xpb +.section s9xqa +.section s9xqb +.section s9xra +.section s9xrb +.section s9xsa +.section s9xsb +.section s9xta +.section s9xtb +.section s9xua +.section s9xub +.section s9xva +.section s9xvb +.section s9xwa +.section s9xwb +.section s9xxa +.section s9xxb +.section s9xya +.section s9xyb +.section s9xza +.section s9xzb +.section s9x1a +.section s9x1b +.section s9x2a +.section s9x2b +.section s9x3a +.section s9x3b +.section s9x4a +.section s9x4b +.section s9x5a +.section s9x5b +.section s9x6a +.section s9x6b +.section s9x7a +.section s9x7b +.section s9x8a +.section s9x8b +.section s9x9a +.section s9x9b +.section s9x0a +.section s9x0b +.section s9yaa +.section s9yab +.section s9yba +.section s9ybb +.section s9yca +.section s9ycb +.section s9yda +.section s9ydb +.section s9yea +.section s9yeb +.section s9yfa +.section s9yfb +.section s9yga +.section s9ygb +.section s9yha +.section s9yhb +.section s9yia +.section s9yib +.section s9yja +.section s9yjb +.section s9yka +.section s9ykb +.section s9yla +.section s9ylb +.section s9yma +.section s9ymb +.section s9yna +.section s9ynb +.section s9yoa +.section s9yob +.section s9ypa +.section s9ypb +.section s9yqa +.section s9yqb +.section s9yra +.section s9yrb +.section s9ysa +.section s9ysb +.section s9yta +.section s9ytb +.section s9yua +.section s9yub +.section s9yva +.section s9yvb +.section s9ywa +.section s9ywb +.section s9yxa +.section s9yxb +.section s9yya +.section s9yyb +.section s9yza +.section s9yzb +.section s9y1a +.section s9y1b +.section s9y2a +.section s9y2b +.section s9y3a +.section s9y3b +.section s9y4a +.section s9y4b +.section s9y5a +.section s9y5b +.section s9y6a +.section s9y6b +.section s9y7a +.section s9y7b +.section s9y8a +.section s9y8b +.section s9y9a +.section s9y9b +.section s9y0a +.section s9y0b +.section s9zaa +.section s9zab +.section s9zba +.section s9zbb +.section s9zca +.section s9zcb +.section s9zda +.section s9zdb +.section s9zea +.section s9zeb +.section s9zfa +.section s9zfb +.section s9zga +.section s9zgb +.section s9zha +.section s9zhb +.section s9zia +.section s9zib +.section s9zja +.section s9zjb +.section s9zka +.section s9zkb +.section s9zla +.section s9zlb +.section s9zma +.section s9zmb +.section s9zna +.section s9znb +.section s9zoa +.section s9zob +.section s9zpa +.section s9zpb +.section s9zqa +.section s9zqb +.section s9zra +.section s9zrb +.section s9zsa +.section s9zsb +.section s9zta +.section s9ztb +.section s9zua +.section s9zub +.section s9zva +.section s9zvb +.section s9zwa +.section s9zwb +.section s9zxa +.section s9zxb +.section s9zya +.section s9zyb +.section s9zza +.section s9zzb +.section s9z1a +.section s9z1b +.section s9z2a +.section s9z2b +.section s9z3a +.section s9z3b +.section s9z4a +.section s9z4b +.section s9z5a +.section s9z5b +.section s9z6a +.section s9z6b +.section s9z7a +.section s9z7b +.section s9z8a +.section s9z8b +.section s9z9a +.section s9z9b +.section s9z0a +.section s9z0b +.section s91aa +.section s91ab +.section s91ba +.section s91bb +.section s91ca +.section s91cb +.section s91da +.section s91db +.section s91ea +.section s91eb +.section s91fa +.section s91fb +.section s91ga +.section s91gb +.section s91ha +.section s91hb +.section s91ia +.section s91ib +.section s91ja +.section s91jb +.section s91ka +.section s91kb +.section s91la +.section s91lb +.section s91ma +.section s91mb +.section s91na +.section s91nb +.section s91oa +.section s91ob +.section s91pa +.section s91pb +.section s91qa +.section s91qb +.section s91ra +.section s91rb +.section s91sa +.section s91sb +.section s91ta +.section s91tb +.section s91ua +.section s91ub +.section s91va +.section s91vb +.section s91wa +.section s91wb +.section s91xa +.section s91xb +.section s91ya +.section s91yb +.section s91za +.section s91zb +.section s911a +.section s911b +.section s912a +.section s912b +.section s913a +.section s913b +.section s914a +.section s914b +.section s915a +.section s915b +.section s916a +.section s916b +.section s917a +.section s917b +.section s918a +.section s918b +.section s919a +.section s919b +.section s910a +.section s910b +.section s92aa +.section s92ab +.section s92ba +.section s92bb +.section s92ca +.section s92cb +.section s92da +.section s92db +.section s92ea +.section s92eb +.section s92fa +.section s92fb +.section s92ga +.section s92gb +.section s92ha +.section s92hb +.section s92ia +.section s92ib +.section s92ja +.section s92jb +.section s92ka +.section s92kb +.section s92la +.section s92lb +.section s92ma +.section s92mb +.section s92na +.section s92nb +.section s92oa +.section s92ob +.section s92pa +.section s92pb +.section s92qa +.section s92qb +.section s92ra +.section s92rb +.section s92sa +.section s92sb +.section s92ta +.section s92tb +.section s92ua +.section s92ub +.section s92va +.section s92vb +.section s92wa +.section s92wb +.section s92xa +.section s92xb +.section s92ya +.section s92yb +.section s92za +.section s92zb +.section s921a +.section s921b +.section s922a +.section s922b +.section s923a +.section s923b +.section s924a +.section s924b +.section s925a +.section s925b +.section s926a +.section s926b +.section s927a +.section s927b +.section s928a +.section s928b +.section s929a +.section s929b +.section s920a +.section s920b +.section s93aa +.section s93ab +.section s93ba +.section s93bb +.section s93ca +.section s93cb +.section s93da +.section s93db +.section s93ea +.section s93eb +.section s93fa +.section s93fb +.section s93ga +.section s93gb +.section s93ha +.section s93hb +.section s93ia +.section s93ib +.section s93ja +.section s93jb +.section s93ka +.section s93kb +.section s93la +.section s93lb +.section s93ma +.section s93mb +.section s93na +.section s93nb +.section s93oa +.section s93ob +.section s93pa +.section s93pb +.section s93qa +.section s93qb +.section s93ra +.section s93rb +.section s93sa +.section s93sb +.section s93ta +.section s93tb +.section s93ua +.section s93ub +.section s93va +.section s93vb +.section s93wa +.section s93wb +.section s93xa +.section s93xb +.section s93ya +.section s93yb +.section s93za +.section s93zb +.section s931a +.section s931b +.section s932a +.section s932b +.section s933a +.section s933b +.section s934a +.section s934b +.section s935a +.section s935b +.section s936a +.section s936b +.section s937a +.section s937b +.section s938a +.section s938b +.section s939a +.section s939b +.section s930a +.section s930b +.section s94aa +.section s94ab +.section s94ba +.section s94bb +.section s94ca +.section s94cb +.section s94da +.section s94db +.section s94ea +.section s94eb +.section s94fa +.section s94fb +.section s94ga +.section s94gb +.section s94ha +.section s94hb +.section s94ia +.section s94ib +.section s94ja +.section s94jb +.section s94ka +.section s94kb +.section s94la +.section s94lb +.section s94ma +.section s94mb +.section s94na +.section s94nb +.section s94oa +.section s94ob +.section s94pa +.section s94pb +.section s94qa +.section s94qb +.section s94ra +.section s94rb +.section s94sa +.section s94sb +.section s94ta +.section s94tb +.section s94ua +.section s94ub +.section s94va +.section s94vb +.section s94wa +.section s94wb +.section s94xa +.section s94xb +.section s94ya +.section s94yb +.section s94za +.section s94zb +.section s941a +.section s941b +.section s942a +.section s942b +.section s943a +.section s943b +.section s944a +.section s944b +.section s945a +.section s945b +.section s946a +.section s946b +.section s947a +.section s947b +.section s948a +.section s948b +.section s949a +.section s949b +.section s940a +.section s940b +.section s95aa +.section s95ab +.section s95ba +.section s95bb +.section s95ca +.section s95cb +.section s95da +.section s95db +.section s95ea +.section s95eb +.section s95fa +.section s95fb +.section s95ga +.section s95gb +.section s95ha +.section s95hb +.section s95ia +.section s95ib +.section s95ja +.section s95jb +.section s95ka +.section s95kb +.section s95la +.section s95lb +.section s95ma +.section s95mb +.section s95na +.section s95nb +.section s95oa +.section s95ob +.section s95pa +.section s95pb +.section s95qa +.section s95qb +.section s95ra +.section s95rb +.section s95sa +.section s95sb +.section s95ta +.section s95tb +.section s95ua +.section s95ub +.section s95va +.section s95vb +.section s95wa +.section s95wb +.section s95xa +.section s95xb +.section s95ya +.section s95yb +.section s95za +.section s95zb +.section s951a +.section s951b +.section s952a +.section s952b +.section s953a +.section s953b +.section s954a +.section s954b +.section s955a +.section s955b +.section s956a +.section s956b +.section s957a +.section s957b +.section s958a +.section s958b +.section s959a +.section s959b +.section s950a +.section s950b +.section s96aa +.section s96ab +.section s96ba +.section s96bb +.section s96ca +.section s96cb +.section s96da +.section s96db +.section s96ea +.section s96eb +.section s96fa +.section s96fb +.section s96ga +.section s96gb +.section s96ha +.section s96hb +.section s96ia +.section s96ib +.section s96ja +.section s96jb +.section s96ka +.section s96kb +.section s96la +.section s96lb +.section s96ma +.section s96mb +.section s96na +.section s96nb +.section s96oa +.section s96ob +.section s96pa +.section s96pb +.section s96qa +.section s96qb +.section s96ra +.section s96rb +.section s96sa +.section s96sb +.section s96ta +.section s96tb +.section s96ua +.section s96ub +.section s96va +.section s96vb +.section s96wa +.section s96wb +.section s96xa +.section s96xb +.section s96ya +.section s96yb +.section s96za +.section s96zb +.section s961a +.section s961b +.section s962a +.section s962b +.section s963a +.section s963b +.section s964a +.section s964b +.section s965a +.section s965b +.section s966a +.section s966b +.section s967a +.section s967b +.section s968a +.section s968b +.section s969a +.section s969b +.section s960a +.section s960b +.section s97aa +.section s97ab +.section s97ba +.section s97bb +.section s97ca +.section s97cb +.section s97da +.section s97db +.section s97ea +.section s97eb +.section s97fa +.section s97fb +.section s97ga +.section s97gb +.section s97ha +.section s97hb +.section s97ia +.section s97ib +.section s97ja +.section s97jb +.section s97ka +.section s97kb +.section s97la +.section s97lb +.section s97ma +.section s97mb +.section s97na +.section s97nb +.section s97oa +.section s97ob +.section s97pa +.section s97pb +.section s97qa +.section s97qb +.section s97ra +.section s97rb +.section s97sa +.section s97sb +.section s97ta +.section s97tb +.section s97ua +.section s97ub +.section s97va +.section s97vb +.section s97wa +.section s97wb +.section s97xa +.section s97xb +.section s97ya +.section s97yb +.section s97za +.section s97zb +.section s971a +.section s971b +.section s972a +.section s972b +.section s973a +.section s973b +.section s974a +.section s974b +.section s975a +.section s975b +.section s976a +.section s976b +.section s977a +.section s977b +.section s978a +.section s978b +.section s979a +.section s979b +.section s970a +.section s970b +.section s98aa +.section s98ab +.section s98ba +.section s98bb +.section s98ca +.section s98cb +.section s98da +.section s98db +.section s98ea +.section s98eb +.section s98fa +.section s98fb +.section s98ga +.section s98gb +.section s98ha +.section s98hb +.section s98ia +.section s98ib +.section s98ja +.section s98jb +.section s98ka +.section s98kb +.section s98la +.section s98lb +.section s98ma +.section s98mb +.section s98na +.section s98nb +.section s98oa +.section s98ob +.section s98pa +.section s98pb +.section s98qa +.section s98qb +.section s98ra +.section s98rb +.section s98sa +.section s98sb +.section s98ta +.section s98tb +.section s98ua +.section s98ub +.section s98va +.section s98vb +.section s98wa +.section s98wb +.section s98xa +.section s98xb +.section s98ya +.section s98yb +.section s98za +.section s98zb +.section s981a +.section s981b +.section s982a +.section s982b +.section s983a +.section s983b +.section s984a +.section s984b +.section s985a +.section s985b +.section s986a +.section s986b +.section s987a +.section s987b +.section s988a +.section s988b +.section s989a +.section s989b +.section s980a +.section s980b +.section s99aa +.section s99ab +.section s99ba +.section s99bb +.section s99ca +.section s99cb +.section s99da +.section s99db +.section s99ea +.section s99eb +.section s99fa +.section s99fb +.section s99ga +.section s99gb +.section s99ha +.section s99hb +.section s99ia +.section s99ib +.section s99ja +.section s99jb +.section s99ka +.section s99kb +.section s99la +.section s99lb +.section s99ma +.section s99mb +.section s99na +.section s99nb +.section s99oa +.section s99ob +.section s99pa +.section s99pb +.section s99qa +.section s99qb +.section s99ra +.section s99rb +.section s99sa +.section s99sb +.section s99ta +.section s99tb +.section s99ua +.section s99ub +.section s99va +.section s99vb +.section s99wa +.section s99wb +.section s99xa +.section s99xb +.section s99ya +.section s99yb +.section s99za +.section s99zb +.section s991a +.section s991b +.section s992a +.section s992b +.section s993a +.section s993b +.section s994a +.section s994b +.section s995a +.section s995b +.section s996a +.section s996b +.section s997a +.section s997b +.section s998a +.section s998b +.section s999a +.section s999b +.section s990a +.section s990b +.section s90aa +.section s90ab +.section s90ba +.section s90bb +.section s90ca +.section s90cb +.section s90da +.section s90db +.section s90ea +.section s90eb +.section s90fa +.section s90fb +.section s90ga +.section s90gb +.section s90ha +.section s90hb +.section s90ia +.section s90ib +.section s90ja +.section s90jb +.section s90ka +.section s90kb +.section s90la +.section s90lb +.section s90ma +.section s90mb +.section s90na +.section s90nb +.section s90oa +.section s90ob +.section s90pa +.section s90pb +.section s90qa +.section s90qb +.section s90ra +.section s90rb +.section s90sa +.section s90sb +.section s90ta +.section s90tb +.section s90ua +.section s90ub +.section s90va +.section s90vb +.section s90wa +.section s90wb +.section s90xa +.section s90xb +.section s90ya +.section s90yb +.section s90za +.section s90zb +.section s901a +.section s901b +.section s902a +.section s902b +.section s903a +.section s903b +.section s904a +.section s904b +.section s905a +.section s905b +.section s906a +.section s906b +.section s907a +.section s907b +.section s908a +.section s908b +.section s909a +.section s909b +.section s900a +.section s900b +.section s0aaa +.section s0aab +.section s0aba +.section s0abb +.section s0aca +.section s0acb +.section s0ada +.section s0adb +.section s0aea +.section s0aeb +.section s0afa +.section s0afb +.section s0aga +.section s0agb +.section s0aha +.section s0ahb +.section s0aia +.section s0aib +.section s0aja +.section s0ajb +.section s0aka +.section s0akb +.section s0ala +.section s0alb +.section s0ama +.section s0amb +.section s0ana +.section s0anb +.section s0aoa +.section s0aob +.section s0apa +.section s0apb +.section s0aqa +.section s0aqb +.section s0ara +.section s0arb +.section s0asa +.section s0asb +.section s0ata +.section s0atb +.section s0aua +.section s0aub +.section s0ava +.section s0avb +.section s0awa +.section s0awb +.section s0axa +.section s0axb +.section s0aya +.section s0ayb +.section s0aza +.section s0azb +.section s0a1a +.section s0a1b +.section s0a2a +.section s0a2b +.section s0a3a +.section s0a3b +.section s0a4a +.section s0a4b +.section s0a5a +.section s0a5b +.section s0a6a +.section s0a6b +.section s0a7a +.section s0a7b +.section s0a8a +.section s0a8b +.section s0a9a +.section s0a9b +.section s0a0a +.section s0a0b +.section s0baa +.section s0bab +.section s0bba +.section s0bbb +.section s0bca +.section s0bcb +.section s0bda +.section s0bdb +.section s0bea +.section s0beb +.section s0bfa +.section s0bfb +.section s0bga +.section s0bgb +.section s0bha +.section s0bhb +.section s0bia +.section s0bib +.section s0bja +.section s0bjb +.section s0bka +.section s0bkb +.section s0bla +.section s0blb +.section s0bma +.section s0bmb +.section s0bna +.section s0bnb +.section s0boa +.section s0bob +.section s0bpa +.section s0bpb +.section s0bqa +.section s0bqb +.section s0bra +.section s0brb +.section s0bsa +.section s0bsb +.section s0bta +.section s0btb +.section s0bua +.section s0bub +.section s0bva +.section s0bvb +.section s0bwa +.section s0bwb +.section s0bxa +.section s0bxb +.section s0bya +.section s0byb +.section s0bza +.section s0bzb +.section s0b1a +.section s0b1b +.section s0b2a +.section s0b2b +.section s0b3a +.section s0b3b +.section s0b4a +.section s0b4b +.section s0b5a +.section s0b5b +.section s0b6a +.section s0b6b +.section s0b7a +.section s0b7b +.section s0b8a +.section s0b8b +.section s0b9a +.section s0b9b +.section s0b0a +.section s0b0b +.section s0caa +.section s0cab +.section s0cba +.section s0cbb +.section s0cca +.section s0ccb +.section s0cda +.section s0cdb +.section s0cea +.section s0ceb +.section s0cfa +.section s0cfb +.section s0cga +.section s0cgb +.section s0cha +.section s0chb +.section s0cia +.section s0cib +.section s0cja +.section s0cjb +.section s0cka +.section s0ckb +.section s0cla +.section s0clb +.section s0cma +.section s0cmb +.section s0cna +.section s0cnb +.section s0coa +.section s0cob +.section s0cpa +.section s0cpb +.section s0cqa +.section s0cqb +.section s0cra +.section s0crb +.section s0csa +.section s0csb +.section s0cta +.section s0ctb +.section s0cua +.section s0cub +.section s0cva +.section s0cvb +.section s0cwa +.section s0cwb +.section s0cxa +.section s0cxb +.section s0cya +.section s0cyb +.section s0cza +.section s0czb +.section s0c1a +.section s0c1b +.section s0c2a +.section s0c2b +.section s0c3a +.section s0c3b +.section s0c4a +.section s0c4b +.section s0c5a +.section s0c5b +.section s0c6a +.section s0c6b +.section s0c7a +.section s0c7b +.section s0c8a +.section s0c8b +.section s0c9a +.section s0c9b +.section s0c0a +.section s0c0b +.section s0daa +.section s0dab +.section s0dba +.section s0dbb +.section s0dca +.section s0dcb +.section s0dda +.section s0ddb +.section s0dea +.section s0deb +.section s0dfa +.section s0dfb +.section s0dga +.section s0dgb +.section s0dha +.section s0dhb +.section s0dia +.section s0dib +.section s0dja +.section s0djb +.section s0dka +.section s0dkb +.section s0dla +.section s0dlb +.section s0dma +.section s0dmb +.section s0dna +.section s0dnb +.section s0doa +.section s0dob +.section s0dpa +.section s0dpb +.section s0dqa +.section s0dqb +.section s0dra +.section s0drb +.section s0dsa +.section s0dsb +.section s0dta +.section s0dtb +.section s0dua +.section s0dub +.section s0dva +.section s0dvb +.section s0dwa +.section s0dwb +.section s0dxa +.section s0dxb +.section s0dya +.section s0dyb +.section s0dza +.section s0dzb +.section s0d1a +.section s0d1b +.section s0d2a +.section s0d2b +.section s0d3a +.section s0d3b +.section s0d4a +.section s0d4b +.section s0d5a +.section s0d5b +.section s0d6a +.section s0d6b +.section s0d7a +.section s0d7b +.section s0d8a +.section s0d8b +.section s0d9a +.section s0d9b +.section s0d0a +.section s0d0b +.section s0eaa +.section s0eab +.section s0eba +.section s0ebb +.section s0eca +.section s0ecb +.section s0eda +.section s0edb +.section s0eea +.section s0eeb +.section s0efa +.section s0efb +.section s0ega +.section s0egb +.section s0eha +.section s0ehb +.section s0eia +.section s0eib +.section s0eja +.section s0ejb +.section s0eka +.section s0ekb +.section s0ela +.section s0elb +.section s0ema +.section s0emb +.section s0ena +.section s0enb +.section s0eoa +.section s0eob +.section s0epa +.section s0epb +.section s0eqa +.section s0eqb +.section s0era +.section s0erb +.section s0esa +.section s0esb +.section s0eta +.section s0etb +.section s0eua +.section s0eub +.section s0eva +.section s0evb +.section s0ewa +.section s0ewb +.section s0exa +.section s0exb +.section s0eya +.section s0eyb +.section s0eza +.section s0ezb +.section s0e1a +.section s0e1b +.section s0e2a +.section s0e2b +.section s0e3a +.section s0e3b +.section s0e4a +.section s0e4b +.section s0e5a +.section s0e5b +.section s0e6a +.section s0e6b +.section s0e7a +.section s0e7b +.section s0e8a +.section s0e8b +.section s0e9a +.section s0e9b +.section s0e0a +.section s0e0b +.section s0faa +.section s0fab +.section s0fba +.section s0fbb +.section s0fca +.section s0fcb +.section s0fda +.section s0fdb +.section s0fea +.section s0feb +.section s0ffa +.section s0ffb +.section s0fga +.section s0fgb +.section s0fha +.section s0fhb +.section s0fia +.section s0fib +.section s0fja +.section s0fjb +.section s0fka +.section s0fkb +.section s0fla +.section s0flb +.section s0fma +.section s0fmb +.section s0fna +.section s0fnb +.section s0foa +.section s0fob +.section s0fpa +.section s0fpb +.section s0fqa +.section s0fqb +.section s0fra +.section s0frb +.section s0fsa +.section s0fsb +.section s0fta +.section s0ftb +.section s0fua +.section s0fub +.section s0fva +.section s0fvb +.section s0fwa +.section s0fwb +.section s0fxa +.section s0fxb +.section s0fya +.section s0fyb +.section s0fza +.section s0fzb +.section s0f1a +.section s0f1b +.section s0f2a +.section s0f2b +.section s0f3a +.section s0f3b +.section s0f4a +.section s0f4b +.section s0f5a +.section s0f5b +.section s0f6a +.section s0f6b +.section s0f7a +.section s0f7b +.section s0f8a +.section s0f8b +.section s0f9a +.section s0f9b +.section s0f0a +.section s0f0b +.section s0gaa +.section s0gab +.section s0gba +.section s0gbb +.section s0gca +.section s0gcb +.section s0gda +.section s0gdb +.section s0gea +.section s0geb +.section s0gfa +.section s0gfb +.section s0gga +.section s0ggb +.section s0gha +.section s0ghb +.section s0gia +.section s0gib +.section s0gja +.section s0gjb +.section s0gka +.section s0gkb +.section s0gla +.section s0glb +.section s0gma +.section s0gmb +.section s0gna +.section s0gnb +.section s0goa +.section s0gob +.section s0gpa +.section s0gpb +.section s0gqa +.section s0gqb +.section s0gra +.section s0grb +.section s0gsa +.section s0gsb +.section s0gta +.section s0gtb +.section s0gua +.section s0gub +.section s0gva +.section s0gvb +.section s0gwa +.section s0gwb +.section s0gxa +.section s0gxb +.section s0gya +.section s0gyb +.section s0gza +.section s0gzb +.section s0g1a +.section s0g1b +.section s0g2a +.section s0g2b +.section s0g3a +.section s0g3b +.section s0g4a +.section s0g4b +.section s0g5a +.section s0g5b +.section s0g6a +.section s0g6b +.section s0g7a +.section s0g7b +.section s0g8a +.section s0g8b +.section s0g9a +.section s0g9b +.section s0g0a +.section s0g0b +.section s0haa +.section s0hab +.section s0hba +.section s0hbb +.section s0hca +.section s0hcb +.section s0hda +.section s0hdb +.section s0hea +.section s0heb +.section s0hfa +.section s0hfb +.section s0hga +.section s0hgb +.section s0hha +.section s0hhb +.section s0hia +.section s0hib +.section s0hja +.section s0hjb +.section s0hka +.section s0hkb +.section s0hla +.section s0hlb +.section s0hma +.section s0hmb +.section s0hna +.section s0hnb +.section s0hoa +.section s0hob +.section s0hpa +.section s0hpb +.section s0hqa +.section s0hqb +.section s0hra +.section s0hrb +.section s0hsa +.section s0hsb +.section s0hta +.section s0htb +.section s0hua +.section s0hub +.section s0hva +.section s0hvb +.section s0hwa +.section s0hwb +.section s0hxa +.section s0hxb +.section s0hya +.section s0hyb +.section s0hza +.section s0hzb +.section s0h1a +.section s0h1b +.section s0h2a +.section s0h2b +.section s0h3a +.section s0h3b +.section s0h4a +.section s0h4b +.section s0h5a +.section s0h5b +.section s0h6a +.section s0h6b +.section s0h7a +.section s0h7b +.section s0h8a +.section s0h8b +.section s0h9a +.section s0h9b +.section s0h0a +.section s0h0b +.section s0iaa +.section s0iab +.section s0iba +.section s0ibb +.section s0ica +.section s0icb +.section s0ida +.section s0idb +.section s0iea +.section s0ieb +.section s0ifa +.section s0ifb +.section s0iga +.section s0igb +.section s0iha +.section s0ihb +.section s0iia +.section s0iib +.section s0ija +.section s0ijb +.section s0ika +.section s0ikb +.section s0ila +.section s0ilb +.section s0ima +.section s0imb +.section s0ina +.section s0inb +.section s0ioa +.section s0iob +.section s0ipa +.section s0ipb +.section s0iqa +.section s0iqb +.section s0ira +.section s0irb +.section s0isa +.section s0isb +.section s0ita +.section s0itb +.section s0iua +.section s0iub +.section s0iva +.section s0ivb +.section s0iwa +.section s0iwb +.section s0ixa +.section s0ixb +.section s0iya +.section s0iyb +.section s0iza +.section s0izb +.section s0i1a +.section s0i1b +.section s0i2a +.section s0i2b +.section s0i3a +.section s0i3b +.section s0i4a +.section s0i4b +.section s0i5a +.section s0i5b +.section s0i6a +.section s0i6b +.section s0i7a +.section s0i7b +.section s0i8a +.section s0i8b +.section s0i9a +.section s0i9b +.section s0i0a +.section s0i0b +.section s0jaa +.section s0jab +.section s0jba +.section s0jbb +.section s0jca +.section s0jcb +.section s0jda +.section s0jdb +.section s0jea +.section s0jeb +.section s0jfa +.section s0jfb +.section s0jga +.section s0jgb +.section s0jha +.section s0jhb +.section s0jia +.section s0jib +.section s0jja +.section s0jjb +.section s0jka +.section s0jkb +.section s0jla +.section s0jlb +.section s0jma +.section s0jmb +.section s0jna +.section s0jnb +.section s0joa +.section s0job +.section s0jpa +.section s0jpb +.section s0jqa +.section s0jqb +.section s0jra +.section s0jrb +.section s0jsa +.section s0jsb +.section s0jta +.section s0jtb +.section s0jua +.section s0jub +.section s0jva +.section s0jvb +.section s0jwa +.section s0jwb +.section s0jxa +.section s0jxb +.section s0jya +.section s0jyb +.section s0jza +.section s0jzb +.section s0j1a +.section s0j1b +.section s0j2a +.section s0j2b +.section s0j3a +.section s0j3b +.section s0j4a +.section s0j4b +.section s0j5a +.section s0j5b +.section s0j6a +.section s0j6b +.section s0j7a +.section s0j7b +.section s0j8a +.section s0j8b +.section s0j9a +.section s0j9b +.section s0j0a +.section s0j0b +.section s0kaa +.section s0kab +.section s0kba +.section s0kbb +.section s0kca +.section s0kcb +.section s0kda +.section s0kdb +.section s0kea +.section s0keb +.section s0kfa +.section s0kfb +.section s0kga +.section s0kgb +.section s0kha +.section s0khb +.section s0kia +.section s0kib +.section s0kja +.section s0kjb +.section s0kka +.section s0kkb +.section s0kla +.section s0klb +.section s0kma +.section s0kmb +.section s0kna +.section s0knb +.section s0koa +.section s0kob +.section s0kpa +.section s0kpb +.section s0kqa +.section s0kqb +.section s0kra +.section s0krb +.section s0ksa +.section s0ksb +.section s0kta +.section s0ktb +.section s0kua +.section s0kub +.section s0kva +.section s0kvb +.section s0kwa +.section s0kwb +.section s0kxa +.section s0kxb +.section s0kya +.section s0kyb +.section s0kza +.section s0kzb +.section s0k1a +.section s0k1b +.section s0k2a +.section s0k2b +.section s0k3a +.section s0k3b +.section s0k4a +.section s0k4b +.section s0k5a +.section s0k5b +.section s0k6a +.section s0k6b +.section s0k7a +.section s0k7b +.section s0k8a +.section s0k8b +.section s0k9a +.section s0k9b +.section s0k0a +.section s0k0b +.section s0laa +.section s0lab +.section s0lba +.section s0lbb +.section s0lca +.section s0lcb +.section s0lda +.section s0ldb +.section s0lea +.section s0leb +.section s0lfa +.section s0lfb +.section s0lga +.section s0lgb +.section s0lha +.section s0lhb +.section s0lia +.section s0lib +.section s0lja +.section s0ljb +.section s0lka +.section s0lkb +.section s0lla +.section s0llb +.section s0lma +.section s0lmb +.section s0lna +.section s0lnb +.section s0loa +.section s0lob +.section s0lpa +.section s0lpb +.section s0lqa +.section s0lqb +.section s0lra +.section s0lrb +.section s0lsa +.section s0lsb +.section s0lta +.section s0ltb +.section s0lua +.section s0lub +.section s0lva +.section s0lvb +.section s0lwa +.section s0lwb +.section s0lxa +.section s0lxb +.section s0lya +.section s0lyb +.section s0lza +.section s0lzb +.section s0l1a +.section s0l1b +.section s0l2a +.section s0l2b +.section s0l3a +.section s0l3b +.section s0l4a +.section s0l4b +.section s0l5a +.section s0l5b +.section s0l6a +.section s0l6b +.section s0l7a +.section s0l7b +.section s0l8a +.section s0l8b +.section s0l9a +.section s0l9b +.section s0l0a +.section s0l0b +.section s0maa +.section s0mab +.section s0mba +.section s0mbb +.section s0mca +.section s0mcb +.section s0mda +.section s0mdb +.section s0mea +.section s0meb +.section s0mfa +.section s0mfb +.section s0mga +.section s0mgb +.section s0mha +.section s0mhb +.section s0mia +.section s0mib +.section s0mja +.section s0mjb +.section s0mka +.section s0mkb +.section s0mla +.section s0mlb +.section s0mma +.section s0mmb +.section s0mna +.section s0mnb +.section s0moa +.section s0mob +.section s0mpa +.section s0mpb +.section s0mqa +.section s0mqb +.section s0mra +.section s0mrb +.section s0msa +.section s0msb +.section s0mta +.section s0mtb +.section s0mua +.section s0mub +.section s0mva +.section s0mvb +.section s0mwa +.section s0mwb +.section s0mxa +.section s0mxb +.section s0mya +.section s0myb +.section s0mza +.section s0mzb +.section s0m1a +.section s0m1b +.section s0m2a +.section s0m2b +.section s0m3a +.section s0m3b +.section s0m4a +.section s0m4b +.section s0m5a +.section s0m5b +.section s0m6a +.section s0m6b +.section s0m7a +.section s0m7b +.section s0m8a +.section s0m8b +.section s0m9a +.section s0m9b +.section s0m0a +.section s0m0b +.section s0naa +.section s0nab +.section s0nba +.section s0nbb +.section s0nca +.section s0ncb +.section s0nda +.section s0ndb +.section s0nea +.section s0neb +.section s0nfa +.section s0nfb +.section s0nga +.section s0ngb +.section s0nha +.section s0nhb +.section s0nia +.section s0nib +.section s0nja +.section s0njb +.section s0nka +.section s0nkb +.section s0nla +.section s0nlb +.section s0nma +.section s0nmb +.section s0nna +.section s0nnb +.section s0noa +.section s0nob +.section s0npa +.section s0npb +.section s0nqa +.section s0nqb +.section s0nra +.section s0nrb +.section s0nsa +.section s0nsb +.section s0nta +.section s0ntb +.section s0nua +.section s0nub +.section s0nva +.section s0nvb +.section s0nwa +.section s0nwb +.section s0nxa +.section s0nxb +.section s0nya +.section s0nyb +.section s0nza +.section s0nzb +.section s0n1a +.section s0n1b +.section s0n2a +.section s0n2b +.section s0n3a +.section s0n3b +.section s0n4a +.section s0n4b +.section s0n5a +.section s0n5b +.section s0n6a +.section s0n6b +.section s0n7a +.section s0n7b +.section s0n8a +.section s0n8b +.section s0n9a +.section s0n9b +.section s0n0a +.section s0n0b +.section s0oaa +.section s0oab +.section s0oba +.section s0obb +.section s0oca +.section s0ocb +.section s0oda +.section s0odb +.section s0oea +.section s0oeb +.section s0ofa +.section s0ofb +.section s0oga +.section s0ogb +.section s0oha +.section s0ohb +.section s0oia +.section s0oib +.section s0oja +.section s0ojb +.section s0oka +.section s0okb +.section s0ola +.section s0olb +.section s0oma +.section s0omb +.section s0ona +.section s0onb +.section s0ooa +.section s0oob +.section s0opa +.section s0opb +.section s0oqa +.section s0oqb +.section s0ora +.section s0orb +.section s0osa +.section s0osb +.section s0ota +.section s0otb +.section s0oua +.section s0oub +.section s0ova +.section s0ovb +.section s0owa +.section s0owb +.section s0oxa +.section s0oxb +.section s0oya +.section s0oyb +.section s0oza +.section s0ozb +.section s0o1a +.section s0o1b +.section s0o2a +.section s0o2b +.section s0o3a +.section s0o3b +.section s0o4a +.section s0o4b +.section s0o5a +.section s0o5b +.section s0o6a +.section s0o6b +.section s0o7a +.section s0o7b +.section s0o8a +.section s0o8b +.section s0o9a +.section s0o9b +.section s0o0a +.section s0o0b +.section s0paa +.section s0pab +.section s0pba +.section s0pbb +.section s0pca +.section s0pcb +.section s0pda +.section s0pdb +.section s0pea +.section s0peb +.section s0pfa +.section s0pfb +.section s0pga +.section s0pgb +.section s0pha +.section s0phb +.section s0pia +.section s0pib +.section s0pja +.section s0pjb +.section s0pka +.section s0pkb +.section s0pla +.section s0plb +.section s0pma +.section s0pmb +.section s0pna +.section s0pnb +.section s0poa +.section s0pob +.section s0ppa +.section s0ppb +.section s0pqa +.section s0pqb +.section s0pra +.section s0prb +.section s0psa +.section s0psb +.section s0pta +.section s0ptb +.section s0pua +.section s0pub +.section s0pva +.section s0pvb +.section s0pwa +.section s0pwb +.section s0pxa +.section s0pxb +.section s0pya +.section s0pyb +.section s0pza +.section s0pzb +.section s0p1a +.section s0p1b +.section s0p2a +.section s0p2b +.section s0p3a +.section s0p3b +.section s0p4a +.section s0p4b +.section s0p5a +.section s0p5b +.section s0p6a +.section s0p6b +.section s0p7a +.section s0p7b +.section s0p8a +.section s0p8b +.section s0p9a +.section s0p9b +.section s0p0a +.section s0p0b +.section s0qaa +.section s0qab +.section s0qba +.section s0qbb +.section s0qca +.section s0qcb +.section s0qda +.section s0qdb +.section s0qea +.section s0qeb +.section s0qfa +.section s0qfb +.section s0qga +.section s0qgb +.section s0qha +.section s0qhb +.section s0qia +.section s0qib +.section s0qja +.section s0qjb +.section s0qka +.section s0qkb +.section s0qla +.section s0qlb +.section s0qma +.section s0qmb +.section s0qna +.section s0qnb +.section s0qoa +.section s0qob +.section s0qpa +.section s0qpb +.section s0qqa +.section s0qqb +.section s0qra +.section s0qrb +.section s0qsa +.section s0qsb +.section s0qta +.section s0qtb +.section s0qua +.section s0qub +.section s0qva +.section s0qvb +.section s0qwa +.section s0qwb +.section s0qxa +.section s0qxb +.section s0qya +.section s0qyb +.section s0qza +.section s0qzb +.section s0q1a +.section s0q1b +.section s0q2a +.section s0q2b +.section s0q3a +.section s0q3b +.section s0q4a +.section s0q4b +.section s0q5a +.section s0q5b +.section s0q6a +.section s0q6b +.section s0q7a +.section s0q7b +.section s0q8a +.section s0q8b +.section s0q9a +.section s0q9b +.section s0q0a +.section s0q0b +.section s0raa +.section s0rab +.section s0rba +.section s0rbb +.section s0rca +.section s0rcb +.section s0rda +.section s0rdb +.section s0rea +.section s0reb +.section s0rfa +.section s0rfb +.section s0rga +.section s0rgb +.section s0rha +.section s0rhb +.section s0ria +.section s0rib +.section s0rja +.section s0rjb +.section s0rka +.section s0rkb +.section s0rla +.section s0rlb +.section s0rma +.section s0rmb +.section s0rna +.section s0rnb +.section s0roa +.section s0rob +.section s0rpa +.section s0rpb +.section s0rqa +.section s0rqb +.section s0rra +.section s0rrb +.section s0rsa +.section s0rsb +.section s0rta +.section s0rtb +.section s0rua +.section s0rub +.section s0rva +.section s0rvb +.section s0rwa +.section s0rwb +.section s0rxa +.section s0rxb +.section s0rya +.section s0ryb +.section s0rza +.section s0rzb +.section s0r1a +.section s0r1b +.section s0r2a +.section s0r2b +.section s0r3a +.section s0r3b +.section s0r4a +.section s0r4b +.section s0r5a +.section s0r5b +.section s0r6a +.section s0r6b +.section s0r7a +.section s0r7b +.section s0r8a +.section s0r8b +.section s0r9a +.section s0r9b +.section s0r0a +.section s0r0b +.section s0saa +.section s0sab +.section s0sba +.section s0sbb +.section s0sca +.section s0scb +.section s0sda +.section s0sdb +.section s0sea +.section s0seb +.section s0sfa +.section s0sfb +.section s0sga +.section s0sgb +.section s0sha +.section s0shb +.section s0sia +.section s0sib +.section s0sja +.section s0sjb +.section s0ska +.section s0skb +.section s0sla +.section s0slb +.section s0sma +.section s0smb +.section s0sna +.section s0snb +.section s0soa +.section s0sob +.section s0spa +.section s0spb +.section s0sqa +.section s0sqb +.section s0sra +.section s0srb +.section s0ssa +.section s0ssb +.section s0sta +.section s0stb +.section s0sua +.section s0sub +.section s0sva +.section s0svb +.section s0swa +.section s0swb +.section s0sxa +.section s0sxb +.section s0sya +.section s0syb +.section s0sza +.section s0szb +.section s0s1a +.section s0s1b +.section s0s2a +.section s0s2b +.section s0s3a +.section s0s3b +.section s0s4a +.section s0s4b +.section s0s5a +.section s0s5b +.section s0s6a +.section s0s6b +.section s0s7a +.section s0s7b +.section s0s8a +.section s0s8b +.section s0s9a +.section s0s9b +.section s0s0a +.section s0s0b +.section s0taa +.section s0tab +.section s0tba +.section s0tbb +.section s0tca +.section s0tcb +.section s0tda +.section s0tdb +.section s0tea +.section s0teb +.section s0tfa +.section s0tfb +.section s0tga +.section s0tgb +.section s0tha +.section s0thb +.section s0tia +.section s0tib +.section s0tja +.section s0tjb +.section s0tka +.section s0tkb +.section s0tla +.section s0tlb +.section s0tma +.section s0tmb +.section s0tna +.section s0tnb +.section s0toa +.section s0tob +.section s0tpa +.section s0tpb +.section s0tqa +.section s0tqb +.section s0tra +.section s0trb +.section s0tsa +.section s0tsb +.section s0tta +.section s0ttb +.section s0tua +.section s0tub +.section s0tva +.section s0tvb +.section s0twa +.section s0twb +.section s0txa +.section s0txb +.section s0tya +.section s0tyb +.section s0tza +.section s0tzb +.section s0t1a +.section s0t1b +.section s0t2a +.section s0t2b +.section s0t3a +.section s0t3b +.section s0t4a +.section s0t4b +.section s0t5a +.section s0t5b +.section s0t6a +.section s0t6b +.section s0t7a +.section s0t7b +.section s0t8a +.section s0t8b +.section s0t9a +.section s0t9b +.section s0t0a +.section s0t0b +.section s0uaa +.section s0uab +.section s0uba +.section s0ubb +.section s0uca +.section s0ucb +.section s0uda +.section s0udb +.section s0uea +.section s0ueb +.section s0ufa +.section s0ufb +.section s0uga +.section s0ugb +.section s0uha +.section s0uhb +.section s0uia +.section s0uib +.section s0uja +.section s0ujb +.section s0uka +.section s0ukb +.section s0ula +.section s0ulb +.section s0uma +.section s0umb +.section s0una +.section s0unb +.section s0uoa +.section s0uob +.section s0upa +.section s0upb +.section s0uqa +.section s0uqb +.section s0ura +.section s0urb +.section s0usa +.section s0usb +.section s0uta +.section s0utb +.section s0uua +.section s0uub +.section s0uva +.section s0uvb +.section s0uwa +.section s0uwb +.section s0uxa +.section s0uxb +.section s0uya +.section s0uyb +.section s0uza +.section s0uzb +.section s0u1a +.section s0u1b +.section s0u2a +.section s0u2b +.section s0u3a +.section s0u3b +.section s0u4a +.section s0u4b +.section s0u5a +.section s0u5b +.section s0u6a +.section s0u6b +.section s0u7a +.section s0u7b +.section s0u8a +.section s0u8b +.section s0u9a +.section s0u9b +.section s0u0a +.section s0u0b +.section s0vaa +.section s0vab +.section s0vba +.section s0vbb +.section s0vca +.section s0vcb +.section s0vda +.section s0vdb +.section s0vea +.section s0veb +.section s0vfa +.section s0vfb +.section s0vga +.section s0vgb +.section s0vha +.section s0vhb +.section s0via +.section s0vib +.section s0vja +.section s0vjb +.section s0vka +.section s0vkb +.section s0vla +.section s0vlb +.section s0vma +.section s0vmb +.section s0vna +.section s0vnb +.section s0voa +.section s0vob +.section s0vpa +.section s0vpb +.section s0vqa +.section s0vqb +.section s0vra +.section s0vrb +.section s0vsa +.section s0vsb +.section s0vta +.section s0vtb +.section s0vua +.section s0vub +.section s0vva +.section s0vvb +.section s0vwa +.section s0vwb +.section s0vxa +.section s0vxb +.section s0vya +.section s0vyb +.section s0vza +.section s0vzb +.section s0v1a +.section s0v1b +.section s0v2a +.section s0v2b +.section s0v3a +.section s0v3b +.section s0v4a +.section s0v4b +.section s0v5a +.section s0v5b +.section s0v6a +.section s0v6b +.section s0v7a +.section s0v7b +.section s0v8a +.section s0v8b +.section s0v9a +.section s0v9b +.section s0v0a +.section s0v0b +.section s0waa +.section s0wab +.section s0wba +.section s0wbb +.section s0wca +.section s0wcb +.section s0wda +.section s0wdb +.section s0wea +.section s0web +.section s0wfa +.section s0wfb +.section s0wga +.section s0wgb +.section s0wha +.section s0whb +.section s0wia +.section s0wib +.section s0wja +.section s0wjb +.section s0wka +.section s0wkb +.section s0wla +.section s0wlb +.section s0wma +.section s0wmb +.section s0wna +.section s0wnb +.section s0woa +.section s0wob +.section s0wpa +.section s0wpb +.section s0wqa +.section s0wqb +.section s0wra +.section s0wrb +.section s0wsa +.section s0wsb +.section s0wta +.section s0wtb +.section s0wua +.section s0wub +.section s0wva +.section s0wvb +.section s0wwa +.section s0wwb +.section s0wxa +.section s0wxb +.section s0wya +.section s0wyb +.section s0wza +.section s0wzb +.section s0w1a +.section s0w1b +.section s0w2a +.section s0w2b +.section s0w3a +.section s0w3b +.section s0w4a +.section s0w4b +.section s0w5a +.section s0w5b +.section s0w6a +.section s0w6b +.section s0w7a +.section s0w7b +.section s0w8a +.section s0w8b +.section s0w9a +.section s0w9b +.section s0w0a +.section s0w0b +.section s0xaa +.section s0xab +.section s0xba +.section s0xbb +.section s0xca +.section s0xcb +.section s0xda +.section s0xdb +.section s0xea +.section s0xeb +.section s0xfa +.section s0xfb +.section s0xga +.section s0xgb +.section s0xha +.section s0xhb +.section s0xia +.section s0xib +.section s0xja +.section s0xjb +.section s0xka +.section s0xkb +.section s0xla +.section s0xlb +.section s0xma +.section s0xmb +.section s0xna +.section s0xnb +.section s0xoa +.section s0xob +.section s0xpa +.section s0xpb +.section s0xqa +.section s0xqb +.section s0xra +.section s0xrb +.section s0xsa +.section s0xsb +.section s0xta +.section s0xtb +.section s0xua +.section s0xub +.section s0xva +.section s0xvb +.section s0xwa +.section s0xwb +.section s0xxa +.section s0xxb +.section s0xya +.section s0xyb +.section s0xza +.section s0xzb +.section s0x1a +.section s0x1b +.section s0x2a +.section s0x2b +.section s0x3a +.section s0x3b +.section s0x4a +.section s0x4b +.section s0x5a +.section s0x5b +.section s0x6a +.section s0x6b +.section s0x7a +.section s0x7b +.section s0x8a +.section s0x8b +.section s0x9a +.section s0x9b +.section s0x0a +.section s0x0b +.section s0yaa +.section s0yab +.section s0yba +.section s0ybb +.section s0yca +.section s0ycb +.section s0yda +.section s0ydb +.section s0yea +.section s0yeb +.section s0yfa +.section s0yfb +.section s0yga +.section s0ygb +.section s0yha +.section s0yhb +.section s0yia +.section s0yib +.section s0yja +.section s0yjb +.section s0yka +.section s0ykb +.section s0yla +.section s0ylb +.section s0yma +.section s0ymb +.section s0yna +.section s0ynb +.section s0yoa +.section s0yob +.section s0ypa +.section s0ypb +.section s0yqa +.section s0yqb +.section s0yra +.section s0yrb +.section s0ysa +.section s0ysb +.section s0yta +.section s0ytb +.section s0yua +.section s0yub +.section s0yva +.section s0yvb +.section s0ywa +.section s0ywb +.section s0yxa +.section s0yxb +.section s0yya +.section s0yyb +.section s0yza +.section s0yzb +.section s0y1a +.section s0y1b +.section s0y2a +.section s0y2b +.section s0y3a +.section s0y3b +.section s0y4a +.section s0y4b +.section s0y5a +.section s0y5b +.section s0y6a +.section s0y6b +.section s0y7a +.section s0y7b +.section s0y8a +.section s0y8b +.section s0y9a +.section s0y9b +.section s0y0a +.section s0y0b +.section s0zaa +.section s0zab +.section s0zba +.section s0zbb +.section s0zca +.section s0zcb +.section s0zda +.section s0zdb +.section s0zea +.section s0zeb +.section s0zfa +.section s0zfb +.section s0zga +.section s0zgb +.section s0zha +.section s0zhb +.section s0zia +.section s0zib +.section s0zja +.section s0zjb +.section s0zka +.section s0zkb +.section s0zla +.section s0zlb +.section s0zma +.section s0zmb +.section s0zna +.section s0znb +.section s0zoa +.section s0zob +.section s0zpa +.section s0zpb +.section s0zqa +.section s0zqb +.section s0zra +.section s0zrb +.section s0zsa +.section s0zsb +.section s0zta +.section s0ztb +.section s0zua +.section s0zub +.section s0zva +.section s0zvb +.section s0zwa +.section s0zwb +.section s0zxa +.section s0zxb +.section s0zya +.section s0zyb +.section s0zza +.section s0zzb +.section s0z1a +.section s0z1b +.section s0z2a +.section s0z2b +.section s0z3a +.section s0z3b +.section s0z4a +.section s0z4b +.section s0z5a +.section s0z5b +.section s0z6a +.section s0z6b +.section s0z7a +.section s0z7b +.section s0z8a +.section s0z8b +.section s0z9a +.section s0z9b +.section s0z0a +.section s0z0b +.section s01aa +.section s01ab +.section s01ba +.section s01bb +.section s01ca +.section s01cb +.section s01da +.section s01db +.section s01ea +.section s01eb +.section s01fa +.section s01fb +.section s01ga +.section s01gb +.section s01ha +.section s01hb +.section s01ia +.section s01ib +.section s01ja +.section s01jb +.section s01ka +.section s01kb +.section s01la +.section s01lb +.section s01ma +.section s01mb +.section s01na +.section s01nb +.section s01oa +.section s01ob +.section s01pa +.section s01pb +.section s01qa +.section s01qb +.section s01ra +.section s01rb +.section s01sa +.section s01sb +.section s01ta +.section s01tb +.section s01ua +.section s01ub +.section s01va +.section s01vb +.section s01wa +.section s01wb +.section s01xa +.section s01xb +.section s01ya +.section s01yb +.section s01za +.section s01zb +.section s011a +.section s011b +.section s012a +.section s012b +.section s013a +.section s013b +.section s014a +.section s014b +.section s015a +.section s015b +.section s016a +.section s016b +.section s017a +.section s017b +.section s018a +.section s018b +.section s019a +.section s019b +.section s010a +.section s010b +.section s02aa +.section s02ab +.section s02ba +.section s02bb +.section s02ca +.section s02cb +.section s02da +.section s02db +.section s02ea +.section s02eb +.section s02fa +.section s02fb +.section s02ga +.section s02gb +.section s02ha +.section s02hb +.section s02ia +.section s02ib +.section s02ja +.section s02jb +.section s02ka +.section s02kb +.section s02la +.section s02lb +.section s02ma +.section s02mb +.section s02na +.section s02nb +.section s02oa +.section s02ob +.section s02pa +.section s02pb +.section s02qa +.section s02qb +.section s02ra +.section s02rb +.section s02sa +.section s02sb +.section s02ta +.section s02tb +.section s02ua +.section s02ub +.section s02va +.section s02vb +.section s02wa +.section s02wb +.section s02xa +.section s02xb +.section s02ya +.section s02yb +.section s02za +.section s02zb +.section s021a +.section s021b +.section s022a +.section s022b +.section s023a +.section s023b +.section s024a +.section s024b +.section s025a +.section s025b +.section s026a +.section s026b +.section s027a +.section s027b +.section s028a +.section s028b +.section s029a +.section s029b +.section s020a +.section s020b +.section s03aa +.section s03ab +.section s03ba +.section s03bb +.section s03ca +.section s03cb +.section s03da +.section s03db +.section s03ea +.section s03eb +.section s03fa +.section s03fb +.section s03ga +.section s03gb +.section s03ha +.section s03hb +.section s03ia +.section s03ib +.section s03ja +.section s03jb +.section s03ka +.section s03kb +.section s03la +.section s03lb +.section s03ma +.section s03mb +.section s03na +.section s03nb +.section s03oa +.section s03ob +.section s03pa +.section s03pb +.section s03qa +.section s03qb +.section s03ra +.section s03rb +.section s03sa +.section s03sb +.section s03ta +.section s03tb +.section s03ua +.section s03ub +.section s03va +.section s03vb +.section s03wa +.section s03wb +.section s03xa +.section s03xb +.section s03ya +.section s03yb +.section s03za +.section s03zb +.section s031a +.section s031b +.section s032a +.section s032b +.section s033a +.section s033b +.section s034a +.section s034b +.section s035a +.section s035b +.section s036a +.section s036b +.section s037a +.section s037b +.section s038a +.section s038b +.section s039a +.section s039b +.section s030a +.section s030b +.section s04aa +.section s04ab +.section s04ba +.section s04bb +.section s04ca +.section s04cb +.section s04da +.section s04db +.section s04ea +.section s04eb +.section s04fa +.section s04fb +.section s04ga +.section s04gb +.section s04ha +.section s04hb +.section s04ia +.section s04ib +.section s04ja +.section s04jb +.section s04ka +.section s04kb +.section s04la +.section s04lb +.section s04ma +.section s04mb +.section s04na +.section s04nb +.section s04oa +.section s04ob +.section s04pa +.section s04pb +.section s04qa +.section s04qb +.section s04ra +.section s04rb +.section s04sa +.section s04sb +.section s04ta +.section s04tb +.section s04ua +.section s04ub +.section s04va +.section s04vb +.section s04wa +.section s04wb +.section s04xa +.section s04xb +.section s04ya +.section s04yb +.section s04za +.section s04zb +.section s041a +.section s041b +.section s042a +.section s042b +.section s043a +.section s043b +.section s044a +.section s044b +.section s045a +.section s045b +.section s046a +.section s046b +.section s047a +.section s047b +.section s048a +.section s048b +.section s049a +.section s049b +.section s040a +.section s040b +.section s05aa +.section s05ab +.section s05ba +.section s05bb +.section s05ca +.section s05cb +.section s05da +.section s05db +.section s05ea +.section s05eb +.section s05fa +.section s05fb +.section s05ga +.section s05gb +.section s05ha +.section s05hb +.section s05ia +.section s05ib +.section s05ja +.section s05jb +.section s05ka +.section s05kb +.section s05la +.section s05lb +.section s05ma +.section s05mb +.section s05na +.section s05nb +.section s05oa +.section s05ob +.section s05pa +.section s05pb +.section s05qa +.section s05qb +.section s05ra +.section s05rb +.section s05sa +.section s05sb +.section s05ta +.section s05tb +.section s05ua +.section s05ub +.section s05va +.section s05vb +.section s05wa +.section s05wb +.section s05xa +.section s05xb +.section s05ya +.section s05yb +.section s05za +.section s05zb +.section s051a +.section s051b +.section s052a +.section s052b +.section s053a +.section s053b +.section s054a +.section s054b +.section s055a +.section s055b +.section s056a +.section s056b +.section s057a +.section s057b +.section s058a +.section s058b +.section s059a +.section s059b +.section s050a +.section s050b +.section s06aa +.section s06ab +.section s06ba +.section s06bb +.section s06ca +.section s06cb +.section s06da +.section s06db +.section s06ea +.section s06eb +.section s06fa +.section s06fb +.section s06ga +.section s06gb +.section s06ha +.section s06hb +.section s06ia +.section s06ib +.section s06ja +.section s06jb +.section s06ka +.section s06kb +.section s06la +.section s06lb +.section s06ma +.section s06mb +.section s06na +.section s06nb +.section s06oa +.section s06ob +.section s06pa +.section s06pb +.section s06qa +.section s06qb +.section s06ra +.section s06rb +.section s06sa +.section s06sb +.section s06ta +.section s06tb +.section s06ua +.section s06ub +.section s06va +.section s06vb +.section s06wa +.section s06wb +.section s06xa +.section s06xb +.section s06ya +.section s06yb +.section s06za +.section s06zb +.section s061a +.section s061b +.section s062a +.section s062b +.section s063a +.section s063b +.section s064a +.section s064b +.section s065a +.section s065b +.section s066a +.section s066b +.section s067a +.section s067b +.section s068a +.section s068b +.section s069a +.section s069b +.section s060a +.section s060b +.section s07aa +.section s07ab +.section s07ba +.section s07bb +.section s07ca +.section s07cb +.section s07da +.section s07db +.section s07ea +.section s07eb +.section s07fa +.section s07fb +.section s07ga +.section s07gb +.section s07ha +.section s07hb +.section s07ia +.section s07ib +.section s07ja +.section s07jb +.section s07ka +.section s07kb +.section s07la +.section s07lb +.section s07ma +.section s07mb +.section s07na +.section s07nb +.section s07oa +.section s07ob +.section s07pa +.section s07pb +.section s07qa +.section s07qb +.section s07ra +.section s07rb +.section s07sa +.section s07sb +.section s07ta +.section s07tb +.section s07ua +.section s07ub +.section s07va +.section s07vb +.section s07wa +.section s07wb +.section s07xa +.section s07xb +.section s07ya +.section s07yb +.section s07za +.section s07zb +.section s071a +.section s071b +.section s072a +.section s072b +.section s073a +.section s073b +.section s074a +.section s074b +.section s075a +.section s075b +.section s076a +.section s076b +.section s077a +.section s077b +.section s078a +.section s078b +.section s079a +.section s079b +.section s070a +.section s070b +.section s08aa +.section s08ab +.section s08ba +.section s08bb +.section s08ca +.section s08cb +.section s08da +.section s08db +.section s08ea +.section s08eb +.section s08fa +.section s08fb +.section s08ga +.section s08gb +.section s08ha +.section s08hb +.section s08ia +.section s08ib +.section s08ja +.section s08jb +.section s08ka +.section s08kb +.section s08la +.section s08lb +.section s08ma +.section s08mb +.section s08na +.section s08nb +.section s08oa +.section s08ob +.section s08pa +.section s08pb +.section s08qa +.section s08qb +.section s08ra +.section s08rb +.section s08sa +.section s08sb +.section s08ta +.section s08tb +.section s08ua +.section s08ub +.section s08va +.section s08vb +.section s08wa +.section s08wb +.section s08xa +.section s08xb +.section s08ya +.section s08yb +.section s08za +.section s08zb +.section s081a +.section s081b +.section s082a +.section s082b +.section s083a +.section s083b +.section s084a +.section s084b +.section s085a +.section s085b +.section s086a +.section s086b +.section s087a +.section s087b +.section s088a +.section s088b +.section s089a +.section s089b +.section s080a +.section s080b +.section s09aa +.section s09ab +.section s09ba +.section s09bb +.section s09ca +.section s09cb +.section s09da +.section s09db +.section s09ea +.section s09eb +.section s09fa +.section s09fb +.section s09ga +.section s09gb +.section s09ha +.section s09hb +.section s09ia +.section s09ib +.section s09ja +.section s09jb +.section s09ka +.section s09kb +.section s09la +.section s09lb +.section s09ma +.section s09mb +.section s09na +.section s09nb +.section s09oa +.section s09ob +.section s09pa +.section s09pb +.section s09qa +.section s09qb +.section s09ra +.section s09rb +.section s09sa +.section s09sb +.section s09ta +.section s09tb +.section s09ua +.section s09ub +.section s09va +.section s09vb +.section s09wa +.section s09wb +.section s09xa +.section s09xb +.section s09ya +.section s09yb +.section s09za +.section s09zb +.section s091a +.section s091b +.section s092a +.section s092b +.section s093a +.section s093b +.section s094a +.section s094b +.section s095a +.section s095b +.section s096a +.section s096b +.section s097a +.section s097b +.section s098a +.section s098b +.section s099a +.section s099b +.section s090a +.section s090b +.section s00aa +.section s00ab +.section s00ba +.section s00bb +.section s00ca +.section s00cb +.section s00da +.section s00db +.section s00ea +.section s00eb +.section s00fa +.section s00fb +.section s00ga +.section s00gb +.section s00ha +.section s00hb +.section s00ia +.section s00ib +.section s00ja +.section s00jb +.section s00ka +.section s00kb +.section s00la +.section s00lb +.section s00ma +.section s00mb +.section s00na +.section s00nb +.section s00oa +.section s00ob +.section s00pa +.section s00pb +.section s00qa +.section s00qb +.section s00ra +.section s00rb +.section s00sa +.section s00sb +.section s00ta +.section s00tb +.section s00ua +.section s00ub +.section s00va +.section s00vb +.section s00wa +.section s00wb +.section s00xa +.section s00xb +.section s00ya +.section s00yb +.section s00za +.section s00zb +.section s001a +.section s001b +.section s002a +.section s002b +.section s003a +.section s003b +.section s004a +.section s004b +.section s005a +.section s005b +.section s006a +.section s006b +.section s007a +.section s007b +.section s008a +.section s008b +.section s009a +.section s009b +.section s000a +.section s000b diff --git a/test/MC/ELF/merge.s b/test/MC/ELF/merge.s index befc2bfc0b52..11a80ad0350d 100644 --- a/test/MC/ELF/merge.s +++ b/test/MC/ELF/merge.s @@ -32,7 +32,7 @@ foo: // CHECK-NEXT: ), // Relocation 1 refers to symbol 6 -// CHECK-NEXT: # Relocation 0x00000001 +// CHECK-NEXT: # Relocation 1 // CHECK-NEXT: (('r_offset', // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x0000000a) @@ -40,7 +40,7 @@ foo: // CHECK-NEXT: ), // Relocation 2 refers to symbol 1 -// CHECK-NEXT: # Relocation 0x00000002 +// CHECK-NEXT: # Relocation 2 // CHECK-NEXT: (('r_offset', // CHECK-NEXT: ('r_sym', 0x00000001) // CHECK-NEXT: ('r_type', 0x0000000a @@ -48,7 +48,7 @@ foo: // CHECK-NEXT: ), // Relocation 3 refers to symbol 2 -// CHECK-NEXT: # Relocation 0x00000003 +// CHECK-NEXT: # Relocation 3 // CHECK-NEXT: (('r_offset', // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000004 @@ -56,7 +56,7 @@ foo: // CHECK-NEXT: ), // Relocation 4 refers to symbol 2 -// CHECK-NEXT: # Relocation 0x00000004 +// CHECK-NEXT: # Relocation 4 // CHECK-NEXT: (('r_offset', // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x00000009 @@ -64,34 +64,34 @@ foo: // CHECK-NEXT: ), // Relocation 5 refers to symbol 8 -// CHECK-NEXT: # Relocation 0x00000005 -// CHECK-NEXT: (('r_offset', 0x00000023) +// CHECK-NEXT: # Relocation 5 +// CHECK-NEXT: (('r_offset', 0x0000000000000023) // CHECK-NEXT: ('r_sym', 0x00000008) // CHECK-NEXT: ('r_type', 0x0000000b) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // Section 5 is "sec1" -// CHECK: # Section 0x00000005 +// CHECK: # Section 5 // CHECK-NEXT: (('sh_name', 0x00000035) # '.sec1' // Symbol number 1 is .Lfoo -// CHECK: # Symbol 0x00000001 +// CHECK: # Symbol 1 // CHECK-NEXT: (('st_name', 0x00000001) # '.Lfoo' // Symbol number 2 is foo -// CHECK: # Symbol 0x00000002 +// CHECK: # Symbol 2 // CHECK-NEXT: (('st_name', 0x00000007) # 'foo' // Symbol number 6 is section 5 -// CHECK: # Symbol 0x00000006 +// CHECK: # Symbol 6 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000005) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x3) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0005) // Symbol number 8 is zed -// CHECK: # Symbol 0x00000008 +// CHECK: # Symbol 8 // CHECK-NEXT: (('st_name', 0x0000000b) # 'zed' diff --git a/test/MC/ELF/n_bytes.s b/test/MC/ELF/n_bytes.s index 59d67bfa71f5..de6632232c06 100644 --- a/test/MC/ELF/n_bytes.s +++ b/test/MC/ELF/n_bytes.s @@ -5,16 +5,16 @@ .8byte 42, 1, 2, 3 .int 42, 1, 2, 3 -// CHECK: # Section 0x00000001 +// CHECK: # Section 1 // CHECK-NEXT: (('sh_name', 0x00000001) # '.text' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000006) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x00000048) +// CHECK-NEXT: ('sh_flags', 0x0000000000000006) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x0000000000000048) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', '2a000100 02000300 2a000000 01000000 02000000 03000000 2a000000 00000000 01000000 00000000 02000000 00000000 03000000 00000000 2a000000 01000000 02000000 03000000') // CHECK-NEXT: ), diff --git a/test/MC/ELF/noexec.s b/test/MC/ELF/noexec.s index c4b7d9851b93..d8b7b3233864 100644 --- a/test/MC/ELF/noexec.s +++ b/test/MC/ELF/noexec.s @@ -1,24 +1,24 @@ // RUN: llvm-mc -mc-no-exec-stack -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump | FileCheck %s -// CHECK: # Section 0x00000004 +// CHECK: # Section 4 // CHECK-NEXT: (('sh_name', 0x0000000c) # '.note.GNU-stack' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x0000000000000000) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK: # Symbol 0x00000004 +// CHECK: # Symbol 4 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000004) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x3) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0004) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/norelocation.s b/test/MC/ELF/norelocation.s index 0a0efe1ed6d6..c6394791ad80 100644 --- a/test/MC/ELF/norelocation.s +++ b/test/MC/ELF/norelocation.s @@ -5,14 +5,14 @@ bar: // CHECK: ('sh_name', 0x00000001) # '.text' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000006) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x00000005) +// CHECK-NEXT: ('sh_flags', 0x0000000000000006) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x0000000000000005) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', 'e8000000 00') // CHECK-NOT: .rela.text // CHECK: shstrtab diff --git a/test/MC/ELF/org.s b/test/MC/ELF/org.s index c073fa5d808e..3afc364b2102 100644 --- a/test/MC/ELF/org.s +++ b/test/MC/ELF/org.s @@ -10,4 +10,4 @@ foo: // CHECK-NEXT: ('sh_flags', // CHECK-NEXT: ('sh_addr', // CHECK-NEXT: ('sh_offset' -// CHECK-NEXT: ('sh_size', 0x00000014) +// CHECK-NEXT: ('sh_size', 0x0000000000000014) diff --git a/test/MC/ELF/pic-diff.s b/test/MC/ELF/pic-diff.s index c2f96c250639..2c68f6cc718a 100644 --- a/test/MC/ELF/pic-diff.s +++ b/test/MC/ELF/pic-diff.s @@ -1,20 +1,20 @@ // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump | FileCheck %s // CHECK: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x0000000c) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x000000000000000c) // CHECK-NEXT: ('r_sym', 0x00000005) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000008) +// CHECK-NEXT: ('r_addend', 0x0000000000000008) // CHECK-NEXT: ), // CHECK-NEXT: ]) -// CHECK: # Symbol 0x00000005 +// CHECK: # Symbol 5 // CHECK-NEXT: (('st_name', 0x00000005) # 'baz' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/plt.s b/test/MC/ELF/plt.s index 7d0073c400d6..7d78e23443e7 100644 --- a/test/MC/ELF/plt.s +++ b/test/MC/ELF/plt.s @@ -5,7 +5,7 @@ jmp foo@PLT // CHECK: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 +// CHECK-NEXT: # Relocation 0 // CHECK-NEXT: (('r_offset', // CHECK-NEXT: ('r_sym', // CHECK-NEXT: ('r_type', 0x00000004) diff --git a/test/MC/ELF/pr9292.s b/test/MC/ELF/pr9292.s index a198fed87949..05f377faa71c 100644 --- a/test/MC/ELF/pr9292.s +++ b/test/MC/ELF/pr9292.s @@ -8,19 +8,19 @@ mov %eax,bar // CHECK: (('st_name', 0x00000005) # 'bar' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000005 +// CHECK-NEXT: # Symbol 5 // CHECK-NEXT: (('st_name', 0x00000001) # 'foo' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/relax.s b/test/MC/ELF/relax.s index 2c0e285db597..0b5d24f0f7ff 100644 --- a/test/MC/ELF/relax.s +++ b/test/MC/ELF/relax.s @@ -13,15 +13,15 @@ foo: // CHECK: ('sh_name', 0x00000001) # '.text' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000006) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x00000006) +// CHECK-NEXT: ('sh_flags', 0x0000000000000006) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x0000000000000006) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ('_section_data', 'ebfeebfc ebfa') -// CHECK: # Symbol 0x00000006 +// CHECK: # Symbol 6 // CHECK-NEXT: (('st_name', 0x00000005) # 'foo' diff --git a/test/MC/ELF/relocation-386.s b/test/MC/ELF/relocation-386.s index 25f3450d44d9..442176307fa4 100644 --- a/test/MC/ELF/relocation-386.s +++ b/test/MC/ELF/relocation-386.s @@ -3,190 +3,190 @@ // Test that we produce the correct relocation types and that the relocations // correctly point to the section or the symbol. -// CHECK: # Relocation 0x00000000 +// CHECK: # Relocation 0 // CHECK-NEXT: (('r_offset', 0x00000002) -// CHECK-NEXT: ('r_sym', 0x00000001) -// CHECK-NEXT: ('r_type', 0x00000009) +// CHECK-NEXT: ('r_sym', 0x000001) +// CHECK-NEXT: ('r_type', 0x09) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000001 +// CHECK-NEXT: # Relocation 1 // CHECK-NEXT: (('r_offset', // CHECK-NEXT: ('r_sym', -// CHECK-NEXT: ('r_type', 0x00000004) +// CHECK-NEXT: ('r_type', 0x04) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000002 +// CHECK-NEXT: # Relocation 2 // CHECK-NEXT: (('r_offset', // CHECK-NEXT: ('r_sym', -// CHECK-NEXT: ('r_type', 0x0000000a) +// CHECK-NEXT: ('r_type', 0x0a) // CHECK-NEXT: ), // Relocation 3 (bar3@GOTOFF) is done with symbol 7 (bss) -// CHECK-NEXT: # Relocation 0x00000003 +// CHECK-NEXT: # Relocation 3 // CHECK-NEXT: (('r_offset', -// CHECK-NEXT: ('r_sym', 0x00000007 +// CHECK-NEXT: ('r_sym', 0x000007 // CHECK-NEXT: ('r_type', // CHECK-NEXT: ), // Relocation 4 (bar2@GOT) is of type R_386_GOT32 -// CHECK-NEXT: # Relocation 0x00000004 +// CHECK-NEXT: # Relocation 4 // CHECK-NEXT: (('r_offset', // CHECK-NEXT: ('r_sym', -// CHECK-NEXT: ('r_type', 0x00000003 +// CHECK-NEXT: ('r_type', 0x03 // CHECK-NEXT: ), // Relocation 5 (foo@TLSGD) is of type R_386_TLS_GD -// CHECK-NEXT: # Relocation 0x00000005 +// CHECK-NEXT: # Relocation 5 // CHECK-NEXT: (('r_offset', 0x00000020) -// CHECK-NEXT: ('r_sym', 0x0000000d) -// CHECK-NEXT: ('r_type', 0x00000012) +// CHECK-NEXT: ('r_sym', 0x00000d) +// CHECK-NEXT: ('r_type', 0x12) // CHECK-NEXT: ), // Relocation 6 ($foo@TPOFF) is of type R_386_TLS_LE_32 -// CHECK-NEXT: # Relocation 0x00000006 +// CHECK-NEXT: # Relocation 6 // CHECK-NEXT: (('r_offset', 0x00000025) -// CHECK-NEXT: ('r_sym', 0x0000000d) -// CHECK-NEXT: ('r_type', 0x00000022) +// CHECK-NEXT: ('r_sym', 0x00000d) +// CHECK-NEXT: ('r_type', 0x22) // CHECK-NEXT: ), // Relocation 7 (foo@INDNTPOFF) is of type R_386_TLS_IE -// CHECK-NEXT: # Relocation 0x00000007 +// CHECK-NEXT: # Relocation 7 // CHECK-NEXT: (('r_offset', 0x0000002b) -// CHECK-NEXT: ('r_sym', 0x0000000d) -// CHECK-NEXT: ('r_type', 0x0000000f) +// CHECK-NEXT: ('r_sym', 0x00000d) +// CHECK-NEXT: ('r_type', 0x0f) // CHECK-NEXT: ), // Relocation 8 (foo@NTPOFF) is of type R_386_TLS_LE -// CHECK-NEXT: # Relocation 0x00000008 +// CHECK-NEXT: # Relocation 8 // CHECK-NEXT: (('r_offset', 0x00000031) -// CHECK-NEXT: ('r_sym', 0x0000000d) -// CHECK-NEXT: ('r_type', 0x00000011) +// CHECK-NEXT: ('r_sym', 0x00000d) +// CHECK-NEXT: ('r_type', 0x11) // CHECK-NEXT: ), // Relocation 9 (foo@GOTNTPOFF) is of type R_386_TLS_GOTIE -// CHECK-NEXT: # Relocation 0x00000009 +// CHECK-NEXT: # Relocation 9 // CHECK-NEXT: (('r_offset', 0x00000037) -// CHECK-NEXT: ('r_sym', 0x0000000d) -// CHECK-NEXT: ('r_type', 0x00000010) +// CHECK-NEXT: ('r_sym', 0x00000d) +// CHECK-NEXT: ('r_type', 0x10) // CHECK-NEXT: ), // Relocation 10 (foo@TLSLDM) is of type R_386_TLS_LDM -// CHECK-NEXT: # Relocation 0x0000000a +// CHECK-NEXT: # Relocation 10 // CHECK-NEXT: (('r_offset', 0x0000003d) -// CHECK-NEXT: ('r_sym', 0x0000000d) -// CHECK-NEXT: ('r_type', 0x00000013) +// CHECK-NEXT: ('r_sym', 0x00000d) +// CHECK-NEXT: ('r_type', 0x13) // CHECK-NEXT: ), // Relocation 11 (foo@DTPOFF) is of type R_386_TLS_LDO_32 -// CHECK-NEXT: # Relocation 0x0000000b +// CHECK-NEXT: # Relocation 11 // CHECK-NEXT: (('r_offset', 0x00000043) -// CHECK-NEXT: ('r_sym', 0x0000000d) -// CHECK-NEXT: ('r_type', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x00000d) +// CHECK-NEXT: ('r_type', 0x20) // CHECK-NEXT: ), // Relocation 12 (calll 4096) is of type R_386_PC32 -// CHECK-NEXT: # Relocation 0x0000000c +// CHECK-NEXT: # Relocation 12 // CHECK-NEXT: (('r_offset', 0x00000048) -// CHECK-NEXT: ('r_sym', 0x00000000) -// CHECK-NEXT: ('r_type', 0x00000002) +// CHECK-NEXT: ('r_sym', 0x000000) +// CHECK-NEXT: ('r_type', 0x02) // CHECK-NEXT: ), // Relocation 13 (zed@GOT) is of type R_386_GOT32 and uses the symbol -// CHECK-NEXT: # Relocation 0x0000000d +// CHECK-NEXT: # Relocation 13 // CHECK-NEXT: (('r_offset', 0x0000004e) -// CHECK-NEXT: ('r_sym', 0x00000004) -// CHECK-NEXT: ('r_type', 0x00000003) +// CHECK-NEXT: ('r_sym', 0x000004) +// CHECK-NEXT: ('r_type', 0x03) // CHECK-NEXT: ), // Relocation 14 (zed@GOTOFF) is of type R_386_GOTOFF and uses the symbol -// CHECK-NEXT: # Relocation 0x0000000e +// CHECK-NEXT: # Relocation 14 // CHECK-NEXT: (('r_offset', 0x00000054) -// CHECK-NEXT: ('r_sym', 0x00000004) -// CHECK-NEXT: ('r_type', 0x00000009) +// CHECK-NEXT: ('r_sym', 0x000004) +// CHECK-NEXT: ('r_type', 0x09) // CHECK-NEXT: ), // Relocation 15 (zed@INDNTPOFF) is of type R_386_TLS_IE and uses the symbol -// CHECK-NEXT: # Relocation 0x0000000f +// CHECK-NEXT: # Relocation 15 // CHECK-NEXT: (('r_offset', 0x0000005a) -// CHECK-NEXT: ('r_sym', 0x00000004) -// CHECK-NEXT: ('r_type', 0x0000000f) +// CHECK-NEXT: ('r_sym', 0x000004) +// CHECK-NEXT: ('r_type', 0x0f) // CHECK-NEXT: ), // Relocation 16 (zed@NTPOFF) is of type R_386_TLS_LE and uses the symbol -// CHECK-NEXT: # Relocation 0x00000010 +// CHECK-NEXT: # Relocation 16 // CHECK-NEXT: (('r_offset', 0x00000060) -// CHECK-NEXT: ('r_sym', 0x00000004) -// CHECK-NEXT: ('r_type', 0x00000011) +// CHECK-NEXT: ('r_sym', 0x000004) +// CHECK-NEXT: ('r_type', 0x11) // CHECK-NEXT: ), // Relocation 17 (zed@GOTNTPOFF) is of type R_386_TLS_GOTIE and uses the symbol -// CHECK-NEXT: # Relocation 0x00000011 +// CHECK-NEXT: # Relocation 17 // CHECK-NEXT: (('r_offset', 0x00000066) -// CHECK-NEXT: ('r_sym', 0x00000004) -// CHECK-NEXT: ('r_type', 0x00000010) +// CHECK-NEXT: ('r_sym', 0x000004) +// CHECK-NEXT: ('r_type', 0x10) // CHECK-NEXT: ), // Relocation 18 (zed@PLT) is of type R_386_PLT32 and uses the symbol -// CHECK-NEXT: # Relocation 0x00000012 +// CHECK-NEXT: # Relocation 18 // CHECK-NEXT: (('r_offset', 0x0000006b) -// CHECK-NEXT: ('r_sym', 0x00000004) -// CHECK-NEXT: ('r_type', 0x00000004) +// CHECK-NEXT: ('r_sym', 0x000004) +// CHECK-NEXT: ('r_type', 0x04) // CHECK-NEXT: ), // Relocation 19 (zed@TLSGD) is of type R_386_TLS_GD and uses the symbol -// CHECK-NEXT: # Relocation 0x00000013 +// CHECK-NEXT: # Relocation 19 // CHECK-NEXT: (('r_offset', 0x00000071) -// CHECK-NEXT: ('r_sym', 0x00000004) -// CHECK-NEXT: ('r_type', 0x00000012) +// CHECK-NEXT: ('r_sym', 0x000004) +// CHECK-NEXT: ('r_type', 0x12) // CHECK-NEXT: ), // Relocation 20 (zed@TLSLDM) is of type R_386_TLS_LDM and uses the symbol -// CHECK-NEXT: # Relocation 0x00000014 +// CHECK-NEXT: # Relocation 20 // CHECK-NEXT: (('r_offset', 0x00000077) -// CHECK-NEXT: ('r_sym', 0x00000004) -// CHECK-NEXT: ('r_type', 0x00000013) +// CHECK-NEXT: ('r_sym', 0x000004) +// CHECK-NEXT: ('r_type', 0x13) // CHECK-NEXT: ), // Relocation 21 (zed@TPOFF) is of type R_386_TLS_LE_32 and uses the symbol -// CHECK-NEXT:# Relocation 0x00000015 +// CHECK-NEXT:# Relocation 21 // CHECK-NEXT: (('r_offset', 0x0000007d) -// CHECK-NEXT: ('r_sym', 0x00000004) -// CHECK-NEXT: ('r_type', 0x00000022) +// CHECK-NEXT: ('r_sym', 0x000004) +// CHECK-NEXT: ('r_type', 0x22) // CHECK-NEXT: ), // Relocation 22 (zed@DTPOFF) is of type R_386_TLS_LDO_32 and uses the symbol -// CHECK-NEXT: Relocation 0x00000016 +// CHECK-NEXT: Relocation 22 // CHECK-NEXT: (('r_offset', 0x00000083) -// CHECK-NEXT: ('r_sym', 0x00000004) -// CHECK-NEXT: ('r_type', 0x00000020) +// CHECK-NEXT: ('r_sym', 0x000004) +// CHECK-NEXT: ('r_type', 0x20) // CHECK-NEXT: ), // Relocation 23 ($bar) is of type R_386_32 and uses the section -// CHECK-NEXT: Relocation 0x00000017 +// CHECK-NEXT: Relocation 23 // CHECK-NEXT: (('r_offset', // CHECK-NEXT: ('r_sym', -// CHECK-NEXT: ('r_type', 0x00000001) +// CHECK-NEXT: ('r_type', 0x01) // CHECK-NEXT: ), // Relocation 24 (foo@GOTTPOFF(%edx)) is of type R_386_TLS_IE_32 and uses the // symbol -// CHECK-NEXT: Relocation 0x00000018 +// CHECK-NEXT: Relocation 24 // CHECK-NEXT: (('r_offset', 0x0000008e) -// CHECK-NEXT: ('r_sym', 0x0000000d) -// CHECK-NEXT: ('r_type', 0x00000021) +// CHECK-NEXT: ('r_sym', 0x00000d) +// CHECK-NEXT: ('r_type', 0x21) // CHECK-NEXT: ), // Section 4 is bss -// CHECK: # Section 0x00000004 +// CHECK: # Section 4 // CHECK-NEXT: (('sh_name', 0x0000000b) # '.bss' -// CHECK: # Symbol 0x00000001 +// CHECK: # Symbol 1 // CHECK-NEXT: (('st_name', 0x00000005) # '.Lfoo' // Symbol 4 is zed -// CHECK: # Symbol 0x00000004 +// CHECK: # Symbol 4 // CHECK-NEXT: (('st_name', 0x00000035) # 'zed' // CHECK-NEXT: ('st_value', 0x00000000) // CHECK-NEXT: ('st_size', 0x00000000) -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000005) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x6) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0005) // Symbol 7 is section 4 -// CHECK: # Symbol 0x00000007 +// CHECK: # Symbol 7 // CHECK-NEXT: (('st_name', 0x00000000) # '' // CHECK-NEXT: ('st_value', 0x00000000) // CHECK-NEXT: ('st_size', 0x00000000) -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000004) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x3) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0004) .text diff --git a/test/MC/ELF/relocation-pc.s b/test/MC/ELF/relocation-pc.s index 36212cb7232a..b6279c3e55dd 100644 --- a/test/MC/ELF/relocation-pc.s +++ b/test/MC/ELF/relocation-pc.s @@ -5,29 +5,29 @@ loope 0 # R_X86_64_PC8 jmp -256 # R_X86_64_PC32 -// CHECK: # Section 0x00000002 +// CHECK: # Section 2 // CHECK-NEXT: (('sh_name', 0x00000001) # '.rela.text' // CHECK-NEXT: ('sh_type', 0x00000004) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x000002e8) -// CHECK-NEXT: ('sh_size', 0x00000030) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x00000000000002e8) +// CHECK-NEXT: ('sh_size', 0x0000000000000030) // CHECK-NEXT: ('sh_link', 0x00000006) // CHECK-NEXT: ('sh_info', 0x00000001) -// CHECK-NEXT: ('sh_addralign', 0x00000008) -// CHECK-NEXT: ('sh_entsize', 0x00000018) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000008) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000018) // CHECK-NEXT: ('_relocations', [ -// CHECK-NEXT: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000001) +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000001) // CHECK-NEXT: ('r_sym', 0x00000000) // CHECK-NEXT: ('r_type', 0x0000000f) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000001 -// CHECK-NEXT: (('r_offset', 0x00000003) +// CHECK-NEXT: # Relocation 1 +// CHECK-NEXT: (('r_offset', 0x0000000000000003) // CHECK-NEXT: ('r_sym', 0x00000000) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT: ]) // CHECK-NEXT: ), diff --git a/test/MC/ELF/relocation.s b/test/MC/ELF/relocation.s index 2760232a5a80..5db213bc0497 100644 --- a/test/MC/ELF/relocation.s +++ b/test/MC/ELF/relocation.s @@ -20,102 +20,102 @@ bar: addq $bar,%rax # R_X86_64_32S -// CHECK: # Section 0x00000001 +// CHECK: # Section 1 // CHECK: (('sh_name', 0x00000006) # '.text' -// CHECK: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000001) +// CHECK: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000001) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', -// CHECK: # Relocation 0x00000001 -// CHECK-NEXT: (('r_offset', 0x00000008) +// CHECK: # Relocation 1 +// CHECK-NEXT: (('r_offset', 0x0000000000000008) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x0000000b) // CHECK-NEXT: ('r_addend', -// CHECK: # Relocation 0x00000002 -// CHECK-NEXT: (('r_offset', 0x00000013) +// CHECK: # Relocation 2 +// CHECK-NEXT: (('r_offset', 0x0000000000000013) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x0000000b) // CHECK-NEXT: ('r_addend', -// CHECK: # Relocation 0x00000003 -// CHECK-NEXT: (('r_offset', 0x0000001a) +// CHECK: # Relocation 3 +// CHECK-NEXT: (('r_offset', 0x000000000000001a) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x0000000b) // CHECK-NEXT: ('r_addend', -// CHECK: # Relocation 0x00000004 -// CHECK-NEXT: (('r_offset', 0x00000022) +// CHECK: # Relocation 4 +// CHECK-NEXT: (('r_offset', 0x0000000000000022) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x0000000b) // CHECK-NEXT: ('r_addend', -// CHECK: # Relocation 0x00000005 -// CHECK-NEXT: (('r_offset', 0x00000026) +// CHECK: # Relocation 5 +// CHECK-NEXT: (('r_offset', 0x0000000000000026) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', -// CHECK: # Relocation 0x00000006 -// CHECK-NEXT: (('r_offset', 0x0000002d) +// CHECK: # Relocation 6 +// CHECK-NEXT: (('r_offset', 0x000000000000002d) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x00000016) -// CHECK-NEXT: ('r_addend', 0xfffffffc) +// CHECK-NEXT: ('r_addend', 0xfffffffffffffffc) -// CHECK: # Relocation 0x00000007 -// CHECK-NEXT: (('r_offset', 0x00000034) +// CHECK: # Relocation 7 +// CHECK-NEXT: (('r_offset', 0x0000000000000034) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x00000013) -// CHECK-NEXT: ('r_addend', 0xfffffffc) +// CHECK-NEXT: ('r_addend', 0xfffffffffffffffc) -// CHECK: # Relocation 0x00000008 -// CHECK-NEXT: (('r_offset', 0x0000003b) +// CHECK: # Relocation 8 +// CHECK-NEXT: (('r_offset', 0x000000000000003b) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x00000017) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) -// CHECK: # Relocation 0x00000009 -// CHECK-NEXT: (('r_offset', 0x00000042) +// CHECK: # Relocation 9 +// CHECK-NEXT: (('r_offset', 0x0000000000000042) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x00000014) -// CHECK-NEXT: ('r_addend', 0xfffffffc) +// CHECK-NEXT: ('r_addend', 0xfffffffffffffffc) -// CHECK: # Relocation 0x0000000a -// CHECK-NEXT: (('r_offset', 0x00000049) +// CHECK: # Relocation 10 +// CHECK-NEXT: (('r_offset', 0x0000000000000049) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x00000015) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) -// CHECK: # Relocation 0x0000000b -// CHECK-NEXT: (('r_offset', 0x0000004e) +// CHECK: # Relocation 11 +// CHECK-NEXT: (('r_offset', 0x000000000000004e) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x0000000b) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) -// CHECK: # Relocation 0x0000000c -// CHECK-NEXT: (('r_offset', 0x00000055) +// CHECK: # Relocation 12 +// CHECK-NEXT: (('r_offset', 0x0000000000000055) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0xfffffffc) +// CHECK-NEXT: ('r_addend', 0xfffffffffffffffc) -// CHECK: # Relocation 0x0000000d -// CHECK-NEXT: (('r_offset', 0x0000005c) +// CHECK: # Relocation 13 +// CHECK-NEXT: (('r_offset', 0x000000000000005c) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0x0000005c) +// CHECK-NEXT: ('r_addend', 0x000000000000005c) -// CHECK: # Relocation 0x0000000e -// CHECK-NEXT: (('r_offset', 0x00000063) +// CHECK: # Relocation 14 +// CHECK-NEXT: (('r_offset', 0x0000000000000063) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x0000000b) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) -// CHECK: # Symbol 0x00000002 +// CHECK: # Symbol 2 // CHECK: (('st_name', 0x00000000) # '' -// CHECK: ('st_bind', 0x00000000) -// CHECK: ('st_type', 0x00000003) -// CHECK: ('st_other', 0x00000000) -// CHECK: ('st_shndx', 0x00000001) +// CHECK: ('st_bind', 0x0) +// CHECK: ('st_type', 0x3) +// CHECK: ('st_other', 0x00) +// CHECK: ('st_shndx', 0x0001) diff --git a/test/MC/ELF/rename.s b/test/MC/ELF/rename.s index e7cedd0afb47..241aa05ecbde 100644 --- a/test/MC/ELF/rename.s +++ b/test/MC/ELF/rename.s @@ -16,31 +16,31 @@ defined3: .global defined1 // Section 1 is .text -// CHECK: # Section 0x00000001 +// CHECK: # Section 1 // CHECK-NEXT: (('sh_name', 0x00000006) # '.text' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000006) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000040) -// CHECK-NEXT: ('sh_size', 0x00000004) +// CHECK-NEXT: ('sh_flags', 0x0000000000000006) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000040) +// CHECK-NEXT: ('sh_size', 0x0000000000000004) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000004) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000004) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // The relocation uses symbol 2 -// CHECK: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000000) +// CHECK: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000000) // CHECK-NEXT: ('r_sym', 0x00000002) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // Symbol 2 is section 1 -// CHECK: # Symbol 0x00000002 +// CHECK: # Symbol 2 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x3) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) diff --git a/test/MC/ELF/section.s b/test/MC/ELF/section.s index 5fb5525cba64..c71e1a72c471 100644 --- a/test/MC/ELF/section.s +++ b/test/MC/ELF/section.s @@ -21,63 +21,63 @@ // CHECK: (('sh_name', 0x00000012) # '.init' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000006) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000050) -// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000006) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000050) +// CHECK-NEXT: ('sh_size', 0x0000000000000000) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Section 0x0000000b +// CHECK-NEXT: # Section 11 // CHECK-NEXT: (('sh_name', 0x00000048) # '.fini' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000006) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000050) -// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000006) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000050) +// CHECK-NEXT: ('sh_size', 0x0000000000000000) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Section 0x0000000c +// CHECK-NEXT: # Section 12 // CHECK-NEXT: (('sh_name', 0x00000076) # '.rodata' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000050) -// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000050) +// CHECK-NEXT: ('sh_size', 0x0000000000000000) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Section 0x0000000d +// CHECK-NEXT: # Section 13 // CHECK-NEXT: (('sh_name', 0x00000058) # 'zed' // CHECK-NEXT: ('sh_type', 0x00000001) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000050) -// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000050) +// CHECK-NEXT: ('sh_size', 0x0000000000000000) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ), .section .note.test,"",@note // CHECK: (('sh_name', 0x00000007) # '.note.test' // CHECK-NEXT: ('sh_type', 0x00000007) -// CHECK-NEXT: ('sh_flags', 0x00000000) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000050) -// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000000) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000050) +// CHECK-NEXT: ('sh_size', 0x0000000000000000) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ), // Test that we can parse these @@ -92,14 +92,14 @@ bar: // CHECK: (('sh_name', 0x0000004e) # '.eh_frame' // CHECK-NEXT: ('sh_type', 0x70000001) -// CHECK-NEXT: ('sh_flags', 0x00000002) -// CHECK-NEXT: ('sh_addr', 0x00000000) -// CHECK-NEXT: ('sh_offset', 0x00000050) -// CHECK-NEXT: ('sh_size', 0x00000000) +// CHECK-NEXT: ('sh_flags', 0x0000000000000002) +// CHECK-NEXT: ('sh_addr', 0x0000000000000000) +// CHECK-NEXT: ('sh_offset', 0x0000000000000050) +// CHECK-NEXT: ('sh_size', 0x0000000000000000) // CHECK-NEXT: ('sh_link', 0x00000000) // CHECK-NEXT: ('sh_info', 0x00000000) -// CHECK-NEXT: ('sh_addralign', 0x00000001) -// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x0000000000000001) +// CHECK-NEXT: ('sh_entsize', 0x0000000000000000) // CHECK-NEXT: ), // Test that we handle the strings like gas diff --git a/test/MC/ELF/set.s b/test/MC/ELF/set.s index 69d6c910636f..2258b1923678 100644 --- a/test/MC/ELF/set.s +++ b/test/MC/ELF/set.s @@ -5,10 +5,10 @@ .set kernbase,0xffffffff80000000 // CHECK: (('st_name', 0x00000001) # 'kernbase' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x0000fff1) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0xfff1) // CHECK-NEXT: ('st_value', 0xffffffff80000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), @@ -25,10 +25,10 @@ // Test that there is an undefined reference to bar // CHECK: (('st_name', 0x0000000a) # 'bar' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/symref.s b/test/MC/ELF/symref.s index d945c826d74f..2dfa058ab086 100644 --- a/test/MC/ELF/symref.s +++ b/test/MC/ELF/symref.s @@ -22,143 +22,143 @@ defined3: global1: -// CHECK: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000000) +// CHECK: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000000) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000001 -// CHECK-NEXT: (('r_offset', 0x00000004) +// CHECK-NEXT: # Relocation 1 +// CHECK-NEXT: (('r_offset', 0x0000000000000004) // CHECK-NEXT: ('r_sym', 0x0000000b) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000002 -// CHECK-NEXT: (('r_offset', 0x00000008) +// CHECK-NEXT: # Relocation 2 +// CHECK-NEXT: (('r_offset', 0x0000000000000008) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000003 -// CHECK-NEXT: (('r_offset', 0x0000000c) +// CHECK-NEXT: # Relocation 3 +// CHECK-NEXT: (('r_offset', 0x000000000000000c) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000004 -// CHECK-NEXT: (('r_offset', 0x00000010) +// CHECK-NEXT: # Relocation 4 +// CHECK-NEXT: (('r_offset', 0x0000000000000010) // CHECK-NEXT: ('r_sym', 0x0000000c) // CHECK-NEXT: ('r_type', 0x0000000a) -// CHECK-NEXT: ('r_addend', 0x00000000) +// CHECK-NEXT: ('r_addend', 0x0000000000000000) // CHECK-NEXT: ), // CHECK-NEXT:]) -// CHECK: # Symbol 0x00000001 +// CHECK: # Symbol 1 // CHECK-NEXT: (('st_name', 0x00000013) # 'bar1@zed' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000002 +// CHECK-NEXT: # Symbol 2 // CHECK-NEXT: (('st_name', 0x00000025) # 'bar3@@zed' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000003 +// CHECK-NEXT: # Symbol 3 // CHECK-NEXT: (('st_name', 0x0000002f) # 'bar5@@zed' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000004 +// CHECK-NEXT: # Symbol 4 // CHECK-NEXT: (('st_name', 0x00000001) # 'defined1' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000005 +// CHECK-NEXT: # Symbol 5 // CHECK-NEXT: (('st_name', 0x0000000a) # 'defined2' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000006 +// CHECK-NEXT: # Symbol 6 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x3) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000007 +// CHECK-NEXT: # Symbol 7 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000003) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x3) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0003) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000008 +// CHECK-NEXT: # Symbol 8 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000004) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x3) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0004) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000009 +// CHECK-NEXT: # Symbol 9 // CHECK-NEXT: (('st_name', 0x0000004a) # 'g1@@zed' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000014) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x0000000a +// CHECK-NEXT: # Symbol 10 // CHECK-NEXT: (('st_name', 0x00000042) # 'global1' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000014) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x0000000b +// CHECK-NEXT: # Symbol 11 // CHECK-NEXT: (('st_name', 0x0000001c) # 'bar2@zed' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x0000000c +// CHECK-NEXT: # Symbol 12 // CHECK-NEXT: (('st_name', 0x00000039) # 'bar6@zed' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/tls-i386.s b/test/MC/ELF/tls-i386.s index c754121cd694..197418d93ce4 100644 --- a/test/MC/ELF/tls-i386.s +++ b/test/MC/ELF/tls-i386.s @@ -13,62 +13,62 @@ // CHECK: (('st_name', 0x00000001) # 'foo1' // CHECK-NEXT: ('st_value', 0x00000000) // CHECK-NEXT: ('st_size', 0x00000000) -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x6) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000006 +// CHECK-NEXT: # Symbol 6 // CHECK-NEXT: (('st_name', 0x00000006) # 'foo2' // CHECK-NEXT: ('st_value', 0x00000000) // CHECK-NEXT: ('st_size', 0x00000000) -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x6) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000007 +// CHECK-NEXT: # Symbol 7 // CHECK-NEXT: (('st_name', 0x0000000b) # 'foo3' // CHECK-NEXT: ('st_value', 0x00000000) // CHECK-NEXT: ('st_size', 0x00000000) -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x6) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000008 +// CHECK-NEXT: # Symbol 8 // CHECK-NEXT: (('st_name', 0x00000010) # 'foo4' // CHECK-NEXT: ('st_value', 0x00000000) // CHECK-NEXT: ('st_size', 0x00000000) -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x6) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000009 +// CHECK-NEXT: # Symbol 9 // CHECK-NEXT: (('st_name', 0x00000015) # 'foo5' // CHECK-NEXT: ('st_value', 0x00000000) // CHECK-NEXT: ('st_size', 0x00000000) -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x6) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x0000000a +// CHECK-NEXT: # Symbol 10 // CHECK-NEXT: (('st_name', 0x0000001a) # 'foo6' // CHECK-NEXT: ('st_value', 0x00000000) // CHECK-NEXT: ('st_size', 0x00000000) -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x6) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x0000000b +// CHECK-NEXT: # Symbol 11 // CHECK-NEXT: (('st_name', 0x0000001f) # 'foo7' // CHECK-NEXT: ('st_value', 0x00000000) // CHECK-NEXT: ('st_size', 0x00000000) -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x6) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/tls.s b/test/MC/ELF/tls.s index f9d6425f10e9..d6d7de6ff2cf 100644 --- a/test/MC/ELF/tls.s +++ b/test/MC/ELF/tls.s @@ -11,38 +11,38 @@ foobar: .long 43 // CHECK: (('st_name', 0x00000010) # 'foobar' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000005) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x6) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0005) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK: # Symbol 0x00000007 +// CHECK: # Symbol 7 // CHECK-NEXT: (('st_name', 0x00000001) # 'foo1' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x6) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000008 +// CHECK-NEXT: # Symbol 8 // CHECK-NEXT: (('st_name', 0x00000006) # 'foo2' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x6) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000009 +// CHECK-NEXT: # Symbol 9 // CHECK-NEXT: (('st_name', 0x0000000b) # 'foo3' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000006) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x6) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/type.s b/test/MC/ELF/type.s index 4b98c02e97d5..2b25a6b69f69 100644 --- a/test/MC/ELF/type.s +++ b/test/MC/ELF/type.s @@ -12,21 +12,21 @@ bar: // Test that gnu_unique_object is accepted. .type zed,@gnu_unique_object -// CHECK: # Symbol 0x00000004 +// CHECK: # Symbol 4 // CHECK-NEXT: (('st_name', 0x00000005) # 'bar' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000001) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x1) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000005 +// CHECK-NEXT: # Symbol 5 // CHECK-NEXT: (('st_name', 0x00000001) # 'foo' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000002) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x2) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/undef.s b/test/MC/ELF/undef.s index fc3a2d23be39..e377c6331747 100644 --- a/test/MC/ELF/undef.s +++ b/test/MC/ELF/undef.s @@ -20,26 +20,26 @@ movsd .Lsym8(%rip), %xmm1 // CHECK: ('_symbols', [ -// CHECK-NEXT: # Symbol 0x00000000 +// CHECK-NEXT: # Symbol 0 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK: # Symbol 0x00000001 +// CHECK: # Symbol 1 // CHECK-NEXT: (('st_name', 0x0000000d) # '.Lsym8' -// CHECK: # Symbol 0x00000002 +// CHECK: # Symbol 2 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK: # Symbol 0x00000003 +// CHECK: # Symbol 3 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK: # Symbol 0x00000004 +// CHECK: # Symbol 4 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK: # Symbol 0x00000005 +// CHECK: # Symbol 5 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK: # Symbol 0x00000006 +// CHECK: # Symbol 6 // CHECK-NEXT: (('st_name', 0x00000001) # '.Lsym1' -// CHECK: # Symbol 0x00000007 +// CHECK: # Symbol 7 // CHECK-NEXT: (('st_name', 0x00000008) # 'sym6' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000001) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x1) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/undef2.s b/test/MC/ELF/undef2.s index 6ce269bec2eb..6f971c55bf6c 100644 --- a/test/MC/ELF/undef2.s +++ b/test/MC/ELF/undef2.s @@ -6,5 +6,5 @@ // CHECK: ('_symbols', [ // CHECK: (('st_name', 0x00000001) # '.Lfoo' -// CHECK-NEXT: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) // CHECK: (('sh_name', 0x0000001b) # '.strtab' diff --git a/test/MC/ELF/weak-relocation.s b/test/MC/ELF/weak-relocation.s index ef331d7e6da2..88e841e65bf5 100644 --- a/test/MC/ELF/weak-relocation.s +++ b/test/MC/ELF/weak-relocation.s @@ -7,9 +7,9 @@ foo: bar: call foo -//CHECK: # Relocation 0x00000000 -//CHECK-NEXT: (('r_offset', 0x00000001) +//CHECK: # Relocation 0 +//CHECK-NEXT: (('r_offset', 0x0000000000000001) //CHECK-NEXT: ('r_sym', 0x00000005) //CHECK-NEXT: ('r_type', 0x00000002) -//CHECK-NEXT: ('r_addend', 0xfffffffc) +//CHECK-NEXT: ('r_addend', 0xfffffffffffffffc) //CHECK-NEXT: ), diff --git a/test/MC/ELF/weak.s b/test/MC/ELF/weak.s index 67e9b188eb06..07a83913631a 100644 --- a/test/MC/ELF/weak.s +++ b/test/MC/ELF/weak.s @@ -9,21 +9,21 @@ .weak bar bar: -//CHECK: # Symbol 0x00000004 +//CHECK: # Symbol 4 //CHECK-NEXT: (('st_name', 0x00000005) # 'bar' -//CHECK-NEXT: ('st_bind', 0x00000002) -//CHECK-NEXT: ('st_type', 0x00000000) -//CHECK-NEXT: ('st_other', 0x00000000) -//CHECK-NEXT: ('st_shndx', 0x00000001) +//CHECK-NEXT: ('st_bind', 0x2) +//CHECK-NEXT: ('st_type', 0x0) +//CHECK-NEXT: ('st_other', 0x00) +//CHECK-NEXT: ('st_shndx', 0x0001) //CHECK-NEXT: ('st_value', 0x0000000000000004) //CHECK-NEXT: ('st_size', 0x0000000000000000) //CHECK-NEXT: ), -//CHECK-NEXT: # Symbol 0x00000005 +//CHECK-NEXT: # Symbol 5 //CHECK: (('st_name', 0x00000001) # 'foo' -//CHECK-NEXT: ('st_bind', 0x00000002) -//CHECK-NEXT: ('st_type', 0x00000000) -//CHECK-NEXT: ('st_other', 0x00000000) -//CHECK-NEXT: ('st_shndx', 0x00000000) +//CHECK-NEXT: ('st_bind', 0x2) +//CHECK-NEXT: ('st_type', 0x0) +//CHECK-NEXT: ('st_other', 0x00) +//CHECK-NEXT: ('st_shndx', 0x0000) //CHECK-NEXT: ('st_value', 0x0000000000000000) //CHECK-NEXT: ('st_size', 0x0000000000000000) //CHECK-NEXT: ), diff --git a/test/MC/ELF/weakref-plt.s b/test/MC/ELF/weakref-plt.s index 26ba3f6df543..2e500935b6db 100644 --- a/test/MC/ELF/weakref-plt.s +++ b/test/MC/ELF/weakref-plt.s @@ -3,6 +3,6 @@ .weakref bar,foo call bar@PLT -// CHECK: # Symbol 0x00000005 +// CHECK: # Symbol 5 // CHECK-NEXT: (('st_name', 0x00000001) # 'foo' -// CHECK-NEXT: ('st_bind', 0x00000002) +// CHECK-NEXT: ('st_bind', 0x2) diff --git a/test/MC/ELF/weakref-reloc.s b/test/MC/ELF/weakref-reloc.s index 63c1f5ea2592..4bbf2645a8cd 100644 --- a/test/MC/ELF/weakref-reloc.s +++ b/test/MC/ELF/weakref-reloc.s @@ -7,43 +7,43 @@ call zed@PLT call bar -// CHECK: # Relocation 0x00000000 -// CHECK-NEXT: (('r_offset', 0x00000001) +// CHECK: # Relocation 0 +// CHECK-NEXT: (('r_offset', 0x0000000000000001) // CHECK-NEXT: ('r_sym', 0x00000006) // CHECK-NEXT: ('r_type', 0x00000004) -// CHECK-NEXT: ('r_addend', 0xfffffffc) +// CHECK-NEXT: ('r_addend', 0xfffffffffffffffc) // CHECK-NEXT: ), -// CHECK-NEXT: # Relocation 0x00000001 -// CHECK-NEXT: (('r_offset', 0x00000006) +// CHECK-NEXT: # Relocation 1 +// CHECK-NEXT: (('r_offset', 0x0000000000000006) // CHECK-NEXT: ('r_sym', 0x00000005) // CHECK-NEXT: ('r_type', 0x00000002) -// CHECK-NEXT: ('r_addend', 0xfffffffc) +// CHECK-NEXT: ('r_addend', 0xfffffffffffffffc) // CHECK-NEXT: ), -// CHECK: # Symbol 0x00000004 +// CHECK: # Symbol 4 // CHECK-NEXT: (('st_name', 0x00000009) # '_GLOBAL_OFFSET_TABLE_' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000005 +// CHECK-NEXT: # Symbol 5 // CHECK-NEXT: (('st_name', 0x00000001) # 'foo' -// CHECK-NEXT: ('st_bind', 0x00000002) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x2) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000006 +// CHECK-NEXT: # Symbol 6 // CHECK-NEXT: (('st_name', 0x00000005) # 'zed' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/weakref.s b/test/MC/ELF/weakref.s index 9100073551a2..e12d2c74eb8a 100644 --- a/test/MC/ELF/weakref.s +++ b/test/MC/ELF/weakref.s @@ -69,165 +69,165 @@ bar15: .long bar15 .long foo15 -// CHECK: # Symbol 0x00000000 +// CHECK: # Symbol 0 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000001 +// CHECK-NEXT: # Symbol 1 // CHECK-NEXT: (('st_name', 0x00000015) # 'bar6' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000018) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000002 +// CHECK-NEXT: # Symbol 2 // CHECK-NEXT: (('st_name', 0x0000001a) # 'bar7' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000018) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000003 +// CHECK-NEXT: # Symbol 3 // CHECK-NEXT: (('st_name', 0x0000001f) # 'bar8' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x000000000000001c) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000004 +// CHECK-NEXT: # Symbol 4 // CHECK-NEXT: (('st_name', 0x00000024) # 'bar9' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000020) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000005 +// CHECK-NEXT: # Symbol 5 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x3) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000006 +// CHECK-NEXT: # Symbol 6 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000003) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x3) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0003) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000007 +// CHECK-NEXT: # Symbol 7 // CHECK-NEXT: (('st_name', 0x00000000) # '' -// CHECK-NEXT: ('st_bind', 0x00000000) -// CHECK-NEXT: ('st_type', 0x00000003) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000004) +// CHECK-NEXT: ('st_bind', 0x0) +// CHECK-NEXT: ('st_type', 0x3) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0004) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000008 +// CHECK-NEXT: # Symbol 8 // CHECK-NEXT: (('st_name', 0x00000029) # 'bar10' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000028) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000009 +// CHECK-NEXT: # Symbol 9 // CHECK-NEXT: (('st_name', 0x0000002f) # 'bar11' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000030) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x0000000a +// CHECK-NEXT: # Symbol 10 // CHECK-NEXT: (('st_name', 0x00000035) # 'bar12' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000030) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x0000000b +// CHECK-NEXT: # Symbol 11 // CHECK-NEXT: (('st_name', 0x0000003b) # 'bar13' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000034) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x0000000c +// CHECK-NEXT: # Symbol 12 // CHECK-NEXT: (('st_name', 0x00000041) # 'bar14' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000038) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x0000000d +// CHECK-NEXT: # Symbol 13 // CHECK-NEXT: (('st_name', 0x00000047) # 'bar15' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0001) // CHECK-NEXT: ('st_value', 0x0000000000000040) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x0000000e +// CHECK-NEXT: # Symbol 14 // CHECK-NEXT: (('st_name', 0x00000001) # 'bar2' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x0000000f +// CHECK-NEXT: # Symbol 15 // CHECK-NEXT: (('st_name', 0x00000006) # 'bar3' -// CHECK-NEXT: ('st_bind', 0x00000002) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x2) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000010 +// CHECK-NEXT: # Symbol 16 // CHECK-NEXT: (('st_name', 0x0000000b) # 'bar4' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x00000011 +// CHECK-NEXT: # Symbol 17 // CHECK-NEXT: (('st_name', 0x00000010) # 'bar5' -// CHECK-NEXT: ('st_bind', 0x00000001) -// CHECK-NEXT: ('st_type', 0x00000000) -// CHECK-NEXT: ('st_other', 0x00000000) -// CHECK-NEXT: ('st_shndx', 0x00000000) +// CHECK-NEXT: ('st_bind', 0x1) +// CHECK-NEXT: ('st_type', 0x0) +// CHECK-NEXT: ('st_other', 0x00) +// CHECK-NEXT: ('st_shndx', 0x0000) // CHECK-NEXT: ('st_value', 0x0000000000000000) // CHECK-NEXT: ('st_size', 0x0000000000000000) // CHECK-NEXT: ), diff --git a/test/MC/ELF/x86_64-reloc-sizetest.s b/test/MC/ELF/x86_64-reloc-sizetest.s new file mode 100644 index 000000000000..acca2f5076a5 --- /dev/null +++ b/test/MC/ELF/x86_64-reloc-sizetest.s @@ -0,0 +1,13 @@ +// RUN: llvm-mc -triple x86_64-linux-gnu -filetype=obj %s | elf-dump | FileCheck %s + +// Tests that relocation value fits in the provided size +// Original bug http://llvm.org/bugs/show_bug.cgi?id=10568 + +L: movq $(L + 2147483648),%rax + + +// CHECK: Relocation 0 +// CHECK-NEXT: ('r_offset', 0x0000000000000003) +// CHECK-NEXT: ('r_sym' +// CHECK-NEXT: ('r_type', 0x0000000b) +// CHECK-NEXT: ('r_addend', 0x0000000080000000 diff --git a/test/MC/ELF/zero.s b/test/MC/ELF/zero.s index adf21f8a6bee..46ffe17cfbf7 100644 --- a/test/MC/ELF/zero.s +++ b/test/MC/ELF/zero.s @@ -5,12 +5,12 @@ // CHECK: ('sh_name', 0x00000001) # '.text' // CHECK: ('sh_type', 0x00000001) -// CHECK: ('sh_flags', 0x00000006) -// CHECK: ('sh_addr', 0x00000000) -// CHECK: ('sh_offset', 0x00000040) -// CHECK: ('sh_size', 0x00000005) +// CHECK: ('sh_flags', 0x0000000000000006) +// CHECK: ('sh_addr', 0x0000000000000000) +// CHECK: ('sh_offset', 0x0000000000000040) +// CHECK: ('sh_size', 0x0000000000000005) // CHECK: ('sh_link', 0x00000000) // CHECK: ('sh_info', 0x00000000) -// CHECK: ('sh_addralign', 0x00000004) -// CHECK: ('sh_entsize', 0x00000000) +// CHECK: ('sh_addralign', 0x0000000000000004) +// CHECK: ('sh_entsize', 0x0000000000000000) // CHECK: ('_section_data', '00000000 2a') diff --git a/test/MC/MachO/darwin-x86_64-nobase-relocs.s b/test/MC/MachO/darwin-x86_64-nobase-relocs.s new file mode 100644 index 000000000000..a90b3e4d0962 --- /dev/null +++ b/test/MC/MachO/darwin-x86_64-nobase-relocs.s @@ -0,0 +1,58 @@ +// RUN: llvm-mc -n -triple x86_64-apple-darwin9 %s -filetype=obj -o - | macho-dump --dump-section-data | FileCheck %s + +// Test case for rdar://10062261 + +// Must be no base, non-temporary, symbol before the reference to Lbar at the +// start of the section. What we are testing for is that the reference does not +// create a relocation entry. +.text +Ladd: + nop + jmp Lbar + .byte 0x0f,0x1f,0x40,0x00 + .byte 0x0f,0x1f,0x40,0x00 +Lbar: + mov $1, %eax + ret + +// CHECK: ('cputype', 16777223) +// CHECK: ('cpusubtype', 3) +// CHECK: ('filetype', 1) +// CHECK: ('num_load_commands', 1) +// CHECK: ('load_commands_size', 152) +// CHECK: ('flag', 0) +// CHECK: ('reserved', 0) +// CHECK: ('load_commands', [ +// CHECK: # Load Command 0 +// CHECK: (('command', 25) +// CHECK: ('size', 152) +// CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('vm_addr', 0) +// CHECK: ('vm_size', 17) +// CHECK: ('file_offset', 184) +// CHECK: ('file_size', 17) +// CHECK: ('maxprot', 7) +// CHECK: ('initprot', 7) +// CHECK: ('num_sections', 1) +// CHECK: ('flags', 0) +// CHECK: ('sections', [ +// CHECK: # Section 0 +// CHECK: (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +// CHECK: ('address', 0) +// CHECK: ('size', 17) +// CHECK: ('offset', 184) +// CHECK: ('alignment', 0) +// CHECK: ('reloc_offset', 0) +// CHECK: ('num_reloc', 0) +// CHECK: ('flags', 0x80000400) +// CHECK: ('reserved1', 0) +// CHECK: ('reserved2', 0) +// CHECK: ('reserved3', 0) +// CHECK: ), +// CHECK: ('_relocations', [ +// CHECK: ]) +// CHECK: ('_section_data', '90eb080f 1f40000f 1f4000b8 01000000 c3') +// CHECK: ]) +// CHECK: ), +// CHECK: ]) diff --git a/test/MC/MachO/debug_frame.s b/test/MC/MachO/debug_frame.s index 47264ef87991..20bfd8dde2e7 100644 --- a/test/MC/MachO/debug_frame.s +++ b/test/MC/MachO/debug_frame.s @@ -1,5 +1,11 @@ // RUN: llvm-mc -triple i386-apple-darwin %s -filetype=obj -o - | macho-dump | FileCheck %s +// Make sure MC can handle file level .cfi_startproc and .cfi_endproc that creates +// an empty frame. +// rdar://10017184 +.cfi_startproc +.cfi_endproc + // Check that we don't produce a relocation for the CIE pointer and therefore // we have only one relocation in __debug_frame. @@ -22,17 +28,20 @@ Ltext_end: // CHECK: (('section_name', '__debug_frame\x00\x00\x00') // CHECK-NEXT: ('segment_name', '__DWARF\x00\x00\x00\x00\x00\x00\x00\x00\x00') // CHECK-NEXT: ('address', 8) -// CHECK-NEXT: ('size', 36) +// CHECK-NEXT: ('size', 52) // CHECK-NEXT: ('offset', 332) // CHECK-NEXT: ('alignment', 2) -// CHECK-NEXT: ('reloc_offset', 368) -// CHECK-NEXT: ('num_reloc', 1) +// CHECK-NEXT: ('reloc_offset', 384) +// CHECK-NEXT: ('num_reloc', 2) // CHECK-NEXT: ('flags', 0x2000000) // CHECK-NEXT: ('reserved1', 0) // CHECK-NEXT: ('reserved2', 0) // CHECK-NEXT: ), // CHECK-NEXT: ('_relocations', [ // CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('word-0', 0x2c), +// CHECK-NEXT: ('word-1', 0x4000001)), +// CHECK-NEXT: # Relocation 1 // CHECK-NEXT: (('word-0', 0x1c), // CHECK-NEXT: ('word-1', 0x4000001)), // CHECK-NEXT: ]) diff --git a/test/MC/MachO/x86_64-reloc-arithmetic.s b/test/MC/MachO/x86_64-reloc-arithmetic.s new file mode 100644 index 000000000000..e82f69b6d477 --- /dev/null +++ b/test/MC/MachO/x86_64-reloc-arithmetic.s @@ -0,0 +1,21 @@ +// RUN: llvm-mc -triple x86_64-apple-darwin10 %s -filetype=obj -o - | macho-dump | FileCheck %s + +// rdar://9906375 +.org 0x100 +_foo: +_bar = _foo + 2 +_baz: + leaq _bar(%rip), %rcx + +// CHECK: ('_relocations', [ +// CHECK-NEXT: # Relocation 0 +// CHECK-NEXT: (('word-0', 0x103), +// CHECK-NEXT: ('word-1', 0x1d000001)) + +// CHECK: # Symbol 1 +// CHECK-NEXT: (('n_strx', 6) +// CHECK-NEXT: ('n_type', 0xe) +// CHECK-NEXT: ('n_sect', 1) +// CHECK-NEXT: ('n_desc', 0) +// CHECK-NEXT: ('n_value', 258) +// CHECK-NEXT: ('_string', '_bar') diff --git a/test/MC/X86/3DNow.s b/test/MC/X86/3DNow.s index 4dc68aecf4fa..871857b155d0 100644 --- a/test/MC/X86/3DNow.s +++ b/test/MC/X86/3DNow.s @@ -1,18 +1,18 @@ -// RUN: llvm-mc -triple i386-unknown-unknown --show-encoding %s | FileCheck %s +// RUN: llvm-mc -triple x86_64-unknown-unknown --show-encoding %s | FileCheck %s // PR8283 // CHECK: pavgusb %mm2, %mm1 # encoding: [0x0f,0x0f,0xca,0xbf] pavgusb %mm2, %mm1 -// CHECK: pavgusb 9(%esi,%edx), %mm3 # encoding: [0x0f,0x0f,0x5c,0x16,0x09,0xbf] +// CHECK: pavgusb 9(%esi,%edx), %mm3 # encoding: [0x67,0x0f,0x0f,0x5c,0x16,0x09,0xbf] pavgusb 9(%esi,%edx), %mm3 // CHECK: pf2id %mm2, %mm1 # encoding: [0x0f,0x0f,0xca,0x1d] pf2id %mm2, %mm1 -// CHECK: pf2id 9(%esi,%edx), %mm3 # encoding: [0x0f,0x0f,0x5c,0x16,0x09,0x1d] +// CHECK: pf2id 9(%esi,%edx), %mm3 # encoding: [0x67,0x0f,0x0f,0x5c,0x16,0x09,0x1d] pf2id 9(%esi,%edx), %mm3 // CHECK: pfacc %mm2, %mm1 # encoding: [0x0f,0x0f,0xca,0xae] diff --git a/test/MC/X86/x86-32-avx.s b/test/MC/X86/x86-32-avx.s index 1927e4e7a6b9..e13a8712f7d6 100644 --- a/test/MC/X86/x86-32-avx.s +++ b/test/MC/X86/x86-32-avx.s @@ -479,6 +479,14 @@ // CHECK: encoding: [0xc5,0xf9,0x50,0xc2] vmovmskpd %xmm2, %eax +// CHECK: vmovmskps %ymm2, %eax +// CHECK: encoding: [0xc5,0xfc,0x50,0xc2] + vmovmskps %ymm2, %eax + +// CHECK: vmovmskpd %ymm2, %eax +// CHECK: encoding: [0xc5,0xfd,0x50,0xc2] + vmovmskpd %ymm2, %eax + // CHECK: vcmpss $0, %xmm1, %xmm2, %xmm3 // CHECK: encoding: [0xc5,0xea,0xc2,0xd9,0x00] vcmpeqss %xmm1, %xmm2, %xmm3 @@ -3281,3 +3289,25 @@ // CHECK: encoding: [0xc4,0xe3,0x51,0x44,0x18,0x11] vpclmulqdq $17, (%eax), %xmm5, %xmm3 +// rdar://9795008 +// These instructions take a mask not an 8-bit sign extended value. +// CHECK: vblendps $129, %ymm2, %ymm5, %ymm1 + vblendps $0x81, %ymm2, %ymm5, %ymm1 +// CHECK: vblendps $129, (%eax), %ymm5, %ymm1 + vblendps $0x81, (%eax), %ymm5, %ymm1 +// CHECK: vblendpd $129, %ymm2, %ymm5, %ymm1 + vblendpd $0x81, %ymm2, %ymm5, %ymm1 +// CHECK: vblendpd $129, (%eax), %ymm5, %ymm1 + vblendpd $0x81, (%eax), %ymm5, %ymm1 +// CHECK: vpblendw $129, %xmm2, %xmm5, %xmm1 + vpblendw $0x81, %xmm2, %xmm5, %xmm1 +// CHECK: vmpsadbw $129, %xmm2, %xmm5, %xmm1 + vmpsadbw $0x81, %xmm2, %xmm5, %xmm1 +// CHECK: vdpps $129, %ymm2, %ymm5, %ymm1 + vdpps $0x81, %ymm2, %ymm5, %ymm1 +// CHECK: vdpps $129, (%eax), %ymm5, %ymm1 + vdpps $0x81, (%eax), %ymm5, %ymm1 +// CHECK: vdppd $129, %xmm2, %xmm5, %xmm1 + vdppd $0x81, %xmm2, %xmm5, %xmm1 +// CHECK: vinsertps $129, %xmm3, %xmm2, %xmm1 + vinsertps $0x81, %xmm3, %xmm2, %xmm1 diff --git a/test/MC/X86/x86-32-coverage.s b/test/MC/X86/x86-32-coverage.s index bdc54a60e37b..0954ce2b02cd 100644 --- a/test/MC/X86/x86-32-coverage.s +++ b/test/MC/X86/x86-32-coverage.s @@ -19571,7 +19571,24 @@ // CHECK: aeskeygenassist $125, (%edx,%eax,4), %xmm2 aeskeygenassist $125, (%edx,%eax,4), %xmm2 -// CHECK: blendvps (%rax), %xmm1 # encoding: [0x66,0x0f,0x38,0x14,0x08] - blendvps (%rax), %xmm1 +// CHECK: blendvps (%eax), %xmm1 # encoding: [0x66,0x0f,0x38,0x14,0x08] + blendvps (%eax), %xmm1 // CHECK: blendvps %xmm2, %xmm1 # encoding: [0x66,0x0f,0x38,0x14,0xca] blendvps %xmm2, %xmm1 + +// rdar://9795008 +// These instructions take a mask not an 8-bit sign extended value. +// CHECK: blendps $129, %xmm2, %xmm1 + blendps $0x81, %xmm2, %xmm1 +// CHECK: blendpd $129, %xmm2, %xmm1 + blendpd $0x81, %xmm2, %xmm1 +// CHECK: pblendw $129, %xmm2, %xmm1 + pblendw $0x81, %xmm2, %xmm1 +// CHECK: mpsadbw $129, %xmm2, %xmm1 + mpsadbw $0x81, %xmm2, %xmm1 +// CHECK: dpps $129, %xmm2, %xmm1 + dpps $0x81, %xmm2, %xmm1 +// CHECK: dppd $129, %xmm2, %xmm1 + dppd $0x81, %xmm2, %xmm1 +// CHECK: insertps $129, %xmm2, %xmm1 + insertps $0x81, %xmm2, %xmm1 diff --git a/test/MC/X86/x86-32.s b/test/MC/X86/x86-32.s index 60178801efbe..19f14450fee9 100644 --- a/test/MC/X86/x86-32.s +++ b/test/MC/X86/x86-32.s @@ -946,3 +946,19 @@ fsubp %st,%st(1) // CHECK: encoding: [0xde,0xe2] fsubp %st, %st(2) +// PR10345 +// CHECK: xchgl %eax, %eax +// CHECK: encoding: [0x90] +xchgl %eax, %eax + +// CHECK: xchgw %ax, %ax +// CHECK: encoding: [0x66,0x90] +xchgw %ax, %ax + +// CHECK: xchgl %ecx, %eax +// CHECK: encoding: [0x91] +xchgl %ecx, %eax + +// CHECK: xchgl %ecx, %eax +// CHECK: encoding: [0x91] +xchgl %eax, %ecx diff --git a/test/MC/X86/x86-64.s b/test/MC/X86/x86-64.s index 6f828e815d0b..a9cdaa495f05 100644 --- a/test/MC/X86/x86-64.s +++ b/test/MC/X86/x86-64.s @@ -1170,3 +1170,24 @@ pclmullqhqdq (%rdi), %xmm1 // CHECK: pclmulqdq $0, (%rdi), %xmm1 // CHECK: encoding: [0x66,0x0f,0x3a,0x44,0x0f,0x00] pclmulqdq $0, (%rdi), %xmm1 + +// PR10345 +// CHECK: xchgq %rax, %rax +// CHECK: encoding: [0x48,0x90] +xchgq %rax, %rax + +// CHECK: xchgl %eax, %eax +// CHECK: encoding: [0x87,0xc0] +xchgl %eax, %eax + +// CHECK: xchgw %ax, %ax +// CHECK: encoding: [0x66,0x90] +xchgw %ax, %ax + +// CHECK: xchgl %ecx, %eax +// CHECK: encoding: [0x91] +xchgl %ecx, %eax + +// CHECK: xchgl %ecx, %eax +// CHECK: encoding: [0x91] +xchgl %eax, %ecx diff --git a/test/MC/X86/x86_64-avx-encoding.s b/test/MC/X86/x86_64-avx-encoding.s index 7a96bb5a2b48..d3b226f205db 100644 --- a/test/MC/X86/x86_64-avx-encoding.s +++ b/test/MC/X86/x86_64-avx-encoding.s @@ -1448,6 +1448,10 @@ vdivpd -4(%rcx,%rbx,8), %xmm10, %xmm11 // CHECK: encoding: [0xc4,0x61,0xf9,0x6e,0xf0] vmovd %rax, %xmm14 +// CHECK: vmovd %xmm0, %rax +// CHECK: encoding: [0xc4,0xe1,0xf9,0x7e,0xc0] + vmovd %xmm0, %rax + // CHECK: vmovq %xmm14, (%rax) // CHECK: encoding: [0xc5,0x79,0xd6,0x30] vmovq %xmm14, (%rax) @@ -3316,3 +3320,29 @@ vdivpd -4(%rcx,%rbx,8), %xmm10, %xmm11 // CHECK: encoding: [0xc4,0x63,0x1d,0x4b,0xac,0x20,0xad,0xde,0x00,0x00,0xb0] vblendvpd %ymm11, 0xdead(%rax,%riz), %ymm12, %ymm13 +// CHECK: vmovaps %xmm3, (%r14,%r11) +// CHECK: encoding: [0xc4,0x81,0x78,0x29,0x1c,0x1e] + vmovaps %xmm3, (%r14,%r11) + +// CHECK: vmovaps (%r14,%r11), %xmm3 +// CHECK: encoding: [0xc4,0x81,0x78,0x28,0x1c,0x1e] + vmovaps (%r14,%r11), %xmm3 + +// CHECK: vmovaps %xmm3, (%r14,%rbx) +// CHECK: encoding: [0xc4,0xc1,0x78,0x29,0x1c,0x1e] + vmovaps %xmm3, (%r14,%rbx) + +// CHECK: vmovaps (%r14,%rbx), %xmm3 +// CHECK: encoding: [0xc4,0xc1,0x78,0x28,0x1c,0x1e] + vmovaps (%r14,%rbx), %xmm3 + +// CHECK: vmovaps %xmm3, (%rax,%r11) +// CHECK: encoding: [0xc4,0xa1,0x78,0x29,0x1c,0x18] + vmovaps %xmm3, (%rax,%r11) + +// CHECK: vpshufb _foo(%rip), %xmm0, %xmm0 +// CHECK: encoding: [0xc4,0xe2,0x79,0x00,0x05,A,A,A,A] +// CHECK: kind: reloc_riprel_4byte +_foo: + nop + vpshufb _foo(%rip), %xmm0, %xmm0 diff --git a/test/MC/X86/x86_errors.s b/test/MC/X86/x86_errors.s index 183306be2c11..e0a2c676d3df 100644 --- a/test/MC/X86/x86_errors.s +++ b/test/MC/X86/x86_errors.s @@ -1,5 +1,17 @@ // RUN: not llvm-mc -triple x86_64-unknown-unknown %s 2> %t.err -// RUN: FileCheck < %t.err %s +// RUN: FileCheck --check-prefix=64 < %t.err %s -// CHECK: error: ambiguous instructions require an explicit suffix (could be 'cmpb', 'cmpw', 'cmpl', or 'cmpq') +// RUN: not llvm-mc -triple i386-unknown-unknown %s 2> %t.err +// RUN: FileCheck --check-prefix=32 < %t.err %s +// rdar://8204588 + +// 64: error: ambiguous instructions require an explicit suffix (could be 'cmpb', 'cmpw', 'cmpl', or 'cmpq') cmp $0, 0(%eax) + +// 32: error: register %rax is only available in 64-bit mode +addl $0, 0(%rax) + +// 32: test.s:8:2: error: invalid instruction mnemonic 'movi' + +# 8 "test.s" + movi $8,%eax diff --git a/test/Object/TestObjectFiles/archive-test.a-bitcode b/test/Object/TestObjectFiles/archive-test.a-bitcode new file mode 100644 index 0000000000000000000000000000000000000000..3aeb34fa334257f953f121226bba8fdb5cccd8f4 GIT binary patch literal 790 zcmZ8eO-vI}5T3T{zU@+A3k|jj;;UPUBu4vRYS6UZHM9{D6=R~8Zjlg!CI+NwxR_K=o=kdx=*8gKgU+s^fyumYX5KgNdz1IvLz&XO$t%2= z9vQhknjX6|n!XiJq(xuA7x4w7{y>D%a3~ZAA7U^_bqgD)gTez-$mFKVrQB>TlfRJ5 zT{O7A3ci4s(kR*?Mj|MQ77iV1D11WN`r@_$yaE7|0MLbzJQAPBcbOC`_@k?)s_pCv z&eg{}8&`#^=EQ1SqAK_ugPb$P`(;m(uertgP1WXdmpo*bvyZQ9>#@dx33XCV02X6g z^%vUdEyZM4DYrm>=%vL8%M_pkdH)&CO0x@9=$DgLYrovEO6~#An&3LgSzplUeXf>= zr%|)_+_qqMWLBmajZNKM@UY!4%Nv%Vjm5C~q&T_wFi9S)S)!k{uDvFEpph9$Dqd1D zl0vPcsF6AJCi_h#6~pySg;WGGs}W4FJa%L@Mk)#^YXp;ma+Fm%jk3!-rGd zyqQrk0o#opsz;!0j6wPP)@&~ONNvU1Kips>K3mI%f40AQx0l~E>wOstfZq+>O#Hka z8C*dTCM1{H>yYAww-x}Al?AS`v@I~hJ*^l3ZUMP2d~jqQ$GELctN`Zmj|s*Ar}oxc zz4sla%S+N=b!R1^lKD9@qxTf)pK*I)UijpM*0r$-b6px;ZI@r~2w%&>$KlZX>R`Lx G3cmsK8^=8W literal 0 HcmV?d00001 diff --git a/test/Object/TestObjectFiles/archive-test.a-coff-i386 b/test/Object/TestObjectFiles/archive-test.a-coff-i386 new file mode 100644 index 0000000000000000000000000000000000000000..846cd636f1ed8dbcbe94d2f7126dae79abcdb14d GIT binary patch literal 658 zcmY$iNi0gvu;bEKKm~@zhUSJQW)>EPsNx1tuAvD`Jb{aWfq@Z-|HS7eX67-FYLXGm zNQDG0urW~M7#X1Ep&3ZXWyVP6l@w)`WhUn6<|k#PCYR`zq!yRxCFiH5>1G;Rm@(+X zRYLp%GT8tKO-*5bgNhp%n3Wan2{1_D@?m6RSm)5^vl-}G4j={ry^_?55(pDa zssPCpAnt&QF#~A@hJXaUl*E!ms2GUi1>$8$d=S%tLEu318=m7XDqz!(vw#d^cmXH6 zffCI}cn zKq5ddAUTZ*$Y*8*ISvLuA`H-IfrtThF)=at#OoE86hTD5x)|aMN=u3%0$>uNlLbXY a9LS3g&d*KtFUd$Pax2YCF3HT#V*miHEnjT_ literal 0 HcmV?d00001 diff --git a/test/Object/nm-archive.test b/test/Object/nm-archive.test new file mode 100644 index 000000000000..da6144ee712d --- /dev/null +++ b/test/Object/nm-archive.test @@ -0,0 +1,17 @@ +RUN: llvm-nm %p/TestObjectFiles/archive-test.a-coff-i386 \ +RUN: | FileCheck %s -check-prefix COFF +RUN: llvm-nm %p/TestObjectFiles/archive-test.a-bitcode \ +RUN: | FileCheck %s -check-prefix BITCODE + + +COFF: trivial-object-test.coff-i386: +COFF-NEXT: 00000000 d .data +COFF-NEXT: 00000000 t .text +COFF-NEXT: 00000000 d L_.str +COFF-NEXT: U _SomeOtherFunction +COFF-NEXT: 00000000 T _main +COFF-NEXT: U _puts + +BITCODE: U SomeOtherFunction +BITCODE-NEXT: T main +BITCODE-NEXT: U puts diff --git a/test/Object/nm-trivial-object.test-broken b/test/Object/nm-trivial-object.test similarity index 100% rename from test/Object/nm-trivial-object.test-broken rename to test/Object/nm-trivial-object.test diff --git a/test/Object/objdump-disassembly-inline-relocations.test b/test/Object/objdump-disassembly-inline-relocations.test new file mode 100644 index 000000000000..91f2e48f6230 --- /dev/null +++ b/test/Object/objdump-disassembly-inline-relocations.test @@ -0,0 +1,32 @@ +RUN: llvm-objdump -d -r %p/TestObjectFiles/trivial-object-test.coff-i386 \ +RUN: | FileCheck %s -check-prefix COFF-i386 +RUN: llvm-objdump -d -r %p/TestObjectFiles/trivial-object-test.coff-x86-64 \ +RUN: | FileCheck %s -check-prefix COFF-x86-64 + +COFF-i386: file format COFF-i386 +COFF-i386: Disassembly of section .text: +COFF-i386: 0: 83 ec 0c subl $12, %esp +COFF-i386: 3: c7 44 24 08 00 00 00 00 movl $0, 8(%esp) +COFF-i386: b: c7 04 24 00 00 00 00 movl $0, (%esp) +COFF-i386: e: IMAGE_REL_I386_DIR32 L_.str +COFF-i386: 12: e8 00 00 00 00 calll 0 +COFF-i386: 13: IMAGE_REL_I386_REL32 _puts +COFF-i386: 17: e8 00 00 00 00 calll 0 +COFF-i386: 18: IMAGE_REL_I386_REL32 _SomeOtherFunction +COFF-i386: 1c: 8b 44 24 08 movl 8(%esp), %eax +COFF-i386: 20: 83 c4 0c addl $12, %esp +COFF-i386: 23: c3 ret + +COFF-x86-64: file format COFF-x86-64 +COFF-x86-64: Disassembly of section .text: +COFF-x86-64: 0: 48 83 ec 28 subq $40, %rsp +COFF-x86-64: 4: c7 44 24 24 00 00 00 00 movl $0, 36(%rsp) +COFF-x86-64: c: 48 8d 0d 00 00 00 00 leaq (%rip), %rcx +COFF-x86-64: f: IMAGE_REL_AMD64_REL32 L.str +COFF-x86-64: 13: e8 00 00 00 00 callq 0 +COFF-x86-64: 14: IMAGE_REL_AMD64_REL32 puts +COFF-x86-64: 18: e8 00 00 00 00 callq 0 +COFF-x86-64: 19: IMAGE_REL_AMD64_REL32 SomeOtherFunction +COFF-x86-64: 1d: 8b 44 24 24 movl 36(%rsp), %eax +COFF-x86-64: 21: 48 83 c4 28 addq $40, %rsp +COFF-x86-64: 25: c3 ret diff --git a/test/Object/objdump-relocations.test b/test/Object/objdump-relocations.test new file mode 100644 index 000000000000..2dcdb432ef61 --- /dev/null +++ b/test/Object/objdump-relocations.test @@ -0,0 +1,28 @@ +RUN: llvm-objdump -r %p/TestObjectFiles/trivial-object-test.coff-i386 \ +RUN: | FileCheck %s -check-prefix COFF-i386 +RUN: llvm-objdump -r %p/TestObjectFiles/trivial-object-test.coff-x86-64 \ +RUN: | FileCheck %s -check-prefix COFF-x86-64 +RUN: llvm-objdump -r %p/TestObjectFiles/trivial-object-test.elf-i386 \ +RUN: | FileCheck %s -check-prefix ELF-i386 +RUN: llvm-objdump -r %p/TestObjectFiles/trivial-object-test.elf-x86-64 \ +RUN: | FileCheck %s -check-prefix ELF-x86-64 + +COFF-i386: .text +COFF-i386: IMAGE_REL_I386_DIR32 L_.str +COFF-i386: IMAGE_REL_I386_REL32 _puts +COFF-i386: IMAGE_REL_I386_REL32 _SomeOtherFunction + +COFF-x86-64: .text +COFF-x86-64: IMAGE_REL_AMD64_REL32 L.str +COFF-x86-64: IMAGE_REL_AMD64_REL32 puts +COFF-x86-64: IMAGE_REL_AMD64_REL32 SomeOtherFunction + +ELF-i386: .text +ELF-i386: R_386_32 +ELF-i386: R_386_PC32 +ELF-i386: R_386_PC32 + +ELF-x86-64: .text +ELF-x86-64: R_X86_64_32S .rodata.str1.1 +ELF-x86-64: R_X86_64_PC32 puts +ELF-x86-64: R_X86_64_PC32 SomeOtherFunction diff --git a/test/Object/objdump-sectionheaders.test b/test/Object/objdump-sectionheaders.test new file mode 100644 index 000000000000..4515d00e618d --- /dev/null +++ b/test/Object/objdump-sectionheaders.test @@ -0,0 +1,16 @@ +; RUN: llvm-objdump -h %p/TestObjectFiles/trivial-object-test.elf-x86-64 \ +; RUN: | FileCheck %s + +; To verify this, use readelf -S, not objdump -h. Binutils objdump filters the +; results in a way that we don't emulate. + +; CHECK: Sections: +; CHECK: Idx Name Size Address Type +; CHECK: 0 000000000 00000000000000000 +; CHECK: 1 .text 000000026 00000000000000000 TEXT DATA +; CHECK: 2 .rodata.str1.1 00000000d 00000000000000026 DATA +; CHECK: 3 .note.GNU-stack 000000000 00000000000000033 +; CHECK: 4 .rela.text 000000048 00000000000000038 +; CHECK: 5 .symtab 0000000c0 00000000000000080 +; CHECK: 6 .strtab 000000033 00000000000000140 +; CHECK: 7 .shstrtab 00000004b 00000000000000173 diff --git a/test/Object/objdump-trivial-object.test-broken b/test/Object/objdump-trivial-object.test similarity index 100% rename from test/Object/objdump-trivial-object.test-broken rename to test/Object/objdump-trivial-object.test diff --git a/test/Other/2008-10-15-MissingSpace.ll b/test/Other/2008-10-15-MissingSpace.ll index a61fa614213a..d16ea72c2bda 100644 --- a/test/Other/2008-10-15-MissingSpace.ll +++ b/test/Other/2008-10-15-MissingSpace.ll @@ -3,5 +3,10 @@ declare void @g() define void @f() { invoke void @g() to label %c unwind label %c - c: ret void +c: + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup + ret void } + +declare i32 @__gxx_personality_v0(...) diff --git a/test/Scripts/common_dump.py b/test/Scripts/common_dump.py index 3d69c3fb27f2..fd58993c0584 100644 --- a/test/Scripts/common_dump.py +++ b/test/Scripts/common_dump.py @@ -31,7 +31,7 @@ def dataToHexUnified(d): return ''.join(bytes).strip() -def HexDump(val, numBits=32): +def HexDump(valPair): """ 1. do not print 'L' 2. Handle negatives and large numbers by mod (2^numBits) @@ -40,7 +40,9 @@ def HexDump(val, numBits=32): 4. Do print 0x Why? so that they can be easily distinguished using sed/rx """ + val, numBits = valPair + assert 0 <= val < (1 << numBits) + val = val & (( 1 << numBits) - 1) newFmt = "0x%0" + "%d" % (numBits / 4) + "x" return newFmt % val - diff --git a/test/Scripts/elf-dump b/test/Scripts/elf-dump index 76cdbf91c73f..58ca1773280e 100755 --- a/test/Scripts/elf-dump +++ b/test/Scripts/elf-dump @@ -26,22 +26,16 @@ class Reader: return data def read8(self): - return ord(self.read(1)) + return (ord(self.read(1)), 8) def read16(self): - return struct.unpack('><'[self.isLSB] + 'H', self.read(2))[0] + return (struct.unpack('><'[self.isLSB] + 'H', self.read(2))[0], 16) def read32(self): - return struct.unpack('><'[self.isLSB] + 'I', self.read(4))[0] - - def read32S(self): - return struct.unpack('><'[self.isLSB] + 'i', self.read(4))[0] + return (struct.unpack('><'[self.isLSB] + 'I', self.read(4))[0], 32) def read64(self): - return struct.unpack('><'[self.isLSB] + 'Q', self.read(8))[0] - - def read64S(self): - return struct.unpack('><'[self.isLSB] + 'q', self.read(8))[0] + return (struct.unpack('><'[self.isLSB] + 'Q', self.read(8))[0], 64) def readWord(self): if self.is64Bit: @@ -49,12 +43,6 @@ class Reader: else: return self.read32() - def readWordS(self): - if self.is64Bit: - return self.read64S() - else: - return self.read32S() - class StringTable: def __init__(self, strings): self.string_table = strings @@ -77,7 +65,7 @@ class Section: self.sh_entsize = f.readWord() def dump(self, shstrtab, f, strtab, dumpdata): - print " (('sh_name', %s)" % common_dump.HexDump(self.sh_name), "# %r" % shstrtab[self.sh_name] + print " (('sh_name', %s)" % common_dump.HexDump(self.sh_name), "# %r" % shstrtab[self.sh_name[0]] print " ('sh_type', %s)" % common_dump.HexDump(self.sh_type) print " ('sh_flags', %s)" % common_dump.HexDump(self.sh_flags) print " ('sh_addr', %s)" % common_dump.HexDump(self.sh_addr) @@ -87,60 +75,64 @@ class Section: print " ('sh_info', %s)" % common_dump.HexDump(self.sh_info) print " ('sh_addralign', %s)" % common_dump.HexDump(self.sh_addralign) print " ('sh_entsize', %s)" % common_dump.HexDump(self.sh_entsize) - if self.sh_type == 2: # SHT_SYMTAB + if self.sh_type[0] == 2: # SHT_SYMTAB print " ('_symbols', [" dumpSymtab(f, self, strtab) print " ])" - elif self.sh_type == 4 or self.sh_type == 9: # SHT_RELA / SHT_REL + elif self.sh_type[0] == 4 or self.sh_type[0] == 9: # SHT_RELA / SHT_REL print " ('_relocations', [" - dumpRel(f, self, self.sh_type == 4) + dumpRel(f, self, self.sh_type[0] == 4) print " ])" elif dumpdata: - f.seek(self.sh_offset) + f.seek(self.sh_offset[0]) if self.sh_type != 8: # != SHT_NOBITS - data = f.read(self.sh_size) + data = f.read(self.sh_size[0]) print " ('_section_data', '%s')" % common_dump.dataToHex(data) else: print " ('_section_data', '')" print " )," def dumpSymtab(f, section, strtab): - entries = section.sh_size // section.sh_entsize + entries = section.sh_size[0] // section.sh_entsize[0] for index in range(entries): - f.seek(section.sh_offset + index * section.sh_entsize) - print " # Symbol %s" % common_dump.HexDump(index) + f.seek(section.sh_offset[0] + index * section.sh_entsize[0]) + print " # Symbol %s" % index name = f.read32() - print " (('st_name', %s)" % common_dump.HexDump(name), "# %r" % strtab[name] + print " (('st_name', %s)" % common_dump.HexDump(name), "# %r" % strtab[name[0]] if not f.is64Bit: print " ('st_value', %s)" % common_dump.HexDump(f.read32()) print " ('st_size', %s)" % common_dump.HexDump(f.read32()) - st_info = f.read8() - print " ('st_bind', %s)" % common_dump.HexDump((st_info >> 4)) - print " ('st_type', %s)" % common_dump.HexDump((st_info & 0xf)) + st_info = f.read8()[0] + st_bind = (st_info >> 4, 4) + st_type = (st_info & 0xf, 4) + print " ('st_bind', %s)" % common_dump.HexDump(st_bind) + print " ('st_type', %s)" % common_dump.HexDump(st_type) print " ('st_other', %s)" % common_dump.HexDump(f.read8()) print " ('st_shndx', %s)" % common_dump.HexDump(f.read16()) if f.is64Bit: - print " ('st_value', %s)" % common_dump.HexDump(f.read64(), 64) - print " ('st_size', %s)" % common_dump.HexDump(f.read64(), 64) + print " ('st_value', %s)" % common_dump.HexDump(f.read64()) + print " ('st_size', %s)" % common_dump.HexDump(f.read64()) print " )," def dumpRel(f, section, dumprela = False): - entries = section.sh_size // section.sh_entsize + entries = section.sh_size[0] // section.sh_entsize[0] for index in range(entries): - f.seek(section.sh_offset + index * section.sh_entsize) - print " # Relocation %s" % common_dump.HexDump(index) + f.seek(section.sh_offset[0] + index * section.sh_entsize[0]) + print " # Relocation %s" % index print " (('r_offset', %s)" % common_dump.HexDump(f.readWord()) - r_info = f.readWord() + r_info = f.readWord()[0] if f.is64Bit: - print " ('r_sym', %s)" % common_dump.HexDump((r_info >> 32)) - print " ('r_type', %s)" % common_dump.HexDump((r_info & 0xffffffff)) + r_sym = (r_info >> 32, 32) + r_type = (r_info & 0xffffffff, 32) else: - print " ('r_sym', %s)" % common_dump.HexDump((r_info >> 8)) - print " ('r_type', %s)" % common_dump.HexDump((r_info & 0xff)) + r_sym = (r_info >> 8, 24) + r_type = (r_info & 0xff, 8) + print " ('r_sym', %s)" % common_dump.HexDump(r_sym) + print " ('r_type', %s)" % common_dump.HexDump(r_type) if dumprela: - print " ('r_addend', %s)" % common_dump.HexDump(f.readWordS()) + print " ('r_addend', %s)" % common_dump.HexDump(f.readWord()) print " )," def dumpELF(path, opts): @@ -150,18 +142,18 @@ def dumpELF(path, opts): assert magic == '\x7FELF' fileclass = f.read8() - if fileclass == 1: # ELFCLASS32 + if fileclass[0] == 1: # ELFCLASS32 f.is64Bit = False - elif fileclass == 2: # ELFCLASS64 + elif fileclass[0] == 2: # ELFCLASS64 f.is64Bit = True else: raise ValueError, "Unknown file class %s" % common_dump.HexDump(fileclass) print "('e_indent[EI_CLASS]', %s)" % common_dump.HexDump(fileclass) byteordering = f.read8() - if byteordering == 1: # ELFDATA2LSB + if byteordering[0] == 1: # ELFDATA2LSB f.isLSB = True - elif byteordering == 2: # ELFDATA2MSB + elif byteordering[0] == 2: # ELFDATA2MSB f.isLSB = False else: raise ValueError, "Unknown byte ordering %s" % common_dump.HexDump(byteordering) @@ -193,26 +185,26 @@ def dumpELF(path, opts): # Read all section headers sections = [] - for index in range(e_shnum): - f.seek(e_shoff + index * e_shentsize) + for index in range(e_shnum[0]): + f.seek(e_shoff[0] + index * e_shentsize[0]) s = Section(f) sections.append(s) # Read .shstrtab so we can resolve section names - f.seek(sections[e_shstrndx].sh_offset) - shstrtab = StringTable(f.read(sections[e_shstrndx].sh_size)) + f.seek(sections[e_shstrndx[0]].sh_offset[0]) + shstrtab = StringTable(f.read(sections[e_shstrndx[0]].sh_size[0])) # Get the symbol string table strtab = None for section in sections: - if shstrtab[section.sh_name] == ".strtab": - f.seek(section.sh_offset) - strtab = StringTable(f.read(section.sh_size)) + if shstrtab[section.sh_name[0]] == ".strtab": + f.seek(section.sh_offset[0]) + strtab = StringTable(f.read(section.sh_size[0])) break print "('_sections', [" - for index in range(e_shnum): - print " # Section %s" % common_dump.HexDump(index) + for index in range(e_shnum[0]): + print " # Section %s" % index sections[index].dump(shstrtab, f, strtab, opts.dumpSectionData) print "])" diff --git a/test/TableGen/2003-08-03-PassCode.td b/test/TableGen/2003-08-03-PassCode.td index c02f499b3822..de7d6261b230 100644 --- a/test/TableGen/2003-08-03-PassCode.td +++ b/test/TableGen/2003-08-03-PassCode.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak class test { diff --git a/test/TableGen/2006-09-18-LargeInt.td b/test/TableGen/2006-09-18-LargeInt.td index 194699acc632..f7ae4eecceb4 100644 --- a/test/TableGen/2006-09-18-LargeInt.td +++ b/test/TableGen/2006-09-18-LargeInt.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | grep -- 4294901760 +// RUN: llvm-tblgen %s | grep -- 4294901760 // XFAIL: vg_leak def X { diff --git a/test/TableGen/2010-03-24-PrematureDefaults.td b/test/TableGen/2010-03-24-PrematureDefaults.td index 2ff2d42d2730..24f6c93b3e17 100644 --- a/test/TableGen/2010-03-24-PrematureDefaults.td +++ b/test/TableGen/2010-03-24-PrematureDefaults.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | FileCheck %s +// RUN: llvm-tblgen %s | FileCheck %s // XFAIL: vg_leak class A x = 1> { diff --git a/test/TableGen/AnonDefinitionOnDemand.td b/test/TableGen/AnonDefinitionOnDemand.td index b10ad5870de1..b6e0fc7df558 100644 --- a/test/TableGen/AnonDefinitionOnDemand.td +++ b/test/TableGen/AnonDefinitionOnDemand.td @@ -1,4 +1,4 @@ -// RUN: tblgen < %s +// RUN: llvm-tblgen < %s // XFAIL: vg_leak class foo { int THEVAL = X; } diff --git a/test/TableGen/BitsInitOverflow.td b/test/TableGen/BitsInitOverflow.td index 076b3f6f73eb..c3f9720c2d3d 100644 --- a/test/TableGen/BitsInitOverflow.td +++ b/test/TableGen/BitsInitOverflow.td @@ -1,4 +1,4 @@ -// RUN: not tblgen %s 2> /dev/null +// RUN: not llvm-tblgen %s 2> /dev/null def { bits<2> X = 5; // bitfield is too small, reject diff --git a/test/TableGen/CStyleComment.td b/test/TableGen/CStyleComment.td index 703ae6837eb8..55fb0e787b62 100644 --- a/test/TableGen/CStyleComment.td +++ b/test/TableGen/CStyleComment.td @@ -1,6 +1,7 @@ // Test that multiline, nested, comments work correctly. // -// RUN: tblgen < %s +// RUN: llvm-tblgen < %s +// XFAIL: vg_leak /* Foo bar diff --git a/test/TableGen/Dag.td b/test/TableGen/Dag.td index d3481a550c34..9ed2301cef04 100644 --- a/test/TableGen/Dag.td +++ b/test/TableGen/Dag.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | FileCheck %s +// RUN: llvm-tblgen %s | FileCheck %s // XFAIL: vg_leak //===----------------------------------------------------------------------===// diff --git a/test/TableGen/DefmInherit.td b/test/TableGen/DefmInherit.td index 9e1667052697..47fd81d2e719 100644 --- a/test/TableGen/DefmInherit.td +++ b/test/TableGen/DefmInherit.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | grep {zing = 4} | count 4 +// RUN: llvm-tblgen %s | grep {zing = 4} | count 4 // XFAIL: vg_leak class C1 { diff --git a/test/TableGen/DefmInsideMultiClass.td b/test/TableGen/DefmInsideMultiClass.td index 68cc12d56811..e6fc019b1e3e 100644 --- a/test/TableGen/DefmInsideMultiClass.td +++ b/test/TableGen/DefmInsideMultiClass.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | grep ADDPSrr | count 1 +// RUN: llvm-tblgen %s | grep ADDPSrr | count 1 // XFAIL: vg_leak class Instruction opc, string Name> { diff --git a/test/TableGen/FieldAccess.td b/test/TableGen/FieldAccess.td index 8b4dc83e0a5b..d69caae8a6fb 100644 --- a/test/TableGen/FieldAccess.td +++ b/test/TableGen/FieldAccess.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak class Bla diff --git a/test/TableGen/ForwardRef.td b/test/TableGen/ForwardRef.td index 955cc14248f8..73884455b883 100644 --- a/test/TableGen/ForwardRef.td +++ b/test/TableGen/ForwardRef.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s -o - +// RUN: llvm-tblgen %s -o - // XFAIL: vg_leak class bar { diff --git a/test/TableGen/GeneralList.td b/test/TableGen/GeneralList.td index ca92a213b228..9e0c7df552b3 100644 --- a/test/TableGen/GeneralList.td +++ b/test/TableGen/GeneralList.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak // // Test to make sure that lists work with any data-type diff --git a/test/TableGen/Include.td b/test/TableGen/Include.td index 29ed5150c622..8783638f0c61 100644 --- a/test/TableGen/Include.td +++ b/test/TableGen/Include.td @@ -1,4 +1,5 @@ -// RUN: tblgen -I %p %s +// RUN: llvm-tblgen -I %p %s +// XFAIL: vg_leak def BeforeInclude; include "Include.inc" diff --git a/test/TableGen/IntBitInit.td b/test/TableGen/IntBitInit.td index 16ac9c8f912d..83713a33321b 100644 --- a/test/TableGen/IntBitInit.td +++ b/test/TableGen/IntBitInit.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak def { bit A = 1; diff --git a/test/TableGen/LazyChange.td b/test/TableGen/LazyChange.td index fa53562b8c27..8145a3ff8d38 100644 --- a/test/TableGen/LazyChange.td +++ b/test/TableGen/LazyChange.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | grep {int Y = 3} +// RUN: llvm-tblgen %s | grep {int Y = 3} // XFAIL: vg_leak class C { diff --git a/test/TableGen/LetInsideMultiClasses.td b/test/TableGen/LetInsideMultiClasses.td index 9238bf42d9bd..cb13508e5117 100644 --- a/test/TableGen/LetInsideMultiClasses.td +++ b/test/TableGen/LetInsideMultiClasses.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | grep "bit IsDouble = 1;" | count 3 +// RUN: llvm-tblgen %s | grep "bit IsDouble = 1;" | count 3 // XFAIL: vg_leak class Instruction opc, string Name> { diff --git a/test/TableGen/ListArgs.td b/test/TableGen/ListArgs.td index a513db6da3cd..8714112d137b 100644 --- a/test/TableGen/ListArgs.td +++ b/test/TableGen/ListArgs.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak class B v> { diff --git a/test/TableGen/ListArgsSimple.td b/test/TableGen/ListArgsSimple.td index f7caed69a996..b8ec6e024178 100644 --- a/test/TableGen/ListArgsSimple.td +++ b/test/TableGen/ListArgsSimple.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak class B { diff --git a/test/TableGen/ListConversion.td b/test/TableGen/ListConversion.td index 222b6140564e..29b87795bee5 100644 --- a/test/TableGen/ListConversion.td +++ b/test/TableGen/ListConversion.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak class A; class B : A; diff --git a/test/TableGen/ListManip.td b/test/TableGen/ListManip.td index 6b1e491cd25f..bece266acbf9 100644 --- a/test/TableGen/ListManip.td +++ b/test/TableGen/ListManip.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak class Bli diff --git a/test/TableGen/ListOfList.td b/test/TableGen/ListOfList.td new file mode 100644 index 000000000000..565a99cf5fe2 --- /dev/null +++ b/test/TableGen/ListOfList.td @@ -0,0 +1,14 @@ +// RUN llvm-tblgen %s | FileCheck %s + +// RUN: llvm-tblgen %s | grep {foo} | count 1 +// XFAIL: vg_leak + +class Base { + string text = t; +} + +class Derived> thetext> : Base; + +def FOO : Derived<[["foo"]]>; + +// CHECK: text = "foo" diff --git a/test/TableGen/ListSlices.td b/test/TableGen/ListSlices.td index 5848a4e48704..cbb2326a95c0 100644 --- a/test/TableGen/ListSlices.td +++ b/test/TableGen/ListSlices.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak def A { diff --git a/test/TableGen/LoLoL.td b/test/TableGen/LoLoL.td new file mode 100644 index 000000000000..778c9609d1a2 --- /dev/null +++ b/test/TableGen/LoLoL.td @@ -0,0 +1,18 @@ +// RUN: llvm-tblgen %s | FileCheck %s +// XFAIL: vg_leak + +class Base v> { + list values = v; +} + +class Derived v> : Base; + +multiclass Multi>> v> { + def ONE : Derived,!if(!empty(!head(v)),[],v[0][0]))>; + def TWO : Derived,!if(!empty(!tail(v)),!if(!empty(!head(v)),[],v[0][0]),v[1][0]))>; +} + +defm Def : Multi<[[[]],[[1, 2, 3]]]>; + +// CHECK: values = [0] +// CHECK: values = [1, 2, 3] diff --git a/test/TableGen/MultiClass.td b/test/TableGen/MultiClass.td index 9f92b73dba65..04f3a5655821 100644 --- a/test/TableGen/MultiClass.td +++ b/test/TableGen/MultiClass.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | grep {zing = 4} | count 2 +// RUN: llvm-tblgen %s | grep {zing = 4} | count 2 // XFAIL: vg_leak class C1 { diff --git a/test/TableGen/MultiClassDefName.td b/test/TableGen/MultiClassDefName.td index 138c93d9bb0c..296e30c7c788 100644 --- a/test/TableGen/MultiClassDefName.td +++ b/test/TableGen/MultiClassDefName.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | grep WorldHelloCC | count 1 +// RUN: llvm-tblgen %s | grep WorldHelloCC | count 1 // XFAIL: vg_leak class C { diff --git a/test/TableGen/MultiClassInherit.td b/test/TableGen/MultiClassInherit.td index 9da80bad2d74..8b78bc7736c3 100644 --- a/test/TableGen/MultiClassInherit.td +++ b/test/TableGen/MultiClassInherit.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | grep {zing = 4} | count 28 +// RUN: llvm-tblgen %s | grep {zing = 4} | count 28 // XFAIL: vg_leak class C1 { diff --git a/test/TableGen/MultiPat.td b/test/TableGen/MultiPat.td new file mode 100644 index 000000000000..b3792777b6b5 --- /dev/null +++ b/test/TableGen/MultiPat.td @@ -0,0 +1,121 @@ +// RUN: llvm-tblgen %s | FileCheck %s +// XFAIL: vg_leak + +class ValueType { + int Size = size; + int Value = value; +} + +def v2i64 : ValueType<128, 22>; // 2 x i64 vector value +def v2f64 : ValueType<128, 28>; // 2 x f64 vector value + +class Intrinsic { + string Name = name; +} + +class Pattern resultInstrs> { + dag PatternToMatch = patternToMatch; + list ResultInstrs = resultInstrs; +} + +// Pat - A simple (but common) form of a pattern, which produces a simple result +// not needing a full list. +class Pat : Pattern; + +class Inst opcode, dag oopnds, dag iopnds, string asmstr, + list pattern> { + bits<8> Opcode = opcode; + dag OutOperands = oopnds; + dag InOperands = iopnds; + string AssemblyString = asmstr; + list Pattern = pattern; +} + +def ops; +def outs; +def ins; + +def set; + +// Define registers +class Register { + string Name = n; +} + +class RegisterClass regTypes, list regList> { + list RegTypes = regTypes; + list MemberList = regList; +} + +def XMM0: Register<"xmm0">; +def XMM1: Register<"xmm1">; +def XMM2: Register<"xmm2">; +def XMM3: Register<"xmm3">; +def XMM4: Register<"xmm4">; +def XMM5: Register<"xmm5">; +def XMM6: Register<"xmm6">; +def XMM7: Register<"xmm7">; +def XMM8: Register<"xmm8">; +def XMM9: Register<"xmm9">; +def XMM10: Register<"xmm10">; +def XMM11: Register<"xmm11">; +def XMM12: Register<"xmm12">; +def XMM13: Register<"xmm13">; +def XMM14: Register<"xmm14">; +def XMM15: Register<"xmm15">; + +def VR128 : RegisterClass<[v2i64, v2f64], + [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, + XMM8, XMM9, XMM10, XMM11, + XMM12, XMM13, XMM14, XMM15]>; + +// Dummy for subst +def REGCLASS : RegisterClass<[], []>; +def MNEMONIC; + +class decls { + // Dummy for foreach + dag pattern; + int operand; +} + +def Decls : decls; + +// Define intrinsics +def int_x86_sse2_add_ps : Intrinsic<"addps">; +def int_x86_sse2_add_pd : Intrinsic<"addpd">; +def INTRINSIC : Intrinsic<"Dummy">; +def bitconvert; + +class MakePat patterns> : Pat; + +class Base opcode, dag opnds, dag iopnds, string asmstr, Intrinsic intr, + list> patterns> + : Inst, + MakePat; + +multiclass arith opcode, string asmstr, string intr, list> patterns> { + def PS : Base(!subst("SUFFIX", "_ps", intr)), patterns>; + + def PD : Base(!subst("SUFFIX", "_pd", intr)), patterns>; +} + +defm ADD : arith<0x58, "add", "int_x86_sse2_addSUFFIX", + // rr Patterns + [[(set REGCLASS:$dst, (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))], + [(set REGCLASS:$dst, (bitconvert (INTRINSIC REGCLASS:$src1, REGCLASS:$src2))), + (MNEMONIC REGCLASS:$dst, REGCLASS:$src)]]>; + +// CHECK: [(set VR128:$dst, (int_x86_sse2_add_pd VR128:$src1, VR128:$src2))] +// CHECK: [(set VR128:$dst, (int_x86_sse2_add_ps VR128:$src1, VR128:$src2))] diff --git a/test/TableGen/SetTheory.td b/test/TableGen/SetTheory.td index e0abc631e0d2..a4acea907d80 100644 --- a/test/TableGen/SetTheory.td +++ b/test/TableGen/SetTheory.td @@ -1,5 +1,5 @@ // Test evaluation of set operations in dags. -// RUN: tblgen -print-sets %s | FileCheck %s +// RUN: llvm-tblgen -print-sets %s | FileCheck %s // XFAIL: vg_leak // // The -print-sets driver configures a primitive SetTheory instance that diff --git a/test/TableGen/Slice.td b/test/TableGen/Slice.td index 13d9da2b9fd6..2d2822c53b14 100644 --- a/test/TableGen/Slice.td +++ b/test/TableGen/Slice.td @@ -1,5 +1,5 @@ -// RUN: tblgen %s | grep {\\\[(set} | count 2 -// RUN: tblgen %s | grep {\\\[\\\]} | count 2 +// RUN: llvm-tblgen %s | grep {\\\[(set} | count 2 +// RUN: llvm-tblgen %s | grep {\\\[\\\]} | count 2 // XFAIL: vg_leak class ValueType { diff --git a/test/TableGen/String.td b/test/TableGen/String.td index fc0f5b8eb546..c71ed50f9860 100644 --- a/test/TableGen/String.td +++ b/test/TableGen/String.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak class x { string y = "missing terminating '\"' character"; diff --git a/test/TableGen/SuperSubclassSameName.td b/test/TableGen/SuperSubclassSameName.td index 304c883417fa..643b380ca005 100644 --- a/test/TableGen/SuperSubclassSameName.td +++ b/test/TableGen/SuperSubclassSameName.td @@ -1,4 +1,4 @@ -// RUN: tblgen < %s +// RUN: llvm-tblgen < %s // XFAIL: vg_leak // Test for template arguments that have the same name as superclass template // arguments. diff --git a/test/TableGen/TargetInstrInfo.td b/test/TableGen/TargetInstrInfo.td index 6c39d5ce57c3..e6c563b06aa5 100644 --- a/test/TableGen/TargetInstrInfo.td +++ b/test/TableGen/TargetInstrInfo.td @@ -1,6 +1,6 @@ // This test describes how we eventually want to describe instructions in // the target independent code generators. -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak // Target indep stuff. diff --git a/test/TableGen/TargetInstrSpec.td b/test/TableGen/TargetInstrSpec.td index a7ca9022f848..7b611e7c174d 100644 --- a/test/TableGen/TargetInstrSpec.td +++ b/test/TableGen/TargetInstrSpec.td @@ -1,5 +1,5 @@ -// RUN: tblgen %s | grep {\\\[(set VR128:\$dst, (int_x86_sse2_add_pd VR128:\$src1, VR128:\$src2))\\\]} | count 1 -// RUN: tblgen %s | grep {\\\[(set VR128:\$dst, (int_x86_sse2_add_ps VR128:\$src1, VR128:\$src2))\\\]} | count 1 +// RUN: llvm-tblgen %s | grep {\\\[(set VR128:\$dst, (int_x86_sse2_add_pd VR128:\$src1, VR128:\$src2))\\\]} | count 1 +// RUN: llvm-tblgen %s | grep {\\\[(set VR128:\$dst, (int_x86_sse2_add_ps VR128:\$src1, VR128:\$src2))\\\]} | count 1 // XFAIL: vg_leak class ValueType { diff --git a/test/TableGen/TemplateArgRename.td b/test/TableGen/TemplateArgRename.td index ee5d2cf77525..654b86dc03e2 100644 --- a/test/TableGen/TemplateArgRename.td +++ b/test/TableGen/TemplateArgRename.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak // Make sure there is no collision between XX and XX. diff --git a/test/TableGen/Tree.td b/test/TableGen/Tree.td index 2796cfd3586f..5190b96fcce1 100644 --- a/test/TableGen/Tree.td +++ b/test/TableGen/Tree.td @@ -1,5 +1,5 @@ // This tests to make sure we can parse tree patterns. -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak class TreeNode; diff --git a/test/TableGen/TreeNames.td b/test/TableGen/TreeNames.td index ccdeb88dd02a..b224e909f882 100644 --- a/test/TableGen/TreeNames.td +++ b/test/TableGen/TreeNames.td @@ -1,5 +1,5 @@ // This tests to make sure we can parse tree patterns with names. -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak class TreeNode; diff --git a/test/TableGen/UnsetBitInit.td b/test/TableGen/UnsetBitInit.td index ff7010868bc0..d232293d7872 100644 --- a/test/TableGen/UnsetBitInit.td +++ b/test/TableGen/UnsetBitInit.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s +// RUN: llvm-tblgen %s // XFAIL: vg_leak class x { field bits<32> A; diff --git a/test/TableGen/UnterminatedComment.td b/test/TableGen/UnterminatedComment.td index 158cede2607a..f92525a99164 100644 --- a/test/TableGen/UnterminatedComment.td +++ b/test/TableGen/UnterminatedComment.td @@ -1,4 +1,4 @@ -// RUN: not tblgen < %s >& /dev/null +// RUN: not llvm-tblgen < %s >& /dev/null def x; diff --git a/test/TableGen/cast.td b/test/TableGen/cast.td index 8164e74eae43..8a23eb4cc91f 100644 --- a/test/TableGen/cast.td +++ b/test/TableGen/cast.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | grep {add_ps} | count 3 +// RUN: llvm-tblgen %s | grep {add_ps} | count 3 // XFAIL: vg_leak class ValueType { diff --git a/test/TableGen/defmclass.td b/test/TableGen/defmclass.td index 57972b6dae54..80f03b319426 100644 --- a/test/TableGen/defmclass.td +++ b/test/TableGen/defmclass.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | FileCheck %s +// RUN: llvm-tblgen %s | FileCheck %s // XFAIL: vg_leak class XD { bits<4> Prefix = 11; } diff --git a/test/TableGen/eq.td b/test/TableGen/eq.td index 518a80ac0d26..f8daf880b9ed 100644 --- a/test/TableGen/eq.td +++ b/test/TableGen/eq.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | FileCheck %s +// RUN: llvm-tblgen %s | FileCheck %s // XFAIL: vg_leak // CHECK: Value = 0 // CHECK: Value = 1 diff --git a/test/TableGen/eqbit.td b/test/TableGen/eqbit.td index 3953252c4179..1d58fa0c1916 100644 --- a/test/TableGen/eqbit.td +++ b/test/TableGen/eqbit.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | FileCheck %s +// RUN: llvm-tblgen %s | FileCheck %s // XFAIL: vg_leak // CHECK: a = 6 // CHECK: a = 5 diff --git a/test/TableGen/foreach.td b/test/TableGen/foreach.td index d4d81f829ed7..cbcade921b91 100644 --- a/test/TableGen/foreach.td +++ b/test/TableGen/foreach.td @@ -1,6 +1,6 @@ -// RUN: tblgen %s | grep {Jr} | count 2 -// RUN: tblgen %s | grep {Sr} | count 2 -// RUN: tblgen %s | grep {NAME} | count 1 +// RUN: llvm-tblgen %s | grep {Jr} | count 2 +// RUN: llvm-tblgen %s | grep {Sr} | count 2 +// RUN: llvm-tblgen %s | grep {NAME} | count 1 // XFAIL: vg_leak // Variables for foreach diff --git a/test/TableGen/if.td b/test/TableGen/if.td index c4d953ea2245..18de368af9f1 100644 --- a/test/TableGen/if.td +++ b/test/TableGen/if.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | FileCheck %s +// RUN: llvm-tblgen %s | FileCheck %s // XFAIL: vg_leak // Support for an `!if' operator as part of a `let' statement. diff --git a/test/TableGen/ifbit.td b/test/TableGen/ifbit.td index 3b0349e19b4e..88f575e9acfc 100644 --- a/test/TableGen/ifbit.td +++ b/test/TableGen/ifbit.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | FileCheck %s +// RUN: llvm-tblgen %s | FileCheck %s // XFAIL: vg_leak // CHECK: a = 6 // CHECK: a = 5 diff --git a/test/TableGen/lisp.td b/test/TableGen/lisp.td index bbed8690dd5d..025aca961cd5 100644 --- a/test/TableGen/lisp.td +++ b/test/TableGen/lisp.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | grep {} +// RUN: llvm-tblgen %s | grep {} // XFAIL: vg_leak class List n> { diff --git a/test/TableGen/nested-comment.td b/test/TableGen/nested-comment.td index 68e29581bc7f..bf030e77a4b0 100644 --- a/test/TableGen/nested-comment.td +++ b/test/TableGen/nested-comment.td @@ -1,4 +1,5 @@ -// RUN: tblgen < %s +// RUN: llvm-tblgen < %s +// XFAIL: vg_leak /* foo diff --git a/test/TableGen/strconcat.td b/test/TableGen/strconcat.td index 38409a99dc4e..85ee831b4dae 100644 --- a/test/TableGen/strconcat.td +++ b/test/TableGen/strconcat.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | grep fufoo +// RUN: llvm-tblgen %s | grep fufoo // XFAIL: vg_leak class Y { diff --git a/test/TableGen/subst.td b/test/TableGen/subst.td index 05d424f68355..5a73ec4f1294 100644 --- a/test/TableGen/subst.td +++ b/test/TableGen/subst.td @@ -1,9 +1,9 @@ -// RUN: tblgen %s | grep {Smith} | count 7 -// RUN: tblgen %s | grep {Johnson} | count 2 -// RUN: tblgen %s | grep {FIRST} | count 1 -// RUN: tblgen %s | grep {LAST} | count 1 -// RUN: tblgen %s | grep {TVAR} | count 2 -// RUN: tblgen %s | grep {Bogus} | count 1 +// RUN: llvm-tblgen %s | grep {Smith} | count 7 +// RUN: llvm-tblgen %s | grep {Johnson} | count 2 +// RUN: llvm-tblgen %s | grep {FIRST} | count 1 +// RUN: llvm-tblgen %s | grep {LAST} | count 1 +// RUN: llvm-tblgen %s | grep {TVAR} | count 2 +// RUN: llvm-tblgen %s | grep {Bogus} | count 1 // XFAIL: vg_leak class Honorific { diff --git a/test/TableGen/subst2.td b/test/TableGen/subst2.td index 584266ef2335..7c007f7db12e 100644 --- a/test/TableGen/subst2.td +++ b/test/TableGen/subst2.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | FileCheck %s +// RUN: llvm-tblgen %s | FileCheck %s // XFAIL: vg_leak // CHECK: No subst // CHECK: No foo diff --git a/test/TableGen/usevalname.td b/test/TableGen/usevalname.td index 1b31c8f15061..d85b98ac33e6 100644 --- a/test/TableGen/usevalname.td +++ b/test/TableGen/usevalname.td @@ -1,4 +1,4 @@ -// RUN: tblgen %s | FileCheck %s +// RUN: llvm-tblgen %s | FileCheck %s // XFAIL: vg_leak class Instr pat> { diff --git a/test/Transforms/ADCE/2003-09-10-UnwindInstFail.ll b/test/Transforms/ADCE/2003-09-10-UnwindInstFail.ll index 444ca8ec904b..6bbcfdb67ec5 100644 --- a/test/Transforms/ADCE/2003-09-10-UnwindInstFail.ll +++ b/test/Transforms/ADCE/2003-09-10-UnwindInstFail.ll @@ -8,7 +8,9 @@ then: ; preds = %0 to label %invoke_cont unwind label %invoke_catch invoke_catch: ; preds = %then - unwind + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup + resume { i8*, i32 } %exn invoke_cont: ; preds = %then ret void @@ -17,3 +19,4 @@ endif: ; preds = %0 ret void } +declare i32 @__gxx_personality_v0(...) diff --git a/test/Transforms/ADCE/2004-05-04-UnreachableBlock.ll b/test/Transforms/ADCE/2004-05-04-UnreachableBlock.ll index a6a41fd69eff..7ee0f468af0b 100644 --- a/test/Transforms/ADCE/2004-05-04-UnreachableBlock.ll +++ b/test/Transforms/ADCE/2004-05-04-UnreachableBlock.ll @@ -11,6 +11,6 @@ invoke_catch.0: ; No predecessors! br i1 false, label %UnifiedUnwindBlock, label %UnifiedReturnBlock UnifiedUnwindBlock: ; preds = %invoke_catch.0 - unwind + unreachable } diff --git a/test/Transforms/ADCE/2005-02-17-PHI-Invoke-Crash.ll b/test/Transforms/ADCE/2005-02-17-PHI-Invoke-Crash.ll index 991e876a25b7..4ddc2f180a2d 100644 --- a/test/Transforms/ADCE/2005-02-17-PHI-Invoke-Crash.ll +++ b/test/Transforms/ADCE/2005-02-17-PHI-Invoke-Crash.ll @@ -15,17 +15,21 @@ tmp.3.i.noexc: ; preds = %entry br i1 false, label %then.0, label %else.0 invoke_catch.0: ; preds = %entry + %exn.0 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup invoke void @q_atomic_decrement( ) to label %tmp.1.i.i183.noexc unwind label %terminate tmp.1.i.i183.noexc: ; preds = %invoke_catch.0 - unwind + ret void then.0: ; preds = %tmp.3.i.noexc invoke void @_ZN10QByteArray6resizeEi( ) to label %invoke_cont.1 unwind label %invoke_catch.1 invoke_catch.1: ; preds = %then.0 + %exn.1 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup invoke void @q_atomic_decrement( ) to label %tmp.1.i.i162.noexc unwind label %terminate @@ -40,6 +44,9 @@ else.0: ; preds = %tmp.3.i.noexc terminate: ; preds = %invoke_catch.1, %invoke_catch.0 %dbg.0.1 = phi { }* [ null, %invoke_catch.1 ], [ null, %invoke_catch.0 ] ; <{ }*> [#uses=0] + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup unreachable } +declare i32 @__gxx_personality_v0(...) diff --git a/test/Transforms/ADCE/dce_pure_invoke.ll b/test/Transforms/ADCE/dce_pure_invoke.ll index c16d45cc2393..8e7851804575 100644 --- a/test/Transforms/ADCE/dce_pure_invoke.ll +++ b/test/Transforms/ADCE/dce_pure_invoke.ll @@ -11,5 +11,9 @@ Cont: ; preds = %0 ret i32 0 Other: ; preds = %0 + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup ret i32 1 } + +declare i32 @__gxx_personality_v0(...) diff --git a/test/Transforms/CodeExtractor/2004-03-18-InvokeHandling.ll b/test/Transforms/CodeExtractor/2004-03-18-InvokeHandling.ll index 91e9799ad9ca..ff5de6b73e21 100644 --- a/test/Transforms/CodeExtractor/2004-03-18-InvokeHandling.ll +++ b/test/Transforms/CodeExtractor/2004-03-18-InvokeHandling.ll @@ -190,5 +190,9 @@ return: ; preds = %entry ret void LongJmpBlkPre: ; preds = %endif.52, %then.40 + %exn = landingpad { i8*, i32 } personality i32 (...)* @__gcc_personality_v0 + catch i8* null ret void } + +declare i32 @__gcc_personality_v0(...) diff --git a/test/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll b/test/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll index fc58577f67ab..92603d9e634e 100644 --- a/test/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll +++ b/test/Transforms/CodeExtractor/2004-11-12-InvokeExtract.ll @@ -10,6 +10,9 @@ Cont: ; preds = %EB ret i32 %V Unw: ; preds = %EB - unwind + %exn = landingpad { i8*, i32 } personality i32 (...)* @__gcc_personality_v0 + catch i8* null + resume { i8*, i32 } %exn } +declare i32 @__gcc_personality_v0(...) diff --git a/test/Transforms/ConstantMerge/merge-both.ll b/test/Transforms/ConstantMerge/merge-both.ll index 0282f464aeee..b71eb437dbc3 100644 --- a/test/Transforms/ConstantMerge/merge-both.ll +++ b/test/Transforms/ConstantMerge/merge-both.ll @@ -1,5 +1,7 @@ ; RUN: opt -constmerge %s -S -o - | FileCheck %s ; Test that in one run var3 is merged into var2 and var1 into var4. +; Test that we merge @var5 and @var6 into one with the higher alignment, and +; don't merge var7/var8 into var5/var6. declare void @zed(%struct.foobar*, %struct.foobar*) @@ -14,13 +16,24 @@ declare void @zed(%struct.foobar*, %struct.foobar*) ; CHECK-NOT: @ ; CHECK: @var2 = constant %struct.foobar { i32 2 } ; CHECK-NEXT: @var4 = constant %struct.foobar { i32 2 } -; CHECK-NOT: @ -; CHECK: declare void @zed(%struct.foobar*, %struct.foobar*) + +declare void @helper([16 x i8]*) +@var5 = internal constant [16 x i8] c"foo1bar2foo3bar\00", align 16 +@var6 = private unnamed_addr constant [16 x i8] c"foo1bar2foo3bar\00", align 1 +@var7 = internal constant [16 x i8] c"foo1bar2foo3bar\00" +@var8 = private unnamed_addr constant [16 x i8] c"foo1bar2foo3bar\00" + +; CHECK-NEXT: @var6 = private constant [16 x i8] c"foo1bar2foo3bar\00", align 16 +; CHECK-NEXT: @var8 = private constant [16 x i8] c"foo1bar2foo3bar\00" define i32 @main() { entry: call void @zed(%struct.foobar* @var1, %struct.foobar* @var2) call void @zed(%struct.foobar* @var3, %struct.foobar* @var4) + call void @helper([16 x i8]* @var5) + call void @helper([16 x i8]* @var6) + call void @helper([16 x i8]* @var7) + call void @helper([16 x i8]* @var8) ret i32 0 } diff --git a/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll b/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll index 161821f3f8f7..fc25daca1c2e 100644 --- a/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll +++ b/test/Transforms/DeadArgElim/2009-03-17-MRE-Invoke.ll @@ -11,6 +11,8 @@ T: %y = extractvalue {i32,i32} %x, 1 ret i32 %y T2: + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup unreachable } @@ -22,5 +24,9 @@ T: %y = extractvalue {i32,i32} %x, 1 ret i32 %y T2: + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup unreachable } + +declare i32 @__gxx_personality_v0(...) diff --git a/test/Transforms/DeadArgElim/deadexternal.ll b/test/Transforms/DeadArgElim/deadexternal.ll index 84092613130b..b2d63ec77209 100644 --- a/test/Transforms/DeadArgElim/deadexternal.ll +++ b/test/Transforms/DeadArgElim/deadexternal.ll @@ -31,7 +31,7 @@ define void @h() { entry: %i = alloca i32, align 4 volatile store i32 10, i32* %i, align 4 -; CHECK: %tmp = volatile load i32* %i, align 4 +; CHECK: %tmp = load volatile i32* %i, align 4 ; CHECK-next: call void @f(i32 undef) %tmp = volatile load i32* %i, align 4 call void @f(i32 %tmp) diff --git a/test/Transforms/DeadStoreElimination/2011-09-06-EndOfFunction.ll b/test/Transforms/DeadStoreElimination/2011-09-06-EndOfFunction.ll new file mode 100644 index 000000000000..c5cc101a5f7b --- /dev/null +++ b/test/Transforms/DeadStoreElimination/2011-09-06-EndOfFunction.ll @@ -0,0 +1,27 @@ +; RUN: opt -dse -S < %s | 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-n8:16:32:64" +target triple = "x86_64-apple-darwin" + +%"class.std::auto_ptr" = type { i32* } + +; CHECK: @_Z3foov +define void @_Z3foov(%"class.std::auto_ptr"* noalias nocapture sret %agg.result) uwtable ssp { +_ZNSt8auto_ptrIiED1Ev.exit: + %temp.lvalue = alloca %"class.std::auto_ptr", align 8 + call void @_Z3barv(%"class.std::auto_ptr"* sret %temp.lvalue) + %_M_ptr.i.i = getelementptr inbounds %"class.std::auto_ptr"* %temp.lvalue, i64 0, i32 0 + %tmp.i.i = load i32** %_M_ptr.i.i, align 8, !tbaa !0 +; CHECK-NOT: store i32* null + store i32* null, i32** %_M_ptr.i.i, align 8, !tbaa !0 + %_M_ptr.i.i4 = getelementptr inbounds %"class.std::auto_ptr"* %agg.result, i64 0, i32 0 + store i32* %tmp.i.i, i32** %_M_ptr.i.i4, align 8, !tbaa !0 +; CHECK: ret void + ret void +} + +declare void @_Z3barv(%"class.std::auto_ptr"* sret) + +!0 = metadata !{metadata !"any pointer", metadata !1} +!1 = metadata !{metadata !"omnipotent char", metadata !2} +!2 = metadata !{metadata !"Simple C/C++ TBAA", null} diff --git a/test/Transforms/DeadStoreElimination/2011-09-06-MemCpy.ll b/test/Transforms/DeadStoreElimination/2011-09-06-MemCpy.ll new file mode 100644 index 000000000000..22b87864c063 --- /dev/null +++ b/test/Transforms/DeadStoreElimination/2011-09-06-MemCpy.ll @@ -0,0 +1,85 @@ +; RUN: opt -dse -S < %s | 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-f128:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +%struct.pair.162 = type { %struct.BasicBlock*, i32, [4 x i8] } +%struct.BasicBlock = type { %struct.Value, %struct.ilist_node.24, %struct.iplist.22, %struct.Function* } +%struct.Value = type { i32 (...)**, i8, i8, i16, %struct.Type*, %struct.Use*, %struct.StringMapEntry* } +%struct.Type = type { %struct.LLVMContext*, i8, [3 x i8], i32, {}* } +%struct.LLVMContext = type { %struct.LLVMContextImpl* } +%struct.LLVMContextImpl = type opaque +%struct.Use = type { %struct.Value*, %struct.Use*, %struct.PointerIntPair } +%struct.PointerIntPair = type { i64 } +%struct.StringMapEntry = type opaque +%struct.ilist_node.24 = type { %struct.ilist_half_node.23, %struct.BasicBlock* } +%struct.ilist_half_node.23 = type { %struct.BasicBlock* } +%struct.iplist.22 = type { %struct.ilist_traits.21, %struct.Instruction* } +%struct.ilist_traits.21 = type { %struct.ilist_half_node.25 } +%struct.ilist_half_node.25 = type { %struct.Instruction* } +%struct.Instruction = type { [52 x i8], %struct.ilist_node.26, %struct.BasicBlock*, %struct.DebugLoc } +%struct.ilist_node.26 = type { %struct.ilist_half_node.25, %struct.Instruction* } +%struct.DebugLoc = type { i32, i32 } +%struct.Function = type { %struct.GlobalValue, %struct.ilist_node.14, %struct.iplist.4, %struct.iplist, %struct.ValueSymbolTable*, %struct.AttrListPtr } +%struct.GlobalValue = type <{ [52 x i8], [4 x i8], %struct.Module*, i8, i16, [5 x i8], %struct.basic_string }> +%struct.Module = type { %struct.LLVMContext*, %struct.iplist.20, %struct.iplist.16, %struct.iplist.12, %struct.vector.2, %struct.ilist, %struct.basic_string, %struct.ValueSymbolTable*, %struct.OwningPtr, %struct.basic_string, %struct.basic_string, %struct.basic_string, i8* } +%struct.iplist.20 = type { %struct.ilist_traits.19, %struct.GlobalVariable* } +%struct.ilist_traits.19 = type { %struct.ilist_node.18 } +%struct.ilist_node.18 = type { %struct.ilist_half_node.17, %struct.GlobalVariable* } +%struct.ilist_half_node.17 = type { %struct.GlobalVariable* } +%struct.GlobalVariable = type { %struct.GlobalValue, %struct.ilist_node.18, i8, [7 x i8] } +%struct.iplist.16 = type { %struct.ilist_traits.15, %struct.Function* } +%struct.ilist_traits.15 = type { %struct.ilist_node.14 } +%struct.ilist_node.14 = type { %struct.ilist_half_node.13, %struct.Function* } +%struct.ilist_half_node.13 = type { %struct.Function* } +%struct.iplist.12 = type { %struct.ilist_traits.11, %struct.GlobalAlias* } +%struct.ilist_traits.11 = type { %struct.ilist_node.10 } +%struct.ilist_node.10 = type { %struct.ilist_half_node.9, %struct.GlobalAlias* } +%struct.ilist_half_node.9 = type { %struct.GlobalAlias* } +%struct.GlobalAlias = type { %struct.GlobalValue, %struct.ilist_node.10 } +%struct.vector.2 = type { %struct._Vector_base.1 } +%struct._Vector_base.1 = type { %struct._Vector_impl.0 } +%struct._Vector_impl.0 = type { %struct.basic_string*, %struct.basic_string*, %struct.basic_string* } +%struct.basic_string = type { %struct._Alloc_hider } +%struct._Alloc_hider = type { i8* } +%struct.ilist = type { %struct.iplist.8 } +%struct.iplist.8 = type { %struct.ilist_traits.7, %struct.NamedMDNode* } +%struct.ilist_traits.7 = type { %struct.ilist_node.6 } +%struct.ilist_node.6 = type { %struct.ilist_half_node.5, %struct.NamedMDNode* } +%struct.ilist_half_node.5 = type { %struct.NamedMDNode* } +%struct.NamedMDNode = type { %struct.ilist_node.6, %struct.basic_string, %struct.Module*, i8* } +%struct.ValueSymbolTable = type opaque +%struct.OwningPtr = type { %struct.GVMaterializer* } +%struct.GVMaterializer = type opaque +%struct.iplist.4 = type { %struct.ilist_traits.3, %struct.BasicBlock* } +%struct.ilist_traits.3 = type { %struct.ilist_half_node.23 } +%struct.iplist = type { %struct.ilist_traits, %struct.Argument* } +%struct.ilist_traits = type { %struct.ilist_half_node } +%struct.ilist_half_node = type { %struct.Argument* } +%struct.Argument = type { %struct.Value, %struct.ilist_node, %struct.Function* } +%struct.ilist_node = type { %struct.ilist_half_node, %struct.Argument* } +%struct.AttrListPtr = type { %struct.AttributeListImpl* } +%struct.AttributeListImpl = type opaque + +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind + +; CHECK: _ZSt9iter_swapIPSt4pairIPN4llvm10BasicBlockEjES5_EvT_T0_ +; CHECK: store +; CHECK: ret void +define void @_ZSt9iter_swapIPSt4pairIPN4llvm10BasicBlockEjES5_EvT_T0_(%struct.pair.162* %__a, %struct.pair.162* %__b) nounwind uwtable inlinehint { +entry: + %memtmp = alloca %struct.pair.162, align 8 + %0 = getelementptr inbounds %struct.pair.162* %memtmp, i64 0, i32 0 + %1 = getelementptr inbounds %struct.pair.162* %__a, i64 0, i32 0 + %2 = load %struct.BasicBlock** %1, align 8 + store %struct.BasicBlock* %2, %struct.BasicBlock** %0, align 8 + %3 = getelementptr inbounds %struct.pair.162* %memtmp, i64 0, i32 1 + %4 = getelementptr inbounds %struct.pair.162* %__a, i64 0, i32 1 + %5 = load i32* %4, align 4 + store i32 %5, i32* %3, align 8 + %6 = bitcast %struct.pair.162* %__a to i8* + %7 = bitcast %struct.pair.162* %__b to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %6, i8* %7, i64 12, i32 1, i1 false) + %8 = bitcast %struct.pair.162* %memtmp to i8* + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %7, i8* %8, i64 12, i32 1, i1 false) + ret void +} diff --git a/test/Transforms/DeadStoreElimination/atomic.ll b/test/Transforms/DeadStoreElimination/atomic.ll new file mode 100644 index 000000000000..2e84298ad400 --- /dev/null +++ b/test/Transforms/DeadStoreElimination/atomic.ll @@ -0,0 +1,107 @@ +; RUN: opt -basicaa -dse -S < %s | 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-n8:16:32:64" +target triple = "x86_64-apple-macosx10.7.0" + +; Sanity tests for atomic stores. +; Note that it turns out essentially every transformation DSE does is legal on +; atomic ops, just some transformations are not allowed across them. + +@x = common global i32 0, align 4 +@y = common global i32 0, align 4 + +declare void @randomop(i32*) + +; DSE across unordered store (allowed) +define void @test1() nounwind uwtable ssp { +; CHECK: test1 +; CHECK-NOT: store i32 0 +; CHECK: store i32 1 +entry: + store i32 0, i32* @x + store atomic i32 0, i32* @y unordered, align 4 + store i32 1, i32* @x + ret void +} + +; DSE across seq_cst load (allowed in theory; not implemented ATM) +define i32 @test2() nounwind uwtable ssp { +; CHECK: test2 +; CHECK: store i32 0 +; CHECK: store i32 1 +entry: + store i32 0, i32* @x + %x = load atomic i32* @y seq_cst, align 4 + store i32 1, i32* @x + ret i32 %x +} + +; DSE across seq_cst store (store before atomic store must not be removed) +define void @test3() nounwind uwtable ssp { +; CHECK: test3 +; CHECK: store i32 +; CHECK: store atomic i32 2 +entry: + store i32 0, i32* @x + store atomic i32 2, i32* @y seq_cst, align 4 + store i32 1, i32* @x + ret void +} + +; DSE remove unordered store (allowed) +define void @test4() nounwind uwtable ssp { +; CHECK: test4 +; CHECK-NOT: store atomic +; CHECK: store i32 1 +entry: + store atomic i32 0, i32* @x unordered, align 4 + store i32 1, i32* @x + ret void +} + +; DSE unordered store overwriting non-atomic store (allowed) +define void @test5() nounwind uwtable ssp { +; CHECK: test5 +; CHECK: store atomic i32 1 +entry: + store i32 0, i32* @x + store atomic i32 1, i32* @x unordered, align 4 + ret void +} + +; DSE no-op unordered atomic store (allowed) +define void @test6() nounwind uwtable ssp { +; CHECK: test6 +; CHECK-NOT: store +; CHECK: ret void +entry: + %x = load atomic i32* @x unordered, align 4 + store atomic i32 %x, i32* @x unordered, align 4 + ret void +} + +; DSE seq_cst store (be conservative; DSE doesn't have infrastructure +; to reason about atomic operations). +define void @test7() nounwind uwtable ssp { +; CHECK: test7 +; CHECK: store atomic +entry: + %a = alloca i32 + store atomic i32 0, i32* %a seq_cst, align 4 + ret void +} + +; DSE and seq_cst load (be conservative; DSE doesn't have infrastructure +; to reason about atomic operations). +define i32 @test8() nounwind uwtable ssp { +; CHECK: test8 +; CHECK: store +; CHECK: load atomic +entry: + %a = alloca i32 + call void @randomop(i32* %a) + store i32 0, i32* %a, align 4 + %x = load atomic i32* @x seq_cst, align 4 + ret i32 %x +} + diff --git a/test/Transforms/DeadStoreElimination/simple.ll b/test/Transforms/DeadStoreElimination/simple.ll index 5f143fcd1ede..ec2f15737a37 100644 --- a/test/Transforms/DeadStoreElimination/simple.ll +++ b/test/Transforms/DeadStoreElimination/simple.ll @@ -42,20 +42,20 @@ define i32 @test3(i32* %g_addr) nounwind { define void @test4(i32* %Q) { %a = load i32* %Q - volatile store i32 %a, i32* %Q + store volatile i32 %a, i32* %Q ret void ; CHECK: @test4 ; CHECK-NEXT: load i32 -; CHECK-NEXT: volatile store +; CHECK-NEXT: store volatile ; CHECK-NEXT: ret void } define void @test5(i32* %Q) { - %a = volatile load i32* %Q + %a = load volatile i32* %Q store i32 %a, i32* %Q ret void ; CHECK: @test5 -; CHECK-NEXT: volatile load +; CHECK-NEXT: load volatile ; CHECK-NEXT: ret void } diff --git a/test/Transforms/EarlyCSE/basic.ll b/test/Transforms/EarlyCSE/basic.ll index e3c75f97dcfc..57b1697ff4de 100644 --- a/test/Transforms/EarlyCSE/basic.ll +++ b/test/Transforms/EarlyCSE/basic.ll @@ -13,21 +13,21 @@ define void @test1(i8 %V, i32 *%P) { volatile store i32 %C, i32* %P volatile store i32 %D, i32* %P ; CHECK-NEXT: %C = zext i8 %V to i32 - ; CHECK-NEXT: volatile store i32 %C - ; CHECK-NEXT: volatile store i32 %C + ; CHECK-NEXT: store volatile i32 %C + ; CHECK-NEXT: store volatile i32 %C %E = add i32 %C, %C %F = add i32 %C, %C volatile store i32 %E, i32* %P volatile store i32 %F, i32* %P ; CHECK-NEXT: %E = add i32 %C, %C - ; CHECK-NEXT: volatile store i32 %E - ; CHECK-NEXT: volatile store i32 %E + ; CHECK-NEXT: store volatile i32 %E + ; CHECK-NEXT: store volatile i32 %E %G = add nuw i32 %C, %C ;; not a CSE with E volatile store i32 %G, i32* %P ; CHECK-NEXT: %G = add nuw i32 %C, %C - ; CHECK-NEXT: volatile store i32 %G + ; CHECK-NEXT: store volatile i32 %G ret void } diff --git a/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll b/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll index 53857f61ce58..e2bab19e7efd 100644 --- a/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll +++ b/test/Transforms/FunctionAttrs/2008-12-31-NoCapture.ll @@ -46,9 +46,13 @@ define i1 @c6(i8* %q, i8 %bit) { ret0: ret i1 0 ret1: + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup ret i1 1 } +declare i32 @__gxx_personality_v0(...) + define i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind { %tmp = ptrtoint i32* %q to i32 %tmp2 = lshr i32 %tmp, %bitno diff --git a/test/Transforms/FunctionAttrs/atomic.ll b/test/Transforms/FunctionAttrs/atomic.ll new file mode 100644 index 000000000000..7c2bff7a05f7 --- /dev/null +++ b/test/Transforms/FunctionAttrs/atomic.ll @@ -0,0 +1,21 @@ +; RUN: opt -basicaa -functionattrs -S < %s | FileCheck %s + +; Atomic load/store to local doesn't affect whether a function is +; readnone/readonly. +define i32 @test1(i32 %x) uwtable ssp { +; CHECK: define i32 @test1(i32 %x) uwtable readnone ssp { +entry: + %x.addr = alloca i32, align 4 + store atomic i32 %x, i32* %x.addr seq_cst, align 4 + %r = load atomic i32* %x.addr seq_cst, align 4 + ret i32 %r +} + +; A function with an Acquire load is not readonly. +define i32 @test2(i32* %x) uwtable ssp { +; CHECK: define i32 @test2(i32* nocapture %x) uwtable ssp { +entry: + %r = load atomic i32* %x seq_cst, align 4 + ret i32 %r +} + diff --git a/test/Transforms/GVN/2010-05-08-OneBit.ll b/test/Transforms/GVN/2010-05-08-OneBit.ll index 1809cf03f900..480ce8ba0ae1 100644 --- a/test/Transforms/GVN/2010-05-08-OneBit.ll +++ b/test/Transforms/GVN/2010-05-08-OneBit.ll @@ -45,6 +45,8 @@ k151.i.i: ; preds = %k133.i.i ret i32 0 landing_pad: ; preds = %l147.i.i, %l129.i.i, %l117.i.i + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup switch i32 undef, label %fin [ i32 1, label %catch1 i32 2, label %catch @@ -61,3 +63,5 @@ catch1: ; preds = %landing_pad } declare fastcc void @foo() + +declare i32 @__gxx_personality_v0(...) diff --git a/test/Transforms/GVN/2011-09-07-TypeIdFor.ll b/test/Transforms/GVN/2011-09-07-TypeIdFor.ll new file mode 100644 index 000000000000..314b5bb113a6 --- /dev/null +++ b/test/Transforms/GVN/2011-09-07-TypeIdFor.ll @@ -0,0 +1,81 @@ +; RUN: opt < %s -basicaa -gvn -S | FileCheck %s +%struct.__fundamental_type_info_pseudo = type { %struct.__type_info_pseudo } +%struct.__type_info_pseudo = type { i8*, i8* } + +@_ZTIi = external constant %struct.__fundamental_type_info_pseudo +@_ZTIb = external constant %struct.__fundamental_type_info_pseudo + +declare void @_Z4barv() + +declare void @_Z7cleanupv() + +declare i32 @llvm.eh.typeid.for(i8*) nounwind readonly + +declare i8* @__cxa_begin_catch(i8*) nounwind + +declare void @__cxa_end_catch() + +declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*) + +define void @_Z3foov() uwtable { +entry: + invoke void @_Z4barv() + to label %return unwind label %lpad + +lpad: ; preds = %entry + %0 = landingpad { i8*, i32 } personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0 + catch %struct.__fundamental_type_info_pseudo* @_ZTIi + catch %struct.__fundamental_type_info_pseudo* @_ZTIb + catch %struct.__fundamental_type_info_pseudo* @_ZTIi + catch %struct.__fundamental_type_info_pseudo* @_ZTIb + %exc_ptr2.i = extractvalue { i8*, i32 } %0, 0 + %filter3.i = extractvalue { i8*, i32 } %0, 1 + %typeid.i = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIi to i8*)) +; CHECK: call i32 @llvm.eh.typeid.for + %1 = icmp eq i32 %filter3.i, %typeid.i + br i1 %1, label %ppad, label %next + +next: ; preds = %lpad + %typeid1.i = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIb to i8*)) +; CHECK: call i32 @llvm.eh.typeid.for + %2 = icmp eq i32 %filter3.i, %typeid1.i + br i1 %2, label %ppad2, label %next2 + +ppad: ; preds = %lpad + %3 = tail call i8* @__cxa_begin_catch(i8* %exc_ptr2.i) nounwind + tail call void @__cxa_end_catch() nounwind + br label %return + +ppad2: ; preds = %next + %D.2073_5.i = tail call i8* @__cxa_begin_catch(i8* %exc_ptr2.i) nounwind + tail call void @__cxa_end_catch() nounwind + br label %return + +next2: ; preds = %next + call void @_Z7cleanupv() + %typeid = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIi to i8*)) +; CHECK-NOT: call i32 @llvm.eh.typeid.for + %4 = icmp eq i32 %filter3.i, %typeid + br i1 %4, label %ppad3, label %next3 + +next3: ; preds = %next2 + %typeid1 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (%struct.__fundamental_type_info_pseudo* @_ZTIb to i8*)) + %5 = icmp eq i32 %filter3.i, %typeid1 + br i1 %5, label %ppad4, label %unwind + +unwind: ; preds = %next3 + resume { i8*, i32 } %0 + +ppad3: ; preds = %next2 + %6 = tail call i8* @__cxa_begin_catch(i8* %exc_ptr2.i) nounwind + tail call void @__cxa_end_catch() nounwind + br label %return + +ppad4: ; preds = %next3 + %D.2080_5 = tail call i8* @__cxa_begin_catch(i8* %exc_ptr2.i) nounwind + tail call void @__cxa_end_catch() nounwind + br label %return + +return: ; preds = %ppad4, %ppad3, %ppad2, %ppad, %entry + ret void +} diff --git a/test/Transforms/GVN/atomic.ll b/test/Transforms/GVN/atomic.ll new file mode 100644 index 000000000000..094e22bd07e1 --- /dev/null +++ b/test/Transforms/GVN/atomic.ll @@ -0,0 +1,80 @@ +; RUN: opt -basicaa -gvn -S < %s | 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-n8:16:32:64" +target triple = "x86_64-apple-macosx10.7.0" + +@x = common global i32 0, align 4 +@y = common global i32 0, align 4 + +; GVN across unordered store (allowed) +define i32 @test1() nounwind uwtable ssp { +; CHECK: test1 +; CHECK: add i32 %x, %x +entry: + %x = load i32* @y + store atomic i32 %x, i32* @x unordered, align 4 + %y = load i32* @y + %z = add i32 %x, %y + ret i32 %z +} + +; GVN across seq_cst store (allowed in theory; not implemented ATM) +define i32 @test2() nounwind uwtable ssp { +; CHECK: test2 +; CHECK: add i32 %x, %y +entry: + %x = load i32* @y + store atomic i32 %x, i32* @x seq_cst, align 4 + %y = load i32* @y + %z = add i32 %x, %y + ret i32 %z +} + +; GVN across unordered load (allowed) +define i32 @test3() nounwind uwtable ssp { +; CHECK: test3 +; CHECK: add i32 %x, %x +entry: + %x = load i32* @y + %y = load atomic i32* @x unordered, align 4 + %z = load i32* @y + %a = add i32 %x, %z + %b = add i32 %y, %a + ret i32 %b +} + +; GVN across acquire load (load after atomic load must not be removed) +define i32 @test4() nounwind uwtable ssp { +; CHECK: test4 +; CHECK: load atomic i32* @x +; CHECK: load i32* @y +entry: + %x = load i32* @y + %y = load atomic i32* @x seq_cst, align 4 + %x2 = load i32* @y + %x3 = add i32 %x, %x2 + %y2 = add i32 %y, %x3 + ret i32 %y2 +} + +; GVN load to unordered load (allowed) +define i32 @test5() nounwind uwtable ssp { +; CHECK: test5 +; CHECK: add i32 %x, %x +entry: + %x = load atomic i32* @x unordered, align 4 + %y = load i32* @x + %z = add i32 %x, %y + ret i32 %z +} + +; GVN unordered load to load (unordered load must not be removed) +define i32 @test6() nounwind uwtable ssp { +; CHECK: test6 +; CHECK: load atomic i32* @x unordered +entry: + %x = load i32* @x + %x2 = load atomic i32* @x unordered, align 4 + %x3 = add i32 %x, %x2 + ret i32 %x3 +} diff --git a/test/Transforms/GVN/condprop.ll b/test/Transforms/GVN/condprop.ll index be6c3498fe40..0b31b01b7b14 100644 --- a/test/Transforms/GVN/condprop.ll +++ b/test/Transforms/GVN/condprop.ll @@ -2,8 +2,8 @@ @a = external global i32 ; [#uses=7] -; CHECK: @foo -define i32 @foo() nounwind { +; CHECK: @test1 +define i32 @test1() nounwind { entry: %0 = load i32* @a, align 4 %1 = icmp eq i32 %0, 4 @@ -52,4 +52,81 @@ bb8: ; preds = %bb7, %bb6, %bb4, %bb2, %bb return: ; preds = %bb8 ret i32 %.0 -} \ No newline at end of file +} + +declare void @foo(i1) + +; CHECK: @test2 +define void @test2(i1 %x, i1 %y) { + %z = or i1 %x, %y + br i1 %z, label %true, label %false +true: +; CHECK: true: + %z2 = or i1 %x, %y + call void @foo(i1 %z2) +; CHECK: call void @foo(i1 true) + br label %true +false: +; CHECK: false: + %z3 = or i1 %x, %y + call void @foo(i1 %z3) +; CHECK: call void @foo(i1 false) + br label %false +} + +declare void @bar(i32) + +; CHECK: @test3 +define void @test3(i32 %x, i32 %y) { + %xz = icmp eq i32 %x, 0 + %yz = icmp eq i32 %y, 0 + %z = and i1 %xz, %yz + br i1 %z, label %both_zero, label %nope +both_zero: + call void @foo(i1 %xz) +; CHECK: call void @foo(i1 true) + call void @foo(i1 %yz) +; CHECK: call void @foo(i1 true) + call void @bar(i32 %x) +; CHECK: call void @bar(i32 0) + call void @bar(i32 %y) +; CHECK: call void @bar(i32 0) + ret void +nope: + call void @foo(i1 %z) +; CHECK: call void @foo(i1 false) + ret void +} + +; CHECK: @test4 +define void @test4(i1 %b, i32 %x) { + br i1 %b, label %sw, label %case3 +sw: + switch i32 %x, label %default [ + i32 0, label %case0 + i32 1, label %case1 + i32 2, label %case0 + i32 3, label %case3 + i32 4, label %default + ] +default: +; CHECK: default: + call void @bar(i32 %x) +; CHECK: call void @bar(i32 %x) + ret void +case0: +; CHECK: case0: + call void @bar(i32 %x) +; CHECK: call void @bar(i32 %x) + ret void +case1: +; CHECK: case1: + call void @bar(i32 %x) +; CHECK: call void @bar(i32 1) + ret void +case3: +; CHECK: case3: + call void @bar(i32 %x) +; CHECK: call void @bar(i32 %x) + ret void +} diff --git a/test/Transforms/GVN/phi-translate.ll b/test/Transforms/GVN/phi-translate.ll index f10537e0c930..fa91d2919eb2 100644 --- a/test/Transforms/GVN/phi-translate.ll +++ b/test/Transforms/GVN/phi-translate.ll @@ -14,7 +14,7 @@ target datalayout = "e-p:64:64:64" @G = external global [100 x i32] define i32 @foo(i32 %x, i32 %z) { entry: - %tobool = icmp eq i32 %x, 0 + %tobool = icmp eq i32 %z, 0 br i1 %tobool, label %end, label %then then: diff --git a/test/Transforms/GVN/pr10820.ll b/test/Transforms/GVN/pr10820.ll new file mode 100644 index 000000000000..12c1e70fc387 --- /dev/null +++ b/test/Transforms/GVN/pr10820.ll @@ -0,0 +1,18 @@ +; RUN: opt < %s -basicaa -gvn -S | 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-f128:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +@g = external global i31 + +define void @main() nounwind uwtable { +entry: +; CHECK: store i32 + store i32 402662078, i32* bitcast (i31* @g to i32*), align 8 +; CHECK-NOT: load i31 + %0 = load i31* @g, align 8 +; CHECK: store i31 + store i31 %0, i31* undef, align 1 + unreachable +} diff --git a/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll b/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll index 0c817005c273..a6803abc5d36 100644 --- a/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll +++ b/test/Transforms/GlobalOpt/2008-01-29-VolatileGlobal.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -globalopt -S | grep {volatile load} +; RUN: opt < %s -globalopt -S | grep {load volatile} @t0.1441 = internal global double 0x3FD5555555555555, align 8 ; [#uses=1] define double @foo() nounwind { diff --git a/test/Transforms/IPConstantProp/global.ll b/test/Transforms/IPConstantProp/global.ll new file mode 100644 index 000000000000..67152937beec --- /dev/null +++ b/test/Transforms/IPConstantProp/global.ll @@ -0,0 +1,26 @@ +; RUN: opt < %s -S -ipsccp | FileCheck %s + +@_ZL6test1g = internal global i32 42, align 4 + +define void @_Z7test1f1v() nounwind { +entry: + %tmp = load i32* @_ZL6test1g, align 4 + %cmp = icmp eq i32 %tmp, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + store i32 0, i32* @_ZL6test1g, align 4 + br label %if.end + +if.end: ; preds = %if.then, %entry + ret void +} + +; CHECK: @_Z7test1f2v() +; CHECK: entry: +; CHECK-NEXT: ret i32 42 +define i32 @_Z7test1f2v() nounwind { +entry: + %tmp = load i32* @_ZL6test1g, align 4 + ret i32 %tmp +} diff --git a/test/Transforms/IPConstantProp/return-argument.ll b/test/Transforms/IPConstantProp/return-argument.ll index 6d6eb24cf542..f4b7018222e9 100644 --- a/test/Transforms/IPConstantProp/return-argument.ll +++ b/test/Transforms/IPConstantProp/return-argument.ll @@ -36,14 +36,22 @@ define void @caller(i1 %C) { ;; propagated per-caller). %S1 = call { i32, i32 } @foo(i32 1, i32 2) %X1 = extractvalue { i32, i32 } %S1, 0 - %S2 = invoke { i32, i32 } @foo(i32 3, i32 4) to label %OK unwind label %RET + %S2 = invoke { i32, i32 } @foo(i32 3, i32 4) to label %OK unwind label %LPAD + OK: %X2 = extractvalue { i32, i32 } %S2, 0 ;; Do some stuff with the returned values which we can grep for %Z = add i32 %X1, %X2 store i32 %Z, i32* %W br label %RET + +LPAD: + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup + br label %RET + RET: ret void } +declare i32 @__gxx_personality_v0(...) diff --git a/test/Transforms/IPConstantProp/return-constant.ll b/test/Transforms/IPConstantProp/return-constant.ll index b25585952873..ff15df738816 100644 --- a/test/Transforms/IPConstantProp/return-constant.ll +++ b/test/Transforms/IPConstantProp/return-constant.ll @@ -22,5 +22,9 @@ OK: %Y = icmp ne i32 %X, 0 ; [#uses=1] ret i1 %Y FAIL: + %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 + cleanup ret i1 false } + +declare i32 @__gxx_personality_v0(...) diff --git a/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll b/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll deleted file mode 100644 index ecd5086f7308..000000000000 --- a/test/Transforms/IndVarSimplify/2003-09-12-MultiplePred.ll +++ /dev/null @@ -1,15 +0,0 @@ -; RUN: opt < %s -indvars -S | grep indvar - -define i32 @test() { -;

    Sections, + MachOObject *MachOObj, raw_ostream &OS) { + for (unsigned i = 0; i != Sections.size(); ++i) { + uint64_t addr = Address-Sections[i].Address; + if (Sections[i].Address <= Address && + Sections[i].Address + Sections[i].Size > Address) { + StringRef bytes = MachOObj->getData(Sections[i].Offset, + Sections[i].Size); + // Print constant strings. + if (!strcmp(Sections[i].Name, "__cstring")) + OS << '"' << bytes.substr(addr, bytes.find('\0', addr)) << '"'; + // Print constant CFStrings. + if (!strcmp(Sections[i].Name, "__cfstring")) + OS << "@\"" << bytes.substr(addr, bytes.find('\0', addr)) << '"'; + } + } +} + +typedef std::map FunctionMapTy; +typedef SmallVector FunctionListTy; +static void createMCFunctionAndSaveCalls(StringRef Name, + const MCDisassembler *DisAsm, + MemoryObject &Object, uint64_t Start, + uint64_t End, + MCInstrAnalysis *InstrAnalysis, + uint64_t Address, + raw_ostream &DebugOut, + FunctionMapTy &FunctionMap, + FunctionListTy &Functions) { + SmallVector Calls; + MCFunction f = + MCFunction::createFunctionFromMC(Name, DisAsm, Object, Start, End, + InstrAnalysis, DebugOut, Calls); + Functions.push_back(f); + FunctionMap[Address] = &Functions.back(); + + // Add the gathered callees to the map. + for (unsigned i = 0, e = Calls.size(); i != e; ++i) + FunctionMap.insert(std::make_pair(Calls[i], (MCFunction*)0)); +} + +// Write a graphviz file for the CFG inside an MCFunction. +static void emitDOTFile(const char *FileName, const MCFunction &f, + MCInstPrinter *IP) { + // Start a new dot file. + std::string Error; + raw_fd_ostream Out(FileName, Error); + if (!Error.empty()) { + errs() << "llvm-objdump: warning: " << Error << '\n'; + return; + } + + Out << "digraph " << f.getName() << " {\n"; + Out << "graph [ rankdir = \"LR\" ];\n"; + for (MCFunction::iterator i = f.begin(), e = f.end(); i != e; ++i) { + bool hasPreds = false; + // Only print blocks that have predecessors. + // FIXME: Slow. + for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe; + ++pi) + if (pi->second.contains(i->first)) { + hasPreds = true; + break; + } + + if (!hasPreds && i != f.begin()) + continue; + + Out << '"' << i->first << "\" [ label=\""; + // Print instructions. + for (unsigned ii = 0, ie = i->second.getInsts().size(); ii != ie; + ++ii) { + // Escape special chars and print the instruction in mnemonic form. + std::string Str; + raw_string_ostream OS(Str); + IP->printInst(&i->second.getInsts()[ii].Inst, OS, ""); + Out << DOT::EscapeString(OS.str()) << '|'; + } + Out << "\" shape=\"record\" ];\n"; + + // Add edges. + for (MCBasicBlock::succ_iterator si = i->second.succ_begin(), + se = i->second.succ_end(); si != se; ++si) + Out << i->first << ":o -> " << *si <<":a\n"; + } + Out << "}\n"; +} + +static void getSectionsAndSymbols(const macho::Header &Header, + MachOObject *MachOObj, + InMemoryStruct *SymtabLC, + std::vector
    &Sections, + std::vector &Symbols, + SmallVectorImpl &FoundFns) { + // Make a list of all symbols in the object file. + for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { + const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i); + if (LCI.Command.Type == macho::LCT_Segment) { + InMemoryStruct SegmentLC; + MachOObj->ReadSegmentLoadCommand(LCI, SegmentLC); + + // Store the sections in this segment. + for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) { + InMemoryStruct Sect; + MachOObj->ReadSection(LCI, SectNum, Sect); + Sections.push_back(copySection(Sect)); + + } + } else if (LCI.Command.Type == macho::LCT_Segment64) { + InMemoryStruct Segment64LC; + MachOObj->ReadSegment64LoadCommand(LCI, Segment64LC); + + // Store the sections in this segment. + for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections; + ++SectNum) { + InMemoryStruct Sect64; + MachOObj->ReadSection64(LCI, SectNum, Sect64); + Sections.push_back(copySection(Sect64)); + } + } else if (LCI.Command.Type == macho::LCT_FunctionStarts) { + // We found a function starts segment, parse the addresses for later + // consumption. + InMemoryStruct LLC; + MachOObj->ReadLinkeditDataLoadCommand(LCI, LLC); + + MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns); + } + } + // Store the symbols. + if (SymtabLC) { + for (unsigned i = 0; i != (*SymtabLC)->NumSymbolTableEntries; ++i) { + if (MachOObj->is64Bit()) { + InMemoryStruct STE; + MachOObj->ReadSymbol64TableEntry((*SymtabLC)->SymbolTableOffset, i, + STE); + Symbols.push_back(copySymbol(STE)); + } else { + InMemoryStruct STE; + MachOObj->ReadSymbolTableEntry((*SymtabLC)->SymbolTableOffset, i, + STE); + Symbols.push_back(copySymbol(STE)); + } + } + } +} + +void llvm::DisassembleInputMachO(StringRef Filename) { + OwningPtr Buff; + + if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { + errs() << "llvm-objdump: " << Filename << ": " << ec.message() << "\n"; + return; + } + + OwningPtr MachOObj(MachOObject::LoadFromBuffer(Buff.take())); + + const Target *TheTarget = GetTarget(MachOObj.get()); + if (!TheTarget) { + // GetTarget prints out stuff. + return; + } + OwningPtr InstrInfo(TheTarget->createMCInstrInfo()); + OwningPtr + InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo.get())); + + // Set up disassembler. + OwningPtr AsmInfo(TheTarget->createMCAsmInfo(TripleName)); + OwningPtr + STI(TheTarget->createMCSubtargetInfo(TripleName, "", "")); + OwningPtr DisAsm(TheTarget->createMCDisassembler(*STI)); + int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); + OwningPtr IP(TheTarget->createMCInstPrinter( + AsmPrinterVariant, *AsmInfo, *STI)); + + if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) { + errs() << "error: couldn't initialize disassembler for target " + << TripleName << '\n'; + return; + } + + outs() << '\n' << Filename << ":\n\n"; + + const macho::Header &Header = MachOObj->getHeader(); + + const MachOObject::LoadCommandInfo *SymtabLCI = 0; + // First, find the symbol table segment. + for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { + const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i); + if (LCI.Command.Type == macho::LCT_Symtab) { + SymtabLCI = &LCI; + break; + } + } + + // Read and register the symbol table data. + InMemoryStruct SymtabLC; + MachOObj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC); + MachOObj->RegisterStringTable(*SymtabLC); + + std::vector
    Sections; + std::vector Symbols; + SmallVector FoundFns; + + getSectionsAndSymbols(Header, MachOObj.get(), &SymtabLC, Sections, Symbols, + FoundFns); + + // Make a copy of the unsorted symbol list. FIXME: duplication + std::vector UnsortedSymbols(Symbols); + // Sort the symbols by address, just in case they didn't come in that way. + array_pod_sort(Symbols.begin(), Symbols.end()); + +#ifndef NDEBUG + raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); +#else + raw_ostream &DebugOut = nulls(); +#endif + + StringRef DebugAbbrevSection, DebugInfoSection, DebugArangesSection, + DebugLineSection, DebugStrSection; + OwningPtr diContext; + OwningPtr DSYMObj; + MachOObject *DbgInfoObj = MachOObj.get(); + // Try to find debug info and set up the DIContext for it. + if (UseDbg) { + ArrayRef
    DebugSections = Sections; + std::vector
    DSYMSections; + + // A separate DSym file path was specified, parse it as a macho file, + // get the sections and supply it to the section name parsing machinery. + if (!DSYMFile.empty()) { + OwningPtr Buf; + if (error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile.c_str(), Buf)) { + errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n'; + return; + } + DSYMObj.reset(MachOObject::LoadFromBuffer(Buf.take())); + const macho::Header &Header = DSYMObj->getHeader(); + + std::vector Symbols; + SmallVector FoundFns; + getSectionsAndSymbols(Header, DSYMObj.get(), 0, DSYMSections, Symbols, + FoundFns); + DebugSections = DSYMSections; + DbgInfoObj = DSYMObj.get(); + } + + // Find the named debug info sections. + for (unsigned SectIdx = 0; SectIdx != DebugSections.size(); SectIdx++) { + if (!strcmp(DebugSections[SectIdx].Name, "__debug_abbrev")) + DebugAbbrevSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset, + DebugSections[SectIdx].Size); + else if (!strcmp(DebugSections[SectIdx].Name, "__debug_info")) + DebugInfoSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset, + DebugSections[SectIdx].Size); + else if (!strcmp(DebugSections[SectIdx].Name, "__debug_aranges")) + DebugArangesSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset, + DebugSections[SectIdx].Size); + else if (!strcmp(DebugSections[SectIdx].Name, "__debug_line")) + DebugLineSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset, + DebugSections[SectIdx].Size); + else if (!strcmp(DebugSections[SectIdx].Name, "__debug_str")) + DebugStrSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset, + DebugSections[SectIdx].Size); + } + + // Setup the DIContext. + diContext.reset(DIContext::getDWARFContext(DbgInfoObj->isLittleEndian(), + DebugInfoSection, + DebugAbbrevSection, + DebugArangesSection, + DebugLineSection, + DebugStrSection)); + } + + FunctionMapTy FunctionMap; + FunctionListTy Functions; + + for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) { + if (strcmp(Sections[SectIdx].Name, "__text")) + continue; // Skip non-text sections + + // Insert the functions from the function starts segment into our map. + uint64_t VMAddr = Sections[SectIdx].Address - Sections[SectIdx].Offset; + for (unsigned i = 0, e = FoundFns.size(); i != e; ++i) + FunctionMap.insert(std::make_pair(FoundFns[i]+VMAddr, (MCFunction*)0)); + + StringRef Bytes = MachOObj->getData(Sections[SectIdx].Offset, + Sections[SectIdx].Size); + StringRefMemoryObject memoryObject(Bytes); + bool symbolTableWorked = false; + + // Parse relocations. + std::vector > Relocs; + for (unsigned j = 0; j != Sections[SectIdx].NumRelocs; ++j) { + InMemoryStruct RE; + MachOObj->ReadRelocationEntry(Sections[SectIdx].RelocTableOffset, j, RE); + Relocs.push_back(std::make_pair(RE->Word0, RE->Word1 & 0xffffff)); + } + array_pod_sort(Relocs.begin(), Relocs.end()); + + // Disassemble symbol by symbol. + for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) { + // Make sure the symbol is defined in this section. + if ((unsigned)Symbols[SymIdx].SectionIndex - 1 != SectIdx) + continue; + + // Start at the address of the symbol relative to the section's address. + uint64_t Start = Symbols[SymIdx].Value - Sections[SectIdx].Address; + // Stop disassembling either at the beginning of the next symbol or at + // the end of the section. + uint64_t End = (SymIdx+1 == Symbols.size() || + Symbols[SymIdx].SectionIndex != Symbols[SymIdx+1].SectionIndex) ? + Sections[SectIdx].Size : + Symbols[SymIdx+1].Value - Sections[SectIdx].Address; + uint64_t Size; + + if (Start >= End) + continue; + + symbolTableWorked = true; + + if (!CFG) { + // Normal disassembly, print addresses, bytes and mnemonic form. + outs() << MachOObj->getStringAtIndex(Symbols[SymIdx].StringIndex) + << ":\n"; + DILineInfo lastLine; + for (uint64_t Index = Start; Index < End; Index += Size) { + MCInst Inst; + + if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, + DebugOut, nulls())) { + outs() << format("%8llx:\t", Sections[SectIdx].Address + Index); + DumpBytes(StringRef(Bytes.data() + Index, Size)); + IP->printInst(&Inst, outs(), ""); + + // Print debug info. + if (diContext) { + DILineInfo dli = + diContext->getLineInfoForAddress(Sections[SectIdx].Address + + Index); + // Print valid line info if it changed. + if (dli != lastLine && dli.getLine() != 0) + outs() << "\t## " << dli.getFileName() << ':' + << dli.getLine() << ':' << dli.getColumn(); + lastLine = dli; + } + outs() << "\n"; + } else { + errs() << "llvm-objdump: warning: invalid instruction encoding\n"; + if (Size == 0) + Size = 1; // skip illegible bytes + } + } + } else { + // Create CFG and use it for disassembly. + createMCFunctionAndSaveCalls( + MachOObj->getStringAtIndex(Symbols[SymIdx].StringIndex), + DisAsm.get(), memoryObject, Start, End, InstrAnalysis.get(), + Start, DebugOut, FunctionMap, Functions); + } + } + + if (CFG) { + if (!symbolTableWorked) { + // Reading the symbol table didn't work, create a big __TEXT symbol. + createMCFunctionAndSaveCalls("__TEXT", DisAsm.get(), memoryObject, + 0, Sections[SectIdx].Size, + InstrAnalysis.get(), + Sections[SectIdx].Offset, DebugOut, + FunctionMap, Functions); + } + for (std::map::iterator mi = FunctionMap.begin(), + me = FunctionMap.end(); mi != me; ++mi) + if (mi->second == 0) { + // Create functions for the remaining callees we have gathered, + // but we didn't find a name for them. + SmallVector Calls; + MCFunction f = + MCFunction::createFunctionFromMC("unknown", DisAsm.get(), + memoryObject, mi->first, + Sections[SectIdx].Size, + InstrAnalysis.get(), DebugOut, + Calls); + Functions.push_back(f); + mi->second = &Functions.back(); + for (unsigned i = 0, e = Calls.size(); i != e; ++i) { + std::pair p(Calls[i], (MCFunction*)0); + if (FunctionMap.insert(p).second) + mi = FunctionMap.begin(); + } + } + + DenseSet PrintedBlocks; + for (unsigned ffi = 0, ffe = Functions.size(); ffi != ffe; ++ffi) { + MCFunction &f = Functions[ffi]; + for (MCFunction::iterator fi = f.begin(), fe = f.end(); fi != fe; ++fi){ + if (!PrintedBlocks.insert(fi->first).second) + continue; // We already printed this block. + + // We assume a block has predecessors when it's the first block after + // a symbol. + bool hasPreds = FunctionMap.find(fi->first) != FunctionMap.end(); + + // See if this block has predecessors. + // FIXME: Slow. + for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe; + ++pi) + if (pi->second.contains(fi->first)) { + hasPreds = true; + break; + } + + // No predecessors, this is a data block. Print as .byte directives. + if (!hasPreds) { + uint64_t End = llvm::next(fi) == fe ? Sections[SectIdx].Size : + llvm::next(fi)->first; + outs() << "# " << End-fi->first << " bytes of data:\n"; + for (unsigned pos = fi->first; pos != End; ++pos) { + outs() << format("%8x:\t", Sections[SectIdx].Address + pos); + DumpBytes(StringRef(Bytes.data() + pos, 1)); + outs() << format("\t.byte 0x%02x\n", (uint8_t)Bytes[pos]); + } + continue; + } + + if (fi->second.contains(fi->first)) // Print a header for simple loops + outs() << "# Loop begin:\n"; + + DILineInfo lastLine; + // Walk over the instructions and print them. + for (unsigned ii = 0, ie = fi->second.getInsts().size(); ii != ie; + ++ii) { + const MCDecodedInst &Inst = fi->second.getInsts()[ii]; + + // If there's a symbol at this address, print its name. + if (FunctionMap.find(Sections[SectIdx].Address + Inst.Address) != + FunctionMap.end()) + outs() << FunctionMap[Sections[SectIdx].Address + Inst.Address]-> + getName() << ":\n"; + + outs() << format("%8llx:\t", Sections[SectIdx].Address + + Inst.Address); + DumpBytes(StringRef(Bytes.data() + Inst.Address, Inst.Size)); + + if (fi->second.contains(fi->first)) // Indent simple loops. + outs() << '\t'; + + IP->printInst(&Inst.Inst, outs(), ""); + + // Look for relocations inside this instructions, if there is one + // print its target and additional information if available. + for (unsigned j = 0; j != Relocs.size(); ++j) + if (Relocs[j].first >= Sections[SectIdx].Address + Inst.Address && + Relocs[j].first < Sections[SectIdx].Address + Inst.Address + + Inst.Size) { + outs() << "\t# " + << MachOObj->getStringAtIndex( + UnsortedSymbols[Relocs[j].second].StringIndex) + << ' '; + DumpAddress(UnsortedSymbols[Relocs[j].second].Value, Sections, + MachOObj.get(), outs()); + } + + // If this instructions contains an address, see if we can evaluate + // it and print additional information. + uint64_t targ = InstrAnalysis->evaluateBranch(Inst.Inst, + Inst.Address, + Inst.Size); + if (targ != -1ULL) + DumpAddress(targ, Sections, MachOObj.get(), outs()); + + // Print debug info. + if (diContext) { + DILineInfo dli = + diContext->getLineInfoForAddress(Sections[SectIdx].Address + + Inst.Address); + // Print valid line info if it changed. + if (dli != lastLine && dli.getLine() != 0) + outs() << "\t## " << dli.getFileName() << ':' + << dli.getLine() << ':' << dli.getColumn(); + lastLine = dli; + } + + outs() << '\n'; + } + } + + emitDOTFile((f.getName().str() + ".dot").c_str(), f, IP.get()); + } + } + } +} diff --git a/tools/llvm-objdump/Makefile b/tools/llvm-objdump/Makefile index 4d7cd34eac97..703bf6c8a4f1 100644 --- a/tools/llvm-objdump/Makefile +++ b/tools/llvm-objdump/Makefile @@ -9,7 +9,8 @@ LEVEL = ../.. TOOLNAME = llvm-objdump -LINK_COMPONENTS = $(TARGETS_TO_BUILD) MC MCParser MCDisassembler Object +LINK_COMPONENTS = $(TARGETS_TO_BUILD) DebugInfo MC MCParser MCDisassembler \ + Object # This tool has no plugins, optimize startup time. TOOL_NO_EXPORTS = 1 diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 4079e4aabe60..4ae13be3cdca 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -13,6 +13,9 @@ // //===----------------------------------------------------------------------===// +#include "llvm-objdump.h" +#include "MCFunction.h" +#include "llvm/Object/Archive.h" #include "llvm/Object/ObjectFile.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Triple.h" @@ -21,9 +24,13 @@ #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" +#include "llvm/Support/GraphWriter.h" #include "llvm/Support/Host.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" @@ -31,44 +38,59 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetSelect.h" #include #include using namespace llvm; using namespace object; -namespace { - cl::list - InputFilenames(cl::Positional, cl::desc(""), - cl::ZeroOrMore); +static cl::list +InputFilenames(cl::Positional, cl::desc(""),cl::ZeroOrMore); - cl::opt - Disassemble("disassemble", - cl::desc("Display assembler mnemonics for the machine instructions")); - cl::alias - Disassembled("d", cl::desc("Alias for --disassemble"), - cl::aliasopt(Disassemble)); +static cl::opt +Disassemble("disassemble", + cl::desc("Display assembler mnemonics for the machine instructions")); +static cl::alias +Disassembled("d", cl::desc("Alias for --disassemble"), + cl::aliasopt(Disassemble)); - cl::opt - TripleName("triple", cl::desc("Target triple to disassemble for, " +static cl::opt +Relocations("r", cl::desc("Display the relocation entries in the file")); + +static cl::opt +MachO("macho", cl::desc("Use MachO specific object file parser")); +static cl::alias +MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachO)); + +cl::opt +llvm::TripleName("triple", cl::desc("Target triple to disassemble for, " + "see -version for available targets")); + +cl::opt +llvm::ArchName("arch", cl::desc("Target arch to disassemble for, " "see -version for available targets")); - cl::opt - ArchName("arch", cl::desc("Target arch to disassemble for, " - "see -version for available targets")); +static cl::opt +SectionHeaders("section-headers", cl::desc("Display summaries of the headers " + "for each section.")); +static cl::alias +SectionHeadersShort("headers", cl::desc("Alias for --section-headers"), + cl::aliasopt(SectionHeaders)); +static cl::alias +SectionHeadersShorter("h", cl::desc("Alias for --section-headers"), + cl::aliasopt(SectionHeaders)); - StringRef ToolName; +static StringRef ToolName; - bool error(error_code ec) { - if (!ec) return false; +static bool error(error_code ec) { + if (!ec) return false; - outs() << ToolName << ": error reading file: " << ec.message() << ".\n"; - outs().flush(); - return true; - } + outs() << ToolName << ": error reading file: " << ec.message() << ".\n"; + outs().flush(); + return true; } static const Target *GetTarget(const ObjectFile *Obj = NULL) { @@ -96,27 +118,8 @@ static const Target *GetTarget(const ObjectFile *Obj = NULL) { return 0; } -namespace { -class StringRefMemoryObject : public MemoryObject { -private: - StringRef Bytes; -public: - StringRefMemoryObject(StringRef 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]; - return 0; - } -}; -} - -static void DumpBytes(StringRef bytes) { - static char hex_rep[] = "0123456789abcdef"; +void llvm::DumpBytes(StringRef bytes) { + static const char hex_rep[] = "0123456789abcdef"; // FIXME: The real way to do this is to figure out the longest instruction // and align to that size before printing. I'll fix this when I get // around to outputting relocations. @@ -141,44 +144,45 @@ static void DumpBytes(StringRef bytes) { outs() << output; } -static void DisassembleInput(const StringRef &Filename) { - OwningPtr Buff; +static bool RelocAddressLess(RelocationRef a, RelocationRef b) { + uint64_t a_addr, b_addr; + if (error(a.getAddress(a_addr))) return false; + if (error(b.getAddress(b_addr))) return false; + return a_addr < b_addr; +} - if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { - errs() << ToolName << ": " << Filename << ": " << ec.message() << "\n"; - return; - } - - OwningPtr Obj(ObjectFile::createObjectFile(Buff.take())); - - const Target *TheTarget = GetTarget(Obj.get()); +static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { + const Target *TheTarget = GetTarget(Obj); if (!TheTarget) { // GetTarget prints out stuff. return; } outs() << '\n'; - outs() << Filename + outs() << Obj->getFileName() << ":\tfile format " << Obj->getFileFormatName() << "\n\n"; error_code ec; - for (ObjectFile::section_iterator i = Obj->begin_sections(), - e = Obj->end_sections(); - i != e; i.increment(ec)) { + for (section_iterator i = Obj->begin_sections(), + e = Obj->end_sections(); + i != e; i.increment(ec)) { if (error(ec)) break; bool text; if (error(i->isText(text))) break; if (!text) continue; + uint64_t SectionAddr; + if (error(i->getAddress(SectionAddr))) break; + // Make a list of all the symbols in this section. std::vector > Symbols; - for (ObjectFile::symbol_iterator si = Obj->begin_symbols(), - se = Obj->end_symbols(); - si != se; si.increment(ec)) { + for (symbol_iterator si = Obj->begin_symbols(), + se = Obj->end_symbols(); + si != se; si.increment(ec)) { bool contains; if (!error(i->containsSymbol(*si, contains)) && contains) { uint64_t Address; - if (error(si->getAddress(Address))) break; + if (error(si->getOffset(Address))) break; StringRef Name; if (error(si->getName(Name))) break; Symbols.push_back(std::make_pair(Address, Name)); @@ -188,6 +192,20 @@ static void DisassembleInput(const StringRef &Filename) { // Sort the symbols by address, just in case they didn't come in that way. array_pod_sort(Symbols.begin(), Symbols.end()); + // Make a list of all the relocations for this section. + std::vector Rels; + if (InlineRelocs) { + for (relocation_iterator ri = i->begin_relocations(), + re = i->end_relocations(); + ri != re; ri.increment(ec)) { + if (error(ec)) break; + Rels.push_back(*ri); + } + } + + // Sort relocations by address. + std::sort(Rels.begin(), Rels.end(), RelocAddressLess); + StringRef name; if (error(i->getName(name))) break; outs() << "Disassembly of section " << name << ':'; @@ -205,7 +223,16 @@ static void DisassembleInput(const StringRef &Filename) { return; } - OwningPtr DisAsm(TheTarget->createMCDisassembler()); + OwningPtr STI( + TheTarget->createMCSubtargetInfo(TripleName, "", "")); + + if (!STI) { + errs() << "error: no subtarget info for target " << TripleName << "\n"; + return; + } + + OwningPtr DisAsm( + TheTarget->createMCDisassembler(*STI)); if (!DisAsm) { errs() << "error: no disassembler for target " << TripleName << "\n"; return; @@ -213,9 +240,10 @@ static void DisassembleInput(const StringRef &Filename) { int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); OwningPtr IP(TheTarget->createMCInstPrinter( - AsmPrinterVariant, *AsmInfo)); + AsmPrinterVariant, *AsmInfo, *STI)); if (!IP) { - errs() << "error: no instruction printer for target " << TripleName << '\n'; + errs() << "error: no instruction printer for target " << TripleName + << '\n'; return; } @@ -227,14 +255,24 @@ static void DisassembleInput(const StringRef &Filename) { uint64_t SectSize; if (error(i->getSize(SectSize))) break; + std::vector::const_iterator rel_cur = Rels.begin(); + std::vector::const_iterator rel_end = Rels.end(); // Disassemble symbol by symbol. for (unsigned si = 0, se = Symbols.size(); si != se; ++si) { uint64_t Start = Symbols[si].first; - uint64_t End = si == se-1 ? SectSize : Symbols[si + 1].first - 1; - outs() << '\n' << Symbols[si].second << ":\n"; + uint64_t End; + // The end is either the size of the section or the beginning of the next + // symbol. + if (si == se - 1) + End = SectSize; + // Make sure this symbol takes up space. + else if (Symbols[si + 1].first != Start) + End = Symbols[si + 1].first - 1; + else + // This symbol has the same address as the next symbol. Skip it. + continue; - for (Index = Start; Index < End; Index += Size) { - MCInst Inst; + outs() << '\n' << Symbols[si].second << ":\n"; #ifndef NDEBUG raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls(); @@ -242,23 +280,152 @@ static void DisassembleInput(const StringRef &Filename) { raw_ostream &DebugOut = nulls(); #endif - if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, DebugOut)) { - uint64_t addr; - if (error(i->getAddress(addr))) break; - outs() << format("%8x:\t", addr + Index); + for (Index = Start; Index < End; Index += Size) { + MCInst Inst; + + if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, + DebugOut, nulls())) { + outs() << format("%8x:\t", SectionAddr + Index); DumpBytes(StringRef(Bytes.data() + Index, Size)); - IP->printInst(&Inst, outs()); + IP->printInst(&Inst, outs(), ""); outs() << "\n"; } else { errs() << ToolName << ": warning: invalid instruction encoding\n"; if (Size == 0) Size = 1; // skip illegible bytes } + + // Print relocation for instruction. + while (rel_cur != rel_end) { + uint64_t addr; + SmallString<16> name; + SmallString<32> val; + if (error(rel_cur->getAddress(addr))) goto skip_print_rel; + // Stop when rel_cur's address is past the current instruction. + if (addr > Index + Size) break; + if (error(rel_cur->getTypeName(name))) goto skip_print_rel; + if (error(rel_cur->getValueString(val))) goto skip_print_rel; + + outs() << format("\t\t\t%8x: ", SectionAddr + addr) << name << "\t" + << val << "\n"; + + skip_print_rel: + ++rel_cur; + } } } } } +static void PrintRelocations(const ObjectFile *o) { + error_code ec; + for (section_iterator si = o->begin_sections(), se = o->end_sections(); + si != se; si.increment(ec)){ + if (error(ec)) return; + if (si->begin_relocations() == si->end_relocations()) + continue; + StringRef secname; + if (error(si->getName(secname))) continue; + outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n"; + for (relocation_iterator ri = si->begin_relocations(), + re = si->end_relocations(); + ri != re; ri.increment(ec)) { + if (error(ec)) return; + + uint64_t address; + SmallString<32> relocname; + SmallString<32> valuestr; + if (error(ri->getTypeName(relocname))) continue; + if (error(ri->getAddress(address))) continue; + if (error(ri->getValueString(valuestr))) continue; + outs() << address << " " << relocname << " " << valuestr << "\n"; + } + outs() << "\n"; + } +} + +static void PrintSectionHeaders(const ObjectFile *o) { + outs() << "Sections:\n" + "Idx Name Size Address Type\n"; + error_code ec; + unsigned i = 0; + for (section_iterator si = o->begin_sections(), se = o->end_sections(); + si != se; si.increment(ec)) { + if (error(ec)) return; + StringRef Name; + if (error(si->getName(Name))) return; + uint64_t Address; + if (error(si->getAddress(Address))) return; + uint64_t Size; + if (error(si->getSize(Size))) return; + bool Text, Data, BSS; + if (error(si->isText(Text))) return; + if (error(si->isData(Data))) return; + if (error(si->isBSS(BSS))) return; + std::string Type = (std::string(Text ? "TEXT " : "") + + (Data ? "DATA " : "") + (BSS ? "BSS" : "")); + outs() << format("%3d %-13s %09"PRIx64" %017"PRIx64" %s\n", i, Name.str().c_str(), Size, + Address, Type.c_str()); + ++i; + } +} + +static void DumpObject(const ObjectFile *o) { + if (Disassemble) + DisassembleObject(o, Relocations); + if (Relocations && !Disassemble) + PrintRelocations(o); + if (SectionHeaders) + PrintSectionHeaders(o); +} + +/// @brief Dump each object file in \a a; +static void DumpArchive(const Archive *a) { + for (Archive::child_iterator i = a->begin_children(), + e = a->end_children(); i != e; ++i) { + OwningPtr child; + if (error_code ec = i->getAsBinary(child)) { + errs() << ToolName << ": '" << a->getFileName() << "': " << ec.message() + << ".\n"; + continue; + } + if (ObjectFile *o = dyn_cast(child.get())) + DumpObject(o); + else + errs() << ToolName << ": '" << a->getFileName() << "': " + << "Unrecognized file type.\n"; + } +} + +/// @brief Open file and figure out how to dump it. +static void DumpInput(StringRef file) { + // If file isn't stdin, check that it exists. + if (file != "-" && !sys::fs::exists(file)) { + errs() << ToolName << ": '" << file << "': " << "No such file\n"; + return; + } + + if (MachO && Disassemble) { + DisassembleInputMachO(file); + return; + } + + // Attempt to open the binary. + OwningPtr binary; + if (error_code ec = createBinary(file, binary)) { + errs() << ToolName << ": '" << file << "': " << ec.message() << ".\n"; + return; + } + + if (Archive *a = dyn_cast(binary.get())) { + DumpArchive(a); + } else if (ObjectFile *o = dyn_cast(binary.get())) { + DumpObject(o); + } else { + errs() << ToolName << ": '" << file << "': " << "Unrecognized file type.\n"; + } +} + int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); @@ -267,10 +434,7 @@ int main(int argc, char **argv) { // Initialize targets and assembly printers/parsers. llvm::InitializeAllTargetInfos(); - // FIXME: We shouldn't need to initialize the Target(Machine)s. - llvm::InitializeAllTargets(); - llvm::InitializeAllMCAsmInfos(); - llvm::InitializeAllAsmPrinters(); + llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); @@ -283,15 +447,13 @@ int main(int argc, char **argv) { if (InputFilenames.size() == 0) InputFilenames.push_back("a.out"); - // -d is the only flag that is currently implemented, so just print help if - // it is not set. - if (!Disassemble) { + if (!Disassemble && !Relocations && !SectionHeaders) { cl::PrintHelpMessage(); return 2; } std::for_each(InputFilenames.begin(), InputFilenames.end(), - DisassembleInput); + DumpInput); return 0; } diff --git a/tools/llvm-objdump/llvm-objdump.h b/tools/llvm-objdump/llvm-objdump.h new file mode 100644 index 000000000000..75f852afbc7e --- /dev/null +++ b/tools/llvm-objdump/llvm-objdump.h @@ -0,0 +1,46 @@ +//===-- llvm-objdump.h ----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJDUMP_H +#define LLVM_OBJDUMP_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/MemoryObject.h" + +namespace llvm { + +extern cl::opt TripleName; +extern cl::opt ArchName; + +// Various helper functions. +void DumpBytes(StringRef bytes); +void DisassembleInputMachO(StringRef Filename); + +class StringRefMemoryObject : public MemoryObject { +private: + StringRef Bytes; +public: + StringRefMemoryObject(StringRef 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]; + return 0; + } +}; + +} + +#endif diff --git a/tools/llvm-shlib/Makefile b/tools/llvm-shlib/Makefile index 9e6facab7028..0695c0070d36 100644 --- a/tools/llvm-shlib/Makefile +++ b/tools/llvm-shlib/Makefile @@ -30,10 +30,11 @@ endif include $(LEVEL)/Makefile.common # Include all archives in libLLVM.(so|dylib) except the ones that have -# their own dynamic libraries. +# their own dynamic libraries and TableGen. Archives := $(wildcard $(LibDir)/libLLVM*.a) SharedLibraries := $(wildcard $(LibDir)/libLLVM*$(SHLIBEXT)) -IncludeInLibLlvm := $(filter-out $(basename $(SharedLibraries)).a, $(Archives)) +ExcludeFromLibLlvm := $(basename $(SharedLibraries)).a %/libLLVMTableGen.a +IncludeInLibLlvm := $(filter-out $(ExcludeFromLibLlvm), $(Archives)) LLVMLibsOptions := $(IncludeInLibLlvm:$(LibDir)/lib%.a=-l%) LLVMLibsPaths := $(IncludeInLibLlvm) diff --git a/tools/llvm-size/CMakeLists.txt b/tools/llvm-size/CMakeLists.txt new file mode 100644 index 000000000000..933cc75c3fe9 --- /dev/null +++ b/tools/llvm-size/CMakeLists.txt @@ -0,0 +1,5 @@ +set(LLVM_LINK_COMPONENTS object) + +add_llvm_tool(llvm-size + llvm-size.cpp + ) diff --git a/tools/llvmc/examples/Simple/Makefile b/tools/llvm-size/Makefile similarity index 61% rename from tools/llvmc/examples/Simple/Makefile rename to tools/llvm-size/Makefile index c10387c4f556..5d0e27ed16e4 100644 --- a/tools/llvmc/examples/Simple/Makefile +++ b/tools/llvm-size/Makefile @@ -1,4 +1,4 @@ -##===- llvmc/examples/Simple/Makefile ----------------------*- Makefile -*-===## +##===- tools/llvm-size/Makefile ----------------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # @@ -6,10 +6,12 @@ # License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## +LEVEL = ../.. -LEVEL = ../../../.. +TOOLNAME = llvm-size +LINK_COMPONENTS = object -LLVMC_BASED_DRIVER = Simple -BUILT_SOURCES = Simple.inc +# This tool has no plugins, optimize startup time. +TOOL_NO_EXPORTS = 1 include $(LEVEL)/Makefile.common diff --git a/tools/llvm-size/llvm-size.cpp b/tools/llvm-size/llvm-size.cpp new file mode 100644 index 000000000000..70e5cb9439b3 --- /dev/null +++ b/tools/llvm-size/llvm-size.cpp @@ -0,0 +1,311 @@ +//===-- llvm-size.cpp - Print the size of each object section -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This program is a utility that works like traditional Unix "size", +// that is, it prints out the size of each section, and the total size of all +// sections. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/APInt.h" +#include "llvm/Object/Archive.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/system_error.h" +#include +#include +using namespace llvm; +using namespace object; + +enum OutputFormatTy {berkeley, sysv}; +static cl::opt + OutputFormat("format", + cl::desc("Specify output format"), + cl::values(clEnumVal(sysv, "System V format"), + clEnumVal(berkeley, "Berkeley format"), + clEnumValEnd), + cl::init(berkeley)); + +static cl::opt + OutputFormatShort(cl::desc("Specify output format"), + cl::values(clEnumValN(sysv, "A", "System V format"), + clEnumValN(berkeley, "B", "Berkeley format"), + clEnumValEnd), + cl::init(berkeley)); + +enum RadixTy {octal = 8, decimal = 10, hexadecimal = 16}; +static cl::opt + Radix("-radix", + cl::desc("Print size in radix. Only 8, 10, and 16 are valid"), + cl::init(decimal)); + +static cl::opt + RadixShort(cl::desc("Print size in radix:"), + cl::values(clEnumValN(octal, "o", "Print size in octal"), + clEnumValN(decimal, "d", "Print size in decimal"), + clEnumValN(hexadecimal, "x", "Print size in hexadecimal"), + clEnumValEnd), + cl::init(decimal)); + +static cl::list + InputFilenames(cl::Positional, cl::desc(""), + cl::ZeroOrMore); + +static std::string ToolName; + +/// @brief If ec is not success, print the error and return true. +static bool error(error_code ec) { + if (!ec) return false; + + outs() << ToolName << ": error reading file: " << ec.message() << ".\n"; + outs().flush(); + return true; +} + +/// @brief Get the length of the string that represents @p num in Radix +/// including the leading 0x or 0 for hexadecimal and octal respectively. +static size_t getNumLengthAsString(uint64_t num) { + APInt conv(64, num); + SmallString<32> result; + conv.toString(result, Radix, false, true); + return result.size(); +} + +/// @brief Print the size of each section in @p o. +/// +/// The format used is determined by @c OutputFormat and @c Radix. +static void PrintObjectSectionSizes(ObjectFile *o) { + uint64_t total = 0; + std::string fmtbuf; + raw_string_ostream fmt(fmtbuf); + + const char *radix_fmt = 0; + switch (Radix) { + case octal: + radix_fmt = "llo"; + break; + case decimal: + radix_fmt = "llu"; + break; + case hexadecimal: + radix_fmt = "llx"; + break; + } + if (OutputFormat == sysv) { + // Run two passes over all sections. The first gets the lengths needed for + // formatting the output. The second actually does the output. + std::size_t max_name_len = strlen("section"); + std::size_t max_size_len = strlen("size"); + std::size_t max_addr_len = strlen("addr"); + error_code ec; + for (section_iterator i = o->begin_sections(), + e = o->end_sections(); i != e; + i.increment(ec)) { + if (error(ec)) + return; + uint64_t size = 0; + if (error(i->getSize(size))) + return; + total += size; + + StringRef name; + uint64_t addr = 0; + if (error(i->getName(name))) return; + if (error(i->getAddress(addr))) return; + max_name_len = std::max(max_name_len, name.size()); + max_size_len = std::max(max_size_len, getNumLengthAsString(size)); + max_addr_len = std::max(max_addr_len, getNumLengthAsString(addr)); + } + + // Add extra padding. + max_name_len += 2; + max_size_len += 2; + max_addr_len += 2; + + // Setup header format. + fmt << "%-" << max_name_len << "s " + << "%" << max_size_len << "s " + << "%" << max_addr_len << "s\n"; + + // Print header + outs() << format(fmt.str().c_str(), + static_cast("section"), + static_cast("size"), + static_cast("addr")); + fmtbuf.clear(); + + // Setup per section format. + fmt << "%-" << max_name_len << "s " + << "%#" << max_size_len << radix_fmt << " " + << "%#" << max_addr_len << radix_fmt << "\n"; + + // Print each section. + for (section_iterator i = o->begin_sections(), + e = o->end_sections(); i != e; + i.increment(ec)) { + if (error(ec)) + return; + + StringRef name; + uint64_t size = 0; + uint64_t addr = 0; + if (error(i->getName(name))) return; + if (error(i->getSize(size))) return; + if (error(i->getAddress(addr))) return; + std::string namestr = name; + + outs() << format(fmt.str().c_str(), + namestr.c_str(), + size, + addr); + } + + // Print total. + fmtbuf.clear(); + fmt << "%-" << max_name_len << "s " + << "%#" << max_size_len << radix_fmt << "\n"; + outs() << format(fmt.str().c_str(), + static_cast("Total"), + total); + } else { + // The Berkeley format does not display individual section sizes. It + // displays the cumulative size for each section type. + uint64_t total_text = 0; + uint64_t total_data = 0; + uint64_t total_bss = 0; + + // Make one pass over the section table to calculate sizes. + error_code ec; + for (section_iterator i = o->begin_sections(), + e = o->end_sections(); i != e; + i.increment(ec)) { + if (error(ec)) + return; + + uint64_t size = 0; + bool isText = false; + bool isData = false; + bool isBSS = false; + if (error(i->getSize(size))) return; + if (error(i->isText(isText))) return; + if (error(i->isData(isData))) return; + if (error(i->isBSS(isBSS))) return; + if (isText) + total_text += size; + else if (isData) + total_data += size; + else if (isBSS) + total_bss += size; + } + + total = total_text + total_data + total_bss; + + // Print result. + fmt << "%#7" << radix_fmt << " " + << "%#7" << radix_fmt << " " + << "%#7" << radix_fmt << " "; + outs() << format(fmt.str().c_str(), + total_text, + total_data, + total_bss); + fmtbuf.clear(); + fmt << "%7" << (Radix == octal ? "llo" : "llu") << " " + << "%7llx "; + outs() << format(fmt.str().c_str(), + total, + total); + } +} + +/// @brief Print the section sizes for @p file. If @p file is an archive, print +/// the section sizes for each archive member. +static void PrintFileSectionSizes(StringRef file) { + // If file is not stdin, check that it exists. + if (file != "-") { + bool exists; + if (sys::fs::exists(file, exists) || !exists) { + errs() << ToolName << ": '" << file << "': " << "No such file\n"; + return; + } + } + + // Attempt to open the binary. + OwningPtr binary; + if (error_code ec = createBinary(file, binary)) { + errs() << ToolName << ": " << file << ": " << ec.message() << ".\n"; + return; + } + + if (Archive *a = dyn_cast(binary.get())) { + // This is an archive. Iterate over each member and display its sizes. + for (object::Archive::child_iterator i = a->begin_children(), + e = a->end_children(); i != e; ++i) { + OwningPtr child; + if (error_code ec = i->getAsBinary(child)) { + errs() << ToolName << ": " << file << ": " << ec.message() << ".\n"; + continue; + } + if (ObjectFile *o = dyn_cast(child.get())) { + if (OutputFormat == sysv) + outs() << o->getFileName() << " (ex " << a->getFileName() + << "):\n"; + PrintObjectSectionSizes(o); + if (OutputFormat == berkeley) + outs() << o->getFileName() << " (ex " << a->getFileName() << ")\n"; + } + } + } else if (ObjectFile *o = dyn_cast(binary.get())) { + if (OutputFormat == sysv) + outs() << o->getFileName() << " :\n"; + PrintObjectSectionSizes(o); + if (OutputFormat == berkeley) + outs() << o->getFileName() << "\n"; + } else { + errs() << ToolName << ": " << file << ": " << "Unrecognized file type.\n"; + } + // System V adds an extra newline at the end of each file. + if (OutputFormat == sysv) + outs() << "\n"; +} + +int main(int argc, char **argv) { + // Print a stack trace if we signal out. + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + cl::ParseCommandLineOptions(argc, argv, "llvm object size dumper\n"); + + ToolName = argv[0]; + if (OutputFormatShort.getNumOccurrences()) + OutputFormat = OutputFormatShort; + if (RadixShort.getNumOccurrences()) + Radix = RadixShort; + + if (InputFilenames.size() == 0) + InputFilenames.push_back("a.out"); + + if (OutputFormat == berkeley) + outs() << " text data bss " + << (Radix == octal ? "oct" : "dec") + << " hex filename\n"; + + std::for_each(InputFilenames.begin(), InputFilenames.end(), + PrintFileSectionSizes); + + return 0; +} diff --git a/tools/llvmc/CMakeLists.txt b/tools/llvmc/CMakeLists.txt deleted file mode 100644 index 10ad5d82009f..000000000000 --- a/tools/llvmc/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -# add_subdirectory(src) - -# TODO: support plugins and user-configured builds. -# See ./doc/LLVMC-Reference.rst "Customizing LLVMC: the compilation graph" diff --git a/tools/llvmc/Makefile b/tools/llvmc/Makefile deleted file mode 100644 index 7c03e2a74f7c..000000000000 --- a/tools/llvmc/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -##===- tools/llvmc/Makefile --------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open -# Source License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. - -DIRS = src - -ifeq ($(BUILD_EXAMPLES),1) - OPTIONAL_DIRS += examples -endif - -include $(LEVEL)/Makefile.common diff --git a/tools/llvmc/doc/LLVMC-Reference.rst b/tools/llvmc/doc/LLVMC-Reference.rst deleted file mode 100644 index 041aedf9e16d..000000000000 --- a/tools/llvmc/doc/LLVMC-Reference.rst +++ /dev/null @@ -1,747 +0,0 @@ -=================================== -Customizing LLVMC: Reference Manual -=================================== -.. - This file was automatically generated by rst2html. - Please do not edit directly! - The ReST source lives in the directory 'tools/llvmc/doc'. - -.. contents:: - -.. raw:: html - - - -Introduction -============ - -LLVMC is a generic compiler driver, designed to be customizable and -extensible. It plays the same role for LLVM as the ``gcc`` program does for -GCC - LLVMC's job is essentially to transform a set of input files into a set of -targets depending on configuration rules and user options. What makes LLVMC -different is that these transformation rules are completely customizable - in -fact, LLVMC knows nothing about the specifics of transformation (even the -command-line options are mostly not hard-coded) and regards the transformation -structure as an abstract graph. The structure of this graph is described in -high-level TableGen code, from which an efficient C++ representation is -automatically derived. This makes it possible to adapt LLVMC for other -purposes - for example, as a build tool for game resources. - -Because LLVMC employs TableGen_ as its configuration language, you -need to be familiar with it to customize LLVMC. - -.. _TableGen: http://llvm.org/docs/TableGenFundamentals.html - - -Compiling with ``llvmc`` -======================== - -LLVMC tries hard to be as compatible with ``gcc`` as possible, -although there are some small differences. Most of the time, however, -you shouldn't be able to notice them:: - - $ # This works as expected: - $ llvmc -O3 -Wall hello.cpp - $ ./a.out - hello - -One nice feature of LLVMC is that one doesn't have to distinguish between -different compilers for different languages (think ``g++`` vs. ``gcc``) - the -right toolchain is chosen automatically based on input language names (which -are, in turn, determined from file extensions). If you want to force files -ending with ".c" to compile as C++, use the ``-x`` option, just like you would -do it with ``gcc``:: - - $ # hello.c is really a C++ file - $ llvmc -x c++ hello.c - $ ./a.out - hello - -On the other hand, when using LLVMC as a linker to combine several C++ -object files you should provide the ``--linker`` option since it's -impossible for LLVMC to choose the right linker in that case:: - - $ llvmc -c hello.cpp - $ llvmc hello.o - [A lot of link-time errors skipped] - $ llvmc --linker=c++ hello.o - $ ./a.out - hello - -By default, LLVMC uses ``llvm-gcc`` to compile the source code. It is also -possible to choose the ``clang`` compiler with the ``-clang`` option. - - -Predefined options -================== - -LLVMC has some built-in options that can't be overridden in the TableGen code: - -* ``-o FILE`` - Output file name. - -* ``-x LANGUAGE`` - Specify the language of the following input files - until the next -x option. - -* ``-v`` - Enable verbose mode, i.e. print out all executed commands. - -* ``--save-temps`` - Write temporary files to the current directory and do not - delete them on exit. This option can also take an argument: the - ``--save-temps=obj`` switch will write files into the directory specified with - the ``-o`` option. The ``--save-temps=cwd`` and ``--save-temps`` switches are - both synonyms for the default behaviour. - -* ``--temp-dir DIRECTORY`` - Store temporary files in the given directory. This - directory is deleted on exit unless ``--save-temps`` is specified. If - ``--save-temps=obj`` is also specified, ``--temp-dir`` is given the - precedence. - -* ``--check-graph`` - Check the compilation for common errors like mismatched - output/input language names, multiple default edges and cycles. Exit with code - zero if no errors were found, and return the number of found errors - otherwise. Hidden option, useful for debugging. - -* ``--view-graph`` - Show a graphical representation of the compilation graph - and exit. Requires that you have ``dot`` and ``gv`` programs installed. Hidden - option, useful for debugging. - -* ``--write-graph`` - Write a ``compilation-graph.dot`` file in the current - directory with the compilation graph description in Graphviz format (identical - to the file used by the ``--view-graph`` option). The ``-o`` option can be - used to set the output file name. Hidden option, useful for debugging. - -* ``--help``, ``--help-hidden``, ``--version`` - These options have - their standard meaning. - -Compiling LLVMC-based drivers -============================= - -It's easiest to start working on your own LLVMC driver by copying the skeleton -project which lives under ``$LLVMC_DIR/examples/Skeleton``:: - - $ cd $LLVMC_DIR/examples - $ cp -r Skeleton MyDriver - $ cd MyDriver - $ ls - AutoGenerated.td Hooks.cpp Main.cpp Makefile - -As you can see, our basic driver consists of only three files (not counting the -build script). ``AutoGenerated.td`` contains TableGen description of the -compilation graph; its format is documented in the following -sections. ``Hooks.cpp`` is an empty file that should be used for hook -definitions (see `below`__). ``Main.cpp`` is just a helper used to compile the -auto-generated C++ code produced from TableGen source. - -__ hooks_ - -The first thing that you should do is to change the ``LLVMC_BASED_DRIVER`` -variable in the ``Makefile``:: - - LLVMC_BASED_DRIVER=MyDriver - -It can also be a good idea to put your TableGen code into a file with a less -generic name:: - - $ touch MyDriver.td - $ vim AutoGenerated.td - [...] - include "MyDriver.td" - -If you have more than one TableGen source file, they all should be included from -``AutoGenerated.td``, since this file is used by the build system to generate -C++ code. - -To build your driver, just ``cd`` to its source directory and run ``make``. The -resulting executable will be put into ``$LLVM_OBJ_DIR/$(BuildMode)/bin``. - -If you're compiling LLVM with different source and object directories, then you -must perform the following additional steps before running ``make``:: - - # LLVMC_SRC_DIR = $LLVM_SRC_DIR/tools/llvmc/ - # LLVMC_OBJ_DIR = $LLVM_OBJ_DIR/tools/llvmc/ - $ mkdir $LLVMC_OBJ_DIR/examples/MyDriver/ - $ cp $LLVMC_SRC_DIR/examples/MyDriver/Makefile \ - $LLVMC_OBJ_DIR/examples/MyDriver/ - $ cd $LLVMC_OBJ_DIR/examples/MyDriver - $ make - - -Customizing LLVMC: the compilation graph -======================================== - -Each TableGen configuration file should include the common definitions:: - - include "llvm/CompilerDriver/Common.td" - -Internally, LLVMC stores information about possible source transformations in -form of a graph. Nodes in this graph represent tools, and edges between two -nodes represent a transformation path. A special "root" node is used to mark -entry points for the transformations. LLVMC also assigns a weight to each edge -(more on this later) to choose between several alternative edges. - -The definition of the compilation graph (see file ``llvmc/src/Base.td`` for an -example) is just a list of edges:: - - def CompilationGraph : CompilationGraph<[ - Edge<"root", "llvm_gcc_c">, - Edge<"root", "llvm_gcc_assembler">, - ... - - Edge<"llvm_gcc_c", "llc">, - Edge<"llvm_gcc_cpp", "llc">, - ... - - OptionalEdge<"llvm_gcc_c", "opt", (case (switch_on "opt"), - (inc_weight))>, - OptionalEdge<"llvm_gcc_cpp", "opt", (case (switch_on "opt"), - (inc_weight))>, - ... - - OptionalEdge<"llvm_gcc_assembler", "llvm_gcc_cpp_linker", - (case (input_languages_contain "c++"), (inc_weight), - (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")), (inc_weight))>, - ... - - ]>; - -As you can see, the edges can be either default or optional, where optional -edges are differentiated by an additional ``case`` expression used to calculate -the weight of this edge. Notice also that we refer to tools via their names (as -strings). This makes it possible to add edges to an existing compilation graph -without having to know about all tool definitions used in the graph. - -The default edges are assigned a weight of 1, and optional edges get a weight of -0 + 2*N where N is the number of tests that evaluated to true in the ``case`` -expression. It is also possible to provide an integer parameter to -``inc_weight`` and ``dec_weight`` - in this case, the weight is increased (or -decreased) by the provided value instead of the default 2. Default weight of an -optional edge can be changed by using the ``default`` clause of the ``case`` -construct. - -When passing an input file through the graph, LLVMC picks the edge with the -maximum weight. To avoid ambiguity, there should be only one default edge -between two nodes (with the exception of the root node, which gets a special -treatment - there you are allowed to specify one default edge *per language*). - -When multiple compilation graphs are defined, they are merged together. Multiple -edges with the same end nodes are not allowed (i.e. the graph is not a -multigraph), and will lead to a compile-time error. - -To get a visual representation of the compilation graph (useful for debugging), -run ``llvmc --view-graph``. You will need ``dot`` and ``gsview`` installed for -this to work properly. - -Describing options -================== - -Command-line options supported by the driver are defined by using an -``OptionList``:: - - def Options : OptionList<[ - (switch_option "E", (help "Help string")), - (alias_option "quiet", "q") - ... - ]>; - -As you can see, the option list is just a list of DAGs, where each DAG is an -option description consisting of the option name and some properties. More than -one option list can be defined (they are all merged together in the end), which -can be handy if one wants to separate option groups syntactically. - -* Possible option types: - - - ``switch_option`` - a simple boolean switch without arguments, for example - ``-O2`` or ``-time``. At most one occurrence is allowed by default. - - - ``parameter_option`` - option that takes one argument, for example - ``-std=c99``. It is also allowed to use spaces instead of the equality - sign: ``-std c99``. At most one occurrence is allowed. - - - ``parameter_list_option`` - same as the above, but more than one option - occurrence is allowed. - - - ``prefix_option`` - same as the parameter_option, but the option name and - argument do not have to be separated. Example: ``-ofile``. This can be also - specified as ``-o file``; however, ``-o=file`` will be parsed incorrectly - (``=file`` will be interpreted as option value). At most one occurrence is - allowed. - - - ``prefix_list_option`` - same as the above, but more than one occurrence of - the option is allowed; example: ``-lm -lpthread``. - - - ``alias_option`` - a special option type for creating aliases. Unlike other - option types, aliases are not allowed to have any properties besides the - aliased option name. - Usage example: ``(alias_option "preprocess", "E")`` - - - ``switch_list_option`` - like ``switch_option`` with the ``zero_or_more`` - property, but remembers how many times the switch was turned on. Useful - mostly for forwarding. Example: when ``-foo`` is a switch option (with the - ``zero_or_more`` property), the command ``driver -foo -foo`` is forwarded - as ``some-tool -foo``, but when ``-foo`` is a switch list, the same command - is forwarded as ``some-tool -foo -foo``. - - -* Possible option properties: - - - ``help`` - help string associated with this option. Used for ``--help`` - output. - - - ``required`` - this option must be specified exactly once (or, in case of - the list options without the ``multi_val`` property, at least - once). Incompatible with ``optional`` and ``one_or_more``. - - - ``optional`` - the option can be specified either zero times or exactly - once. The default for switch options. Useful only for list options in - conjunction with ``multi_val``. Incompatible with ``required``, - ``zero_or_more`` and ``one_or_more``. - - - ``one_or_more`` - the option must be specified at least once. Can be useful - to allow switch options be both obligatory and be specified multiple - times. For list options is useful only in conjunction with ``multi_val``; - for ordinary it is synonymous with ``required``. Incompatible with - ``required``, ``optional`` and ``zero_or_more``. - - - ``zero_or_more`` - the option can be specified zero or more times. Useful - to allow a single switch option to be specified more than - once. Incompatible with ``required``, ``optional`` and ``one_or_more``. - - - ``hidden`` - the description of this option will not appear in - the ``--help`` output (but will appear in the ``--help-hidden`` - output). - - - ``really_hidden`` - the option will not be mentioned in any help - output. - - - ``comma_separated`` - Indicates that any commas specified for an option's - value should be used to split the value up into multiple values for the - option. This property is valid only for list options. In conjunction with - ``forward_value`` can be used to implement option forwarding in style of - gcc's ``-Wa,``. - - - ``multi_val n`` - this option takes *n* arguments (can be useful in some - special cases). Usage example: ``(parameter_list_option "foo", (multi_val - 3))``; the command-line syntax is '-foo a b c'. Only list options can have - this attribute; you can, however, use the ``one_or_more``, ``optional`` - and ``required`` properties. - - - ``init`` - this option has a default value, either a string (if it is a - parameter), or a boolean (if it is a switch; as in C++, boolean constants - are called ``true`` and ``false``). List options can't have ``init`` - attribute. - Usage examples: ``(switch_option "foo", (init true))``; ``(prefix_option - "bar", (init "baz"))``. - -.. _case: - -Conditional evaluation -====================== - -The 'case' construct is the main means by which programmability is achieved in -LLVMC. It can be used to calculate edge weights, program actions and modify the -shell commands to be executed. The 'case' expression is designed after the -similarly-named construct in functional languages and takes the form ``(case -(test_1), statement_1, (test_2), statement_2, ... (test_N), statement_N)``. The -statements are evaluated only if the corresponding tests evaluate to true. - -Examples:: - - // Edge weight calculation - - // Increases edge weight by 5 if "-A" is provided on the - // command-line, and by 5 more if "-B" is also provided. - (case - (switch_on "A"), (inc_weight 5), - (switch_on "B"), (inc_weight 5)) - - - // Tool command line specification - - // Evaluates to "cmdline1" if the option "-A" is provided on the - // command line; to "cmdline2" if "-B" is provided; - // otherwise to "cmdline3". - - (case - (switch_on "A"), "cmdline1", - (switch_on "B"), "cmdline2", - (default), "cmdline3") - -Note the slight difference in 'case' expression handling in contexts of edge -weights and command line specification - in the second example the value of the -``"B"`` switch is never checked when switch ``"A"`` is enabled, and the whole -expression always evaluates to ``"cmdline1"`` in that case. - -Case expressions can also be nested, i.e. the following is legal:: - - (case (switch_on "E"), (case (switch_on "o"), ..., (default), ...) - (default), ...) - -You should, however, try to avoid doing that because it hurts readability. It is -usually better to split tool descriptions and/or use TableGen inheritance -instead. - -* Possible tests are: - - - ``switch_on`` - Returns true if a given command-line switch is provided by - the user. Can be given multiple arguments, in that case ``(switch_on "foo", - "bar", "baz")`` is equivalent to ``(and (switch_on "foo"), (switch_on - "bar"), (switch_on "baz"))``. - Example: ``(switch_on "opt")``. - - - ``any_switch_on`` - Given a number of switch options, returns true if any of - the switches is turned on. - Example: ``(any_switch_on "foo", "bar", "baz")`` is equivalent to ``(or - (switch_on "foo"), (switch_on "bar"), (switch_on "baz"))``. - - - ``parameter_equals`` - Returns true if a command-line parameter (first - argument) equals a given value (second argument). - Example: ``(parameter_equals "W", "all")``. - - - ``element_in_list`` - Returns true if a command-line parameter list (first - argument) contains a given value (second argument). - Example: ``(element_in_list "l", "pthread")``. - - - ``input_languages_contain`` - Returns true if a given language - belongs to the current input language set. - Example: ``(input_languages_contain "c++")``. - - - ``in_language`` - Evaluates to true if the input file language is equal to - the argument. At the moment works only with ``command`` and ``actions`` (on - non-join nodes). - Example: ``(in_language "c++")``. - - - ``not_empty`` - Returns true if a given option (which should be either a - parameter or a parameter list) is set by the user. Like ``switch_on``, can - be also given multiple arguments. - Examples: ``(not_empty "o")``, ``(not_empty "o", "l")``. - - - ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of - the provided options. - Example: ``(any_not_empty "foo", "bar", "baz")`` is equivalent to ``(or - (not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``. - - - ``empty`` - The opposite of ``not_empty``. Equivalent to ``(not (not_empty - X))``. Can be given multiple arguments. - - - ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of - the provided options. - Example: ``(any_empty "foo", "bar", "baz")`` is equivalent to ``(or - (not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``. - - - ``single_input_file`` - Returns true if there was only one input file - provided on the command-line. Used without arguments: - ``(single_input_file)``. - - - ``multiple_input_files`` - Equivalent to ``(not (single_input_file))`` (the - case of zero input files is considered an error). - - - ``default`` - Always evaluates to true. Should always be the last - test in the ``case`` expression. - - - ``and`` - A standard logical combinator that returns true iff all of - its arguments return true. Used like this: ``(and (test1), (test2), - ... (testN))``. Nesting of ``and`` and ``or`` is allowed, but not - encouraged. - - - ``or`` - A logical combinator that returns true iff any of its arguments - return true. - Example: ``(or (test1), (test2), ... (testN))``. - - - ``not`` - Standard unary logical combinator that negates its - argument. - Example: ``(not (or (test1), (test2), ... (testN)))``. - - -Writing a tool description -========================== - -As was said earlier, nodes in the compilation graph represent tools, which are -described separately. A tool definition looks like this (taken from the -``llvmc/src/Base.td`` file):: - - def llvm_gcc_cpp : Tool<[ - (in_language "c++"), - (out_language "llvm-assembler"), - (output_suffix "bc"), - (command "llvm-g++ -c -emit-llvm"), - (sink) - ]>; - -This defines a new tool called ``llvm_gcc_cpp``, which is an alias for -``llvm-g++``. As you can see, a tool definition is just a list of properties; -most of them should be self-explanatory. The ``sink`` property means that this -tool should be passed all command-line options that aren't mentioned in the -option list. - -The complete list of all currently implemented tool properties follows. - -* Possible tool properties: - - - ``in_language`` - input language name. Can be given multiple arguments, in - case the tool supports multiple input languages. Used for typechecking and - mapping file extensions to tools. - - - ``out_language`` - output language name. Multiple output languages are - allowed. Used for typechecking the compilation graph. - - - ``output_suffix`` - output file suffix. Can also be changed dynamically, see - documentation on `actions`__. - -__ actions_ - - - ``command`` - the actual command used to run the tool. You can use output - redirection with ``>``, hook invocations (``$CALL``), environment variables - (via ``$ENV``) and the ``case`` construct. - - - ``join`` - this tool is a "join node" in the graph, i.e. it gets a list of - input files and joins them together. Used for linkers. - - - ``sink`` - all command-line options that are not handled by other tools are - passed to this tool. - - - ``actions`` - A single big ``case`` expression that specifies how this tool - reacts on command-line options (described in more detail `below`__). - -__ actions_ - - - ``out_file_option``, ``in_file_option`` - Options appended to the - ``command`` string to designate output and input files. Default values are - ``"-o"`` and ``""``, respectively. - -.. _actions: - -Actions -------- - -A tool often needs to react to command-line options, and this is precisely what -the ``actions`` property is for. The next example illustrates this feature:: - - def llvm_gcc_linker : Tool<[ - (in_language "object-code"), - (out_language "executable"), - (output_suffix "out"), - (command "llvm-gcc"), - (join), - (actions (case (not_empty "L"), (forward "L"), - (not_empty "l"), (forward "l"), - (not_empty "dummy"), - [(append_cmd "-dummy1"), (append_cmd "-dummy2")]) - ]>; - -The ``actions`` tool property is implemented on top of the omnipresent ``case`` -expression. It associates one or more different *actions* with given -conditions - in the example, the actions are ``forward``, which forwards a given -option unchanged, and ``append_cmd``, which appends a given string to the tool -execution command. Multiple actions can be associated with a single condition by -using a list of actions (used in the example to append some dummy options). The -same ``case`` construct can also be used in the ``cmd_line`` property to modify -the tool command line. - -The "join" property used in the example means that this tool behaves like a -linker. - -The list of all possible actions follows. - -* Possible actions: - - - ``append_cmd`` - Append a string to the tool invocation command. - Example: ``(case (switch_on "pthread"), (append_cmd "-lpthread"))``. - - - ``error`` - Exit with error. - Example: ``(error "Mixing -c and -S is not allowed!")``. - - - ``warning`` - Print a warning. - Example: ``(warning "Specifying both -O1 and -O2 is meaningless!")``. - - - ``forward`` - Forward the option unchanged. - Example: ``(forward "Wall")``. - - - ``forward_as`` - Change the option's name, but forward the argument - unchanged. - Example: ``(forward_as "O0", "--disable-optimization")``. - - - ``forward_value`` - Forward only option's value. Cannot be used with switch - options (since they don't have values), but works fine with lists. - Example: ``(forward_value "Wa,")``. - - - ``forward_transformed_value`` - As above, but applies a hook to the - option's value before forwarding (see `below`__). When - ``forward_transformed_value`` is applied to a list - option, the hook must have signature - ``std::string hooks::HookName (const std::vector&)``. - Example: ``(forward_transformed_value "m", "ConvertToMAttr")``. - - __ hooks_ - - - ``output_suffix`` - Modify the output suffix of this tool. - Example: ``(output_suffix "i")``. - - - ``stop_compilation`` - Stop compilation after this tool processes its - input. Used without arguments. - Example: ``(stop_compilation)``. - - -Language map -============ - -If you are adding support for a new language to LLVMC, you'll need to modify the -language map, which defines mappings from file extensions to language names. It -is used to choose the proper toolchain(s) for a given input file set. Language -map definition looks like this:: - - def LanguageMap : LanguageMap< - [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>, - LangToSuffixes<"c", ["c"]>, - ... - ]>; - -For example, without those definitions the following command wouldn't work:: - - $ llvmc hello.cpp - llvmc: Unknown suffix: cpp - -The language map entries are needed only for the tools that are linked from the -root node. A tool can have multiple output languages. - -Option preprocessor -=================== - -It is sometimes useful to run error-checking code before processing the -compilation graph. For example, if optimization options "-O1" and "-O2" are -implemented as switches, we might want to output a warning if the user invokes -the driver with both of these options enabled. - -The ``OptionPreprocessor`` feature is reserved specially for these -occasions. Example (adapted from ``llvm/src/Base.td.in``):: - - - def Preprocess : OptionPreprocessor< - (case (not (any_switch_on "O0", "O1", "O2", "O3")), - (set_option "O2"), - (and (switch_on "O3"), (any_switch_on "O0", "O1", "O2")), - (unset_option "O0", "O1", "O2"), - (and (switch_on "O2"), (any_switch_on "O0", "O1")), - (unset_option "O0", "O1"), - (and (switch_on "O1"), (switch_on "O0")), - (unset_option "O0")) - >; - -Here, ``OptionPreprocessor`` is used to unset all spurious ``-O`` options so -that they are not forwarded to the compiler. If no optimization options are -specified, ``-O2`` is enabled. - -``OptionPreprocessor`` is basically a single big ``case`` expression, which is -evaluated only once right after the driver is started. The only allowed actions -in ``OptionPreprocessor`` are ``error``, ``warning``, and two special actions: -``unset_option`` and ``set_option``. As their names suggest, they can be used to -set or unset a given option. To set an option with ``set_option``, use the -two-argument form: ``(set_option "parameter", VALUE)``. Here, ``VALUE`` can be -either a string, a string list, or a boolean constant. - -For convenience, ``set_option`` and ``unset_option`` also work with multiple -arguments. That is, instead of ``[(unset_option "A"), (unset_option "B")]`` you -can use ``(unset_option "A", "B")``. Obviously, ``(set_option "A", "B")`` is -only valid if both ``A`` and ``B`` are switches. - - -More advanced topics -==================== - -.. _hooks: - -Hooks and environment variables -------------------------------- - -Normally, LLVMC searches for programs in the system ``PATH``. Sometimes, this is -not sufficient: for example, we may want to specify tool paths or names in the -configuration file. This can be achieved via the hooks mechanism. To write your -own hooks, add their definitions to the ``Hooks.cpp`` or drop a ``.cpp`` file -into your driver directory. Hooks should live in the ``hooks`` namespace and -have the signature ``std::string hooks::MyHookName ([const char* Arg0 [ const -char* Arg2 [, ...]]])``. They can be used from the ``command`` tool property:: - - (command "$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)") - -To pass arguments to hooks, use the following syntax:: - - (command "$CALL(MyHook, 'Arg1', 'Arg2', 'Arg # 3')/path/to/file -o1 -o2") - -It is also possible to use environment variables in the same manner:: - - (command "$ENV(VAR1)/path/to/file -o $ENV(VAR2)") - -To change the command line string based on user-provided options use -the ``case`` expression (documented `above`__):: - - (command - (case - (switch_on "E"), - "llvm-g++ -E -x c $INFILE -o $OUTFILE", - (default), - "llvm-g++ -c -x c $INFILE -o $OUTFILE -emit-llvm")) - -__ case_ - -Debugging ---------- - -When writing LLVMC-based drivers, it can be useful to get a visual view of the -resulting compilation graph. This can be achieved via the command line option -``--view-graph`` (which assumes that Graphviz_ and Ghostview_ are -installed). There is also a ``--write-graph`` option that creates a Graphviz -source file (``compilation-graph.dot``) in the current directory. - -Another useful ``llvmc`` option is ``--check-graph``. It checks the compilation -graph for common errors like mismatched output/input language names, multiple -default edges and cycles. When invoked with ``--check-graph``, ``llvmc`` doesn't -perform any compilation tasks and returns the number of encountered errors as -its status code. In the future, these checks will be performed at compile-time -and this option will disappear. - -.. _Graphviz: http://www.graphviz.org/ -.. _Ghostview: http://pages.cs.wisc.edu/~ghost/ - -Conditioning on the executable name ------------------------------------ - -For now, the executable name (the value passed to the driver in ``argv[0]``) is -accessible only in the C++ code (i.e. hooks). Use the following code:: - - namespace llvmc { - extern const char* ProgramName; - } - - namespace hooks { - - std::string MyHook() { - //... - if (strcmp(ProgramName, "mydriver") == 0) { - //... - - } - - } // end namespace hooks - -In general, you're encouraged not to make the behaviour dependent on the -executable file name, and use command-line switches instead. See for example how -the ``llvmc`` program behaves when it needs to choose the correct linker options -(think ``g++`` vs. ``gcc``). - -.. raw:: html - -
    -
    - - Valid CSS - - Valid XHTML 1.0 Transitional - - Mikhail Glushenkov
    - LLVM Compiler Infrastructure
    - - Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $ -
    diff --git a/tools/llvmc/doc/LLVMC-Tutorial.rst b/tools/llvmc/doc/LLVMC-Tutorial.rst deleted file mode 100644 index fc4c12408c40..000000000000 --- a/tools/llvmc/doc/LLVMC-Tutorial.rst +++ /dev/null @@ -1,127 +0,0 @@ -====================== -Tutorial - Using LLVMC -====================== -.. - This file was automatically generated by rst2html. - Please do not edit directly! - The ReST source lives in the directory 'tools/llvmc/doc'. - -.. contents:: - -.. raw:: html - -
    -

    Written by Mikhail Glushenkov

    -
    - -Introduction -============ - -LLVMC is a generic compiler driver, which plays the same role for LLVM as the -``gcc`` program does for GCC - the difference being that LLVMC is designed to be -more adaptable and easier to customize. Most of LLVMC functionality is -implemented via high-level TableGen code, from which a corresponding C++ source -file is automatically generated. This tutorial describes the basic usage and -configuration of LLVMC. - - -Using the ``llvmc`` program -=========================== - -In general, ``llvmc`` tries to be command-line compatible with ``gcc`` as much -as possible, so most of the familiar options work:: - - $ llvmc -O3 -Wall hello.cpp - $ ./a.out - hello - -This will invoke ``llvm-g++`` under the hood (you can see which commands are -executed by using the ``-v`` option). For further help on command-line LLVMC -usage, refer to the ``llvmc --help`` output. - - -Using LLVMC to generate toolchain drivers -========================================= - -LLVMC-based drivers are written mostly using TableGen_, so you need to be -familiar with it to get anything done. - -.. _TableGen: http://llvm.org/docs/TableGenFundamentals.html - -Start by compiling ``example/Simple``, which is a primitive wrapper for -``gcc``:: - - $ cd $LLVM_OBJ_DIR/tools/examples/Simple - $ make - $ cat > hello.c - #include - int main() { printf("Hello\n"); } - $ $LLVM_BIN_DIR/Simple -v hello.c - gcc hello.c -o hello.out - $ ./hello.out - Hello - -We have thus produced a simple driver called, appropriately, ``Simple``, from -the input TableGen file ``Simple.td``. The ``llvmc`` program itself is generated -using a similar process (see ``llvmc/src``). Contents of the file ``Simple.td`` -look like this:: - - // Include common definitions - include "llvm/CompilerDriver/Common.td" - - // Tool descriptions - def gcc : Tool< - [(in_language "c"), - (out_language "executable"), - (output_suffix "out"), - (command "gcc"), - (sink), - - // -o is what is used by default, out_file_option here is included for - // instructive purposes. - (out_file_option "-o") - ]>; - - // Language map - def LanguageMap : LanguageMap<[(lang_to_suffixes "c", "c")]>; - - // Compilation graph - def CompilationGraph : CompilationGraph<[(edge "root", "gcc")]>; - -As you can see, this file consists of three parts: tool descriptions, language -map, and the compilation graph definition. - -At the heart of LLVMC is the idea of a compilation graph: vertices in this graph -are tools, and edges represent a transformation path between two tools (for -example, assembly source produced by the compiler can be transformed into -executable code by an assembler). The compilation graph is basically a list of -edges; a special node named ``root`` is used to mark graph entry points. - -Tool descriptions are represented as property lists: most properties in the -example above should be self-explanatory; the ``sink`` property means that all -options lacking an explicit description should be forwarded to this tool. - -The ``LanguageMap`` associates a language name with a list of suffixes and is -used for deciding which toolchain corresponds to a given input file. - -To learn more about writing your own drivers with LLVMC, refer to the reference -manual and examples in the ``examples`` directory. Of a particular interest is -the ``Skeleton`` example, which can serve as a template for your LLVMC-based -drivers. - -.. raw:: html - -
    -
    - - Valid CSS - - Valid XHTML 1.0 Transitional - - Mikhail Glushenkov
    - LLVM Compiler Infrastructure
    - - Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $ -
    diff --git a/tools/llvmc/doc/Makefile b/tools/llvmc/doc/Makefile deleted file mode 100644 index ef98767e7b48..000000000000 --- a/tools/llvmc/doc/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -##===- tools/llvmc/doc/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL=../../.. - -ifneq (,$(strip $(wildcard $(LEVEL)/Makefile.config))) -include $(LEVEL)/Makefile.config -else -CP=cp -RM=rm -endif - -DOC_DIR=../../../docs -RST2HTML=rst2html --stylesheet=llvm.css --link-stylesheet - -all : LLVMC-Reference.html LLVMC-Tutorial.html - $(CP) LLVMC-Reference.html $(DOC_DIR)/CompilerDriver.html - $(CP) LLVMC-Tutorial.html $(DOC_DIR)/CompilerDriverTutorial.html - -LLVMC-Tutorial.html : LLVMC-Tutorial.rst - $(RST2HTML) $< $@ - -LLVMC-Reference.html : LLVMC-Reference.rst - $(RST2HTML) $< $@ - -clean : - $(RM) LLVMC-Tutorial.html LLVMC-Reference.html diff --git a/tools/llvmc/doc/img/lines.gif b/tools/llvmc/doc/img/lines.gif deleted file mode 100644 index 88f491edc302684624036548ce3910f32cd4514f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91 zcmZ?wbhEHb6kw2JSj4~}!yWbi|Nq;!Zv#mNB%lLggVZoEYe?+6^Uvpm=jsLv^V7@! jMO<%uq861ZHD`s_rm4RV&HHn4>)eNv)_rVZVXy`Ob}}Q< diff --git a/tools/llvmc/examples/Hello/Hello.cpp b/tools/llvmc/examples/Hello/Hello.cpp deleted file mode 100644 index 71f04fdd49d7..000000000000 --- a/tools/llvmc/examples/Hello/Hello.cpp +++ /dev/null @@ -1,29 +0,0 @@ -//===- Hello.cpp - Example code from "Writing an LLVMC Plugin" ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Shows how to write llvmc-based drivers without using TableGen. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CompilerDriver/AutoGenerated.h" -#include "llvm/CompilerDriver/Main.inc" - -#include "llvm/Support/raw_ostream.h" - -namespace llvmc { -namespace autogenerated { - -int PreprocessOptions () { return 0; } - -int PopulateLanguageMap (LanguageMap&) { llvm::outs() << "Hello!\n"; return 0; } - -int PopulateCompilationGraph (CompilationGraph&) { return 0; } - -} -} diff --git a/tools/llvmc/examples/Simple/Simple.cpp b/tools/llvmc/examples/Simple/Simple.cpp deleted file mode 100644 index 8ac73130f9eb..000000000000 --- a/tools/llvmc/examples/Simple/Simple.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "llvm/CompilerDriver/Main.inc" -#include "Simple.inc" diff --git a/tools/llvmc/examples/Simple/Simple.td b/tools/llvmc/examples/Simple/Simple.td deleted file mode 100644 index b47483b5d382..000000000000 --- a/tools/llvmc/examples/Simple/Simple.td +++ /dev/null @@ -1,41 +0,0 @@ -//===- Simple.td - A simple LLVMC-based driver ----------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// A simple LLVMC-based gcc wrapper. -// -// To compile, use this command: -// -// $ cd $LLVM_OBJ_DIR/tools/llvmc -// $ make BUILD_EXAMPLES=1 -// -// Run as: -// -// $ $LLVM_OBJ_DIR/$(BuildMode)/bin/Simple -// -// For instructions on how to build your own LLVMC-based driver, see -// the 'examples/Skeleton' directory. -//===----------------------------------------------------------------------===// - -include "llvm/CompilerDriver/Common.td" - -def gcc : Tool< -[(in_language "c"), - (out_language "executable"), - (output_suffix "out"), - (command "gcc"), - (sink), - - // -o is what is used by default, out_file_option here is included for - // instructive purposes. - (out_file_option "-o") -]>; - -def LanguageMap : LanguageMap<[(lang_to_suffixes "c", "c")]>; - -def CompilationGraph : CompilationGraph<[(edge "root", "gcc")]>; diff --git a/tools/llvmc/examples/Skeleton/AutoGenerated.td b/tools/llvmc/examples/Skeleton/AutoGenerated.td deleted file mode 100644 index 97483ce92822..000000000000 --- a/tools/llvmc/examples/Skeleton/AutoGenerated.td +++ /dev/null @@ -1,7 +0,0 @@ -//===- AutoGenerated.td ------------------------------------*- tablegen -*-===// -// -// Write the TableGen description of your llvmc-based driver here. -// -//===----------------------------------------------------------------------===// - -include "llvm/CompilerDriver/Common.td" diff --git a/tools/llvmc/examples/Skeleton/Hooks.cpp b/tools/llvmc/examples/Skeleton/Hooks.cpp deleted file mode 100644 index ddd38f6e707c..000000000000 --- a/tools/llvmc/examples/Skeleton/Hooks.cpp +++ /dev/null @@ -1,12 +0,0 @@ -//===--- Hooks.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Hook definitions should go here. -// -//===----------------------------------------------------------------------===// diff --git a/tools/llvmc/examples/Skeleton/Main.cpp b/tools/llvmc/examples/Skeleton/Main.cpp deleted file mode 100644 index 24c7768f93b7..000000000000 --- a/tools/llvmc/examples/Skeleton/Main.cpp +++ /dev/null @@ -1,15 +0,0 @@ -//===--- Main.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Just include CompilerDriver/Main.inc and AutoGenerated.inc. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CompilerDriver/Main.inc" -#include "AutoGenerated.inc" diff --git a/tools/llvmc/examples/Skeleton/Makefile b/tools/llvmc/examples/Skeleton/Makefile deleted file mode 100644 index 41ca8235e24d..000000000000 --- a/tools/llvmc/examples/Skeleton/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -##===- llvmc/examples/Skeleton/Makefile --------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open -# Source License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -# Change this so that $(LEVEL)/Makefile.common refers to -# $LLVM_OBJ_DIR/Makefile.common or $YOUR_LLVM_BASED_PROJECT/Makefile.common. -export LEVEL = ../../../.. - -# Change this to the name of your LLVMC-based driver. -LLVMC_BASED_DRIVER = llvmc-skeleton - -# Change this to the name of .inc file built from your .td file. -BUILT_SOURCES = AutoGenerated.inc - -include $(LEVEL)/Makefile.common diff --git a/tools/llvmc/examples/Skeleton/README b/tools/llvmc/examples/Skeleton/README deleted file mode 100644 index 282ee15d35db..000000000000 --- a/tools/llvmc/examples/Skeleton/README +++ /dev/null @@ -1,6 +0,0 @@ - -This is a template that can be used to create your own LLVMC-based drivers. Just -copy the `Skeleton` directory to the location of your preference and edit -`Skeleton/Makefile` and `Skeleton/AutoGenerated.td`. - -The build system assumes that your project is based on LLVM. diff --git a/tools/llvmc/examples/mcc16/Hooks.cpp b/tools/llvmc/examples/mcc16/Hooks.cpp deleted file mode 100644 index 95158efeece0..000000000000 --- a/tools/llvmc/examples/mcc16/Hooks.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "llvm/Support/Path.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/raw_ostream.h" - -#include - -namespace llvmc { - extern char *ProgramName; - - namespace autogenerated { - extern llvm::cl::opt Parameter_p; - } -} - -using namespace llvm; -using namespace llvmc; - -// Returns the platform specific directory separator via #ifdefs. -// FIXME: This currently work on linux and windows only. It does not -// work on other unices. -static std::string GetDirSeparator() { -#if __linux__ || __APPLE__ - return "/"; -#else - return "\\"; -#endif -} - -namespace hooks { -// Get preprocessor define for the part. -// It is __partname format in lower case. -std::string -GetLowerCasePartDefine(void) { - std::string Partname; - if (autogenerated::Parameter_p.empty()) { - Partname = "16f1xxx"; - } else { - Partname = autogenerated::Parameter_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 (autogenerated::Parameter_p.empty()) { - Partname = "16f1xxx"; - } else { - Partname = autogenerated::Parameter_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. - void *P = (void*) (intptr_t) GetBinDir; - sys::Path ProgramFullPath - = sys::Path::GetMainExecutable(llvmc::ProgramName, P); - - // Get the dir name for the program. It's last component should be 'bin'. - std::string BinDir = ProgramFullPath.getDirname(); - - // llvm::errs() << "BinDir: " << BinDir << '\n'; - return BinDir + GetDirSeparator(); -} - -// Get the Top-level Installation dir for c16. -std::string GetInstallDir() { - sys::Path BinDirPath = sys::Path(GetBinDir()); - - // Go one more level up to get the install dir. - std::string InstallDir = BinDirPath.getDirname(); - - return InstallDir + GetDirSeparator(); -} - -// Get the dir where the c16 header files reside. -std::string GetStdHeadersDir() { - return GetInstallDir() + "include"; -} - -// Get the dir where the assembler header files reside. -std::string GetStdAsmHeadersDir() { - return GetInstallDir() + "inc"; -} - -// Get the dir where the linker scripts reside. -std::string GetStdLinkerScriptsDir() { - return GetInstallDir() + "lkr"; -} - -// Get the dir where startup code, intrinsics and lib reside. -std::string GetStdLibsDir() { - return GetInstallDir() + "lib"; -} -} diff --git a/tools/llvmc/examples/mcc16/Main.cpp b/tools/llvmc/examples/mcc16/Main.cpp deleted file mode 100644 index 5d4992dd9ce7..000000000000 --- a/tools/llvmc/examples/mcc16/Main.cpp +++ /dev/null @@ -1,57 +0,0 @@ -//===--- Main.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Usually this file just includes CompilerDriver/Main.inc, but here we apply -// some trickery to make the built-in '-save-temps' option hidden and enable -// '--temp-dir' by default. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CompilerDriver/BuiltinOptions.h" -#include "llvm/CompilerDriver/Main.h" - -#include "llvm/Support/Path.h" -#include "llvm/Config/config.h" - -#include - -#include "PIC16.inc" - -namespace { - -// Modify the PACKAGE_VERSION to use build number in top level configure file. -void PIC16VersionPrinter(void) { - std::cout << "MPLAB C16 1.0 " << PACKAGE_VERSION << "\n"; -} - -} - -int main(int argc, char** argv) { - - // HACK - SaveTemps.setHiddenFlag(llvm::cl::Hidden); - TempDirname.setHiddenFlag(llvm::cl::Hidden); - Languages.setHiddenFlag(llvm::cl::Hidden); - DryRun.setHiddenFlag(llvm::cl::Hidden); - - llvm::cl::SetVersionPrinter(PIC16VersionPrinter); - - // 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); - - return llvmc::Main(argc, argv); -} diff --git a/tools/llvmc/examples/mcc16/PIC16.td b/tools/llvmc/examples/mcc16/PIC16.td deleted file mode 100644 index 6f0419675e0c..000000000000 --- a/tools/llvmc/examples/mcc16/PIC16.td +++ /dev/null @@ -1,234 +0,0 @@ -//===- PIC16.td - PIC16 toolchain driver -------------------*- tablegen -*-===// -// -// A basic driver for the PIC16 toolchain. -// -//===----------------------------------------------------------------------===// - -include "llvm/CompilerDriver/Common.td" - -// Options - -def OptionList : OptionList<[ - (switch_option "g", - (help "Enable Debugging")), - (switch_option "E", - (help "Stop after preprocessing, do not compile")), - (switch_option "S", - (help "Stop after compilation, do not assemble")), - (switch_option "bc", - (help "Stop after b-code generation, do not compile")), - (switch_option "c", - (help "Stop after assemble, do not link")), - (prefix_option "p", - (help "Specify part name")), - (prefix_list_option "I", - (help "Add a directory to include path")), - (prefix_list_option "L", - (help "Add a directory to library path")), - (prefix_list_option "K", - (help "Add a directory to linker script search path")), - (parameter_option "l", - (help "Specify a library to link")), - (parameter_option "k", - (help "Specify a linker script")), - (parameter_option "m", - (help "Generate linker map file with the given name")), - (prefix_list_option "D", - (help "Define a macro")), - (switch_option "X", - (help "Do not invoke mp2hex to create an output hex file.")), - (switch_option "O0", - (help "Do not optimize")), - (switch_option "O1", - (help "Optimization Level 1.")), - (switch_option "O2", - (help "Optimization Level 2.")), - (switch_option "O3", - (help "Optimization Level 3.")), - (switch_option "Od", - (help "Perform Debug-safe Optimizations only.")), - (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=linearscan)")), - (prefix_list_option "Wa,", (comma_separated), - (help "Pass options to assembler (Run 'gpasm -help' for assembler options)")), - (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 -class clang_based : Tool< -[(in_language language), - (out_language "llvm-bitcode"), - (output_suffix "bc"), - (command cmd), - (actions (case - (and (multiple_input_files), - (or (switch_on "S"), (switch_on "c"))), - (error "cannot specify -o with -c or -S with multiple files"), - (switch_on "E"), [(forward "E"), - (stop_compilation), (output_suffix ext_E)], - (and (switch_on "E"), (empty "o")), (no_out_file), - (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 ""), - (switch_on "Od"), (append_cmd ""), - (not_empty "D"), (forward "D"), - (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) -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. -def llvm_ld : Tool<[ - (in_language "llvm-bitcode"), - (out_language "llvm-bitcode"), - (output_suffix "bc"), - (command "$CALL(GetBinDir)llvm-ld -L $CALL(GetStdLibsDir) -disable-licm-promotion -l std"), - (out_file_option "-b"), - (actions (case - (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"))), - (join) -]>; - -// optimize single file -def llvm_ld_optimizer : Tool<[ - (in_language "llvm-bitcode"), - (out_language "llvm-bitcode"), - (output_suffix "bc"), -// FIXME: we are still not disabling licm-promotion. -// -disable-licm-promotion and building stdn library causes c16-71 to fail. - (command "$CALL(GetBinDir)llvm-ld "), - (out_file_option "-b"), - (actions (case - (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. -def pic16passes : Tool<[ - (in_language "llvm-bitcode"), - (out_language "llvm-bitcode"), - (output_suffix "obc"), - (command "$CALL(GetBinDir)opt -pic16cloner -pic16overlay -f"), - (actions (case - (switch_on "O0"), (append_cmd "-disable-opt"))) -]>; - -def llc : Tool<[ - (in_language "llvm-bitcode"), - (out_language "assembler"), - (output_suffix "s"), - (command "$CALL(GetBinDir)llc -march=pic16 -disable-jump-tables -pre-RA-sched=list-burr -f"), - (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=linearscan"))) -]>; - -def gpasm : Tool<[ - (in_language "assembler"), - (out_language "object-code"), - (output_suffix "o"), - (command "$CALL(GetBinDir)gpasm -z -r decimal -I $CALL(GetStdAsmHeadersDir) -C -c -w 2"), - (actions (case - (switch_on "c"), (stop_compilation), - (switch_on "g"), (append_cmd "-g"), - (not_empty "p"), (forward "p"), - (empty "p"), (append_cmd "-p 16f1xxx"), - (not_empty "Wa,"), (forward_value "Wa,"))) -]>; - -def mplink : Tool<[ - (in_language "object-code"), - (out_language "executable"), - (output_suffix "cof"), - (command "$CALL(GetBinDir)mplink -e -k $CALL(GetStdLinkerScriptsDir) -l $CALL(GetStdLibsDir) intrinsics.lib stdn.lib"), - (actions (case - (not_empty "Wl,"), (forward_value "Wl,"), - (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 "l"), [(unpack_values "l"),(append_cmd ".lib")])), - (not_empty "k"), (forward "k"), - (not_empty "l"), (forward "l"))), - (join) -]>; - -// Language map - -def LanguageMap : LanguageMap<[ - (lang_to_suffixes "c", "c"), - (lang_to_suffixes "c-cpp-output", "i"), - (lang_to_suffixes "assembler", "s"), - (lang_to_suffixes "assembler-with-cpp", "S"), - (lang_to_suffixes "llvm-assembler", "ll"), - (lang_to_suffixes "llvm-bitcode", "bc"), - (lang_to_suffixes "object-code", "o"), - (lang_to_suffixes "executable", "cof") -]>; - -// Compilation graph - -def CompilationGraph : CompilationGraph<[ - (edge "root", "clang_cc"), - (edge "root", "llvm_ld"), - (optional_edge "root", "llvm_ld_optimizer", - (case (switch_on "S"), (inc_weight), - (switch_on "c"), (inc_weight))), - (edge "root", "gpasm"), - (edge "root", "mplink"), - (edge "clang_cc", "llvm_ld"), - (optional_edge "clang_cc", "llvm_ld_optimizer", - (case (switch_on "S"), (inc_weight), - (switch_on "c"), (inc_weight))), - (edge "llvm_ld", "pic16passes"), - (edge "llvm_ld_optimizer", "pic16passes"), - (edge "pic16passes", "llc"), - (edge "llc", "gpasm"), - (edge "gpasm", "mplink") -]>; diff --git a/tools/llvmc/examples/mcc16/README b/tools/llvmc/examples/mcc16/README deleted file mode 100644 index 6d2b73d5d979..000000000000 --- a/tools/llvmc/examples/mcc16/README +++ /dev/null @@ -1,75 +0,0 @@ -This is a basic compiler driver for the PIC16 toolchain that shows how to create -your own llvmc-based drivers. It is based on the examples/Skeleton template. - -The PIC16 toolchain looks like this: - -clang-cc (FE) -> llvm-ld (optimizer) -> llc (codegen) -> native-as -> native-ld - -Following features were requested by Sanjiv: - -From: Sanjiv Gupta microchip.com> -Subject: Re: llvmc for PIC16 -Newsgroups: gmane.comp.compilers.llvm.devel -Date: 2009-06-05 06:51:14 GMT - -The salient features that we want to have in the driver are: -1. llvm-ld will be used as "The Optimizer". -2. If the user has specified to generate the final executable, then -llvm-ld should run on all the .bc files generated by clang and create a -single optimized .bc file for further tools. -3. -Wo - pass optimizations to the llvm-ld -4. mcc16 -Wl - pass options to native linker. -5. mcc16 -Wa - pass options to native assembler. - -Here are some example command lines and sample command invocations as to -what should be done. - -$ mcc16 -S foo.c -// [clang-cc foo.c] -> foo.bc -// [llvm-ld foo.bc] -> foo.opt.bc -// [llc foo.opt.bc] -> foo.s - -$ mcc16 -S foo.c bar.c -// [clang-cc foo.c] -> foo.bc -// [llvm-ld foo.bc] -> foo.opt.bc -// [llc foo.opt.bc] -> foo.s -// [clang-cc bar.c] -> bar.bc -// [llvm-ld bar.bc] -> bar.opt.bc -// [llc bar.opt.bc] -> bar.s - -** Use of -g causes llvm-ld to run with -disable-opt -$ mcc16 -S -g foo.c -// [clang-cc foo.c] -> foo.bc -// [llvm-ld -disable-opt foo.bc] -> foo.opt.bc -// [llc foo.opt.bc] -> foo.s - -** -I is passed to clang-cc, -pre-RA-sched=list-burr to llc. -$ mcc16 -S -g -I ../include -pre-RA-sched=list-burr foo.c -// [clang-cc -I ../include foo.c] -> foo.bc -// [llvm-ld -disable-opt foo.bc] -> foo.opt.bc -// [llc -pre-RA-sched=list-burr foo.opt.bc] -> foo.s - -** -Wo passes options to llvm-ld -$ mcc16 -Wo=opt1,opt2 -S -I ../include -pre-RA-sched=list-burr foo.c -// [clang-cc -I ../include foo.c] -> foo.bc -// [llvm-ld -opt1 -opt2 foo.bc] -> foo.opt.bc -// [llc -pre-RA-sched=list-burr foo.opt.bc] -> foo.s - -** -Wa passes options to native as. -$ mcc16 -c foo.c -Wa=opt1 -// [clang-cc foo.c] -> foo.bc -// [llvm-ld foo.bc] -> foo.opt.bc -// [llc foo.opt.bc] -> foo.s -// [native-as -opt1 foo.s] -> foo.o - -$ mcc16 -Wo=opt1 -Wl=opt2 -Wa=opt3 foo.c bar.c -// [clang-cc foo.c] -> foo.bc -// [clang-cc bar.c] -> bar.bc -// [llvm-ld -opt1 foo.bc bar.bc] -> a.out.bc -// [llc a.out.bc] -> a.out.s -// [native-as -opt3 a.out.s] -> a.out.o -// [native-ld -opt2 a.out.o] -> a.out - -Is this achievable by a tablegen based driver ? - -- Sanjiv diff --git a/tools/llvmc/src/AutoGenerated.td b/tools/llvmc/src/AutoGenerated.td deleted file mode 100644 index 8507b1ff225a..000000000000 --- a/tools/llvmc/src/AutoGenerated.td +++ /dev/null @@ -1,17 +0,0 @@ -//===- AutoGenerated.td - LLVMC toolchain descriptions -----*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains compilation graph description used by llvmc. -// -//===----------------------------------------------------------------------===// - -include "llvm/CompilerDriver/Common.td" - -include "Base.td" -include "Clang.td" diff --git a/tools/llvmc/src/Base.td.in b/tools/llvmc/src/Base.td.in deleted file mode 100644 index 84e39e756e63..000000000000 --- a/tools/llvmc/src/Base.td.in +++ /dev/null @@ -1,461 +0,0 @@ -//===- Base.td - LLVMC toolchain descriptions --------------*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains compilation graph description used by llvmc. -// -//===----------------------------------------------------------------------===// - -// Options - -def OptList : OptionList<[ - (switch_option "emit-llvm", - (help "Emit LLVM .ll files instead of native object files")), - (switch_option "E", - (help "Stop after the preprocessing stage, do not run the compiler")), - (switch_option "fsyntax-only", - (help "Stop after checking the input for syntax errors")), - (switch_option "opt", - (help "Enable opt")), - (switch_option "O0", - (help "Turn off optimization"), (zero_or_more)), - (switch_option "O1", - (help "Optimization level 1"), (zero_or_more)), - (switch_option "O2", - (help "Optimization level 2"), (zero_or_more)), - (switch_option "O3", - (help "Optimization level 3"), (zero_or_more)), - (switch_option "S", - (help "Stop after compilation, do not assemble")), - (switch_option "c", - (help "Compile and assemble, but do not link")), - (switch_option "m32", - (help "Generate code for a 32-bit environment"), (hidden)), - (switch_option "m64", - (help "Generate code for a 64-bit environment"), (hidden)), - (switch_option "fPIC", - (help "Relocation model: PIC"), (hidden)), - (switch_option "mdynamic-no-pic", - (help "Relocation model: dynamic-no-pic"), (hidden)), - (parameter_option "linker", - (help "Choose linker (possible values: gcc, g++)")), - (parameter_option "mtune", - (help "Target a specific CPU type"), (forward_not_split)), - (parameter_list_option "march", - (help "Generate code for the specified machine type")), - (parameter_option "mcpu", - (help "A deprecated synonym for -mtune"), (hidden), (forward_not_split)), - (parameter_option "mfpu", - (help "Specify type of floating point unit"), - (hidden), (forward_not_split)), - (parameter_option "mabi", - (help "Generate code for the specified ABI"), (hidden)), - (parameter_option "mfloat-abi", - (help "Specifies which floating-point ABI to use"), (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", - (help "Change the name of the rule emitted by dependency generation"), - (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)), - (prefix_list_option "I", - (help "Add a directory to include path")), - (prefix_list_option "D", - (help "Define a macro")), - (parameter_list_option "Xpreprocessor", (hidden), - (help "Pass options to preprocessor")), - (prefix_list_option "Wa,", (comma_separated), - (help "Pass options to assembler")), - (parameter_list_option "Xassembler", (hidden), - (help "Pass options to assembler")), - (prefix_list_option "Wllc,", (comma_separated), - (help "Pass options to llc")), - (prefix_list_option "Wl,", - (help "Pass options to linker")), - (parameter_list_option "Xlinker", (hidden), - (help "Pass options to linker")), - (prefix_list_option "Wo,", (comma_separated), - (help "Pass options to opt")), - (prefix_list_option "m", - (help "Enable or disable various extensions (-mmmx, -msse, etc.)"), - (hidden)) -]>; - -def LinkerOptList : OptionList<[ - (prefix_list_option "L", - (help "Add a directory to link path")), - (prefix_list_option "l", - (help "Search a library when linking")), - (parameter_option "filelist", (hidden), - (help "Link the files listed in file")), - (switch_option "nostartfiles", - (help "Do not use the standard system startup files when linking"), - (hidden)), - (switch_option "nodefaultlibs", - (help "Do not use the standard system libraries when linking"), (hidden)), - (switch_option "nostdlib", - (help - "Do not use the standard system startup files or libraries when linking"), - (hidden)), - (switch_option "pie", - (help "Produce a position independent executable"), (hidden)), - (switch_option "rdynamic", - (help "Add all symbols to the dynamic export table"), (hidden)), - (switch_option "s", - (help "Strip all symbols"), (hidden)), - (switch_option "static", - (help "Do not link against shared libraries"), (hidden)), - (switch_option "static-libgcc", - (help "Use static libgcc"), (hidden)), - (switch_option "shared", - (help "Create a DLL instead of the regular executable")), - (switch_option "shared-libgcc", - (help "Use shared libgcc"), (hidden)), - (parameter_option "T", - (help "Read linker script"), (hidden)), - (parameter_option "u", - (help "Start with undefined reference to SYMBOL"), (hidden)), - (switch_option "pthread", - (help "Enable threads")), - - // 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)), - (prefix_list_option "F", - (help "Add a directory to framework search path")), - (parameter_list_option "framework", - (help "Specifies a framework to link against")), - (parameter_list_option "weak_framework", - (help "Specifies a framework to weakly link against"), (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 "install_name", (hidden), - (help "File name the library will be installed in")), - (parameter_option "compatibility_version", (hidden), - (help "Compatibility version number")), - (parameter_option "current_version", (hidden), - (help "Current version number")) -]>; - -// Option preprocessor. - -def Preprocess : OptionPreprocessor< -(case (not (any_switch_on "O0", "O1", "O2", "O3")), - (set_option "O2"), - (and (switch_on "O3"), (any_switch_on "O0", "O1", "O2")), - (unset_option "O0", "O1", "O2"), - (and (switch_on "O2"), (any_switch_on "O0", "O1")), - (unset_option "O0", "O1"), - (switch_on "O1", "O0"), - (unset_option "O0")) ->; - -// Tools - -class llvm_gcc_based : Tool< -[(in_language in_lang), - out_lang, - (output_suffix out_ext), - (command cmd), - (actions - (case - (and (not_empty "o"), - (multiple_input_files), (or (switch_on "S"), (switch_on "c"))), - (error "cannot specify -o with -c or -S with multiple files"), - (switch_on "E"), - [(forward "E"), (stop_compilation), (output_suffix E_ext)], - (and (switch_on "E"), (empty "o")), (no_out_file), - - // ('-emit-llvm') && !('opt') -> stop compilation - (and (switch_on "emit-llvm"), (not (switch_on "opt"))), - (stop_compilation), - // ('-S' && '-emit-llvm') && !('opt') -> output .ll - (and (switch_on "emit-llvm", "S"), (not (switch_on "opt"))), - [(forward "S"), (output_suffix "ll")], - // Usually just output .bc - (not (switch_on "fsyntax-only")), - [(append_cmd "-c"), (append_cmd "-emit-llvm")], - - // -fsyntax-only - (switch_on "fsyntax-only"), [(forward "fsyntax-only"), - (no_out_file), (stop_compilation)], - - // Forwards - (not_empty "Xpreprocessor"), (forward "Xpreprocessor"), - (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 "mcpu"), (forward "mcpu"), - (not_empty "mtune"), (forward "mtune"), - (not_empty "mfpu"), (forward "mfpu"), - (not_empty "mabi"), (forward "mabi"), - (not_empty "mfloat-abi"), (forward "mfloat-abi"), - (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"), - (switch_on "O1"), (forward "O1"), - (switch_on "O2"), (forward "O2"), - (switch_on "O3"), (forward "O3"), - (switch_on "fPIC"), (forward "fPIC"), - (switch_on "mdynamic-no-pic"), (forward "mdynamic-no-pic"), - (not_empty "MF"), (forward "MF"), - (not_empty "MT"), (forward "MT"))), - (sink) -]>; - -class llvm_gcc_comp_based -: llvm_gcc_based; - -class llvm_gcc_pch_based -: llvm_gcc_based; - -def llvm_gcc_c : llvm_gcc_comp_based - <"@LLVMGCCCOMMAND@ -x c", "c", "i">; -def llvm_gcc_cpp : llvm_gcc_comp_based - <"@LLVMGXXCOMMAND@ -x c++", "c++", "i">; -def llvm_gcc_m : llvm_gcc_comp_based - <"@LLVMGCCCOMMAND@ -x objective-c", "objective-c", "mi">; -def llvm_gcc_mxx : llvm_gcc_comp_based - <"@LLVMGCCCOMMAND@ -x objective-c++", "objective-c++", "mi">; - -def llvm_gcc_c_pch : llvm_gcc_pch_based - <"@LLVMGCCCOMMAND@ -x c-header", "c-header", "i">; -def llvm_gcc_cpp_pch : llvm_gcc_pch_based - <"@LLVMGXXCOMMAND@ -x c++-header", "c++-header", "i">; -def llvm_gcc_m_pch : llvm_gcc_pch_based - <"@LLVMGCCCOMMAND@ -x objective-c-header", "objective-c-header", "mi">; -def llvm_gcc_mxx_pch : llvm_gcc_pch_based - <"@LLVMGCCCOMMAND@ -x objective-c++-header", "objective-c++-header", "mi">; - -def opt : Tool< -[(in_language "llvm-bitcode"), - (out_language "llvm-bitcode"), - (output_suffix "opt.bc"), - (actions (case (switch_on "emit-llvm"), (stop_compilation), - (switch_on "emit-llvm", "S"), - [(append_cmd "-S"), (output_suffix "ll")], - (not_empty "Wo,"), (forward_value "Wo,"), - (switch_on "O1"), (forward "O1"), - (switch_on "O2"), (forward "O2"), - (switch_on "O3"), (forward "O3"))), - (command "opt -f") -]>; - -def llvm_as : Tool< -[(in_language "llvm-assembler"), - (out_language "llvm-bitcode"), - (output_suffix "bc"), - (command "llvm-as"), - (actions (case (and (switch_on "emit-llvm"), (not (switch_on "opt"))), - (stop_compilation))) -]>; - -def llvm_gcc_assembler : Tool< -[(in_language "assembler"), - (out_language "object-code"), - (output_suffix "o"), - (command "@LLVMGCCCOMMAND@ -c -x assembler"), - (actions (case - (switch_on "c"), (stop_compilation), - (not_empty "arch"), (forward "arch"), - (not_empty "Xassembler"), (forward "Xassembler"), - (not_empty "march"), (forward "march"), - (not_empty "mcpu"), (forward "mcpu"), - (not_empty "mtune"), (forward "mtune"), - (not_empty "mabi"), (forward "mabi"), - (not_empty "mfloat-abi"), (forward "mfloat-abi"), - (switch_on "m32"), (forward "m32"), - (switch_on "m64"), (forward "m64"), - (not_empty "Wa,"), (forward "Wa,"))) -]>; - -def llc : Tool< -[(in_language "llvm-bitcode", "llvm-assembler"), - (out_language "assembler"), - (output_suffix "s"), - (command "llc -disable-cfi"), - (actions (case - (switch_on "S"), (stop_compilation), - (switch_on "O0"), (forward "O0"), - (switch_on "O1"), (forward "O1"), - (switch_on "O2"), (forward "O2"), - (switch_on "O3"), (forward "O3"), - (switch_on "fPIC"), (append_cmd "-relocation-model=pic"), - (switch_on "mdynamic-no-pic"), - (append_cmd "-relocation-model=dynamic-no-pic"), - (not_empty "march"), (forward_transformed_value - "march", "ConvertMArchToMAttr"), - (not_empty "mcpu"), (forward_transformed_value "mcpu", "ConvertMCpu"), - (and (not_empty "mtune"), (empty "mcpu")), - (forward_as "mtune", "-mcpu"), - (not_empty "mfpu"), (forward_transformed_value "mfpu", "ConvertMFpu"), - (not_empty "m"), (forward_transformed_value "m", "ConvertToMAttr"), - (not_empty "Wllc,"), (forward_value "Wllc,"))) -]>; - -// Base class for linkers -class llvm_gcc_based_linker : Tool< -[(in_language "object-code", "static-library", "dynamic-library"), - (out_language "executable"), - (output_suffix "out"), - (command cmd), - (works_on_empty (case (and (not_empty "filelist"), on_empty), true, - (default), false)), - (join), - (actions (case - (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"), - (not_empty "filelist"), (forward "filelist"), - (not_empty "march"), (forward "march"), - (not_empty "mcpu"), (forward "mcpu"), - (not_empty "mtune"), (forward "mtune"), - (not_empty "mabi"), (forward "mabi"), - (not_empty "mfloat-abi"), (forward "mfloat-abi"), - (switch_on "m32"), (forward "m32"), - (switch_on "m64"), (forward "m64"), - (not_empty "l"), (forward "l"), - (not_empty "Xlinker"), (forward "Xlinker"), - (not_empty "Wl,"), (forward "Wl,"), - (switch_on "nostartfiles"), (forward "nostartfiles"), - (switch_on "nodefaultlibs"), (forward "nodefaultlibs"), - (switch_on "nostdlib"), (forward "nostdlib"), - (switch_on "pie"), (forward "pie"), - (switch_on "rdynamic"), (forward "rdynamic"), - (switch_on "s"), (forward "s"), - (switch_on "static"), (forward "static"), - (switch_on "static-libgcc"), (forward "static-libgcc"), - (switch_on "shared"), (forward "shared"), - (switch_on "shared-libgcc"), (forward "shared-libgcc"), - (not_empty "T"), (forward "T"), - (not_empty "u"), (forward "u"), - (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"), - (not_empty "install_name"), (forward "install_name"))) -]>; - -// Default linker -def llvm_gcc_linker : llvm_gcc_based_linker<"@LLVMGCCCOMMAND@", - (not (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")))>; -// Alternative linker for C++ -def llvm_gcc_cpp_linker : llvm_gcc_based_linker<"@LLVMGXXCOMMAND@", - (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++"))>; - -// Language map - -def LanguageMap : LanguageMap<[ - (lang_to_suffixes "precompiled-header", ["gch", "pch"]), - (lang_to_suffixes "c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]), - (lang_to_suffixes "c++-header", "hpp"), - (lang_to_suffixes "c", "c"), - (lang_to_suffixes "c-header", "h"), - (lang_to_suffixes "c-cpp-output", "i"), - (lang_to_suffixes "objective-c-cpp-output", "mi"), - (lang_to_suffixes "objective-c++", "mm"), - (lang_to_suffixes "objective-c++-header", "hmm"), - (lang_to_suffixes "objective-c", "m"), - (lang_to_suffixes "objective-c-header", "hm"), - (lang_to_suffixes "assembler", "s"), - (lang_to_suffixes "assembler-with-cpp", "S"), - (lang_to_suffixes "llvm-assembler", "ll"), - (lang_to_suffixes "llvm-bitcode", "bc"), - (lang_to_suffixes "object-code", ["o", "*empty*"]), - (lang_to_suffixes "static-library", ["a", "lib"]), - (lang_to_suffixes "dynamic-library", ["so", "dylib", "dll"]), - (lang_to_suffixes "executable", "out") -]>; - -// Compilation graph - -def CompilationGraph : CompilationGraph<[ - (edge "root", "llvm_gcc_c"), - (edge "root", "llvm_gcc_assembler"), - (edge "root", "llvm_gcc_cpp"), - (edge "root", "llvm_gcc_m"), - (edge "root", "llvm_gcc_mxx"), - (edge "root", "llc"), - - (edge "root", "llvm_gcc_c_pch"), - (edge "root", "llvm_gcc_cpp_pch"), - (edge "root", "llvm_gcc_m_pch"), - (edge "root", "llvm_gcc_mxx_pch"), - - (edge "llvm_gcc_c", "llc"), - (edge "llvm_gcc_cpp", "llc"), - (edge "llvm_gcc_m", "llc"), - (edge "llvm_gcc_mxx", "llc"), - (edge "llvm_as", "llc"), - - (optional_edge "root", "llvm_as", - (case (or (switch_on "emit-llvm"), - (switch_on "opt")), (inc_weight))), - (optional_edge "llvm_gcc_c", "opt", - (case (switch_on "opt"), (inc_weight))), - (optional_edge "llvm_gcc_cpp", "opt", - (case (switch_on "opt"), (inc_weight))), - (optional_edge "llvm_gcc_m", "opt", - (case (switch_on "opt"), (inc_weight))), - (optional_edge "llvm_gcc_mxx", "opt", - (case (switch_on "opt"), (inc_weight))), - (optional_edge "llvm_as", "opt", - (case (switch_on "opt"), (inc_weight))), - (edge "opt", "llc"), - - (edge "llc", "llvm_gcc_assembler"), - (edge "llvm_gcc_assembler", "llvm_gcc_linker"), - (optional_edge "llvm_gcc_assembler", "llvm_gcc_cpp_linker", - (case - (or (input_languages_contain "c++"), - (input_languages_contain "objective-c++")), - (inc_weight), - (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")), (inc_weight))), - - - (edge "root", "llvm_gcc_linker"), - (optional_edge "root", "llvm_gcc_cpp_linker", - (case - (or (input_languages_contain "c++"), - (input_languages_contain "objective-c++")), - (inc_weight), - (or (parameter_equals "linker", "g++"), - (parameter_equals "linker", "c++")), (inc_weight))) -]>; diff --git a/tools/llvmc/src/Clang.td b/tools/llvmc/src/Clang.td deleted file mode 100644 index e2d32e88ff22..000000000000 --- a/tools/llvmc/src/Clang.td +++ /dev/null @@ -1,87 +0,0 @@ -//===- Clang.td - LLVMC toolchain descriptions -------------*- tablegen -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains compilation graph description used by llvmc. -// -//===----------------------------------------------------------------------===// - - -def Options : OptionList<[ -(switch_option "clang", (help "Use Clang instead of llvm-gcc")) -]>; - -class clang_based : Tool< -[(in_language language), - (out_language "llvm-bitcode"), - (output_suffix "bc"), - (command cmd), - (actions (case (switch_on "E"), - [(forward "E"), (stop_compilation), (output_suffix ext_E)], - (and (switch_on "E"), (empty "o")), (no_out_file), - (switch_on "fsyntax-only"), (stop_compilation), - (switch_on "S", "emit-llvm"), - [(append_cmd "-emit-llvm"), - (stop_compilation), (output_suffix "ll")], - (not (switch_on "S", "emit-llvm")), - (append_cmd "-emit-llvm-bc"), - (switch_on "c", "emit-llvm"), - (stop_compilation), - (not_empty "include"), (forward "include"), - (not_empty "I"), (forward "I"))), - (sink) -]>; - -def clang_c : clang_based<"c", "clang -x c", "i">; -def clang_cpp : clang_based<"c++", "clang -x c++", "i">; -def clang_objective_c : clang_based<"objective-c", - "clang -x objective-c", "mi">; -def clang_objective_cpp : clang_based<"objective-c++", - "clang -x objective-c++", "mi">; - -def as : Tool< -[(in_language "assembler"), - (out_language "object-code"), - (output_suffix "o"), - (command "as"), - (actions (case (not_empty "Wa,"), (forward_value "Wa,"), - (switch_on "c"), (stop_compilation))) -]>; - -// Default linker -def llvm_ld : Tool< -[(in_language "object-code"), - (out_language "executable"), - (output_suffix "out"), - (command "llvm-ld -native -disable-internalize"), - (actions (case - (switch_on "pthread"), (append_cmd "-lpthread"), - (not_empty "L"), (forward "L"), - (not_empty "l"), (forward "l"), - (not_empty "Wl,"), (forward_value "Wl,"))), - (join) -]>; - -// Compilation graph - -def ClangCompilationGraph : CompilationGraph<[ - (optional_edge "root", "clang_c", - (case (switch_on "clang"), (inc_weight))), - (optional_edge "root", "clang_cpp", - (case (switch_on "clang"), (inc_weight))), - (optional_edge "root", "clang_objective_c", - (case (switch_on "clang"), (inc_weight))), - (optional_edge "root", "clang_objective_cpp", - (case (switch_on "clang"), (inc_weight))), - (edge "clang_c", "llc"), - (edge "clang_cpp", "llc"), - (edge "clang_objective_c", "llc"), - (edge "clang_objective_cpp", "llc"), - (optional_edge "llc", "as", (case (switch_on "clang"), (inc_weight))), - (edge "as", "llvm_ld") -]>; diff --git a/tools/llvmc/src/Hooks.cpp b/tools/llvmc/src/Hooks.cpp deleted file mode 100644 index ddad08a1b4ca..000000000000 --- a/tools/llvmc/src/Hooks.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include "llvm/ADT/StringMap.h" - -#include -#include - -namespace hooks { - -/// NUM_KEYS - Calculate the size of a const char* array. -#define NUM_KEYS(Keys) sizeof(Keys) / sizeof(const char*) - -// See http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 -inline unsigned NextHighestPowerOf2 (unsigned i) { - --i; - i |= i >> 1; - i |= i >> 2; - i |= i >> 4; - i |= i >> 8; - i |= i >> 16; - ++i; - return i; -} - -typedef std::vector StrVec; -typedef llvm::StringMap ArgMap; - -/// AddPlusOrMinus - Convert 'no-foo' to '-foo' and 'foo' to '+foo'. -void AddPlusOrMinus (const std::string& Arg, std::string& out) { - if (Arg.find("no-") == 0 && Arg[3] != 0) { - out += '-'; - out += Arg.c_str() + 3; - } - else { - out += '+'; - out += Arg; - } -} - -// -march values that need to be special-cased. -const char* MArchKeysARM[] = { "armv4t", "armv5t", "armv5te", "armv6", - "armv6-m", "armv6t2", "armv7-a", "armv7-m" }; -const char* MArchValuesARM[] = { "v4t", "v5t", "v5te", "v6", "v6m", "v6t2", - "v7a", "v7m" }; -const unsigned MArchNumKeysARM = NUM_KEYS(MArchKeysARM); -const unsigned MArchMapSize = NextHighestPowerOf2(MArchNumKeysARM); - -// -march values that should be forwarded as -mcpu -const char* MArchMCpuKeysARM[] = { "iwmmxt", "ep9312" }; -const char* MArchMCpuValuesARM[] = { "iwmmxt", "ep9312"}; -const unsigned MArchMCpuNumKeysARM = NUM_KEYS(MArchMCpuKeysARM); - - -void FillInArgMap(ArgMap& Args, const char* Keys[], - const char* Values[], unsigned NumKeys) -{ - for (unsigned i = 0; i < NumKeys; ++i) { - // Explicit cast to StringRef here is necessary to pick up the right - // overload. - Args.GetOrCreateValue(llvm::StringRef(Keys[i]), Values[i]); - } -} - -/// ConvertMArchToMAttr - Convert -march from the gcc dialect to -/// something llc can understand. -std::string ConvertMArchToMAttr(const StrVec& Opts) { - static ArgMap MArchMap(MArchMapSize); - static ArgMap MArchMCpuMap(MArchMapSize); - static bool StaticDataInitialized = false; - - if (!StaticDataInitialized) { - FillInArgMap(MArchMap, MArchKeysARM, MArchValuesARM, MArchNumKeysARM); - FillInArgMap(MArchMCpuMap, MArchMCpuKeysARM, - MArchMCpuValuesARM, MArchMCpuNumKeysARM); - StaticDataInitialized = true; - } - - std::string mattr("-mattr="); - std::string mcpu("-mcpu="); - bool mattrTouched = false; - bool mcpuTouched = false; - - for (StrVec::const_iterator B = Opts.begin(), E = Opts.end(); B!=E; ++B) { - const std::string& Arg = *B; - - // Check if the argument should be forwarded to -mcpu instead of -mattr. - { - ArgMap::const_iterator I = MArchMCpuMap.find(Arg); - - if (I != MArchMCpuMap.end()) { - mcpuTouched = true; - mcpu += I->getValue(); - continue; - } - } - - if (mattrTouched) - mattr += ","; - - // Check if the argument is a special case. - { - ArgMap::const_iterator I = MArchMap.find(Arg); - - if (I != MArchMap.end()) { - mattrTouched = true; - mattr += '+'; - mattr += I->getValue(); - continue; - } - } - - AddPlusOrMinus(Arg, mattr); - } - - std::string out; - if (mattrTouched) - out += mattr; - if (mcpuTouched) - out += (mattrTouched ? " " : "") + mcpu; - - return out; -} - -// -mcpu values that need to be special-cased. -const char* MCpuKeysPPC[] = { "G3", "G4", "G5", "powerpc", "powerpc64"}; -const char* MCpuValuesPPC[] = { "g3", "g4", "g5", "ppc", "ppc64"}; -const unsigned MCpuNumKeysPPC = NUM_KEYS(MCpuKeysPPC); -const unsigned MCpuMapSize = NextHighestPowerOf2(MCpuNumKeysPPC); - -/// ConvertMCpu - Convert -mcpu value from the gcc to the llc dialect. -std::string ConvertMCpu(const char* Val) { - static ArgMap MCpuMap(MCpuMapSize); - static bool StaticDataInitialized = false; - - if (!StaticDataInitialized) { - FillInArgMap(MCpuMap, MCpuKeysPPC, MCpuValuesPPC, MCpuNumKeysPPC); - StaticDataInitialized = true; - } - - std::string ret = "-mcpu="; - ArgMap::const_iterator I = MCpuMap.find(Val); - if (I != MCpuMap.end()) { - return ret + I->getValue(); - } - return ret + Val; -} - -// -mfpu values that need to be special-cased. -const char* MFpuKeysARM[] = { "vfp", "vfpv3", - "vfpv3-fp16", "vfpv3-d16", "vfpv3-d16-fp16", - "neon", "neon-fp16" }; -const char* MFpuValuesARM[] = { "vfp2", "vfp3", - "+vfp3,+fp16", "+vfp3,+d16", "+vfp3,+d16,+fp16", - "+neon", "+neon,+neonfp" }; -const unsigned MFpuNumKeysARM = NUM_KEYS(MFpuKeysARM); -const unsigned MFpuMapSize = NextHighestPowerOf2(MFpuNumKeysARM); - -/// ConvertMFpu - Convert -mfpu value from the gcc to the llc dialect. -std::string ConvertMFpu(const char* Val) { - static ArgMap MFpuMap(MFpuMapSize); - static bool StaticDataInitialized = false; - - if (!StaticDataInitialized) { - FillInArgMap(MFpuMap, MFpuKeysARM, MFpuValuesARM, MFpuNumKeysARM); - StaticDataInitialized = true; - } - - std::string ret = "-mattr="; - ArgMap::const_iterator I = MFpuMap.find(Val); - if (I != MFpuMap.end()) { - return ret + I->getValue(); - } - return ret + '+' + Val; -} - -/// ConvertToMAttr - Convert '-mfoo' and '-mno-bar' to '-mattr=+foo,-bar'. -std::string ConvertToMAttr(const StrVec& Opts) { - std::string out("-mattr="); - bool firstIter = true; - - for (StrVec::const_iterator B = Opts.begin(), E = Opts.end(); B!=E; ++B) { - const std::string& Arg = *B; - - if (firstIter) - firstIter = false; - else - out += ","; - - AddPlusOrMinus(Arg, out); - } - - return out; -} - -} diff --git a/tools/llvmc/src/Main.cpp b/tools/llvmc/src/Main.cpp deleted file mode 100644 index 9f9c71aa8c34..000000000000 --- a/tools/llvmc/src/Main.cpp +++ /dev/null @@ -1,16 +0,0 @@ -//===--- Main.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open -// Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Just include AutoGenerated.inc and CompilerDriver/Main.inc. -// -//===----------------------------------------------------------------------===// - -#include "AutoGenerated.inc" - -#include "llvm/CompilerDriver/Main.inc" diff --git a/tools/llvmc/src/Makefile b/tools/llvmc/src/Makefile deleted file mode 100644 index f3f30911a400..000000000000 --- a/tools/llvmc/src/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- tools/llvmc/src/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open -# Source License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../.. -LLVMC_BASED_DRIVER = llvmc -BUILT_SOURCES = AutoGenerated.inc - -include $(LEVEL)/Makefile.common diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 14594cf553a3..6c8dbad460c0 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -23,6 +23,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Triple.h" #include "llvm/Analysis/Passes.h" +#include "llvm/Analysis/Verifier.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" @@ -31,19 +32,21 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetSelect.h" +#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PassManagerBuilder.h" #include "llvm/Support/SystemUtils.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/Host.h" #include "llvm/Support/Program.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Support/system_error.h" #include "llvm/Config/config.h" +#include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include #include #include @@ -73,8 +76,7 @@ LTOCodeGenerator::LTOCodeGenerator() _nativeObjectFile(NULL) { InitializeAllTargets(); - InitializeAllMCAsmInfos(); - InitializeAllMCSubtargetInfos(); + InitializeAllTargetMCs(); InitializeAllAsmPrinters(); } @@ -191,7 +193,7 @@ bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg) bool genResult = false; tool_output_file objFile(uniqueObjPath.c_str(), errMsg); if (!errMsg.empty()) - return NULL; + return true; genResult = this->generateObjectFile(objFile.os(), errMsg); objFile.os().close(); if (objFile.os().has_error()) { @@ -250,23 +252,25 @@ bool LTOCodeGenerator::determineTarget(std::string& errMsg) // The relocation model is actually a static member of TargetMachine // and needs to be set before the TargetMachine is instantiated. + Reloc::Model RelocModel = Reloc::Default; switch( _codeModel ) { case LTO_CODEGEN_PIC_MODEL_STATIC: - TargetMachine::setRelocationModel(Reloc::Static); + RelocModel = Reloc::Static; break; case LTO_CODEGEN_PIC_MODEL_DYNAMIC: - TargetMachine::setRelocationModel(Reloc::PIC_); + RelocModel = Reloc::PIC_; break; case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: - TargetMachine::setRelocationModel(Reloc::DynamicNoPIC); + RelocModel = Reloc::DynamicNoPIC; break; } - // construct LTModule, hand over ownership of module and target + // construct LTOModule, hand over ownership of module and target SubtargetFeatures Features; Features.getDefaultSubtargetFeatures(llvm::Triple(Triple)); std::string FeatureStr = Features.getString(); - _target = march->createTargetMachine(Triple, _mCpu, FeatureStr); + _target = march->createTargetMachine(Triple, _mCpu, FeatureStr, + RelocModel); } return false; } @@ -308,7 +312,7 @@ void LTOCodeGenerator::applyScopeRestrictions() { passes.add(createVerifierPass()); // mark which symbols can not be internalized - MCContext Context(*_target->getMCAsmInfo(), NULL); + MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL); Mangler mangler(Context, *_target->getTargetData()); std::vector mustPreserveList; SmallPtrSet asmUsed; @@ -329,7 +333,7 @@ void LTOCodeGenerator::applyScopeRestrictions() { if (LLVMCompilerUsed) LLVMCompilerUsed->eraseFromParent(); - const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context); + llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context); std::vector asmUsed2; for (SmallPtrSet::const_iterator i = asmUsed.begin(), e = asmUsed.end(); i !=e; ++i) { diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index dc99b94f04e6..4ba8985e72a8 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -27,6 +27,8 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Support/system_error.h" #include "llvm/Target/Mangler.h" #include "llvm/MC/MCAsmInfo.h" @@ -38,10 +40,9 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/SubtargetFeature.h" -#include "llvm/Target/TargetAsmParser.h" +#include "llvm/MC/MCTargetAsmParser.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/Target/TargetSelect.h" +#include "llvm/Target/TargetRegisterInfo.h" using namespace llvm; @@ -135,8 +136,7 @@ LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, static bool Initialized = false; if (!Initialized) { InitializeAllTargets(); - InitializeAllMCAsmInfos(); - InitializeAllMCSubtargetInfos(); + InitializeAllTargetMCs(); InitializeAllAsmParsers(); Initialized = true; } @@ -165,7 +165,7 @@ LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, std::string CPU; TargetMachine *target = march->createTargetMachine(Triple, CPU, FeatureStr); LTOModule *Ret = new LTOModule(m.take(), target); - bool Err = Ret->ParseSymbols(); + bool Err = Ret->ParseSymbols(errMsg); if (Err) { delete Ret; return NULL; @@ -581,7 +581,8 @@ namespace { markDefined(*Symbol); } virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {} - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {} + virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment) {} virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) {} virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {} @@ -612,22 +613,30 @@ namespace { }; } -bool LTOModule::addAsmGlobalSymbols(MCContext &Context) { +bool LTOModule::addAsmGlobalSymbols(MCContext &Context, std::string &errMsg) { const std::string &inlineAsm = _module->getModuleInlineAsm(); + if (inlineAsm.empty()) + return false; OwningPtr Streamer(new RecordStreamer(Context)); MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(inlineAsm); SourceMgr SrcMgr; SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); - OwningPtr Parser(createMCAsmParser(_target->getTarget(), SrcMgr, + OwningPtr Parser(createMCAsmParser(SrcMgr, Context, *Streamer, *_target->getMCAsmInfo())); OwningPtr STI(_target->getTarget(). createMCSubtargetInfo(_target->getTargetTriple(), _target->getTargetCPU(), _target->getTargetFeatureString())); - OwningPtr - TAP(_target->getTarget().createAsmParser(*STI, *Parser.get())); + OwningPtr + TAP(_target->getTarget().createMCAsmParser(*STI, *Parser.get())); + if (!TAP) { + errMsg = "target " + std::string(_target->getTarget().getName()) + + " does not define AsmParser."; + return true; + } + Parser->setTargetParser(*TAP); int Res = Parser->Run(false); if (Res) @@ -660,9 +669,9 @@ static bool isAliasToDeclaration(const GlobalAlias &V) { return isDeclaration(*V.getAliasedGlobal()); } -bool LTOModule::ParseSymbols() { +bool LTOModule::ParseSymbols(std::string &errMsg) { // Use mangler to add GlobalPrefix to names to match linker names. - MCContext Context(*_target->getMCAsmInfo(), NULL); + MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(),NULL); Mangler mangler(Context, *_target->getTargetData()); // add functions @@ -683,7 +692,7 @@ bool LTOModule::ParseSymbols() { } // add asm globals - if (addAsmGlobalSymbols(Context)) + if (addAsmGlobalSymbols(Context, errMsg)) return true; // add aliases diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h index 0b64a902f916..ca08aea90adb 100644 --- a/tools/lto/LTOModule.h +++ b/tools/lto/LTOModule.h @@ -76,7 +76,7 @@ struct LTOModule { private: LTOModule(llvm::Module* m, llvm::TargetMachine* t); - bool ParseSymbols(); + bool ParseSymbols(std::string &errMsg); void addDefinedSymbol(llvm::GlobalValue* def, llvm::Mangler& mangler, bool isFunction); @@ -86,7 +86,8 @@ struct LTOModule { llvm::Mangler &mangler); void addDefinedDataSymbol(llvm::GlobalValue* v, llvm::Mangler &mangler); - bool addAsmGlobalSymbols(llvm::MCContext &Context); + bool addAsmGlobalSymbols(llvm::MCContext &Context, + std::string &errMsg); void addAsmGlobalSymbol(const char *, lto_symbol_attributes scope); void addAsmGlobalSymbolUndef(const char *); diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp index f324259a856f..2b22c3b0fd91 100644 --- a/tools/macho-dump/macho-dump.cpp +++ b/tools/macho-dump/macho-dump.cpp @@ -310,6 +310,29 @@ static int DumpDysymtabCommand(MachOObject &Obj, return Res; } +static int DumpLinkeditDataCommand(MachOObject &Obj, + const MachOObject::LoadCommandInfo &LCI) { + InMemoryStruct LLC; + Obj.ReadLinkeditDataLoadCommand(LCI, LLC); + if (!LLC) + return Error("unable to read segment load command"); + + outs() << " ('dataoff', " << LLC->DataOffset << ")\n" + << " ('datasize', " << LLC->DataSize << ")\n" + << " ('_addresses', [\n"; + + SmallVector Addresses; + Obj.ReadULEB128s(LLC->DataOffset, Addresses); + for (unsigned i = 0, e = Addresses.size(); i != e; ++i) + outs() << " # Address " << i << '\n' + << " ('address', " << format("0x%x", Addresses[i]) << "),\n"; + + outs() << " ])\n"; + + return 0; +} + + static int DumpLoadCommand(MachOObject &Obj, unsigned Index) { const MachOObject::LoadCommandInfo &LCI = Obj.getLoadCommandInfo(Index); int Res = 0; @@ -330,6 +353,11 @@ static int DumpLoadCommand(MachOObject &Obj, unsigned Index) { case macho::LCT_Dysymtab: Res = DumpDysymtabCommand(Obj, LCI); break; + case macho::LCT_CodeSignature: + case macho::LCT_SegmentSplitInfo: + case macho::LCT_FunctionStarts: + Res = DumpLinkeditDataCommand(Obj, LCI); + break; default: Warning("unknown load command: " + Twine(LCI.Command.Type)); break; diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index aa375c588990..ffd2c21736e5 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -35,11 +35,11 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/PassManagerBuilder.h" #include "llvm/Support/SystemUtils.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/LinkAllPasses.h" #include "llvm/LinkAllVMCore.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include #include using namespace llvm; @@ -431,8 +431,6 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, static void AddStandardCompilePasses(PassManagerBase &PM) { PM.add(createVerifierPass()); // Verify that input is correct - addPass(PM, createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp - // If the -strip-debug command line option was specified, do it. if (StripDebug) addPass(PM, createStripSymbolsPass(true)); diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp index 08ac2a05254a..b6e02e3a9a3e 100644 --- a/unittests/ADT/APFloatTest.cpp +++ b/unittests/ADT/APFloatTest.cpp @@ -34,11 +34,13 @@ static std::string convertToString(double d, unsigned Prec, unsigned Pad) { namespace { TEST(APFloatTest, Zero) { - EXPECT_EQ(0.0f, APFloat(APFloat::IEEEsingle, 0.0f).convertToFloat()); - EXPECT_EQ(-0.0f, APFloat(APFloat::IEEEsingle, -0.0f).convertToFloat()); + EXPECT_EQ(0.0f, APFloat(0.0f).convertToFloat()); + EXPECT_EQ(-0.0f, APFloat(-0.0f).convertToFloat()); + EXPECT_TRUE(APFloat(-0.0f).isNegative()); - EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble, 0.0).convertToDouble()); - EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, -0.0).convertToDouble()); + EXPECT_EQ(0.0, APFloat(0.0).convertToDouble()); + EXPECT_EQ(-0.0, APFloat(-0.0).convertToDouble()); + EXPECT_TRUE(APFloat(-0.0).isNegative()); } TEST(APFloatTest, fromZeroDecimalString) { @@ -646,4 +648,9 @@ TEST(APFloatTest, exactInverse) { EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(0)); } +TEST(APFloatTest, getLargest) { + EXPECT_EQ(3.402823466e+38f, APFloat::getLargest(APFloat::IEEEsingle).convertToFloat()); + EXPECT_EQ(1.7976931348623158e+308, APFloat::getLargest(APFloat::IEEEdouble).convertToDouble()); +} + } diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp index 1f78cd33bdf1..490811deb8f9 100644 --- a/unittests/ADT/APIntTest.cpp +++ b/unittests/ADT/APIntTest.cpp @@ -237,6 +237,24 @@ TEST(APIntTest, fromString) { EXPECT_EQ(APInt(32, uint64_t(-16LL)), APInt(32, "-10", 16)); EXPECT_EQ(APInt(32, uint64_t(-31LL)), APInt(32, "-1F", 16)); EXPECT_EQ(APInt(32, uint64_t(-32LL)), APInt(32, "-20", 16)); + + EXPECT_EQ(APInt(32, 0), APInt(32, "0", 36)); + EXPECT_EQ(APInt(32, 1), APInt(32, "1", 36)); + EXPECT_EQ(APInt(32, 35), APInt(32, "Z", 36)); + EXPECT_EQ(APInt(32, 36), APInt(32, "10", 36)); + EXPECT_EQ(APInt(32, 71), APInt(32, "1Z", 36)); + EXPECT_EQ(APInt(32, 72), APInt(32, "20", 36)); + + EXPECT_EQ(APInt(32, uint64_t(-0LL)), APInt(32, "-0", 36)); + EXPECT_EQ(APInt(32, uint64_t(-1LL)), APInt(32, "-1", 36)); + EXPECT_EQ(APInt(32, uint64_t(-35LL)), APInt(32, "-Z", 36)); + EXPECT_EQ(APInt(32, uint64_t(-36LL)), APInt(32, "-10", 36)); + EXPECT_EQ(APInt(32, uint64_t(-71LL)), APInt(32, "-1Z", 36)); + EXPECT_EQ(APInt(32, uint64_t(-72LL)), APInt(32, "-20", 36)); +} + +TEST(APIntTest, FromArray) { + EXPECT_EQ(APInt(32, uint64_t(1)), APInt(32, ArrayRef(1))); } TEST(APIntTest, StringBitsNeeded2) { @@ -336,6 +354,9 @@ TEST(APIntTest, toString) { APInt(8, 0).toString(S, 16, true, true); EXPECT_EQ(S.str().str(), "0x0"); S.clear(); + APInt(8, 0).toString(S, 36, true, true); + EXPECT_EQ(S.str().str(), "0"); + S.clear(); isSigned = false; APInt(8, 255, isSigned).toString(S, 2, isSigned, true); @@ -350,6 +371,9 @@ TEST(APIntTest, toString) { APInt(8, 255, isSigned).toString(S, 16, isSigned, true); EXPECT_EQ(S.str().str(), "0xFF"); S.clear(); + APInt(8, 255, isSigned).toString(S, 36, isSigned, true); + EXPECT_EQ(S.str().str(), "73"); + S.clear(); isSigned = true; APInt(8, 255, isSigned).toString(S, 2, isSigned, true); @@ -364,6 +388,9 @@ TEST(APIntTest, toString) { APInt(8, 255, isSigned).toString(S, 16, isSigned, true); EXPECT_EQ(S.str().str(), "-0x1"); S.clear(); + APInt(8, 255, isSigned).toString(S, 36, isSigned, true); + EXPECT_EQ(S.str().str(), "-1"); + S.clear(); } TEST(APIntTest, Log2) { @@ -403,7 +430,7 @@ TEST(APIntTest, magicu) { TEST(APIntTest, StringDeath) { EXPECT_DEATH(APInt(0, "", 0), "Bitwidth too small"); EXPECT_DEATH(APInt(32, "", 0), "Invalid string length"); - EXPECT_DEATH(APInt(32, "0", 0), "Radix should be 2, 8, 10, or 16!"); + EXPECT_DEATH(APInt(32, "0", 0), "Radix should be 2, 8, 10, 16, or 36!"); EXPECT_DEATH(APInt(32, "", 10), "Invalid string length"); EXPECT_DEATH(APInt(32, "-", 10), "String is only a sign, needs a value."); EXPECT_DEATH(APInt(1, "1234", 10), "Insufficient bit width"); @@ -414,4 +441,13 @@ TEST(APIntTest, StringDeath) { #endif #endif +TEST(APIntTest, mul_clear) { + APInt ValA(65, -1ULL); + APInt ValB(65, 4); + APInt ValC(65, 0); + ValC = ValA * ValB; + ValA *= ValB; + EXPECT_EQ(ValA.toString(10, false), ValC.toString(10, false)); +} + } diff --git a/unittests/ADT/DAGDeltaAlgorithmTest.cpp b/unittests/ADT/DAGDeltaAlgorithmTest.cpp index b90e0c7fc231..370b7c20a093 100644 --- a/unittests/ADT/DAGDeltaAlgorithmTest.cpp +++ b/unittests/ADT/DAGDeltaAlgorithmTest.cpp @@ -13,23 +13,6 @@ #include using namespace llvm; -namespace std { - -static std::ostream &operator<<(std::ostream &OS, - const std::set &S) { - OS << "{"; - for (std::set::const_iterator it = S.begin(), - ie = S.end(); it != ie; ++it) { - if (it != S.begin()) - OS << ","; - OS << *it; - } - OS << "}"; - return OS; -} - -} - namespace { typedef DAGDeltaAlgorithm::edge_ty edge_ty; diff --git a/unittests/ADT/SCCIteratorTest.cpp b/unittests/ADT/SCCIteratorTest.cpp new file mode 100644 index 000000000000..00fa0665dda8 --- /dev/null +++ b/unittests/ADT/SCCIteratorTest.cpp @@ -0,0 +1,346 @@ +//===----- llvm/unittest/ADT/SCCIteratorTest.cpp - SCCIterator tests ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include +#include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/SCCIterator.h" +#include "gtest/gtest.h" + +using namespace llvm; + +namespace llvm { + +/// Graph - A graph with N nodes. Note that N can be at most 8. +template +class Graph { +private: + // Disable copying. + Graph(const Graph&); + Graph& operator=(const Graph&); + + static void ValidateIndex(unsigned Idx) { + assert(Idx < N && "Invalid node index!"); + } +public: + + /// NodeSubset - A subset of the graph's nodes. + class NodeSubset { + typedef unsigned char BitVector; // Where the limitation N <= 8 comes from. + BitVector Elements; + NodeSubset(BitVector e) : Elements(e) {} + public: + /// NodeSubset - Default constructor, creates an empty subset. + NodeSubset() : Elements(0) { + assert(N <= sizeof(BitVector)*CHAR_BIT && "Graph too big!"); + } + /// NodeSubset - Copy constructor. + NodeSubset(const NodeSubset &other) : Elements(other.Elements) {} + + /// Comparison operators. + bool operator==(const NodeSubset &other) const { + return other.Elements == this->Elements; + } + bool operator!=(const NodeSubset &other) const { + return !(*this == other); + } + + /// AddNode - Add the node with the given index to the subset. + void AddNode(unsigned Idx) { + ValidateIndex(Idx); + Elements |= 1U << Idx; + } + + /// DeleteNode - Remove the node with the given index from the subset. + void DeleteNode(unsigned Idx) { + ValidateIndex(Idx); + Elements &= ~(1U << Idx); + } + + /// count - Return true if the node with the given index is in the subset. + bool count(unsigned Idx) { + ValidateIndex(Idx); + return (Elements & (1U << Idx)) != 0; + } + + /// isEmpty - Return true if this is the empty set. + bool isEmpty() const { + return Elements == 0; + } + + /// isSubsetOf - Return true if this set is a subset of the given one. + bool isSubsetOf(const NodeSubset &other) const { + return (this->Elements | other.Elements) == other.Elements; + } + + /// Complement - Return the complement of this subset. + NodeSubset Complement() const { + return ~(unsigned)this->Elements & ((1U << N) - 1); + } + + /// Join - Return the union of this subset and the given one. + NodeSubset Join(const NodeSubset &other) const { + return this->Elements | other.Elements; + } + + /// Meet - Return the intersection of this subset and the given one. + NodeSubset Meet(const NodeSubset &other) const { + return this->Elements & other.Elements; + } + }; + + /// NodeType - Node index and set of children of the node. + typedef std::pair NodeType; + +private: + /// Nodes - The list of nodes for this graph. + NodeType Nodes[N]; +public: + + /// Graph - Default constructor. Creates an empty graph. + Graph() { + // Let each node know which node it is. This allows us to find the start of + // the Nodes array given a pointer to any element of it. + for (unsigned i = 0; i != N; ++i) + Nodes[i].first = i; + } + + /// AddEdge - Add an edge from the node with index FromIdx to the node with + /// index ToIdx. + void AddEdge(unsigned FromIdx, unsigned ToIdx) { + ValidateIndex(FromIdx); + Nodes[FromIdx].second.AddNode(ToIdx); + } + + /// DeleteEdge - Remove the edge (if any) from the node with index FromIdx to + /// the node with index ToIdx. + void DeleteEdge(unsigned FromIdx, unsigned ToIdx) { + ValidateIndex(FromIdx); + Nodes[FromIdx].second.DeleteNode(ToIdx); + } + + /// AccessNode - Get a pointer to the node with the given index. + NodeType *AccessNode(unsigned Idx) const { + ValidateIndex(Idx); + // The constant cast is needed when working with GraphTraits, which insists + // on taking a constant Graph. + return const_cast(&Nodes[Idx]); + } + + /// NodesReachableFrom - Return the set of all nodes reachable from the given + /// node. + NodeSubset NodesReachableFrom(unsigned Idx) const { + // This algorithm doesn't scale, but that doesn't matter given the small + // size of our graphs. + NodeSubset Reachable; + + // The initial node is reachable. + Reachable.AddNode(Idx); + do { + NodeSubset Previous(Reachable); + + // Add in all nodes which are children of a reachable node. + for (unsigned i = 0; i != N; ++i) + if (Previous.count(i)) + Reachable = Reachable.Join(Nodes[i].second); + + // If nothing changed then we have found all reachable nodes. + if (Reachable == Previous) + return Reachable; + + // Rinse and repeat. + } while (1); + } + + /// ChildIterator - Visit all children of a node. + class ChildIterator { + friend class Graph; + + /// FirstNode - Pointer to first node in the graph's Nodes array. + NodeType *FirstNode; + /// Children - Set of nodes which are children of this one and that haven't + /// yet been visited. + NodeSubset Children; + + ChildIterator(); // Disable default constructor. + protected: + ChildIterator(NodeType *F, NodeSubset C) : FirstNode(F), Children(C) {} + + public: + /// ChildIterator - Copy constructor. + ChildIterator(const ChildIterator& other) : FirstNode(other.FirstNode), + Children(other.Children) {} + + /// Comparison operators. + bool operator==(const ChildIterator &other) const { + return other.FirstNode == this->FirstNode && + other.Children == this->Children; + } + bool operator!=(const ChildIterator &other) const { + return !(*this == other); + } + + /// Prefix increment operator. + ChildIterator& operator++() { + // Find the next unvisited child node. + for (unsigned i = 0; i != N; ++i) + if (Children.count(i)) { + // Remove that child - it has been visited. This is the increment! + Children.DeleteNode(i); + return *this; + } + assert(false && "Incrementing end iterator!"); + return *this; // Avoid compiler warnings. + } + + /// Postfix increment operator. + ChildIterator operator++(int) { + ChildIterator Result(*this); + ++(*this); + return Result; + } + + /// Dereference operator. + NodeType *operator*() { + // Find the next unvisited child node. + for (unsigned i = 0; i != N; ++i) + if (Children.count(i)) + // Return a pointer to it. + return FirstNode + i; + assert(false && "Dereferencing end iterator!"); + return 0; // Avoid compiler warning. + } + }; + + /// child_begin - Return an iterator pointing to the first child of the given + /// node. + static ChildIterator child_begin(NodeType *Parent) { + return ChildIterator(Parent - Parent->first, Parent->second); + } + + /// child_end - Return the end iterator for children of the given node. + static ChildIterator child_end(NodeType *Parent) { + return ChildIterator(Parent - Parent->first, NodeSubset()); + } +}; + +template +struct GraphTraits > { + typedef typename Graph::NodeType NodeType; + typedef typename Graph::ChildIterator ChildIteratorType; + + static inline NodeType *getEntryNode(const Graph &G) { return G.AccessNode(0); } + static inline ChildIteratorType child_begin(NodeType *Node) { + return Graph::child_begin(Node); + } + static inline ChildIteratorType child_end(NodeType *Node) { + return Graph::child_end(Node); + } +}; + +TEST(SCCIteratorTest, AllSmallGraphs) { + // Test SCC computation against every graph with NUM_NODES nodes or less. + // Since SCC considers every node to have an implicit self-edge, we only + // create graphs for which every node has a self-edge. +#define NUM_NODES 4 +#define NUM_GRAPHS (NUM_NODES * (NUM_NODES - 1)) + typedef Graph GT; + + /// Enumerate all graphs using NUM_GRAPHS bits. + assert(NUM_GRAPHS < sizeof(unsigned) * CHAR_BIT && "Too many graphs!"); + for (unsigned GraphDescriptor = 0; GraphDescriptor < (1U << NUM_GRAPHS); + ++GraphDescriptor) { + GT G; + + // Add edges as specified by the descriptor. + unsigned DescriptorCopy = GraphDescriptor; + for (unsigned i = 0; i != NUM_NODES; ++i) + for (unsigned j = 0; j != NUM_NODES; ++j) { + // Always add a self-edge. + if (i == j) { + G.AddEdge(i, j); + continue; + } + if (DescriptorCopy & 1) + G.AddEdge(i, j); + DescriptorCopy >>= 1; + } + + // Test the SCC logic on this graph. + + /// NodesInSomeSCC - Those nodes which are in some SCC. + GT::NodeSubset NodesInSomeSCC; + + for (scc_iterator I = scc_begin(G), E = scc_end(G); I != E; ++I) { + std::vector &SCC = *I; + + // Get the nodes in this SCC as a NodeSubset rather than a vector. + GT::NodeSubset NodesInThisSCC; + for (unsigned i = 0, e = SCC.size(); i != e; ++i) + NodesInThisSCC.AddNode(SCC[i]->first); + + // There should be at least one node in every SCC. + EXPECT_FALSE(NodesInThisSCC.isEmpty()); + + // Check that every node in the SCC is reachable from every other node in + // the SCC. + for (unsigned i = 0; i != NUM_NODES; ++i) + if (NodesInThisSCC.count(i)) + EXPECT_TRUE(NodesInThisSCC.isSubsetOf(G.NodesReachableFrom(i))); + + // OK, now that we now that every node in the SCC is reachable from every + // other, this means that the set of nodes reachable from any node in the + // SCC is the same as the set of nodes reachable from every node in the + // SCC. Check that for every node N not in the SCC but reachable from the + // SCC, no element of the SCC is reachable from N. + for (unsigned i = 0; i != NUM_NODES; ++i) + if (NodesInThisSCC.count(i)) { + GT::NodeSubset NodesReachableFromSCC = G.NodesReachableFrom(i); + GT::NodeSubset ReachableButNotInSCC = + NodesReachableFromSCC.Meet(NodesInThisSCC.Complement()); + + for (unsigned j = 0; j != NUM_NODES; ++j) + if (ReachableButNotInSCC.count(j)) + EXPECT_TRUE(G.NodesReachableFrom(j).Meet(NodesInThisSCC).isEmpty()); + + // The result must be the same for all other nodes in this SCC, so + // there is no point in checking them. + break; + } + + // This is indeed a SCC: a maximal set of nodes for which each node is + // reachable from every other. + + // Check that we didn't already see this SCC. + EXPECT_TRUE(NodesInSomeSCC.Meet(NodesInThisSCC).isEmpty()); + + NodesInSomeSCC = NodesInSomeSCC.Join(NodesInThisSCC); + + // Check a property that is specific to the LLVM SCC iterator and + // guaranteed by it: if a node in SCC S1 has an edge to a node in + // SCC S2, then S1 is visited *after* S2. This means that the set + // of nodes reachable from this SCC must be contained either in the + // union of this SCC and all previously visited SCC's. + + for (unsigned i = 0; i != NUM_NODES; ++i) + if (NodesInThisSCC.count(i)) { + GT::NodeSubset NodesReachableFromSCC = G.NodesReachableFrom(i); + EXPECT_TRUE(NodesReachableFromSCC.isSubsetOf(NodesInSomeSCC)); + // The result must be the same for all other nodes in this SCC, so + // there is no point in checking them. + break; + } + } + + // Finally, check that the nodes in some SCC are exactly those that are + // reachable from the initial node. + EXPECT_EQ(NodesInSomeSCC, G.NodesReachableFrom(0)); + } +} + +} diff --git a/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp index 0d3535d6dbc0..d5bfe768003a 100644 --- a/unittests/ADT/SmallVectorTest.cpp +++ b/unittests/ADT/SmallVectorTest.cpp @@ -383,7 +383,7 @@ TEST_F(SmallVectorTest, ComparisonTest) { // Constant vector tests. TEST_F(SmallVectorTest, ConstVectorTest) { - const VectorType constVector; + VectorType constVector; EXPECT_EQ(0u, constVector.size()); EXPECT_TRUE(constVector.empty()); diff --git a/unittests/ADT/StringRefTest.cpp b/unittests/ADT/StringRefTest.cpp index 5731e4abaf15..8364eac82748 100644 --- a/unittests/ADT/StringRefTest.cpp +++ b/unittests/ADT/StringRefTest.cpp @@ -73,6 +73,12 @@ TEST(StringRefTest, StringOps) { EXPECT_EQ( 1, StringRef("2").compare_numeric("1")); EXPECT_EQ( 0, StringRef("llvm_v1i64_ty").compare_numeric("llvm_v1i64_ty")); EXPECT_EQ( 1, StringRef("\xFF").compare_numeric("\1")); + EXPECT_EQ( 1, StringRef("V16").compare_numeric("V1_q0")); + EXPECT_EQ(-1, StringRef("V1_q0").compare_numeric("V16")); + EXPECT_EQ(-1, StringRef("V8_q0").compare_numeric("V16")); + EXPECT_EQ( 1, StringRef("V16").compare_numeric("V8_q0")); + EXPECT_EQ(-1, StringRef("V1_q0").compare_numeric("V8_q0")); + EXPECT_EQ( 1, StringRef("V8_q0").compare_numeric("V1_q0")); } TEST(StringRefTest, Operators) { diff --git a/unittests/ADT/TwineTest.cpp b/unittests/ADT/TwineTest.cpp index 57f54cb0060f..e9cc41d13fc0 100644 --- a/unittests/ADT/TwineTest.cpp +++ b/unittests/ADT/TwineTest.cpp @@ -37,12 +37,16 @@ TEST(TwineTest, Numbers) { EXPECT_EQ("-123", Twine(-123).str()); EXPECT_EQ("123", Twine(123).str()); EXPECT_EQ("-123", Twine(-123).str()); - EXPECT_EQ("123", Twine((char) 123).str()); - EXPECT_EQ("-123", Twine((signed char) -123).str()); EXPECT_EQ("7b", Twine::utohexstr(123).str()); } +TEST(TwineTest, Characters) { + EXPECT_EQ("x", Twine('x').str()); + EXPECT_EQ("x", Twine(static_cast('x')).str()); + EXPECT_EQ("x", Twine(static_cast('x')).str()); +} + TEST(TwineTest, Concat) { // Check verse repr, since we care about the actual representation not just // the result. diff --git a/unittests/Analysis/ScalarEvolutionTest.cpp b/unittests/Analysis/ScalarEvolutionTest.cpp index 39ced2a16e67..ea5aeb38b01e 100644 --- a/unittests/Analysis/ScalarEvolutionTest.cpp +++ b/unittests/Analysis/ScalarEvolutionTest.cpp @@ -8,35 +8,48 @@ //===----------------------------------------------------------------------===// #include +#include #include #include #include #include #include +#include #include "gtest/gtest.h" namespace llvm { namespace { -TEST(ScalarEvolutionsTest, SCEVUnknownRAUW) { +// We use this fixture to ensure that we clean up ScalarEvolution before +// deleting the PassManager. +class ScalarEvolutionsTest : public testing::Test { +protected: + ScalarEvolutionsTest() : M("", Context), SE(*new ScalarEvolution) {} + ~ScalarEvolutionsTest() { + // Manually clean up, since we allocated new SCEV objects after the + // pass was finished. + SE.releaseMemory(); + } LLVMContext Context; - Module M("world", Context); + Module M; + PassManager PM; + ScalarEvolution &SE; +}; - const FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), +TEST_F(ScalarEvolutionsTest, SCEVUnknownRAUW) { + FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), std::vector(), false); Function *F = cast(M.getOrInsertFunction("f", FTy)); BasicBlock *BB = BasicBlock::Create(Context, "entry", F); ReturnInst::Create(Context, 0, BB); - const Type *Ty = Type::getInt1Ty(Context); + Type *Ty = Type::getInt1Ty(Context); Constant *Init = Constant::getNullValue(Ty); Value *V0 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V0"); Value *V1 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V1"); Value *V2 = new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, Init, "V2"); // Create a ScalarEvolution and "run" it so that it gets initialized. - PassManager PM; - ScalarEvolution &SE = *new ScalarEvolution(); PM.add(&SE); PM.run(M); @@ -72,10 +85,149 @@ TEST(ScalarEvolutionsTest, SCEVUnknownRAUW) { EXPECT_EQ(cast(M0->getOperand(1))->getValue(), V0); EXPECT_EQ(cast(M1->getOperand(1))->getValue(), V0); EXPECT_EQ(cast(M2->getOperand(1))->getValue(), V0); +} - // Manually clean up, since we allocated new SCEV objects after the - // pass was finished. - SE.releaseMemory(); +TEST_F(ScalarEvolutionsTest, SCEVMultiplyAddRecs) { + Type *Ty = Type::getInt32Ty(Context); + SmallVector Types; + Types.append(10, Ty); + FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Types, false); + Function *F = cast(M.getOrInsertFunction("f", FTy)); + BasicBlock *BB = BasicBlock::Create(Context, "entry", F); + ReturnInst::Create(Context, 0, BB); + + // Create a ScalarEvolution and "run" it so that it gets initialized. + PM.add(&SE); + PM.run(M); + + // It's possible to produce an empty loop through the default constructor, + // but you can't add any blocks to it without a LoopInfo pass. + Loop L; + const_cast&>(L.getBlocks()).push_back(BB); + + Function::arg_iterator AI = F->arg_begin(); + SmallVector A; + A.push_back(SE.getSCEV(&*AI++)); + A.push_back(SE.getSCEV(&*AI++)); + A.push_back(SE.getSCEV(&*AI++)); + A.push_back(SE.getSCEV(&*AI++)); + A.push_back(SE.getSCEV(&*AI++)); + const SCEV *A_rec = SE.getAddRecExpr(A, &L, SCEV::FlagAnyWrap); + + SmallVector B; + B.push_back(SE.getSCEV(&*AI++)); + B.push_back(SE.getSCEV(&*AI++)); + B.push_back(SE.getSCEV(&*AI++)); + B.push_back(SE.getSCEV(&*AI++)); + B.push_back(SE.getSCEV(&*AI++)); + const SCEV *B_rec = SE.getAddRecExpr(B, &L, SCEV::FlagAnyWrap); + + /* Spot check that we perform this transformation: + {A0,+,A1,+,A2,+,A3,+,A4} * {B0,+,B1,+,B2,+,B3,+,B4} = + {A0*B0,+, + A1*B0 + A0*B1 + A1*B1,+, + A2*B0 + 2A1*B1 + A0*B2 + 2A2*B1 + 2A1*B2 + A2*B2,+, + A3*B0 + 3A2*B1 + 3A1*B2 + A0*B3 + 3A3*B1 + 6A2*B2 + 3A1*B3 + 3A3*B2 + + 3A2*B3 + A3*B3,+, + A4*B0 + 4A3*B1 + 6A2*B2 + 4A1*B3 + A0*B4 + 4A4*B1 + 12A3*B2 + 12A2*B3 + + 4A1*B4 + 6A4*B2 + 12A3*B3 + 6A2*B4 + 4A4*B3 + 4A3*B4 + A4*B4,+, + 5A4*B1 + 10A3*B2 + 10A2*B3 + 5A1*B4 + 20A4*B2 + 30A3*B3 + 20A2*B4 + + 30A4*B3 + 30A3*B4 + 20A4*B4,+, + 15A4*B2 + 20A3*B3 + 15A2*B4 + 60A4*B3 + 60A3*B4 + 90A4*B4,+, + 35A4*B3 + 35A3*B4 + 140A4*B4,+, + 70A4*B4} + */ + + const SCEVAddRecExpr *Product = + dyn_cast(SE.getMulExpr(A_rec, B_rec)); + ASSERT_TRUE(Product); + ASSERT_EQ(Product->getNumOperands(), 9u); + + SmallVector Sum; + Sum.push_back(SE.getMulExpr(A[0], B[0])); + EXPECT_EQ(Product->getOperand(0), SE.getAddExpr(Sum)); + Sum.clear(); + + // SCEV produces different an equal but different expression for these. + // Re-enable when PR11052 is fixed. +#if 0 + Sum.push_back(SE.getMulExpr(A[1], B[0])); + Sum.push_back(SE.getMulExpr(A[0], B[1])); + Sum.push_back(SE.getMulExpr(A[1], B[1])); + EXPECT_EQ(Product->getOperand(1), SE.getAddExpr(Sum)); + Sum.clear(); + + Sum.push_back(SE.getMulExpr(A[2], B[0])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 2), A[1], B[1])); + Sum.push_back(SE.getMulExpr(A[0], B[2])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 2), A[2], B[1])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 2), A[1], B[2])); + Sum.push_back(SE.getMulExpr(A[2], B[2])); + EXPECT_EQ(Product->getOperand(2), SE.getAddExpr(Sum)); + Sum.clear(); + + Sum.push_back(SE.getMulExpr(A[3], B[0])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[2], B[1])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[1], B[2])); + Sum.push_back(SE.getMulExpr(A[0], B[3])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[3], B[1])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 6), A[2], B[2])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[1], B[3])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[3], B[2])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 3), A[2], B[3])); + Sum.push_back(SE.getMulExpr(A[3], B[3])); + EXPECT_EQ(Product->getOperand(3), SE.getAddExpr(Sum)); + Sum.clear(); + + Sum.push_back(SE.getMulExpr(A[4], B[0])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[3], B[1])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 6), A[2], B[2])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[1], B[3])); + Sum.push_back(SE.getMulExpr(A[0], B[4])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[4], B[1])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 12), A[3], B[2])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 12), A[2], B[3])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[1], B[4])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 6), A[4], B[2])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 12), A[3], B[3])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 6), A[2], B[4])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[4], B[3])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 4), A[3], B[4])); + Sum.push_back(SE.getMulExpr(A[4], B[4])); + EXPECT_EQ(Product->getOperand(4), SE.getAddExpr(Sum)); + Sum.clear(); + + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 5), A[4], B[1])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 10), A[3], B[2])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 10), A[2], B[3])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 5), A[1], B[4])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 20), A[4], B[2])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 30), A[3], B[3])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 20), A[2], B[4])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 30), A[4], B[3])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 30), A[3], B[4])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 20), A[4], B[4])); + EXPECT_EQ(Product->getOperand(5), SE.getAddExpr(Sum)); + Sum.clear(); + + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 15), A[4], B[2])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 20), A[3], B[3])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 15), A[2], B[4])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 60), A[4], B[3])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 60), A[3], B[4])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 90), A[4], B[4])); + EXPECT_EQ(Product->getOperand(6), SE.getAddExpr(Sum)); + Sum.clear(); + + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 35), A[4], B[3])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 35), A[3], B[4])); + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 140), A[4], B[4])); + EXPECT_EQ(Product->getOperand(7), SE.getAddExpr(Sum)); + Sum.clear(); +#endif + + Sum.push_back(SE.getMulExpr(SE.getConstant(Ty, 70), A[4], B[4])); + EXPECT_EQ(Product->getOperand(8), SE.getAddExpr(Sum)); } } // end anonymous namespace diff --git a/unittests/ExecutionEngine/ExecutionEngineTest.cpp b/unittests/ExecutionEngine/ExecutionEngineTest.cpp index 904ee2b6c49f..4dcef20c6e77 100644 --- a/unittests/ExecutionEngine/ExecutionEngineTest.cpp +++ b/unittests/ExecutionEngine/ExecutionEngineTest.cpp @@ -30,7 +30,7 @@ class ExecutionEngineTest : public testing::Test { ASSERT_TRUE(Engine.get() != NULL); } - GlobalVariable *NewExtGlobal(const Type *T, const Twine &Name) { + GlobalVariable *NewExtGlobal(Type *T, const Twine &Name) { return new GlobalVariable(*M, T, false, // Not constant. GlobalValue::ExternalLinkage, NULL, Name); } diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp index a36ec3bf2a1b..f8d88301ba1e 100644 --- a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp @@ -16,7 +16,7 @@ #include "llvm/CodeGen/MachineCodeInfo.h" #include "llvm/ExecutionEngine/JIT.h" #include "llvm/Support/TypeBuilder.h" -#include "llvm/Target/TargetSelect.h" +#include "llvm/Support/TargetSelect.h" #include "gtest/gtest.h" #include @@ -45,7 +45,7 @@ struct RecordingJITEventListener : public JITEventListener { std::vector EmittedEvents; std::vector FreedEvents; - int NextIndex; + unsigned NextIndex; RecordingJITEventListener() : NextIndex(0) {} diff --git a/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp b/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp index 039b5e00f2e6..be5d152c1c51 100644 --- a/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp @@ -22,7 +22,7 @@ namespace { Function *makeFakeFunction() { std::vector params; - const FunctionType *FTy = + FunctionType *FTy = FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false); return Function::Create(FTy, GlobalValue::ExternalLinkage); } diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp index 9c001c423f90..2ef273020f9e 100644 --- a/unittests/ExecutionEngine/JIT/JITTest.cpp +++ b/unittests/ExecutionEngine/JIT/JITTest.cpp @@ -27,7 +27,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TypeBuilder.h" -#include "llvm/Target/TargetSelect.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Type.h" #include @@ -38,13 +38,13 @@ namespace { Function *makeReturnGlobal(std::string Name, GlobalVariable *G, Module *M) { std::vector params; - const FunctionType *FTy = FunctionType::get(G->getType()->getElementType(), + FunctionType *FTy = FunctionType::get(G->getType()->getElementType(), params, false); Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M); BasicBlock *Entry = BasicBlock::Create(M->getContext(), "entry", F); IRBuilder<> builder(Entry); Value *Load = builder.CreateLoad(G); - const Type *GTy = G->getType()->getElementType(); + Type *GTy = G->getType()->getElementType(); Value *Add = builder.CreateAdd(Load, ConstantInt::get(GTy, 1LL)); builder.CreateStore(Add, G); builder.CreateRet(Add); @@ -236,7 +236,7 @@ TEST(JIT, GlobalInFunction) { ASSERT_EQ(Error, ""); // Create a global variable. - const Type *GTy = Type::getInt32Ty(context); + Type *GTy = Type::getInt32Ty(context); GlobalVariable *G = new GlobalVariable( *M, GTy, @@ -284,6 +284,8 @@ int PlusOne(int arg) { return arg + 1; } +// ARM tests disabled pending fix for PR10783. +#if !defined(__arm__) TEST_F(JITTest, FarCallToKnownFunction) { // x86-64 can only make direct calls to functions within 32 bits of // the current PC. To call anything farther away, we have to load @@ -320,11 +322,11 @@ TEST_F(JITTest, FarCallToKnownFunction) { TEST_F(JITTest, NonLazyCompilationStillNeedsStubs) { TheJIT->DisableLazyCompilation(true); - const FunctionType *Func1Ty = + FunctionType *Func1Ty = cast(TypeBuilder::get(Context)); std::vector arg_types; arg_types.push_back(Type::getInt1Ty(Context)); - const FunctionType *FuncTy = FunctionType::get( + FunctionType *FuncTy = FunctionType::get( Type::getVoidTy(Context), arg_types, false); Function *Func1 = Function::Create(Func1Ty, Function::ExternalLinkage, "func1", M); @@ -377,7 +379,7 @@ TEST_F(JITTest, NonLazyLeaksNoStubs) { TheJIT->DisableLazyCompilation(true); // Create two functions with a single basic block each. - const FunctionType *FuncTy = + FunctionType *FuncTy = cast(TypeBuilder::get(Context)); Function *Func1 = Function::Create(FuncTy, Function::ExternalLinkage, "func1", M); @@ -461,6 +463,7 @@ TEST_F(JITTest, ModuleDeletion) { EXPECT_EQ(RJMM->startExceptionTableCalls.size(), NumTablesDeallocated); } +#endif // !defined(__arm__) // ARM and PPC still emit stubs for calls since the target may be too far away // to call directly. This #if can probably be removed when @@ -608,6 +611,8 @@ extern "C" int32_t JITTest_AvailableExternallyFunction() { } namespace { +// ARM tests disabled pending fix for PR10783. +#if !defined(__arm__) TEST_F(JITTest, AvailableExternallyFunctionIsntCompiled) { TheJIT->DisableLazyCompilation(true); LoadAssembly("define available_externally i32 " @@ -763,6 +768,7 @@ TEST(LazyLoadedJITTest, EagerCompiledRecursionThroughGhost) { (intptr_t)TheJIT->getPointerToFunction(recur1IR)); EXPECT_EQ(3, recur1(4)); } +#endif // !defined(__arm__) // This code is copied from JITEventListenerTest, but it only runs once for all // the tests in this directory. Everything seems fine, but that's strange diff --git a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp index 8997d39836c9..91ea64aa53c9 100644 --- a/unittests/ExecutionEngine/JIT/MultiJITTest.cpp +++ b/unittests/ExecutionEngine/JIT/MultiJITTest.cpp @@ -65,6 +65,9 @@ void createModule2(LLVMContext &Context2, Module *&M2, Function *&FooF2) { FooF2 = M2->getFunction("foo2"); } +// ARM tests disabled pending fix for PR10783. +#if !defined(__arm__) + TEST(MultiJitTest, EagerMode) { LLVMContext Context1; Module *M1 = 0; @@ -160,5 +163,6 @@ TEST(MultiJitTest, JitPool) { EXPECT_EQ((intptr_t)getPointerToNamedFunction("getPointerToNamedFunction"), (intptr_t)&getPointerToNamedFunction); } +#endif // !defined(__arm__) } // anonymous namespace diff --git a/unittests/Support/BlockFrequencyTest.cpp b/unittests/Support/BlockFrequencyTest.cpp new file mode 100644 index 000000000000..edeea9b357f5 --- /dev/null +++ b/unittests/Support/BlockFrequencyTest.cpp @@ -0,0 +1,56 @@ +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/BlockFrequency.h" +#include "llvm/Support/BranchProbability.h" + +#include "gtest/gtest.h" +#include + +using namespace llvm; + +namespace { + +TEST(BlockFrequencyTest, OneToZero) { + BlockFrequency Freq(1); + BranchProbability Prob(UINT32_MAX - 1, UINT32_MAX); + Freq *= Prob; + EXPECT_EQ(Freq.getFrequency(), 0u); +} + +TEST(BlockFrequencyTest, OneToOne) { + BlockFrequency Freq(1); + BranchProbability Prob(UINT32_MAX, UINT32_MAX); + Freq *= Prob; + EXPECT_EQ(Freq.getFrequency(), 1u); +} + +TEST(BlockFrequencyTest, ThreeToOne) { + BlockFrequency Freq(3); + BranchProbability Prob(3000000, 9000000); + Freq *= Prob; + EXPECT_EQ(Freq.getFrequency(), 1u); +} + +TEST(BlockFrequencyTest, MaxToHalfMax) { + BlockFrequency Freq(UINT64_MAX); + BranchProbability Prob(UINT32_MAX / 2, UINT32_MAX); + Freq *= Prob; + EXPECT_EQ(Freq.getFrequency(), 9223372034707292159LLu); +} + +TEST(BlockFrequencyTest, BigToBig) { + const uint64_t Big = 387246523487234346LL; + const uint32_t P = 123456789; + BlockFrequency Freq(Big); + BranchProbability Prob(P, P); + Freq *= Prob; + EXPECT_EQ(Freq.getFrequency(), Big); +} + +TEST(BlockFrequencyTest, MaxToMax) { + BlockFrequency Freq(UINT64_MAX); + BranchProbability Prob(UINT32_MAX, UINT32_MAX); + Freq *= Prob; + EXPECT_EQ(Freq.getFrequency(), UINT64_MAX); +} + +} diff --git a/unittests/Support/DataExtractorTest.cpp b/unittests/Support/DataExtractorTest.cpp new file mode 100644 index 000000000000..9813e465f7ed --- /dev/null +++ b/unittests/Support/DataExtractorTest.cpp @@ -0,0 +1,111 @@ +//===- llvm/unittest/Support/DataExtractorTest.cpp - DataExtractor tests --===// +// +// 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/Support/DataExtractor.h" +using namespace llvm; + +namespace { + +const char numberData[] = "\x80\x90\xFF\xFF\x80\x00\x00\x00"; +const char stringData[] = "hellohello\0hello"; +const char leb128data[] = "\xA6\x49"; + +TEST(DataExtractorTest, OffsetOverflow) { + DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8); + EXPECT_FALSE(DE.isValidOffsetForDataOfSize(-2U, 5)); +} + +TEST(DataExtractorTest, UnsignedNumbers) { + DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8); + uint32_t offset = 0; + + EXPECT_EQ(0x80U, DE.getU8(&offset)); + EXPECT_EQ(1U, offset); + offset = 0; + EXPECT_EQ(0x8090U, DE.getU16(&offset)); + EXPECT_EQ(2U, offset); + offset = 0; + EXPECT_EQ(0x8090FFFFU, DE.getU32(&offset)); + EXPECT_EQ(4U, offset); + offset = 0; + EXPECT_EQ(0x8090FFFF80000000ULL, DE.getU64(&offset)); + EXPECT_EQ(8U, offset); + offset = 0; + EXPECT_EQ(0x8090FFFF80000000ULL, DE.getAddress(&offset)); + EXPECT_EQ(8U, offset); + offset = 0; + + uint32_t data[2]; + EXPECT_EQ(data, DE.getU32(&offset, data, 2)); + EXPECT_EQ(0x8090FFFFU, data[0]); + EXPECT_EQ(0x80000000U, data[1]); + EXPECT_EQ(8U, offset); + offset = 0; + + // Now for little endian. + DE = DataExtractor(StringRef(numberData, sizeof(numberData)-1), true, 4); + EXPECT_EQ(0x9080U, DE.getU16(&offset)); + EXPECT_EQ(2U, offset); + offset = 0; + EXPECT_EQ(0xFFFF9080U, DE.getU32(&offset)); + EXPECT_EQ(4U, offset); + offset = 0; + EXPECT_EQ(0x80FFFF9080ULL, DE.getU64(&offset)); + EXPECT_EQ(8U, offset); + offset = 0; + EXPECT_EQ(0xFFFF9080U, DE.getAddress(&offset)); + EXPECT_EQ(4U, offset); + offset = 0; + + EXPECT_EQ(data, DE.getU32(&offset, data, 2)); + EXPECT_EQ(0xFFFF9080U, data[0]); + EXPECT_EQ(0x80U, data[1]); + EXPECT_EQ(8U, offset); +} + +TEST(DataExtractorTest, SignedNumbers) { + DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8); + uint32_t offset = 0; + + EXPECT_EQ(-128, DE.getSigned(&offset, 1)); + EXPECT_EQ(1U, offset); + offset = 0; + EXPECT_EQ(-32624, DE.getSigned(&offset, 2)); + EXPECT_EQ(2U, offset); + offset = 0; + EXPECT_EQ(-2137980929, DE.getSigned(&offset, 4)); + EXPECT_EQ(4U, offset); + offset = 0; + EXPECT_EQ(-9182558167379214336LL, DE.getSigned(&offset, 8)); + EXPECT_EQ(8U, offset); +} + +TEST(DataExtractorTest, Strings) { + DataExtractor DE(StringRef(stringData, sizeof(stringData)-1), false, 8); + uint32_t offset = 0; + + EXPECT_EQ(stringData, DE.getCStr(&offset)); + EXPECT_EQ(11U, offset); + EXPECT_EQ(NULL, DE.getCStr(&offset)); + EXPECT_EQ(11U, offset); +} + +TEST(DataExtractorTest, LEB128) { + DataExtractor DE(StringRef(leb128data, sizeof(leb128data)-1), false, 8); + uint32_t offset = 0; + + EXPECT_EQ(9382ULL, DE.getULEB128(&offset)); + EXPECT_EQ(2U, offset); + offset = 0; + EXPECT_EQ(-7002LL, DE.getSLEB128(&offset)); + EXPECT_EQ(2U, offset); +} + +} diff --git a/unittests/Support/TypeBuilderTest.cpp b/unittests/Support/TypeBuilderTest.cpp index 06091784cf0c..20d0e739147d 100644 --- a/unittests/Support/TypeBuilderTest.cpp +++ b/unittests/Support/TypeBuilderTest.cpp @@ -184,14 +184,14 @@ class MyPortableType { namespace llvm { template class TypeBuilder { public: - static const StructType *get(LLVMContext &Context) { + static StructType *get(LLVMContext &Context) { // Using the static result variable ensures that the type is // only looked up once. std::vector st; st.push_back(TypeBuilder::get(Context)); st.push_back(TypeBuilder::get(Context)); st.push_back(TypeBuilder::get(Context)); - static const StructType *const result = StructType::get(Context, st); + static StructType *const result = StructType::get(Context, st); return result; } @@ -207,14 +207,14 @@ template class TypeBuilder { template class TypeBuilder { public: - static const StructType *get(LLVMContext &Context) { + static StructType *get(LLVMContext &Context) { // Using the static result variable ensures that the type is // only looked up once. std::vector st; st.push_back(TypeBuilder, cross>::get(Context)); st.push_back(TypeBuilder*, cross>::get(Context)); st.push_back(TypeBuilder*[], cross>::get(Context)); - static const StructType *const result = StructType::get(Context, st); + static StructType *const result = StructType::get(Context, st); return result; } @@ -235,19 +235,19 @@ TEST(TypeBuilderTest, Extensions) { TypeBuilder::get(getGlobalContext()), TypeBuilder::get(getGlobalContext()), TypeBuilder::get(getGlobalContext()), - NULL)), + (void*)0)), (TypeBuilder::get(getGlobalContext()))); EXPECT_EQ(PointerType::getUnqual(StructType::get( TypeBuilder, false>::get(getGlobalContext()), TypeBuilder*, false>::get(getGlobalContext()), TypeBuilder*[], false>::get(getGlobalContext()), - NULL)), + (void*)0)), (TypeBuilder::get(getGlobalContext()))); EXPECT_EQ(PointerType::getUnqual(StructType::get( TypeBuilder, false>::get(getGlobalContext()), TypeBuilder*, false>::get(getGlobalContext()), TypeBuilder*[], false>::get(getGlobalContext()), - NULL)), + (void*)0)), (TypeBuilder::get(getGlobalContext()))); } diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp index 1ce549d1ebfc..1b858695b1d3 100644 --- a/unittests/Transforms/Utils/Cloning.cpp +++ b/unittests/Transforms/Utils/Cloning.cpp @@ -124,7 +124,7 @@ TEST_F(CloneInstruction, Inbounds) { Constant *Z = Constant::getNullValue(Type::getInt32Ty(context)); std::vector ops; ops.push_back(Z); - GetElementPtrInst *GEP = GetElementPtrInst::Create(V, ops.begin(), ops.end()); + GetElementPtrInst *GEP = GetElementPtrInst::Create(V, ops); EXPECT_FALSE(this->clone(GEP)->isInBounds()); GEP->setIsInBounds(); diff --git a/unittests/VMCore/ConstantsTest.cpp b/unittests/VMCore/ConstantsTest.cpp index 8277584ba24d..623ea0d10290 100644 --- a/unittests/VMCore/ConstantsTest.cpp +++ b/unittests/VMCore/ConstantsTest.cpp @@ -16,7 +16,7 @@ namespace llvm { namespace { TEST(ConstantsTest, Integer_i1) { - const IntegerType* Int1 = IntegerType::get(getGlobalContext(), 1); + IntegerType* Int1 = IntegerType::get(getGlobalContext(), 1); Constant* One = ConstantInt::get(Int1, 1, true); Constant* Zero = ConstantInt::get(Int1, 0); Constant* NegOne = ConstantInt::get(Int1, static_cast(-1), true); @@ -97,7 +97,7 @@ TEST(ConstantsTest, Integer_i1) { } TEST(ConstantsTest, IntSigns) { - const IntegerType* Int8Ty = Type::getInt8Ty(getGlobalContext()); + IntegerType* Int8Ty = Type::getInt8Ty(getGlobalContext()); EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, false)->getSExtValue()); EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, true)->getSExtValue()); EXPECT_EQ(100, ConstantInt::getSigned(Int8Ty, 100)->getSExtValue()); @@ -110,9 +110,9 @@ TEST(ConstantsTest, IntSigns) { } TEST(ConstantsTest, FP128Test) { - const Type *FP128Ty = Type::getFP128Ty(getGlobalContext()); + Type *FP128Ty = Type::getFP128Ty(getGlobalContext()); - const IntegerType *Int128Ty = Type::getIntNTy(getGlobalContext(), 128); + IntegerType *Int128Ty = Type::getIntNTy(getGlobalContext(), 128); Constant *Zero128 = Constant::getNullValue(Int128Ty); Constant *X = ConstantExpr::getUIToFP(Zero128, FP128Ty); EXPECT_TRUE(isa(X)); diff --git a/unittests/VMCore/InstructionsTest.cpp b/unittests/VMCore/InstructionsTest.cpp index 9624b816a8d1..f0197bb671ab 100644 --- a/unittests/VMCore/InstructionsTest.cpp +++ b/unittests/VMCore/InstructionsTest.cpp @@ -26,16 +26,16 @@ TEST(InstructionsTest, ReturnInst) { EXPECT_EQ(r0->getNumOperands(), 0U); EXPECT_EQ(r0->op_begin(), r0->op_end()); - const IntegerType* Int1 = IntegerType::get(C, 1); + IntegerType* Int1 = IntegerType::get(C, 1); Constant* One = ConstantInt::get(Int1, 1, true); const ReturnInst* r1 = ReturnInst::Create(C, One); - EXPECT_EQ(r1->getNumOperands(), 1U); + EXPECT_EQ(1U, r1->getNumOperands()); User::const_op_iterator b(r1->op_begin()); - EXPECT_NE(b, r1->op_end()); - EXPECT_EQ(*b, One); - EXPECT_EQ(r1->getOperand(0), One); + EXPECT_NE(r1->op_end(), b); + EXPECT_EQ(One, *b); + EXPECT_EQ(One, r1->getOperand(0)); ++b; - EXPECT_EQ(b, r1->op_end()); + EXPECT_EQ(r1->op_end(), b); // clean up delete r0; @@ -54,17 +54,17 @@ TEST(InstructionsTest, BranchInst) { EXPECT_TRUE(b0->isUnconditional()); EXPECT_FALSE(b0->isConditional()); - EXPECT_EQ(b0->getNumSuccessors(), 1U); + EXPECT_EQ(1U, b0->getNumSuccessors()); // check num operands - EXPECT_EQ(b0->getNumOperands(), 1U); + EXPECT_EQ(1U, b0->getNumOperands()); EXPECT_NE(b0->op_begin(), b0->op_end()); - EXPECT_EQ(llvm::next(b0->op_begin()), b0->op_end()); + EXPECT_EQ(b0->op_end(), llvm::next(b0->op_begin())); - EXPECT_EQ(llvm::next(b0->op_begin()), b0->op_end()); + EXPECT_EQ(b0->op_end(), llvm::next(b0->op_begin())); - const IntegerType* Int1 = IntegerType::get(C, 1); + IntegerType* Int1 = IntegerType::get(C, 1); Constant* One = ConstantInt::get(Int1, 1, true); // Conditional BranchInst @@ -72,33 +72,33 @@ TEST(InstructionsTest, BranchInst) { EXPECT_FALSE(b1->isUnconditional()); EXPECT_TRUE(b1->isConditional()); - EXPECT_EQ(b1->getNumSuccessors(), 2U); + EXPECT_EQ(2U, b1->getNumSuccessors()); // check num operands - EXPECT_EQ(b1->getNumOperands(), 3U); + EXPECT_EQ(3U, b1->getNumOperands()); User::const_op_iterator b(b1->op_begin()); // check COND EXPECT_NE(b, b1->op_end()); - EXPECT_EQ(*b, One); - EXPECT_EQ(b1->getOperand(0), One); - EXPECT_EQ(b1->getCondition(), One); + EXPECT_EQ(One, *b); + EXPECT_EQ(One, b1->getOperand(0)); + EXPECT_EQ(One, b1->getCondition()); ++b; // check ELSE - EXPECT_EQ(*b, bb1); - EXPECT_EQ(b1->getOperand(1), bb1); - EXPECT_EQ(b1->getSuccessor(1), bb1); + EXPECT_EQ(bb1, *b); + EXPECT_EQ(bb1, b1->getOperand(1)); + EXPECT_EQ(bb1, b1->getSuccessor(1)); ++b; // check THEN - EXPECT_EQ(*b, bb0); - EXPECT_EQ(b1->getOperand(2), bb0); - EXPECT_EQ(b1->getSuccessor(0), bb0); + EXPECT_EQ(bb0, *b); + EXPECT_EQ(bb0, b1->getOperand(2)); + EXPECT_EQ(bb0, b1->getSuccessor(0)); ++b; - EXPECT_EQ(b, b1->op_end()); + EXPECT_EQ(b1->op_end(), b); // clean up delete b0; @@ -111,11 +111,11 @@ TEST(InstructionsTest, BranchInst) { TEST(InstructionsTest, CastInst) { LLVMContext &C(getGlobalContext()); - const Type* Int8Ty = Type::getInt8Ty(C); - const Type* Int64Ty = Type::getInt64Ty(C); - const Type* V8x8Ty = VectorType::get(Int8Ty, 8); - const Type* V8x64Ty = VectorType::get(Int64Ty, 8); - const Type* X86MMXTy = Type::getX86_MMXTy(C); + Type* Int8Ty = Type::getInt8Ty(C); + Type* Int64Ty = Type::getInt64Ty(C); + Type* V8x8Ty = VectorType::get(Int8Ty, 8); + Type* V8x64Ty = VectorType::get(Int64Ty, 8); + Type* X86MMXTy = Type::getX86_MMXTy(C); const Constant* c8 = Constant::getNullValue(V8x8Ty); const Constant* c64 = Constant::getNullValue(V8x64Ty); @@ -125,8 +125,8 @@ TEST(InstructionsTest, CastInst) { EXPECT_FALSE(CastInst::isCastable(Int64Ty, X86MMXTy)); EXPECT_TRUE(CastInst::isCastable(V8x64Ty, V8x8Ty)); EXPECT_TRUE(CastInst::isCastable(V8x8Ty, V8x64Ty)); - EXPECT_EQ(CastInst::getCastOpcode(c64, true, V8x8Ty, true), CastInst::Trunc); - EXPECT_EQ(CastInst::getCastOpcode(c8, true, V8x64Ty, true), CastInst::SExt); + EXPECT_EQ(CastInst::Trunc, CastInst::getCastOpcode(c64, true, V8x8Ty, true)); + EXPECT_EQ(CastInst::SExt, CastInst::getCastOpcode(c8, true, V8x64Ty, true)); } } // end anonymous namespace diff --git a/unittests/VMCore/MetadataTest.cpp b/unittests/VMCore/MetadataTest.cpp index 0b2c012edaac..12ac2e704c8e 100644 --- a/unittests/VMCore/MetadataTest.cpp +++ b/unittests/VMCore/MetadataTest.cpp @@ -63,7 +63,7 @@ TEST_F(MDStringTest, PrintingSimple) { // Test printing of MDString with non-printable characters. TEST_F(MDStringTest, PrintingComplex) { - char str[5] = {0, '\n', '"', '\\', -1}; + char str[5] = {0, '\n', '"', '\\', (char)-1}; MDString *s = MDString::get(Context, StringRef(str+0, 5)); std::string Str; raw_string_ostream oss(Str); diff --git a/unittests/VMCore/VerifierTest.cpp b/unittests/VMCore/VerifierTest.cpp index 1924661200b5..324b4e193ba6 100644 --- a/unittests/VMCore/VerifierTest.cpp +++ b/unittests/VMCore/VerifierTest.cpp @@ -47,7 +47,7 @@ TEST(VerifierTest, Branch_i1) { TEST(VerifierTest, AliasUnnamedAddr) { LLVMContext &C = getGlobalContext(); Module M("M", C); - const Type *Ty = Type::getInt8Ty(C); + Type *Ty = Type::getInt8Ty(C); Constant *Init = Constant::getNullValue(Ty); GlobalVariable *Aliasee = new GlobalVariable(M, Ty, true, GlobalValue::ExternalLinkage, diff --git a/utils/TableGen/ARMDecoderEmitter.cpp b/utils/TableGen/ARMDecoderEmitter.cpp index 8a5dc8ba1543..145b96df98e2 100644 --- a/utils/TableGen/ARMDecoderEmitter.cpp +++ b/utils/TableGen/ARMDecoderEmitter.cpp @@ -18,10 +18,10 @@ #include "ARMDecoderEmitter.h" #include "CodeGenTarget.h" -#include "Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TableGen/Record.h" #include #include @@ -41,7 +41,7 @@ using namespace llvm; ENTRY(ARM_FORMAT_BRFRM, 2) \ ENTRY(ARM_FORMAT_BRMISCFRM, 3) \ ENTRY(ARM_FORMAT_DPFRM, 4) \ - ENTRY(ARM_FORMAT_DPSOREGFRM, 5) \ + ENTRY(ARM_FORMAT_DPSOREGREGFRM, 5) \ ENTRY(ARM_FORMAT_LDFRM, 6) \ ENTRY(ARM_FORMAT_STFRM, 7) \ ENTRY(ARM_FORMAT_LDMISCFRM, 8) \ @@ -77,7 +77,8 @@ using namespace llvm; ENTRY(ARM_FORMAT_N3RegVecSh, 38) \ ENTRY(ARM_FORMAT_NVecExtract, 39) \ ENTRY(ARM_FORMAT_NVecMulScalar, 40) \ - ENTRY(ARM_FORMAT_NVTBL, 41) + ENTRY(ARM_FORMAT_NVTBL, 41) \ + ENTRY(ARM_FORMAT_DPSOREGIMMFRM, 42) // ARM instruction format specifies the encoding used by the instruction. #define ENTRY(n, v) n = v, @@ -1614,15 +1615,6 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI, if (!thumbInstruction(Form)) return false; - // A8.6.189 STM / STMIA / STMEA -- Encoding T1 - // There's only STMIA_UPD for Thumb1. - if (Name == "tSTMIA") - return false; - - // On Darwin R9 is call-clobbered. Ignore the non-Darwin counterparts. - if (Name == "tBL" || Name == "tBLXi" || Name == "tBLXr") - return false; - // A8.6.25 BX. Use the generic tBX_Rm, ignore tBX_RET and tBX_RET_vararg. if (Name == "tBX_RET" || Name == "tBX_RET_vararg") return false; @@ -1654,14 +1646,12 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI, // Resolve conflicts: // - // tBfar conflicts with tBLr9 // t2LDMIA_RET conflict with t2LDM (ditto) // tMOVCCi conflicts with tMOVi8 // tMOVCCr conflicts with tMOVgpr2gpr // tLDRcp conflicts with tLDRspi // t2MOVCCi16 conflicts with tMOVi16 - if (Name == "tBfar" || - Name == "t2LDMIA_RET" || + if (Name == "t2LDMIA_RET" || Name == "tMOVCCi" || Name == "tMOVCCr" || Name == "tLDRcp" || Name == "t2MOVCCi16") diff --git a/utils/TableGen/ARMDecoderEmitter.h b/utils/TableGen/ARMDecoderEmitter.h index 1faeb91fae8a..486f899354f4 100644 --- a/utils/TableGen/ARMDecoderEmitter.h +++ b/utils/TableGen/ARMDecoderEmitter.h @@ -15,9 +15,8 @@ #ifndef ARMDECODEREMITTER_H #define ARMDECODEREMITTER_H -#include "TableGenBackend.h" - #include "llvm/Support/DataTypes.h" +#include "llvm/TableGen/TableGenBackend.h" namespace llvm { diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index a6a4fecd3015..8b86c23d0632 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -98,8 +98,6 @@ #include "AsmMatcherEmitter.h" #include "CodeGenTarget.h" -#include "Error.h" -#include "Record.h" #include "StringMatcher.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/PointerUnion.h" @@ -109,6 +107,8 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" #include #include using namespace llvm; @@ -914,17 +914,17 @@ void AsmMatcherInfo:: BuildRegisterClasses(SmallPtrSet &SingletonRegisters) { const std::vector &Registers = Target.getRegBank().getRegisters(); - const std::vector &RegClassList = - Target.getRegisterClasses(); + ArrayRef RegClassList = + Target.getRegBank().getRegClasses(); // The register sets used for matching. std::set< std::set > RegisterSets; // Gather the defined sets. - for (std::vector::const_iterator it = + for (ArrayRef::const_iterator it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) - RegisterSets.insert(std::set(it->getOrder().begin(), - it->getOrder().end())); + RegisterSets.insert(std::set( + (*it)->getOrder().begin(), (*it)->getOrder().end())); // Add any required singleton sets. for (SmallPtrSet::iterator it = SingletonRegisters.begin(), @@ -996,18 +996,23 @@ BuildRegisterClasses(SmallPtrSet &SingletonRegisters) { } // Name the register classes which correspond to a user defined RegisterClass. - for (std::vector::const_iterator + for (ArrayRef::const_iterator it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) { - ClassInfo *CI = RegisterSetClasses[std::set(it->getOrder().begin(), - it->getOrder().end())]; + const CodeGenRegisterClass &RC = **it; + // Def will be NULL for non-user defined register classes. + Record *Def = RC.getDef(); + if (!Def) + continue; + ClassInfo *CI = RegisterSetClasses[std::set(RC.getOrder().begin(), + RC.getOrder().end())]; if (CI->ValueName.empty()) { - CI->ClassName = it->getName(); - CI->Name = "MCK_" + it->getName(); - CI->ValueName = it->getName(); + CI->ClassName = RC.getName(); + CI->Name = "MCK_" + RC.getName(); + CI->ValueName = RC.getName(); } else - CI->ValueName = CI->ValueName + "," + it->getName(); + CI->ValueName = CI->ValueName + "," + RC.getName(); - RegisterClassClasses.insert(std::make_pair(it->TheDef, CI)); + RegisterClassClasses.insert(std::make_pair(Def, CI)); } // Populate the map for individual registers. @@ -2172,21 +2177,14 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "\n#ifdef GET_ASSEMBLER_HEADER\n"; OS << "#undef GET_ASSEMBLER_HEADER\n"; OS << " // This should be included into the middle of the declaration of\n"; - OS << " // your subclasses implementation of TargetAsmParser.\n"; + OS << " // your subclasses implementation of MCTargetAsmParser.\n"; OS << " unsigned ComputeAvailableFeatures(uint64_t FeatureBits) const;\n"; - OS << " enum MatchResultTy {\n"; - OS << " Match_ConversionFail,\n"; - OS << " Match_InvalidOperand,\n"; - OS << " Match_MissingFeature,\n"; - OS << " Match_MnemonicFail,\n"; - OS << " Match_Success\n"; - OS << " };\n"; OS << " bool ConvertToMCInst(unsigned Kind, MCInst &Inst, " << "unsigned Opcode,\n" << " const SmallVectorImpl " << "&Operands);\n"; OS << " bool MnemonicIsValid(StringRef Mnemonic);\n"; - OS << " MatchResultTy MatchInstructionImpl(\n"; + OS << " unsigned MatchInstructionImpl(\n"; OS << " const SmallVectorImpl &Operands,\n"; OS << " MCInst &Inst, unsigned &ErrorInfo);\n"; @@ -2328,7 +2326,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "}\n\n"; // Finally, build the match function. - OS << Target.getName() << ClassName << "::MatchResultTy " + OS << "unsigned " << Target.getName() << ClassName << "::\n" << "MatchInstructionImpl(const SmallVectorImpl" << " &Operands,\n"; @@ -2355,7 +2353,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " }\n\n"; OS << " // Some state to try to produce better error messages.\n"; - OS << " bool HadMatchOtherThanFeatures = false;\n\n"; + OS << " bool HadMatchOtherThanFeatures = false;\n"; + OS << " bool HadMatchOtherThanPredicate = false;\n"; + OS << " unsigned RetCode = Match_InvalidOperand;\n"; OS << " // Set ErrorInfo to the operand that mismatches if it is\n"; OS << " // wrong for all instances of the instruction.\n"; OS << " ErrorInfo = ~0U;\n"; @@ -2411,6 +2411,18 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " return Match_ConversionFail;\n"; OS << "\n"; + // Verify the instruction with the target-specific match predicate function. + OS << " // We have a potential match. Check the target predicate to\n" + << " // handle any context sensitive constraints.\n" + << " unsigned MatchResult;\n" + << " if ((MatchResult = checkTargetMatchPredicate(Inst)) !=" + << " Match_Success) {\n" + << " Inst.clear();\n" + << " RetCode = MatchResult;\n" + << " HadMatchOtherThanPredicate = true;\n" + << " continue;\n" + << " }\n\n"; + // Call the post-processing function, if used. std::string InsnCleanupFn = AsmParser->getValueAsString("AsmParserInstCleanup"); @@ -2421,8 +2433,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " }\n\n"; OS << " // Okay, we had no match. Try to return a useful error code.\n"; - OS << " if (HadMatchOtherThanFeatures) return Match_MissingFeature;\n"; - OS << " return Match_InvalidOperand;\n"; + OS << " if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)"; + OS << " return RetCode;\n"; + OS << " return Match_MissingFeature;\n"; OS << "}\n\n"; if (Info.OperandMatchInfo.size()) diff --git a/utils/TableGen/AsmMatcherEmitter.h b/utils/TableGen/AsmMatcherEmitter.h index c13adf3dc535..e04ac103a401 100644 --- a/utils/TableGen/AsmMatcherEmitter.h +++ b/utils/TableGen/AsmMatcherEmitter.h @@ -15,7 +15,7 @@ #ifndef ASMMATCHER_EMITTER_H #define ASMMATCHER_EMITTER_H -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" #include namespace llvm { diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index f44f050ef048..3123e11f774f 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -14,13 +14,13 @@ #include "AsmWriterEmitter.h" #include "AsmWriterInst.h" -#include "Error.h" #include "CodeGenTarget.h" -#include "Record.h" #include "StringToOffsetTable.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" #include using namespace llvm; @@ -703,8 +703,8 @@ void AsmWriterEmitter::EmitRegIsInRegClass(raw_ostream &O) { CodeGenTarget Target(Records); // Enumerate the register classes. - const std::vector &RegisterClasses = - Target.getRegisterClasses(); + ArrayRef RegisterClasses = + Target.getRegBank().getRegClasses(); O << "namespace { // Register classes\n"; O << " enum RegClass {\n"; @@ -712,7 +712,7 @@ void AsmWriterEmitter::EmitRegIsInRegClass(raw_ostream &O) { // Emit the register enum value for each RegisterClass. for (unsigned I = 0, E = RegisterClasses.size(); I != E; ++I) { if (I != 0) O << ",\n"; - O << " RC_" << RegisterClasses[I].TheDef->getName(); + O << " RC_" << RegisterClasses[I]->getName(); } O << "\n };\n"; @@ -729,10 +729,10 @@ void AsmWriterEmitter::EmitRegIsInRegClass(raw_ostream &O) { O << " default: break;\n"; for (unsigned I = 0, E = RegisterClasses.size(); I != E; ++I) { - const CodeGenRegisterClass &RC = RegisterClasses[I]; + const CodeGenRegisterClass &RC = *RegisterClasses[I]; // Give the register class a legal C name if it's anonymous. - std::string Name = RC.TheDef->getName(); + std::string Name = RC.getName(); O << " case RC_" << Name << ":\n"; // Emit the register list now. diff --git a/utils/TableGen/AsmWriterEmitter.h b/utils/TableGen/AsmWriterEmitter.h index 84c925b66e8c..731e31cc746e 100644 --- a/utils/TableGen/AsmWriterEmitter.h +++ b/utils/TableGen/AsmWriterEmitter.h @@ -15,7 +15,7 @@ #ifndef ASMWRITER_EMITTER_H #define ASMWRITER_EMITTER_H -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" #include #include #include diff --git a/utils/TableGen/AsmWriterInst.cpp b/utils/TableGen/AsmWriterInst.cpp index fdf447f2aaf3..350a2ccfcc23 100644 --- a/utils/TableGen/AsmWriterInst.cpp +++ b/utils/TableGen/AsmWriterInst.cpp @@ -13,8 +13,8 @@ #include "AsmWriterInst.h" #include "CodeGenTarget.h" -#include "Record.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/TableGen/Record.h" using namespace llvm; diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt index 4d71259a8315..02ebd67ba662 100644 --- a/utils/TableGen/CMakeLists.txt +++ b/utils/TableGen/CMakeLists.txt @@ -1,18 +1,12 @@ set(LLVM_REQUIRES_EH 1) set(LLVM_REQUIRES_RTTI 1) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_TOOLS_BINARY_DIR}) - -add_llvm_utility(tblgen +add_tablegen(llvm-tblgen LLVM ARMDecoderEmitter.cpp AsmMatcherEmitter.cpp AsmWriterEmitter.cpp AsmWriterInst.cpp CallingConvEmitter.cpp - ClangASTNodesEmitter.cpp - ClangAttrEmitter.cpp - ClangDiagnosticsEmitter.cpp - ClangSACheckersEmitter.cpp CodeEmitterGen.cpp CodeGenDAGPatterns.cpp CodeGenInstruction.cpp @@ -25,36 +19,18 @@ add_llvm_utility(tblgen DAGISelMatcher.cpp DisassemblerEmitter.cpp EDEmitter.cpp - Error.cpp FastISelEmitter.cpp FixedLenDecoderEmitter.cpp InstrEnumEmitter.cpp InstrInfoEmitter.cpp IntrinsicEmitter.cpp - LLVMCConfigurationEmitter.cpp - NeonEmitter.cpp - OptParserEmitter.cpp PseudoLoweringEmitter.cpp - Record.cpp RegisterInfoEmitter.cpp SetTheory.cpp StringMatcher.cpp SubtargetEmitter.cpp - TGLexer.cpp - TGParser.cpp TGValueTypes.cpp TableGen.cpp - TableGenBackend.cpp X86DisassemblerTables.cpp X86RecognizableInstr.cpp ) - -target_link_libraries(tblgen LLVMSupport) -if( MINGW ) - target_link_libraries(tblgen imagehlp psapi) -endif( MINGW ) -if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD AND NOT BEOS ) - target_link_libraries(tblgen pthread) -endif() - -install(TARGETS tblgen RUNTIME DESTINATION bin) diff --git a/utils/TableGen/CallingConvEmitter.cpp b/utils/TableGen/CallingConvEmitter.cpp index c51afd82a37a..fcdaa082fb2a 100644 --- a/utils/TableGen/CallingConvEmitter.cpp +++ b/utils/TableGen/CallingConvEmitter.cpp @@ -13,8 +13,8 @@ //===----------------------------------------------------------------------===// #include "CallingConvEmitter.h" -#include "Record.h" #include "CodeGenTarget.h" +#include "llvm/TableGen/Record.h" using namespace llvm; void CallingConvEmitter::run(raw_ostream &O) { diff --git a/utils/TableGen/CallingConvEmitter.h b/utils/TableGen/CallingConvEmitter.h index 431c33bcc0df..7bddd6c93eff 100644 --- a/utils/TableGen/CallingConvEmitter.h +++ b/utils/TableGen/CallingConvEmitter.h @@ -15,7 +15,7 @@ #ifndef CALLINGCONV_EMITTER_H #define CALLINGCONV_EMITTER_H -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" #include namespace llvm { diff --git a/utils/TableGen/ClangASTNodesEmitter.cpp b/utils/TableGen/ClangASTNodesEmitter.cpp deleted file mode 100644 index d9d5a3ccd907..000000000000 --- a/utils/TableGen/ClangASTNodesEmitter.cpp +++ /dev/null @@ -1,168 +0,0 @@ -//=== ClangASTNodesEmitter.cpp - Generate Clang AST node tables -*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// These tablegen backends emit Clang AST node tables -// -//===----------------------------------------------------------------------===// - -#include "ClangASTNodesEmitter.h" -#include -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Statement Node Tables (.inc file) generation. -//===----------------------------------------------------------------------===// - -// Returns the first and last non-abstract subrecords -// Called recursively to ensure that nodes remain contiguous -std::pair ClangASTNodesEmitter::EmitNode( - const ChildMap &Tree, - raw_ostream &OS, - Record *Base) { - std::string BaseName = macroName(Base->getName()); - - ChildIterator i = Tree.lower_bound(Base), e = Tree.upper_bound(Base); - - Record *First = 0, *Last = 0; - // This might be the pseudo-node for Stmt; don't assume it has an Abstract - // bit - if (Base->getValue("Abstract") && !Base->getValueAsBit("Abstract")) - First = Last = Base; - - for (; i != e; ++i) { - Record *R = i->second; - bool Abstract = R->getValueAsBit("Abstract"); - std::string NodeName = macroName(R->getName()); - - OS << "#ifndef " << NodeName << "\n"; - OS << "# define " << NodeName << "(Type, Base) " - << BaseName << "(Type, Base)\n"; - OS << "#endif\n"; - - if (Abstract) - OS << "ABSTRACT_" << macroName(Root.getName()) << "(" << NodeName << "(" - << R->getName() << ", " << baseName(*Base) << "))\n"; - else - OS << NodeName << "(" << R->getName() << ", " - << baseName(*Base) << ")\n"; - - if (Tree.find(R) != Tree.end()) { - const std::pair &Result - = EmitNode(Tree, OS, R); - if (!First && Result.first) - First = Result.first; - if (Result.second) - Last = Result.second; - } else { - if (!Abstract) { - Last = R; - - if (!First) - First = R; - } - } - - OS << "#undef " << NodeName << "\n\n"; - } - - if (First) { - assert (Last && "Got a first node but not a last node for a range!"); - if (Base == &Root) - OS << "LAST_" << macroName(Root.getName()) << "_RANGE("; - else - OS << macroName(Root.getName()) << "_RANGE("; - OS << Base->getName() << ", " << First->getName() << ", " - << Last->getName() << ")\n\n"; - } - - return std::make_pair(First, Last); -} - -void ClangASTNodesEmitter::run(raw_ostream &OS) { - // Write the preamble - OS << "#ifndef ABSTRACT_" << macroName(Root.getName()) << "\n"; - OS << "# define ABSTRACT_" << macroName(Root.getName()) << "(Type) Type\n"; - OS << "#endif\n"; - - OS << "#ifndef " << macroName(Root.getName()) << "_RANGE\n"; - OS << "# define " - << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n"; - OS << "#endif\n\n"; - - OS << "#ifndef LAST_" << macroName(Root.getName()) << "_RANGE\n"; - OS << "# define LAST_" - << macroName(Root.getName()) << "_RANGE(Base, First, Last) " - << macroName(Root.getName()) << "_RANGE(Base, First, Last)\n"; - OS << "#endif\n\n"; - - // Emit statements - const std::vector Stmts - = Records.getAllDerivedDefinitions(Root.getName()); - - ChildMap Tree; - - for (unsigned i = 0, e = Stmts.size(); i != e; ++i) { - Record *R = Stmts[i]; - - if (R->getValue("Base")) - Tree.insert(std::make_pair(R->getValueAsDef("Base"), R)); - else - Tree.insert(std::make_pair(&Root, R)); - } - - EmitNode(Tree, OS, &Root); - - OS << "#undef " << macroName(Root.getName()) << "\n"; - OS << "#undef " << macroName(Root.getName()) << "_RANGE\n"; - OS << "#undef LAST_" << macroName(Root.getName()) << "_RANGE\n"; - OS << "#undef ABSTRACT_" << macroName(Root.getName()) << "\n"; -} - -void ClangDeclContextEmitter::run(raw_ostream &OS) { - // FIXME: Find a .td file format to allow for this to be represented better. - - OS << "#ifndef DECL_CONTEXT\n"; - OS << "# define DECL_CONTEXT(DECL)\n"; - OS << "#endif\n"; - - OS << "#ifndef DECL_CONTEXT_BASE\n"; - OS << "# define DECL_CONTEXT_BASE(DECL) DECL_CONTEXT(DECL)\n"; - OS << "#endif\n"; - - typedef std::set RecordSet; - typedef std::vector RecordVector; - - RecordVector DeclContextsVector - = Records.getAllDerivedDefinitions("DeclContext"); - RecordVector Decls = Records.getAllDerivedDefinitions("Decl"); - RecordSet DeclContexts (DeclContextsVector.begin(), DeclContextsVector.end()); - - for (RecordVector::iterator i = Decls.begin(), e = Decls.end(); i != e; ++i) { - Record *R = *i; - - if (R->getValue("Base")) { - Record *B = R->getValueAsDef("Base"); - if (DeclContexts.find(B) != DeclContexts.end()) { - OS << "DECL_CONTEXT_BASE(" << B->getName() << ")\n"; - DeclContexts.erase(B); - } - } - } - - // To keep identical order, RecordVector may be used - // instead of RecordSet. - for (RecordVector::iterator - i = DeclContextsVector.begin(), e = DeclContextsVector.end(); - i != e; ++i) - if (DeclContexts.find(*i) != DeclContexts.end()) - OS << "DECL_CONTEXT(" << (*i)->getName() << ")\n"; - - OS << "#undef DECL_CONTEXT\n"; - OS << "#undef DECL_CONTEXT_BASE\n"; -} diff --git a/utils/TableGen/ClangASTNodesEmitter.h b/utils/TableGen/ClangASTNodesEmitter.h deleted file mode 100644 index 712333bd2d25..000000000000 --- a/utils/TableGen/ClangASTNodesEmitter.h +++ /dev/null @@ -1,84 +0,0 @@ -//===- ClangASTNodesEmitter.h - Generate Clang AST node tables -*- C++ -*--===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// These tablegen backends emit Clang AST node tables -// -//===----------------------------------------------------------------------===// - -#ifndef CLANGAST_EMITTER_H -#define CLANGAST_EMITTER_H - -#include "TableGenBackend.h" -#include "Record.h" -#include -#include -#include - -namespace llvm { - -/// ClangASTNodesEmitter - The top-level class emits .inc files containing -/// declarations of Clang statements. -/// -class ClangASTNodesEmitter : public TableGenBackend { - // A map from a node to each of its derived nodes. - typedef std::multimap ChildMap; - typedef ChildMap::const_iterator ChildIterator; - - RecordKeeper &Records; - Record Root; - const std::string &BaseSuffix; - - // Create a macro-ized version of a name - static std::string macroName(std::string S) { - for (unsigned i = 0; i < S.size(); ++i) - S[i] = std::toupper(S[i]); - - return S; - } - - // Return the name to be printed in the base field. Normally this is - // the record's name plus the base suffix, but if it is the root node and - // the suffix is non-empty, it's just the suffix. - std::string baseName(Record &R) { - if (&R == &Root && !BaseSuffix.empty()) - return BaseSuffix; - - return R.getName() + BaseSuffix; - } - - std::pair EmitNode (const ChildMap &Tree, raw_ostream& OS, - Record *Base); -public: - explicit ClangASTNodesEmitter(RecordKeeper &R, const std::string &N, - const std::string &S) - : Records(R), Root(N, SMLoc(), R), BaseSuffix(S) - {} - - // run - Output the .inc file contents - void run(raw_ostream &OS); -}; - -/// ClangDeclContextEmitter - Emits an addendum to a .inc file to enumerate the -/// clang declaration contexts. -/// -class ClangDeclContextEmitter : public TableGenBackend { - RecordKeeper &Records; - -public: - explicit ClangDeclContextEmitter(RecordKeeper &R) - : Records(R) - {} - - // run - Output the .inc file contents - void run(raw_ostream &OS); -}; - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp deleted file mode 100644 index 26bd8786a49c..000000000000 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ /dev/null @@ -1,756 +0,0 @@ -//===- ClangAttrEmitter.cpp - Generate Clang attribute handling =-*- C++ -*--=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// These tablegen backends emit Clang attribute processing code -// -//===----------------------------------------------------------------------===// - -#include "ClangAttrEmitter.h" -#include "Record.h" -#include "llvm/ADT/StringSwitch.h" -#include -#include - -using namespace llvm; - -static const std::vector -getValueAsListOfStrings(Record &R, StringRef FieldName) { - ListInit *List = R.getValueAsListInit(FieldName); - assert (List && "Got a null ListInit"); - - std::vector Strings; - Strings.reserve(List->getSize()); - - for (ListInit::iterator i = List->begin(), e = List->end(); i != e; ++i) { - assert(*i && "Got a null element in a ListInit"); - if (StringInit *S = dynamic_cast(*i)) - Strings.push_back(S->getValue()); - else if (CodeInit *C = dynamic_cast(*i)) - Strings.push_back(C->getValue()); - else - assert(false && "Got a non-string, non-code element in a ListInit"); - } - - return Strings; -} - -std::string ReadPCHRecord(StringRef type) { - return StringSwitch(type) - .EndsWith("Decl *", "cast_or_null<" + std::string(type, 0, type.size()-1) + - ">(GetDecl(Record[Idx++]))") - .Case("QualType", "GetType(Record[Idx++])") - .Case("Expr *", "ReadSubExpr()") - .Case("IdentifierInfo *", "GetIdentifierInfo(Record, Idx)") - .Default("Record[Idx++]"); -} - -// Assumes that the way to get the value is SA->getname() -std::string WritePCHRecord(StringRef type, StringRef name) { - return StringSwitch(type) - .EndsWith("Decl *", "AddDeclRef(" + std::string(name) + - ", Record);\n") - .Case("QualType", "AddTypeRef(" + std::string(name) + ", Record);\n") - .Case("Expr *", "AddStmt(" + std::string(name) + ");\n") - .Case("IdentifierInfo *", - "AddIdentifierRef(" + std::string(name) + ", Record);\n") - .Default("Record.push_back(" + std::string(name) + ");\n"); -} - -namespace { - class Argument { - std::string lowerName, upperName; - StringRef attrName; - - public: - Argument(Record &Arg, StringRef Attr) - : lowerName(Arg.getValueAsString("Name")), upperName(lowerName), - attrName(Attr) { - if (!lowerName.empty()) { - lowerName[0] = std::tolower(lowerName[0]); - upperName[0] = std::toupper(upperName[0]); - } - } - virtual ~Argument() {} - - StringRef getLowerName() const { return lowerName; } - StringRef getUpperName() const { return upperName; } - StringRef getAttrName() const { return attrName; } - - // These functions print the argument contents formatted in different ways. - virtual void writeAccessors(raw_ostream &OS) const = 0; - virtual void writeAccessorDefinitions(raw_ostream &OS) const {} - virtual void writeCloneArgs(raw_ostream &OS) const = 0; - virtual void writeCtorBody(raw_ostream &OS) const {} - virtual void writeCtorInitializers(raw_ostream &OS) const = 0; - virtual void writeCtorParameters(raw_ostream &OS) const = 0; - virtual void writeDeclarations(raw_ostream &OS) const = 0; - virtual void writePCHReadArgs(raw_ostream &OS) const = 0; - virtual void writePCHReadDecls(raw_ostream &OS) const = 0; - virtual void writePCHWrite(raw_ostream &OS) const = 0; - }; - - class SimpleArgument : public Argument { - std::string type; - - public: - SimpleArgument(Record &Arg, StringRef Attr, std::string T) - : Argument(Arg, Attr), type(T) - {} - - void writeAccessors(raw_ostream &OS) const { - OS << " " << type << " get" << getUpperName() << "() const {\n"; - OS << " return " << getLowerName() << ";\n"; - OS << " }"; - } - void writeCloneArgs(raw_ostream &OS) const { - OS << getLowerName(); - } - void writeCtorInitializers(raw_ostream &OS) const { - OS << getLowerName() << "(" << getUpperName() << ")"; - } - void writeCtorParameters(raw_ostream &OS) const { - OS << type << " " << getUpperName(); - } - void writeDeclarations(raw_ostream &OS) const { - OS << type << " " << getLowerName() << ";"; - } - void writePCHReadDecls(raw_ostream &OS) const { - std::string read = ReadPCHRecord(type); - OS << " " << type << " " << getLowerName() << " = " << read << ";\n"; - } - void writePCHReadArgs(raw_ostream &OS) const { - OS << getLowerName(); - } - void writePCHWrite(raw_ostream &OS) const { - OS << " " << WritePCHRecord(type, "SA->get" + - std::string(getUpperName()) + "()"); - } - }; - - class StringArgument : public Argument { - public: - StringArgument(Record &Arg, StringRef Attr) - : Argument(Arg, Attr) - {} - - void writeAccessors(raw_ostream &OS) const { - OS << " llvm::StringRef get" << getUpperName() << "() const {\n"; - OS << " return llvm::StringRef(" << getLowerName() << ", " - << getLowerName() << "Length);\n"; - OS << " }\n"; - OS << " unsigned get" << getUpperName() << "Length() const {\n"; - OS << " return " << getLowerName() << "Length;\n"; - OS << " }\n"; - OS << " void set" << getUpperName() - << "(ASTContext &C, llvm::StringRef S) {\n"; - OS << " " << getLowerName() << "Length = S.size();\n"; - OS << " this->" << getLowerName() << " = new (C, 1) char [" - << getLowerName() << "Length];\n"; - OS << " std::memcpy(this->" << getLowerName() << ", S.data(), " - << getLowerName() << "Length);\n"; - OS << " }"; - } - void writeCloneArgs(raw_ostream &OS) const { - OS << "get" << getUpperName() << "()"; - } - void writeCtorBody(raw_ostream &OS) const { - OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() - << ".data(), " << getLowerName() << "Length);"; - } - void writeCtorInitializers(raw_ostream &OS) const { - OS << getLowerName() << "Length(" << getUpperName() << ".size())," - << getLowerName() << "(new (Ctx, 1) char[" << getLowerName() - << "Length])"; - } - void writeCtorParameters(raw_ostream &OS) const { - OS << "llvm::StringRef " << getUpperName(); - } - void writeDeclarations(raw_ostream &OS) const { - OS << "unsigned " << getLowerName() << "Length;\n"; - OS << "char *" << getLowerName() << ";"; - } - void writePCHReadDecls(raw_ostream &OS) const { - OS << " std::string " << getLowerName() - << "= ReadString(Record, Idx);\n"; - } - void writePCHReadArgs(raw_ostream &OS) const { - OS << getLowerName(); - } - void writePCHWrite(raw_ostream &OS) const { - OS << " AddString(SA->get" << getUpperName() << "(), Record);\n"; - } - }; - - class AlignedArgument : public Argument { - public: - AlignedArgument(Record &Arg, StringRef Attr) - : Argument(Arg, Attr) - {} - - void writeAccessors(raw_ostream &OS) const { - OS << " bool is" << getUpperName() << "Dependent() const;\n"; - - OS << " unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n"; - - OS << " bool is" << getUpperName() << "Expr() const {\n"; - OS << " return is" << getLowerName() << "Expr;\n"; - OS << " }\n"; - - OS << " Expr *get" << getUpperName() << "Expr() const {\n"; - OS << " assert(is" << getLowerName() << "Expr);\n"; - OS << " return " << getLowerName() << "Expr;\n"; - OS << " }\n"; - - OS << " TypeSourceInfo *get" << getUpperName() << "Type() const {\n"; - OS << " assert(!is" << getLowerName() << "Expr);\n"; - OS << " return " << getLowerName() << "Type;\n"; - OS << " }"; - } - void writeAccessorDefinitions(raw_ostream &OS) const { - OS << "bool " << getAttrName() << "Attr::is" << getUpperName() - << "Dependent() const {\n"; - OS << " if (is" << getLowerName() << "Expr)\n"; - OS << " return " << getLowerName() << "Expr && (" << getLowerName() - << "Expr->isValueDependent() || " << getLowerName() - << "Expr->isTypeDependent());\n"; - OS << " else\n"; - OS << " return " << getLowerName() - << "Type->getType()->isDependentType();\n"; - OS << "}\n"; - - // FIXME: Do not do the calculation here - // FIXME: Handle types correctly - // A null pointer means maximum alignment - // FIXME: Load the platform-specific maximum alignment, rather than - // 16, the x86 max. - OS << "unsigned " << getAttrName() << "Attr::get" << getUpperName() - << "(ASTContext &Ctx) const {\n"; - OS << " assert(!is" << getUpperName() << "Dependent());\n"; - OS << " if (is" << getLowerName() << "Expr)\n"; - OS << " return (" << getLowerName() << "Expr ? " << getLowerName() - << "Expr->EvaluateAsInt(Ctx).getZExtValue() : 16)" - << "* Ctx.getCharWidth();\n"; - OS << " else\n"; - OS << " return 0; // FIXME\n"; - OS << "}\n"; - } - void writeCloneArgs(raw_ostream &OS) const { - OS << "is" << getLowerName() << "Expr, is" << getLowerName() - << "Expr ? static_cast(" << getLowerName() - << "Expr) : " << getLowerName() - << "Type"; - } - void writeCtorBody(raw_ostream &OS) const { - OS << " if (is" << getLowerName() << "Expr)\n"; - OS << " " << getLowerName() << "Expr = reinterpret_cast(" - << getUpperName() << ");\n"; - OS << " else\n"; - OS << " " << getLowerName() - << "Type = reinterpret_cast(" << getUpperName() - << ");"; - } - void writeCtorInitializers(raw_ostream &OS) const { - OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)"; - } - void writeCtorParameters(raw_ostream &OS) const { - OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName(); - } - void writeDeclarations(raw_ostream &OS) const { - OS << "bool is" << getLowerName() << "Expr;\n"; - OS << "union {\n"; - OS << "Expr *" << getLowerName() << "Expr;\n"; - OS << "TypeSourceInfo *" << getLowerName() << "Type;\n"; - OS << "};"; - } - void writePCHReadArgs(raw_ostream &OS) const { - OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr"; - } - void writePCHReadDecls(raw_ostream &OS) const { - OS << " bool is" << getLowerName() << "Expr = Record[Idx++];\n"; - OS << " void *" << getLowerName() << "Ptr;\n"; - OS << " if (is" << getLowerName() << "Expr)\n"; - OS << " " << getLowerName() << "Ptr = ReadExpr(F);\n"; - OS << " else\n"; - OS << " " << getLowerName() - << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n"; - } - void writePCHWrite(raw_ostream &OS) const { - OS << " Record.push_back(SA->is" << getUpperName() << "Expr());\n"; - OS << " if (SA->is" << getUpperName() << "Expr())\n"; - OS << " AddStmt(SA->get" << getUpperName() << "Expr());\n"; - OS << " else\n"; - OS << " AddTypeSourceInfo(SA->get" << getUpperName() - << "Type(), Record);\n"; - } - }; - - class VariadicArgument : public Argument { - std::string type; - - public: - VariadicArgument(Record &Arg, StringRef Attr, std::string T) - : Argument(Arg, Attr), type(T) - {} - - std::string getType() const { return type; } - - void writeAccessors(raw_ostream &OS) const { - OS << " typedef " << type << "* " << getLowerName() << "_iterator;\n"; - OS << " " << getLowerName() << "_iterator " << getLowerName() - << "_begin() const {\n"; - OS << " return " << getLowerName() << ";\n"; - OS << " }\n"; - OS << " " << getLowerName() << "_iterator " << getLowerName() - << "_end() const {\n"; - OS << " return " << getLowerName() << " + " << getLowerName() - << "Size;\n"; - OS << " }\n"; - OS << " unsigned " << getLowerName() << "_size() const {\n" - << " return " << getLowerName() << "Size;\n;"; - OS << " }"; - } - void writeCloneArgs(raw_ostream &OS) const { - OS << getLowerName() << ", " << getLowerName() << "Size"; - } - void writeCtorBody(raw_ostream &OS) const { - // FIXME: memcpy is not safe on non-trivial types. - OS << " std::memcpy(" << getLowerName() << ", " << getUpperName() - << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n"; - } - void writeCtorInitializers(raw_ostream &OS) const { - OS << getLowerName() << "Size(" << getUpperName() << "Size), " - << getLowerName() << "(new (Ctx, 16) " << getType() << "[" - << getLowerName() << "Size])"; - } - void writeCtorParameters(raw_ostream &OS) const { - OS << getType() << " *" << getUpperName() << ", unsigned " - << getUpperName() << "Size"; - } - void writeDeclarations(raw_ostream &OS) const { - OS << " unsigned " << getLowerName() << "Size;\n"; - OS << " " << getType() << " *" << getLowerName() << ";"; - } - void writePCHReadDecls(raw_ostream &OS) const { - OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n"; - OS << " llvm::SmallVector<" << type << ", 4> " << getLowerName() - << ";\n"; - OS << " " << getLowerName() << ".reserve(" << getLowerName() - << "Size);\n"; - OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n"; - - std::string read = ReadPCHRecord(type); - OS << " " << getLowerName() << ".push_back(" << read << ");\n"; - } - void writePCHReadArgs(raw_ostream &OS) const { - OS << getLowerName() << ".data(), " << getLowerName() << "Size"; - } - void writePCHWrite(raw_ostream &OS) const{ - OS << " Record.push_back(SA->" << getLowerName() << "_size());\n"; - OS << " for (" << getAttrName() << "Attr::" << getLowerName() - << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->" - << getLowerName() << "_end(); i != e; ++i)\n"; - OS << " " << WritePCHRecord(type, "(*i)"); - } - }; - - class EnumArgument : public Argument { - std::string type; - std::vector values, enums; - public: - EnumArgument(Record &Arg, StringRef Attr) - : Argument(Arg, Attr), type(Arg.getValueAsString("Type")), - values(getValueAsListOfStrings(Arg, "Values")), - enums(getValueAsListOfStrings(Arg, "Enums")) - {} - - void writeAccessors(raw_ostream &OS) const { - OS << " " << type << " get" << getUpperName() << "() const {\n"; - OS << " return " << getLowerName() << ";\n"; - OS << " }"; - } - void writeCloneArgs(raw_ostream &OS) const { - OS << getLowerName(); - } - void writeCtorInitializers(raw_ostream &OS) const { - OS << getLowerName() << "(" << getUpperName() << ")"; - } - void writeCtorParameters(raw_ostream &OS) const { - OS << type << " " << getUpperName(); - } - void writeDeclarations(raw_ostream &OS) const { - // Calculate the various enum values - std::vector uniques(enums); - std::sort(uniques.begin(), uniques.end()); - uniques.erase(std::unique(uniques.begin(), uniques.end()), - uniques.end()); - // FIXME: Emit a proper error - assert(!uniques.empty()); - - std::vector::iterator i = uniques.begin(), - e = uniques.end(); - // The last one needs to not have a comma. - --e; - - OS << "public:\n"; - OS << " enum " << type << " {\n"; - for (; i != e; ++i) - OS << " " << *i << ",\n"; - OS << " " << *e << "\n"; - OS << " };\n"; - OS << "private:\n"; - OS << " " << type << " " << getLowerName() << ";"; - } - void writePCHReadDecls(raw_ostream &OS) const { - OS << " " << getAttrName() << "Attr::" << type << " " << getLowerName() - << "(static_cast<" << getAttrName() << "Attr::" << type - << ">(Record[Idx++]));\n"; - } - void writePCHReadArgs(raw_ostream &OS) const { - OS << getLowerName(); - } - void writePCHWrite(raw_ostream &OS) const { - OS << "Record.push_back(SA->get" << getUpperName() << "());\n"; - } - }; - - class VersionArgument : public Argument { - public: - VersionArgument(Record &Arg, StringRef Attr) - : Argument(Arg, Attr) - {} - - void writeAccessors(raw_ostream &OS) const { - OS << " VersionTuple get" << getUpperName() << "() const {\n"; - OS << " return " << getLowerName() << ";\n"; - OS << " }\n"; - OS << " void set" << getUpperName() - << "(ASTContext &C, VersionTuple V) {\n"; - OS << " " << getLowerName() << " = V;\n"; - OS << " }"; - } - void writeCloneArgs(raw_ostream &OS) const { - OS << "get" << getUpperName() << "()"; - } - void writeCtorBody(raw_ostream &OS) const { - } - void writeCtorInitializers(raw_ostream &OS) const { - OS << getLowerName() << "(" << getUpperName() << ")"; - } - void writeCtorParameters(raw_ostream &OS) const { - OS << "VersionTuple " << getUpperName(); - } - void writeDeclarations(raw_ostream &OS) const { - OS << "VersionTuple " << getLowerName() << ";\n"; - } - void writePCHReadDecls(raw_ostream &OS) const { - OS << " VersionTuple " << getLowerName() - << "= ReadVersionTuple(Record, Idx);\n"; - } - void writePCHReadArgs(raw_ostream &OS) const { - OS << getLowerName(); - } - void writePCHWrite(raw_ostream &OS) const { - OS << " AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n"; - } - }; -} - -static Argument *createArgument(Record &Arg, StringRef Attr, - Record *Search = 0) { - if (!Search) - Search = &Arg; - - Argument *Ptr = 0; - llvm::StringRef ArgName = Search->getName(); - - if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr); - else if (ArgName == "EnumArgument") Ptr = new EnumArgument(Arg, Attr); - else if (ArgName == "ExprArgument") Ptr = new SimpleArgument(Arg, Attr, - "Expr *"); - else if (ArgName == "FunctionArgument") - Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *"); - else if (ArgName == "IdentifierArgument") - Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *"); - else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, - "bool"); - else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int"); - else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr); - else if (ArgName == "TypeArgument") - Ptr = new SimpleArgument(Arg, Attr, "QualType"); - else if (ArgName == "UnsignedArgument") - Ptr = new SimpleArgument(Arg, Attr, "unsigned"); - else if (ArgName == "VariadicUnsignedArgument") - Ptr = new VariadicArgument(Arg, Attr, "unsigned"); - else if (ArgName == "VersionArgument") - Ptr = new VersionArgument(Arg, Attr); - - if (!Ptr) { - std::vector Bases = Search->getSuperClasses(); - for (std::vector::iterator i = Bases.begin(), e = Bases.end(); - i != e; ++i) { - Ptr = createArgument(Arg, Attr, *i); - if (Ptr) - break; - } - } - return Ptr; -} - -void ClangAttrClassEmitter::run(raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; - OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n"; - OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n\n"; - - std::vector Attrs = Records.getAllDerivedDefinitions("Attr"); - - for (std::vector::iterator i = Attrs.begin(), e = Attrs.end(); - i != e; ++i) { - Record &R = **i; - const std::string &SuperName = R.getSuperClasses().back()->getName(); - - OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n"; - - std::vector ArgRecords = R.getValueAsListOfDefs("Args"); - std::vector Args; - std::vector::iterator ai, ae; - Args.reserve(ArgRecords.size()); - - for (std::vector::iterator ri = ArgRecords.begin(), - re = ArgRecords.end(); - ri != re; ++ri) { - Record &ArgRecord = **ri; - Argument *Arg = createArgument(ArgRecord, R.getName()); - assert(Arg); - Args.push_back(Arg); - - Arg->writeDeclarations(OS); - OS << "\n\n"; - } - - ae = Args.end(); - - OS << "\n public:\n"; - OS << " " << R.getName() << "Attr(SourceLocation L, ASTContext &Ctx\n"; - - for (ai = Args.begin(); ai != ae; ++ai) { - OS << " , "; - (*ai)->writeCtorParameters(OS); - OS << "\n"; - } - - OS << " )\n"; - OS << " : " << SuperName << "(attr::" << R.getName() << ", L)\n"; - - for (ai = Args.begin(); ai != ae; ++ai) { - OS << " , "; - (*ai)->writeCtorInitializers(OS); - OS << "\n"; - } - - OS << " {\n"; - - for (ai = Args.begin(); ai != ae; ++ai) { - (*ai)->writeCtorBody(OS); - OS << "\n"; - } - OS << " }\n\n"; - - OS << " virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n"; - - for (ai = Args.begin(); ai != ae; ++ai) { - (*ai)->writeAccessors(OS); - OS << "\n\n"; - } - - OS << R.getValueAsCode("AdditionalMembers"); - OS << "\n\n"; - - OS << " static bool classof(const Attr *A) { return A->getKind() == " - << "attr::" << R.getName() << "; }\n"; - OS << " static bool classof(const " << R.getName() - << "Attr *) { return true; }\n"; - OS << "};\n\n"; - } - - OS << "#endif\n"; -} - -void ClangAttrImplEmitter::run(raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; - - std::vector Attrs = Records.getAllDerivedDefinitions("Attr"); - std::vector::iterator i = Attrs.begin(), e = Attrs.end(), ri, re; - std::vector::iterator ai, ae; - - for (; i != e; ++i) { - Record &R = **i; - std::vector ArgRecords = R.getValueAsListOfDefs("Args"); - std::vector Args; - for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri) - Args.push_back(createArgument(**ri, R.getName())); - - for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) - (*ai)->writeAccessorDefinitions(OS); - - OS << R.getName() << "Attr *" << R.getName() - << "Attr::clone(ASTContext &C) const {\n"; - OS << " return new (C) " << R.getName() << "Attr(getLocation(), C"; - for (ai = Args.begin(); ai != ae; ++ai) { - OS << ", "; - (*ai)->writeCloneArgs(OS); - } - OS << ");\n}\n\n"; - } -} - -static void EmitAttrList(raw_ostream &OS, StringRef Class, - const std::vector &AttrList) { - std::vector::const_iterator i = AttrList.begin(), e = AttrList.end(); - - if (i != e) { - // Move the end iterator back to emit the last attribute. - for(--e; i != e; ++i) - OS << Class << "(" << (*i)->getName() << ")\n"; - - OS << "LAST_" << Class << "(" << (*i)->getName() << ")\n\n"; - } -} - -void ClangAttrListEmitter::run(raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; - - OS << "#ifndef LAST_ATTR\n"; - OS << "#define LAST_ATTR(NAME) ATTR(NAME)\n"; - OS << "#endif\n\n"; - - OS << "#ifndef INHERITABLE_ATTR\n"; - OS << "#define INHERITABLE_ATTR(NAME) ATTR(NAME)\n"; - OS << "#endif\n\n"; - - OS << "#ifndef LAST_INHERITABLE_ATTR\n"; - OS << "#define LAST_INHERITABLE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n"; - OS << "#endif\n\n"; - - OS << "#ifndef INHERITABLE_PARAM_ATTR\n"; - OS << "#define INHERITABLE_PARAM_ATTR(NAME) ATTR(NAME)\n"; - OS << "#endif\n\n"; - - OS << "#ifndef LAST_INHERITABLE_PARAM_ATTR\n"; - OS << "#define LAST_INHERITABLE_PARAM_ATTR(NAME)" - " INHERITABLE_PARAM_ATTR(NAME)\n"; - OS << "#endif\n\n"; - - Record *InhClass = Records.getClass("InheritableAttr"); - Record *InhParamClass = Records.getClass("InheritableParamAttr"); - std::vector Attrs = Records.getAllDerivedDefinitions("Attr"), - NonInhAttrs, InhAttrs, InhParamAttrs; - for (std::vector::iterator i = Attrs.begin(), e = Attrs.end(); - i != e; ++i) { - if ((*i)->isSubClassOf(InhParamClass)) - InhParamAttrs.push_back(*i); - else if ((*i)->isSubClassOf(InhClass)) - InhAttrs.push_back(*i); - else - NonInhAttrs.push_back(*i); - } - - EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs); - EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs); - EmitAttrList(OS, "ATTR", NonInhAttrs); - - OS << "#undef LAST_ATTR\n"; - OS << "#undef INHERITABLE_ATTR\n"; - OS << "#undef LAST_INHERITABLE_ATTR\n"; - OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n"; - OS << "#undef ATTR\n"; -} - -void ClangAttrPCHReadEmitter::run(raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; - - Record *InhClass = Records.getClass("InheritableAttr"); - std::vector Attrs = Records.getAllDerivedDefinitions("Attr"), - ArgRecords; - std::vector::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; - std::vector Args; - std::vector::iterator ri, re; - - OS << " switch (Kind) {\n"; - OS << " default:\n"; - OS << " assert(0 && \"Unknown attribute!\");\n"; - OS << " break;\n"; - for (; i != e; ++i) { - Record &R = **i; - OS << " case attr::" << R.getName() << ": {\n"; - if (R.isSubClassOf(InhClass)) - OS << " bool isInherited = Record[Idx++];\n"; - ArgRecords = R.getValueAsListOfDefs("Args"); - Args.clear(); - for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) { - Argument *A = createArgument(**ai, R.getName()); - Args.push_back(A); - A->writePCHReadDecls(OS); - } - OS << " New = new (*Context) " << R.getName() << "Attr(Loc, *Context"; - for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) { - OS << ", "; - (*ri)->writePCHReadArgs(OS); - } - OS << ");\n"; - if (R.isSubClassOf(InhClass)) - OS << " cast(New)->setInherited(isInherited);\n"; - OS << " break;\n"; - OS << " }\n"; - } - OS << " }\n"; -} - -void ClangAttrPCHWriteEmitter::run(raw_ostream &OS) { - Record *InhClass = Records.getClass("InheritableAttr"); - std::vector Attrs = Records.getAllDerivedDefinitions("Attr"), Args; - std::vector::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae; - - OS << " switch (A->getKind()) {\n"; - OS << " default:\n"; - OS << " llvm_unreachable(\"Unknown attribute kind!\");\n"; - OS << " break;\n"; - for (; i != e; ++i) { - Record &R = **i; - OS << " case attr::" << R.getName() << ": {\n"; - Args = R.getValueAsListOfDefs("Args"); - if (R.isSubClassOf(InhClass) || !Args.empty()) - OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName() - << "Attr>(A);\n"; - if (R.isSubClassOf(InhClass)) - OS << " Record.push_back(SA->isInherited());\n"; - for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai) - createArgument(**ai, R.getName())->writePCHWrite(OS); - OS << " break;\n"; - OS << " }\n"; - } - OS << " }\n"; -} - -void ClangAttrSpellingListEmitter::run(raw_ostream &OS) { - OS << "// This file is generated by TableGen. Do not edit.\n\n"; - - std::vector Attrs = Records.getAllDerivedDefinitions("Attr"); - - for (std::vector::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) { - Record &Attr = **I; - - std::vector Spellings = getValueAsListOfStrings(Attr, "Spellings"); - - for (std::vector::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) { - StringRef Spelling = *I; - OS << ".Case(\"" << Spelling << "\", true)\n"; - } - } - -} diff --git a/utils/TableGen/ClangAttrEmitter.h b/utils/TableGen/ClangAttrEmitter.h deleted file mode 100644 index af870098a842..000000000000 --- a/utils/TableGen/ClangAttrEmitter.h +++ /dev/null @@ -1,101 +0,0 @@ -//===- ClangAttrEmitter.h - Generate Clang attribute handling =-*- C++ -*--===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// These tablegen backends emit Clang attribute processing code -// -//===----------------------------------------------------------------------===// - -#ifndef CLANGATTR_EMITTER_H -#define CLANGATTR_EMITTER_H - -#include "TableGenBackend.h" - -namespace llvm { - -/// ClangAttrClassEmitter - class emits the class defintions for attributes for -/// clang. -class ClangAttrClassEmitter : public TableGenBackend { - RecordKeeper &Records; - - public: - explicit ClangAttrClassEmitter(RecordKeeper &R) - : Records(R) - {} - - void run(raw_ostream &OS); -}; - -/// ClangAttrImplEmitter - class emits the class method defintions for -/// attributes for clang. -class ClangAttrImplEmitter : public TableGenBackend { - RecordKeeper &Records; - - public: - explicit ClangAttrImplEmitter(RecordKeeper &R) - : Records(R) - {} - - void run(raw_ostream &OS); -}; - -/// ClangAttrListEmitter - class emits the enumeration list for attributes for -/// clang. -class ClangAttrListEmitter : public TableGenBackend { - RecordKeeper &Records; - - public: - explicit ClangAttrListEmitter(RecordKeeper &R) - : Records(R) - {} - - void run(raw_ostream &OS); -}; - -/// ClangAttrPCHReadEmitter - class emits the code to read an attribute from -/// a clang precompiled header. -class ClangAttrPCHReadEmitter : public TableGenBackend { - RecordKeeper &Records; - -public: - explicit ClangAttrPCHReadEmitter(RecordKeeper &R) - : Records(R) - {} - - void run(raw_ostream &OS); -}; - -/// ClangAttrPCHWriteEmitter - class emits the code to read an attribute from -/// a clang precompiled header. -class ClangAttrPCHWriteEmitter : public TableGenBackend { - RecordKeeper &Records; - -public: - explicit ClangAttrPCHWriteEmitter(RecordKeeper &R) - : Records(R) - {} - - void run(raw_ostream &OS); -}; - -/// ClangAttrSpellingListEmitter - class emits the list of spellings for attributes for -/// clang. -class ClangAttrSpellingListEmitter : public TableGenBackend { - RecordKeeper &Records; - - public: - explicit ClangAttrSpellingListEmitter(RecordKeeper &R) - : Records(R) - {} - - void run(raw_ostream &OS); -}; - -} - -#endif diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp deleted file mode 100644 index 0a48e75681fc..000000000000 --- a/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ /dev/null @@ -1,362 +0,0 @@ -//=- ClangDiagnosticsEmitter.cpp - Generate Clang diagnostics tables -*- C++ -*- -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// These tablegen backends emit Clang diagnostics tables. -// -//===----------------------------------------------------------------------===// - -#include "ClangDiagnosticsEmitter.h" -#include "Record.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Compiler.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/VectorExtras.h" -#include -#include -#include -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Diagnostic category computation code. -//===----------------------------------------------------------------------===// - -namespace { -class DiagGroupParentMap { - RecordKeeper &Records; - std::map > Mapping; -public: - DiagGroupParentMap(RecordKeeper &records) : Records(records) { - std::vector DiagGroups - = Records.getAllDerivedDefinitions("DiagGroup"); - for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) { - std::vector SubGroups = - DiagGroups[i]->getValueAsListOfDefs("SubGroups"); - for (unsigned j = 0, e = SubGroups.size(); j != e; ++j) - Mapping[SubGroups[j]].push_back(DiagGroups[i]); - } - } - - const std::vector &getParents(const Record *Group) { - return Mapping[Group]; - } -}; -} // end anonymous namespace. - - -static std::string -getCategoryFromDiagGroup(const Record *Group, - DiagGroupParentMap &DiagGroupParents) { - // If the DiagGroup has a category, return it. - std::string CatName = Group->getValueAsString("CategoryName"); - if (!CatName.empty()) return CatName; - - // The diag group may the subgroup of one or more other diagnostic groups, - // check these for a category as well. - const std::vector &Parents = DiagGroupParents.getParents(Group); - for (unsigned i = 0, e = Parents.size(); i != e; ++i) { - CatName = getCategoryFromDiagGroup(Parents[i], DiagGroupParents); - if (!CatName.empty()) return CatName; - } - return ""; -} - -/// getDiagnosticCategory - Return the category that the specified diagnostic -/// lives in. -static std::string getDiagnosticCategory(const Record *R, - DiagGroupParentMap &DiagGroupParents) { - // If the diagnostic is in a group, and that group has a category, use it. - if (DefInit *Group = dynamic_cast(R->getValueInit("Group"))) { - // Check the diagnostic's diag group for a category. - std::string CatName = getCategoryFromDiagGroup(Group->getDef(), - DiagGroupParents); - if (!CatName.empty()) return CatName; - } - - // If the diagnostic itself has a category, get it. - return R->getValueAsString("CategoryName"); -} - -namespace { - class DiagCategoryIDMap { - RecordKeeper &Records; - StringMap CategoryIDs; - std::vector CategoryStrings; - public: - DiagCategoryIDMap(RecordKeeper &records) : Records(records) { - DiagGroupParentMap ParentInfo(Records); - - // The zero'th category is "". - CategoryStrings.push_back(""); - CategoryIDs[""] = 0; - - std::vector Diags = - Records.getAllDerivedDefinitions("Diagnostic"); - for (unsigned i = 0, e = Diags.size(); i != e; ++i) { - std::string Category = getDiagnosticCategory(Diags[i], ParentInfo); - if (Category.empty()) continue; // Skip diags with no category. - - unsigned &ID = CategoryIDs[Category]; - if (ID != 0) continue; // Already seen. - - ID = CategoryStrings.size(); - CategoryStrings.push_back(Category); - } - } - - unsigned getID(StringRef CategoryString) { - return CategoryIDs[CategoryString]; - } - - typedef std::vector::iterator iterator; - iterator begin() { return CategoryStrings.begin(); } - iterator end() { return CategoryStrings.end(); } - }; -} // end anonymous namespace. - - -//===----------------------------------------------------------------------===// -// Warning Tables (.inc file) generation. -//===----------------------------------------------------------------------===// - -void ClangDiagsDefsEmitter::run(raw_ostream &OS) { - // Write the #if guard - if (!Component.empty()) { - std::string ComponentName = UppercaseString(Component); - OS << "#ifdef " << ComponentName << "START\n"; - OS << "__" << ComponentName << "START = DIAG_START_" << ComponentName - << ",\n"; - OS << "#undef " << ComponentName << "START\n"; - OS << "#endif\n\n"; - } - - const std::vector &Diags = - Records.getAllDerivedDefinitions("Diagnostic"); - - DiagCategoryIDMap CategoryIDs(Records); - DiagGroupParentMap DGParentMap(Records); - - for (unsigned i = 0, e = Diags.size(); i != e; ++i) { - const Record &R = *Diags[i]; - // Filter by component. - if (!Component.empty() && Component != R.getValueAsString("Component")) - continue; - - OS << "DIAG(" << R.getName() << ", "; - OS << R.getValueAsDef("Class")->getName(); - OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName(); - - // Description string. - OS << ", \""; - OS.write_escaped(R.getValueAsString("Text")) << '"'; - - // Warning associated with the diagnostic. - if (DefInit *DI = dynamic_cast(R.getValueInit("Group"))) { - OS << ", \""; - OS.write_escaped(DI->getDef()->getValueAsString("GroupName")) << '"'; - } else { - OS << ", \"\""; - } - - // SFINAE bit - if (R.getValueAsBit("SFINAE")) - OS << ", true"; - else - OS << ", false"; - - // Access control bit - if (R.getValueAsBit("AccessControl")) - OS << ", true"; - else - OS << ", false"; - - // Category number. - OS << ", " << CategoryIDs.getID(getDiagnosticCategory(&R, DGParentMap)); - - // Brief - OS << ", \""; - OS.write_escaped(R.getValueAsString("Brief")) << '"'; - - // Explanation - OS << ", \""; - OS.write_escaped(R.getValueAsString("Explanation")) << '"'; - OS << ")\n"; - } -} - -//===----------------------------------------------------------------------===// -// Warning Group Tables generation -//===----------------------------------------------------------------------===// - -static std::string getDiagCategoryEnum(llvm::StringRef name) { - if (name.empty()) - return "DiagCat_None"; - llvm::SmallString<256> enumName = llvm::StringRef("DiagCat_"); - for (llvm::StringRef::iterator I = name.begin(), E = name.end(); I != E; ++I) - enumName += isalnum(*I) ? *I : '_'; - return enumName.str(); -} - -namespace { -struct GroupInfo { - std::vector DiagsInGroup; - std::vector SubGroups; - unsigned IDNo; -}; -} // end anonymous namespace. - -void ClangDiagGroupsEmitter::run(raw_ostream &OS) { - // Compute a mapping from a DiagGroup to all of its parents. - DiagGroupParentMap DGParentMap(Records); - - // Invert the 1-[0/1] mapping of diags to group into a one to many mapping of - // groups to diags in the group. - std::map DiagsInGroup; - - std::vector Diags = - Records.getAllDerivedDefinitions("Diagnostic"); - for (unsigned i = 0, e = Diags.size(); i != e; ++i) { - const Record *R = Diags[i]; - DefInit *DI = dynamic_cast(R->getValueInit("Group")); - if (DI == 0) continue; - std::string GroupName = DI->getDef()->getValueAsString("GroupName"); - DiagsInGroup[GroupName].DiagsInGroup.push_back(R); - } - - // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty - // groups (these are warnings that GCC supports that clang never produces). - std::vector DiagGroups - = Records.getAllDerivedDefinitions("DiagGroup"); - for (unsigned i = 0, e = DiagGroups.size(); i != e; ++i) { - Record *Group = DiagGroups[i]; - GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")]; - - std::vector SubGroups = Group->getValueAsListOfDefs("SubGroups"); - for (unsigned j = 0, e = SubGroups.size(); j != e; ++j) - GI.SubGroups.push_back(SubGroups[j]->getValueAsString("GroupName")); - } - - // Assign unique ID numbers to the groups. - unsigned IDNo = 0; - for (std::map::iterator - I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I, ++IDNo) - I->second.IDNo = IDNo; - - // Walk through the groups emitting an array for each diagnostic of the diags - // that are mapped to. - OS << "\n#ifdef GET_DIAG_ARRAYS\n"; - unsigned MaxLen = 0; - for (std::map::iterator - I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { - MaxLen = std::max(MaxLen, (unsigned)I->first.size()); - - std::vector &V = I->second.DiagsInGroup; - if (!V.empty()) { - OS << "static const short DiagArray" << I->second.IDNo << "[] = { "; - for (unsigned i = 0, e = V.size(); i != e; ++i) - OS << "diag::" << V[i]->getName() << ", "; - OS << "-1 };\n"; - } - - const std::vector &SubGroups = I->second.SubGroups; - if (!SubGroups.empty()) { - OS << "static const short DiagSubGroup" << I->second.IDNo << "[] = { "; - for (unsigned i = 0, e = SubGroups.size(); i != e; ++i) { - std::map::iterator RI = - DiagsInGroup.find(SubGroups[i]); - assert(RI != DiagsInGroup.end() && "Referenced without existing?"); - OS << RI->second.IDNo << ", "; - } - OS << "-1 };\n"; - } - } - OS << "#endif // GET_DIAG_ARRAYS\n\n"; - - // Emit the table now. - OS << "\n#ifdef GET_DIAG_TABLE\n"; - for (std::map::iterator - I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) { - // Group option string. - OS << " { "; - OS << I->first.size() << ", "; - OS << "\""; - OS.write_escaped(I->first) << "\"," - << std::string(MaxLen-I->first.size()+1, ' '); - - // Diagnostics in the group. - if (I->second.DiagsInGroup.empty()) - OS << "0, "; - else - OS << "DiagArray" << I->second.IDNo << ", "; - - // Subgroups. - if (I->second.SubGroups.empty()) - OS << 0; - else - OS << "DiagSubGroup" << I->second.IDNo; - OS << " },\n"; - } - OS << "#endif // GET_DIAG_TABLE\n\n"; - - // Emit the category table next. - DiagCategoryIDMap CategoriesByID(Records); - OS << "\n#ifdef GET_CATEGORY_TABLE\n"; - for (DiagCategoryIDMap::iterator I = CategoriesByID.begin(), - E = CategoriesByID.end(); I != E; ++I) - OS << "CATEGORY(\"" << *I << "\", " << getDiagCategoryEnum(*I) << ")\n"; - OS << "#endif // GET_CATEGORY_TABLE\n\n"; -} - -//===----------------------------------------------------------------------===// -// Diagnostic name index generation -//===----------------------------------------------------------------------===// - -namespace { -struct RecordIndexElement -{ - RecordIndexElement() {} - explicit RecordIndexElement(Record const &R): - Name(R.getName()) {} - - std::string Name; -}; - -struct RecordIndexElementSorter : - public std::binary_function { - - bool operator()(RecordIndexElement const &Lhs, - RecordIndexElement const &Rhs) const { - return Lhs.Name < Rhs.Name; - } - -}; - -} // end anonymous namespace. - -void ClangDiagsIndexNameEmitter::run(raw_ostream &OS) { - const std::vector &Diags = - Records.getAllDerivedDefinitions("Diagnostic"); - - std::vector Index; - Index.reserve(Diags.size()); - for (unsigned i = 0, e = Diags.size(); i != e; ++i) { - const Record &R = *(Diags[i]); - Index.push_back(RecordIndexElement(R)); - } - - std::sort(Index.begin(), Index.end(), RecordIndexElementSorter()); - - for (unsigned i = 0, e = Index.size(); i != e; ++i) { - const RecordIndexElement &R = Index[i]; - - OS << "DIAG_NAME_INDEX(" << R.Name << ")\n"; - } -} diff --git a/utils/TableGen/ClangDiagnosticsEmitter.h b/utils/TableGen/ClangDiagnosticsEmitter.h deleted file mode 100644 index 1e4c8b70c26d..000000000000 --- a/utils/TableGen/ClangDiagnosticsEmitter.h +++ /dev/null @@ -1,54 +0,0 @@ -//===- ClangDiagnosticsEmitter.h - Generate Clang diagnostics tables -*- C++ -*- -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// These tablegen backends emit Clang diagnostics tables. -// -//===----------------------------------------------------------------------===// - -#ifndef CLANGDIAGS_EMITTER_H -#define CLANGDIAGS_EMITTER_H - -#include "TableGenBackend.h" - -namespace llvm { - -/// ClangDiagsDefsEmitter - The top-level class emits .def files containing -/// declarations of Clang diagnostics. -/// -class ClangDiagsDefsEmitter : public TableGenBackend { - RecordKeeper &Records; - const std::string& Component; -public: - explicit ClangDiagsDefsEmitter(RecordKeeper &R, const std::string& component) - : Records(R), Component(component) {} - - // run - Output the .def file contents - void run(raw_ostream &OS); -}; - -class ClangDiagGroupsEmitter : public TableGenBackend { - RecordKeeper &Records; -public: - explicit ClangDiagGroupsEmitter(RecordKeeper &R) : Records(R) {} - - void run(raw_ostream &OS); -}; - -class ClangDiagsIndexNameEmitter : public TableGenBackend { - RecordKeeper &Records; -public: - explicit ClangDiagsIndexNameEmitter(RecordKeeper &R) : Records(R) {} - - void run(raw_ostream &OS); -}; - - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp deleted file mode 100644 index 97739c6b3f4c..000000000000 --- a/utils/TableGen/ClangSACheckersEmitter.cpp +++ /dev/null @@ -1,319 +0,0 @@ -//=- ClangSACheckersEmitter.cpp - Generate Clang SA checkers tables -*- 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 emits Clang Static Analyzer checkers tables. -// -//===----------------------------------------------------------------------===// - -#include "ClangSACheckersEmitter.h" -#include "Record.h" -#include "llvm/ADT/DenseSet.h" -#include -#include -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Static Analyzer Checkers Tables generation -//===----------------------------------------------------------------------===// - -/// \brief True if it is specified hidden or a parent package is specified -/// as hidden, otherwise false. -static bool isHidden(const Record &R) { - if (R.getValueAsBit("Hidden")) - return true; - // Not declared as hidden, check the parent package if it is hidden. - if (DefInit *DI = dynamic_cast(R.getValueInit("ParentPackage"))) - return isHidden(*DI->getDef()); - - return false; -} - -static bool isCheckerNamed(const Record *R) { - return !R->getValueAsString("CheckerName").empty(); -} - -static std::string getPackageFullName(const Record *R); - -static std::string getParentPackageFullName(const Record *R) { - std::string name; - if (DefInit *DI = dynamic_cast(R->getValueInit("ParentPackage"))) - name = getPackageFullName(DI->getDef()); - return name; -} - -static std::string getPackageFullName(const Record *R) { - std::string name = getParentPackageFullName(R); - if (!name.empty()) name += "."; - return name + R->getValueAsString("PackageName"); -} - -static std::string getCheckerFullName(const Record *R) { - std::string name = getParentPackageFullName(R); - if (isCheckerNamed(R)) { - if (!name.empty()) name += "."; - name += R->getValueAsString("CheckerName"); - } - return name; -} - -static std::string getStringValue(const Record &R, StringRef field) { - if (StringInit * - SI = dynamic_cast(R.getValueInit(field))) - return SI->getValue(); - return std::string(); -} - -namespace { -struct GroupInfo { - llvm::DenseSet Checkers; - llvm::DenseSet SubGroups; - bool Hidden; - unsigned Index; - - GroupInfo() : Hidden(false) { } -}; -} - -static void addPackageToCheckerGroup(const Record *package, const Record *group, - llvm::DenseMap &recordGroupMap) { - llvm::DenseSet &checkers = recordGroupMap[package]->Checkers; - for (llvm::DenseSet::iterator - I = checkers.begin(), E = checkers.end(); I != E; ++I) - recordGroupMap[group]->Checkers.insert(*I); - - llvm::DenseSet &subGroups = recordGroupMap[package]->SubGroups; - for (llvm::DenseSet::iterator - I = subGroups.begin(), E = subGroups.end(); I != E; ++I) - addPackageToCheckerGroup(*I, group, recordGroupMap); -} - -void ClangSACheckersEmitter::run(raw_ostream &OS) { - std::vector checkers = Records.getAllDerivedDefinitions("Checker"); - llvm::DenseMap checkerRecIndexMap; - for (unsigned i = 0, e = checkers.size(); i != e; ++i) - checkerRecIndexMap[checkers[i]] = i; - - // Invert the mapping of checkers to package/group into a one to many - // mapping of packages/groups to checkers. - std::map groupInfoByName; - llvm::DenseMap recordGroupMap; - - std::vector packages = Records.getAllDerivedDefinitions("Package"); - for (unsigned i = 0, e = packages.size(); i != e; ++i) { - Record *R = packages[i]; - std::string fullName = getPackageFullName(R); - if (!fullName.empty()) { - GroupInfo &info = groupInfoByName[fullName]; - info.Hidden = isHidden(*R); - recordGroupMap[R] = &info; - } - } - - std::vector - checkerGroups = Records.getAllDerivedDefinitions("CheckerGroup"); - for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) { - Record *R = checkerGroups[i]; - std::string name = R->getValueAsString("GroupName"); - if (!name.empty()) { - GroupInfo &info = groupInfoByName[name]; - recordGroupMap[R] = &info; - } - } - - for (unsigned i = 0, e = checkers.size(); i != e; ++i) { - Record *R = checkers[i]; - Record *package = 0; - if (DefInit * - DI = dynamic_cast(R->getValueInit("ParentPackage"))) - package = DI->getDef(); - if (!isCheckerNamed(R) && !package) - throw "Checker '" + R->getName() + "' is neither named, nor in a package!"; - - if (isCheckerNamed(R)) { - // Create a pseudo-group to hold this checker. - std::string fullName = getCheckerFullName(R); - GroupInfo &info = groupInfoByName[fullName]; - info.Hidden = R->getValueAsBit("Hidden"); - recordGroupMap[R] = &info; - info.Checkers.insert(R); - } else { - recordGroupMap[package]->Checkers.insert(R); - } - - Record *currR = isCheckerNamed(R) ? R : package; - // Insert the checker and its parent packages into the subgroups set of - // the corresponding parent package. - while (DefInit *DI - = dynamic_cast(currR->getValueInit("ParentPackage"))) { - Record *parentPackage = DI->getDef(); - recordGroupMap[parentPackage]->SubGroups.insert(currR); - currR = parentPackage; - } - // Insert the checker into the set of its group. - if (DefInit *DI = dynamic_cast(R->getValueInit("Group"))) - recordGroupMap[DI->getDef()]->Checkers.insert(R); - } - - // If a package is in group, add all its checkers and its sub-packages - // checkers into the group. - for (unsigned i = 0, e = packages.size(); i != e; ++i) - if (DefInit *DI = dynamic_cast(packages[i]->getValueInit("Group"))) - addPackageToCheckerGroup(packages[i], DI->getDef(), recordGroupMap); - - typedef std::map SortedRecords; - typedef llvm::DenseMap RecToSortIndex; - - SortedRecords sortedGroups; - RecToSortIndex groupToSortIndex; - OS << "\n#ifdef GET_GROUPS\n"; - { - for (unsigned i = 0, e = checkerGroups.size(); i != e; ++i) - sortedGroups[checkerGroups[i]->getValueAsString("GroupName")] - = checkerGroups[i]; - - unsigned sortIndex = 0; - for (SortedRecords::iterator - I = sortedGroups.begin(), E = sortedGroups.end(); I != E; ++I) { - const Record *R = I->second; - - OS << "GROUP(" << "\""; - OS.write_escaped(R->getValueAsString("GroupName")) << "\""; - OS << ")\n"; - - groupToSortIndex[R] = sortIndex++; - } - } - OS << "#endif // GET_GROUPS\n\n"; - - OS << "\n#ifdef GET_PACKAGES\n"; - { - SortedRecords sortedPackages; - for (unsigned i = 0, e = packages.size(); i != e; ++i) - sortedPackages[getPackageFullName(packages[i])] = packages[i]; - - for (SortedRecords::iterator - I = sortedPackages.begin(), E = sortedPackages.end(); I != E; ++I) { - const Record &R = *I->second; - - OS << "PACKAGE(" << "\""; - OS.write_escaped(getPackageFullName(&R)) << "\", "; - // Group index - if (DefInit *DI = dynamic_cast(R.getValueInit("Group"))) - OS << groupToSortIndex[DI->getDef()] << ", "; - else - OS << "-1, "; - // Hidden bit - if (isHidden(R)) - OS << "true"; - else - OS << "false"; - OS << ")\n"; - } - } - OS << "#endif // GET_PACKAGES\n\n"; - - OS << "\n#ifdef GET_CHECKERS\n"; - for (unsigned i = 0, e = checkers.size(); i != e; ++i) { - const Record &R = *checkers[i]; - - OS << "CHECKER(" << "\""; - std::string name; - if (isCheckerNamed(&R)) - name = getCheckerFullName(&R); - OS.write_escaped(name) << "\", "; - OS << R.getName() << ", "; - OS << getStringValue(R, "DescFile") << ", "; - OS << "\""; - OS.write_escaped(getStringValue(R, "HelpText")) << "\", "; - // Group index - if (DefInit *DI = dynamic_cast(R.getValueInit("Group"))) - OS << groupToSortIndex[DI->getDef()] << ", "; - else - OS << "-1, "; - // Hidden bit - if (isHidden(R)) - OS << "true"; - else - OS << "false"; - OS << ")\n"; - } - OS << "#endif // GET_CHECKERS\n\n"; - - unsigned index = 0; - for (std::map::iterator - I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) - I->second.Index = index++; - - // Walk through the packages/groups/checkers emitting an array for each - // set of checkers and an array for each set of subpackages. - - OS << "\n#ifdef GET_MEMBER_ARRAYS\n"; - unsigned maxLen = 0; - for (std::map::iterator - I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) { - maxLen = std::max(maxLen, (unsigned)I->first.size()); - - llvm::DenseSet &checkers = I->second.Checkers; - if (!checkers.empty()) { - OS << "static const short CheckerArray" << I->second.Index << "[] = { "; - // Make the output order deterministic. - std::map sorted; - for (llvm::DenseSet::iterator - I = checkers.begin(), E = checkers.end(); I != E; ++I) - sorted[(*I)->getID()] = *I; - - for (std::map::iterator - I = sorted.begin(), E = sorted.end(); I != E; ++I) - OS << checkerRecIndexMap[I->second] << ", "; - OS << "-1 };\n"; - } - - llvm::DenseSet &subGroups = I->second.SubGroups; - if (!subGroups.empty()) { - OS << "static const short SubPackageArray" << I->second.Index << "[] = { "; - // Make the output order deterministic. - std::map sorted; - for (llvm::DenseSet::iterator - I = subGroups.begin(), E = subGroups.end(); I != E; ++I) - sorted[(*I)->getID()] = *I; - - for (std::map::iterator - I = sorted.begin(), E = sorted.end(); I != E; ++I) { - OS << recordGroupMap[I->second]->Index << ", "; - } - OS << "-1 };\n"; - } - } - OS << "#endif // GET_MEMBER_ARRAYS\n\n"; - - OS << "\n#ifdef GET_CHECKNAME_TABLE\n"; - for (std::map::iterator - I = groupInfoByName.begin(), E = groupInfoByName.end(); I != E; ++I) { - // Group option string. - OS << " { \""; - OS.write_escaped(I->first) << "\"," - << std::string(maxLen-I->first.size()+1, ' '); - - if (I->second.Checkers.empty()) - OS << "0, "; - else - OS << "CheckerArray" << I->second.Index << ", "; - - // Subgroups. - if (I->second.SubGroups.empty()) - OS << "0, "; - else - OS << "SubPackageArray" << I->second.Index << ", "; - - OS << (I->second.Hidden ? "true" : "false"); - - OS << " },\n"; - } - OS << "#endif // GET_CHECKNAME_TABLE\n\n"; -} diff --git a/utils/TableGen/ClangSACheckersEmitter.h b/utils/TableGen/ClangSACheckersEmitter.h deleted file mode 100644 index 6bd163547329..000000000000 --- a/utils/TableGen/ClangSACheckersEmitter.h +++ /dev/null @@ -1,31 +0,0 @@ -//===- ClangSACheckersEmitter.h - Generate Clang SA checkers tables -*- 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 emits Clang Static Analyzer checkers tables. -// -//===----------------------------------------------------------------------===// - -#ifndef CLANGSACHECKERS_EMITTER_H -#define CLANGSACHECKERS_EMITTER_H - -#include "TableGenBackend.h" - -namespace llvm { - -class ClangSACheckersEmitter : public TableGenBackend { - RecordKeeper &Records; -public: - explicit ClangSACheckersEmitter(RecordKeeper &R) : Records(R) {} - - void run(raw_ostream &OS); -}; - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp index d828dfc25db7..c5a152665b06 100644 --- a/utils/TableGen/CodeEmitterGen.cpp +++ b/utils/TableGen/CodeEmitterGen.cpp @@ -15,7 +15,7 @@ #include "CodeEmitterGen.h" #include "CodeGenTarget.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -41,19 +41,23 @@ void CodeEmitterGen::reverseBits(std::vector &Insts) { BitsInit *BI = R->getValueAsBitsInit("Inst"); unsigned numBits = BI->getNumBits(); - BitsInit *NewBI = new BitsInit(numBits); + + SmallVector NewBits(numBits); + for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) { unsigned bitSwapIdx = numBits - bit - 1; Init *OrigBit = BI->getBit(bit); Init *BitSwap = BI->getBit(bitSwapIdx); - NewBI->setBit(bit, BitSwap); - NewBI->setBit(bitSwapIdx, OrigBit); + NewBits[bit] = BitSwap; + NewBits[bitSwapIdx] = OrigBit; } if (numBits % 2) { unsigned middle = (numBits + 1) / 2; - NewBI->setBit(middle, BI->getBit(middle)); + NewBits[middle] = BI->getBit(middle); } + BitsInit *NewBI = BitsInit::get(NewBits); + // Update the bits in reversed order so that emitInstrOpBits will get the // correct endianness. R->getValue("Inst")->setValue(NewBI); diff --git a/utils/TableGen/CodeEmitterGen.h b/utils/TableGen/CodeEmitterGen.h index a874d970feac..7f6ee2a1b40f 100644 --- a/utils/TableGen/CodeEmitterGen.h +++ b/utils/TableGen/CodeEmitterGen.h @@ -14,7 +14,7 @@ #ifndef CODEMITTERGEN_H #define CODEMITTERGEN_H -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" #include #include diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index 072893fe5abd..dbf166262bb6 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/utils/TableGen/CodeGenDAGPatterns.cpp @@ -13,8 +13,8 @@ //===----------------------------------------------------------------------===// #include "CodeGenDAGPatterns.h" -#include "Error.h" -#include "Record.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Debug.h" @@ -1747,9 +1747,10 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ // TreePatternNode of its own. For example: /// (foo GPR, imm) -> (foo GPR, (imm)) if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag")) - return ParseTreePattern(new DagInit(DI, "", - std::vector >()), - OpName); + return ParseTreePattern( + DagInit::get(DI, "", + std::vector >()), + OpName); // Input argument? TreePatternNode *Res = new TreePatternNode(DI, 1); @@ -1771,7 +1772,7 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ if (BitsInit *BI = dynamic_cast(TheInit)) { // Turn this into an IntInit. - Init *II = BI->convertInitializerTo(new IntRecTy()); + Init *II = BI->convertInitializerTo(IntRecTy::get()); if (II == 0 || !dynamic_cast(II)) error("Bits value must be constants!"); return ParseTreePattern(II, OpName); @@ -1860,7 +1861,7 @@ TreePatternNode *TreePattern::ParseTreePattern(Init *TheInit, StringRef OpName){ else // Otherwise, no chain. Operator = getDAGPatterns().get_intrinsic_wo_chain_sdnode(); - TreePatternNode *IIDNode = new TreePatternNode(new IntInit(IID), 1); + TreePatternNode *IIDNode = new TreePatternNode(IntInit::get(IID), 1); Children.insert(Children.begin(), IIDNode); } @@ -2180,7 +2181,7 @@ void CodeGenDAGPatterns::ParseDefaultOperands() { // Find some SDNode. assert(!SDNodes.empty() && "No SDNodes parsed?"); - Init *SomeSDNode = new DefInit(SDNodes.begin()->first); + Init *SomeSDNode = DefInit::get(SDNodes.begin()->first); for (unsigned iter = 0; iter != 2; ++iter) { for (unsigned i = 0, e = DefaultOps[iter].size(); i != e; ++i) { @@ -2192,7 +2193,7 @@ void CodeGenDAGPatterns::ParseDefaultOperands() { for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op) Ops.push_back(std::make_pair(DefaultInfo->getArg(op), DefaultInfo->getArgName(op))); - DagInit *DI = new DagInit(SomeSDNode, "", Ops); + DagInit *DI = DagInit::get(SomeSDNode, "", Ops); // Create a TreePattern to parse this. TreePattern P(DefaultOps[iter][i], DI, false, *this); @@ -2828,6 +2829,12 @@ void CodeGenDAGPatterns::InferInstructionFlags() { InstInfo.isBitcast = IsBitcast; InstInfo.hasSideEffects = HasSideEffects; InstInfo.Operands.isVariadic = IsVariadic; + + // Sanity checks. + if (InstInfo.isReMaterializable && InstInfo.hasSideEffects) + throw TGError(InstInfo.TheDef->getLoc(), "The instruction " + + InstInfo.TheDef->getName() + + " is rematerializable AND has unmodeled side effects?"); } } diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index a52ce86c485a..53d499f39553 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -13,8 +13,8 @@ #include "CodeGenInstruction.h" #include "CodeGenTarget.h" -#include "Error.h" -#include "Record.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/STLExtras.h" @@ -267,8 +267,9 @@ static void ParseConstraints(const std::string &CStr, CGIOperandList &Ops) { void CGIOperandList::ProcessDisableEncoding(std::string DisableEncoding) { while (1) { - std::string OpName; - tie(OpName, DisableEncoding) = getToken(DisableEncoding, " ,\t"); + std::pair P = getToken(DisableEncoding, " ,\t"); + std::string OpName = P.first; + DisableEncoding = P.second; if (OpName.empty()) break; // Figure out which operand this is. @@ -308,6 +309,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R), Operands(R) { isReMaterializable = R->getValueAsBit("isReMaterializable"); hasDelaySlot = R->getValueAsBit("hasDelaySlot"); usesCustomInserter = R->getValueAsBit("usesCustomInserter"); + hasPostISelHook = R->getValueAsBit("hasPostISelHook"); hasCtrlDep = R->getValueAsBit("hasCtrlDep"); isNotDuplicable = R->getValueAsBit("isNotDuplicable"); hasSideEffects = R->getValueAsBit("hasSideEffects"); @@ -423,6 +425,13 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, // Handle explicit registers. if (ADI && ADI->getDef()->isSubClassOf("Register")) { + if (InstOpRec->isSubClassOf("OptionalDefOperand")) { + DagInit *DI = InstOpRec->getValueAsDag("MIOperandInfo"); + // The operand info should only have a single (register) entry. We + // want the register class of it. + InstOpRec = dynamic_cast(DI->getArg(0))->getDef(); + } + if (InstOpRec->isSubClassOf("RegisterOperand")) InstOpRec = InstOpRec->getValueAsDef("RegClass"); @@ -431,8 +440,8 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo, if (!T.getRegisterClass(InstOpRec) .contains(T.getRegBank().getReg(ADI->getDef()))) - throw TGError(Loc, "fixed register " +ADI->getDef()->getName() - + " is not a member of the " + InstOpRec->getName() + + throw TGError(Loc, "fixed register " + ADI->getDef()->getName() + + " is not a member of the " + InstOpRec->getName() + " register class!"); if (!Result->getArgName(AliasOpNo).empty()) diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index 8d7669aca98c..468277aa96c2 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -233,6 +233,7 @@ namespace llvm { bool isReMaterializable; bool hasDelaySlot; bool usesCustomInserter; + bool hasPostISelHook; bool hasCtrlDep; bool isNotDuplicable; bool hasSideEffects; diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 1acf3a85b600..8de461527955 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -14,8 +14,9 @@ #include "CodeGenRegisters.h" #include "CodeGenTarget.h" -#include "Error.h" +#include "llvm/TableGen/Error.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; @@ -182,8 +183,8 @@ struct TupleExpander : SetTheory::Expander { // Precompute some types. Record *RegisterCl = Def->getRecords().getClass("Register"); - RecTy *RegisterRecTy = new RecordRecTy(RegisterCl); - StringInit *BlankName = new StringInit(""); + RecTy *RegisterRecTy = RecordRecTy::get(RegisterCl); + StringInit *BlankName = StringInit::get(""); // Zip them up. for (unsigned n = 0; n != Length; ++n) { @@ -195,7 +196,7 @@ struct TupleExpander : SetTheory::Expander { Record *Reg = Lists[i][n]; if (i) Name += '_'; Name += Reg->getName(); - Tuple.push_back(new DefInit(Reg)); + Tuple.push_back(DefInit::get(Reg)); CostPerUse = std::max(CostPerUse, unsigned(Reg->getValueAsInt("CostPerUse"))); } @@ -216,7 +217,7 @@ struct TupleExpander : SetTheory::Expander { // Replace the sub-register list with Tuple. if (RV.getName() == "SubRegs") - RV.setValue(new ListInit(Tuple, RegisterRecTy)); + RV.setValue(ListInit::get(Tuple, RegisterRecTy)); // Provide a blank AsmName. MC hacks are required anyway. if (RV.getName() == "AsmName") @@ -224,7 +225,7 @@ struct TupleExpander : SetTheory::Expander { // CostPerUse is aggregated from all Tuple members. if (RV.getName() == "CostPerUse") - RV.setValue(new IntInit(CostPerUse)); + RV.setValue(IntInit::get(CostPerUse)); // Copy fields from the RegisterTuples def. if (RV.getName() == "SubRegIndices" || @@ -255,7 +256,7 @@ struct TupleExpander : SetTheory::Expander { //===----------------------------------------------------------------------===// CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) - : TheDef(R) { + : TheDef(R), Name(R->getName()), EnumValue(-1) { // Rename anonymous register classes. if (R->getName().size() > 9 && R->getName()[9] == '.') { static unsigned AnonCounter = 0; @@ -272,18 +273,22 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) } assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!"); + // Allocation order 0 is the full set. AltOrders provides others. + const SetTheory::RecVec *Elements = RegBank.getSets().expand(R); + ListInit *AltOrders = R->getValueAsListInit("AltOrders"); + Orders.resize(1 + AltOrders->size()); + // Default allocation order always contains all registers. - Elements = RegBank.getSets().expand(R); - for (unsigned i = 0, e = Elements->size(); i != e; ++i) + for (unsigned i = 0, e = Elements->size(); i != e; ++i) { + Orders[0].push_back((*Elements)[i]); Members.insert(RegBank.getReg((*Elements)[i])); + } // Alternative allocation orders may be subsets. - ListInit *Alts = R->getValueAsListInit("AltOrders"); - AltOrders.resize(Alts->size()); SetTheory::RecSet Order; - for (unsigned i = 0, e = Alts->size(); i != e; ++i) { - RegBank.getSets().evaluate(Alts->getElement(i), Order); - AltOrders[i].append(Order.begin(), Order.end()); + for (unsigned i = 0, e = AltOrders->size(); i != e; ++i) { + RegBank.getSets().evaluate(AltOrders->getElement(i), Order); + Orders[1 + i].append(Order.begin(), Order.end()); // Verify that all altorder members are regclass members. while (!Order.empty()) { CodeGenRegister *Reg = RegBank.getReg(Order.back()); @@ -328,10 +333,71 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) AltOrderSelect = R->getValueAsCode("AltOrderSelect"); } +// Create an inferred register class that was missing from the .td files. +// Most properties will be inherited from the closest super-class after the +// class structure has been computed. +CodeGenRegisterClass::CodeGenRegisterClass(StringRef Name, Key Props) + : Members(*Props.Members), + TheDef(0), + Name(Name), + EnumValue(-1), + SpillSize(Props.SpillSize), + SpillAlignment(Props.SpillAlignment), + CopyCost(0), + Allocatable(true) { +} + +// Compute inherited propertied for a synthesized register class. +void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) { + assert(!getDef() && "Only synthesized classes can inherit properties"); + assert(!SuperClasses.empty() && "Synthesized class without super class"); + + // The last super-class is the smallest one. + CodeGenRegisterClass &Super = *SuperClasses.back(); + + // Most properties are copied directly. + // Exceptions are members, size, and alignment + Namespace = Super.Namespace; + VTs = Super.VTs; + CopyCost = Super.CopyCost; + Allocatable = Super.Allocatable; + AltOrderSelect = Super.AltOrderSelect; + + // Copy all allocation orders, filter out foreign registers from the larger + // super-class. + Orders.resize(Super.Orders.size()); + for (unsigned i = 0, ie = Super.Orders.size(); i != ie; ++i) + for (unsigned j = 0, je = Super.Orders[i].size(); j != je; ++j) + if (contains(RegBank.getReg(Super.Orders[i][j]))) + Orders[i].push_back(Super.Orders[i][j]); +} + bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const { return Members.count(Reg); } +namespace llvm { + raw_ostream &operator<<(raw_ostream &OS, const CodeGenRegisterClass::Key &K) { + OS << "{ S=" << K.SpillSize << ", A=" << K.SpillAlignment; + for (CodeGenRegister::Set::const_iterator I = K.Members->begin(), + E = K.Members->end(); I != E; ++I) + OS << ", " << (*I)->getName(); + return OS << " }"; + } +} + +// This is a simple lexicographical order that can be used to search for sets. +// It is not the same as the topological order provided by TopoOrderRC. +bool CodeGenRegisterClass::Key:: +operator<(const CodeGenRegisterClass::Key &B) const { + assert(Members && B.Members); + if (*Members != *B.Members) + return *Members < *B.Members; + if (SpillSize != B.SpillSize) + return SpillSize < B.SpillSize; + return SpillAlignment < B.SpillAlignment; +} + // Returns true if RC is a strict subclass. // RC is a sub-class of this class if it is a valid replacement for any // instruction operand where a register of this classis required. It must @@ -341,16 +407,101 @@ bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const { // 2. The RC spill size must not be smaller than our spill size. // 3. RC spill alignment must be compatible with ours. // -bool CodeGenRegisterClass::hasSubClass(const CodeGenRegisterClass *RC) const { - return SpillAlignment && RC->SpillAlignment % SpillAlignment == 0 && - SpillSize <= RC->SpillSize && - std::includes(Members.begin(), Members.end(), - RC->Members.begin(), RC->Members.end(), +static bool testSubClass(const CodeGenRegisterClass *A, + const CodeGenRegisterClass *B) { + return A->SpillAlignment && B->SpillAlignment % A->SpillAlignment == 0 && + A->SpillSize <= B->SpillSize && + std::includes(A->getMembers().begin(), A->getMembers().end(), + B->getMembers().begin(), B->getMembers().end(), CodeGenRegister::Less()); } -const std::string &CodeGenRegisterClass::getName() const { - return TheDef->getName(); +/// Sorting predicate for register classes. This provides a topological +/// ordering that arranges all register classes before their sub-classes. +/// +/// Register classes with the same registers, spill size, and alignment form a +/// clique. They will be ordered alphabetically. +/// +static int TopoOrderRC(const void *PA, const void *PB) { + const CodeGenRegisterClass *A = *(const CodeGenRegisterClass* const*)PA; + const CodeGenRegisterClass *B = *(const CodeGenRegisterClass* const*)PB; + if (A == B) + return 0; + + // Order by descending set size. Note that the classes' allocation order may + // not have been computed yet. The Members set is always vaild. + if (A->getMembers().size() > B->getMembers().size()) + return -1; + if (A->getMembers().size() < B->getMembers().size()) + return 1; + + // Order by ascending spill size. + if (A->SpillSize < B->SpillSize) + return -1; + if (A->SpillSize > B->SpillSize) + return 1; + + // Order by ascending spill alignment. + if (A->SpillAlignment < B->SpillAlignment) + return -1; + if (A->SpillAlignment > B->SpillAlignment) + return 1; + + // Finally order by name as a tie breaker. + return A->getName() < B->getName(); +} + +std::string CodeGenRegisterClass::getQualifiedName() const { + if (Namespace.empty()) + return getName(); + else + return Namespace + "::" + getName(); +} + +// Compute sub-classes of all register classes. +// Assume the classes are ordered topologically. +void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) { + ArrayRef RegClasses = RegBank.getRegClasses(); + + // Visit backwards so sub-classes are seen first. + for (unsigned rci = RegClasses.size(); rci; --rci) { + CodeGenRegisterClass &RC = *RegClasses[rci - 1]; + RC.SubClasses.resize(RegClasses.size()); + RC.SubClasses.set(RC.EnumValue); + + // Normally, all subclasses have IDs >= rci, unless RC is part of a clique. + for (unsigned s = rci; s != RegClasses.size(); ++s) { + if (RC.SubClasses.test(s)) + continue; + CodeGenRegisterClass *SubRC = RegClasses[s]; + if (!testSubClass(&RC, SubRC)) + continue; + // SubRC is a sub-class. Grap all its sub-classes so we won't have to + // check them again. + RC.SubClasses |= SubRC->SubClasses; + } + + // Sweep up missed clique members. They will be immediately preceeding RC. + for (unsigned s = rci - 1; s && testSubClass(&RC, RegClasses[s - 1]); --s) + RC.SubClasses.set(s - 1); + } + + // Compute the SuperClasses lists from the SubClasses vectors. + for (unsigned rci = 0; rci != RegClasses.size(); ++rci) { + const BitVector &SC = RegClasses[rci]->getSubClasses(); + for (int s = SC.find_first(); s >= 0; s = SC.find_next(s)) { + if (unsigned(s) == rci) + continue; + RegClasses[s]->SuperClasses.push_back(RegClasses[rci]); + } + } + + // With the class hierarchy in place, let synthesized register classes inherit + // properties from their closest super-class. The iteration order here can + // propagate properties down multiple levels. + for (unsigned rci = 0; rci != RegClasses.size(); ++rci) + if (!RegClasses[rci]->getDef()) + RegClasses[rci]->inheritProperties(RegBank); } //===----------------------------------------------------------------------===// @@ -385,14 +536,29 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) { getReg((*TupRegs)[j]); } + // Precompute all sub-register maps now all the registers are known. + // This will create Composite entries for all inferred sub-register indices. + for (unsigned i = 0, e = Registers.size(); i != e; ++i) + Registers[i]->getSubRegs(*this); + // Read in register class definitions. std::vector RCs = Records.getAllDerivedDefinitions("RegisterClass"); if (RCs.empty()) throw std::string("No 'RegisterClass' subclasses defined!"); + // Allocate user-defined register classes. RegClasses.reserve(RCs.size()); for (unsigned i = 0, e = RCs.size(); i != e; ++i) - RegClasses.push_back(CodeGenRegisterClass(*this, RCs[i])); + addToMaps(new CodeGenRegisterClass(*this, RCs[i])); + + // Infer missing classes to create a full algebra. + computeInferredRegisterClasses(); + + // Order register classes topologically and assign enum values. + array_pod_sort(RegClasses.begin(), RegClasses.end(), TopoOrderRC); + for (unsigned i = 0, e = RegClasses.size(); i != e; ++i) + RegClasses[i]->EnumValue = i; + CodeGenRegisterClass::computeSubClasses(*this); } CodeGenRegister *CodeGenRegBank::getReg(Record *Def) { @@ -404,11 +570,19 @@ CodeGenRegister *CodeGenRegBank::getReg(Record *Def) { return Reg; } -CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) { - if (Def2RC.empty()) - for (unsigned i = 0, e = RegClasses.size(); i != e; ++i) - Def2RC[RegClasses[i].TheDef] = &RegClasses[i]; +void CodeGenRegBank::addToMaps(CodeGenRegisterClass *RC) { + RegClasses.push_back(RC); + if (Record *Def = RC->getDef()) + Def2RC.insert(std::make_pair(Def, RC)); + + // Duplicate classes are rejected by insert(). + // That's OK, we only care about the properties handled by CGRC::Key. + CodeGenRegisterClass::Key K(*RC); + Key2RC.insert(std::make_pair(K, RC)); +} + +CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) { if (CodeGenRegisterClass *RC = Def2RC[Def]) return RC; @@ -425,7 +599,6 @@ Record *CodeGenRegBank::getCompositeSubRegIndex(Record *A, Record *B, // None exists, synthesize one. std::string Name = A->getName() + "_then_" + B->getName(); Comp = new Record(Name, SMLoc(), Records); - Records.addDef(Comp); SubRegIndices.push_back(Comp); return Comp; } @@ -438,11 +611,6 @@ unsigned CodeGenRegBank::getSubRegIndexNo(Record *idx) { } void CodeGenRegBank::computeComposites() { - // Precompute all sub-register maps. This will create Composite entries for - // all inferred sub-register indices. - for (unsigned i = 0, e = Registers.size(); i != e; ++i) - Registers[i]->getSubRegs(*this); - for (unsigned i = 0, e = Registers.size(); i != e; ++i) { CodeGenRegister *Reg1 = Registers[i]; const CodeGenRegister::SubRegMap &SRM1 = Reg1->getSubRegs(); @@ -571,6 +739,64 @@ void CodeGenRegBank::computeDerivedInfo() { computeComposites(); } +// Infer missing register classes. +// +// For every register class RC, make sure that the set of registers in RC with +// a given SubIxx sub-register form a register class. +void CodeGenRegBank::computeInferredRegisterClasses() { + // When this function is called, the register classes have not been sorted + // and assigned EnumValues yet. That means getSubClasses(), + // getSuperClasses(), and hasSubClass() functions are defunct. + + // Map SubRegIndex to register set. + typedef std::map SubReg2SetMap; + + // Visit all register classes, including the ones being added by the loop. + for (unsigned rci = 0; rci != RegClasses.size(); ++rci) { + CodeGenRegisterClass &RC = *RegClasses[rci]; + + // Compute the set of registers supporting each SubRegIndex. + SubReg2SetMap SRSets; + for (CodeGenRegister::Set::const_iterator RI = RC.getMembers().begin(), + RE = RC.getMembers().end(); RI != RE; ++RI) { + const CodeGenRegister::SubRegMap &SRM = (*RI)->getSubRegs(); + for (CodeGenRegister::SubRegMap::const_iterator I = SRM.begin(), + E = SRM.end(); I != E; ++I) + SRSets[I->first].insert(*RI); + } + + // Find matching classes for all SRSets entries. Iterate in SubRegIndex + // numerical order to visit synthetic indices last. + for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) { + Record *SubIdx = SubRegIndices[sri]; + SubReg2SetMap::const_iterator I = SRSets.find(SubIdx); + // Unsupported SubRegIndex. Skip it. + if (I == SRSets.end()) + continue; + // In most cases, all RC registers support the SubRegIndex. + if (I->second.size() == RC.getMembers().size()) { + RC.setSubClassWithSubReg(SubIdx, &RC); + continue; + } + + // This is a real subset. See if we have a matching class. + CodeGenRegisterClass::Key K(&I->second, RC.SpillSize, RC.SpillAlignment); + RCKeyMap::const_iterator FoundI = Key2RC.find(K); + if (FoundI != Key2RC.end()) { + RC.setSubClassWithSubReg(SubIdx, FoundI->second); + continue; + } + + // Class doesn't exist. + CodeGenRegisterClass *NewRC = + new CodeGenRegisterClass(RC.getName() + "_with_" + + I->first->getName(), K); + addToMaps(NewRC); + RC.setSubClassWithSubReg(SubIdx, NewRC); + } + } +} + /// getRegisterClassForRegister - Find the register class that contains the /// specified physical register. If the register is not in a register class, /// return null. If the register is in multiple classes, and the classes have a @@ -579,10 +805,10 @@ void CodeGenRegBank::computeDerivedInfo() { const CodeGenRegisterClass* CodeGenRegBank::getRegClassForRegister(Record *R) { const CodeGenRegister *Reg = getReg(R); - const std::vector &RCs = getRegClasses(); + ArrayRef RCs = getRegClasses(); const CodeGenRegisterClass *FoundRC = 0; for (unsigned i = 0, e = RCs.size(); i != e; ++i) { - const CodeGenRegisterClass &RC = RCs[i]; + const CodeGenRegisterClass &RC = *RCs[i]; if (!RC.contains(Reg)) continue; diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 5edbf475659b..4fc34b092260 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -15,10 +15,11 @@ #ifndef CODEGEN_REGISTERS_H #define CODEGEN_REGISTERS_H -#include "Record.h" #include "SetTheory.h" +#include "llvm/TableGen/Record.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SetVector.h" #include @@ -69,6 +70,7 @@ namespace llvm { struct Less { bool operator()(const CodeGenRegister *A, const CodeGenRegister *B) const { + assert(A && B); return A->EnumValue < B->EnumValue; } }; @@ -85,10 +87,25 @@ namespace llvm { class CodeGenRegisterClass { CodeGenRegister::Set Members; - const std::vector *Elements; - std::vector > AltOrders; - public: + // Allocation orders. Order[0] always contains all registers in Members. + std::vector > Orders; + // Bit mask of sub-classes including this, indexed by their EnumValue. + BitVector SubClasses; + // List of super-classes, topologocally ordered to have the larger classes + // first. This is the same as sorting by EnumValue. + SmallVector SuperClasses; Record *TheDef; + std::string Name; + + // For a synthesized class, inherit missing properties from the nearest + // super-class. + void inheritProperties(CodeGenRegBank&); + + // Map SubRegIndex -> sub-class + DenseMap SubClassWithSubReg; + + public: + unsigned EnumValue; std::string Namespace; std::vector VTs; unsigned SpillSize; @@ -99,7 +116,12 @@ namespace llvm { DenseMap SubRegClasses; std::string AltOrderSelect; - const std::string &getName() const; + // Return the Record that defined this class, or NULL if the class was + // created by TableGen. + Record *getDef() const { return TheDef; } + + const std::string &getName() const { return Name; } + std::string getQualifiedName() const; const std::vector &getValueTypes() const {return VTs;} unsigned getNumValueTypes() const { return VTs.size(); } @@ -122,22 +144,77 @@ namespace llvm { // 2. The RC spill size must not be smaller than our spill size. // 3. RC spill alignment must be compatible with ours. // - bool hasSubClass(const CodeGenRegisterClass *RC) const; + bool hasSubClass(const CodeGenRegisterClass *RC) const { + return SubClasses.test(RC->EnumValue); + } + + // getSubClassWithSubReg - Returns the largest sub-class where all + // registers have a SubIdx sub-register. + CodeGenRegisterClass *getSubClassWithSubReg(Record *SubIdx) const { + return SubClassWithSubReg.lookup(SubIdx); + } + + void setSubClassWithSubReg(Record *SubIdx, CodeGenRegisterClass *SubRC) { + SubClassWithSubReg[SubIdx] = SubRC; + } + + // getSubClasses - Returns a constant BitVector of subclasses indexed by + // EnumValue. + // The SubClasses vector includs an entry for this class. + const BitVector &getSubClasses() const { return SubClasses; } + + // getSuperClasses - Returns a list of super classes ordered by EnumValue. + // The array does not include an entry for this class. + ArrayRef getSuperClasses() const { + return SuperClasses; + } // Returns an ordered list of class members. // The order of registers is the same as in the .td file. // No = 0 is the default allocation order, No = 1 is the first alternative. ArrayRef getOrder(unsigned No = 0) const { - if (No == 0) - return *Elements; - else - return AltOrders[No - 1]; + return Orders[No]; } // Return the total number of allocation orders available. - unsigned getNumOrders() const { return 1 + AltOrders.size(); } + unsigned getNumOrders() const { return Orders.size(); } + + // Get the set of registers. This set contains the same registers as + // getOrder(0). + const CodeGenRegister::Set &getMembers() const { return Members; } CodeGenRegisterClass(CodeGenRegBank&, Record *R); + + // A key representing the parts of a register class used for forming + // sub-classes. Note the ordering provided by this key is not the same as + // the topological order used for the EnumValues. + struct Key { + const CodeGenRegister::Set *Members; + unsigned SpillSize; + unsigned SpillAlignment; + + Key(const Key &O) + : Members(O.Members), + SpillSize(O.SpillSize), + SpillAlignment(O.SpillAlignment) {} + + Key(const CodeGenRegister::Set *M, unsigned S = 0, unsigned A = 0) + : Members(M), SpillSize(S), SpillAlignment(A) {} + + Key(const CodeGenRegisterClass &RC) + : Members(&RC.getMembers()), + SpillSize(RC.SpillSize), + SpillAlignment(RC.SpillAlignment) {} + + // Lexicographical order of (Members, SpillSize, SpillAlignment). + bool operator<(const Key&) const; + }; + + // Create a non-user defined register class. + CodeGenRegisterClass(StringRef Name, Key Props); + + // Called by CodeGenRegBank::CodeGenRegBank(). + static void computeSubClasses(CodeGenRegBank&); }; // CodeGenRegBank - Represent a target's registers and the relations between @@ -151,8 +228,17 @@ namespace llvm { std::vector Registers; DenseMap Def2Reg; - std::vector RegClasses; + // Register classes. + std::vector RegClasses; DenseMap Def2RC; + typedef std::map RCKeyMap; + RCKeyMap Key2RC; + + // Add RC to *2RC maps. + void addToMaps(CodeGenRegisterClass*); + + // Infer missing register classes. + void computeInferredRegisterClasses(); // Composite SubRegIndex instances. // Map (SubRegIndex, SubRegIndex) -> SubRegIndex. @@ -184,7 +270,7 @@ namespace llvm { // Find a register from its Record def. CodeGenRegister *getReg(Record*); - const std::vector &getRegClasses() { + ArrayRef getRegClasses() const { return RegClasses; } diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 929791c3182a..4a7bad7e6d85 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -16,7 +16,7 @@ #include "CodeGenTarget.h" #include "CodeGenIntrinsics.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/CommandLine.h" @@ -184,9 +184,9 @@ std::vector CodeGenTarget:: getRegisterVTs(Record *R) const { const CodeGenRegister *Reg = getRegBank().getReg(R); std::vector Result; - const std::vector &RCs = getRegisterClasses(); + ArrayRef RCs = getRegBank().getRegClasses(); for (unsigned i = 0, e = RCs.size(); i != e; ++i) { - const CodeGenRegisterClass &RC = RCs[i]; + const CodeGenRegisterClass &RC = *RCs[i]; if (RC.contains(Reg)) { const std::vector &InVTs = RC.getValueTypes(); Result.insert(Result.end(), InVTs.begin(), InVTs.end()); @@ -201,10 +201,10 @@ getRegisterVTs(Record *R) const { void CodeGenTarget::ReadLegalValueTypes() const { - const std::vector &RCs = getRegisterClasses(); + ArrayRef RCs = getRegBank().getRegClasses(); for (unsigned i = 0, e = RCs.size(); i != e; ++i) - for (unsigned ri = 0, re = RCs[i].VTs.size(); ri != re; ++ri) - LegalValueTypes.push_back(RCs[i].VTs[ri]); + for (unsigned ri = 0, re = RCs[i]->VTs.size(); ri != re; ++ri) + LegalValueTypes.push_back(RCs[i]->VTs[ri]); // Remove duplicates. std::sort(LegalValueTypes.begin(), LegalValueTypes.end()); diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h index 143daedae837..730216c331b4 100644 --- a/utils/TableGen/CodeGenTarget.h +++ b/utils/TableGen/CodeGenTarget.h @@ -19,7 +19,7 @@ #include "CodeGenRegisters.h" #include "CodeGenInstruction.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/Support/raw_ostream.h" #include @@ -107,10 +107,6 @@ class CodeGenTarget { return RegAltNameIndices; } - const std::vector &getRegisterClasses() const { - return getRegBank().getRegClasses(); - } - const CodeGenRegisterClass &getRegisterClass(Record *R) const { return *getRegBank().getRegClass(R); } diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index d66ae96cbc97..7db90034999f 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -13,7 +13,7 @@ #include "DAGISelEmitter.h" #include "DAGISelMatcher.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/Support/Debug.h" using namespace llvm; diff --git a/utils/TableGen/DAGISelEmitter.h b/utils/TableGen/DAGISelEmitter.h index 35ab55034308..9c9fe4273fed 100644 --- a/utils/TableGen/DAGISelEmitter.h +++ b/utils/TableGen/DAGISelEmitter.h @@ -14,7 +14,7 @@ #ifndef DAGISEL_EMITTER_H #define DAGISEL_EMITTER_H -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" #include "CodeGenDAGPatterns.h" namespace llvm { diff --git a/utils/TableGen/DAGISelMatcher.cpp b/utils/TableGen/DAGISelMatcher.cpp index b12e1015c33b..1367e8dd6e86 100644 --- a/utils/TableGen/DAGISelMatcher.cpp +++ b/utils/TableGen/DAGISelMatcher.cpp @@ -10,7 +10,7 @@ #include "DAGISelMatcher.h" #include "CodeGenDAGPatterns.h" #include "CodeGenTarget.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp index acb0135422e8..3b65b2a6de0c 100644 --- a/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -13,7 +13,7 @@ #include "DAGISelMatcher.h" #include "CodeGenDAGPatterns.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp index c5897c72d365..49ad956f8866 100644 --- a/utils/TableGen/DAGISelMatcherGen.cpp +++ b/utils/TableGen/DAGISelMatcherGen.cpp @@ -10,7 +10,7 @@ #include "DAGISelMatcher.h" #include "CodeGenDAGPatterns.h" #include "CodeGenRegisters.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" @@ -26,10 +26,10 @@ static MVT::SimpleValueType getRegisterValueType(Record *R, bool FoundRC = false; MVT::SimpleValueType VT = MVT::Other; const CodeGenRegister *Reg = T.getRegBank().getReg(R); - const std::vector &RCs = T.getRegisterClasses(); + ArrayRef RCs = T.getRegBank().getRegClasses(); for (unsigned rc = 0, e = RCs.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = RCs[rc]; + const CodeGenRegisterClass &RC = *RCs[rc]; if (!RC.contains(Reg)) continue; diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp index 07313d19e874..ff314e9c4f2f 100644 --- a/utils/TableGen/DisassemblerEmitter.cpp +++ b/utils/TableGen/DisassemblerEmitter.cpp @@ -9,12 +9,12 @@ #include "DisassemblerEmitter.h" #include "CodeGenTarget.h" -#include "Error.h" -#include "Record.h" #include "X86DisassemblerTables.h" #include "X86RecognizableInstr.h" #include "ARMDecoderEmitter.h" #include "FixedLenDecoderEmitter.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" using namespace llvm; using namespace llvm::X86Disassembler; @@ -128,12 +128,16 @@ void DisassemblerEmitter::run(raw_ostream &OS) { return; } - // Fixed-instruction-length targets use a common disassembler. - // ARM use its own implementation for now. - if (Target.getName() == "ARM") { - ARMDecoderEmitter(Records).run(OS); + // ARM and Thumb have a CHECK() macro to deal with DecodeStatuses. + if (Target.getName() == "ARM" || + Target.getName() == "Thumb") { + FixedLenDecoderEmitter(Records, + "ARM", + "if (!Check(S, ", ")) return MCDisassembler::Fail;", + "S", "MCDisassembler::Fail", + " MCDisassembler::DecodeStatus S = MCDisassembler::Success;\n(void)S;").run(OS); return; - } + } - FixedLenDecoderEmitter(Records).run(OS); + FixedLenDecoderEmitter(Records, Target.getName()).run(OS); } diff --git a/utils/TableGen/DisassemblerEmitter.h b/utils/TableGen/DisassemblerEmitter.h index 7229d81649ee..63ee55264ad8 100644 --- a/utils/TableGen/DisassemblerEmitter.h +++ b/utils/TableGen/DisassemblerEmitter.h @@ -10,7 +10,7 @@ #ifndef DISASSEMBLEREMITTER_H #define DISASSEMBLEREMITTER_H -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" namespace llvm { diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index 2f9814aee484..abef70e31897 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -17,8 +17,8 @@ #include "AsmWriterInst.h" #include "CodeGenTarget.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/MC/EDInstInfo.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" @@ -256,12 +256,15 @@ static int X86TypeFromOpName(LiteralConstantEmitter *type, REG("GR8"); REG("GR8_NOREX"); REG("GR16"); + REG("GR16_NOAX"); REG("GR32"); + REG("GR32_NOAX"); REG("GR32_NOREX"); REG("GR32_TC"); REG("FR32"); REG("RFP32"); REG("GR64"); + REG("GR64_NOAX"); REG("GR64_TC"); REG("FR64"); REG("VR64"); @@ -279,6 +282,7 @@ static int X86TypeFromOpName(LiteralConstantEmitter *type, IMM("i16i8imm"); IMM("i32imm"); IMM("i32i8imm"); + IMM("u32u8imm"); IMM("i64imm"); IMM("i64i8imm"); IMM("i64i32imm"); @@ -554,6 +558,8 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, const std::string &name) { REG("GPR"); REG("rGPR"); + REG("GPRnopc"); + REG("GPRsp"); REG("tcGPR"); REG("cc_out"); REG("s_cc_out"); @@ -575,6 +581,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("nohash_imm"); IMM("p_imm"); IMM("c_imm"); + IMM("coproc_option_imm"); IMM("imod_op"); IMM("iflags_op"); IMM("cpinst_operand"); @@ -587,26 +594,40 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("neg_zero"); IMM("imm0_31"); IMM("imm0_31_m1"); + IMM("imm1_16"); + IMM("imm1_32"); IMM("nModImm"); IMM("imm0_7"); IMM("imm0_15"); IMM("imm0_255"); IMM("imm0_4095"); IMM("imm0_65535"); + IMM("imm0_65535_expr"); + IMM("imm24b"); + IMM("pkh_lsl_amt"); + IMM("pkh_asr_amt"); IMM("jt2block_operand"); - IMM("t_imm_s4"); + IMM("t_imm0_1020s4"); + IMM("t_imm0_508s4"); IMM("pclabel"); IMM("adrlabel"); IMM("t_adrlabel"); IMM("t2adrlabel"); IMM("shift_imm"); - IMM("ssat_imm"); + IMM("t2_shift_imm"); IMM("neon_vcvt_imm32"); IMM("shr_imm8"); IMM("shr_imm16"); IMM("shr_imm32"); IMM("shr_imm64"); IMM("t2ldrlabel"); + IMM("postidx_imm8"); + IMM("postidx_imm8s4"); + IMM("imm_sr"); + IMM("imm1_31"); + IMM("VectorIndex8"); + IMM("VectorIndex16"); + IMM("VectorIndex32"); MISC("brtarget", "kOperandTypeARMBranchTarget"); // ? MISC("uncondbrtarget", "kOperandTypeARMBranchTarget"); // ? @@ -617,11 +638,14 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, MISC("br_target", "kOperandTypeARMBranchTarget"); // ? MISC("bl_target", "kOperandTypeARMBranchTarget"); // ? + MISC("blx_target", "kOperandTypeARMBranchTarget"); // ? MISC("t_bltarget", "kOperandTypeARMBranchTarget"); // ? MISC("t_blxtarget", "kOperandTypeARMBranchTarget"); // ? - MISC("so_reg", "kOperandTypeARMSoReg"); // R, R, I - MISC("shift_so_reg", "kOperandTypeARMSoReg"); // R, R, I + MISC("so_reg_imm", "kOperandTypeARMSoRegReg"); // R, R, I + MISC("so_reg_reg", "kOperandTypeARMSoRegImm"); // R, R, I + MISC("shift_so_reg_reg", "kOperandTypeARMSoRegReg"); // R, R, I + MISC("shift_so_reg_imm", "kOperandTypeARMSoRegImm"); // R, R, I MISC("t2_so_reg", "kOperandTypeThumb2SoReg"); // R, I MISC("so_imm", "kOperandTypeARMSoImm"); // I MISC("rot_imm", "kOperandTypeARMRotImm"); // I @@ -631,8 +655,10 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, MISC("it_pred", "kOperandTypeARMPredicate"); // I MISC("addrmode_imm12", "kOperandTypeAddrModeImm12"); // R, I MISC("ldst_so_reg", "kOperandTypeLdStSOReg"); // R, R, I + MISC("postidx_reg", "kOperandTypeARMAddrMode3Offset"); // R, I MISC("addrmode2", "kOperandTypeARMAddrMode2"); // R, R, I - MISC("am2offset", "kOperandTypeARMAddrMode2Offset"); // R, I + MISC("am2offset_reg", "kOperandTypeARMAddrMode2Offset"); // R, I + MISC("am2offset_imm", "kOperandTypeARMAddrMode2Offset"); // R, I MISC("addrmode3", "kOperandTypeARMAddrMode3"); // R, R, I MISC("am3offset", "kOperandTypeARMAddrMode3Offset"); // R, I MISC("ldstm_mode", "kOperandTypeARMLdStmMode"); // I @@ -642,17 +668,20 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, MISC("addrmode6dup", "kOperandTypeARMAddrMode6"); // R, R, I, I MISC("addrmode6oneL32", "kOperandTypeARMAddrMode6"); // R, R, I, I MISC("addrmodepc", "kOperandTypeARMAddrModePC"); // R, I - MISC("addrmode7", "kOperandTypeARMAddrMode7"); // R + MISC("addr_offset_none", "kOperandTypeARMAddrMode7"); // R MISC("reglist", "kOperandTypeARMRegisterList"); // I, R, ... MISC("dpr_reglist", "kOperandTypeARMDPRRegisterList"); // I, R, ... MISC("spr_reglist", "kOperandTypeARMSPRRegisterList"); // I, R, ... MISC("it_mask", "kOperandTypeThumbITMask"); // I MISC("t2addrmode_reg", "kOperandTypeThumb2AddrModeReg"); // R + MISC("t2addrmode_posimm8", "kOperandTypeThumb2AddrModeImm8"); // R, I + MISC("t2addrmode_negimm8", "kOperandTypeThumb2AddrModeImm8"); // R, I MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8"); // R, I MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I MISC("t2addrmode_imm12", "kOperandTypeThumb2AddrModeImm12"); // R, I MISC("t2addrmode_so_reg", "kOperandTypeThumb2AddrModeSoReg"); // R, R, I MISC("t2addrmode_imm8s4", "kOperandTypeThumb2AddrModeImm8s4"); // R, I + MISC("t2addrmode_imm0_1020s4", "kOperandTypeThumb2AddrModeImm8s4"); // R, I MISC("t2am_imm8s4_offset", "kOperandTypeThumb2AddrModeImm8s4Offset"); // R, I MISC("tb_addrmode", "kOperandTypeARMTBAddrMode"); // I @@ -665,6 +694,8 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, MISC("t_addrmode_rr", "kOperandTypeThumbAddrModeRR"); // R, R MISC("t_addrmode_sp", "kOperandTypeThumbAddrModeSP"); // R, I MISC("t_addrmode_pc", "kOperandTypeThumbAddrModePC"); // R, I + MISC("addrmode_tbb", "kOperandTypeThumbAddrModeRR"); // R, R + MISC("addrmode_tbh", "kOperandTypeThumbAddrModeRR"); // R, R return 1; } @@ -772,11 +803,6 @@ static void populateInstInfo(CompoundConstantEmitter &infoArray, for (index = 0; index < numInstructions; ++index) { const CodeGenInstruction& inst = *numberedInstructions[index]; - // We don't need to do anything for pseudo-instructions, as we'll never - // see them here. We'll only see real instructions. - if (inst.isPseudo) - continue; - CompoundConstantEmitter *infoStruct = new CompoundConstantEmitter; infoArray.addEntry(infoStruct); @@ -809,15 +835,20 @@ static void populateInstInfo(CompoundConstantEmitter &infoArray, unsigned numSyntaxes = 0; - if (target.getName() == "X86") { - X86PopulateOperands(operandTypes, inst); - X86ExtractSemantics(*instType, operandFlags, inst); - numSyntaxes = 2; - } - else if (target.getName() == "ARM") { - ARMPopulateOperands(operandTypes, inst); - ARMExtractSemantics(*instType, operandTypes, operandFlags, inst); - numSyntaxes = 1; + // We don't need to do anything for pseudo-instructions, as we'll never + // see them here. We'll only see real instructions. + // We still need to emit null initializers for everything. + if (!inst.isPseudo) { + if (target.getName() == "X86") { + X86PopulateOperands(operandTypes, inst); + X86ExtractSemantics(*instType, operandFlags, inst); + numSyntaxes = 2; + } + else if (target.getName() == "ARM") { + ARMPopulateOperands(operandTypes, inst); + ARMExtractSemantics(*instType, operandTypes, operandFlags, inst); + numSyntaxes = 1; + } } CompoundConstantEmitter *operandOrderArray = new CompoundConstantEmitter; @@ -850,7 +881,8 @@ static void emitCommonEnums(raw_ostream &o, unsigned int &i) { operandTypes.addEntry("kOperandTypeX86EffectiveAddress"); operandTypes.addEntry("kOperandTypeX86PCRelative"); operandTypes.addEntry("kOperandTypeARMBranchTarget"); - operandTypes.addEntry("kOperandTypeARMSoReg"); + operandTypes.addEntry("kOperandTypeARMSoRegReg"); + operandTypes.addEntry("kOperandTypeARMSoRegImm"); operandTypes.addEntry("kOperandTypeARMSoImm"); operandTypes.addEntry("kOperandTypeARMRotImm"); operandTypes.addEntry("kOperandTypeARMSoImm2Part"); diff --git a/utils/TableGen/EDEmitter.h b/utils/TableGen/EDEmitter.h index e30373fed2eb..f26837554722 100644 --- a/utils/TableGen/EDEmitter.h +++ b/utils/TableGen/EDEmitter.h @@ -16,7 +16,7 @@ #ifndef SEMANTIC_INFO_EMITTER_H #define SEMANTIC_INFO_EMITTER_H -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" namespace llvm { diff --git a/utils/TableGen/FastISelEmitter.cpp b/utils/TableGen/FastISelEmitter.cpp index f54e8df40f2d..9fdc2e33a546 100644 --- a/utils/TableGen/FastISelEmitter.cpp +++ b/utils/TableGen/FastISelEmitter.cpp @@ -18,8 +18,8 @@ //===----------------------------------------------------------------------===// #include "FastISelEmitter.h" -#include "Error.h" -#include "Record.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/VectorExtras.h" #include "llvm/Support/Debug.h" @@ -504,7 +504,7 @@ void FastISelMap::collectPatterns(CodeGenDAGPatterns &CGP) { std::vector* PhysRegInputs = new std::vector(); if (InstPatNode->getOperator()->getName() == "imm" || - InstPatNode->getOperator()->getName() == "fpimmm") + InstPatNode->getOperator()->getName() == "fpimm") PhysRegInputs->push_back(""); else { // Compute the PhysRegs used by the given pattern, and check that diff --git a/utils/TableGen/FastISelEmitter.h b/utils/TableGen/FastISelEmitter.h index ce4e77e6f8f2..4f75ac1fd9d2 100644 --- a/utils/TableGen/FastISelEmitter.h +++ b/utils/TableGen/FastISelEmitter.h @@ -14,8 +14,8 @@ #ifndef FASTISEL_EMITTER_H #define FASTISEL_EMITTER_H -#include "TableGenBackend.h" #include "CodeGenDAGPatterns.h" +#include "llvm/TableGen/TableGenBackend.h" namespace llvm { diff --git a/utils/TableGen/FixedLenDecoderEmitter.cpp b/utils/TableGen/FixedLenDecoderEmitter.cpp index c9dcb01de008..02b966a21431 100644 --- a/utils/TableGen/FixedLenDecoderEmitter.cpp +++ b/utils/TableGen/FixedLenDecoderEmitter.cpp @@ -16,7 +16,7 @@ #include "FixedLenDecoderEmitter.h" #include "CodeGenTarget.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -84,11 +84,8 @@ static BitsInit &getBitsField(const Record &def, const char *str) { // Forward declaration. class FilterChooser; -// FIXME: Possibly auto-detected? -#define BIT_WIDTH 32 - // Representation of the instruction to work on. -typedef bit_value_t insn_t[BIT_WIDTH]; +typedef std::vector insn_t; /// Filter - Filter works with FilterChooser to produce the decoding tree for /// the ISA. @@ -230,7 +227,7 @@ class FilterChooser { // Array of bit values passed down from our parent. // Set to all BIT_UNFILTERED's for Parent == NULL. - bit_value_t FilterBitValues[BIT_WIDTH]; + std::vector FilterBitValues; // Links to the FilterChooser above us in the decoding tree. FilterChooser *Parent; @@ -238,21 +235,29 @@ class FilterChooser { // Index of the best filter from Filters. int BestIndex; + // Width of instructions + unsigned BitWidth; + + // Parent emitter + const FixedLenDecoderEmitter *Emitter; + public: FilterChooser(const FilterChooser &FC) : AllInstructions(FC.AllInstructions), Opcodes(FC.Opcodes), - Operands(FC.Operands), Filters(FC.Filters), Parent(FC.Parent), - BestIndex(FC.BestIndex) { - memcpy(FilterBitValues, FC.FilterBitValues, sizeof(FilterBitValues)); - } + Operands(FC.Operands), Filters(FC.Filters), + FilterBitValues(FC.FilterBitValues), Parent(FC.Parent), + BestIndex(FC.BestIndex), BitWidth(FC.BitWidth), + Emitter(FC.Emitter) { } FilterChooser(const std::vector &Insts, const std::vector &IDs, - std::map > &Ops) : + std::map > &Ops, + unsigned BW, + const FixedLenDecoderEmitter *E) : AllInstructions(Insts), Opcodes(IDs), Operands(Ops), Filters(), - Parent(NULL), BestIndex(-1) { - for (unsigned i = 0; i < BIT_WIDTH; ++i) - FilterBitValues[i] = BIT_UNFILTERED; + Parent(NULL), BestIndex(-1), BitWidth(BW), Emitter(E) { + for (unsigned i = 0; i < BitWidth; ++i) + FilterBitValues.push_back(BIT_UNFILTERED); doFilter(); } @@ -260,13 +265,12 @@ class FilterChooser { FilterChooser(const std::vector &Insts, const std::vector &IDs, std::map > &Ops, - bit_value_t (&ParentFilterBitValues)[BIT_WIDTH], + std::vector &ParentFilterBitValues, FilterChooser &parent) : AllInstructions(Insts), Opcodes(IDs), Operands(Ops), - Filters(), Parent(&parent), BestIndex(-1) { - for (unsigned i = 0; i < BIT_WIDTH; ++i) - FilterBitValues[i] = ParentFilterBitValues[i]; - + Filters(), FilterBitValues(ParentFilterBitValues), + Parent(&parent), BestIndex(-1), BitWidth(parent.BitWidth), + Emitter(parent.Emitter) { doFilter(); } @@ -274,15 +278,15 @@ class FilterChooser { bool isTopLevel() { return Parent == NULL; } // Emit the top level typedef and decodeInstruction() function. - void emitTop(raw_ostream &o, unsigned Indentation); + void emitTop(raw_ostream &o, unsigned Indentation, std::string Namespace); protected: // Populates the insn given the uid. void insnWithID(insn_t &Insn, unsigned Opcode) const { BitsInit &Bits = getBitsField(*AllInstructions[Opcode]->TheDef, "Inst"); - for (unsigned i = 0; i < BIT_WIDTH; ++i) - Insn[i] = bitFromBits(Bits, i); + for (unsigned i = 0; i < BitWidth; ++i) + Insn.push_back(bitFromBits(Bits, i)); } // Returns the record name. @@ -300,7 +304,7 @@ class FilterChooser { /// dumpFilterArray - dumpFilterArray prints out debugging info for the given /// filter array as a series of chars. - void dumpFilterArray(raw_ostream &o, bit_value_t (&filter)[BIT_WIDTH]); + void dumpFilterArray(raw_ostream &o, std::vector & filter); /// dumpStack - dumpStack traverses the filter chooser chain and calls /// dumpFilterArray on each filter chooser up to the top level one. @@ -326,6 +330,10 @@ class FilterChooser { std::vector &EndBits, std::vector &FieldVals, insn_t &Insn); + // Emits code to check the Predicates member of an instruction are true. + // Returns true if predicate matches were emitted, false otherwise. + bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,unsigned Opc); + // Emits code to decode the singleton. Return true if we have matched all the // well-known bits. bool emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,unsigned Opc); @@ -333,6 +341,9 @@ class FilterChooser { // Emits code to decode the singleton, and then to decode the rest. void emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,Filter &Best); + void emitBinaryParser(raw_ostream &o , unsigned &Indentation, + OperandInfo &OpInfo); + // Assign a single filter and run with it. void runSingleFilter(FilterChooser &owner, unsigned startBit, unsigned numBit, bool mixed); @@ -375,7 +386,7 @@ Filter::Filter(const Filter &f) : Filter::Filter(FilterChooser &owner, unsigned startBit, unsigned numBits, bool mixed) : Owner(&owner), StartBit(startBit), NumBits(numBits), Mixed(mixed) { - assert(StartBit + NumBits - 1 < BIT_WIDTH); + assert(StartBit + NumBits - 1 < Owner->BitWidth); NumFiltered = 0; LastOpcFiltered = 0; @@ -427,9 +438,8 @@ Filter::~Filter() { void Filter::recurse() { std::map >::const_iterator mapIterator; - bit_value_t BitValueArray[BIT_WIDTH]; // Starts by inheriting our parent filter chooser's filter bit values. - memcpy(BitValueArray, Owner->FilterBitValues, sizeof(BitValueArray)); + std::vector BitValueArray(Owner->FilterBitValues); unsigned bitIndex; @@ -493,8 +503,9 @@ void Filter::emit(raw_ostream &o, unsigned &Indentation) { o << StartBit << "} ...\n"; - o.indent(Indentation) << "switch (fieldFromInstruction(insn, " - << StartBit << ", " << NumBits << ")) {\n"; + o.indent(Indentation) << "switch (fieldFromInstruction" << Owner->BitWidth + << "(insn, " << StartBit << ", " + << NumBits << ")) {\n"; std::map::iterator filterIterator; @@ -559,68 +570,21 @@ unsigned Filter::usefulness() const { ////////////////////////////////// // Emit the top level typedef and decodeInstruction() function. -void FilterChooser::emitTop(raw_ostream &o, unsigned Indentation) { - switch (BIT_WIDTH) { - case 8: - o.indent(Indentation) << "typedef uint8_t field_t;\n"; - break; - case 16: - o.indent(Indentation) << "typedef uint16_t field_t;\n"; - break; - case 32: - o.indent(Indentation) << "typedef uint32_t field_t;\n"; - break; - case 64: - o.indent(Indentation) << "typedef uint64_t field_t;\n"; - break; - default: - assert(0 && "Unexpected instruction size!"); - } - - o << '\n'; - - o.indent(Indentation) << "static field_t " << - "fieldFromInstruction(field_t insn, unsigned startBit, unsigned numBits)\n"; - - o.indent(Indentation) << "{\n"; - - ++Indentation; ++Indentation; - o.indent(Indentation) << "assert(startBit + numBits <= " << BIT_WIDTH - << " && \"Instruction field out of bounds!\");\n"; - o << '\n'; - o.indent(Indentation) << "field_t fieldMask;\n"; - o << '\n'; - o.indent(Indentation) << "if (numBits == " << BIT_WIDTH << ")\n"; - - ++Indentation; ++Indentation; - o.indent(Indentation) << "fieldMask = (field_t)-1;\n"; - --Indentation; --Indentation; - - o.indent(Indentation) << "else\n"; - - ++Indentation; ++Indentation; - o.indent(Indentation) << "fieldMask = ((1 << numBits) - 1) << startBit;\n"; - --Indentation; --Indentation; - - o << '\n'; - o.indent(Indentation) << "return (insn & fieldMask) >> startBit;\n"; - --Indentation; --Indentation; - - o.indent(Indentation) << "}\n"; - - o << '\n'; - +void FilterChooser::emitTop(raw_ostream &o, unsigned Indentation, + std::string Namespace) { o.indent(Indentation) << - "static bool decodeInstruction(MCInst &MI, field_t insn, " - "uint64_t Address, const void *Decoder) {\n"; - o.indent(Indentation) << " unsigned tmp = 0;\n"; + "static MCDisassembler::DecodeStatus decode" << Namespace << "Instruction" << BitWidth + << "(MCInst &MI, uint" << BitWidth << "_t insn, uint64_t Address, " + << "const void *Decoder, const MCSubtargetInfo &STI) {\n"; + o.indent(Indentation) << " unsigned tmp = 0;\n (void)tmp;\n" << Emitter->Locals << "\n"; + o.indent(Indentation) << " uint64_t Bits = STI.getFeatureBits();\n"; ++Indentation; ++Indentation; // Emits code to decode the instructions. emit(o, Indentation); o << '\n'; - o.indent(Indentation) << "return false;\n"; + o.indent(Indentation) << "return " << Emitter->ReturnFail << ";\n"; --Indentation; --Indentation; o.indent(Indentation) << "}\n"; @@ -651,10 +615,10 @@ bool FilterChooser::fieldFromInsn(uint64_t &Field, insn_t &Insn, /// dumpFilterArray - dumpFilterArray prints out debugging info for the given /// filter array as a series of chars. void FilterChooser::dumpFilterArray(raw_ostream &o, - bit_value_t (&filter)[BIT_WIDTH]) { + std::vector &filter) { unsigned bitIndex; - for (bitIndex = BIT_WIDTH; bitIndex > 0; bitIndex--) { + for (bitIndex = BitWidth; bitIndex > 0; bitIndex--) { switch (filter[bitIndex - 1]) { case BIT_UNFILTERED: o << "."; @@ -727,7 +691,7 @@ unsigned FilterChooser::getIslands(std::vector &StartBits, int State = 0; int Val = -1; - for (unsigned i = 0; i < BIT_WIDTH; ++i) { + for (unsigned i = 0; i < BitWidth; ++i) { Val = Value(Insn[i]); bool Filtered = PositionFiltered(i); switch (State) { @@ -761,7 +725,7 @@ unsigned FilterChooser::getIslands(std::vector &StartBits, } // If we are still in Island after the loop, do some housekeeping. if (State == 2) { - EndBits.push_back(BIT_WIDTH - 1); + EndBits.push_back(BitWidth - 1); FieldVals.push_back(FieldVal); ++Num; } @@ -771,6 +735,70 @@ unsigned FilterChooser::getIslands(std::vector &StartBits, return Num; } +void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation, + OperandInfo &OpInfo) { + std::string &Decoder = OpInfo.Decoder; + + if (OpInfo.numFields() == 1) { + OperandInfo::iterator OI = OpInfo.begin(); + o.indent(Indentation) << " tmp = fieldFromInstruction" << BitWidth + << "(insn, " << OI->Base << ", " << OI->Width + << ");\n"; + } else { + o.indent(Indentation) << " tmp = 0;\n"; + for (OperandInfo::iterator OI = OpInfo.begin(), OE = OpInfo.end(); + OI != OE; ++OI) { + o.indent(Indentation) << " tmp |= (fieldFromInstruction" << BitWidth + << "(insn, " << OI->Base << ", " << OI->Width + << ") << " << OI->Offset << ");\n"; + } + } + + if (Decoder != "") + o.indent(Indentation) << " " << Emitter->GuardPrefix << Decoder + << "(MI, tmp, Address, Decoder)" << Emitter->GuardPostfix << "\n"; + else + o.indent(Indentation) << " MI.addOperand(MCOperand::CreateImm(tmp));\n"; + +} + +static void emitSinglePredicateMatch(raw_ostream &o, StringRef str, + std::string PredicateNamespace) { + if (str[0] == '!') + o << "!(Bits & " << PredicateNamespace << "::" + << str.slice(1,str.size()) << ")"; + else + o << "(Bits & " << PredicateNamespace << "::" << str << ")"; +} + +bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation, + unsigned Opc) { + ListInit *Predicates = AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates"); + for (unsigned i = 0; i < Predicates->getSize(); ++i) { + Record *Pred = Predicates->getElementAsRecord(i); + if (!Pred->getValue("AssemblerMatcherPredicate")) + continue; + + std::string P = Pred->getValueAsString("AssemblerCondString"); + + if (!P.length()) + continue; + + if (i != 0) + o << " && "; + + StringRef SR(P); + std::pair pairs = SR.split(','); + while (pairs.second.size()) { + emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); + o << " && "; + pairs = pairs.second.split(','); + } + emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace); + } + return Predicates->getSize() > 0; +} + // Emits code to decode the singleton. Return true if we have matched all the // well-known bits. bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, @@ -789,33 +817,27 @@ bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, // If we have matched all the well-known bits, just issue a return. if (Size == 0) { - o.indent(Indentation) << "{\n"; + o.indent(Indentation) << "if ("; + if (!emitPredicateMatch(o, Indentation, Opc)) + o << "1"; + o << ") {\n"; o.indent(Indentation) << " MI.setOpcode(" << Opc << ");\n"; std::vector& InsnOperands = Operands[Opc]; for (std::vector::iterator I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) { // If a custom instruction decoder was specified, use that. - if (I->FieldBase == ~0U && I->FieldLength == ~0U) { - o.indent(Indentation) << " " << I->Decoder - << "(MI, insn, Address, Decoder);\n"; + if (I->numFields() == 0 && I->Decoder.size()) { + o.indent(Indentation) << " " << Emitter->GuardPrefix << I->Decoder + << "(MI, insn, Address, Decoder)" << Emitter->GuardPostfix << "\n"; break; } - o.indent(Indentation) - << " tmp = fieldFromInstruction(insn, " << I->FieldBase - << ", " << I->FieldLength << ");\n"; - if (I->Decoder != "") { - o.indent(Indentation) << " " << I->Decoder - << "(MI, tmp, Address, Decoder);\n"; - } else { - o.indent(Indentation) - << " MI.addOperand(MCOperand::CreateImm(tmp));\n"; - } + emitBinaryParser(o, Indentation, *I); } - o.indent(Indentation) << " return true; // " << nameWithID(Opc) + o.indent(Indentation) << " return " << Emitter->ReturnOK << "; // " << nameWithID(Opc) << '\n'; - o.indent(Indentation) << "}\n"; + o.indent(Indentation) << "}\n"; // Closing predicate block. return true; } @@ -827,16 +849,21 @@ bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, for (I = Size; I != 0; --I) { o << "Inst{" << EndBits[I-1] << '-' << StartBits[I-1] << "} "; if (I > 1) - o << "&& "; + o << " && "; else o << "for singleton decoding...\n"; } o.indent(Indentation) << "if ("; + if (emitPredicateMatch(o, Indentation, Opc)) { + o << " &&\n"; + o.indent(Indentation+4); + } for (I = Size; I != 0; --I) { NumBits = EndBits[I-1] - StartBits[I-1] + 1; - o << "fieldFromInstruction(insn, " << StartBits[I-1] << ", " << NumBits + o << "fieldFromInstruction" << BitWidth << "(insn, " + << StartBits[I-1] << ", " << NumBits << ") == " << FieldVals[I-1]; if (I > 1) o << " && "; @@ -848,24 +875,15 @@ bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, for (std::vector::iterator I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) { // If a custom instruction decoder was specified, use that. - if (I->FieldBase == ~0U && I->FieldLength == ~0U) { - o.indent(Indentation) << " " << I->Decoder - << "(MI, insn, Address, Decoder);\n"; + if (I->numFields() == 0 && I->Decoder.size()) { + o.indent(Indentation) << " " << Emitter->GuardPrefix << I->Decoder + << "(MI, insn, Address, Decoder)" << Emitter->GuardPostfix << "\n"; break; } - o.indent(Indentation) - << " tmp = fieldFromInstruction(insn, " << I->FieldBase - << ", " << I->FieldLength << ");\n"; - if (I->Decoder != "") { - o.indent(Indentation) << " " << I->Decoder - << "(MI, tmp, Address, Decoder);\n"; - } else { - o.indent(Indentation) - << " MI.addOperand(MCOperand::CreateImm(tmp));\n"; - } + emitBinaryParser(o, Indentation, *I); } - o.indent(Indentation) << " return true; // " << nameWithID(Opc) + o.indent(Indentation) << " return " << Emitter->ReturnOK << "; // " << nameWithID(Opc) << '\n'; o.indent(Indentation) << "}\n"; @@ -965,23 +983,23 @@ bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) { // (MIXED) ------ . ----> (MIXED) // (FILTERED)---- . ----> (FILTERED) - bitAttr_t bitAttrs[BIT_WIDTH]; + std::vector bitAttrs; // FILTERED bit positions provide no entropy and are not worthy of pursuing. // Filter::recurse() set either BIT_TRUE or BIT_FALSE for each position. - for (BitIndex = 0; BitIndex < BIT_WIDTH; ++BitIndex) + for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) if (FilterBitValues[BitIndex] == BIT_TRUE || FilterBitValues[BitIndex] == BIT_FALSE) - bitAttrs[BitIndex] = ATTR_FILTERED; + bitAttrs.push_back(ATTR_FILTERED); else - bitAttrs[BitIndex] = ATTR_NONE; + bitAttrs.push_back(ATTR_NONE); for (InsnIndex = 0; InsnIndex < numInstructions; ++InsnIndex) { insn_t insn; insnWithID(insn, Opcodes[InsnIndex]); - for (BitIndex = 0; BitIndex < BIT_WIDTH; ++BitIndex) { + for (BitIndex = 0; BitIndex < BitWidth; ++BitIndex) { switch (bitAttrs[BitIndex]) { case ATTR_NONE: if (insn[BitIndex] == BIT_UNSET) @@ -1027,7 +1045,7 @@ bool FilterChooser::filterProcessor(bool AllowMixed, bool Greedy) { bitAttr_t RA = ATTR_NONE; unsigned StartBit = 0; - for (BitIndex = 0; BitIndex < BIT_WIDTH; BitIndex++) { + for (BitIndex = 0; BitIndex < BitWidth; BitIndex++) { bitAttr_t bitAttr = bitAttrs[BitIndex]; assert(bitAttr != ATTR_NONE && "Bit without attributes"); @@ -1216,8 +1234,9 @@ bool FilterChooser::emit(raw_ostream &o, unsigned &Indentation) { return true; } -bool FixedLenDecoderEmitter::populateInstruction(const CodeGenInstruction &CGI, - unsigned Opc){ +static bool populateInstruction(const CodeGenInstruction &CGI, + unsigned Opc, + std::map >& Operands){ const Record &Def = *CGI.TheDef; // If all the bit positions are not specified; do not decode this instruction. // We are bound to fail! For proper disassembly, the well-known encoding bits @@ -1239,7 +1258,7 @@ bool FixedLenDecoderEmitter::populateInstruction(const CodeGenInstruction &CGI, // of trying to auto-generate the decoder. std::string InstDecoder = Def.getValueAsString("DecoderMethod"); if (InstDecoder != "") { - InsnOperands.push_back(OperandInfo(~0U, ~0U, InstDecoder)); + InsnOperands.push_back(OperandInfo(InstDecoder)); Operands[Opc] = InsnOperands; return true; } @@ -1259,72 +1278,97 @@ bool FixedLenDecoderEmitter::populateInstruction(const CodeGenInstruction &CGI, for (unsigned i = 0; i < In->getNumArgs(); ++i) InOutOperands.push_back(std::make_pair(In->getArg(i), In->getArgName(i))); + // Search for tied operands, so that we can correctly instantiate + // operands that are not explicitly represented in the encoding. + std::map TiedNames; + for (unsigned i = 0; i < CGI.Operands.size(); ++i) { + int tiedTo = CGI.Operands[i].getTiedRegister(); + if (tiedTo != -1) { + TiedNames[InOutOperands[i].second] = InOutOperands[tiedTo].second; + TiedNames[InOutOperands[tiedTo].second] = InOutOperands[i].second; + } + } + // For each operand, see if we can figure out where it is encoded. for (std::vector >::iterator NI = InOutOperands.begin(), NE = InOutOperands.end(); NI != NE; ++NI) { - unsigned PrevBit = ~0; - unsigned Base = ~0; - unsigned PrevPos = ~0; std::string Decoder = ""; + // At this point, we can locate the field, but we need to know how to + // interpret it. As a first step, require the target to provide callbacks + // for decoding register classes. + // FIXME: This need to be extended to handle instructions with custom + // decoder methods, and operands with (simple) MIOperandInfo's. + TypedInit *TI = dynamic_cast(NI->first); + RecordRecTy *Type = dynamic_cast(TI->getType()); + Record *TypeRecord = Type->getRecord(); + bool isReg = false; + if (TypeRecord->isSubClassOf("RegisterOperand")) + TypeRecord = TypeRecord->getValueAsDef("RegClass"); + if (TypeRecord->isSubClassOf("RegisterClass")) { + Decoder = "Decode" + TypeRecord->getName() + "RegisterClass"; + isReg = true; + } + + RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod"); + StringInit *String = DecoderString ? + dynamic_cast(DecoderString->getValue()) : 0; + if (!isReg && String && String->getValue() != "") + Decoder = String->getValue(); + + OperandInfo OpInfo(Decoder); + unsigned Base = ~0U; + unsigned Width = 0; + unsigned Offset = 0; + for (unsigned bi = 0; bi < Bits.getNumBits(); ++bi) { + VarInit *Var = 0; VarBitInit *BI = dynamic_cast(Bits.getBit(bi)); - if (!BI) continue; + if (BI) + Var = dynamic_cast(BI->getVariable()); + else + Var = dynamic_cast(Bits.getBit(bi)); - VarInit *Var = dynamic_cast(BI->getVariable()); - assert(Var); - unsigned CurrBit = BI->getBitNum(); - if (Var->getName() != NI->second) continue; - - // Figure out the lowest bit of the value, and the width of the field. - // Deliberately don't try to handle cases where the field is scattered, - // or where not all bits of the the field are explicit. - if (Base == ~0U && PrevBit == ~0U && PrevPos == ~0U) { - if (CurrBit == 0) - Base = bi; - else - continue; + if (!Var) { + if (Base != ~0U) { + OpInfo.addField(Base, Width, Offset); + Base = ~0U; + Width = 0; + Offset = 0; + } + continue; } - if ((PrevPos != ~0U && bi-1 != PrevPos) || - (CurrBit != ~0U && CurrBit-1 != PrevBit)) { - PrevBit = ~0; - Base = ~0; - PrevPos = ~0; + if (Var->getName() != NI->second && + Var->getName() != TiedNames[NI->second]) { + if (Base != ~0U) { + OpInfo.addField(Base, Width, Offset); + Base = ~0U; + Width = 0; + Offset = 0; + } + continue; } - PrevPos = bi; - PrevBit = CurrBit; - - // At this point, we can locate the field, but we need to know how to - // interpret it. As a first step, require the target to provide callbacks - // for decoding register classes. - // FIXME: This need to be extended to handle instructions with custom - // decoder methods, and operands with (simple) MIOperandInfo's. - TypedInit *TI = dynamic_cast(NI->first); - RecordRecTy *Type = dynamic_cast(TI->getType()); - Record *TypeRecord = Type->getRecord(); - bool isReg = false; - if (TypeRecord->isSubClassOf("RegisterOperand")) - TypeRecord = TypeRecord->getValueAsDef("RegClass"); - if (TypeRecord->isSubClassOf("RegisterClass")) { - Decoder = "Decode" + TypeRecord->getName() + "RegisterClass"; - isReg = true; + if (Base == ~0U) { + Base = bi; + Width = 1; + Offset = BI ? BI->getBitNum() : 0; + } else if (BI && BI->getBitNum() != Offset + Width) { + OpInfo.addField(Base, Width, Offset); + Base = bi; + Width = 1; + Offset = BI->getBitNum(); + } else { + ++Width; } - - RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod"); - StringInit *String = DecoderString ? - dynamic_cast(DecoderString->getValue()) : - 0; - if (!isReg && String && String->getValue() != "") - Decoder = String->getValue(); } - if (Base != ~0U) { - InsnOperands.push_back(OperandInfo(Base, PrevBit+1, Decoder)); - DEBUG(errs() << "ENCODED OPERAND: $" << NI->second << " @ (" - << utostr(Base+PrevBit) << ", " << utostr(Base) << ")\n"); - } + if (Base != ~0U) + OpInfo.addField(Base, Width, Offset); + + if (OpInfo.numFields() > 0) + InsnOperands.push_back(OpInfo); } Operands[Opc] = InsnOperands; @@ -1351,16 +1395,43 @@ bool FixedLenDecoderEmitter::populateInstruction(const CodeGenInstruction &CGI, return true; } -void FixedLenDecoderEmitter::populateInstructions() { - for (unsigned i = 0, e = NumberedInstructions.size(); i < e; ++i) { - Record *R = NumberedInstructions[i]->TheDef; - if (R->getValueAsString("Namespace") == "TargetOpcode" || - R->getValueAsBit("isPseudo")) - continue; +static void emitHelper(llvm::raw_ostream &o, unsigned BitWidth) { + unsigned Indentation = 0; + std::string WidthStr = "uint" + utostr(BitWidth) + "_t"; - if (populateInstruction(*NumberedInstructions[i], i)) - Opcodes.push_back(i); - } + o << '\n'; + + o.indent(Indentation) << "static " << WidthStr << + " fieldFromInstruction" << BitWidth << + "(" << WidthStr <<" insn, unsigned startBit, unsigned numBits)\n"; + + o.indent(Indentation) << "{\n"; + + ++Indentation; ++Indentation; + o.indent(Indentation) << "assert(startBit + numBits <= " << BitWidth + << " && \"Instruction field out of bounds!\");\n"; + o << '\n'; + o.indent(Indentation) << WidthStr << " fieldMask;\n"; + o << '\n'; + o.indent(Indentation) << "if (numBits == " << BitWidth << ")\n"; + + ++Indentation; ++Indentation; + o.indent(Indentation) << "fieldMask = (" << WidthStr << ")-1;\n"; + --Indentation; --Indentation; + + o.indent(Indentation) << "else\n"; + + ++Indentation; ++Indentation; + o.indent(Indentation) << "fieldMask = ((1 << numBits) - 1) << startBit;\n"; + --Indentation; --Indentation; + + o << '\n'; + o.indent(Indentation) << "return (insn & fieldMask) >> startBit;\n"; + --Indentation; --Indentation; + + o.indent(Indentation) << "}\n"; + + o << '\n'; } // Emits disassembler code for instruction decoding. @@ -1372,10 +1443,47 @@ void FixedLenDecoderEmitter::run(raw_ostream &o) o << '\n'; o << "namespace llvm {\n\n"; + // Parameterize the decoders based on namespace and instruction width. NumberedInstructions = Target.getInstructionsByEnumValue(); - populateInstructions(); - FilterChooser FC(NumberedInstructions, Opcodes, Operands); - FC.emitTop(o, 0); + std::map, + std::vector > OpcMap; + std::map > Operands; + + for (unsigned i = 0; i < NumberedInstructions.size(); ++i) { + const CodeGenInstruction *Inst = NumberedInstructions[i]; + Record *Def = Inst->TheDef; + unsigned Size = Def->getValueAsInt("Size"); + if (Def->getValueAsString("Namespace") == "TargetOpcode" || + Def->getValueAsBit("isPseudo") || + Def->getValueAsBit("isAsmParserOnly") || + Def->getValueAsBit("isCodeGenOnly")) + continue; + + std::string DecoderNamespace = Def->getValueAsString("DecoderNamespace"); + + if (Size) { + if (populateInstruction(*Inst, i, Operands)) { + OpcMap[std::make_pair(DecoderNamespace, Size)].push_back(i); + } + } + } + + std::set Sizes; + for (std::map, + std::vector >::iterator + I = OpcMap.begin(), E = OpcMap.end(); I != E; ++I) { + // If we haven't visited this instruction width before, emit the + // helper method to extract fields. + if (!Sizes.count(I->first.second)) { + emitHelper(o, 8*I->first.second); + Sizes.insert(I->first.second); + } + + // Emit the decoder for this namespace+width combination. + FilterChooser FC(NumberedInstructions, I->second, Operands, + 8*I->first.second, this); + FC.emitTop(o, 0, I->first.first); + } o << "\n} // End llvm namespace \n"; } diff --git a/utils/TableGen/FixedLenDecoderEmitter.h b/utils/TableGen/FixedLenDecoderEmitter.h index d46a495540ea..2df5448aa8d1 100644 --- a/utils/TableGen/FixedLenDecoderEmitter.h +++ b/utils/TableGen/FixedLenDecoderEmitter.h @@ -16,26 +16,51 @@ #define FixedLenDECODEREMITTER_H #include "CodeGenTarget.h" -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" #include "llvm/Support/DataTypes.h" namespace llvm { +struct EncodingField { + unsigned Base, Width, Offset; + EncodingField(unsigned B, unsigned W, unsigned O) + : Base(B), Width(W), Offset(O) { } +}; + struct OperandInfo { - unsigned FieldBase; - unsigned FieldLength; + std::vector Fields; std::string Decoder; - OperandInfo(unsigned FB, unsigned FL, std::string D) - : FieldBase(FB), FieldLength(FL), Decoder(D) { } + OperandInfo(std::string D) + : Decoder(D) { } + + void addField(unsigned Base, unsigned Width, unsigned Offset) { + Fields.push_back(EncodingField(Base, Width, Offset)); + } + + unsigned numFields() { return Fields.size(); } + + typedef std::vector::iterator iterator; + + iterator begin() { return Fields.begin(); } + iterator end() { return Fields.end(); } }; class FixedLenDecoderEmitter : public TableGenBackend { public: - FixedLenDecoderEmitter(RecordKeeper &R) : + FixedLenDecoderEmitter(RecordKeeper &R, + std::string PredicateNamespace, + std::string GPrefix = "if (", + std::string GPostfix = " == MCDisassembler::Fail) return MCDisassembler::Fail;", + std::string ROK = "MCDisassembler::Success", + std::string RFail = "MCDisassembler::Fail", + std::string L = "") : Records(R), Target(R), - NumberedInstructions(Target.getInstructionsByEnumValue()) {} + NumberedInstructions(Target.getInstructionsByEnumValue()), + PredicateNamespace(PredicateNamespace), + GuardPrefix(GPrefix), GuardPostfix(GPostfix), + ReturnOK(ROK), ReturnFail(RFail), Locals(L) {} // run - Output the code emitter void run(raw_ostream &o); @@ -46,9 +71,11 @@ class FixedLenDecoderEmitter : public TableGenBackend { std::vector NumberedInstructions; std::vector Opcodes; std::map > Operands; - - bool populateInstruction(const CodeGenInstruction &CGI, unsigned Opc); - void populateInstructions(); +public: + std::string PredicateNamespace; + std::string GuardPrefix, GuardPostfix; + std::string ReturnOK, ReturnFail; + std::string Locals; }; } // end llvm namespace diff --git a/utils/TableGen/InstrEnumEmitter.cpp b/utils/TableGen/InstrEnumEmitter.cpp index aa596892f52f..5981afde0e7e 100644 --- a/utils/TableGen/InstrEnumEmitter.cpp +++ b/utils/TableGen/InstrEnumEmitter.cpp @@ -14,7 +14,7 @@ #include "InstrEnumEmitter.h" #include "CodeGenTarget.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include using namespace llvm; diff --git a/utils/TableGen/InstrEnumEmitter.h b/utils/TableGen/InstrEnumEmitter.h index 89f8b659d702..c29a30938d34 100644 --- a/utils/TableGen/InstrEnumEmitter.h +++ b/utils/TableGen/InstrEnumEmitter.h @@ -15,7 +15,7 @@ #ifndef INSTRENUM_EMITTER_H #define INSTRENUM_EMITTER_H -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" namespace llvm { diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 5ebaf174655b..8341724a73e4 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -14,7 +14,7 @@ #include "InstrInfoEmitter.h" #include "CodeGenTarget.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include using namespace llvm; @@ -268,6 +268,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, << Inst.TheDef->getName() << "\", 0"; // Emit all of the target indepedent flags... + if (Inst.isPseudo) OS << "|(1< #include diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index e5e7cea1200f..782b89ede2e7 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -13,8 +13,8 @@ #include "CodeGenTarget.h" #include "IntrinsicEmitter.h" -#include "Record.h" #include "StringMatcher.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include using namespace llvm; diff --git a/utils/TableGen/IntrinsicEmitter.h b/utils/TableGen/IntrinsicEmitter.h index b1efecb92eea..eb6379cc7414 100644 --- a/utils/TableGen/IntrinsicEmitter.h +++ b/utils/TableGen/IntrinsicEmitter.h @@ -15,7 +15,7 @@ #define INTRINSIC_EMITTER_H #include "CodeGenIntrinsics.h" -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" namespace llvm { class IntrinsicEmitter : public TableGenBackend { diff --git a/utils/TableGen/LLVMCConfigurationEmitter.cpp b/utils/TableGen/LLVMCConfigurationEmitter.cpp deleted file mode 100644 index cd0cbeb1c6b3..000000000000 --- a/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ /dev/null @@ -1,3134 +0,0 @@ -//===- LLVMCConfigurationEmitter.cpp - Generate LLVMC config ----*- 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 LLVMC configuration code. -// -//===----------------------------------------------------------------------===// - -#include "LLVMCConfigurationEmitter.h" -#include "Record.h" - -#include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringSet.h" - -#include -#include -#include -#include -#include -#include - - -using namespace llvm; - -namespace { - -//===----------------------------------------------------------------------===// -/// Typedefs - -typedef std::vector RecordVector; -typedef std::vector DagVector; -typedef std::vector StrVector; - -//===----------------------------------------------------------------------===// -/// Constants - -// Indentation. -const unsigned TabWidth = 4; -const unsigned Indent1 = TabWidth*1; -const unsigned Indent2 = TabWidth*2; -const unsigned Indent3 = TabWidth*3; -const unsigned Indent4 = TabWidth*4; - -// Default help string. -const char * const DefaultHelpString = "NO HELP MESSAGE PROVIDED"; - -// Name for the "sink" option. -const char * const SinkOptionName = "SinkOption"; - -//===----------------------------------------------------------------------===// -/// Helper functions - -/// Id - An 'identity' function object. -struct Id { - template - void operator()(const T0&) const { - } - template - void operator()(const T0&, const T1&) const { - } - template - void operator()(const T0&, const T1&, const T2&) const { - } -}; - -int InitPtrToInt(const Init* ptr) { - const IntInit& val = dynamic_cast(*ptr); - return val.getValue(); -} - -bool InitPtrToBool(const Init* ptr) { - bool ret = false; - const DefInit& val = dynamic_cast(*ptr); - const std::string& str = val.getAsString(); - - if (str == "true") { - ret = true; - } - else if (str == "false") { - ret = false; - } - else { - throw "Incorrect boolean value: '" + str + - "': must be either 'true' or 'false'"; - } - - return ret; -} - -const std::string& InitPtrToString(const Init* ptr) { - const StringInit& val = dynamic_cast(*ptr); - return val.getValue(); -} - -const ListInit& InitPtrToList(const Init* ptr) { - const ListInit& val = dynamic_cast(*ptr); - return val; -} - -const DagInit& InitPtrToDag(const Init* ptr) { - const DagInit& val = dynamic_cast(*ptr); - return val; -} - -const std::string GetOperatorName(const DagInit& D) { - return D.getOperator()->getAsString(); -} - -/// CheckBooleanConstant - Check that the provided value is a boolean constant. -void CheckBooleanConstant(const Init* I) { - InitPtrToBool(I); -} - -// CheckNumberOfArguments - Ensure that the number of args in d is -// greater than or equal to min_arguments, otherwise throw an exception. -void CheckNumberOfArguments (const DagInit& d, unsigned minArgs) { - if (d.getNumArgs() < minArgs) - throw GetOperatorName(d) + ": too few arguments!"; -} - -// 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 ret; - for (unsigned i = 0; i != Var.size(); ++i) { - char cur_char = Var[i]; - if (cur_char == ',') { - ret += "_comma_"; - } - else if (cur_char == '+') { - ret += "_plus_"; - } - else if (cur_char == '-') { - ret += "_dash_"; - } - else { - ret.push_back(cur_char); - } - } - 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) { - if (*lst++ == c) - return true; - } - return false; -} - -template -void CheckedIncrement(I& P, I E, S ErrorString) { - ++P; - if (P == E) - throw ErrorString; -} - -//===----------------------------------------------------------------------===// -/// Back-end specific code - - -/// OptionType - One of six different option types. See the -/// documentation for detailed description of differences. -namespace OptionType { - - enum OptionType { Alias, Switch, SwitchList, - Parameter, ParameterList, Prefix, PrefixList }; - - bool IsAlias(OptionType t) { - return (t == Alias); - } - - bool IsList (OptionType t) { - return (t == SwitchList || t == ParameterList || t == PrefixList); - } - - bool IsSwitch (OptionType t) { - return (t == Switch); - } - - bool IsSwitchList (OptionType t) { - return (t == SwitchList); - } - - bool IsParameter (OptionType t) { - return (t == Parameter || t == Prefix); - } - -} - -OptionType::OptionType stringToOptionType(const std::string& T) { - if (T == "alias_option") - return OptionType::Alias; - else if (T == "switch_option") - return OptionType::Switch; - else if (T == "switch_list_option") - return OptionType::SwitchList; - else if (T == "parameter_option") - return OptionType::Parameter; - else if (T == "parameter_list_option") - return OptionType::ParameterList; - else if (T == "prefix_option") - return OptionType::Prefix; - else if (T == "prefix_list_option") - return OptionType::PrefixList; - else - throw "Unknown option type: " + T + '!'; -} - -namespace OptionDescriptionFlags { - enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2, - ReallyHidden = 0x4, OneOrMore = 0x8, - Optional = 0x10, CommaSeparated = 0x20, - ForwardNotSplit = 0x40, ZeroOrMore = 0x80 }; -} - -/// OptionDescription - Represents data contained in a single -/// OptionList entry. -struct OptionDescription { - OptionType::OptionType Type; - std::string Name; - unsigned Flags; - std::string Help; - unsigned MultiVal; - Init* InitVal; - - OptionDescription(OptionType::OptionType t = OptionType::Switch, - const std::string& n = "", - const std::string& h = DefaultHelpString) - : Type(t), Name(n), Flags(0x0), Help(h), MultiVal(1), InitVal(0) - {} - - /// GenTypeDeclaration - Returns the C++ variable type of this - /// option. - const char* GenTypeDeclaration() const; - - /// GenVariableName - Returns the variable name used in the - /// generated C++ code. - std::string GenVariableName() const - { return "autogenerated::" + GenOptionType() + EscapeVariableName(Name); } - - /// GenPlainVariableName - Returns the variable name without the namespace - /// prefix. - std::string GenPlainVariableName() const - { return GenOptionType() + EscapeVariableName(Name); } - - /// Merge - Merge two option descriptions. - void Merge (const OptionDescription& other); - - /// CheckConsistency - Check that the flags are consistent. - void CheckConsistency() const; - - // Misc convenient getters/setters. - - bool isAlias() const; - - bool isMultiVal() const; - - bool isCommaSeparated() const; - void setCommaSeparated(); - - bool isForwardNotSplit() const; - void setForwardNotSplit(); - - bool isRequired() const; - void setRequired(); - - bool isOneOrMore() const; - void setOneOrMore(); - - bool isZeroOrMore() const; - void setZeroOrMore(); - - bool isOptional() const; - void setOptional(); - - bool isHidden() const; - void setHidden(); - - bool isReallyHidden() const; - void setReallyHidden(); - - bool isSwitch() const - { return OptionType::IsSwitch(this->Type); } - - bool isSwitchList() const - { return OptionType::IsSwitchList(this->Type); } - - bool isParameter() const - { return OptionType::IsParameter(this->Type); } - - bool isList() const - { return OptionType::IsList(this->Type); } - - bool isParameterList() const - { return (OptionType::IsList(this->Type) - && !OptionType::IsSwitchList(this->Type)); } - -private: - - // GenOptionType - Helper function used by GenVariableName(). - std::string GenOptionType() const; -}; - -void OptionDescription::CheckConsistency() const { - unsigned i = 0; - - i += this->isRequired(); - i += this->isOptional(); - i += this->isOneOrMore(); - i += this->isZeroOrMore(); - - if (i > 1) { - throw "Only one of (required), (optional), (one_or_more) or " - "(zero_or_more) properties is allowed!"; - } -} - -void OptionDescription::Merge (const OptionDescription& other) -{ - if (other.Type != Type) - throw "Conflicting definitions for the option " + Name + "!"; - - if (Help == other.Help || Help == DefaultHelpString) - Help = other.Help; - else if (other.Help != DefaultHelpString) { - llvm::errs() << "Warning: several different help strings" - " defined for option " + Name + "\n"; - } - - Flags |= other.Flags; -} - -bool OptionDescription::isAlias() const { - return OptionType::IsAlias(this->Type); -} - -bool OptionDescription::isMultiVal() const { - return MultiVal > 1; -} - -bool OptionDescription::isCommaSeparated() const { - return Flags & OptionDescriptionFlags::CommaSeparated; -} -void OptionDescription::setCommaSeparated() { - Flags |= OptionDescriptionFlags::CommaSeparated; -} - -bool OptionDescription::isForwardNotSplit() const { - return Flags & OptionDescriptionFlags::ForwardNotSplit; -} -void OptionDescription::setForwardNotSplit() { - Flags |= OptionDescriptionFlags::ForwardNotSplit; -} - -bool OptionDescription::isRequired() const { - return Flags & OptionDescriptionFlags::Required; -} -void OptionDescription::setRequired() { - Flags |= OptionDescriptionFlags::Required; -} - -bool OptionDescription::isOneOrMore() const { - return Flags & OptionDescriptionFlags::OneOrMore; -} -void OptionDescription::setOneOrMore() { - Flags |= OptionDescriptionFlags::OneOrMore; -} - -bool OptionDescription::isZeroOrMore() const { - return Flags & OptionDescriptionFlags::ZeroOrMore; -} -void OptionDescription::setZeroOrMore() { - Flags |= OptionDescriptionFlags::ZeroOrMore; -} - -bool OptionDescription::isOptional() const { - return Flags & OptionDescriptionFlags::Optional; -} -void OptionDescription::setOptional() { - Flags |= OptionDescriptionFlags::Optional; -} - -bool OptionDescription::isHidden() const { - return Flags & OptionDescriptionFlags::Hidden; -} -void OptionDescription::setHidden() { - Flags |= OptionDescriptionFlags::Hidden; -} - -bool OptionDescription::isReallyHidden() const { - return Flags & OptionDescriptionFlags::ReallyHidden; -} -void OptionDescription::setReallyHidden() { - Flags |= OptionDescriptionFlags::ReallyHidden; -} - -const char* OptionDescription::GenTypeDeclaration() const { - switch (Type) { - case OptionType::Alias: - return "cl::alias"; - case OptionType::PrefixList: - case OptionType::ParameterList: - return "cl::list"; - case OptionType::Switch: - return "cl::opt"; - case OptionType::SwitchList: - return "cl::list"; - case OptionType::Parameter: - case OptionType::Prefix: - default: - return "cl::opt"; - } -} - -std::string OptionDescription::GenOptionType() const { - switch (Type) { - case OptionType::Alias: - return "Alias_"; - case OptionType::PrefixList: - case OptionType::ParameterList: - return "List_"; - case OptionType::Switch: - return "Switch_"; - case OptionType::SwitchList: - return "SwitchList_"; - case OptionType::Prefix: - case OptionType::Parameter: - default: - return "Parameter_"; - } -} - -/// OptionDescriptions - An OptionDescription array plus some helper -/// functions. -class OptionDescriptions { - typedef StringMap container_type; - - /// Descriptions - A list of OptionDescriptions. - container_type Descriptions; - -public: - /// FindOption - exception-throwing wrapper for find(). - const OptionDescription& FindOption(const std::string& OptName) const; - - // Wrappers for FindOption that throw an exception in case the option has a - // wrong type. - const OptionDescription& FindSwitch(const std::string& OptName) const; - const OptionDescription& FindParameter(const std::string& OptName) const; - const OptionDescription& FindParameterList(const std::string& OptName) const; - const OptionDescription& - FindListOrParameter(const std::string& OptName) const; - const OptionDescription& - FindParameterListOrParameter(const std::string& OptName) const; - - /// insertDescription - Insert new OptionDescription into - /// OptionDescriptions list - void InsertDescription (const OptionDescription& o); - - // Support for STL-style iteration - typedef container_type::const_iterator const_iterator; - const_iterator begin() const { return Descriptions.begin(); } - const_iterator end() const { return Descriptions.end(); } -}; - -const OptionDescription& -OptionDescriptions::FindOption(const std::string& OptName) const { - const_iterator I = Descriptions.find(OptName); - if (I != Descriptions.end()) - return I->second; - else - throw OptName + ": no such option!"; -} - -const OptionDescription& -OptionDescriptions::FindSwitch(const std::string& OptName) const { - const OptionDescription& OptDesc = this->FindOption(OptName); - if (!OptDesc.isSwitch()) - throw OptName + ": incorrect option type - should be a switch!"; - return OptDesc; -} - -const OptionDescription& -OptionDescriptions::FindParameterList(const std::string& OptName) const { - const OptionDescription& OptDesc = this->FindOption(OptName); - if (!OptDesc.isList() || OptDesc.isSwitchList()) - throw OptName + ": incorrect option type - should be a parameter list!"; - return OptDesc; -} - -const OptionDescription& -OptionDescriptions::FindParameter(const std::string& OptName) const { - const OptionDescription& OptDesc = this->FindOption(OptName); - if (!OptDesc.isParameter()) - throw OptName + ": incorrect option type - should be a parameter!"; - return OptDesc; -} - -const OptionDescription& -OptionDescriptions::FindListOrParameter(const std::string& OptName) const { - const OptionDescription& OptDesc = this->FindOption(OptName); - if (!OptDesc.isList() && !OptDesc.isParameter()) - throw OptName - + ": incorrect option type - should be a list or parameter!"; - return OptDesc; -} - -const OptionDescription& -OptionDescriptions::FindParameterListOrParameter -(const std::string& OptName) const { - const OptionDescription& OptDesc = this->FindOption(OptName); - if ((!OptDesc.isList() && !OptDesc.isParameter()) || OptDesc.isSwitchList()) - throw OptName - + ": incorrect option type - should be a parameter list or parameter!"; - return OptDesc; -} - -void OptionDescriptions::InsertDescription (const OptionDescription& o) { - container_type::iterator I = Descriptions.find(o.Name); - if (I != Descriptions.end()) { - OptionDescription& D = I->second; - D.Merge(o); - } - else { - Descriptions[o.Name] = o; - } -} - -/// HandlerTable - A base class for function objects implemented as -/// 'tables of handlers'. -template -class HandlerTable { -protected: - // Implementation details. - - /// HandlerMap - A map from property names to property handlers - typedef StringMap HandlerMap; - - static HandlerMap Handlers_; - static bool staticMembersInitialized_; - -public: - - Handler GetHandler (const std::string& HandlerName) const { - typename HandlerMap::iterator method = Handlers_.find(HandlerName); - - if (method != Handlers_.end()) { - Handler h = method->second; - return h; - } - else { - throw "No handler found for property " + HandlerName + "!"; - } - } - - void AddHandler(const char* Property, Handler H) { - Handlers_[Property] = H; - } - -}; - -template -Handler GetHandler(FunctionObject* Obj, const DagInit& Dag) { - const std::string& HandlerName = GetOperatorName(Dag); - return Obj->GetHandler(HandlerName); -} - -template -void InvokeDagInitHandler(FunctionObject* Obj, Init* I) { - typedef void (FunctionObject::*Handler) (const DagInit&); - - const DagInit& Dag = InitPtrToDag(I); - Handler h = GetHandler(Obj, Dag); - - ((Obj)->*(h))(Dag); -} - -template -void InvokeDagInitHandler(const FunctionObject* const Obj, - const Init* I, unsigned IndentLevel, raw_ostream& O) -{ - typedef void (FunctionObject::*Handler) - (const DagInit&, unsigned IndentLevel, raw_ostream& O) const; - - const DagInit& Dag = InitPtrToDag(I); - Handler h = GetHandler(Obj, Dag); - - ((Obj)->*(h))(Dag, IndentLevel, O); -} - -template -typename HandlerTable::HandlerMap HandlerTable::Handlers_; - -template -bool HandlerTable::staticMembersInitialized_ = false; - - -/// CollectOptionProperties - Function object for iterating over an -/// option property list. -class CollectOptionProperties; -typedef void (CollectOptionProperties::* CollectOptionPropertiesHandler) -(const DagInit&); - -class CollectOptionProperties -: public HandlerTable -{ -private: - - /// optDescs_ - OptionDescriptions table. This is where the - /// information is stored. - OptionDescription& optDesc_; - -public: - - explicit CollectOptionProperties(OptionDescription& OD) - : optDesc_(OD) - { - if (!staticMembersInitialized_) { - AddHandler("help", &CollectOptionProperties::onHelp); - AddHandler("hidden", &CollectOptionProperties::onHidden); - AddHandler("init", &CollectOptionProperties::onInit); - AddHandler("multi_val", &CollectOptionProperties::onMultiVal); - AddHandler("one_or_more", &CollectOptionProperties::onOneOrMore); - AddHandler("zero_or_more", &CollectOptionProperties::onZeroOrMore); - AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden); - AddHandler("required", &CollectOptionProperties::onRequired); - AddHandler("optional", &CollectOptionProperties::onOptional); - AddHandler("comma_separated", &CollectOptionProperties::onCommaSeparated); - AddHandler("forward_not_split", - &CollectOptionProperties::onForwardNotSplit); - - staticMembersInitialized_ = true; - } - } - - /// operator() - Just forwards to the corresponding property - /// handler. - void operator() (Init* I) { - InvokeDagInitHandler(this, I); - } - -private: - - /// Option property handlers -- - /// Methods that handle option properties such as (help) or (hidden). - - void onHelp (const DagInit& d) { - CheckNumberOfArguments(d, 1); - optDesc_.Help = EscapeQuotes(InitPtrToString(d.getArg(0))); - } - - void onHidden (const DagInit& d) { - CheckNumberOfArguments(d, 0); - optDesc_.setHidden(); - } - - void onReallyHidden (const DagInit& d) { - CheckNumberOfArguments(d, 0); - optDesc_.setReallyHidden(); - } - - void onCommaSeparated (const DagInit& d) { - CheckNumberOfArguments(d, 0); - if (!optDesc_.isParameterList()) - throw "'comma_separated' is valid only on parameter list options!"; - optDesc_.setCommaSeparated(); - } - - void onForwardNotSplit (const DagInit& d) { - CheckNumberOfArguments(d, 0); - if (!optDesc_.isParameter()) - throw "'forward_not_split' is valid only for parameter options!"; - optDesc_.setForwardNotSplit(); - } - - void onRequired (const DagInit& d) { - CheckNumberOfArguments(d, 0); - - optDesc_.setRequired(); - optDesc_.CheckConsistency(); - } - - void onInit (const DagInit& d) { - CheckNumberOfArguments(d, 1); - Init* i = d.getArg(0); - const std::string& str = i->getAsString(); - - bool correct = optDesc_.isParameter() && dynamic_cast(i); - correct |= (optDesc_.isSwitch() && (str == "true" || str == "false")); - - if (!correct) - throw "Incorrect usage of the 'init' option property!"; - - optDesc_.InitVal = i; - } - - void onOneOrMore (const DagInit& d) { - CheckNumberOfArguments(d, 0); - - optDesc_.setOneOrMore(); - optDesc_.CheckConsistency(); - } - - void onZeroOrMore (const DagInit& d) { - CheckNumberOfArguments(d, 0); - - if (optDesc_.isList()) - llvm::errs() << "Warning: specifying the 'zero_or_more' property " - "on a list option has no effect.\n"; - - optDesc_.setZeroOrMore(); - optDesc_.CheckConsistency(); - } - - void onOptional (const DagInit& d) { - CheckNumberOfArguments(d, 0); - - if (!optDesc_.isList()) - llvm::errs() << "Warning: specifying the 'optional' property" - "on a non-list option has no effect.\n"; - - optDesc_.setOptional(); - optDesc_.CheckConsistency(); - } - - void onMultiVal (const DagInit& d) { - CheckNumberOfArguments(d, 1); - int val = InitPtrToInt(d.getArg(0)); - if (val < 2) - throw "Error in the 'multi_val' property: " - "the value must be greater than 1!"; - if (!optDesc_.isParameterList()) - throw "The multi_val property is valid only on list options!"; - optDesc_.MultiVal = val; - } - -}; - -/// AddOption - A function object that is applied to every option -/// description. Used by CollectOptionDescriptions. -class AddOption { -private: - OptionDescriptions& OptDescs_; - -public: - explicit AddOption(OptionDescriptions& OD) : OptDescs_(OD) - {} - - void operator()(const Init* i) { - const DagInit& d = InitPtrToDag(i); - CheckNumberOfArguments(d, 1); - - const OptionType::OptionType Type = - stringToOptionType(GetOperatorName(d)); - const std::string& Name = InitPtrToString(d.getArg(0)); - - OptionDescription OD(Type, Name); - - CheckNumberOfArguments(d, 2); - - // Alias option store the aliased option name in the 'Help' field and do not - // have any properties. - if (OD.isAlias()) { - OD.Help = InitPtrToString(d.getArg(1)); - } - else { - processOptionProperties(d, OD); - } - - // Switch options are ZeroOrMore by default. - if (OD.isSwitch()) { - if (!(OD.isOptional() || OD.isOneOrMore() || OD.isRequired())) - OD.setZeroOrMore(); - } - - OptDescs_.InsertDescription(OD); - } - -private: - /// processOptionProperties - Go through the list of option - /// properties and call a corresponding handler for each. - static void processOptionProperties (const DagInit& d, OptionDescription& o) { - CheckNumberOfArguments(d, 2); - DagInit::const_arg_iterator B = d.arg_begin(); - // Skip the first argument: it's always the option name. - ++B; - std::for_each(B, d.arg_end(), CollectOptionProperties(o)); - } - -}; - -/// CollectOptionDescriptions - Collects option properties from all -/// OptionLists. -void CollectOptionDescriptions (const RecordVector& V, - OptionDescriptions& OptDescs) -{ - // For every OptionList: - for (RecordVector::const_iterator B = V.begin(), E = V.end(); B!=E; ++B) - { - // Throws an exception if the value does not exist. - ListInit* PropList = (*B)->getValueAsListInit("options"); - - // For every option description in this list: invoke AddOption. - std::for_each(PropList->begin(), PropList->end(), AddOption(OptDescs)); - } -} - -// Tool information record - -namespace ToolFlags { - enum ToolFlags { Join = 0x1, Sink = 0x2 }; -} - -struct ToolDescription : public RefCountedBase { - std::string Name; - Init* CmdLine; - Init* Actions; - StrVector InLanguage; - std::string InFileOption; - std::string OutFileOption; - StrVector OutLanguage; - std::string OutputSuffix; - unsigned Flags; - const Init* OnEmpty; - - // Various boolean properties - void setSink() { Flags |= ToolFlags::Sink; } - bool isSink() const { return Flags & ToolFlags::Sink; } - void setJoin() { Flags |= ToolFlags::Join; } - bool isJoin() const { return Flags & ToolFlags::Join; } - - // Default ctor here is needed because StringMap can only store - // DefaultConstructible objects - ToolDescription (const std::string &n = "") - : Name(n), CmdLine(0), Actions(0), OutFileOption("-o"), - Flags(0), OnEmpty(0) - {} -}; - -/// ToolDescriptions - A list of Tool information records. -typedef std::vector > ToolDescriptions; - - -/// CollectToolProperties - Function object for iterating over a list of -/// tool property records. - -class CollectToolProperties; -typedef void (CollectToolProperties::* CollectToolPropertiesHandler) -(const DagInit&); - -class CollectToolProperties : public HandlerTable -{ -private: - - /// toolDesc_ - Properties of the current Tool. This is where the - /// information is stored. - ToolDescription& toolDesc_; - -public: - - explicit CollectToolProperties (ToolDescription& d) - : toolDesc_(d) - { - if (!staticMembersInitialized_) { - - AddHandler("actions", &CollectToolProperties::onActions); - AddHandler("command", &CollectToolProperties::onCommand); - AddHandler("in_language", &CollectToolProperties::onInLanguage); - AddHandler("join", &CollectToolProperties::onJoin); - AddHandler("out_language", &CollectToolProperties::onOutLanguage); - - AddHandler("out_file_option", &CollectToolProperties::onOutFileOption); - AddHandler("in_file_option", &CollectToolProperties::onInFileOption); - - AddHandler("output_suffix", &CollectToolProperties::onOutputSuffix); - AddHandler("sink", &CollectToolProperties::onSink); - AddHandler("works_on_empty", &CollectToolProperties::onWorksOnEmpty); - - staticMembersInitialized_ = true; - } - } - - void operator() (Init* I) { - InvokeDagInitHandler(this, I); - } - -private: - - /// Property handlers -- - /// Functions that extract information about tool properties from - /// DAG representation. - - void onActions (const DagInit& d) { - CheckNumberOfArguments(d, 1); - Init* Case = d.getArg(0); - if (typeid(*Case) != typeid(DagInit) || - GetOperatorName(static_cast(*Case)) != "case") - throw "The argument to (actions) should be a 'case' construct!"; - toolDesc_.Actions = Case; - } - - void onCommand (const DagInit& d) { - CheckNumberOfArguments(d, 1); - toolDesc_.CmdLine = d.getArg(0); - } - - /// onInOutLanguage - Common implementation of on{In,Out}Language(). - void onInOutLanguage (const DagInit& d, StrVector& OutVec) { - CheckNumberOfArguments(d, 1); - - // Copy strings to the output vector. - for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) { - OutVec.push_back(InitPtrToString(d.getArg(i))); - } - - // Remove duplicates. - std::sort(OutVec.begin(), OutVec.end()); - StrVector::iterator newE = std::unique(OutVec.begin(), OutVec.end()); - OutVec.erase(newE, OutVec.end()); - } - - - void onInLanguage (const DagInit& d) { - this->onInOutLanguage(d, toolDesc_.InLanguage); - } - - void onJoin (const DagInit& d) { - bool isReallyJoin = false; - - if (d.getNumArgs() == 0) { - isReallyJoin = true; - } - else { - Init* I = d.getArg(0); - isReallyJoin = InitPtrToBool(I); - } - - // Is this *really* a join tool? We allow (join false) for generating two - // tool descriptions from a single generic one. - // TOFIX: come up with a cleaner solution. - if (isReallyJoin) { - toolDesc_.setJoin(); - } - } - - void onOutLanguage (const DagInit& d) { - this->onInOutLanguage(d, toolDesc_.OutLanguage); - } - - void onOutFileOption (const DagInit& d) { - CheckNumberOfArguments(d, 1); - toolDesc_.OutFileOption = InitPtrToString(d.getArg(0)); - } - - void onInFileOption (const DagInit& d) { - CheckNumberOfArguments(d, 1); - toolDesc_.InFileOption = InitPtrToString(d.getArg(0)); - } - - void onOutputSuffix (const DagInit& d) { - CheckNumberOfArguments(d, 1); - toolDesc_.OutputSuffix = InitPtrToString(d.getArg(0)); - } - - void onSink (const DagInit& d) { - CheckNumberOfArguments(d, 0); - toolDesc_.setSink(); - } - - void onWorksOnEmpty (const DagInit& d) { - toolDesc_.OnEmpty = d.getArg(0); - } - -}; - -/// CollectToolDescriptions - Gather information about tool properties -/// from the parsed TableGen data (basically a wrapper for the -/// CollectToolProperties function object). -void CollectToolDescriptions (const RecordVector& Tools, - ToolDescriptions& ToolDescs) -{ - // Iterate over a properties list of every Tool definition - for (RecordVector::const_iterator B = Tools.begin(), - E = Tools.end(); B!=E; ++B) { - const Record* T = *B; - // Throws an exception if the value does not exist. - ListInit* PropList = T->getValueAsListInit("properties"); - - IntrusiveRefCntPtr - ToolDesc(new ToolDescription(T->getName())); - - std::for_each(PropList->begin(), PropList->end(), - CollectToolProperties(*ToolDesc)); - ToolDescs.push_back(ToolDesc); - } -} - -/// FillInEdgeVector - Merge all compilation graph definitions into -/// one single edge list. -void FillInEdgeVector(const RecordVector& CompilationGraphs, - DagVector& Out) { - for (RecordVector::const_iterator B = CompilationGraphs.begin(), - E = CompilationGraphs.end(); B != E; ++B) { - const ListInit* Edges = (*B)->getValueAsListInit("edges"); - - for (ListInit::const_iterator B = Edges->begin(), - E = Edges->end(); B != E; ++B) { - Out.push_back(&InitPtrToDag(*B)); - } - } -} - -/// NotInGraph - Helper function object for FilterNotInGraph. -struct NotInGraph { -private: - const llvm::StringSet<>& ToolsInGraph_; - -public: - NotInGraph(const llvm::StringSet<>& ToolsInGraph) - : ToolsInGraph_(ToolsInGraph) - {} - - bool operator()(const IntrusiveRefCntPtr& x) { - return (ToolsInGraph_.count(x->Name) == 0); - } -}; - -/// FilterNotInGraph - Filter out from ToolDescs all Tools not -/// mentioned in the compilation graph definition. -void FilterNotInGraph (const DagVector& EdgeVector, - ToolDescriptions& ToolDescs) { - - // List all tools mentioned in the graph. - llvm::StringSet<> ToolsInGraph; - - for (DagVector::const_iterator B = EdgeVector.begin(), - E = EdgeVector.end(); B != E; ++B) { - - const DagInit* Edge = *B; - const std::string& NodeA = InitPtrToString(Edge->getArg(0)); - const std::string& NodeB = InitPtrToString(Edge->getArg(1)); - - if (NodeA != "root") - ToolsInGraph.insert(NodeA); - ToolsInGraph.insert(NodeB); - } - - // Filter ToolPropertiesList. - ToolDescriptions::iterator new_end = - std::remove_if(ToolDescs.begin(), ToolDescs.end(), - NotInGraph(ToolsInGraph)); - ToolDescs.erase(new_end, ToolDescs.end()); -} - -/// FillInToolToLang - Fills in two tables that map tool names to -/// input & output language names. Helper function used by TypecheckGraph(). -void FillInToolToLang (const ToolDescriptions& ToolDescs, - StringMap >& ToolToInLang, - StringMap >& ToolToOutLang) { - for (ToolDescriptions::const_iterator B = ToolDescs.begin(), - E = ToolDescs.end(); B != E; ++B) { - const ToolDescription& D = *(*B); - for (StrVector::const_iterator B = D.InLanguage.begin(), - E = D.InLanguage.end(); B != E; ++B) - ToolToInLang[D.Name].insert(*B); - for (StrVector::const_iterator B = D.OutLanguage.begin(), - E = D.OutLanguage.end(); B != E; ++B) - ToolToOutLang[D.Name].insert(*B); - } -} - -/// Intersect - Is set intersection non-empty? -bool Intersect (const StringSet<>& S1, const StringSet<>& S2) { - for (StringSet<>::const_iterator B = S1.begin(), E = S1.end(); B != E; ++B) { - if (S2.count(B->first()) != 0) - return true; - } - return false; -} - -/// TypecheckGraph - Check that names for output and input languages -/// on all edges do match. -void TypecheckGraph (const DagVector& EdgeVector, - const ToolDescriptions& ToolDescs) { - StringMap > ToolToInLang; - StringMap > ToolToOutLang; - - FillInToolToLang(ToolDescs, ToolToInLang, ToolToOutLang); - - for (DagVector::const_iterator B = EdgeVector.begin(), - E = EdgeVector.end(); B != E; ++B) { - const DagInit* Edge = *B; - const std::string& NodeA = InitPtrToString(Edge->getArg(0)); - const std::string& NodeB = InitPtrToString(Edge->getArg(1)); - StringMap >::iterator IA = ToolToOutLang.find(NodeA); - StringMap >::iterator IB = ToolToInLang.find(NodeB); - - if (NodeB == "root") - throw "Edges back to the root are not allowed!"; - - if (NodeA != "root") { - if (IA == ToolToOutLang.end()) - throw NodeA + ": no output language defined!"; - if (IB == ToolToInLang.end()) - throw NodeB + ": no input language defined!"; - - if (!Intersect(IA->second, IB->second)) { - throw "Edge " + NodeA + "->" + NodeB - + ": output->input language mismatch"; - } - } - } -} - -/// WalkCase - Walks the 'case' expression DAG and invokes -/// TestCallback on every test, and StatementCallback on every -/// statement. Handles 'case' nesting, but not the 'and' and 'or' -/// combinators (that is, they are passed directly to TestCallback). -/// TestCallback must have type 'void TestCallback(const DagInit*, unsigned -/// IndentLevel, bool FirstTest)'. -/// StatementCallback must have type 'void StatementCallback(const Init*, -/// unsigned IndentLevel)'. -template -void WalkCase(const Init* Case, F1 TestCallback, F2 StatementCallback, - unsigned IndentLevel = 0) -{ - const DagInit& d = InitPtrToDag(Case); - - // Error checks. - if (GetOperatorName(d) != "case") - throw "WalkCase should be invoked only on 'case' expressions!"; - - if (d.getNumArgs() < 2) - throw "There should be at least one clause in the 'case' expression:\n" - + d.getAsString(); - - // Main loop. - bool even = false; - const unsigned numArgs = d.getNumArgs(); - unsigned i = 1; - for (DagInit::const_arg_iterator B = d.arg_begin(), E = d.arg_end(); - B != E; ++B) { - Init* arg = *B; - - if (!even) - { - // Handle test. - const DagInit& Test = InitPtrToDag(arg); - - if (GetOperatorName(Test) == "default" && (i+1 != numArgs)) - throw "The 'default' clause should be the last in the " - "'case' construct!"; - if (i == numArgs) - throw "Case construct handler: no corresponding action " - "found for the test " + Test.getAsString() + '!'; - - TestCallback(Test, IndentLevel, (i == 1)); - } - else - { - if (dynamic_cast(arg) - && GetOperatorName(static_cast(*arg)) == "case") { - // Nested 'case'. - WalkCase(arg, TestCallback, StatementCallback, IndentLevel + Indent1); - } - - // Handle statement. - StatementCallback(arg, IndentLevel); - } - - ++i; - even = !even; - } -} - -/// ExtractOptionNames - A helper function object used by -/// CheckForSuperfluousOptions() to walk the 'case' DAG. -class ExtractOptionNames { - llvm::StringSet<>& OptionNames_; - - void processDag(const Init* Statement) { - const DagInit& Stmt = InitPtrToDag(Statement); - const std::string& ActionName = GetOperatorName(Stmt); - if (ActionName == "forward" || ActionName == "forward_as" || - ActionName == "forward_value" || - ActionName == "forward_transformed_value" || - ActionName == "parameter_equals" || ActionName == "element_in_list") { - CheckNumberOfArguments(Stmt, 1); - - Init* Arg = Stmt.getArg(0); - if (typeid(*Arg) == typeid(StringInit)) - OptionNames_.insert(InitPtrToString(Arg)); - } - else if (ActionName == "any_switch_on" || ActionName == "switch_on" || - ActionName == "any_not_empty" || ActionName == "any_empty" || - ActionName == "not_empty" || ActionName == "empty") { - for (unsigned i = 0, NumArgs = Stmt.getNumArgs(); i < NumArgs; ++i) { - Init* Arg = Stmt.getArg(i); - if (typeid(*Arg) == typeid(StringInit)) - OptionNames_.insert(InitPtrToString(Arg)); - } - } - else if (ActionName == "and" || ActionName == "or" || ActionName == "not") { - for (unsigned i = 0, NumArgs = Stmt.getNumArgs(); i < NumArgs; ++i) { - this->processDag(Stmt.getArg(i)); - } - } - } - -public: - ExtractOptionNames(llvm::StringSet<>& OptionNames) : OptionNames_(OptionNames) - {} - - void operator()(const Init* Statement) { - // Statement is either a dag, or a list of dags. - if (typeid(*Statement) == typeid(ListInit)) { - const ListInit& DagList = *static_cast(Statement); - for (ListInit::const_iterator B = DagList.begin(), E = DagList.end(); - B != E; ++B) - this->processDag(*B); - } - else { - this->processDag(Statement); - } - } - - void operator()(const DagInit& Test, unsigned, bool) { - this->operator()(&Test); - } - void operator()(const Init* Statement, unsigned) { - this->operator()(Statement); - } -}; - -/// IsOptionalEdge - Validate that the 'optional_edge' has proper structure. -bool IsOptionalEdge (const DagInit& Edg) { - return (GetOperatorName(Edg) == "optional_edge") && (Edg.getNumArgs() > 2); -} - -/// CheckForSuperfluousOptions - Check that there are no side -/// effect-free options (specified only in the OptionList). Otherwise, -/// output a warning. -void CheckForSuperfluousOptions (const DagVector& EdgeVector, - const ToolDescriptions& ToolDescs, - const OptionDescriptions& OptDescs) { - llvm::StringSet<> nonSuperfluousOptions; - - // Add all options mentioned in the ToolDesc.Actions to the set of - // non-superfluous options. - for (ToolDescriptions::const_iterator B = ToolDescs.begin(), - E = ToolDescs.end(); B != E; ++B) { - const ToolDescription& TD = *(*B); - ExtractOptionNames Callback(nonSuperfluousOptions); - if (TD.Actions) - WalkCase(TD.Actions, Callback, Callback); - } - - // Add all options mentioned in the 'case' clauses of the - // OptionalEdges of the compilation graph to the set of - // non-superfluous options. - for (DagVector::const_iterator B = EdgeVector.begin(), - E = EdgeVector.end(); B != E; ++B) { - const DagInit& Edge = **B; - if (IsOptionalEdge(Edge)) { - const DagInit& Weight = InitPtrToDag(Edge.getArg(2)); - WalkCase(&Weight, ExtractOptionNames(nonSuperfluousOptions), Id()); - } - } - - // Check that all options in OptDescs belong to the set of - // non-superfluous options. - for (OptionDescriptions::const_iterator B = OptDescs.begin(), - E = OptDescs.end(); B != E; ++B) { - const OptionDescription& Val = B->second; - if (!nonSuperfluousOptions.count(Val.Name) - && Val.Type != OptionType::Alias) - llvm::errs() << "Warning: option '-" << Val.Name << "' has no effect! " - "Probable cause: this option is specified only in the OptionList.\n"; - } -} - -/// EmitCaseTest0Args - Helper function used by EmitCaseConstructHandler(). -bool EmitCaseTest0Args(const std::string& TestName, raw_ostream& O) { - if (TestName == "single_input_file") { - O << "InputFilenames.size() == 1"; - return true; - } - else if (TestName == "multiple_input_files") { - O << "InputFilenames.size() > 1"; - return true; - } - - return false; -} - -/// EmitMultipleArgumentTest - Helper function used by -/// EmitCaseTestMultipleArgs() -template -void EmitMultipleArgumentTest(const DagInit& D, const char* LogicOp, - F Callback, raw_ostream& O) -{ - for (unsigned i = 0, NumArgs = D.getNumArgs(); i < NumArgs; ++i) { - if (i != 0) - O << ' ' << LogicOp << ' '; - Callback(InitPtrToString(D.getArg(i)), O); - } -} - -// Callbacks for use with EmitMultipleArgumentTest - -class EmitSwitchOn { - const OptionDescriptions& OptDescs_; -public: - EmitSwitchOn(const OptionDescriptions& OptDescs) : OptDescs_(OptDescs) - {} - - void operator()(const std::string& OptName, raw_ostream& O) const { - const OptionDescription& OptDesc = OptDescs_.FindSwitch(OptName); - O << OptDesc.GenVariableName(); - } -}; - -class EmitEmptyTest { - bool EmitNegate_; - const OptionDescriptions& OptDescs_; -public: - EmitEmptyTest(bool EmitNegate, const OptionDescriptions& OptDescs) - : EmitNegate_(EmitNegate), OptDescs_(OptDescs) - {} - - void operator()(const std::string& OptName, raw_ostream& O) const { - const char* Neg = (EmitNegate_ ? "!" : ""); - if (OptName == "o") { - O << Neg << "OutputFilename.empty()"; - } - else if (OptName == "save-temps") { - O << Neg << "(SaveTemps == SaveTempsEnum::Unset)"; - } - else { - const OptionDescription& OptDesc = OptDescs_.FindListOrParameter(OptName); - O << Neg << OptDesc.GenVariableName() << ".empty()"; - } - } -}; - - -/// EmitCaseTestMultipleArgs - Helper function used by EmitCaseTest1Arg() -bool EmitCaseTestMultipleArgs (const std::string& TestName, - const DagInit& d, - const OptionDescriptions& OptDescs, - raw_ostream& O) { - if (TestName == "any_switch_on") { - EmitMultipleArgumentTest(d, "||", EmitSwitchOn(OptDescs), O); - return true; - } - else if (TestName == "switch_on") { - EmitMultipleArgumentTest(d, "&&", EmitSwitchOn(OptDescs), O); - return true; - } - else if (TestName == "any_not_empty") { - EmitMultipleArgumentTest(d, "||", EmitEmptyTest(true, OptDescs), O); - return true; - } - else if (TestName == "any_empty") { - EmitMultipleArgumentTest(d, "||", EmitEmptyTest(false, OptDescs), O); - return true; - } - else if (TestName == "not_empty") { - EmitMultipleArgumentTest(d, "&&", EmitEmptyTest(true, OptDescs), O); - return true; - } - else if (TestName == "empty") { - EmitMultipleArgumentTest(d, "&&", EmitEmptyTest(false, OptDescs), O); - return true; - } - - return false; -} - -/// EmitCaseTest1Arg - Helper function used by EmitCaseTest1OrMoreArgs() -bool EmitCaseTest1Arg (const std::string& TestName, - const DagInit& d, - const OptionDescriptions& OptDescs, - raw_ostream& O) { - const std::string& Arg = InitPtrToString(d.getArg(0)); - - if (TestName == "input_languages_contain") { - O << "InLangs.count(\"" << Arg << "\") != 0"; - return true; - } - else if (TestName == "in_language") { - // This works only for single-argument Tool::GenerateAction. Join - // tools can process several files in different languages simultaneously. - - // TODO: make this work with Edge::Weight (if possible). - O << "LangMap.GetLanguage(inFile) == \"" << Arg << '\"'; - return true; - } - - return false; -} - -/// EmitCaseTest1OrMoreArgs - Helper function used by -/// EmitCaseConstructHandler() -bool EmitCaseTest1OrMoreArgs(const std::string& TestName, - const DagInit& d, - const OptionDescriptions& OptDescs, - raw_ostream& O) { - CheckNumberOfArguments(d, 1); - return EmitCaseTest1Arg(TestName, d, OptDescs, O) || - EmitCaseTestMultipleArgs(TestName, d, OptDescs, O); -} - -/// EmitCaseTest2Args - Helper function used by EmitCaseConstructHandler(). -bool EmitCaseTest2Args(const std::string& TestName, - const DagInit& d, - unsigned IndentLevel, - const OptionDescriptions& OptDescs, - raw_ostream& O) { - CheckNumberOfArguments(d, 2); - const std::string& OptName = InitPtrToString(d.getArg(0)); - const std::string& OptArg = InitPtrToString(d.getArg(1)); - - if (TestName == "parameter_equals") { - const OptionDescription& OptDesc = OptDescs.FindParameter(OptName); - O << OptDesc.GenVariableName() << " == \"" << OptArg << "\""; - return true; - } - else if (TestName == "element_in_list") { - const OptionDescription& OptDesc = OptDescs.FindParameterList(OptName); - const std::string& VarName = OptDesc.GenVariableName(); - O << "std::find(" << VarName << ".begin(),\n"; - O.indent(IndentLevel + Indent1) - << VarName << ".end(), \"" - << OptArg << "\") != " << VarName << ".end()"; - return true; - } - - return false; -} - -// Forward declaration. -// EmitLogicalOperationTest and EmitCaseTest are mutually recursive. -void EmitCaseTest(const DagInit& d, unsigned IndentLevel, - const OptionDescriptions& OptDescs, - raw_ostream& O); - -/// EmitLogicalOperationTest - Helper function used by -/// EmitCaseConstructHandler. -void EmitLogicalOperationTest(const DagInit& d, const char* LogicOp, - unsigned IndentLevel, - const OptionDescriptions& OptDescs, - raw_ostream& O) { - O << '('; - for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) { - const DagInit& InnerTest = InitPtrToDag(d.getArg(i)); - EmitCaseTest(InnerTest, IndentLevel, OptDescs, O); - if (i != NumArgs - 1) { - O << ")\n"; - O.indent(IndentLevel + Indent1) << ' ' << LogicOp << " ("; - } - else { - O << ')'; - } - } -} - -void EmitLogicalNot(const DagInit& d, unsigned IndentLevel, - const OptionDescriptions& OptDescs, raw_ostream& O) -{ - CheckNumberOfArguments(d, 1); - const DagInit& InnerTest = InitPtrToDag(d.getArg(0)); - O << "! ("; - EmitCaseTest(InnerTest, IndentLevel, OptDescs, O); - O << ")"; -} - -/// EmitCaseTest - Helper function used by EmitCaseConstructHandler. -void EmitCaseTest(const DagInit& d, unsigned IndentLevel, - const OptionDescriptions& OptDescs, - raw_ostream& O) { - const std::string& TestName = GetOperatorName(d); - - if (TestName == "and") - EmitLogicalOperationTest(d, "&&", IndentLevel, OptDescs, O); - else if (TestName == "or") - EmitLogicalOperationTest(d, "||", IndentLevel, OptDescs, O); - else if (TestName == "not") - EmitLogicalNot(d, IndentLevel, OptDescs, O); - else if (EmitCaseTest0Args(TestName, O)) - return; - else if (EmitCaseTest1OrMoreArgs(TestName, d, OptDescs, O)) - return; - else if (EmitCaseTest2Args(TestName, d, IndentLevel, OptDescs, O)) - return; - else - throw "Unknown test '" + TestName + "' used in the 'case' construct!"; -} - - -/// EmitCaseTestCallback - Callback used by EmitCaseConstructHandler. -class EmitCaseTestCallback { - bool EmitElseIf_; - const OptionDescriptions& OptDescs_; - raw_ostream& O_; -public: - - EmitCaseTestCallback(bool EmitElseIf, - const OptionDescriptions& OptDescs, raw_ostream& O) - : EmitElseIf_(EmitElseIf), OptDescs_(OptDescs), O_(O) - {} - - void operator()(const DagInit& Test, unsigned IndentLevel, bool FirstTest) - { - if (GetOperatorName(Test) == "default") { - O_.indent(IndentLevel) << "else {\n"; - } - else { - O_.indent(IndentLevel) - << ((!FirstTest && EmitElseIf_) ? "else if (" : "if ("); - EmitCaseTest(Test, IndentLevel, OptDescs_, O_); - O_ << ") {\n"; - } - } -}; - -/// EmitCaseStatementCallback - Callback used by EmitCaseConstructHandler. -template -class EmitCaseStatementCallback { - F Callback_; - raw_ostream& O_; -public: - - EmitCaseStatementCallback(F Callback, raw_ostream& O) - : Callback_(Callback), O_(O) - {} - - void operator() (const Init* Statement, unsigned IndentLevel) { - // Is this a nested 'case'? - bool IsCase = dynamic_cast(Statement) && - GetOperatorName(static_cast(*Statement)) == "case"; - - // If so, ignore it, it is handled by our caller, WalkCase. - if (!IsCase) { - if (typeid(*Statement) == typeid(ListInit)) { - const ListInit& DagList = *static_cast(Statement); - for (ListInit::const_iterator B = DagList.begin(), E = DagList.end(); - B != E; ++B) - Callback_(*B, (IndentLevel + Indent1), O_); - } - else { - Callback_(Statement, (IndentLevel + Indent1), O_); - } - } - O_.indent(IndentLevel) << "}\n"; - } - -}; - -/// EmitCaseConstructHandler - Emit code that handles the 'case' -/// construct. Takes a function object that should emit code for every case -/// clause. Implemented on top of WalkCase. -/// Callback's type is void F(const Init* Statement, unsigned IndentLevel, -/// raw_ostream& O). -/// EmitElseIf parameter controls the type of condition that is emitted ('if -/// (..) {..} else if (..) {} .. else {..}' vs. 'if (..) {..} if(..) {..} -/// .. else {..}'). -template -void EmitCaseConstructHandler(const Init* Case, unsigned IndentLevel, - F Callback, bool EmitElseIf, - const OptionDescriptions& OptDescs, - raw_ostream& O) { - WalkCase(Case, EmitCaseTestCallback(EmitElseIf, OptDescs, O), - EmitCaseStatementCallback(Callback, O), IndentLevel); -} - -/// TokenizeCmdLine - converts from -/// "$CALL(HookName, 'Arg1', 'Arg2')/path -arg1 -arg2" to -/// ["$CALL(", "HookName", "Arg1", "Arg2", ")/path", "-arg1", "-arg2"]. -void TokenizeCmdLine(const std::string& CmdLine, StrVector& Out) { - const char* Delimiters = " \t\n\v\f\r"; - enum TokenizerState - { Normal, SpecialCommand, InsideSpecialCommand, InsideQuotationMarks } - cur_st = Normal; - - if (CmdLine.empty()) - return; - Out.push_back(""); - - std::string::size_type B = CmdLine.find_first_not_of(Delimiters), - E = CmdLine.size(); - - for (; B != E; ++B) { - char cur_ch = CmdLine[B]; - - switch (cur_st) { - case Normal: - if (cur_ch == '$') { - cur_st = SpecialCommand; - break; - } - if (OneOf(Delimiters, cur_ch)) { - // Skip whitespace - B = CmdLine.find_first_not_of(Delimiters, B); - if (B == std::string::npos) { - B = E-1; - continue; - } - --B; - Out.push_back(""); - continue; - } - break; - - - case SpecialCommand: - if (OneOf(Delimiters, cur_ch)) { - cur_st = Normal; - Out.push_back(""); - continue; - } - if (cur_ch == '(') { - Out.push_back(""); - cur_st = InsideSpecialCommand; - continue; - } - break; - - case InsideSpecialCommand: - if (OneOf(Delimiters, cur_ch)) { - continue; - } - if (cur_ch == '\'') { - cur_st = InsideQuotationMarks; - Out.push_back(""); - continue; - } - if (cur_ch == ')') { - cur_st = Normal; - Out.push_back(""); - } - if (cur_ch == ',') { - continue; - } - - break; - - case InsideQuotationMarks: - if (cur_ch == '\'') { - cur_st = InsideSpecialCommand; - continue; - } - break; - } - - Out.back().push_back(cur_ch); - } -} - -/// SubstituteCall - Given "$CALL(HookName, [Arg1 [, Arg2 [...]]])", output -/// "hooks::HookName([Arg1 [, Arg2 [, ...]]])". Helper function used by -/// SubstituteSpecialCommands(). -StrVector::const_iterator -SubstituteCall (StrVector::const_iterator Pos, - StrVector::const_iterator End, - bool IsJoin, raw_ostream& O) -{ - const char* errorMessage = "Syntax error in $CALL invocation!"; - CheckedIncrement(Pos, End, errorMessage); - const std::string& CmdName = *Pos; - - if (CmdName == ")") - throw "$CALL invocation: empty argument list!"; - - O << "hooks::"; - O << CmdName << "("; - - - bool firstIteration = true; - while (true) { - CheckedIncrement(Pos, End, errorMessage); - const std::string& Arg = *Pos; - assert(Arg.size() != 0); - - if (Arg[0] == ')') - break; - - if (firstIteration) - firstIteration = false; - else - O << ", "; - - if (Arg == "$INFILE") { - if (IsJoin) - throw "$CALL(Hook, $INFILE) can't be used with a Join tool!"; - else - O << "inFile.c_str()"; - } - else { - O << '"' << Arg << '"'; - } - } - - O << ')'; - - return Pos; -} - -/// SubstituteEnv - Given '$ENV(VAR_NAME)', output 'getenv("VAR_NAME")'. Helper -/// function used by SubstituteSpecialCommands(). -StrVector::const_iterator -SubstituteEnv (StrVector::const_iterator Pos, - StrVector::const_iterator End, raw_ostream& O) -{ - const char* errorMessage = "Syntax error in $ENV invocation!"; - CheckedIncrement(Pos, End, errorMessage); - const std::string& EnvName = *Pos; - - if (EnvName == ")") - throw "$ENV invocation: empty argument list!"; - - O << "checkCString(std::getenv(\""; - O << EnvName; - O << "\"))"; - - CheckedIncrement(Pos, End, errorMessage); - - return Pos; -} - -/// SubstituteSpecialCommands - Given an invocation of $CALL or $ENV, output -/// handler code. Helper function used by EmitCmdLineVecFill(). -StrVector::const_iterator -SubstituteSpecialCommands (StrVector::const_iterator Pos, - StrVector::const_iterator End, - bool IsJoin, raw_ostream& O) -{ - - const std::string& cmd = *Pos; - - // Perform substitution. - if (cmd == "$CALL") { - Pos = SubstituteCall(Pos, End, IsJoin, O); - } - else if (cmd == "$ENV") { - Pos = SubstituteEnv(Pos, End, O); - } - else { - throw "Unknown special command: " + cmd; - } - - // Handle '$CMD(ARG)/additional/text'. - const std::string& Leftover = *Pos; - assert(Leftover.at(0) == ')'); - if (Leftover.size() != 1) - O << " + std::string(\"" << (Leftover.c_str() + 1) << "\")"; - - return Pos; -} - -/// EmitCmdLineVecFill - Emit code that fills in the command line -/// vector. Helper function used by EmitGenerateActionMethod(). -void EmitCmdLineVecFill(const Init* CmdLine, const std::string& ToolName, - bool IsJoin, unsigned IndentLevel, - raw_ostream& O) { - StrVector StrVec; - TokenizeCmdLine(InitPtrToString(CmdLine), StrVec); - - if (StrVec.empty()) - throw "Tool '" + ToolName + "' has empty command line!"; - - StrVector::const_iterator B = StrVec.begin(), E = StrVec.end(); - - // Emit the command itself. - assert(!StrVec[0].empty()); - O.indent(IndentLevel) << "cmd = "; - if (StrVec[0][0] == '$') { - B = SubstituteSpecialCommands(B, E, IsJoin, O); - ++B; - } - else { - O << '"' << StrVec[0] << '"'; - ++B; - } - O << ";\n"; - - // Go through the command arguments. - assert(B <= E); - for (; B != E; ++B) { - const std::string& cmd = *B; - - assert(!cmd.empty()); - O.indent(IndentLevel); - - if (cmd.at(0) == '$') { - O << "vec.push_back(std::make_pair(0, "; - B = SubstituteSpecialCommands(B, E, IsJoin, O); - O << "));\n"; - } - else { - O << "vec.push_back(std::make_pair(0, \"" << cmd << "\"));\n"; - } - } - -} - -/// EmitForEachListElementCycleHeader - Emit common code for iterating through -/// all elements of a list. Helper function used by -/// EmitForwardOptionPropertyHandlingCode. -void EmitForEachListElementCycleHeader (const OptionDescription& D, - unsigned IndentLevel, - raw_ostream& O) { - unsigned IndentLevel1 = IndentLevel + Indent1; - - O.indent(IndentLevel) - << "for (" << D.GenTypeDeclaration() - << "::iterator B = " << D.GenVariableName() << ".begin(),\n"; - O.indent(IndentLevel) - << "E = " << D.GenVariableName() << ".end(); B != E;) {\n"; - O.indent(IndentLevel1) << "unsigned pos = " << D.GenVariableName() - << ".getPosition(B - " << D.GenVariableName() - << ".begin());\n"; -} - -/// EmitForwardOptionPropertyHandlingCode - Helper function used to -/// implement EmitActionHandler. Emits code for -/// handling the (forward) and (forward_as) option properties. -void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D, - unsigned IndentLevel, - const std::string& NewName, - raw_ostream& O) { - const std::string& Name = NewName.empty() - ? ("-" + D.Name) - : NewName; - unsigned IndentLevel1 = IndentLevel + Indent1; - - switch (D.Type) { - case OptionType::Switch: - O.indent(IndentLevel) - << "vec.push_back(std::make_pair(" << D.GenVariableName() - << ".getPosition(), \"" << Name << "\"));\n"; - break; - case OptionType::Parameter: - O.indent(IndentLevel) << "vec.push_back(std::make_pair(" - << D.GenVariableName() - <<".getPosition(), \"" << Name; - - if (!D.isForwardNotSplit()) { - O << "\"));\n"; - O.indent(IndentLevel) << "vec.push_back(std::make_pair(" - << D.GenVariableName() << ".getPosition(), " - << D.GenVariableName() << "));\n"; - } - else { - O << "=\" + " << D.GenVariableName() << "));\n"; - } - break; - case OptionType::Prefix: - O.indent(IndentLevel) << "vec.push_back(std::make_pair(" - << D.GenVariableName() << ".getPosition(), \"" - << Name << "\" + " - << D.GenVariableName() << "));\n"; - break; - case OptionType::PrefixList: - EmitForEachListElementCycleHeader(D, IndentLevel, O); - O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \"" - << Name << "\" + " << "*B));\n"; - O.indent(IndentLevel1) << "++B;\n"; - - for (int i = 1, j = D.MultiVal; i < j; ++i) { - O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, *B));\n"; - O.indent(IndentLevel1) << "++B;\n"; - } - - O.indent(IndentLevel) << "}\n"; - break; - case OptionType::ParameterList: - EmitForEachListElementCycleHeader(D, IndentLevel, O); - O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \"" - << Name << "\"));\n"; - - for (int i = 0, j = D.MultiVal; i < j; ++i) { - O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, *B));\n"; - O.indent(IndentLevel1) << "++B;\n"; - } - - O.indent(IndentLevel) << "}\n"; - break; - case OptionType::SwitchList: - EmitForEachListElementCycleHeader(D, IndentLevel, O); - O.indent(IndentLevel1) << "vec.push_back(std::make_pair(pos, \"" - << Name << "\"));\n"; - O.indent(IndentLevel1) << "++B;\n"; - O.indent(IndentLevel) << "}\n"; - break; - case OptionType::Alias: - default: - throw "Aliases are not allowed in tool option descriptions!"; - } -} - -/// ActionHandlingCallbackBase - Base class of EmitActionHandlersCallback and -/// EmitPreprocessOptionsCallback. -struct ActionHandlingCallbackBase -{ - - void onErrorDag(const DagInit& d, - unsigned IndentLevel, raw_ostream& O) const - { - O.indent(IndentLevel) - << "PrintError(\"" - << (d.getNumArgs() >= 1 ? InitPtrToString(d.getArg(0)) : "Unknown error!") - << "\");\n"; - O.indent(IndentLevel) << "return 1;\n"; - } - - void onWarningDag(const DagInit& d, - unsigned IndentLevel, raw_ostream& O) const - { - CheckNumberOfArguments(d, 1); - O.indent(IndentLevel) << "llvm::errs() << \"" - << InitPtrToString(d.getArg(0)) << "\";\n"; - } - -}; - -/// EmitActionHandlersCallback - Emit code that handles actions. Used by -/// EmitGenerateActionMethod() as an argument to EmitCaseConstructHandler(). -class EmitActionHandlersCallback; - -typedef void (EmitActionHandlersCallback::* EmitActionHandlersCallbackHandler) -(const DagInit&, unsigned, raw_ostream&) const; - -class EmitActionHandlersCallback : - public ActionHandlingCallbackBase, - public HandlerTable -{ - typedef EmitActionHandlersCallbackHandler Handler; - - const OptionDescriptions& OptDescs; - - /// EmitHookInvocation - Common code for hook invocation from actions. Used by - /// onAppendCmd and onOutputSuffix. - void EmitHookInvocation(const std::string& Str, - const char* BlockOpen, const char* BlockClose, - unsigned IndentLevel, raw_ostream& O) const - { - StrVector Out; - TokenizeCmdLine(Str, Out); - - for (StrVector::const_iterator B = Out.begin(), E = Out.end(); - B != E; ++B) { - const std::string& cmd = *B; - - O.indent(IndentLevel) << BlockOpen; - - if (cmd.at(0) == '$') - B = SubstituteSpecialCommands(B, E, /* IsJoin = */ true, O); - else - O << '"' << cmd << '"'; - - O << BlockClose; - } - } - - void onAppendCmd (const DagInit& Dag, - unsigned IndentLevel, raw_ostream& O) const - { - CheckNumberOfArguments(Dag, 1); - this->EmitHookInvocation(InitPtrToString(Dag.getArg(0)), - "vec.push_back(std::make_pair(65536, ", "));\n", - IndentLevel, O); - } - - void onForward (const DagInit& Dag, - unsigned IndentLevel, raw_ostream& O) const - { - CheckNumberOfArguments(Dag, 1); - const std::string& Name = InitPtrToString(Dag.getArg(0)); - EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name), - IndentLevel, "", O); - } - - void onForwardAs (const DagInit& Dag, - unsigned IndentLevel, raw_ostream& O) const - { - CheckNumberOfArguments(Dag, 2); - const std::string& Name = InitPtrToString(Dag.getArg(0)); - const std::string& NewName = InitPtrToString(Dag.getArg(1)); - EmitForwardOptionPropertyHandlingCode(OptDescs.FindOption(Name), - IndentLevel, NewName, O); - } - - void onForwardValue (const DagInit& Dag, - unsigned IndentLevel, raw_ostream& O) const - { - CheckNumberOfArguments(Dag, 1); - const std::string& Name = InitPtrToString(Dag.getArg(0)); - const OptionDescription& D = OptDescs.FindParameterListOrParameter(Name); - - if (D.isSwitchList()) { - throw std::runtime_error - ("forward_value is not allowed with switch_list"); - } - - if (D.isParameter()) { - O.indent(IndentLevel) << "vec.push_back(std::make_pair(" - << D.GenVariableName() << ".getPosition(), " - << D.GenVariableName() << "));\n"; - } - else { - O.indent(IndentLevel) << "for (" << D.GenTypeDeclaration() - << "::iterator B = " << D.GenVariableName() - << ".begin(), \n"; - O.indent(IndentLevel + Indent1) << " E = " << D.GenVariableName() - << ".end(); B != E; ++B)\n"; - O.indent(IndentLevel) << "{\n"; - O.indent(IndentLevel + Indent1) - << "unsigned pos = " << D.GenVariableName() - << ".getPosition(B - " << D.GenVariableName() - << ".begin());\n"; - O.indent(IndentLevel + Indent1) - << "vec.push_back(std::make_pair(pos, *B));\n"; - O.indent(IndentLevel) << "}\n"; - } - } - - void onForwardTransformedValue (const DagInit& Dag, - unsigned IndentLevel, raw_ostream& O) const - { - CheckNumberOfArguments(Dag, 2); - const std::string& Name = InitPtrToString(Dag.getArg(0)); - const std::string& Hook = InitPtrToString(Dag.getArg(1)); - const OptionDescription& D = OptDescs.FindParameterListOrParameter(Name); - - O.indent(IndentLevel) << "vec.push_back(std::make_pair(" - << D.GenVariableName() << ".getPosition(" - << (D.isList() ? "0" : "") << "), " - << "hooks::" << Hook << "(" << D.GenVariableName() - << (D.isParameter() ? ".c_str()" : "") << ")));\n"; - } - - void onNoOutFile (const DagInit& Dag, - unsigned IndentLevel, raw_ostream& O) const - { - CheckNumberOfArguments(Dag, 0); - O.indent(IndentLevel) << "no_out_file = true;\n"; - } - - void onOutputSuffix (const DagInit& Dag, - unsigned IndentLevel, raw_ostream& O) const - { - CheckNumberOfArguments(Dag, 1); - this->EmitHookInvocation(InitPtrToString(Dag.getArg(0)), - "output_suffix = ", ";\n", IndentLevel, O); - } - - void onStopCompilation (const DagInit& Dag, - unsigned IndentLevel, raw_ostream& O) const - { - O.indent(IndentLevel) << "stop_compilation = true;\n"; - } - - - void onUnpackValues (const DagInit& Dag, - unsigned IndentLevel, raw_ostream& O) const - { - throw "'unpack_values' is deprecated. " - "Use 'comma_separated' + 'forward_value' instead!"; - } - - public: - - explicit EmitActionHandlersCallback(const OptionDescriptions& OD) - : OptDescs(OD) - { - if (!staticMembersInitialized_) { - AddHandler("error", &EmitActionHandlersCallback::onErrorDag); - AddHandler("warning", &EmitActionHandlersCallback::onWarningDag); - AddHandler("append_cmd", &EmitActionHandlersCallback::onAppendCmd); - AddHandler("forward", &EmitActionHandlersCallback::onForward); - AddHandler("forward_as", &EmitActionHandlersCallback::onForwardAs); - AddHandler("forward_value", &EmitActionHandlersCallback::onForwardValue); - AddHandler("forward_transformed_value", - &EmitActionHandlersCallback::onForwardTransformedValue); - AddHandler("no_out_file", - &EmitActionHandlersCallback::onNoOutFile); - AddHandler("output_suffix", &EmitActionHandlersCallback::onOutputSuffix); - AddHandler("stop_compilation", - &EmitActionHandlersCallback::onStopCompilation); - AddHandler("unpack_values", - &EmitActionHandlersCallback::onUnpackValues); - - - staticMembersInitialized_ = true; - } - } - - void operator()(const Init* I, - unsigned IndentLevel, raw_ostream& O) const - { - InvokeDagInitHandler(this, I, IndentLevel, O); - } -}; - -void EmitGenerateActionMethodHeader(const ToolDescription& D, - bool IsJoin, bool Naked, - raw_ostream& O) -{ - O.indent(Indent1) << "int GenerateAction(Action& Out,\n"; - - if (IsJoin) - O.indent(Indent2) << "const PathVector& inFiles,\n"; - else - O.indent(Indent2) << "const sys::Path& inFile,\n"; - - O.indent(Indent2) << "const bool HasChildren,\n"; - O.indent(Indent2) << "const llvm::sys::Path& TempDir,\n"; - O.indent(Indent2) << "const InputLanguagesSet& InLangs,\n"; - O.indent(Indent2) << "const LanguageMap& LangMap) const\n"; - O.indent(Indent1) << "{\n"; - - if (!Naked) { - O.indent(Indent2) << "std::string cmd;\n"; - O.indent(Indent2) << "std::string out_file;\n"; - O.indent(Indent2) - << "std::vector > vec;\n"; - O.indent(Indent2) << "bool stop_compilation = !HasChildren;\n"; - O.indent(Indent2) << "bool no_out_file = false;\n"; - O.indent(Indent2) << "std::string output_suffix(\"" - << D.OutputSuffix << "\");\n"; - } -} - -// EmitGenerateActionMethod - Emit either a normal or a "join" version of the -// Tool::GenerateAction() method. -void EmitGenerateActionMethod (const ToolDescription& D, - const OptionDescriptions& OptDescs, - bool IsJoin, raw_ostream& O) { - - EmitGenerateActionMethodHeader(D, IsJoin, /* Naked = */ false, O); - - if (!D.CmdLine) - throw "Tool " + D.Name + " has no cmd_line property!"; - - // Process the 'command' property. - O << '\n'; - EmitCmdLineVecFill(D.CmdLine, D.Name, IsJoin, Indent2, O); - O << '\n'; - - // Process the 'actions' list of this tool. - if (D.Actions) - EmitCaseConstructHandler(D.Actions, Indent2, - EmitActionHandlersCallback(OptDescs), - false, OptDescs, O); - O << '\n'; - - // Input file (s) - if (!D.InFileOption.empty()) { - O.indent(Indent2) - << "vec.push_back(std::make_pair(InputFilenames.getPosition(0), \"" - << D.InFileOption << "\");\n"; - } - - if (IsJoin) { - O.indent(Indent2) - << "for (PathVector::const_iterator B = inFiles.begin(),\n"; - O.indent(Indent3) << "E = inFiles.end(); B != E; ++B)\n"; - O.indent(Indent2) << "{\n"; - O.indent(Indent3) << "vec.push_back(std::make_pair(" - << "InputFilenames.getPosition(B - inFiles.begin()), " - << "B->str()));\n"; - O.indent(Indent2) << "}\n"; - } - else { - O.indent(Indent2) << "vec.push_back(std::make_pair(" - << "InputFilenames.getPosition(0), inFile.str()));\n"; - } - - // Output file - O.indent(Indent2) << "if (!no_out_file) {\n"; - if (!D.OutFileOption.empty()) - O.indent(Indent3) << "vec.push_back(std::make_pair(65536, \"" - << D.OutFileOption << "\"));\n"; - - O.indent(Indent3) << "out_file = this->OutFilename(" - << (IsJoin ? "sys::Path(),\n" : "inFile,\n"); - O.indent(Indent4) << - "TempDir, stop_compilation, output_suffix.c_str()).str();\n\n"; - O.indent(Indent3) << "vec.push_back(std::make_pair(65536, out_file));\n"; - - O.indent(Indent2) << "}\n\n"; - - // Handle the Sink property. - std::string SinkOption("autogenerated::"); - SinkOption += SinkOptionName; - if (D.isSink()) { - O.indent(Indent2) << "if (!" << SinkOption << ".empty()) {\n"; - O.indent(Indent3) << "for (cl::list::iterator B = " - << SinkOption << ".begin(), E = " << SinkOption - << ".end(); B != E; ++B)\n"; - O.indent(Indent4) << "vec.push_back(std::make_pair(" << SinkOption - << ".getPosition(B - " << SinkOption - << ".begin()), *B));\n"; - O.indent(Indent2) << "}\n"; - } - - O.indent(Indent2) << "Out.Construct(cmd, this->SortArgs(vec), " - << "stop_compilation, out_file);\n"; - O.indent(Indent2) << "return 0;\n"; - O.indent(Indent1) << "}\n\n"; -} - -/// EmitGenerateActionMethods - Emit two GenerateAction() methods for -/// a given Tool class. -void EmitGenerateActionMethods (const ToolDescription& ToolDesc, - const OptionDescriptions& OptDescs, - raw_ostream& O) { - if (!ToolDesc.isJoin()) { - EmitGenerateActionMethodHeader(ToolDesc, /* IsJoin = */ true, - /* Naked = */ true, O); - O.indent(Indent2) << "PrintError(\"" << ToolDesc.Name - << " is not a Join tool!\");\n"; - O.indent(Indent2) << "return -1;\n"; - O.indent(Indent1) << "}\n\n"; - } - else { - EmitGenerateActionMethod(ToolDesc, OptDescs, true, O); - } - - EmitGenerateActionMethod(ToolDesc, OptDescs, false, O); -} - -/// EmitInOutLanguageMethods - Emit the [Input,Output]Language() -/// methods for a given Tool class. -void EmitInOutLanguageMethods (const ToolDescription& D, raw_ostream& O) { - O.indent(Indent1) << "const char** InputLanguages() const {\n"; - O.indent(Indent2) << "return InputLanguages_;\n"; - O.indent(Indent1) << "}\n\n"; - - O.indent(Indent1) << "const char** OutputLanguages() const {\n"; - O.indent(Indent2) << "return OutputLanguages_;\n"; - O.indent(Indent1) << "}\n\n"; -} - -/// EmitNameMethod - Emit the Name() method for a given Tool class. -void EmitNameMethod (const ToolDescription& D, raw_ostream& O) { - O.indent(Indent1) << "const char* Name() const {\n"; - O.indent(Indent2) << "return \"" << D.Name << "\";\n"; - O.indent(Indent1) << "}\n\n"; -} - -/// EmitIsJoinMethod - Emit the IsJoin() method for a given Tool -/// class. -void EmitIsJoinMethod (const ToolDescription& D, raw_ostream& O) { - O.indent(Indent1) << "bool IsJoin() const {\n"; - if (D.isJoin()) - O.indent(Indent2) << "return true;\n"; - else - O.indent(Indent2) << "return false;\n"; - O.indent(Indent1) << "}\n\n"; -} - -/// EmitWorksOnEmptyCallback - Callback used by EmitWorksOnEmptyMethod in -/// conjunction with EmitCaseConstructHandler. -void EmitWorksOnEmptyCallback (const Init* Value, - unsigned IndentLevel, raw_ostream& O) { - CheckBooleanConstant(Value); - O.indent(IndentLevel) << "return " << Value->getAsString() << ";\n"; -} - -/// EmitWorksOnEmptyMethod - Emit the WorksOnEmpty() method for a given Tool -/// class. -void EmitWorksOnEmptyMethod (const ToolDescription& D, - const OptionDescriptions& OptDescs, - raw_ostream& O) -{ - O.indent(Indent1) << "bool WorksOnEmpty() const {\n"; - if (D.OnEmpty == 0) - O.indent(Indent2) << "return false;\n"; - else - EmitCaseConstructHandler(D.OnEmpty, Indent2, EmitWorksOnEmptyCallback, - /*EmitElseIf = */ true, OptDescs, O); - O.indent(Indent1) << "}\n\n"; -} - -/// EmitStrArray - Emit definition of a 'const char**' static member -/// variable. Helper used by EmitStaticMemberDefinitions(); -void EmitStrArray(const std::string& Name, const std::string& VarName, - const StrVector& StrVec, raw_ostream& O) { - O << "const char* " << Name << "::" << VarName << "[] = {"; - for (StrVector::const_iterator B = StrVec.begin(), E = StrVec.end(); - B != E; ++B) - O << '\"' << *B << "\", "; - O << "0};\n"; -} - -/// EmitStaticMemberDefinitions - Emit static member definitions for a -/// given Tool class. -void EmitStaticMemberDefinitions(const ToolDescription& D, raw_ostream& O) { - if (D.InLanguage.empty()) - throw "Tool " + D.Name + " has no 'in_language' property!"; - if (D.OutLanguage.empty()) - throw "Tool " + D.Name + " has no 'out_language' property!"; - - EmitStrArray(D.Name, "InputLanguages_", D.InLanguage, O); - EmitStrArray(D.Name, "OutputLanguages_", D.OutLanguage, O); - O << '\n'; -} - -/// EmitToolClassDefinition - Emit a Tool class definition. -void EmitToolClassDefinition (const ToolDescription& D, - const OptionDescriptions& OptDescs, - raw_ostream& O) { - if (D.Name == "root") - return; - - // Header - O << "class " << D.Name << " : public "; - if (D.isJoin()) - O << "JoinTool"; - else - O << "Tool"; - - O << " {\nprivate:\n"; - O.indent(Indent1) << "static const char* InputLanguages_[];\n"; - O.indent(Indent1) << "static const char* OutputLanguages_[];\n\n"; - - O << "public:\n"; - EmitNameMethod(D, O); - EmitInOutLanguageMethods(D, O); - EmitIsJoinMethod(D, O); - EmitWorksOnEmptyMethod(D, OptDescs, O); - EmitGenerateActionMethods(D, OptDescs, O); - - // Close class definition - O << "};\n"; - - EmitStaticMemberDefinitions(D, O); - -} - -/// EmitOptionDefinitions - Iterate over a list of option descriptions -/// and emit registration code. -void EmitOptionDefinitions (const OptionDescriptions& descs, - bool HasSink, raw_ostream& O) -{ - std::vector Aliases; - - // Emit static cl::Option variables. - for (OptionDescriptions::const_iterator B = descs.begin(), - E = descs.end(); B!=E; ++B) { - const OptionDescription& val = B->second; - - if (val.Type == OptionType::Alias) { - Aliases.push_back(val); - continue; - } - - O << val.GenTypeDeclaration() << ' ' - << val.GenPlainVariableName(); - - O << "(\"" << val.Name << "\"\n"; - - if (val.Type == OptionType::Prefix || val.Type == OptionType::PrefixList) - O << ", cl::Prefix"; - - if (val.isRequired()) { - if (val.isList() && !val.isMultiVal()) - O << ", cl::OneOrMore"; - else - O << ", cl::Required"; - } - - if (val.isOptional()) - O << ", cl::Optional"; - - if (val.isOneOrMore()) - O << ", cl::OneOrMore"; - - if (val.isZeroOrMore()) - O << ", cl::ZeroOrMore"; - - if (val.isReallyHidden()) - O << ", cl::ReallyHidden"; - else if (val.isHidden()) - O << ", cl::Hidden"; - - if (val.isCommaSeparated()) - O << ", cl::CommaSeparated"; - - if (val.MultiVal > 1) - O << ", cl::multi_val(" << val.MultiVal << ')'; - - if (val.InitVal) { - const std::string& str = val.InitVal->getAsString(); - O << ", cl::init(" << str << ')'; - } - - if (!val.Help.empty()) - O << ", cl::desc(\"" << val.Help << "\")"; - - O << ");\n\n"; - } - - // Emit the aliases (they should go after all the 'proper' options). - for (std::vector::const_iterator - B = Aliases.begin(), E = Aliases.end(); B != E; ++B) { - const OptionDescription& val = *B; - - O << val.GenTypeDeclaration() << ' ' - << val.GenPlainVariableName() - << "(\"" << val.Name << '\"'; - - const OptionDescription& D = descs.FindOption(val.Help); - O << ", cl::aliasopt(" << D.GenVariableName() << ")"; - - O << ", cl::desc(\"" << "An alias for -" + val.Help << "\"));\n"; - } - - // Emit the sink option. - if (HasSink) - O << "cl::list " << SinkOptionName << "(cl::Sink);\n"; - - O << '\n'; -} - -/// EmitPreprocessOptionsCallback - Helper function passed to -/// EmitCaseConstructHandler() by EmitPreprocessOptions(). - -class EmitPreprocessOptionsCallback; - -typedef void -(EmitPreprocessOptionsCallback::* EmitPreprocessOptionsCallbackHandler) -(const DagInit&, unsigned, raw_ostream&) const; - -class EmitPreprocessOptionsCallback : - public ActionHandlingCallbackBase, - public HandlerTable -{ - typedef EmitPreprocessOptionsCallbackHandler Handler; - typedef void - (EmitPreprocessOptionsCallback::* HandlerImpl) - (const Init*, unsigned, raw_ostream&) const; - - const OptionDescriptions& OptDescs_; - - void onEachArgument(const DagInit& d, HandlerImpl h, - unsigned IndentLevel, raw_ostream& O) const - { - CheckNumberOfArguments(d, 1); - - for (unsigned i = 0, NumArgs = d.getNumArgs(); i < NumArgs; ++i) { - ((this)->*(h))(d.getArg(i), IndentLevel, O); - } - } - - void onUnsetOptionImpl(const Init* I, - unsigned IndentLevel, raw_ostream& O) const - { - const std::string& OptName = InitPtrToString(I); - const OptionDescription& OptDesc = OptDescs_.FindOption(OptName); - - if (OptDesc.isSwitch()) { - O.indent(IndentLevel) << OptDesc.GenVariableName() << " = false;\n"; - } - else if (OptDesc.isParameter()) { - O.indent(IndentLevel) << OptDesc.GenVariableName() << " = \"\";\n"; - } - else if (OptDesc.isList()) { - O.indent(IndentLevel) << OptDesc.GenVariableName() << ".clear();\n"; - } - else { - throw "Can't apply 'unset_option' to alias option '" + OptName + "'!"; - } - } - - void onUnsetOption(const DagInit& d, - unsigned IndentLevel, raw_ostream& O) const - { - this->onEachArgument(d, &EmitPreprocessOptionsCallback::onUnsetOptionImpl, - IndentLevel, O); - } - - void onSetOptionImpl(const DagInit& D, - unsigned IndentLevel, raw_ostream& O) const { - CheckNumberOfArguments(D, 2); - - const std::string& OptName = InitPtrToString(D.getArg(0)); - const OptionDescription& OptDesc = OptDescs_.FindOption(OptName); - const Init* Value = D.getArg(1); - - if (OptDesc.isList()) { - const ListInit& List = InitPtrToList(Value); - - O.indent(IndentLevel) << OptDesc.GenVariableName() << ".clear();\n"; - for (ListInit::const_iterator B = List.begin(), E = List.end(); - B != E; ++B) { - const Init* CurElem = *B; - if (OptDesc.isSwitchList()) - CheckBooleanConstant(CurElem); - - O.indent(IndentLevel) - << OptDesc.GenVariableName() << ".push_back(\"" - << (OptDesc.isSwitchList() ? CurElem->getAsString() - : InitPtrToString(CurElem)) - << "\");\n"; - } - } - else if (OptDesc.isSwitch()) { - CheckBooleanConstant(Value); - O.indent(IndentLevel) << OptDesc.GenVariableName() - << " = " << Value->getAsString() << ";\n"; - } - else if (OptDesc.isParameter()) { - const std::string& Str = InitPtrToString(Value); - O.indent(IndentLevel) << OptDesc.GenVariableName() - << " = \"" << Str << "\";\n"; - } - else { - throw "Can't apply 'set_option' to alias option '" + OptName + "'!"; - } - } - - void onSetSwitch(const Init* I, - unsigned IndentLevel, raw_ostream& O) const { - const std::string& OptName = InitPtrToString(I); - const OptionDescription& OptDesc = OptDescs_.FindOption(OptName); - - if (OptDesc.isSwitch()) - O.indent(IndentLevel) << OptDesc.GenVariableName() << " = true;\n"; - else - throw "set_option: -" + OptName + " is not a switch option!"; - } - - void onSetOption(const DagInit& d, - unsigned IndentLevel, raw_ostream& O) const - { - CheckNumberOfArguments(d, 1); - - // 2-argument form: (set_option "A", true), (set_option "B", "C"), - // (set_option "D", ["E", "F"]) - if (d.getNumArgs() == 2) { - const OptionDescription& OptDesc = - OptDescs_.FindOption(InitPtrToString(d.getArg(0))); - const Init* Opt2 = d.getArg(1); - - if (!OptDesc.isSwitch() || typeid(*Opt2) != typeid(StringInit)) { - this->onSetOptionImpl(d, IndentLevel, O); - return; - } - } - - // Multiple argument form: (set_option "A"), (set_option "B", "C", "D") - this->onEachArgument(d, &EmitPreprocessOptionsCallback::onSetSwitch, - IndentLevel, O); - } - -public: - - EmitPreprocessOptionsCallback(const OptionDescriptions& OptDescs) - : OptDescs_(OptDescs) - { - if (!staticMembersInitialized_) { - AddHandler("error", &EmitPreprocessOptionsCallback::onErrorDag); - AddHandler("warning", &EmitPreprocessOptionsCallback::onWarningDag); - AddHandler("unset_option", &EmitPreprocessOptionsCallback::onUnsetOption); - AddHandler("set_option", &EmitPreprocessOptionsCallback::onSetOption); - - staticMembersInitialized_ = true; - } - } - - void operator()(const Init* I, - unsigned IndentLevel, raw_ostream& O) const - { - InvokeDagInitHandler(this, I, IndentLevel, O); - } - -}; - -/// EmitPreprocessOptions - Emit the PreprocessOptions() function. -void EmitPreprocessOptions (const RecordKeeper& Records, - const OptionDescriptions& OptDecs, raw_ostream& O) -{ - O << "int PreprocessOptions () {\n"; - - const RecordVector& OptionPreprocessors = - Records.getAllDerivedDefinitions("OptionPreprocessor"); - - for (RecordVector::const_iterator B = OptionPreprocessors.begin(), - E = OptionPreprocessors.end(); B!=E; ++B) { - DagInit* Case = (*B)->getValueAsDag("preprocessor"); - EmitCaseConstructHandler(Case, Indent1, - EmitPreprocessOptionsCallback(OptDecs), - false, OptDecs, O); - } - - O << '\n'; - O.indent(Indent1) << "return 0;\n"; - O << "}\n\n"; -} - -class DoEmitPopulateLanguageMap; -typedef void (DoEmitPopulateLanguageMap::* DoEmitPopulateLanguageMapHandler) -(const DagInit& D); - -class DoEmitPopulateLanguageMap -: public HandlerTable -{ -private: - raw_ostream& O_; - -public: - - explicit DoEmitPopulateLanguageMap (raw_ostream& O) : O_(O) { - if (!staticMembersInitialized_) { - AddHandler("lang_to_suffixes", - &DoEmitPopulateLanguageMap::onLangToSuffixes); - - staticMembersInitialized_ = true; - } - } - - void operator() (Init* I) { - InvokeDagInitHandler(this, I); - } - -private: - - void onLangToSuffixes (const DagInit& d) { - CheckNumberOfArguments(d, 2); - - const std::string& Lang = InitPtrToString(d.getArg(0)); - Init* Suffixes = d.getArg(1); - - // Second argument to lang_to_suffixes is either a single string... - if (typeid(*Suffixes) == typeid(StringInit)) { - O_.indent(Indent1) << "langMap[\"" << InitPtrToString(Suffixes) - << "\"] = \"" << Lang << "\";\n"; - } - // ...or a list of strings. - else { - const ListInit& Lst = InitPtrToList(Suffixes); - assert(Lst.size() != 0); - for (ListInit::const_iterator B = Lst.begin(), E = Lst.end(); - B != E; ++B) { - O_.indent(Indent1) << "langMap[\"" << InitPtrToString(*B) - << "\"] = \"" << Lang << "\";\n"; - } - } - } - -}; - -/// EmitPopulateLanguageMap - Emit the PopulateLanguageMap() function. -void EmitPopulateLanguageMap (const RecordKeeper& Records, raw_ostream& O) -{ - O << "int PopulateLanguageMap (LanguageMap& langMap) {\n"; - - // For each LanguageMap: - const RecordVector& LangMaps = - Records.getAllDerivedDefinitions("LanguageMap"); - - // Call DoEmitPopulateLanguageMap. - for (RecordVector::const_iterator B = LangMaps.begin(), - E = LangMaps.end(); B!=E; ++B) { - ListInit* LangMap = (*B)->getValueAsListInit("map"); - std::for_each(LangMap->begin(), LangMap->end(), - DoEmitPopulateLanguageMap(O)); - } - - O << '\n'; - O.indent(Indent1) << "return 0;\n"; - O << "}\n\n"; -} - -/// EmitEdgePropertyHandlerCallback - Emits code that handles edge -/// properties. Helper function passed to EmitCaseConstructHandler() by -/// EmitEdgeClass(). -void EmitEdgePropertyHandlerCallback (const Init* i, unsigned IndentLevel, - raw_ostream& O) { - const DagInit& d = InitPtrToDag(i); - const std::string& OpName = GetOperatorName(d); - - if (OpName == "inc_weight") { - O.indent(IndentLevel) << "ret += "; - } - else if (OpName == "error") { - CheckNumberOfArguments(d, 1); - O.indent(IndentLevel) << "PrintError(\"" - << InitPtrToString(d.getArg(0)) - << "\");\n"; - O.indent(IndentLevel) << "return -1;\n"; - return; - } - else { - throw "Unknown operator in edge properties list: '" + OpName + "'!" - "\nOnly 'inc_weight', 'dec_weight' and 'error' are allowed."; - } - - if (d.getNumArgs() > 0) - O << InitPtrToInt(d.getArg(0)) << ";\n"; - else - O << "2;\n"; - -} - -/// EmitEdgeClass - Emit a single Edge# class. -void EmitEdgeClass (unsigned N, const std::string& Target, - const DagInit& Case, const OptionDescriptions& OptDescs, - raw_ostream& O) { - - // Class constructor. - O << "class Edge" << N << ": public Edge {\n" - << "public:\n"; - O.indent(Indent1) << "Edge" << N << "() : Edge(\"" << Target - << "\") {}\n\n"; - - // Function Weight(). - O.indent(Indent1) - << "int Weight(const InputLanguagesSet& InLangs) const {\n"; - O.indent(Indent2) << "unsigned ret = 0;\n"; - - // Handle the 'case' construct. - EmitCaseConstructHandler(&Case, Indent2, EmitEdgePropertyHandlerCallback, - false, OptDescs, O); - - O.indent(Indent2) << "return ret;\n"; - O.indent(Indent1) << "}\n\n};\n\n"; -} - -/// EmitEdgeClasses - Emit Edge* classes that represent graph edges. -void EmitEdgeClasses (const DagVector& EdgeVector, - const OptionDescriptions& OptDescs, - raw_ostream& O) { - int i = 0; - for (DagVector::const_iterator B = EdgeVector.begin(), - E = EdgeVector.end(); B != E; ++B) { - const DagInit& Edge = **B; - const std::string& Name = GetOperatorName(Edge); - - if (Name == "optional_edge") { - assert(IsOptionalEdge(Edge)); - const std::string& NodeB = InitPtrToString(Edge.getArg(1)); - - const DagInit& Weight = InitPtrToDag(Edge.getArg(2)); - EmitEdgeClass(i, NodeB, Weight, OptDescs, O); - } - else if (Name != "edge") { - throw "Unknown edge class: '" + Name + "'!"; - } - - ++i; - } -} - -/// EmitPopulateCompilationGraph - Emit the PopulateCompilationGraph() function. -void EmitPopulateCompilationGraph (const DagVector& EdgeVector, - const ToolDescriptions& ToolDescs, - raw_ostream& O) -{ - O << "int PopulateCompilationGraph (CompilationGraph& G) {\n"; - - for (ToolDescriptions::const_iterator B = ToolDescs.begin(), - E = ToolDescs.end(); B != E; ++B) - O.indent(Indent1) << "G.insertNode(new " << (*B)->Name << "());\n"; - - O << '\n'; - - // Insert edges. - - int i = 0; - for (DagVector::const_iterator B = EdgeVector.begin(), - E = EdgeVector.end(); B != E; ++B) { - const DagInit& Edge = **B; - const std::string& NodeA = InitPtrToString(Edge.getArg(0)); - const std::string& NodeB = InitPtrToString(Edge.getArg(1)); - - O.indent(Indent1) << "if (int ret = G.insertEdge(\"" << NodeA << "\", "; - - if (IsOptionalEdge(Edge)) - O << "new Edge" << i << "()"; - else - O << "new SimpleEdge(\"" << NodeB << "\")"; - - O << "))\n"; - O.indent(Indent2) << "return ret;\n"; - - ++i; - } - - O << '\n'; - O.indent(Indent1) << "return 0;\n"; - O << "}\n\n"; -} - -/// HookInfo - Information about the hook type and number of arguments. -struct HookInfo { - - // A hook can either have a single parameter of type std::vector, - // or NumArgs parameters of type const char*. - enum HookType { ListHook, ArgHook }; - - HookType Type; - unsigned NumArgs; - - HookInfo() : Type(ArgHook), NumArgs(1) - {} - - HookInfo(HookType T) : Type(T), NumArgs(1) - {} - - HookInfo(unsigned N) : Type(ArgHook), NumArgs(N) - {} -}; - -typedef llvm::StringMap HookInfoMap; - -/// ExtractHookNames - Extract the hook names from all instances of -/// $CALL(HookName) in the provided command line string/action. Helper -/// function used by FillInHookNames(). -class ExtractHookNames { - HookInfoMap& HookNames_; - const OptionDescriptions& OptDescs_; -public: - ExtractHookNames(HookInfoMap& HookNames, const OptionDescriptions& OptDescs) - : HookNames_(HookNames), OptDescs_(OptDescs) - {} - - void onAction (const DagInit& Dag) { - const std::string& Name = GetOperatorName(Dag); - - if (Name == "forward_transformed_value") { - CheckNumberOfArguments(Dag, 2); - const std::string& OptName = InitPtrToString(Dag.getArg(0)); - const std::string& HookName = InitPtrToString(Dag.getArg(1)); - const OptionDescription& D = - OptDescs_.FindParameterListOrParameter(OptName); - - HookNames_[HookName] = HookInfo(D.isList() ? HookInfo::ListHook - : HookInfo::ArgHook); - } - else if (Name == "append_cmd" || Name == "output_suffix") { - CheckNumberOfArguments(Dag, 1); - this->onCmdLine(InitPtrToString(Dag.getArg(0))); - } - } - - void onCmdLine(const std::string& Cmd) { - StrVector cmds; - TokenizeCmdLine(Cmd, cmds); - - for (StrVector::const_iterator B = cmds.begin(), E = cmds.end(); - B != E; ++B) { - const std::string& cmd = *B; - - if (cmd == "$CALL") { - unsigned NumArgs = 0; - CheckedIncrement(B, E, "Syntax error in $CALL invocation!"); - const std::string& HookName = *B; - - if (HookName.at(0) == ')') - throw "$CALL invoked with no arguments!"; - - while (++B != E && B->at(0) != ')') { - ++NumArgs; - } - - HookInfoMap::const_iterator H = HookNames_.find(HookName); - - if (H != HookNames_.end() && H->second.NumArgs != NumArgs && - H->second.Type != HookInfo::ArgHook) - throw "Overloading of hooks is not allowed. Overloaded hook: " - + HookName; - else - HookNames_[HookName] = HookInfo(NumArgs); - } - } - } - - void operator()(const Init* Arg) { - - // We're invoked on an action (either a dag or a dag list). - if (typeid(*Arg) == typeid(DagInit)) { - const DagInit& Dag = InitPtrToDag(Arg); - this->onAction(Dag); - return; - } - else if (typeid(*Arg) == typeid(ListInit)) { - const ListInit& List = InitPtrToList(Arg); - for (ListInit::const_iterator B = List.begin(), E = List.end(); B != E; - ++B) { - const DagInit& Dag = InitPtrToDag(*B); - this->onAction(Dag); - } - return; - } - - // We're invoked on a command line string. - this->onCmdLine(InitPtrToString(Arg)); - } - - void operator()(const Init* Statement, unsigned) { - this->operator()(Statement); - } -}; - -/// FillInHookNames - Actually extract the hook names from all command -/// line strings. Helper function used by EmitHookDeclarations(). -void FillInHookNames(const ToolDescriptions& ToolDescs, - const OptionDescriptions& OptDescs, - HookInfoMap& HookNames) -{ - // For all tool descriptions: - for (ToolDescriptions::const_iterator B = ToolDescs.begin(), - E = ToolDescs.end(); B != E; ++B) { - const ToolDescription& D = *(*B); - - // Look for 'forward_transformed_value' in 'actions'. - if (D.Actions) - WalkCase(D.Actions, Id(), ExtractHookNames(HookNames, OptDescs)); - - // Look for hook invocations in 'cmd_line'. - if (!D.CmdLine) - continue; - if (dynamic_cast(D.CmdLine)) - // This is a string. - ExtractHookNames(HookNames, OptDescs).operator()(D.CmdLine); - else - // This is a 'case' construct. - WalkCase(D.CmdLine, Id(), ExtractHookNames(HookNames, OptDescs)); - } -} - -/// EmitHookDeclarations - Parse CmdLine fields of all the tool -/// property records and emit hook function declaration for each -/// instance of $CALL(HookName). -void EmitHookDeclarations(const ToolDescriptions& ToolDescs, - const OptionDescriptions& OptDescs, raw_ostream& O) { - HookInfoMap HookNames; - - FillInHookNames(ToolDescs, OptDescs, HookNames); - if (HookNames.empty()) - return; - - for (HookInfoMap::const_iterator B = HookNames.begin(), - E = HookNames.end(); B != E; ++B) { - StringRef HookName = B->first(); - const HookInfo &Info = B->second; - - O.indent(Indent1) << "std::string " << HookName << "("; - - if (Info.Type == HookInfo::ArgHook) { - for (unsigned i = 0, j = Info.NumArgs; i < j; ++i) { - O << "const char* Arg" << i << (i+1 == j ? "" : ", "); - } - } - else { - O << "const std::vector& Arg"; - } - - O <<");\n"; - } -} - -/// EmitIncludes - Emit necessary #include directives and some -/// additional declarations. -void EmitIncludes(raw_ostream& O) { - O << "#include \"llvm/CompilerDriver/BuiltinOptions.h\"\n" - << "#include \"llvm/CompilerDriver/CompilationGraph.h\"\n" - << "#include \"llvm/CompilerDriver/Error.h\"\n" - << "#include \"llvm/CompilerDriver/Tool.h\"\n\n" - - << "#include \"llvm/Support/CommandLine.h\"\n" - << "#include \"llvm/Support/raw_ostream.h\"\n\n" - - << "#include \n" - << "#include \n" - << "#include \n" - << "#include \n\n" - - << "using namespace llvm;\n" - << "using namespace llvmc;\n\n" - - << "inline const char* checkCString(const char* s)\n" - << "{ return s == NULL ? \"\" : s; }\n\n"; -} - - -/// DriverData - Holds all information about the driver. -struct DriverData { - OptionDescriptions OptDescs; - ToolDescriptions ToolDescs; - DagVector Edges; - bool HasSink; -}; - -/// HasSink - Go through the list of tool descriptions and check if -/// there are any with the 'sink' property set. -bool HasSink(const ToolDescriptions& ToolDescs) { - for (ToolDescriptions::const_iterator B = ToolDescs.begin(), - E = ToolDescs.end(); B != E; ++B) - if ((*B)->isSink()) - return true; - - return false; -} - -/// CollectDriverData - Collect compilation graph edges, tool properties and -/// option properties from the parse tree. -void CollectDriverData (const RecordKeeper& Records, DriverData& Data) { - // Collect option properties. - const RecordVector& OptionLists = - Records.getAllDerivedDefinitions("OptionList"); - CollectOptionDescriptions(OptionLists, Data.OptDescs); - - // Collect tool properties. - const RecordVector& Tools = Records.getAllDerivedDefinitions("Tool"); - CollectToolDescriptions(Tools, Data.ToolDescs); - Data.HasSink = HasSink(Data.ToolDescs); - - // Collect compilation graph edges. - const RecordVector& CompilationGraphs = - Records.getAllDerivedDefinitions("CompilationGraph"); - FillInEdgeVector(CompilationGraphs, Data.Edges); -} - -/// CheckDriverData - Perform some sanity checks on the collected data. -void CheckDriverData(DriverData& Data) { - // Filter out all tools not mentioned in the compilation graph. - FilterNotInGraph(Data.Edges, Data.ToolDescs); - - // Typecheck the compilation graph. - // TODO: use a genuine graph representation instead of a vector and check for - // multiple edges. - TypecheckGraph(Data.Edges, Data.ToolDescs); - - // Check that there are no options without side effects (specified - // only in the OptionList). - CheckForSuperfluousOptions(Data.Edges, Data.ToolDescs, Data.OptDescs); -} - -void EmitDriverCode(const DriverData& Data, - raw_ostream& O, RecordKeeper &Records) { - // Emit file header. - EmitIncludes(O); - - // Emit global option registration code. - O << "namespace llvmc {\n" - << "namespace autogenerated {\n\n"; - EmitOptionDefinitions(Data.OptDescs, Data.HasSink, O); - O << "} // End namespace autogenerated.\n" - << "} // End namespace llvmc.\n\n"; - - // Emit hook declarations. - O << "namespace hooks {\n"; - EmitHookDeclarations(Data.ToolDescs, Data.OptDescs, O); - O << "} // End namespace hooks.\n\n"; - - O << "namespace {\n\n"; - O << "using namespace llvmc::autogenerated;\n\n"; - - // Emit Tool classes. - for (ToolDescriptions::const_iterator B = Data.ToolDescs.begin(), - E = Data.ToolDescs.end(); B!=E; ++B) - EmitToolClassDefinition(*(*B), Data.OptDescs, O); - - // Emit Edge# classes. - EmitEdgeClasses(Data.Edges, Data.OptDescs, O); - - O << "} // End anonymous namespace.\n\n"; - - O << "namespace llvmc {\n"; - O << "namespace autogenerated {\n\n"; - - // Emit PreprocessOptions() function. - EmitPreprocessOptions(Records, Data.OptDescs, O); - - // Emit PopulateLanguageMap() function - // (language map maps from file extensions to language names). - EmitPopulateLanguageMap(Records, O); - - // Emit PopulateCompilationGraph() function. - EmitPopulateCompilationGraph(Data.Edges, Data.ToolDescs, O); - - O << "} // End namespace autogenerated.\n"; - O << "} // End namespace llvmc.\n\n"; - - // EOF -} - - -// End of anonymous namespace -} - -/// run - The back-end entry point. -void LLVMCConfigurationEmitter::run (raw_ostream &O) { - try { - DriverData Data; - - CollectDriverData(Records, Data); - CheckDriverData(Data); - - this->EmitSourceFileHeader("llvmc-based driver: auto-generated code", O); - EmitDriverCode(Data, O, Records); - - } catch (std::exception& Error) { - throw Error.what() + std::string(" - usually this means a syntax error."); - } -} diff --git a/utils/TableGen/LLVMCConfigurationEmitter.h b/utils/TableGen/LLVMCConfigurationEmitter.h deleted file mode 100644 index 0f2ff3719678..000000000000 --- a/utils/TableGen/LLVMCConfigurationEmitter.h +++ /dev/null @@ -1,34 +0,0 @@ -//===- LLVMCConfigurationEmitter.cpp - Generate LLVMCC config ---*- 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 LLVMCC configuration code. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_UTILS_TABLEGEN_LLVMCCONF_EMITTER_H -#define LLVM_UTILS_TABLEGEN_LLVMCCONF_EMITTER_H - -#include "TableGenBackend.h" - -namespace llvm { - - /// LLVMCConfigurationEmitter - TableGen backend that generates - /// configuration code for LLVMC. - class LLVMCConfigurationEmitter : public TableGenBackend { - RecordKeeper &Records; - public: - explicit LLVMCConfigurationEmitter(RecordKeeper &records) : - Records(records) {} - - // run - Output the asmwriter, returning true on failure. - void run(raw_ostream &o); - }; -} - -#endif //LLVM_UTILS_TABLEGEN_LLVMCCONF_EMITTER_H diff --git a/utils/TableGen/Makefile b/utils/TableGen/Makefile index c01b6602faa3..0c4619d1a252 100644 --- a/utils/TableGen/Makefile +++ b/utils/TableGen/Makefile @@ -8,8 +8,8 @@ ##===----------------------------------------------------------------------===## LEVEL = ../.. -TOOLNAME = tblgen -USEDLIBS = LLVMSupport.a +TOOLNAME = llvm-tblgen +USEDLIBS = LLVMTableGen.a LLVMSupport.a REQUIRES_EH := 1 REQUIRES_RTTI := 1 diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp deleted file mode 100644 index ef9774438f7b..000000000000 --- a/utils/TableGen/NeonEmitter.cpp +++ /dev/null @@ -1,1558 +0,0 @@ -//===- NeonEmitter.cpp - Generate arm_neon.h for use with clang -*- 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 arm_neon.h, which includes -// a declaration and definition of each function specified by the ARM NEON -// compiler interface. See ARM document DUI0348B. -// -// Each NEON instruction is implemented in terms of 1 or more functions which -// are suffixed with the element type of the input vectors. Functions may be -// implemented in terms of generic vector operations such as +, *, -, etc. or -// by calling a __builtin_-prefixed function which will be handled by clang's -// CodeGen library. -// -// Additional validation code can be generated by this file when runHeader() is -// called, rather than the normal run() entry point. A complete set of tests -// for Neon intrinsics can be generated by calling the runTests() entry point. -// -//===----------------------------------------------------------------------===// - -#include "NeonEmitter.h" -#include "Error.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringExtras.h" -#include - -using namespace llvm; - -/// ParseTypes - break down a string such as "fQf" into a vector of StringRefs, -/// which each StringRef representing a single type declared in the string. -/// for "fQf" we would end up with 2 StringRefs, "f", and "Qf", representing -/// 2xfloat and 4xfloat respectively. -static void ParseTypes(Record *r, std::string &s, - SmallVectorImpl &TV) { - const char *data = s.data(); - int len = 0; - - for (unsigned i = 0, e = s.size(); i != e; ++i, ++len) { - if (data[len] == 'P' || data[len] == 'Q' || data[len] == 'U') - continue; - - switch (data[len]) { - case 'c': - case 's': - case 'i': - case 'l': - case 'h': - case 'f': - break; - default: - throw TGError(r->getLoc(), - "Unexpected letter: " + std::string(data + len, 1)); - break; - } - TV.push_back(StringRef(data, len + 1)); - data += len + 1; - len = -1; - } -} - -/// Widen - Convert a type code into the next wider type. char -> short, -/// short -> int, etc. -static char Widen(const char t) { - switch (t) { - case 'c': - return 's'; - case 's': - return 'i'; - case 'i': - return 'l'; - case 'h': - return 'f'; - default: throw "unhandled type in widen!"; - } - return '\0'; -} - -/// Narrow - Convert a type code into the next smaller type. short -> char, -/// float -> half float, etc. -static char Narrow(const char t) { - switch (t) { - case 's': - return 'c'; - case 'i': - return 's'; - case 'l': - return 'i'; - case 'f': - return 'h'; - default: throw "unhandled type in narrow!"; - } - return '\0'; -} - -/// For a particular StringRef, return the base type code, and whether it has -/// the quad-vector, polynomial, or unsigned modifiers set. -static char ClassifyType(StringRef ty, bool &quad, bool &poly, bool &usgn) { - unsigned off = 0; - - // remember quad. - if (ty[off] == 'Q') { - quad = true; - ++off; - } - - // remember poly. - if (ty[off] == 'P') { - poly = true; - ++off; - } - - // remember unsigned. - if (ty[off] == 'U') { - usgn = true; - ++off; - } - - // base type to get the type string for. - return ty[off]; -} - -/// ModType - Transform a type code and its modifiers based on a mod code. The -/// mod code definitions may be found at the top of arm_neon.td. -static char ModType(const char mod, char type, bool &quad, bool &poly, - bool &usgn, bool &scal, bool &cnst, bool &pntr) { - switch (mod) { - case 't': - if (poly) { - poly = false; - usgn = true; - } - break; - case 'u': - usgn = true; - poly = false; - if (type == 'f') - type = 'i'; - break; - case 'x': - usgn = false; - poly = false; - if (type == 'f') - type = 'i'; - break; - case 'f': - if (type == 'h') - quad = true; - type = 'f'; - usgn = false; - break; - case 'g': - quad = false; - break; - case 'w': - type = Widen(type); - quad = true; - break; - case 'n': - type = Widen(type); - break; - case 'i': - type = 'i'; - scal = true; - break; - case 'l': - type = 'l'; - scal = true; - usgn = true; - break; - case 's': - case 'a': - scal = true; - break; - case 'k': - quad = true; - break; - case 'c': - cnst = true; - case 'p': - pntr = true; - scal = true; - break; - case 'h': - type = Narrow(type); - if (type == 'h') - quad = false; - break; - case 'e': - type = Narrow(type); - usgn = true; - break; - default: - break; - } - return type; -} - -/// TypeString - for a modifier and type, generate the name of the typedef for -/// that type. QUc -> uint8x8_t. -static std::string TypeString(const char mod, StringRef typestr) { - bool quad = false; - bool poly = false; - bool usgn = false; - bool scal = false; - bool cnst = false; - bool pntr = false; - - if (mod == 'v') - return "void"; - if (mod == 'i') - return "int"; - - // base type to get the type string for. - char type = ClassifyType(typestr, quad, poly, usgn); - - // Based on the modifying character, change the type and width if necessary. - type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr); - - SmallString<128> s; - - if (usgn) - s.push_back('u'); - - switch (type) { - case 'c': - s += poly ? "poly8" : "int8"; - if (scal) - break; - s += quad ? "x16" : "x8"; - break; - case 's': - s += poly ? "poly16" : "int16"; - if (scal) - break; - s += quad ? "x8" : "x4"; - break; - case 'i': - s += "int32"; - if (scal) - break; - s += quad ? "x4" : "x2"; - break; - case 'l': - s += "int64"; - if (scal) - break; - s += quad ? "x2" : "x1"; - break; - case 'h': - s += "float16"; - if (scal) - break; - s += quad ? "x8" : "x4"; - break; - case 'f': - s += "float32"; - if (scal) - break; - s += quad ? "x4" : "x2"; - break; - default: - throw "unhandled type!"; - break; - } - - if (mod == '2') - s += "x2"; - if (mod == '3') - s += "x3"; - if (mod == '4') - s += "x4"; - - // Append _t, finishing the type string typedef type. - s += "_t"; - - if (cnst) - s += " const"; - - if (pntr) - s += " *"; - - return s.str(); -} - -/// BuiltinTypeString - for a modifier and type, generate the clang -/// BuiltinsARM.def prototype code for the function. See the top of clang's -/// Builtins.def for a description of the type strings. -static std::string BuiltinTypeString(const char mod, StringRef typestr, - ClassKind ck, bool ret) { - bool quad = false; - bool poly = false; - bool usgn = false; - bool scal = false; - bool cnst = false; - bool pntr = false; - - if (mod == 'v') - return "v"; // void - if (mod == 'i') - return "i"; // int - - // base type to get the type string for. - char type = ClassifyType(typestr, quad, poly, usgn); - - // Based on the modifying character, change the type and width if necessary. - type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr); - - // All pointers are void* pointers. Change type to 'v' now. - if (pntr) { - usgn = false; - poly = false; - type = 'v'; - } - // Treat half-float ('h') types as unsigned short ('s') types. - if (type == 'h') { - type = 's'; - usgn = true; - } - usgn = usgn | poly | ((ck == ClassI || ck == ClassW) && scal && type != 'f'); - - if (scal) { - SmallString<128> s; - - if (usgn) - s.push_back('U'); - else if (type == 'c') - s.push_back('S'); // make chars explicitly signed - - if (type == 'l') // 64-bit long - s += "LLi"; - else - s.push_back(type); - - if (cnst) - s.push_back('C'); - if (pntr) - s.push_back('*'); - return s.str(); - } - - // Since the return value must be one type, return a vector type of the - // appropriate width which we will bitcast. An exception is made for - // returning structs of 2, 3, or 4 vectors which are returned in a sret-like - // fashion, storing them to a pointer arg. - if (ret) { - if (mod >= '2' && mod <= '4') - return "vv*"; // void result with void* first argument - if (mod == 'f' || (ck != ClassB && type == 'f')) - return quad ? "V4f" : "V2f"; - if (ck != ClassB && type == 's') - return quad ? "V8s" : "V4s"; - if (ck != ClassB && type == 'i') - return quad ? "V4i" : "V2i"; - if (ck != ClassB && type == 'l') - return quad ? "V2LLi" : "V1LLi"; - - return quad ? "V16Sc" : "V8Sc"; - } - - // Non-return array types are passed as individual vectors. - if (mod == '2') - return quad ? "V16ScV16Sc" : "V8ScV8Sc"; - if (mod == '3') - return quad ? "V16ScV16ScV16Sc" : "V8ScV8ScV8Sc"; - if (mod == '4') - return quad ? "V16ScV16ScV16ScV16Sc" : "V8ScV8ScV8ScV8Sc"; - - if (mod == 'f' || (ck != ClassB && type == 'f')) - return quad ? "V4f" : "V2f"; - if (ck != ClassB && type == 's') - return quad ? "V8s" : "V4s"; - if (ck != ClassB && type == 'i') - return quad ? "V4i" : "V2i"; - if (ck != ClassB && type == 'l') - return quad ? "V2LLi" : "V1LLi"; - - return quad ? "V16Sc" : "V8Sc"; -} - -/// MangleName - Append a type or width suffix to a base neon function name, -/// and insert a 'q' in the appropriate location if the operation works on -/// 128b rather than 64b. E.g. turn "vst2_lane" into "vst2q_lane_f32", etc. -static std::string MangleName(const std::string &name, StringRef typestr, - ClassKind ck) { - if (name == "vcvt_f32_f16") - return name; - - bool quad = false; - bool poly = false; - bool usgn = false; - char type = ClassifyType(typestr, quad, poly, usgn); - - std::string s = name; - - switch (type) { - case 'c': - switch (ck) { - case ClassS: s += poly ? "_p8" : usgn ? "_u8" : "_s8"; break; - case ClassI: s += "_i8"; break; - case ClassW: s += "_8"; break; - default: break; - } - break; - case 's': - switch (ck) { - case ClassS: s += poly ? "_p16" : usgn ? "_u16" : "_s16"; break; - case ClassI: s += "_i16"; break; - case ClassW: s += "_16"; break; - default: break; - } - break; - case 'i': - switch (ck) { - case ClassS: s += usgn ? "_u32" : "_s32"; break; - case ClassI: s += "_i32"; break; - case ClassW: s += "_32"; break; - default: break; - } - break; - case 'l': - switch (ck) { - case ClassS: s += usgn ? "_u64" : "_s64"; break; - case ClassI: s += "_i64"; break; - case ClassW: s += "_64"; break; - default: break; - } - break; - case 'h': - switch (ck) { - case ClassS: - case ClassI: s += "_f16"; break; - case ClassW: s += "_16"; break; - default: break; - } - break; - case 'f': - switch (ck) { - case ClassS: - case ClassI: s += "_f32"; break; - case ClassW: s += "_32"; break; - default: break; - } - break; - default: - throw "unhandled type!"; - break; - } - if (ck == ClassB) - s += "_v"; - - // Insert a 'q' before the first '_' character so that it ends up before - // _lane or _n on vector-scalar operations. - if (quad) { - size_t pos = s.find('_'); - s = s.insert(pos, "q"); - } - return s; -} - -/// UseMacro - Examine the prototype string to determine if the intrinsic -/// should be defined as a preprocessor macro instead of an inline function. -static bool UseMacro(const std::string &proto) { - // If this builtin takes an immediate argument, we need to #define it rather - // than use a standard declaration, so that SemaChecking can range check - // the immediate passed by the user. - if (proto.find('i') != std::string::npos) - return true; - - // Pointer arguments need to use macros to avoid hiding aligned attributes - // from the pointer type. - if (proto.find('p') != std::string::npos || - proto.find('c') != std::string::npos) - return true; - - return false; -} - -/// MacroArgUsedDirectly - Return true if argument i for an intrinsic that is -/// defined as a macro should be accessed directly instead of being first -/// assigned to a local temporary. -static bool MacroArgUsedDirectly(const std::string &proto, unsigned i) { - return (proto[i] == 'i' || proto[i] == 'p' || proto[i] == 'c'); -} - -// Generate the string "(argtype a, argtype b, ...)" -static std::string GenArgs(const std::string &proto, StringRef typestr) { - bool define = UseMacro(proto); - char arg = 'a'; - - std::string s; - s += "("; - - for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { - if (define) { - // Some macro arguments are used directly instead of being assigned - // to local temporaries; prepend an underscore prefix to make their - // names consistent with the local temporaries. - if (MacroArgUsedDirectly(proto, i)) - s += "__"; - } else { - s += TypeString(proto[i], typestr) + " __"; - } - s.push_back(arg); - if ((i + 1) < e) - s += ", "; - } - - s += ")"; - return s; -} - -// Macro arguments are not type-checked like inline function arguments, so -// assign them to local temporaries to get the right type checking. -static std::string GenMacroLocals(const std::string &proto, StringRef typestr) { - char arg = 'a'; - std::string s; - bool generatedLocal = false; - - for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { - // Do not create a temporary for an immediate argument. - // That would defeat the whole point of using a macro! - if (proto[i] == 'i') - continue; - generatedLocal = true; - - // For other (non-immediate) arguments that are used directly, a local - // temporary is still needed to get the correct type checking, even though - // that temporary is not used for anything. - if (MacroArgUsedDirectly(proto, i)) { - s += TypeString(proto[i], typestr) + " __"; - s.push_back(arg); - s += "_ = (__"; - s.push_back(arg); - s += "); (void)__"; - s.push_back(arg); - s += "_; "; - continue; - } - - s += TypeString(proto[i], typestr) + " __"; - s.push_back(arg); - s += " = ("; - s.push_back(arg); - s += "); "; - } - - if (generatedLocal) - s += "\\\n "; - return s; -} - -// Use the vmovl builtin to sign-extend or zero-extend a vector. -static std::string Extend(StringRef typestr, const std::string &a) { - std::string s; - s = MangleName("vmovl", typestr, ClassS); - s += "(" + a + ")"; - return s; -} - -static std::string Duplicate(unsigned nElts, StringRef typestr, - const std::string &a) { - std::string s; - - s = "(" + TypeString('d', typestr) + "){ "; - for (unsigned i = 0; i != nElts; ++i) { - s += a; - if ((i + 1) < nElts) - s += ", "; - } - s += " }"; - - return s; -} - -static std::string SplatLane(unsigned nElts, const std::string &vec, - const std::string &lane) { - std::string s = "__builtin_shufflevector(" + vec + ", " + vec; - for (unsigned i = 0; i < nElts; ++i) - s += ", " + lane; - s += ")"; - return s; -} - -static unsigned GetNumElements(StringRef typestr, bool &quad) { - quad = false; - bool dummy = false; - char type = ClassifyType(typestr, quad, dummy, dummy); - unsigned nElts = 0; - switch (type) { - case 'c': nElts = 8; break; - case 's': nElts = 4; break; - case 'i': nElts = 2; break; - case 'l': nElts = 1; break; - case 'h': nElts = 4; break; - case 'f': nElts = 2; break; - default: - throw "unhandled type!"; - break; - } - if (quad) nElts <<= 1; - return nElts; -} - -// Generate the definition for this intrinsic, e.g. "a + b" for OpAdd. -static std::string GenOpString(OpKind op, const std::string &proto, - StringRef typestr) { - bool quad; - unsigned nElts = GetNumElements(typestr, quad); - bool define = UseMacro(proto); - - std::string ts = TypeString(proto[0], typestr); - std::string s; - if (!define) { - s = "return "; - } - - switch(op) { - case OpAdd: - s += "__a + __b;"; - break; - case OpAddl: - s += Extend(typestr, "__a") + " + " + Extend(typestr, "__b") + ";"; - break; - case OpAddw: - s += "__a + " + Extend(typestr, "__b") + ";"; - break; - case OpSub: - s += "__a - __b;"; - break; - case OpSubl: - s += Extend(typestr, "__a") + " - " + Extend(typestr, "__b") + ";"; - break; - case OpSubw: - s += "__a - " + Extend(typestr, "__b") + ";"; - break; - case OpMulN: - s += "__a * " + Duplicate(nElts, typestr, "__b") + ";"; - break; - case OpMulLane: - s += "__a * " + SplatLane(nElts, "__b", "__c") + ";"; - break; - case OpMul: - s += "__a * __b;"; - break; - case OpMullLane: - s += MangleName("vmull", typestr, ClassS) + "(__a, " + - SplatLane(nElts, "__b", "__c") + ");"; - break; - case OpMlaN: - s += "__a + (__b * " + Duplicate(nElts, typestr, "__c") + ");"; - break; - case OpMlaLane: - s += "__a + (__b * " + SplatLane(nElts, "__c", "__d") + ");"; - break; - case OpMla: - s += "__a + (__b * __c);"; - break; - case OpMlalN: - s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " + - Duplicate(nElts, typestr, "__c") + ");"; - break; - case OpMlalLane: - s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " + - SplatLane(nElts, "__c", "__d") + ");"; - break; - case OpMlal: - s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, __c);"; - break; - case OpMlsN: - s += "__a - (__b * " + Duplicate(nElts, typestr, "__c") + ");"; - break; - case OpMlsLane: - s += "__a - (__b * " + SplatLane(nElts, "__c", "__d") + ");"; - break; - case OpMls: - s += "__a - (__b * __c);"; - break; - case OpMlslN: - s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " + - Duplicate(nElts, typestr, "__c") + ");"; - break; - case OpMlslLane: - s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " + - SplatLane(nElts, "__c", "__d") + ");"; - break; - case OpMlsl: - s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, __c);"; - break; - case OpQDMullLane: - s += MangleName("vqdmull", typestr, ClassS) + "(__a, " + - SplatLane(nElts, "__b", "__c") + ");"; - break; - case OpQDMlalLane: - s += MangleName("vqdmlal", typestr, ClassS) + "(__a, __b, " + - SplatLane(nElts, "__c", "__d") + ");"; - break; - case OpQDMlslLane: - s += MangleName("vqdmlsl", typestr, ClassS) + "(__a, __b, " + - SplatLane(nElts, "__c", "__d") + ");"; - break; - case OpQDMulhLane: - s += MangleName("vqdmulh", typestr, ClassS) + "(__a, " + - SplatLane(nElts, "__b", "__c") + ");"; - break; - case OpQRDMulhLane: - s += MangleName("vqrdmulh", typestr, ClassS) + "(__a, " + - SplatLane(nElts, "__b", "__c") + ");"; - break; - case OpEq: - s += "(" + ts + ")(__a == __b);"; - break; - case OpGe: - s += "(" + ts + ")(__a >= __b);"; - break; - case OpLe: - s += "(" + ts + ")(__a <= __b);"; - break; - case OpGt: - s += "(" + ts + ")(__a > __b);"; - break; - case OpLt: - s += "(" + ts + ")(__a < __b);"; - break; - case OpNeg: - s += " -__a;"; - break; - case OpNot: - s += " ~__a;"; - break; - case OpAnd: - s += "__a & __b;"; - break; - case OpOr: - s += "__a | __b;"; - break; - case OpXor: - s += "__a ^ __b;"; - break; - case OpAndNot: - s += "__a & ~__b;"; - break; - case OpOrNot: - s += "__a | ~__b;"; - break; - case OpCast: - s += "(" + ts + ")__a;"; - break; - case OpConcat: - s += "(" + ts + ")__builtin_shufflevector((int64x1_t)__a"; - s += ", (int64x1_t)__b, 0, 1);"; - break; - case OpHi: - s += "(" + ts + - ")__builtin_shufflevector((int64x2_t)__a, (int64x2_t)__a, 1);"; - break; - case OpLo: - s += "(" + ts + - ")__builtin_shufflevector((int64x2_t)__a, (int64x2_t)__a, 0);"; - break; - case OpDup: - s += Duplicate(nElts, typestr, "__a") + ";"; - break; - case OpDupLane: - s += SplatLane(nElts, "__a", "__b") + ";"; - break; - case OpSelect: - // ((0 & 1) | (~0 & 2)) - s += "(" + ts + ")"; - ts = TypeString(proto[1], typestr); - s += "((__a & (" + ts + ")__b) | "; - s += "(~__a & (" + ts + ")__c));"; - break; - case OpRev16: - s += "__builtin_shufflevector(__a, __a"; - for (unsigned i = 2; i <= nElts; i += 2) - for (unsigned j = 0; j != 2; ++j) - s += ", " + utostr(i - j - 1); - s += ");"; - break; - case OpRev32: { - unsigned WordElts = nElts >> (1 + (int)quad); - s += "__builtin_shufflevector(__a, __a"; - for (unsigned i = WordElts; i <= nElts; i += WordElts) - for (unsigned j = 0; j != WordElts; ++j) - s += ", " + utostr(i - j - 1); - s += ");"; - break; - } - case OpRev64: { - unsigned DblWordElts = nElts >> (int)quad; - s += "__builtin_shufflevector(__a, __a"; - for (unsigned i = DblWordElts; i <= nElts; i += DblWordElts) - for (unsigned j = 0; j != DblWordElts; ++j) - s += ", " + utostr(i - j - 1); - s += ");"; - break; - } - case OpAbdl: { - std::string abd = MangleName("vabd", typestr, ClassS) + "(__a, __b)"; - if (typestr[0] != 'U') { - // vabd results are always unsigned and must be zero-extended. - std::string utype = "U" + typestr.str(); - s += "(" + TypeString(proto[0], typestr) + ")"; - abd = "(" + TypeString('d', utype) + ")" + abd; - s += Extend(utype, abd) + ";"; - } else { - s += Extend(typestr, abd) + ";"; - } - break; - } - case OpAba: - s += "__a + " + MangleName("vabd", typestr, ClassS) + "(__b, __c);"; - break; - case OpAbal: { - s += "__a + "; - std::string abd = MangleName("vabd", typestr, ClassS) + "(__b, __c)"; - if (typestr[0] != 'U') { - // vabd results are always unsigned and must be zero-extended. - std::string utype = "U" + typestr.str(); - s += "(" + TypeString(proto[0], typestr) + ")"; - abd = "(" + TypeString('d', utype) + ")" + abd; - s += Extend(utype, abd) + ";"; - } else { - s += Extend(typestr, abd) + ";"; - } - break; - } - default: - throw "unknown OpKind!"; - break; - } - return s; -} - -static unsigned GetNeonEnum(const std::string &proto, StringRef typestr) { - unsigned mod = proto[0]; - unsigned ret = 0; - - if (mod == 'v' || mod == 'f') - mod = proto[1]; - - bool quad = false; - bool poly = false; - bool usgn = false; - bool scal = false; - bool cnst = false; - bool pntr = false; - - // Base type to get the type string for. - char type = ClassifyType(typestr, quad, poly, usgn); - - // Based on the modifying character, change the type and width if necessary. - type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr); - - if (usgn) - ret |= 0x08; - if (quad && proto[1] != 'g') - ret |= 0x10; - - switch (type) { - case 'c': - ret |= poly ? 5 : 0; - break; - case 's': - ret |= poly ? 6 : 1; - break; - case 'i': - ret |= 2; - break; - case 'l': - ret |= 3; - break; - case 'h': - ret |= 7; - break; - case 'f': - ret |= 4; - break; - default: - throw "unhandled type!"; - break; - } - return ret; -} - -// Generate the definition for this intrinsic, e.g. __builtin_neon_cls(a) -static std::string GenBuiltin(const std::string &name, const std::string &proto, - StringRef typestr, ClassKind ck) { - std::string s; - - // If this builtin returns a struct 2, 3, or 4 vectors, pass it as an implicit - // sret-like argument. - bool sret = (proto[0] >= '2' && proto[0] <= '4'); - - bool define = UseMacro(proto); - - // Check if the prototype has a scalar operand with the type of the vector - // elements. If not, bitcasting the args will take care of arg checking. - // The actual signedness etc. will be taken care of with special enums. - if (proto.find('s') == std::string::npos) - ck = ClassB; - - if (proto[0] != 'v') { - std::string ts = TypeString(proto[0], typestr); - - if (define) { - if (sret) - s += ts + " r; "; - else - s += "(" + ts + ")"; - } else if (sret) { - s += ts + " r; "; - } else { - s += "return (" + ts + ")"; - } - } - - bool splat = proto.find('a') != std::string::npos; - - s += "__builtin_neon_"; - if (splat) { - // Call the non-splat builtin: chop off the "_n" suffix from the name. - std::string vname(name, 0, name.size()-2); - s += MangleName(vname, typestr, ck); - } else { - s += MangleName(name, typestr, ck); - } - s += "("; - - // Pass the address of the return variable as the first argument to sret-like - // builtins. - if (sret) - s += "&r, "; - - char arg = 'a'; - for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { - std::string args = std::string(&arg, 1); - - // Use the local temporaries instead of the macro arguments. - args = "__" + args; - - bool argQuad = false; - bool argPoly = false; - bool argUsgn = false; - bool argScalar = false; - bool dummy = false; - char argType = ClassifyType(typestr, argQuad, argPoly, argUsgn); - argType = ModType(proto[i], argType, argQuad, argPoly, argUsgn, argScalar, - dummy, dummy); - - // Handle multiple-vector values specially, emitting each subvector as an - // argument to the __builtin. - if (proto[i] >= '2' && proto[i] <= '4') { - // Check if an explicit cast is needed. - if (argType != 'c' || argPoly || argUsgn) - args = (argQuad ? "(int8x16_t)" : "(int8x8_t)") + args; - - for (unsigned vi = 0, ve = proto[i] - '0'; vi != ve; ++vi) { - s += args + ".val[" + utostr(vi) + "]"; - if ((vi + 1) < ve) - s += ", "; - } - if ((i + 1) < e) - s += ", "; - - continue; - } - - if (splat && (i + 1) == e) - args = Duplicate(GetNumElements(typestr, argQuad), typestr, args); - - // Check if an explicit cast is needed. - if ((splat || !argScalar) && - ((ck == ClassB && argType != 'c') || argPoly || argUsgn)) { - std::string argTypeStr = "c"; - if (ck != ClassB) - argTypeStr = argType; - if (argQuad) - argTypeStr = "Q" + argTypeStr; - args = "(" + TypeString('d', argTypeStr) + ")" + args; - } - - s += args; - if ((i + 1) < e) - s += ", "; - } - - // Extra constant integer to hold type class enum for this function, e.g. s8 - if (ck == ClassB) - s += ", " + utostr(GetNeonEnum(proto, typestr)); - - s += ");"; - - if (proto[0] != 'v' && sret) { - if (define) - s += " r;"; - else - s += " return r;"; - } - return s; -} - -static std::string GenBuiltinDef(const std::string &name, - const std::string &proto, - StringRef typestr, ClassKind ck) { - std::string s("BUILTIN(__builtin_neon_"); - - // If all types are the same size, bitcasting the args will take care - // of arg checking. The actual signedness etc. will be taken care of with - // special enums. - if (proto.find('s') == std::string::npos) - ck = ClassB; - - s += MangleName(name, typestr, ck); - s += ", \""; - - for (unsigned i = 0, e = proto.size(); i != e; ++i) - s += BuiltinTypeString(proto[i], typestr, ck, i == 0); - - // Extra constant integer to hold type class enum for this function, e.g. s8 - if (ck == ClassB) - s += "i"; - - s += "\", \"n\")"; - return s; -} - -static std::string GenIntrinsic(const std::string &name, - const std::string &proto, - StringRef outTypeStr, StringRef inTypeStr, - OpKind kind, ClassKind classKind) { - assert(!proto.empty() && ""); - bool define = UseMacro(proto); - std::string s; - - // static always inline + return type - if (define) - s += "#define "; - else - s += "__ai " + TypeString(proto[0], outTypeStr) + " "; - - // Function name with type suffix - std::string mangledName = MangleName(name, outTypeStr, ClassS); - if (outTypeStr != inTypeStr) { - // If the input type is different (e.g., for vreinterpret), append a suffix - // for the input type. String off a "Q" (quad) prefix so that MangleName - // does not insert another "q" in the name. - unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0); - StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff); - mangledName = MangleName(mangledName, inTypeNoQuad, ClassS); - } - s += mangledName; - - // Function arguments - s += GenArgs(proto, inTypeStr); - - // Definition. - if (define) { - s += " __extension__ ({ \\\n "; - s += GenMacroLocals(proto, inTypeStr); - } else { - s += " { \\\n "; - } - - if (kind != OpNone) - s += GenOpString(kind, proto, outTypeStr); - else - s += GenBuiltin(name, proto, outTypeStr, classKind); - if (define) - s += " })"; - else - s += " }"; - s += "\n"; - return s; -} - -/// run - Read the records in arm_neon.td and output arm_neon.h. arm_neon.h -/// is comprised of type definitions and function declarations. -void NeonEmitter::run(raw_ostream &OS) { - OS << - "/*===---- arm_neon.h - ARM Neon intrinsics ------------------------------" - "---===\n" - " *\n" - " * Permission is hereby granted, free of charge, to any person obtaining " - "a copy\n" - " * of this software and associated documentation files (the \"Software\")," - " to deal\n" - " * in the Software without restriction, including without limitation the " - "rights\n" - " * to use, copy, modify, merge, publish, distribute, sublicense, " - "and/or sell\n" - " * copies of the Software, and to permit persons to whom the Software is\n" - " * furnished to do so, subject to the following conditions:\n" - " *\n" - " * The above copyright notice and this permission notice shall be " - "included in\n" - " * all copies or substantial portions of the Software.\n" - " *\n" - " * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, " - "EXPRESS OR\n" - " * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF " - "MERCHANTABILITY,\n" - " * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT " - "SHALL THE\n" - " * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR " - "OTHER\n" - " * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, " - "ARISING FROM,\n" - " * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER " - "DEALINGS IN\n" - " * THE SOFTWARE.\n" - " *\n" - " *===--------------------------------------------------------------------" - "---===\n" - " */\n\n"; - - OS << "#ifndef __ARM_NEON_H\n"; - OS << "#define __ARM_NEON_H\n\n"; - - OS << "#ifndef __ARM_NEON__\n"; - OS << "#error \"NEON support not enabled\"\n"; - OS << "#endif\n\n"; - - OS << "#include \n\n"; - - // Emit NEON-specific scalar typedefs. - OS << "typedef float float32_t;\n"; - OS << "typedef int8_t poly8_t;\n"; - OS << "typedef int16_t poly16_t;\n"; - OS << "typedef uint16_t float16_t;\n"; - - // Emit Neon vector typedefs. - std::string TypedefTypes("cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfPcQPcPsQPs"); - SmallVector TDTypeVec; - ParseTypes(0, TypedefTypes, TDTypeVec); - - // Emit vector typedefs. - for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) { - bool dummy, quad = false, poly = false; - (void) ClassifyType(TDTypeVec[i], quad, poly, dummy); - if (poly) - OS << "typedef __attribute__((neon_polyvector_type("; - else - OS << "typedef __attribute__((neon_vector_type("; - - unsigned nElts = GetNumElements(TDTypeVec[i], quad); - OS << utostr(nElts) << "))) "; - if (nElts < 10) - OS << " "; - - OS << TypeString('s', TDTypeVec[i]); - OS << " " << TypeString('d', TDTypeVec[i]) << ";\n"; - } - OS << "\n"; - - // Emit struct typedefs. - for (unsigned vi = 2; vi != 5; ++vi) { - for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) { - std::string ts = TypeString('d', TDTypeVec[i]); - std::string vs = TypeString('0' + vi, TDTypeVec[i]); - OS << "typedef struct " << vs << " {\n"; - OS << " " << ts << " val"; - OS << "[" << utostr(vi) << "]"; - OS << ";\n} "; - OS << vs << ";\n\n"; - } - } - - OS << "#define __ai static __attribute__((__always_inline__))\n\n"; - - std::vector RV = Records.getAllDerivedDefinitions("Inst"); - - // Emit vmovl, vmull and vabd intrinsics first so they can be used by other - // intrinsics. (Some of the saturating multiply instructions are also - // used to implement the corresponding "_lane" variants, but tablegen - // sorts the records into alphabetical order so that the "_lane" variants - // come after the intrinsics they use.) - emitIntrinsic(OS, Records.getDef("VMOVL")); - emitIntrinsic(OS, Records.getDef("VMULL")); - emitIntrinsic(OS, Records.getDef("VABD")); - - for (unsigned i = 0, e = RV.size(); i != e; ++i) { - Record *R = RV[i]; - if (R->getName() != "VMOVL" && - R->getName() != "VMULL" && - R->getName() != "VABD") - emitIntrinsic(OS, R); - } - - OS << "#undef __ai\n\n"; - OS << "#endif /* __ARM_NEON_H */\n"; -} - -/// emitIntrinsic - Write out the arm_neon.h header file definitions for the -/// intrinsics specified by record R. -void NeonEmitter::emitIntrinsic(raw_ostream &OS, Record *R) { - std::string name = R->getValueAsString("Name"); - std::string Proto = R->getValueAsString("Prototype"); - std::string Types = R->getValueAsString("Types"); - - SmallVector TypeVec; - ParseTypes(R, Types, TypeVec); - - OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()]; - - ClassKind classKind = ClassNone; - if (R->getSuperClasses().size() >= 2) - classKind = ClassMap[R->getSuperClasses()[1]]; - if (classKind == ClassNone && kind == OpNone) - throw TGError(R->getLoc(), "Builtin has no class kind"); - - for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { - if (kind == OpReinterpret) { - bool outQuad = false; - bool dummy = false; - (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy); - for (unsigned srcti = 0, srcte = TypeVec.size(); - srcti != srcte; ++srcti) { - bool inQuad = false; - (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy); - if (srcti == ti || inQuad != outQuad) - continue; - OS << GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[srcti], - OpCast, ClassS); - } - } else { - OS << GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[ti], - kind, classKind); - } - } - OS << "\n"; -} - -static unsigned RangeFromType(const char mod, StringRef typestr) { - // base type to get the type string for. - bool quad = false, dummy = false; - char type = ClassifyType(typestr, quad, dummy, dummy); - type = ModType(mod, type, quad, dummy, dummy, dummy, dummy, dummy); - - switch (type) { - case 'c': - return (8 << (int)quad) - 1; - case 'h': - case 's': - return (4 << (int)quad) - 1; - case 'f': - case 'i': - return (2 << (int)quad) - 1; - case 'l': - return (1 << (int)quad) - 1; - default: - throw "unhandled type!"; - break; - } - assert(0 && "unreachable"); - return 0; -} - -/// runHeader - Emit a file with sections defining: -/// 1. the NEON section of BuiltinsARM.def. -/// 2. the SemaChecking code for the type overload checking. -/// 3. the SemaChecking code for validation of intrinsic immedate arguments. -void NeonEmitter::runHeader(raw_ostream &OS) { - std::vector RV = Records.getAllDerivedDefinitions("Inst"); - - StringMap EmittedMap; - - // Generate BuiltinsARM.def for NEON - OS << "#ifdef GET_NEON_BUILTINS\n"; - for (unsigned i = 0, e = RV.size(); i != e; ++i) { - Record *R = RV[i]; - OpKind k = OpMap[R->getValueAsDef("Operand")->getName()]; - if (k != OpNone) - continue; - - std::string Proto = R->getValueAsString("Prototype"); - - // Functions with 'a' (the splat code) in the type prototype should not get - // their own builtin as they use the non-splat variant. - if (Proto.find('a') != std::string::npos) - continue; - - std::string Types = R->getValueAsString("Types"); - SmallVector TypeVec; - ParseTypes(R, Types, TypeVec); - - if (R->getSuperClasses().size() < 2) - throw TGError(R->getLoc(), "Builtin has no class kind"); - - std::string name = R->getValueAsString("Name"); - ClassKind ck = ClassMap[R->getSuperClasses()[1]]; - - for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { - // Generate the BuiltinsARM.def declaration for this builtin, ensuring - // that each unique BUILTIN() macro appears only once in the output - // stream. - std::string bd = GenBuiltinDef(name, Proto, TypeVec[ti], ck); - if (EmittedMap.count(bd)) - continue; - - EmittedMap[bd] = OpNone; - OS << bd << "\n"; - } - } - OS << "#endif\n\n"; - - // Generate the overloaded type checking code for SemaChecking.cpp - OS << "#ifdef GET_NEON_OVERLOAD_CHECK\n"; - for (unsigned i = 0, e = RV.size(); i != e; ++i) { - Record *R = RV[i]; - OpKind k = OpMap[R->getValueAsDef("Operand")->getName()]; - if (k != OpNone) - continue; - - std::string Proto = R->getValueAsString("Prototype"); - std::string Types = R->getValueAsString("Types"); - std::string name = R->getValueAsString("Name"); - - // Functions with 'a' (the splat code) in the type prototype should not get - // their own builtin as they use the non-splat variant. - if (Proto.find('a') != std::string::npos) - continue; - - // Functions which have a scalar argument cannot be overloaded, no need to - // check them if we are emitting the type checking code. - if (Proto.find('s') != std::string::npos) - continue; - - SmallVector TypeVec; - ParseTypes(R, Types, TypeVec); - - if (R->getSuperClasses().size() < 2) - throw TGError(R->getLoc(), "Builtin has no class kind"); - - int si = -1, qi = -1; - unsigned mask = 0, qmask = 0; - for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { - // Generate the switch case(s) for this builtin for the type validation. - bool quad = false, poly = false, usgn = false; - (void) ClassifyType(TypeVec[ti], quad, poly, usgn); - - if (quad) { - qi = ti; - qmask |= 1 << GetNeonEnum(Proto, TypeVec[ti]); - } else { - si = ti; - mask |= 1 << GetNeonEnum(Proto, TypeVec[ti]); - } - } - if (mask) - OS << "case ARM::BI__builtin_neon_" - << MangleName(name, TypeVec[si], ClassB) - << ": mask = " << "0x" << utohexstr(mask) << "; break;\n"; - if (qmask) - OS << "case ARM::BI__builtin_neon_" - << MangleName(name, TypeVec[qi], ClassB) - << ": mask = " << "0x" << utohexstr(qmask) << "; break;\n"; - } - OS << "#endif\n\n"; - - // Generate the intrinsic range checking code for shift/lane immediates. - OS << "#ifdef GET_NEON_IMMEDIATE_CHECK\n"; - for (unsigned i = 0, e = RV.size(); i != e; ++i) { - Record *R = RV[i]; - - OpKind k = OpMap[R->getValueAsDef("Operand")->getName()]; - if (k != OpNone) - continue; - - std::string name = R->getValueAsString("Name"); - std::string Proto = R->getValueAsString("Prototype"); - std::string Types = R->getValueAsString("Types"); - - // Functions with 'a' (the splat code) in the type prototype should not get - // their own builtin as they use the non-splat variant. - if (Proto.find('a') != std::string::npos) - continue; - - // Functions which do not have an immediate do not need to have range - // checking code emitted. - size_t immPos = Proto.find('i'); - if (immPos == std::string::npos) - continue; - - SmallVector TypeVec; - ParseTypes(R, Types, TypeVec); - - if (R->getSuperClasses().size() < 2) - throw TGError(R->getLoc(), "Builtin has no class kind"); - - ClassKind ck = ClassMap[R->getSuperClasses()[1]]; - - for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { - std::string namestr, shiftstr, rangestr; - - if (R->getValueAsBit("isVCVT_N")) { - // VCVT between floating- and fixed-point values takes an immediate - // in the range 1 to 32. - ck = ClassB; - rangestr = "l = 1; u = 31"; // upper bound = l + u - } else if (Proto.find('s') == std::string::npos) { - // Builtins which are overloaded by type will need to have their upper - // bound computed at Sema time based on the type constant. - ck = ClassB; - if (R->getValueAsBit("isShift")) { - shiftstr = ", true"; - - // Right shifts have an 'r' in the name, left shifts do not. - if (name.find('r') != std::string::npos) - rangestr = "l = 1; "; - } - rangestr += "u = RFT(TV" + shiftstr + ")"; - } else { - // The immediate generally refers to a lane in the preceding argument. - assert(immPos > 0 && "unexpected immediate operand"); - rangestr = "u = " + utostr(RangeFromType(Proto[immPos-1], TypeVec[ti])); - } - // Make sure cases appear only once by uniquing them in a string map. - namestr = MangleName(name, TypeVec[ti], ck); - if (EmittedMap.count(namestr)) - continue; - EmittedMap[namestr] = OpNone; - - // Calculate the index of the immediate that should be range checked. - unsigned immidx = 0; - - // Builtins that return a struct of multiple vectors have an extra - // leading arg for the struct return. - if (Proto[0] >= '2' && Proto[0] <= '4') - ++immidx; - - // Add one to the index for each argument until we reach the immediate - // to be checked. Structs of vectors are passed as multiple arguments. - for (unsigned ii = 1, ie = Proto.size(); ii != ie; ++ii) { - switch (Proto[ii]) { - default: immidx += 1; break; - case '2': immidx += 2; break; - case '3': immidx += 3; break; - case '4': immidx += 4; break; - case 'i': ie = ii + 1; break; - } - } - OS << "case ARM::BI__builtin_neon_" << MangleName(name, TypeVec[ti], ck) - << ": i = " << immidx << "; " << rangestr << "; break;\n"; - } - } - OS << "#endif\n\n"; -} - -/// GenTest - Write out a test for the intrinsic specified by the name and -/// type strings, including the embedded patterns for FileCheck to match. -static std::string GenTest(const std::string &name, - const std::string &proto, - StringRef outTypeStr, StringRef inTypeStr, - bool isShift) { - assert(!proto.empty() && ""); - std::string s; - - // Function name with type suffix - std::string mangledName = MangleName(name, outTypeStr, ClassS); - if (outTypeStr != inTypeStr) { - // If the input type is different (e.g., for vreinterpret), append a suffix - // for the input type. String off a "Q" (quad) prefix so that MangleName - // does not insert another "q" in the name. - unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0); - StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff); - mangledName = MangleName(mangledName, inTypeNoQuad, ClassS); - } - - // Emit the FileCheck patterns. - s += "// CHECK: test_" + mangledName + "\n"; - // s += "// CHECK: \n"; // FIXME: + expected instruction opcode. - - // Emit the start of the test function. - s += TypeString(proto[0], outTypeStr) + " test_" + mangledName + "("; - char arg = 'a'; - std::string comma; - for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { - // Do not create arguments for values that must be immediate constants. - if (proto[i] == 'i') - continue; - s += comma + TypeString(proto[i], inTypeStr) + " "; - s.push_back(arg); - comma = ", "; - } - s += ") { \\\n "; - - if (proto[0] != 'v') - s += "return "; - s += mangledName + "("; - arg = 'a'; - for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { - if (proto[i] == 'i') { - // For immediate operands, test the maximum value. - if (isShift) - s += "1"; // FIXME - else - // The immediate generally refers to a lane in the preceding argument. - s += utostr(RangeFromType(proto[i-1], inTypeStr)); - } else { - s.push_back(arg); - } - if ((i + 1) < e) - s += ", "; - } - s += ");\n}\n\n"; - return s; -} - -/// runTests - Write out a complete set of tests for all of the Neon -/// intrinsics. -void NeonEmitter::runTests(raw_ostream &OS) { - OS << - "// RUN: %clang_cc1 -triple thumbv7-apple-darwin \\\n" - "// RUN: -target-cpu cortex-a9 -ffreestanding -S -o - %s | FileCheck %s\n" - "\n" - "#include \n" - "\n"; - - std::vector RV = Records.getAllDerivedDefinitions("Inst"); - for (unsigned i = 0, e = RV.size(); i != e; ++i) { - Record *R = RV[i]; - std::string name = R->getValueAsString("Name"); - std::string Proto = R->getValueAsString("Prototype"); - std::string Types = R->getValueAsString("Types"); - bool isShift = R->getValueAsBit("isShift"); - - SmallVector TypeVec; - ParseTypes(R, Types, TypeVec); - - OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()]; - for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { - if (kind == OpReinterpret) { - bool outQuad = false; - bool dummy = false; - (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy); - for (unsigned srcti = 0, srcte = TypeVec.size(); - srcti != srcte; ++srcti) { - bool inQuad = false; - (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy); - if (srcti == ti || inQuad != outQuad) - continue; - OS << GenTest(name, Proto, TypeVec[ti], TypeVec[srcti], isShift); - } - } else { - OS << GenTest(name, Proto, TypeVec[ti], TypeVec[ti], isShift); - } - } - OS << "\n"; - } -} - diff --git a/utils/TableGen/NeonEmitter.h b/utils/TableGen/NeonEmitter.h deleted file mode 100644 index 12e4e8679908..000000000000 --- a/utils/TableGen/NeonEmitter.h +++ /dev/null @@ -1,176 +0,0 @@ -//===- NeonEmitter.h - Generate arm_neon.h for use with clang ---*- 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 arm_neon.h, which includes -// a declaration and definition of each function specified by the ARM NEON -// compiler interface. See ARM document DUI0348B. -// -//===----------------------------------------------------------------------===// - -#ifndef NEON_EMITTER_H -#define NEON_EMITTER_H - -#include "Record.h" -#include "TableGenBackend.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringMap.h" - -enum OpKind { - OpNone, - OpAdd, - OpAddl, - OpAddw, - OpSub, - OpSubl, - OpSubw, - OpMul, - OpMla, - OpMlal, - OpMls, - OpMlsl, - OpMulN, - OpMlaN, - OpMlsN, - OpMlalN, - OpMlslN, - OpMulLane, - OpMullLane, - OpMlaLane, - OpMlsLane, - OpMlalLane, - OpMlslLane, - OpQDMullLane, - OpQDMlalLane, - OpQDMlslLane, - OpQDMulhLane, - OpQRDMulhLane, - OpEq, - OpGe, - OpLe, - OpGt, - OpLt, - OpNeg, - OpNot, - OpAnd, - OpOr, - OpXor, - OpAndNot, - OpOrNot, - OpCast, - OpConcat, - OpDup, - OpDupLane, - OpHi, - OpLo, - OpSelect, - OpRev16, - OpRev32, - OpRev64, - OpReinterpret, - OpAbdl, - OpAba, - OpAbal -}; - -enum ClassKind { - ClassNone, - ClassI, // generic integer instruction, e.g., "i8" suffix - ClassS, // signed/unsigned/poly, e.g., "s8", "u8" or "p8" suffix - ClassW, // width-specific instruction, e.g., "8" suffix - ClassB // bitcast arguments with enum argument to specify type -}; - -namespace llvm { - - class NeonEmitter : public TableGenBackend { - RecordKeeper &Records; - StringMap OpMap; - DenseMap ClassMap; - - public: - NeonEmitter(RecordKeeper &R) : Records(R) { - OpMap["OP_NONE"] = OpNone; - OpMap["OP_ADD"] = OpAdd; - OpMap["OP_ADDL"] = OpAddl; - OpMap["OP_ADDW"] = OpAddw; - OpMap["OP_SUB"] = OpSub; - OpMap["OP_SUBL"] = OpSubl; - OpMap["OP_SUBW"] = OpSubw; - OpMap["OP_MUL"] = OpMul; - OpMap["OP_MLA"] = OpMla; - OpMap["OP_MLAL"] = OpMlal; - OpMap["OP_MLS"] = OpMls; - OpMap["OP_MLSL"] = OpMlsl; - OpMap["OP_MUL_N"] = OpMulN; - OpMap["OP_MLA_N"] = OpMlaN; - OpMap["OP_MLS_N"] = OpMlsN; - OpMap["OP_MLAL_N"] = OpMlalN; - OpMap["OP_MLSL_N"] = OpMlslN; - OpMap["OP_MUL_LN"]= OpMulLane; - OpMap["OP_MULL_LN"] = OpMullLane; - OpMap["OP_MLA_LN"]= OpMlaLane; - OpMap["OP_MLS_LN"]= OpMlsLane; - OpMap["OP_MLAL_LN"] = OpMlalLane; - OpMap["OP_MLSL_LN"] = OpMlslLane; - OpMap["OP_QDMULL_LN"] = OpQDMullLane; - OpMap["OP_QDMLAL_LN"] = OpQDMlalLane; - OpMap["OP_QDMLSL_LN"] = OpQDMlslLane; - OpMap["OP_QDMULH_LN"] = OpQDMulhLane; - OpMap["OP_QRDMULH_LN"] = OpQRDMulhLane; - OpMap["OP_EQ"] = OpEq; - OpMap["OP_GE"] = OpGe; - OpMap["OP_LE"] = OpLe; - OpMap["OP_GT"] = OpGt; - OpMap["OP_LT"] = OpLt; - OpMap["OP_NEG"] = OpNeg; - OpMap["OP_NOT"] = OpNot; - OpMap["OP_AND"] = OpAnd; - OpMap["OP_OR"] = OpOr; - OpMap["OP_XOR"] = OpXor; - OpMap["OP_ANDN"] = OpAndNot; - OpMap["OP_ORN"] = OpOrNot; - OpMap["OP_CAST"] = OpCast; - OpMap["OP_CONC"] = OpConcat; - OpMap["OP_HI"] = OpHi; - OpMap["OP_LO"] = OpLo; - OpMap["OP_DUP"] = OpDup; - OpMap["OP_DUP_LN"] = OpDupLane; - OpMap["OP_SEL"] = OpSelect; - OpMap["OP_REV16"] = OpRev16; - OpMap["OP_REV32"] = OpRev32; - OpMap["OP_REV64"] = OpRev64; - OpMap["OP_REINT"] = OpReinterpret; - OpMap["OP_ABDL"] = OpAbdl; - OpMap["OP_ABA"] = OpAba; - OpMap["OP_ABAL"] = OpAbal; - - Record *SI = R.getClass("SInst"); - Record *II = R.getClass("IInst"); - Record *WI = R.getClass("WInst"); - ClassMap[SI] = ClassS; - ClassMap[II] = ClassI; - ClassMap[WI] = ClassW; - } - - // run - Emit arm_neon.h.inc - void run(raw_ostream &o); - - // runHeader - Emit all the __builtin prototypes used in arm_neon.h - void runHeader(raw_ostream &o); - - // runTests - Emit tests for all the Neon intrinsics. - void runTests(raw_ostream &o); - - private: - void emitIntrinsic(raw_ostream &OS, Record *R); - }; - -} // End llvm namespace - -#endif diff --git a/utils/TableGen/OptParserEmitter.cpp b/utils/TableGen/OptParserEmitter.cpp deleted file mode 100644 index 431026c669c3..000000000000 --- a/utils/TableGen/OptParserEmitter.cpp +++ /dev/null @@ -1,194 +0,0 @@ -//===- OptParserEmitter.cpp - Table Driven Command Line Parsing -----------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "OptParserEmitter.h" -#include "Record.h" -#include "llvm/ADT/STLExtras.h" -using namespace llvm; - -static int StrCmpOptionName(const char *A, const char *B) { - char a = *A, b = *B; - while (a == b) { - if (a == '\0') - return 0; - - a = *++A; - b = *++B; - } - - if (a == '\0') // A is a prefix of B. - return 1; - if (b == '\0') // B is a prefix of A. - return -1; - - // Otherwise lexicographic. - return (a < b) ? -1 : 1; -} - -static int CompareOptionRecords(const void *Av, const void *Bv) { - const Record *A = *(Record**) Av; - const Record *B = *(Record**) Bv; - - // Sentinel options precede all others and are only ordered by precedence. - bool ASent = A->getValueAsDef("Kind")->getValueAsBit("Sentinel"); - bool BSent = B->getValueAsDef("Kind")->getValueAsBit("Sentinel"); - if (ASent != BSent) - return ASent ? -1 : 1; - - // Compare options by name, unless they are sentinels. - if (!ASent) - if (int Cmp = StrCmpOptionName(A->getValueAsString("Name").c_str(), - B->getValueAsString("Name").c_str())) - return Cmp; - - // Then by the kind precedence; - int APrec = A->getValueAsDef("Kind")->getValueAsInt("Precedence"); - int BPrec = B->getValueAsDef("Kind")->getValueAsInt("Precedence"); - assert(APrec != BPrec && "Options are equivalent!"); - return APrec < BPrec ? -1 : 1; -} - -static const std::string getOptionName(const Record &R) { - // Use the record name unless EnumName is defined. - if (dynamic_cast(R.getValueInit("EnumName"))) - return R.getName(); - - return R.getValueAsString("EnumName"); -} - -static raw_ostream &write_cstring(raw_ostream &OS, llvm::StringRef Str) { - OS << '"'; - OS.write_escaped(Str); - OS << '"'; - return OS; -} - -void OptParserEmitter::run(raw_ostream &OS) { - // Get the option groups and options. - const std::vector &Groups = - Records.getAllDerivedDefinitions("OptionGroup"); - std::vector Opts = Records.getAllDerivedDefinitions("Option"); - - if (GenDefs) - EmitSourceFileHeader("Option Parsing Definitions", OS); - else - EmitSourceFileHeader("Option Parsing Table", OS); - - array_pod_sort(Opts.begin(), Opts.end(), CompareOptionRecords); - if (GenDefs) { - OS << "#ifndef OPTION\n"; - OS << "#error \"Define OPTION prior to including this file!\"\n"; - OS << "#endif\n\n"; - - OS << "/////////\n"; - OS << "// Groups\n\n"; - for (unsigned i = 0, e = Groups.size(); i != e; ++i) { - const Record &R = *Groups[i]; - - // Start a single option entry. - OS << "OPTION("; - - // The option string. - OS << '"' << R.getValueAsString("Name") << '"'; - - // The option identifier name. - OS << ", "<< getOptionName(R); - - // The option kind. - OS << ", Group"; - - // The containing option group (if any). - OS << ", "; - if (const DefInit *DI = dynamic_cast(R.getValueInit("Group"))) - OS << getOptionName(*DI->getDef()); - else - OS << "INVALID"; - - // The other option arguments (unused for groups). - OS << ", INVALID, 0, 0"; - - // The option help text. - if (!dynamic_cast(R.getValueInit("HelpText"))) { - OS << ",\n"; - OS << " "; - write_cstring(OS, R.getValueAsString("HelpText")); - } else - OS << ", 0"; - - // The option meta-variable name (unused). - OS << ", 0)\n"; - } - OS << "\n"; - - OS << "//////////\n"; - OS << "// Options\n\n"; - for (unsigned i = 0, e = Opts.size(); i != e; ++i) { - const Record &R = *Opts[i]; - - // Start a single option entry. - OS << "OPTION("; - - // The option string. - write_cstring(OS, R.getValueAsString("Name")); - - // The option identifier name. - OS << ", "<< getOptionName(R); - - // The option kind. - OS << ", " << R.getValueAsDef("Kind")->getValueAsString("Name"); - - // The containing option group (if any). - OS << ", "; - if (const DefInit *DI = dynamic_cast(R.getValueInit("Group"))) - OS << getOptionName(*DI->getDef()); - else - OS << "INVALID"; - - // The option alias (if any). - OS << ", "; - if (const DefInit *DI = dynamic_cast(R.getValueInit("Alias"))) - OS << getOptionName(*DI->getDef()); - else - OS << "INVALID"; - - // The option flags. - const ListInit *LI = R.getValueAsListInit("Flags"); - if (LI->empty()) { - OS << ", 0"; - } else { - OS << ", "; - for (unsigned i = 0, e = LI->size(); i != e; ++i) { - if (i) - OS << " | "; - OS << dynamic_cast(LI->getElement(i))->getDef()->getName(); - } - } - - // The option parameter field. - OS << ", " << R.getValueAsInt("NumArgs"); - - // The option help text. - if (!dynamic_cast(R.getValueInit("HelpText"))) { - OS << ",\n"; - OS << " "; - write_cstring(OS, R.getValueAsString("HelpText")); - } else - OS << ", 0"; - - // The option meta-variable name. - OS << ", "; - if (!dynamic_cast(R.getValueInit("MetaVarName"))) - write_cstring(OS, R.getValueAsString("MetaVarName")); - else - OS << "0"; - - OS << ")\n"; - } - } -} diff --git a/utils/TableGen/OptParserEmitter.h b/utils/TableGen/OptParserEmitter.h deleted file mode 100644 index 241a3f2b4a08..000000000000 --- a/utils/TableGen/OptParserEmitter.h +++ /dev/null @@ -1,34 +0,0 @@ -//===- OptParserEmitter.h - Table Driven Command Line Parsing ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef UTILS_TABLEGEN_OPTPARSEREMITTER_H -#define UTILS_TABLEGEN_OPTPARSEREMITTER_H - -#include "TableGenBackend.h" - -namespace llvm { - /// OptParserEmitter - This tablegen backend takes an input .td file - /// describing a list of options and emits a data structure for parsing and - /// working with those options when given an input command line. - class OptParserEmitter : public TableGenBackend { - RecordKeeper &Records; - bool GenDefs; - - public: - OptParserEmitter(RecordKeeper &R, bool _GenDefs) - : Records(R), GenDefs(_GenDefs) {} - - /// run - Output the option parsing information. - /// - /// \param GenHeader - Generate the header describing the option IDs.x - void run(raw_ostream &OS); - }; -} - -#endif diff --git a/utils/TableGen/PseudoLoweringEmitter.cpp b/utils/TableGen/PseudoLoweringEmitter.cpp index db33c1f7f686..c685527a140c 100644 --- a/utils/TableGen/PseudoLoweringEmitter.cpp +++ b/utils/TableGen/PseudoLoweringEmitter.cpp @@ -8,10 +8,10 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "pseudo-lowering" -#include "Error.h" #include "CodeGenInstruction.h" #include "PseudoLoweringEmitter.h" -#include "Record.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/ErrorHandling.h" diff --git a/utils/TableGen/PseudoLoweringEmitter.h b/utils/TableGen/PseudoLoweringEmitter.h index 2749280e6a9d..325bc8be146f 100644 --- a/utils/TableGen/PseudoLoweringEmitter.h +++ b/utils/TableGen/PseudoLoweringEmitter.h @@ -12,7 +12,7 @@ #include "CodeGenInstruction.h" #include "CodeGenTarget.h" -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/SmallVector.h" diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 65d4a9b02dfd..b0f4ffc84e08 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -16,7 +16,8 @@ #include "RegisterInfoEmitter.h" #include "CodeGenTarget.h" #include "CodeGenRegisters.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Format.h" @@ -39,6 +40,9 @@ RegisterInfoEmitter::runEnums(raw_ostream &OS, OS << "namespace llvm {\n\n"; + OS << "class MCRegisterClass;\n" + << "extern MCRegisterClass " << Namespace << "MCRegisterClasses[];\n\n"; + if (!Namespace.empty()) OS << "namespace " << Namespace << " {\n"; OS << "enum {\n NoRegister,\n"; @@ -53,8 +57,7 @@ RegisterInfoEmitter::runEnums(raw_ostream &OS, if (!Namespace.empty()) OS << "}\n"; - const std::vector &RegisterClasses = - Target.getRegisterClasses(); + ArrayRef RegisterClasses = Bank.getRegClasses(); if (!RegisterClasses.empty()) { OS << "\n// Register classes\n"; if (!Namespace.empty()) @@ -62,7 +65,7 @@ RegisterInfoEmitter::runEnums(raw_ostream &OS, OS << "enum {\n"; for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { if (i) OS << ",\n"; - OS << " " << RegisterClasses[i].getName() << "RegClassID"; + OS << " " << RegisterClasses[i]->getName() << "RegClassID"; OS << " = " << i; } OS << "\n };\n"; @@ -91,6 +94,147 @@ RegisterInfoEmitter::runEnums(raw_ostream &OS, OS << "#endif // GET_REGINFO_ENUM\n\n"; } +void +RegisterInfoEmitter::EmitRegMapping(raw_ostream &OS, + const std::vector &Regs, + bool isCtor) { + + // Collect all information about dwarf register numbers + typedef std::map, LessRecord> DwarfRegNumsMapTy; + DwarfRegNumsMapTy DwarfRegNums; + + // First, just pull all provided information to the map + unsigned maxLength = 0; + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + Record *Reg = Regs[i]->TheDef; + std::vector RegNums = Reg->getValueAsListOfInts("DwarfNumbers"); + maxLength = std::max((size_t)maxLength, RegNums.size()); + if (DwarfRegNums.count(Reg)) + errs() << "Warning: DWARF numbers for register " << getQualifiedName(Reg) + << "specified multiple times\n"; + DwarfRegNums[Reg] = RegNums; + } + + if (!maxLength) + return; + + // Now we know maximal length of number list. Append -1's, where needed + for (DwarfRegNumsMapTy::iterator + I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) + for (unsigned i = I->second.size(), e = maxLength; i != e; ++i) + I->second.push_back(-1); + + // Emit reverse information about the dwarf register numbers. + for (unsigned j = 0; j < 2; ++j) { + OS << " switch ("; + if (j == 0) + OS << "DwarfFlavour"; + else + OS << "EHFlavour"; + OS << ") {\n" + << " default:\n" + << " assert(0 && \"Unknown DWARF flavour\");\n" + << " break;\n"; + + for (unsigned i = 0, e = maxLength; i != e; ++i) { + OS << " case " << i << ":\n"; + for (DwarfRegNumsMapTy::iterator + I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) { + int DwarfRegNo = I->second[i]; + if (DwarfRegNo < 0) + continue; + OS << " "; + if (!isCtor) + OS << "RI->"; + OS << "mapDwarfRegToLLVMReg(" << DwarfRegNo << ", " + << getQualifiedName(I->first) << ", "; + if (j == 0) + OS << "false"; + else + OS << "true"; + OS << " );\n"; + } + OS << " break;\n"; + } + OS << " }\n"; + } + + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + Record *Reg = Regs[i]->TheDef; + const RecordVal *V = Reg->getValue("DwarfAlias"); + if (!V || !V->getValue()) + continue; + + DefInit *DI = dynamic_cast(V->getValue()); + Record *Alias = DI->getDef(); + DwarfRegNums[Reg] = DwarfRegNums[Alias]; + } + + // Emit information about the dwarf register numbers. + for (unsigned j = 0; j < 2; ++j) { + OS << " switch ("; + if (j == 0) + OS << "DwarfFlavour"; + else + OS << "EHFlavour"; + OS << ") {\n" + << " default:\n" + << " assert(0 && \"Unknown DWARF flavour\");\n" + << " break;\n"; + + for (unsigned i = 0, e = maxLength; i != e; ++i) { + OS << " case " << i << ":\n"; + // Sort by name to get a stable order. + for (DwarfRegNumsMapTy::iterator + I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) { + int RegNo = I->second[i]; + OS << " "; + if (!isCtor) + OS << "RI->"; + OS << "mapLLVMRegToDwarfReg(" << getQualifiedName(I->first) << ", " + << RegNo << ", "; + if (j == 0) + OS << "false"; + else + OS << "true"; + OS << " );\n"; + } + OS << " break;\n"; + } + OS << " }\n"; + } +} + +// Print a BitVector as a sequence of hex numbers using a little-endian mapping. +// Width is the number of bits per hex number. +static void printBitVectorAsHex(raw_ostream &OS, + const BitVector &Bits, + unsigned Width) { + assert(Width <= 32 && "Width too large"); + unsigned Digits = (Width + 3) / 4; + for (unsigned i = 0, e = Bits.size(); i < e; i += Width) { + unsigned Value = 0; + for (unsigned j = 0; j != Width && i + j != e; ++j) + Value |= Bits.test(i + j) << j; + OS << format("0x%0*x, ", Digits, Value); + } +} + +// Helper to emit a set of bits into a constant byte array. +class BitVectorEmitter { + BitVector Values; +public: + void add(unsigned v) { + if (v >= Values.size()) + Values.resize(((v/8)+1)*8); // Round up to the next byte. + Values[v] = true; + } + + void print(raw_ostream &OS) { + printBitVectorAsHex(OS, Values, 8); + } +}; + // // runMCDesc - Print out MC register descriptions. // @@ -186,11 +330,73 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, } OS << "};\n\n"; // End of register descriptors... + ArrayRef RegisterClasses = RegBank.getRegClasses(); + + // Loop over all of the register classes... emitting each one. + OS << "namespace { // Register classes...\n"; + + // Emit the register enum value arrays for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = *RegisterClasses[rc]; + ArrayRef Order = RC.getOrder(); + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.getName(); + + // Emit the register list now. + OS << " // " << Name << " Register Class...\n" + << " static const unsigned " << Name + << "[] = {\n "; + for (unsigned i = 0, e = Order.size(); i != e; ++i) { + Record *Reg = Order[i]; + OS << getQualifiedName(Reg) << ", "; + } + OS << "\n };\n\n"; + + OS << " // " << Name << " Bit set.\n" + << " static const unsigned char " << Name + << "Bits[] = {\n "; + BitVectorEmitter BVE; + for (unsigned i = 0, e = Order.size(); i != e; ++i) { + Record *Reg = Order[i]; + BVE.add(Target.getRegBank().getReg(Reg)->EnumValue); + } + BVE.print(OS); + OS << "\n };\n\n"; + + } + OS << "}\n\n"; + + OS << "MCRegisterClass " << TargetName << "MCRegisterClasses[] = {\n"; + + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = *RegisterClasses[rc]; + OS << " MCRegisterClass(" << RC.getQualifiedName() + "RegClassID" << ", " + << '\"' << RC.getName() << "\", " + << RC.SpillSize/8 << ", " + << RC.SpillAlignment/8 << ", " + << RC.CopyCost << ", " + << RC.Allocatable << ", " + << RC.getName() << ", " << RC.getName() << " + " + << RC.getOrder().size() << ", " + << RC.getName() << "Bits, sizeof(" << RC.getName() << "Bits)" + << "),\n"; + } + + OS << "};\n\n"; + // MCRegisterInfo initialization routine. OS << "static inline void Init" << TargetName - << "MCRegisterInfo(MCRegisterInfo *RI) {\n"; + << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, " + << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n"; OS << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, " - << Regs.size()+1 << ");\n}\n\n"; + << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, " + << RegisterClasses.size() << ");\n\n"; + + EmitRegMapping(OS, Regs, false); + + OS << "}\n\n"; + OS << "} // End llvm namespace \n"; OS << "#endif // GET_REGINFO_MC_DESC\n\n"; @@ -213,17 +419,15 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target, OS << "namespace llvm {\n\n"; OS << "struct " << ClassName << " : public TargetRegisterInfo {\n" - << " explicit " << ClassName << "();\n" - << " virtual int getDwarfRegNumFull(unsigned RegNum, " - << "unsigned Flavour) const;\n" - << " virtual int getLLVMRegNumFull(unsigned DwarfRegNum, " - << "unsigned Flavour) const;\n" - << " virtual int getDwarfRegNum(unsigned RegNum, bool isEH) const = 0;\n" + << " explicit " << ClassName + << "(unsigned RA, unsigned D = 0, unsigned E = 0);\n" << " virtual bool needsStackRealignment(const MachineFunction &) const\n" << " { return false; }\n" << " unsigned getSubReg(unsigned RegNo, unsigned Index) const;\n" << " unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;\n" << " unsigned composeSubRegIndices(unsigned, unsigned) const;\n" + << " const TargetRegisterClass *" + "getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n" << "};\n\n"; const std::vector &SubRegIndices = RegBank.getSubRegIndices(); @@ -241,15 +445,14 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target, OS << "}\n"; } - const std::vector &RegisterClasses = - Target.getRegisterClasses(); + ArrayRef RegisterClasses = RegBank.getRegClasses(); if (!RegisterClasses.empty()) { - OS << "namespace " << RegisterClasses[0].Namespace + OS << "namespace " << RegisterClasses[0]->Namespace << " { // Register classes\n"; for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { - const CodeGenRegisterClass &RC = RegisterClasses[i]; + const CodeGenRegisterClass &RC = *RegisterClasses[i]; const std::string &Name = RC.getName(); // Output the register class definition. @@ -285,42 +488,30 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "namespace llvm {\n\n"; + // Get access to MCRegisterClass data. + OS << "extern MCRegisterClass " << Target.getName() + << "MCRegisterClasses[];\n"; + // Start out by emitting each of the register classes. - const std::vector &RegisterClasses = - Target.getRegisterClasses(); + ArrayRef RegisterClasses = RegBank.getRegClasses(); // Collect all registers belonging to any allocatable class. std::set AllocatableRegs; - // Loop over all of the register classes... emitting each one. - OS << "namespace { // Register classes...\n"; - - // Emit the register enum value arrays for each RegisterClass + // Collect allocatable registers. for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = RegisterClasses[rc]; + const CodeGenRegisterClass &RC = *RegisterClasses[rc]; ArrayRef Order = RC.getOrder(); - // Collect allocatable registers. if (RC.Allocatable) AllocatableRegs.insert(Order.begin(), Order.end()); - - // Give the register class a legal C name if it's anonymous. - std::string Name = RC.getName(); - - // Emit the register list now. - OS << " // " << Name << " Register Class...\n" - << " static const unsigned " << Name - << "[] = {\n "; - for (unsigned i = 0, e = Order.size(); i != e; ++i) { - Record *Reg = Order[i]; - OS << getQualifiedName(Reg) << ", "; - } - OS << "\n };\n\n"; } + OS << "namespace { // Register classes...\n"; + // Emit the ValueType arrays for each RegisterClass for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = RegisterClasses[rc]; + const CodeGenRegisterClass &RC = *RegisterClasses[rc]; // Give the register class a legal C name if it's anonymous. std::string Name = RC.getName() + "VTs"; @@ -338,65 +529,39 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, // Now that all of the structs have been emitted, emit the instances. if (!RegisterClasses.empty()) { - OS << "namespace " << RegisterClasses[0].Namespace + OS << "namespace " << RegisterClasses[0]->Namespace << " { // Register class instances\n"; for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) - OS << " " << RegisterClasses[i].getName() << "Class\t" - << RegisterClasses[i].getName() << "RegClass;\n"; + OS << " " << RegisterClasses[i]->getName() << "Class\t" + << RegisterClasses[i]->getName() << "RegClass;\n"; - std::map > SuperClassMap; std::map > SuperRegClassMap; - OS << "\n"; + + OS << "\n static const TargetRegisterClass* const " + << "NullRegClasses[] = { NULL };\n\n"; unsigned NumSubRegIndices = RegBank.getSubRegIndices().size(); if (NumSubRegIndices) { - // Emit the sub-register classes for each RegisterClass + // Compute the super-register classes for each RegisterClass for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = RegisterClasses[rc]; - std::vector SRC(NumSubRegIndices); + const CodeGenRegisterClass &RC = *RegisterClasses[rc]; for (DenseMap::const_iterator i = RC.SubRegClasses.begin(), e = RC.SubRegClasses.end(); i != e; ++i) { - // Build SRC array. - unsigned idx = RegBank.getSubRegIndexNo(i->first); - SRC.at(idx-1) = i->second; - // Find the register class number of i->second for SuperRegClassMap. - for (unsigned rc2 = 0, e2 = RegisterClasses.size(); rc2 != e2; ++rc2) { - const CodeGenRegisterClass &RC2 = RegisterClasses[rc2]; - if (RC2.TheDef == i->second) { - SuperRegClassMap[rc2].insert(rc); - break; - } - } + const CodeGenRegisterClass *RC2 = RegBank.getRegClass(i->second); + assert(RC2 && "Invalid register class in SubRegClasses"); + SuperRegClassMap[RC2->EnumValue].insert(rc); } - - // Give the register class a legal C name if it's anonymous. - std::string Name = RC.TheDef->getName(); - - OS << " // " << Name - << " Sub-register Classes...\n" - << " static const TargetRegisterClass* const " - << Name << "SubRegClasses[] = {\n "; - - for (unsigned idx = 0; idx != NumSubRegIndices; ++idx) { - if (idx) - OS << ", "; - if (SRC[idx]) - OS << "&" << getQualifiedName(SRC[idx]) << "RegClass"; - else - OS << "0"; - } - OS << "\n };\n\n"; } // Emit the super-register classes for each RegisterClass for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = RegisterClasses[rc]; + const CodeGenRegisterClass &RC = *RegisterClasses[rc]; // Give the register class a legal C name if it's anonymous. - std::string Name = RC.TheDef->getName(); + std::string Name = RC.getName(); OS << " // " << Name << " Super-register Classes...\n" @@ -409,10 +574,10 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, if (I != SuperRegClassMap.end()) { for (std::set::iterator II = I->second.begin(), EE = I->second.end(); II != EE; ++II) { - const CodeGenRegisterClass &RC2 = RegisterClasses[*II]; + const CodeGenRegisterClass &RC2 = *RegisterClasses[*II]; if (!Empty) OS << ", "; - OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; + OS << "&" << RC2.getQualifiedName() << "RegClass"; Empty = false; } } @@ -420,97 +585,51 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, OS << (!Empty ? ", " : "") << "NULL"; OS << "\n };\n\n"; } - } else { - // No subregindices in this target - OS << " static const TargetRegisterClass* const " - << "NullRegClasses[] = { NULL };\n\n"; } // Emit the sub-classes array for each RegisterClass for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = RegisterClasses[rc]; + const CodeGenRegisterClass &RC = *RegisterClasses[rc]; // Give the register class a legal C name if it's anonymous. - std::string Name = RC.TheDef->getName(); + std::string Name = RC.getName(); - OS << " // " << Name - << " Register Class sub-classes...\n" - << " static const TargetRegisterClass* const " - << Name << "Subclasses[] = {\n "; - - bool Empty = true; - for (unsigned rc2 = 0, e2 = RegisterClasses.size(); rc2 != e2; ++rc2) { - const CodeGenRegisterClass &RC2 = RegisterClasses[rc2]; - - // Sub-classes are used to determine if a virtual register can be used - // as an instruction operand, or if it must be copied first. - if (rc == rc2 || !RC.hasSubClass(&RC2)) continue; - - if (!Empty) OS << ", "; - OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; - Empty = false; - - std::map >::iterator SCMI = - SuperClassMap.find(rc2); - if (SCMI == SuperClassMap.end()) { - SuperClassMap.insert(std::make_pair(rc2, std::set())); - SCMI = SuperClassMap.find(rc2); - } - SCMI->second.insert(rc); - } - - OS << (!Empty ? ", " : "") << "NULL"; - OS << "\n };\n\n"; + OS << " static const unsigned " << Name << "SubclassMask[] = { "; + printBitVectorAsHex(OS, RC.getSubClasses(), 32); + OS << "};\n\n"; } + // Emit NULL terminated super-class lists. for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = RegisterClasses[rc]; + const CodeGenRegisterClass &RC = *RegisterClasses[rc]; + ArrayRef Supers = RC.getSuperClasses(); - // Give the register class a legal C name if it's anonymous. - std::string Name = RC.TheDef->getName(); + // Skip classes without supers. We can reuse NullRegClasses. + if (Supers.empty()) + continue; - OS << " // " << Name - << " Register Class super-classes...\n" - << " static const TargetRegisterClass* const " - << Name << "Superclasses[] = {\n "; - - bool Empty = true; - std::map >::iterator I = - SuperClassMap.find(rc); - if (I != SuperClassMap.end()) { - for (std::set::iterator II = I->second.begin(), - EE = I->second.end(); II != EE; ++II) { - const CodeGenRegisterClass &RC2 = RegisterClasses[*II]; - if (!Empty) OS << ", "; - OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; - Empty = false; - } - } - - OS << (!Empty ? ", " : "") << "NULL"; - OS << "\n };\n\n"; + OS << " static const TargetRegisterClass* const " + << RC.getName() << "Superclasses[] = {\n"; + for (unsigned i = 0; i != Supers.size(); ++i) + OS << " &" << Supers[i]->getQualifiedName() << "RegClass,\n"; + OS << " NULL\n };\n\n"; } // Emit methods. for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) { - const CodeGenRegisterClass &RC = RegisterClasses[i]; + const CodeGenRegisterClass &RC = *RegisterClasses[i]; OS << RC.getName() << "Class::" << RC.getName() - << "Class() : TargetRegisterClass(" - << RC.getName() + "RegClassID" << ", " - << '\"' << RC.getName() << "\", " + << "Class() : TargetRegisterClass(&" + << Target.getName() << "MCRegisterClasses[" + << RC.getName() + "RegClassID" << "], " << RC.getName() + "VTs" << ", " - << RC.getName() + "Subclasses" << ", " - << RC.getName() + "Superclasses" << ", " - << (NumSubRegIndices ? RC.getName() + "Sub" : std::string("Null")) - << "RegClasses, " - << (NumSubRegIndices ? RC.getName() + "Super" : std::string("Null")) - << "RegClasses, " - << RC.SpillSize/8 << ", " - << RC.SpillAlignment/8 << ", " - << RC.CopyCost << ", " - << RC.Allocatable << ", " - << RC.getName() << ", " << RC.getName() << " + " - << RC.getOrder().size() + << RC.getName() + "SubclassMask" << ", "; + if (RC.getSuperClasses().empty()) + OS << "NullRegClasses, "; + else + OS << RC.getName() + "Superclasses, "; + OS << (NumSubRegIndices ? RC.getName() + "Super" : std::string("Null")) + << "RegClasses" << ") {}\n"; if (!RC.AltOrderSelect.empty()) { OS << "\nstatic inline unsigned " << RC.getName() @@ -525,10 +644,12 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, OS << (elem ? ", " : " ") << getQualifiedName(Elems[elem]); OS << " };\n"; } - OS << " static const ArrayRef Order[] = {\n" - << " ArrayRef(" << RC.getName(); + OS << " const MCRegisterClass &MCR = " << Target.getName() + << "MCRegisterClasses[" << RC.getQualifiedName() + "RegClassID];" + << " static const ArrayRef Order[] = {\n" + << " makeArrayRef(MCR.begin(), MCR.getNumRegs()"; for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi) - OS << "),\n ArrayRef(AltOrder" << oi; + OS << "),\n makeArrayRef(AltOrder" << oi; OS << ")\n };\n const unsigned Select = " << RC.getName() << "AltOrderSelect(MF);\n assert(Select < " << RC.getNumOrders() << ");\n return Order[Select];\n}\n"; @@ -541,7 +662,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "\nnamespace {\n"; OS << " const TargetRegisterClass* const RegisterClasses[] = {\n"; for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) - OS << " &" << getQualifiedName(RegisterClasses[i].TheDef) + OS << " &" << RegisterClasses[i]->getQualifiedName() << "RegClass,\n"; OS << " };\n"; OS << "}\n"; // End of anonymous namespace... @@ -658,106 +779,59 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, } OS << " }\n}\n\n"; + // Emit getSubClassWithSubReg. + OS << "const TargetRegisterClass *" << ClassName + << "::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx)" + " const {\n"; + if (SubRegIndices.empty()) { + OS << " assert(Idx == 0 && \"Target has no sub-registers\");\n" + << " return RC;\n"; + } else { + // Use the smallest type that can hold a regclass ID with room for a + // sentinel. + if (RegisterClasses.size() < UINT8_MAX) + OS << " static const uint8_t Table["; + else if (RegisterClasses.size() < UINT16_MAX) + OS << " static const uint16_t Table["; + else + throw "Too many register classes."; + OS << RegisterClasses.size() << "][" << SubRegIndices.size() << "] = {\n"; + for (unsigned rci = 0, rce = RegisterClasses.size(); rci != rce; ++rci) { + const CodeGenRegisterClass &RC = *RegisterClasses[rci]; + OS << " {\t// " << RC.getName() << "\n"; + for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) { + Record *Idx = SubRegIndices[sri]; + if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(Idx)) + OS << " " << SRC->EnumValue + 1 << ",\t// " << Idx->getName() + << " -> " << SRC->getName() << "\n"; + else + OS << " 0,\t// " << Idx->getName() << "\n"; + } + OS << " },\n"; + } + OS << " };\n assert(RC && \"Missing regclass\");\n" + << " if (!Idx) return RC;\n --Idx;\n" + << " assert(Idx < " << SubRegIndices.size() << " && \"Bad subreg\");\n" + << " unsigned TV = Table[RC->getID()][Idx];\n" + << " return TV ? getRegClass(TV - 1) : 0;\n"; + } + OS << "}\n\n"; + // Emit the constructor of the class... OS << "extern MCRegisterDesc " << TargetName << "RegDesc[];\n"; OS << ClassName << "::" << ClassName - << "()\n" + << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n" << " : TargetRegisterInfo(" << TargetName << "RegInfoDesc" << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n" << " " << TargetName << "SubRegIndexTable) {\n" << " InitMCRegisterInfo(" << TargetName << "RegDesc, " - << Regs.size()+1 << ");\n" - << "}\n\n"; + << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, " + << RegisterClasses.size() << ");\n\n"; - // Collect all information about dwarf register numbers - typedef std::map, LessRecord> DwarfRegNumsMapTy; - DwarfRegNumsMapTy DwarfRegNums; + EmitRegMapping(OS, Regs, true); - // First, just pull all provided information to the map - unsigned maxLength = 0; - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - Record *Reg = Regs[i]->TheDef; - std::vector RegNums = Reg->getValueAsListOfInts("DwarfNumbers"); - maxLength = std::max((size_t)maxLength, RegNums.size()); - if (DwarfRegNums.count(Reg)) - errs() << "Warning: DWARF numbers for register " << getQualifiedName(Reg) - << "specified multiple times\n"; - DwarfRegNums[Reg] = RegNums; - } - - // Now we know maximal length of number list. Append -1's, where needed - for (DwarfRegNumsMapTy::iterator - I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) - for (unsigned i = I->second.size(), e = maxLength; i != e; ++i) - I->second.push_back(-1); - - // Emit reverse information about the dwarf register numbers. - OS << "int " << ClassName << "::getLLVMRegNumFull(unsigned DwarfRegNum, " - << "unsigned Flavour) const {\n" - << " switch (Flavour) {\n" - << " default:\n" - << " assert(0 && \"Unknown DWARF flavour\");\n" - << " return -1;\n"; - - for (unsigned i = 0, e = maxLength; i != e; ++i) { - OS << " case " << i << ":\n" - << " switch (DwarfRegNum) {\n" - << " default:\n" - << " assert(0 && \"Invalid DwarfRegNum\");\n" - << " return -1;\n"; - - for (DwarfRegNumsMapTy::iterator - I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) { - int DwarfRegNo = I->second[i]; - if (DwarfRegNo >= 0) - OS << " case " << DwarfRegNo << ":\n" - << " return " << getQualifiedName(I->first) << ";\n"; - } - OS << " };\n"; - } - - OS << " };\n}\n\n"; - - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - Record *Reg = Regs[i]->TheDef; - const RecordVal *V = Reg->getValue("DwarfAlias"); - if (!V || !V->getValue()) - continue; - - DefInit *DI = dynamic_cast(V->getValue()); - Record *Alias = DI->getDef(); - DwarfRegNums[Reg] = DwarfRegNums[Alias]; - } - - // Emit information about the dwarf register numbers. - OS << "int " << ClassName << "::getDwarfRegNumFull(unsigned RegNum, " - << "unsigned Flavour) const {\n" - << " switch (Flavour) {\n" - << " default:\n" - << " assert(0 && \"Unknown DWARF flavour\");\n" - << " return -1;\n"; - - for (unsigned i = 0, e = maxLength; i != e; ++i) { - OS << " case " << i << ":\n" - << " switch (RegNum) {\n" - << " default:\n" - << " assert(0 && \"Invalid RegNum\");\n" - << " return -1;\n"; - - // Sort by name to get a stable order. - - - for (DwarfRegNumsMapTy::iterator - I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) { - int RegNo = I->second[i]; - OS << " case " << getQualifiedName(I->first) << ":\n" - << " return " << RegNo << ";\n"; - } - OS << " };\n"; - } - - OS << " };\n}\n\n"; + OS << "}\n\n"; OS << "} // End llvm namespace \n"; OS << "#endif // GET_REGINFO_TARGET_DESC\n\n"; diff --git a/utils/TableGen/RegisterInfoEmitter.h b/utils/TableGen/RegisterInfoEmitter.h index 2c01b5c3bd06..0fd4d079ebc0 100644 --- a/utils/TableGen/RegisterInfoEmitter.h +++ b/utils/TableGen/RegisterInfoEmitter.h @@ -16,11 +16,13 @@ #ifndef REGISTER_INFO_EMITTER_H #define REGISTER_INFO_EMITTER_H -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" +#include namespace llvm { class CodeGenRegBank; +struct CodeGenRegister; class CodeGenTarget; class RegisterInfoEmitter : public TableGenBackend { @@ -44,6 +46,11 @@ class RegisterInfoEmitter : public TableGenBackend { // run - Output the register file description. void run(raw_ostream &o); + +private: + void EmitRegMapping(raw_ostream &o, + const std::vector &Regs, bool isCtor); + void EmitRegClasses(raw_ostream &OS, CodeGenTarget &Target); }; } // End llvm namespace diff --git a/utils/TableGen/SetTheory.cpp b/utils/TableGen/SetTheory.cpp index 21ac09cb6625..bef73f33effe 100644 --- a/utils/TableGen/SetTheory.cpp +++ b/utils/TableGen/SetTheory.cpp @@ -13,8 +13,8 @@ //===----------------------------------------------------------------------===// #include "SetTheory.h" -#include "Error.h" -#include "Record.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" #include "llvm/Support/Format.h" using namespace llvm; diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index 978e91a1d6c0..103a4032b02a 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -13,7 +13,7 @@ #include "SubtargetEmitter.h" #include "CodeGenTarget.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Debug.h" #include diff --git a/utils/TableGen/SubtargetEmitter.h b/utils/TableGen/SubtargetEmitter.h index b239f3dda76d..ff01274bd1a7 100644 --- a/utils/TableGen/SubtargetEmitter.h +++ b/utils/TableGen/SubtargetEmitter.h @@ -14,7 +14,7 @@ #ifndef SUBTARGET_EMITTER_H #define SUBTARGET_EMITTER_H -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" #include "llvm/MC/MCInstrItineraries.h" #include #include diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp index e8eacb841d03..eacfdf6fed39 100644 --- a/utils/TableGen/TableGen.cpp +++ b/utils/TableGen/TableGen.cpp @@ -1,4 +1,4 @@ -//===- TableGen.cpp - Top-Level TableGen implementation -------------------===// +//===- TableGen.cpp - Top-Level TableGen implementation for LLVM ----------===// // // The LLVM Compiler Infrastructure // @@ -7,48 +7,34 @@ // //===----------------------------------------------------------------------===// // -// TableGen is a tool which can be used to build up a description of something, -// then invoke one or more "tablegen backends" to emit information about the -// description in some predefined format. In practice, this is used by the LLVM -// code generators to automate generation of a code generator through a -// high-level description of the target. +// This file contains the main function for LLVM's TableGen. // //===----------------------------------------------------------------------===// #include "AsmMatcherEmitter.h" #include "AsmWriterEmitter.h" #include "CallingConvEmitter.h" -#include "ClangASTNodesEmitter.h" -#include "ClangAttrEmitter.h" -#include "ClangDiagnosticsEmitter.h" -#include "ClangSACheckersEmitter.h" #include "CodeEmitterGen.h" #include "DAGISelEmitter.h" #include "DisassemblerEmitter.h" #include "EDEmitter.h" -#include "Error.h" #include "FastISelEmitter.h" #include "InstrInfoEmitter.h" #include "IntrinsicEmitter.h" -#include "LLVMCConfigurationEmitter.h" -#include "NeonEmitter.h" -#include "OptParserEmitter.h" #include "PseudoLoweringEmitter.h" -#include "Record.h" #include "RegisterInfoEmitter.h" #include "ARMDecoderEmitter.h" #include "SubtargetEmitter.h" #include "SetTheory.h" -#include "TGParser.h" -#include "llvm/ADT/OwningPtr.h" + #include "llvm/Support/CommandLine.h" -#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/Signals.h" -#include "llvm/Support/system_error.h" -#include -#include +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Main.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenAction.h" + using namespace llvm; enum ActionType { @@ -62,29 +48,12 @@ enum ActionType { GenDisassembler, GenPseudoLowering, GenCallingConv, - GenClangAttrClasses, - GenClangAttrImpl, - GenClangAttrList, - GenClangAttrPCHRead, - GenClangAttrPCHWrite, - GenClangAttrSpellingList, - GenClangDiagsDefs, - GenClangDiagGroups, - GenClangDiagsIndexName, - GenClangDeclNodes, - GenClangStmtNodes, - GenClangSACheckers, GenDAGISel, GenFastISel, - GenOptParserDefs, GenOptParserImpl, GenSubtarget, GenIntrinsic, GenTgtIntrinsic, - GenLLVMCConf, GenEDInfo, - GenArmNeon, - GenArmNeonSema, - GenArmNeonTest, PrintEnums, PrintSets }; @@ -116,52 +85,14 @@ namespace { "Generate a DAG instruction selector"), clEnumValN(GenFastISel, "gen-fast-isel", "Generate a \"fast\" instruction selector"), - clEnumValN(GenOptParserDefs, "gen-opt-parser-defs", - "Generate option definitions"), - clEnumValN(GenOptParserImpl, "gen-opt-parser-impl", - "Generate option parser implementation"), clEnumValN(GenSubtarget, "gen-subtarget", "Generate subtarget enumerations"), clEnumValN(GenIntrinsic, "gen-intrinsic", "Generate intrinsic information"), clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic", "Generate target intrinsic information"), - clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes", - "Generate clang attribute clases"), - clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl", - "Generate clang attribute implementations"), - clEnumValN(GenClangAttrList, "gen-clang-attr-list", - "Generate a clang attribute list"), - clEnumValN(GenClangAttrPCHRead, "gen-clang-attr-pch-read", - "Generate clang PCH attribute reader"), - clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write", - "Generate clang PCH attribute writer"), - clEnumValN(GenClangAttrSpellingList, - "gen-clang-attr-spelling-list", - "Generate a clang attribute spelling list"), - clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs", - "Generate Clang diagnostics definitions"), - clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups", - "Generate Clang diagnostic groups"), - clEnumValN(GenClangDiagsIndexName, - "gen-clang-diags-index-name", - "Generate Clang diagnostic name index"), - clEnumValN(GenClangDeclNodes, "gen-clang-decl-nodes", - "Generate Clang AST declaration nodes"), - clEnumValN(GenClangStmtNodes, "gen-clang-stmt-nodes", - "Generate Clang AST statement nodes"), - clEnumValN(GenClangSACheckers, "gen-clang-sa-checkers", - "Generate Clang Static Analyzer checkers"), - clEnumValN(GenLLVMCConf, "gen-llvmc", - "Generate LLVMC configuration library"), clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info", "Generate enhanced disassembly info"), - clEnumValN(GenArmNeon, "gen-arm-neon", - "Generate arm_neon.h for clang"), - clEnumValN(GenArmNeonSema, "gen-arm-neon-sema", - "Generate ARM NEON sema support for clang"), - clEnumValN(GenArmNeonTest, "gen-arm-neon-test", - "Generate ARM NEON tests for clang"), clEnumValN(PrintEnums, "print-enums", "Print enum values for a class"), clEnumValN(PrintSets, "print-sets", @@ -171,198 +102,66 @@ namespace { cl::opt Class("class", cl::desc("Print Enum list for this class"), cl::value_desc("class name")); - - cl::opt - OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), - cl::init("-")); - - cl::opt - DependFilename("d", cl::desc("Dependency filename"), cl::value_desc("filename"), - cl::init("")); - - cl::opt - InputFilename(cl::Positional, cl::desc(""), cl::init("-")); - - cl::list - IncludeDirs("I", cl::desc("Directory of include files"), - cl::value_desc("directory"), cl::Prefix); - - cl::opt - ClangComponent("clang-component", - cl::desc("Only use warnings from specified component"), - cl::value_desc("component"), cl::Hidden); } - -int main(int argc, char **argv) { - RecordKeeper Records; - - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - cl::ParseCommandLineOptions(argc, argv); - - - try { - // Parse the input file. - OwningPtr File; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) { - errs() << "Could not open input file '" << InputFilename << "': " - << ec.message() <<"\n"; - return 1; - } - MemoryBuffer *F = File.take(); - - // Tell SrcMgr about this buffer, which is what TGParser will pick up. - SrcMgr.AddNewSourceBuffer(F, SMLoc()); - - // Record the location of the include directory so that the lexer can find - // it later. - SrcMgr.setIncludeDirs(IncludeDirs); - - TGParser Parser(SrcMgr, Records); - - if (Parser.ParseFile()) - return 1; - - std::string Error; - tool_output_file Out(OutputFilename.c_str(), Error); - if (!Error.empty()) { - errs() << argv[0] << ": error opening " << OutputFilename - << ":" << Error << "\n"; - return 1; - } - if (!DependFilename.empty()) { - if (OutputFilename == "-") { - errs() << argv[0] << ": the option -d must be used together with -o\n"; - return 1; - } - tool_output_file DepOut(DependFilename.c_str(), Error); - if (!Error.empty()) { - errs() << argv[0] << ": error opening " << DependFilename - << ":" << Error << "\n"; - return 1; - } - DepOut.os() << DependFilename << ":"; - const std::vector &Dependencies = Parser.getDependencies(); - for (std::vector::const_iterator I = Dependencies.begin(), - E = Dependencies.end(); - I != E; ++I) { - DepOut.os() << " " << (*I); - } - DepOut.os() << "\n"; - DepOut.keep(); - } - +class LLVMTableGenAction : public TableGenAction { +public: + bool operator()(raw_ostream &OS, RecordKeeper &Records) { switch (Action) { case PrintRecords: - Out.os() << Records; // No argument, dump all contents + OS << Records; // No argument, dump all contents break; case GenEmitter: - CodeEmitterGen(Records).run(Out.os()); + CodeEmitterGen(Records).run(OS); break; case GenRegisterInfo: - RegisterInfoEmitter(Records).run(Out.os()); + RegisterInfoEmitter(Records).run(OS); break; case GenInstrInfo: - InstrInfoEmitter(Records).run(Out.os()); + InstrInfoEmitter(Records).run(OS); break; case GenCallingConv: - CallingConvEmitter(Records).run(Out.os()); + CallingConvEmitter(Records).run(OS); break; case GenAsmWriter: - AsmWriterEmitter(Records).run(Out.os()); + AsmWriterEmitter(Records).run(OS); break; case GenARMDecoder: - ARMDecoderEmitter(Records).run(Out.os()); + ARMDecoderEmitter(Records).run(OS); break; case GenAsmMatcher: - AsmMatcherEmitter(Records).run(Out.os()); - break; - case GenClangAttrClasses: - ClangAttrClassEmitter(Records).run(Out.os()); - break; - case GenClangAttrImpl: - ClangAttrImplEmitter(Records).run(Out.os()); - break; - case GenClangAttrList: - ClangAttrListEmitter(Records).run(Out.os()); - break; - case GenClangAttrPCHRead: - ClangAttrPCHReadEmitter(Records).run(Out.os()); - break; - case GenClangAttrPCHWrite: - ClangAttrPCHWriteEmitter(Records).run(Out.os()); - break; - case GenClangAttrSpellingList: - ClangAttrSpellingListEmitter(Records).run(Out.os()); - break; - case GenClangDiagsDefs: - ClangDiagsDefsEmitter(Records, ClangComponent).run(Out.os()); - break; - case GenClangDiagGroups: - ClangDiagGroupsEmitter(Records).run(Out.os()); - break; - case GenClangDiagsIndexName: - ClangDiagsIndexNameEmitter(Records).run(Out.os()); - break; - case GenClangDeclNodes: - ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out.os()); - ClangDeclContextEmitter(Records).run(Out.os()); - break; - case GenClangStmtNodes: - ClangASTNodesEmitter(Records, "Stmt", "").run(Out.os()); - break; - case GenClangSACheckers: - ClangSACheckersEmitter(Records).run(Out.os()); + AsmMatcherEmitter(Records).run(OS); break; case GenDisassembler: - DisassemblerEmitter(Records).run(Out.os()); + DisassemblerEmitter(Records).run(OS); break; case GenPseudoLowering: - PseudoLoweringEmitter(Records).run(Out.os()); - break; - case GenOptParserDefs: - OptParserEmitter(Records, true).run(Out.os()); - break; - case GenOptParserImpl: - OptParserEmitter(Records, false).run(Out.os()); + PseudoLoweringEmitter(Records).run(OS); break; case GenDAGISel: - DAGISelEmitter(Records).run(Out.os()); + DAGISelEmitter(Records).run(OS); break; case GenFastISel: - FastISelEmitter(Records).run(Out.os()); + FastISelEmitter(Records).run(OS); break; case GenSubtarget: - SubtargetEmitter(Records).run(Out.os()); + SubtargetEmitter(Records).run(OS); break; case GenIntrinsic: - IntrinsicEmitter(Records).run(Out.os()); + IntrinsicEmitter(Records).run(OS); break; case GenTgtIntrinsic: - IntrinsicEmitter(Records, true).run(Out.os()); - break; - case GenLLVMCConf: - LLVMCConfigurationEmitter(Records).run(Out.os()); + IntrinsicEmitter(Records, true).run(OS); break; case GenEDInfo: - EDEmitter(Records).run(Out.os()); - break; - case GenArmNeon: - NeonEmitter(Records).run(Out.os()); - break; - case GenArmNeonSema: - NeonEmitter(Records).runHeader(Out.os()); - break; - case GenArmNeonTest: - NeonEmitter(Records).runTests(Out.os()); + EDEmitter(Records).run(OS); break; case PrintEnums: { std::vector Recs = Records.getAllDerivedDefinitions(Class); for (unsigned i = 0, e = Recs.size(); i != e; ++i) - Out.os() << Recs[i]->getName() << ", "; - Out.os() << "\n"; + OS << Recs[i]->getName() << ", "; + OS << "\n"; break; } case PrintSets: @@ -371,33 +170,29 @@ int main(int argc, char **argv) { Sets.addFieldExpander("Set", "Elements"); std::vector Recs = Records.getAllDerivedDefinitions("Set"); for (unsigned i = 0, e = Recs.size(); i != e; ++i) { - Out.os() << Recs[i]->getName() << " = ["; + OS << Recs[i]->getName() << " = ["; const std::vector *Elts = Sets.expand(Recs[i]); assert(Elts && "Couldn't expand Set instance"); for (unsigned ei = 0, ee = Elts->size(); ei != ee; ++ei) - Out.os() << ' ' << (*Elts)[ei]->getName(); - Out.os() << " ]\n"; + OS << ' ' << (*Elts)[ei]->getName(); + OS << " ]\n"; } break; } default: assert(1 && "Invalid Action"); - return 1; + return true; } - // Declare success. - Out.keep(); - return 0; - - } catch (const TGError &Error) { - PrintError(Error); - } catch (const std::string &Error) { - PrintError(Error); - } catch (const char *Error) { - PrintError(Error); - } catch (...) { - errs() << argv[0] << ": Unknown unexpected exception occurred.\n"; + return false; } +}; - return 1; +int main(int argc, char **argv) { + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + cl::ParseCommandLineOptions(argc, argv); + + LLVMTableGenAction Action; + return TableGenMain(argv[0], Action); } diff --git a/utils/TableGen/X86DisassemblerTables.cpp b/utils/TableGen/X86DisassemblerTables.cpp index 74310593d29d..e8c9a4897321 100644 --- a/utils/TableGen/X86DisassemblerTables.cpp +++ b/utils/TableGen/X86DisassemblerTables.cpp @@ -17,7 +17,7 @@ #include "X86DisassemblerShared.h" #include "X86DisassemblerTables.h" -#include "TableGenBackend.h" +#include "llvm/TableGen/TableGenBackend.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" @@ -32,26 +32,32 @@ using namespace X86Disassembler; /// @param parent - The class that may be the superset /// @return - True if child is a subset of parent, false otherwise. static inline bool inheritsFrom(InstructionContext child, - InstructionContext parent) { + InstructionContext parent, + bool VEX_LIG = false) { if (child == parent) return true; switch (parent) { case IC: - return true; + return(inheritsFrom(child, IC_64BIT) || + inheritsFrom(child, IC_OPSIZE) || + inheritsFrom(child, IC_XD) || + inheritsFrom(child, IC_XS)); case IC_64BIT: return(inheritsFrom(child, IC_64BIT_REXW) || inheritsFrom(child, IC_64BIT_OPSIZE) || inheritsFrom(child, IC_64BIT_XD) || inheritsFrom(child, IC_64BIT_XS)); case IC_OPSIZE: - return(inheritsFrom(child, IC_64BIT_OPSIZE)); + return inheritsFrom(child, IC_64BIT_OPSIZE); case IC_XD: - return(inheritsFrom(child, IC_64BIT_XD) || - inheritsFrom(child, IC_VEX_XD)); + return inheritsFrom(child, IC_64BIT_XD); case IC_XS: - return(inheritsFrom(child, IC_64BIT_XS) || - inheritsFrom(child, IC_VEX_XS)); + return inheritsFrom(child, IC_64BIT_XS); + case IC_XD_OPSIZE: + return inheritsFrom(child, IC_64BIT_XD_OPSIZE); + case IC_XS_OPSIZE: + return inheritsFrom(child, IC_64BIT_XS_OPSIZE); case IC_64BIT_REXW: return(inheritsFrom(child, IC_64BIT_REXW_XS) || inheritsFrom(child, IC_64BIT_REXW_XD) || @@ -62,42 +68,37 @@ static inline bool inheritsFrom(InstructionContext child, return(inheritsFrom(child, IC_64BIT_REXW_XD)); case IC_64BIT_XS: return(inheritsFrom(child, IC_64BIT_REXW_XS)); + case IC_64BIT_XD_OPSIZE: + case IC_64BIT_XS_OPSIZE: + return false; case IC_64BIT_REXW_XD: - return false; case IC_64BIT_REXW_XS: - return false; case IC_64BIT_REXW_OPSIZE: return false; case IC_VEX: - return(inheritsFrom(child, IC_VEX_XS) || - inheritsFrom(child, IC_VEX_XD) || - inheritsFrom(child, IC_VEX_L) || - inheritsFrom(child, IC_VEX_W) || - inheritsFrom(child, IC_VEX_OPSIZE)); + return inheritsFrom(child, IC_VEX_W) || + (VEX_LIG && inheritsFrom(child, IC_VEX_L)); case IC_VEX_XS: - return(inheritsFrom(child, IC_VEX_L_XS) || - inheritsFrom(child, IC_VEX_W_XS)); + return inheritsFrom(child, IC_VEX_W_XS) || + (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS)); case IC_VEX_XD: - return(inheritsFrom(child, IC_VEX_L_XD) || - inheritsFrom(child, IC_VEX_W_XD)); - case IC_VEX_L: - return(inheritsFrom(child, IC_VEX_L_XS) || - inheritsFrom(child, IC_VEX_L_XD)); - case IC_VEX_L_XS: - return false; - case IC_VEX_L_XD: - return false; - case IC_VEX_W: - return(inheritsFrom(child, IC_VEX_W_XS) || - inheritsFrom(child, IC_VEX_W_XD) || - inheritsFrom(child, IC_VEX_W_OPSIZE)); - case IC_VEX_W_XS: - return false; - case IC_VEX_W_XD: - return false; + return inheritsFrom(child, IC_VEX_W_XD) || + (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD)); case IC_VEX_OPSIZE: - return inheritsFrom(child, IC_VEX_W_OPSIZE); + return inheritsFrom(child, IC_VEX_W_OPSIZE) || + (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE)); + case IC_VEX_W: + case IC_VEX_W_XS: + case IC_VEX_W_XD: + case IC_VEX_W_OPSIZE: + return false; + case IC_VEX_L: + case IC_VEX_L_XS: + case IC_VEX_L_XD: + case IC_VEX_L_OPSIZE: + return false; default: + llvm_unreachable("Unknown instruction class"); return false; } } @@ -515,6 +516,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const { o << "IC_VEX_XD"; else if ((index & ATTR_VEX) && (index & ATTR_XS)) o << "IC_VEX_XS"; + else if (index & ATTR_VEX) + o << "IC_VEX"; else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS)) o << "IC_64BIT_REXW_XS"; else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD)) @@ -522,6 +525,10 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const { else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_OPSIZE)) o << "IC_64BIT_REXW_OPSIZE"; + else if ((index & ATTR_64BIT) && (index & ATTR_XD) && (index & ATTR_OPSIZE)) + o << "IC_64BIT_XD_OPSIZE"; + else if ((index & ATTR_64BIT) && (index & ATTR_XS) && (index & ATTR_OPSIZE)) + o << "IC_64BIT_XS_OPSIZE"; else if ((index & ATTR_64BIT) && (index & ATTR_XS)) o << "IC_64BIT_XS"; else if ((index & ATTR_64BIT) && (index & ATTR_XD)) @@ -532,14 +539,16 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const { o << "IC_64BIT_REXW"; else if ((index & ATTR_64BIT)) o << "IC_64BIT"; + else if ((index & ATTR_XS) && (index & ATTR_OPSIZE)) + o << "IC_XS_OPSIZE"; + else if ((index & ATTR_XD) && (index & ATTR_OPSIZE)) + o << "IC_XD_OPSIZE"; else if (index & ATTR_XS) o << "IC_XS"; else if (index & ATTR_XD) o << "IC_XD"; else if (index & ATTR_OPSIZE) o << "IC_OPSIZE"; - else if (index & ATTR_VEX) - o << "IC_VEX"; else o << "IC"; @@ -616,8 +625,11 @@ void DisassemblerTables::setTableFields(ModRMDecision &decision, if(newInfo.filtered) continue; // filtered instructions get lowest priority - if(previousInfo.name == "NOOP") - continue; // special case for XCHG32ar and NOOP + if(previousInfo.name == "NOOP" && (newInfo.name == "XCHG16ar" || + newInfo.name == "XCHG32ar" || + newInfo.name == "XCHG32ar64" || + newInfo.name == "XCHG64ar")) + continue; // special case for XCHG*ar and NOOP if (outranks(previousInfo.insnContext, newInfo.insnContext)) continue; @@ -643,14 +655,19 @@ void DisassemblerTables::setTableFields(OpcodeType type, InstructionContext insnContext, uint8_t opcode, const ModRMFilter &filter, - InstrUID uid) { + InstrUID uid, + bool is32bit, + bool ignoresVEX_L) { unsigned index; ContextDecision &decision = *Tables[type]; for (index = 0; index < IC_max; ++index) { + if (is32bit && inheritsFrom((InstructionContext)index, IC_64BIT)) + continue; + if (inheritsFrom((InstructionContext)index, - InstructionSpecifiers[uid].insnContext)) + InstructionSpecifiers[uid].insnContext, ignoresVEX_L)) setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], filter, uid, diff --git a/utils/TableGen/X86DisassemblerTables.h b/utils/TableGen/X86DisassemblerTables.h index d16ebfca419e..e148cd26e809 100644 --- a/utils/TableGen/X86DisassemblerTables.h +++ b/utils/TableGen/X86DisassemblerTables.h @@ -260,11 +260,15 @@ class DisassemblerTables { /// @param filter - The ModRMFilter that decides which ModR/M byte values /// correspond to the desired instruction. /// @param uid - The unique ID of the instruction. + /// @param is32bit - Instructon is only 32-bit + /// @param ignoresVEX_L - Instruction ignores VEX.L void setTableFields(OpcodeType type, InstructionContext insnContext, uint8_t opcode, const ModRMFilter &filter, - InstrUID uid); + InstrUID uid, + bool is32bit, + bool ignoresVEX_L); /// specForUID - Returns the instruction specifier for a given unique /// instruction ID. Used when resolving collisions. diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index ea3bb700b27d..cae823749245 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -68,7 +68,7 @@ namespace X86Local { DC = 7, DD = 8, DE = 9, DF = 10, XD = 11, XS = 12, T8 = 13, P_TA = 14, - A6 = 15, A7 = 16 + A6 = 15, A7 = 16, TF = 17 }; } @@ -217,6 +217,7 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables, HasVEXPrefix = Rec->getValueAsBit("hasVEXPrefix"); HasVEX_4VPrefix = Rec->getValueAsBit("hasVEX_4VPrefix"); HasVEX_WPrefix = Rec->getValueAsBit("hasVEX_WPrefix"); + IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L"); HasLockPrefix = Rec->getValueAsBit("hasLockPrefix"); IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); @@ -225,15 +226,21 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables, Operands = &insn.Operands.OperandList; - IsSSE = HasOpSizePrefix && (Name.find("16") == Name.npos); + IsSSE = (HasOpSizePrefix && (Name.find("16") == Name.npos)) || + (Name.find("CRC32") != Name.npos); HasFROperands = hasFROperands(); HasVEX_LPrefix = has256BitOperands() || Rec->getValueAsBit("hasVEX_L"); // Check for 64-bit inst which does not require REX + Is32Bit = false; Is64Bit = false; // FIXME: Is there some better way to check for In64BitMode? std::vector Predicates = Rec->getValueAsListOfDefs("Predicates"); for (unsigned i = 0, e = Predicates.size(); i != e; ++i) { + if (Predicates[i]->getName().find("32Bit") != Name.npos) { + Is32Bit = true; + break; + } if (Predicates[i]->getName().find("64Bit") != Name.npos) { Is64Bit = true; break; @@ -249,6 +256,8 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables, Rec->getName() == "REX64_PREFIX" || Rec->getName().find("VMREAD64") != Name.npos || Rec->getName().find("VMWRITE64") != Name.npos || + Rec->getName().find("INVEPT64") != Name.npos || + Rec->getName().find("INVVPID64") != Name.npos || Rec->getName().find("MOV64") != Name.npos || Rec->getName().find("PUSH64") != Name.npos || Rec->getName().find("POP64") != Name.npos; @@ -257,7 +266,7 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables, } void RecognizableInstr::processInstr(DisassemblerTables &tables, - const CodeGenInstruction &insn, + const CodeGenInstruction &insn, InstrUID uid) { // Ignore "asm parser only" instructions. @@ -276,7 +285,9 @@ InstructionContext RecognizableInstr::insnContext() const { InstructionContext insnContext; if (HasVEX_4VPrefix || HasVEXPrefix) { - if (HasOpSizePrefix && HasVEX_LPrefix) + if (HasVEX_LPrefix && HasVEX_WPrefix) + llvm_unreachable("Don't support VEX.L and VEX.W together"); + else if (HasOpSizePrefix && HasVEX_LPrefix) insnContext = IC_VEX_L_OPSIZE; else if (HasOpSizePrefix && HasVEX_WPrefix) insnContext = IC_VEX_W_OPSIZE; @@ -303,13 +314,19 @@ InstructionContext RecognizableInstr::insnContext() const { } else if (Is64Bit || HasREX_WPrefix) { if (HasREX_WPrefix && HasOpSizePrefix) insnContext = IC_64BIT_REXW_OPSIZE; + else if (HasOpSizePrefix && + (Prefix == X86Local::XD || Prefix == X86Local::TF)) + insnContext = IC_64BIT_XD_OPSIZE; + else if (HasOpSizePrefix && Prefix == X86Local::XS) + insnContext = IC_64BIT_XS_OPSIZE; else if (HasOpSizePrefix) insnContext = IC_64BIT_OPSIZE; else if (HasREX_WPrefix && Prefix == X86Local::XS) insnContext = IC_64BIT_REXW_XS; - else if (HasREX_WPrefix && Prefix == X86Local::XD) + else if (HasREX_WPrefix && + (Prefix == X86Local::XD || Prefix == X86Local::TF)) insnContext = IC_64BIT_REXW_XD; - else if (Prefix == X86Local::XD) + else if (Prefix == X86Local::XD || Prefix == X86Local::TF) insnContext = IC_64BIT_XD; else if (Prefix == X86Local::XS) insnContext = IC_64BIT_XS; @@ -318,11 +335,16 @@ InstructionContext RecognizableInstr::insnContext() const { else insnContext = IC_64BIT; } else { - if (HasOpSizePrefix) + if (HasOpSizePrefix && + (Prefix == X86Local::XD || Prefix == X86Local::TF)) + insnContext = IC_XD_OPSIZE; + else if (HasOpSizePrefix && Prefix == X86Local::XS) + insnContext = IC_XS_OPSIZE; + else if (HasOpSizePrefix) insnContext = IC_OPSIZE; - else if (Prefix == X86Local::XD) + else if (Prefix == X86Local::XD || Prefix == X86Local::TF) insnContext = IC_XD; - else if (Prefix == X86Local::XS) + else if (Prefix == X86Local::XS || Prefix == X86Local::REP) insnContext = IC_XS; else insnContext = IC; @@ -342,20 +364,13 @@ RecognizableInstr::filter_ret RecognizableInstr::filter() const { return FILTER_STRONG; if (Form == X86Local::Pseudo || - IsCodeGenOnly) + (IsCodeGenOnly && Name.find("_REV") == Name.npos)) return FILTER_STRONG; if (Form == X86Local::MRMInitReg) return FILTER_STRONG; - // TEMPORARY pending bug fixes - - if (Name.find("VMOVDQU") != Name.npos || - Name.find("VMOVDQA") != Name.npos || - Name.find("VROUND") != Name.npos) - return FILTER_STRONG; - // Filter out artificial instructions if (Name.find("TAILJMP") != Name.npos || @@ -401,7 +416,7 @@ RecognizableInstr::filter_ret RecognizableInstr::filter() const { // Filter out alternate forms of AVX instructions if (Name.find("_alt") != Name.npos || Name.find("XrYr") != Name.npos || - Name.find("r64r") != Name.npos || + (Name.find("r64r") != Name.npos && Name.find("r64r64") == Name.npos) || Name.find("_64mr") != Name.npos || Name.find("Xrr") != Name.npos || Name.find("rr64") != Name.npos) @@ -623,20 +638,43 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) { case X86Local::MRMDestReg: // Operand 1 is a register operand in the R/M field. // Operand 2 is a register operand in the Reg/Opcode field. + // - In AVX, there is a register operand in the VEX.vvvv field here - // Operand 3 (optional) is an immediate. - assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && - "Unexpected number of operands for MRMDestRegFrm"); + if (HasVEX_4VPrefix) + assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && + "Unexpected number of operands for MRMDestRegFrm with VEX_4V"); + else + assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && + "Unexpected number of operands for MRMDestRegFrm"); + HANDLE_OPERAND(rmRegister) + + if (HasVEX_4VPrefix) + // FIXME: In AVX, the register below becomes the one encoded + // in ModRMVEX and the one above the one in the VEX.VVVV field + HANDLE_OPERAND(vvvvRegister) + HANDLE_OPERAND(roRegister) HANDLE_OPTIONAL(immediate) break; case X86Local::MRMDestMem: // Operand 1 is a memory operand (possibly SIB-extended) // Operand 2 is a register operand in the Reg/Opcode field. + // - In AVX, there is a register operand in the VEX.vvvv field here - // Operand 3 (optional) is an immediate. - assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && - "Unexpected number of operands for MRMDestMemFrm"); + if (HasVEX_4VPrefix) + assert(numPhysicalOperands >= 3 && numPhysicalOperands <= 4 && + "Unexpected number of operands for MRMDestMemFrm with VEX_4V"); + else + assert(numPhysicalOperands >= 2 && numPhysicalOperands <= 3 && + "Unexpected number of operands for MRMDestMemFrm"); HANDLE_OPERAND(memory) + + if (HasVEX_4VPrefix) + // FIXME: In AVX, the register below becomes the one encoded + // in ModRMVEX and the one above the one in the VEX.VVVV field + HANDLE_OPERAND(vvvvRegister) + HANDLE_OPERAND(roRegister) HANDLE_OPTIONAL(immediate) break; @@ -805,6 +843,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { opcodeToSet = Opcode; break; case X86Local::T8: + case X86Local::TF: opcodeType = THREEBYTE_38; if (needsModRMForDecode(Form)) filter = new ModFilter(isRegFormat(Form)); @@ -855,6 +894,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { } opcodeToSet = 0xd8 + (Prefix - X86Local::D8); break; + case X86Local::REP: default: opcodeType = ONEBYTE; switch (Opcode) { @@ -926,7 +966,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { insnContext(), currentOpcode, *filter, - UID); + UID, Is32Bit, IgnoresVEX_L); Spec->modifierType = MODIFIER_OPCODE; Spec->modifierBase = opcodeToSet; @@ -936,14 +976,14 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { insnContext(), opcodeToSet, *filter, - UID); + UID, Is32Bit, IgnoresVEX_L); } } else { tables.setTableFields(opcodeType, insnContext(), opcodeToSet, *filter, - UID); + UID, Is32Bit, IgnoresVEX_L); Spec->modifierType = MODIFIER_NONE; Spec->modifierBase = opcodeToSet; @@ -984,6 +1024,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("i32mem", TYPE_Mv) TYPE("i32imm", TYPE_IMMv) TYPE("i32i8imm", TYPE_IMM32) + TYPE("u32u8imm", TYPE_IMM32) TYPE("GR32", TYPE_Rv) TYPE("i64mem", TYPE_Mv) TYPE("i64i32imm", TYPE_IMM64) @@ -1029,6 +1070,9 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("offset32", TYPE_MOFFS32) TYPE("offset64", TYPE_MOFFS64) TYPE("VR256", TYPE_XMM256) + TYPE("GR16_NOAX", TYPE_Rv) + TYPE("GR32_NOAX", TYPE_Rv) + TYPE("GR64_NOAX", TYPE_R64) errs() << "Unhandled type string " << s << "\n"; llvm_unreachable("Unhandled type string"); } @@ -1044,6 +1088,7 @@ OperandEncoding RecognizableInstr::immediateEncodingFromString ENCODING("i16imm", ENCODING_IW) } ENCODING("i32i8imm", ENCODING_IB) + ENCODING("u32u8imm", ENCODING_IB) ENCODING("SSECC", ENCODING_IB) ENCODING("i16imm", ENCODING_Iv) ENCODING("i16i8imm", ENCODING_IB) @@ -1097,6 +1142,8 @@ OperandEncoding RecognizableInstr::roRegisterEncodingFromString OperandEncoding RecognizableInstr::vvvvRegisterEncodingFromString (const std::string &s, bool hasOpSizePrefix) { + ENCODING("GR32", ENCODING_VVVV) + ENCODING("GR64", ENCODING_VVVV) ENCODING("FR32", ENCODING_VVVV) ENCODING("FR64", ENCODING_VVVV) ENCODING("VR128", ENCODING_VVVV) @@ -1169,6 +1216,9 @@ OperandEncoding RecognizableInstr::opcodeModifierEncodingFromString ENCODING("GR64", ENCODING_RO) ENCODING("GR16", ENCODING_Rv) ENCODING("GR8", ENCODING_RB) + ENCODING("GR16_NOAX", ENCODING_Rv) + ENCODING("GR32_NOAX", ENCODING_Rv) + ENCODING("GR64_NOAX", ENCODING_RO) errs() << "Unhandled opcode modifier encoding " << s << "\n"; llvm_unreachable("Unhandled opcode modifier encoding"); } diff --git a/utils/TableGen/X86RecognizableInstr.h b/utils/TableGen/X86RecognizableInstr.h index 677d9f01554e..44415978273f 100644 --- a/utils/TableGen/X86RecognizableInstr.h +++ b/utils/TableGen/X86RecognizableInstr.h @@ -20,8 +20,8 @@ #include "X86DisassemblerTables.h" #include "CodeGenTarget.h" -#include "Record.h" +#include "llvm/TableGen/Record.h" #include "llvm/Support/DataTypes.h" #include "llvm/ADT/SmallVector.h" @@ -60,12 +60,16 @@ class RecognizableInstr { bool HasVEX_WPrefix; /// Inferred from the operands; indicates whether the L bit in the VEX prefix is set bool HasVEX_LPrefix; + // The ignoreVEX_L field from the record + bool IgnoresVEX_L; /// The hasLockPrefix field from the record bool HasLockPrefix; /// The isCodeGenOnly filed from the record bool IsCodeGenOnly; - // Whether the instruction has the predicate "Mode64Bit" + // Whether the instruction has the predicate "In64BitMode" bool Is64Bit; + // Whether the instruction has the predicate "In32BitMode" + bool Is32Bit; /// The instruction name as listed in the tables std::string Name; diff --git a/utils/buildit/build_llvm b/utils/buildit/build_llvm index 5665e4cf8b58..0ffbc190d393 100755 --- a/utils/buildit/build_llvm +++ b/utils/buildit/build_llvm @@ -97,31 +97,16 @@ if [ "$ARM_HOSTED_BUILD" = yes ]; then echo 'exec '$T' "$@"' >> $P || exit 1 chmod a+x $P || exit 1 done - # Try to use the platform llvm-gcc. Fall back to gcc if it's not available. - for prog in gcc g++ ; do + # Set up the links for clang. + for prog in clang clang++ ; do P=$DIR/bin/arm-apple-darwin$DARWIN_VERS-${prog} - T=`xcrun -sdk $SDKROOT -find llvm-${prog}` - if [ "x$T" = "x" ] ; then - T=`xcrun -sdk $SDKROOT -find ${prog}` - fi + T=`xcrun -sdk $SDKROOT -find ${prog}` echo '#!/bin/sh' > $P || exit 1 echo 'exec '$T' -arch armv7 -isysroot '${SDKROOT}' "$@"' >> $P || exit 1 chmod a+x $P || exit 1 done PATH=$DIR/bin:$PATH -# otherwise, try to use llvm-gcc if it's available -elif [ $DARWIN_VERS -gt 9 ]; then - # If the user has set CC or CXX, respect their wishes. If not, - # compile with LLVM-GCC/LLVM-G++ if available; if LLVM is not - # available, fall back to usual GCC/G++ default. - savedPATH=$PATH ; PATH="/Developer/usr/bin:$PATH" - XTMPCC=$(which llvm-gcc) - if [ x$CC = x -a x$XTMPCC != x ] ; then export CC=$XTMPCC ; fi - XTMPCC=$(which llvm-g++) - if [ x$CXX = x -a x$XTMPCC != x ] ; then export CXX=$XTMPCC ; fi - PATH=$savedPATH - unset XTMPCC savedPATH fi if [ "$ARM_HOSTED_BUILD" = yes ]; then @@ -157,32 +142,15 @@ else LLVM_VERSION="$LLVM_SUBMIT_VERSION-$LLVM_SUBMIT_SUBVERSION" fi -GCC_VER=`cc --version 2>/dev/null | sed 1q` - -if echo "$GCC_VER" | grep GCC > /dev/null; then - GCC_VER=`echo $GCC_VER | sed -e 's/.*(GCC) \([0-9.][0-9.]*\).*/\1/'` - MAJ_VER=`echo $GCC_VER | sed 's/\..*//'` - MIN_VER=`echo $GCC_VER | sed 's/[^.]*\.\([0-9]*\).*/\1/'` -fi - -JOBS_FLAG="" - -# Note: If compiling with GCC 4.0, don't pass the -jN flag. Building universal -# already has parallelism and we don't want to make the builders hit swap by -# firing off too many gccs at the same time. -if [ "x$MAJ_VER" != "x4" -o "x$MIN_VER" != "x0" ]; then - # Figure out how many make processes to run. - SYSCTL=`sysctl -n hw.activecpu` - - # sysctl -n hw.* does not work when invoked via B&I chroot /BuildRoot. - # Builders can default to 2, since even if they are single processor, - # nothing else is running on the machine. - if [ -z "$SYSCTL" ]; then - SYSCTL=2 - fi - - JOBS_FLAG="-j $SYSCTL" +# Figure out how many make processes to run. +SYSCTL=`sysctl -n hw.activecpu` +# sysctl -n hw.* does not work when invoked via B&I chroot /BuildRoot. +# Builders can default to 2, since even if they are single processor, +# nothing else is running on the machine. +if [ -z "$SYSCTL" ]; then + SYSCTL=2 fi +JOBS_FLAG="-j $SYSCTL" make $JOBS_FLAG $OPTIMIZE_OPTS UNIVERSAL=1 UNIVERSAL_ARCH="$HOSTS" \ UNIVERSAL_SDK_PATH=$SDKROOT \ @@ -233,14 +201,20 @@ RC_ProjectSourceSubversion=`printf "%d" $LLVM_MINOR_VERSION` echo "#define LLVM_VERSION ${RC_ProjectSourceVersion}" > $DEST_DIR$DEST_ROOT/include/llvm/Version.h echo "#define LLVM_MINOR_VERSION ${RC_ProjectSourceSubversion}" >> $DEST_DIR$DEST_ROOT/include/llvm/Version.h +# Find the right version of strip to use. +STRIP=strip +if [ -n "$SDKROOT" ]; then + STRIP=`xcrun -sdk $SDKROOT -find strip` +fi + if [ "x$LLVM_DEBUG" != "x1" ]; then # Strip local symbols from llvm libraries. # # Use '-l' to strip i386 modules. N.B. that flag doesn't work with kext or # PPC objects! - strip -Sl $DEST_DIR$DEST_ROOT/lib/*.[oa] + $STRIP -Sl $DEST_DIR$DEST_ROOT/lib/*.[oa] for f in `ls $DEST_DIR$DEST_ROOT/lib/*.so`; do - strip -Sxl $f + $STRIP -Sxl $f done fi @@ -329,7 +303,7 @@ if [ "$INSTALL_LIBLTO" = "yes" ]; then # Use '-l' to strip i386 modules. N.B. that flag doesn't work with kext or # PPC objects! - strip -arch all -Sl $DT_HOME/lib/libLTO.dylib + $STRIP -arch all -Sl $DT_HOME/lib/libLTO.dylib if [ "x$DISABLE_USR_LINKS" == "x" ]; then # Add a symlink in /usr/lib for B&I. @@ -359,7 +333,7 @@ find $DEST_DIR -name \*.dSYM -print | xargs rm -r || exit 1 # PPC objects! find $DEST_DIR -perm -0111 -type f \ ! \( -name '*.la' -o -name gccas -o -name gccld -o -name llvm-config \) \ - -print | xargs -n 1 -P ${SYSCTL} strip -arch all -Sl + -print | xargs -n 1 -P ${SYSCTL} $STRIP -arch all -Sl chgrp -h -R wheel $DEST_DIR chgrp -R wheel $DEST_DIR diff --git a/utils/lit/lit/LitConfig.py b/utils/lit/lit/LitConfig.py index bda91744cce3..2cc278111991 100644 --- a/utils/lit/lit/LitConfig.py +++ b/utils/lit/lit/LitConfig.py @@ -20,7 +20,7 @@ class LitConfig: def __init__(self, progname, path, quiet, useValgrind, valgrindLeakCheck, valgrindArgs, useTclAsSh, - noExecute, debug, isWindows, + noExecute, ignoreStdErr, debug, isWindows, params): # The name of the test runner. self.progname = progname @@ -32,6 +32,7 @@ def __init__(self, progname, path, quiet, self.valgrindUserArgs = list(valgrindArgs) self.useTclAsSh = bool(useTclAsSh) self.noExecute = noExecute + self.ignoreStdErr = ignoreStdErr self.debug = debug self.isWindows = bool(isWindows) self.params = dict(params) diff --git a/utils/lit/lit/TestFormats.py b/utils/lit/lit/TestFormats.py index 6dda2fdb608d..d1c0558b5f37 100644 --- a/utils/lit/lit/TestFormats.py +++ b/utils/lit/lit/TestFormats.py @@ -125,7 +125,11 @@ def execute(self, test, litConfig): self.execute_external) class TclTest(FileBasedTest): + def __init__(self, ignoreStdErr=False): + self.ignoreStdErr = ignoreStdErr + def execute(self, test, litConfig): + litConfig.ignoreStdErr = self.ignoreStdErr return TestRunner.executeTclTest(test, litConfig) ### diff --git a/utils/lit/lit/TestRunner.py b/utils/lit/lit/TestRunner.py index 80d0ba118399..f5f7c19891b3 100644 --- a/utils/lit/lit/TestRunner.py +++ b/utils/lit/lit/TestRunner.py @@ -397,7 +397,8 @@ def parseIntegratedTestScript(test, normalize_slashes=False): sourcedir = os.path.dirname(sourcepath) execpath = test.getExecPath() execdir,execbase = os.path.split(execpath) - tmpBase = os.path.join(execdir, 'Output', execbase) + tmpDir = os.path.join(execdir, 'Output') + tmpBase = os.path.join(tmpDir, execbase) if test.index is not None: tmpBase += '_%d' % test.index @@ -405,6 +406,7 @@ def parseIntegratedTestScript(test, normalize_slashes=False): if normalize_slashes: sourcepath = sourcepath.replace('\\', '/') sourcedir = sourcedir.replace('\\', '/') + tmpDir = tmpDir.replace('\\', '/') tmpBase = tmpBase.replace('\\', '/') # We use #_MARKER_# to hide %% while we do the other substitutions. @@ -414,6 +416,7 @@ def parseIntegratedTestScript(test, normalize_slashes=False): ('%S', sourcedir), ('%p', sourcedir), ('%t', tmpBase + '.tmp'), + ('%T', tmpDir), # FIXME: Remove this once we kill DejaGNU. ('%abs_tmp', tmpBase + '.tmp'), ('#_MARKER_#', '%')]) @@ -533,13 +536,13 @@ def executeTclTest(test, litConfig): # considered to fail if there is any standard error output. out,err,exitCode = res if isXFail: - ok = exitCode != 0 or err + ok = exitCode != 0 or err and not litConfig.ignoreStdErr if ok: status = Test.XFAIL else: status = Test.XPASS else: - ok = exitCode == 0 and not err + ok = exitCode == 0 and (not err or litConfig.ignoreStdErr) if ok: status = Test.PASS else: @@ -550,7 +553,7 @@ def executeTclTest(test, litConfig): # Set a flag for formatTestOutput so it can explain why the test was # considered to have failed, despite having an exit code of 0. - failDueToStderr = exitCode == 0 and err + failDueToStderr = exitCode == 0 and err and not litConfig.ignoreStdErr return formatTestOutput(status, out, err, exitCode, failDueToStderr, script) diff --git a/utils/lit/lit/TestingConfig.py b/utils/lit/lit/TestingConfig.py index 25bb3417de43..a92dca8fb1b1 100644 --- a/utils/lit/lit/TestingConfig.py +++ b/utils/lit/lit/TestingConfig.py @@ -1,4 +1,5 @@ import os +import sys class TestingConfig: """" @@ -14,12 +15,18 @@ def frompath(path, parent, litConfig, mustExist, config = None): 'LD_LIBRARY_PATH' : os.environ.get('LD_LIBRARY_PATH',''), 'PATH' : os.pathsep.join(litConfig.path + [os.environ.get('PATH','')]), - 'PATHEXT' : os.environ.get('PATHEXT',''), 'SYSTEMROOT' : os.environ.get('SYSTEMROOT',''), - 'LLVM_DISABLE_CRT_DEBUG' : '1', - 'PYTHONUNBUFFERED' : '1', } + if sys.platform == 'win32': + environment.update({ + 'LLVM_DISABLE_CRT_DEBUG' : '1', + 'PATHEXT' : os.environ.get('PATHEXT',''), + 'PYTHONUNBUFFERED' : '1', + 'TEMP' : os.environ.get('TEMP',''), + 'TMP' : os.environ.get('TMP',''), + }) + config = TestingConfig(parent, name = '', suffixes = set(), diff --git a/utils/lit/lit/main.py b/utils/lit/lit/main.py index 13d263009ddd..e1a380c3fcbc 100755 --- a/utils/lit/lit/main.py +++ b/utils/lit/lit/main.py @@ -328,6 +328,7 @@ def load_test_suite(inputs): valgrindArgs = [], useTclAsSh = False, noExecute = False, + ignoreStdErr = False, debug = False, isWindows = (platform.system()=='Windows'), params = {}) @@ -485,6 +486,7 @@ def main(builtinParameters = {}): # Bump the GIL check interval, its more imp valgrindArgs = opts.valgrindArgs, useTclAsSh = opts.useTclAsSh, noExecute = opts.noExecute, + ignoreStdErr = False, debug = opts.debug, isWindows = (platform.system()=='Windows'), params = userParams) diff --git a/utils/llvm.grm b/utils/llvm.grm index 3f33702d2a00..fb26dbb66f60 100644 --- a/utils/llvm.grm +++ b/utils/llvm.grm @@ -172,7 +172,7 @@ FuncAttr ::= noreturn | optsize | ssp | sspreq - | hotpatch + | returns_twice | nonlazybind ; diff --git a/utils/llvmbuild b/utils/llvmbuild index c7d8814abb8b..b623d3202158 100755 --- a/utils/llvmbuild +++ b/utils/llvmbuild @@ -189,6 +189,10 @@ def add_options(parser): help=("Extra flags to pass to gcc configure [default: %default]")) parser.add_option("--force-configure", default=False, action="store_true", help=("Force reconfigure of all components")) + parser.add_option("--no-gcc", default=False, action="store_true", + help=("Do not build dragonegg and gcc")) + parser.add_option("--no-install", default=False, action="store_true", + help=("Do not do installs")) return def check_options(parser, options, valid_builds): @@ -622,6 +626,12 @@ class Builder(threading.Thread): for component in components: comp = component[:] + + if (self.options.no_gcc): + if (comp == 'gcc' or comp == 'dragonegg' or comp == 'llvm2'): + self.logger.info("Skipping " + component + " in " + + builddir) + continue srcdir = source + "/" + comp.rstrip("2") builddir = self.build_prefix + "/" + comp + "/" + build_suffix @@ -643,16 +653,20 @@ class Builder(threading.Thread): configure_env[comp_key][build]) self.logger.info("Building " + component + " in " + builddir) + self.logger.info("Build: make " + str(make_flags[comp_key][build])) self.make(component, srcdir, builddir, make_flags[comp_key][build], make_env[comp_key][build]) - self.logger.info("Installing " + component + " in " + installdir) - self.make(component, srcdir, builddir, - make_install_flags[comp_key][build], - make_install_env[comp_key][build]) + if (not self.options.no_install): + self.logger.info("Installing " + component + " in " + installdir) + self.make(component, srcdir, builddir, + make_install_flags[comp_key][build], + make_install_env[comp_key][build]) self.logger.info("Testing " + component + " in " + builddir) + self.logger.info("Test: make " + + str(make_check_flags[comp_key][build])) self.make(component, srcdir, builddir, make_check_flags[comp_key][build], make_check_env[comp_key][build]) @@ -741,9 +755,10 @@ if jobs == 0: jobs = 1 numthreads = options.threads -if jobs < numthreads: - numthreads = jobs - jobs = 1 + +logging.getLogger().info("Building with " + str(options.jobs) + " jobs and " + + str(numthreads) + " threads using " + str(jobs) + + " make jobs") for t in range(numthreads): builder = Builder(work_queue, jobs, diff --git a/utils/release/findRegressions.py b/utils/release/findRegressions.py index e801dab4aba7..7629c8b4fbf1 100755 --- a/utils/release/findRegressions.py +++ b/utils/release/findRegressions.py @@ -1,68 +1,60 @@ #!/usr/bin/python -import re, string, sys, os, time +import re, string, sys, os, time, math DEBUG = 0 -testDirName = 'llvm-test' -test = ['compile', 'llc', 'jit', 'cbe'] -exectime = ['llc-time', 'jit-time', 'cbe-time',] -comptime = ['llc', 'jit-comptime', 'compile'] -(tp, exp) = ('compileTime_', 'executeTime_') +(tp, exp) = ('compile', 'exec') def parse(file): - f=open(file, 'r') + f = open(file, 'r') d = f.read() - #Cleanup weird stuff - d = re.sub(r',\d+:\d','', d) - + # Cleanup weird stuff + d = re.sub(r',\d+:\d', '', d) + r = re.findall(r'TEST-(PASS|FAIL|RESULT.*?):\s+(.*?)\s+(.*?)\r*\n', d) - + test = {} fname = '' for t in r: if DEBUG: print t + if t[0] == 'PASS' or t[0] == 'FAIL' : - tmp = t[2].split(testDirName) + tmp = t[2].split('llvm-test/') if DEBUG: print tmp - + if len(tmp) == 2: fname = tmp[1].strip('\r\n') else: fname = tmp[0].strip('\r\n') - - if not test.has_key(fname) : + + if not test.has_key(fname): test[fname] = {} - - for k in test: - test[fname][k] = 'NA' - test[fname][t[1]] = t[0] - if DEBUG: - print test[fname][t[1]] + + test[fname][t[1] + ' state'] = t[0] + test[fname][t[1] + ' time'] = float('nan') else : try: n = t[0].split('RESULT-')[1] - + if DEBUG: - print n; + print "n == ", n; - if n == 'llc' or n == 'jit-comptime' or n == 'compile': - test[fname][tp + n] = float(t[2].split(' ')[2]) + if n == 'compile-success': + test[fname]['compile time'] = float(t[2].split('program')[1].strip('\r\n')) + + elif n == 'exec-success': + test[fname]['exec time'] = float(t[2].split('program')[1].strip('\r\n')) if DEBUG: - print test[fname][tp + n] - - elif n.endswith('-time') : - test[fname][exp + n] = float(t[2].strip('\r\n')) - if DEBUG: - print test[fname][exp + n] - + print test[fname][string.replace(n, '-success', '')] + else : - print "ERROR!" + # print "ERROR!" sys.exit(1) - + except: continue @@ -72,59 +64,60 @@ def parse(file): def diffResults(d_old, d_new): for t in sorted(d_old.keys()) : - if DEBUG: - print t - - if d_new.has_key(t) : - + if d_new.has_key(t): + # Check if the test passed or failed. - for x in test: + for x in ['compile state', 'compile time', 'exec state', 'exec time']: + + if not d_old[t].has_key(x) and not d_new[t].has_key(x): + continue + if d_old[t].has_key(x): if d_new[t].has_key(x): + if d_old[t][x] == 'PASS': if d_new[t][x] != 'PASS': - print t + " *** REGRESSION (" + x + ")\n" + print t + " *** REGRESSION (" + x + " now fails)" else: if d_new[t][x] == 'PASS': - print t + " * NEW PASS (" + x + ")\n" - - else : - print t + "*** REGRESSION (" + x + ")\n" - - # For execution time, if there is no result, its a fail. - for x in exectime: - if d_old[t].has_key(tp + x): - if not d_new[t].has_key(tp + x): - print t + " *** REGRESSION (" + tp + x + ")\n" - - else : - if d_new[t].has_key(tp + x): - print t + " * NEW PASS (" + tp + x + ")\n" + print t + " * NEW PASS (" + x + " now fails)" - - for x in comptime: - if d_old[t].has_key(exp + x): - if not d_new[t].has_key(exp + x): - print t + " *** REGRESSION (" + exp + x + ")\n" - else : - if d_new[t].has_key(exp + x): - print t + " * NEW PASS (" + exp + x + ")\n" - + print t + "*** REGRESSION (" + x + " now fails)" + + if x == 'compile state' or x == 'exec state': + continue + + # For execution time, if there is no result it's a fail. + if not d_old[t].has_key(x) and not d_new[t].has_key(x): + continue + elif not d_new[t].has_key(x): + print t + " *** REGRESSION (" + x + ")" + elif not d_old[t].has_key(x): + print t + " * NEW PASS (" + x + ")" + + if math.isnan(d_old[t][x]) and math.isnan(d_new[t][x]): + continue + + elif math.isnan(d_old[t][x]) and not math.isnan(d_new[t][x]): + print t + " * NEW PASS (" + x + ")" + + elif not math.isnan(d_old[t][x]) and math.isnan(d_new[t][x]): + print t + " *** REGRESSION (" + x + ")" + + if d_new[t][x] > d_old[t][x] and \ + (d_new[t][x] - d_old[t][x]) / d_new[t][x] > .05: + print t + " *** REGRESSION (" + x + ")" + else : - print t + ": Removed from test-suite.\n" - + print t + ": Removed from test-suite." -#Main +# Main if len(sys.argv) < 3 : - print 'Usage:', sys.argv[0], \ - ' ' - sys.exit(-1) + print 'Usage:', sys.argv[0], ' ' + sys.exit(-1) d_old = parse(sys.argv[1]) d_new = parse(sys.argv[2]) - diffResults(d_old, d_new) - - diff --git a/utils/release/test-release.sh b/utils/release/test-release.sh index 21d7fee42211..425532419457 100755 --- a/utils/release/test-release.sh +++ b/utils/release/test-release.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #===-- test-release.sh - Test the LLVM release candidates ------------------===# # # The LLVM Compiler Infrastructure @@ -12,7 +12,16 @@ # #===------------------------------------------------------------------------===# -set -e # Exit if any command fails +if [ `uname -s` = "FreeBSD" ]; then + MAKE=gmake +else + MAKE=make +fi + +projects="llvm cfe dragonegg test-suite" + +# Base SVN URL for the sources. +Base_url="http://llvm.org/svn/llvm-project" Release="" Release_no_dot="" @@ -20,8 +29,10 @@ RC="" do_checkout="yes" do_ada="no" do_objc="yes" -do_fortran="yes" +do_fortran="no" do_64bit="yes" +do_debug="no" +do_asserts="no" BuildDir="`pwd`" function usage() { @@ -34,8 +45,10 @@ function usage() { echo " -no-checkout Don't checkout the sources from SVN." echo " -no-64bit Don't test the 64-bit version. [default: yes]" echo " -enable-ada Build Ada. [default: disable]" + echo " -enable-fortran Enable Fortran build. [default: disable]" echo " -disable-objc Disable ObjC build. [default: enable]" - echo " -disable-fortran Disable Fortran build. [default: enable]" + echo " -test-debug Test the debug build. [default: no]" + echo " -test-asserts Test with asserts on. [default: no]" } while [ $# -gt 0 ]; do @@ -69,13 +82,17 @@ while [ $# -gt 0 ]; do -enable-ada | --enable-ada ) do_ada="yes" ;; + -enable-fortran | --enable-fortran ) + do_fortran="yes" + ;; -disable-objc | --disable-objc ) do_objc="no" ;; - -disable-fortran | --disable-fortran ) - echo "WARNING: Do you *really* need to disable Fortran?" - sleep 5 - do_fortran="no" + -test-debug | --test-debug ) + do_debug="yes" + ;; + -test-asserts | --test-asserts ) + do_asserts="yes" ;; -help | --help | -h | --h | -\? ) usage @@ -92,11 +109,11 @@ done # Check required arguments. if [ -z "$Release" ]; then - echo "No release number specified!" + echo "error: no release number specified" exit 1 fi if [ -z "$RC" ]; then - echo "No release candidate number specified!" + echo "error: no release candidate number specified" exit 1 fi @@ -114,55 +131,53 @@ if [ -z "$NumJobs" ]; then NumJobs=3 fi -# Location of sources. -llvmCore_srcdir=$BuildDir/llvmCore-$Release-rc$RC.src -llvmgcc42_srcdir=$BuildDir/llvmgcc42-$Release-rc$RC.src +# Go to the build directory (may be different from CWD) +BuildDir=$BuildDir/rc$RC +mkdir -p $BuildDir +cd $BuildDir # Location of log files. -LogDirName="$Release-rc$RC.logs" -LogDir=$BuildDir/$LogDirName +LogDir=$BuildDir/logs mkdir -p $LogDir -# SVN URLs for the sources. -Base_url="http://llvm.org/svn/llvm-project" -llvmCore_RC_url="$Base_url/llvm/tags/RELEASE_$Release_no_dot/rc$RC" -llvmgcc42_RC_url="$Base_url/llvm-gcc-4.2/tags/RELEASE_$Release_no_dot/rc$RC" -clang_RC_url="$Base_url/cfe/tags/RELEASE_$Release_no_dot/rc$RC" -test_suite_RC_url="$Base_url/test-suite/tags/RELEASE_$Release_no_dot/rc$RC" +# Find a compilers. +c_compiler="$CC" +cxx_compiler="$CXX" # Make sure that the URLs are valid. function check_valid_urls() { - echo "# Validating SVN URLs" - if ! svn ls $llvmCore_RC_url > /dev/null 2>&1 ; then - echo "llvm $Release release candidate $RC doesn't exist!" - exit 1 - fi - if ! svn ls $llvmgcc42_RC_url > /dev/null 2>&1 ; then - echo "llvm-gcc-4.2 $Release release candidate $RC doesn't exist!" - exit 1 - fi - if ! svn ls $clang_RC_url > /dev/null 2>&1 ; then - echo "clang $Release release candidate $RC doesn't exist!" - exit 1 - fi - if ! svn ls $test_suite_RC_url > /dev/null 2>&1 ; then - echo "test-suite $Release release candidate $RC doesn't exist!" - exit 1 - fi + for proj in $projects ; do + echo "# Validating $proj SVN URL" + + if ! svn ls $Base_url/$proj/tags/RELEASE_$Release_no_dot/rc$RC > /dev/null 2>&1 ; then + echo "llvm $Release release candidate $RC doesn't exist!" + exit 1 + fi + done } # Export sources to the the build directory. function export_sources() { check_valid_urls - echo "# Exporting llvm $Release-RC$RC sources" - svn export -q $llvmCore_RC_url $llvmCore_srcdir - echo "# Exporting llvm-gcc-4.2 $Release-rc$RC sources" - svn export -q $llvmgcc42_RC_url $llvmgcc42_srcdir - echo "# Exporting clang $Release-rc$RC sources" - svn export -q $clang_RC_url $llvmCore_srcdir/tools/clang - echo "# Exporting llvm test suite $Release-rc$RC sources" - svn export -q $test_suite_RC_url $llvmCore_srcdir/projects/llvm-test + for proj in $projects ; do + echo "# Exporting $proj $Release-RC$RC sources" + if ! svn export -q $Base_url/$proj/tags/RELEASE_$Release_no_dot/rc$RC $proj.src ; then + echo "error: failed to export $proj project" + exit 1 + fi + done + + echo "# Creating symlinks" + cd $BuildDir/llvm.src/tools + if [ ! -h clang ]; then + ln -s $BuildDir/cfe.src clang + fi + cd $BuildDir/llvm.src/projects + if [ ! -h llvm-test ]; then + ln -s $BuildDir/test-suite.src llvm-test + fi + cd $BuildDir } function configure_llvmCore() { @@ -170,7 +185,6 @@ function configure_llvmCore() { Flavor="$2" ObjDir="$3" InstallDir="$4" - llvmgccDir="$5" case $Flavor in Release | Release-64 ) @@ -186,24 +200,26 @@ function configure_llvmCore() { Assertions="yes" ;; * ) - echo "# Invalid flavor $Flavor!" + echo "# Invalid flavor '$Flavor'" echo "" return ;; esac + echo "# Using C compiler: $c_compiler" + echo "# Using C++ compiler: $cxx_compiler" + cd $ObjDir echo "# Configuring llvm $Release-rc$RC $Flavor" - echo "# $llvmCore_srcdir/configure --prefix=$InstallDir \ + echo "# $BuildDir/llvm.src/configure --prefix=$InstallDir \ + --enable-optimized=$Optimized \ + --enable-assertions=$Assertions" + env CC=$c_compiler CXX=$cxx_compiler \ + $BuildDir/llvm.src/configure --prefix=$InstallDir \ --enable-optimized=$Optimized \ --enable-assertions=$Assertions \ - --with-llvmgccdir=$llvmgccDir" - $llvmCore_srcdir/configure --prefix=$InstallDir \ - --enable-optimized=$Optimized \ - --enable-assertions=$Assertions \ - --with-llvmgccdir=$llvmgccDir \ - > $LogDir/llvm.configure.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1 - cd - + 2>&1 | tee $LogDir/llvm.configure-Phase$Phase-$Flavor.log + cd $BuildDir } function build_llvmCore() { @@ -212,25 +228,21 @@ function build_llvmCore() { ObjDir="$3" ExtraOpts="" - CompilerFlags="" - if [ "$Phase" = "2" ]; then - CompilerFlags="CC=$llvmgccDir/bin/llvm-gcc CXX=$llvmgccDir/bin/llvm-g++" - fi if [ "$Flavor" = "Release-64" ]; then ExtraOpts="EXTRA_OPTIONS=-m64" fi cd $ObjDir echo "# Compiling llvm $Release-rc$RC $Flavor" - echo "# make -j $NumJobs VERBOSE=1 $ExtraOpts" - make -j $NumJobs VERBOSE=1 $ExtraOpts $CompilerFlags \ - > $LogDir/llvm.make.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1 + echo "# ${MAKE} -j $NumJobs VERBOSE=1 $ExtraOpts" + ${MAKE} -j $NumJobs VERBOSE=1 $ExtraOpts \ + 2>&1 | tee $LogDir/llvm.make-Phase$Phase-$Flavor.log echo "# Installing llvm $Release-rc$RC $Flavor" - echo "# make install" - make install \ - > $LogDir/llvm.install.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1 - cd - + echo "# ${MAKE} install" + ${MAKE} install \ + 2>&1 | tee $LogDir/llvm.install-Phase$Phase-$Flavor.log + cd $BuildDir } function test_llvmCore() { @@ -239,75 +251,27 @@ function test_llvmCore() { ObjDir="$3" cd $ObjDir - make check \ - > $LogDir/llvm.check.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1 - make -C tools/clang test \ - > $LogDir/clang.check.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1 - make unittests \ - > $LogDir/llvm.unittests.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1 - cd - + ${MAKE} -k check-all \ + 2>&1 | tee $LogDir/llvm.check-Phase$Phase-$Flavor.log + ${MAKE} -k unittests \ + 2>&1 | tee $LogDir/llvm.unittests-Phase$Phase-$Flavor.log + cd $BuildDir } -function configure_llvm_gcc() { - Phase="$1" - Flavor="$2" - ObjDir="$3" - InstallDir="$4" - llvmObjDir="$5" - - languages="c,c++" - if [ "$do_objc" = "yes" ]; then - languages="$languages,objc,obj-c++" - fi - if [ "$do_fortran" = "yes" ]; then - languages="$languages,fortran" - fi - if [ "$do_ada" = "yes" ]; then - languages="$languages,ada" - fi - - cd $ObjDir - echo "# Configuring llvm-gcc $Release-rc$RC $Flavor" - echo "# $llvmgcc42_srcdir/configure --prefix=$InstallDir \ - --program-prefix=llvm- --enable-llvm=$llvmObjDir \ - --enable-languages=$languages" - $llvmgcc42_srcdir/configure --prefix=$InstallDir \ - --program-prefix=llvm- --enable-llvm=$llvmObjDir \ - --enable-languages=$languages \ - > $LogDir/llvm-gcc.configure.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1 - cd - -} - -function build_llvm_gcc() { - Phase="$1" - Flavor="$2" - ObjDir="$3" - llvmgccDir="$4" - - CompilerFlags="" - if [ "$Phase" = "2" ]; then - CompilerFlags="CC=$llvmgccDir/bin/llvm-gcc CXX=$llvmgccDir/bin/llvm-g++" - fi - - cd $ObjDir - echo "# Compiling llvm-gcc $Release-rc$RC $Flavor" - echo "# make -j $NumJobs bootstrap LLVM_VERSION_INFO=$Release" - make -j $NumJobs bootstrap LLVM_VERSION_INFO=$Release $CompilerFlags \ - > $LogDir/llvm-gcc.make.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1 - - echo "# Installing llvm-gcc $Release-rc$RC $Flavor" - echo "# make install" - make install \ - > $LogDir/llvm-gcc.install.$Release-rc$RC-Phase$Phase-$Flavor.log 2>&1 - cd - -} +set -e # Exit if any command fails if [ "$do_checkout" = "yes" ]; then export_sources fi ( -Flavors="Debug Release Release+Asserts" +Flavors="Release" +if [ "$do_debug" = "yes" ]; then + Flavors="Debug $Flavors" +fi +if [ "$do_asserts" = "yes" ]; then + Flavors="$Flavors Release+Asserts" +fi if [ "$do_64bit" = "yes" ]; then Flavors="$Flavors Release-64" fi @@ -329,69 +293,71 @@ for Flavor in $Flavors ; do llvmCore_phase2_objdir=$BuildDir/Phase2/$Flavor/llvmCore-$Release-rc$RC.obj llvmCore_phase2_installdir=$BuildDir/Phase2/$Flavor/llvmCore-$Release-rc$RC.install + llvmCore_phase3_objdir=$BuildDir/Phase3/$Flavor/llvmCore-$Release-rc$RC.obj + llvmCore_phase3_installdir=$BuildDir/Phase3/$Flavor/llvmCore-$Release-rc$RC.install + rm -rf $llvmCore_phase1_objdir rm -rf $llvmCore_phase1_installdir rm -rf $llvmCore_phase2_objdir rm -rf $llvmCore_phase2_installdir + rm -rf $llvmCore_phase3_objdir + rm -rf $llvmCore_phase3_installdir mkdir -p $llvmCore_phase1_objdir mkdir -p $llvmCore_phase1_installdir mkdir -p $llvmCore_phase2_objdir mkdir -p $llvmCore_phase2_installdir - - llvmgcc42_phase1_objdir=$BuildDir/Phase1/$Flavor/llvmgcc42-$Release-rc$RC.obj - llvmgcc42_phase1_installdir=$BuildDir/Phase1/$Flavor/llvmgcc42-$Release-rc$RC.install - - llvmgcc42_phase2_objdir=$BuildDir/Phase2/$Flavor/llvmgcc42-$Release-rc$RC.obj - llvmgcc42_phase2_installdir=$BuildDir/Phase2/$Flavor/llvmgcc42-$Release-rc$RC.install - - rm -rf $llvmgcc42_phase1_objdir - rm -rf $llvmgcc42_phase1_installdir - rm -rf $llvmgcc42_phase2_objdir - rm -rf $llvmgcc42_phase2_installdir - - mkdir -p $llvmgcc42_phase1_objdir - mkdir -p $llvmgcc42_phase1_installdir - mkdir -p $llvmgcc42_phase2_objdir - mkdir -p $llvmgcc42_phase2_installdir + mkdir -p $llvmCore_phase3_objdir + mkdir -p $llvmCore_phase3_installdir ############################################################################ # Phase 1: Build llvmCore and llvmgcc42 echo "# Phase 1: Building llvmCore" configure_llvmCore 1 $Flavor \ - $llvmCore_phase1_objdir $llvmCore_phase1_installdir \ - $llvmgcc42_phase1_installdir + $llvmCore_phase1_objdir $llvmCore_phase1_installdir build_llvmCore 1 $Flavor \ $llvmCore_phase1_objdir - echo "# Phase 1: Building llvmgcc42" - configure_llvm_gcc 1 $Flavor \ - $llvmgcc42_phase1_objdir $llvmgcc42_phase1_installdir \ - $llvmCore_phase1_objdir - build_llvm_gcc 1 $Flavor \ - $llvmgcc42_phase1_objdir $llvmgcc42_phase1_installdir - ############################################################################ - # Phase 2: Build llvmCore with newly built llvmgcc42 from phase 1. + # Phase 2: Build llvmCore with newly built clang from phase 1. + c_compiler=$llvmCore_phase1_installdir/bin/clang + cxx_compiler=$llvmCore_phase1_installdir/bin/clang++ echo "# Phase 2: Building llvmCore" configure_llvmCore 2 $Flavor \ - $llvmCore_phase2_objdir $llvmCore_phase2_installdir \ - $llvmgcc42_phase1_installdir + $llvmCore_phase2_objdir $llvmCore_phase2_installdir build_llvmCore 2 $Flavor \ $llvmCore_phase2_objdir - echo "# Phase 2: Building llvmgcc42" - configure_llvm_gcc 2 $Flavor \ - $llvmgcc42_phase2_objdir $llvmgcc42_phase2_installdir \ - $llvmCore_phase2_objdir - build_llvm_gcc 2 $Flavor \ - $llvmgcc42_phase2_objdir $llvmgcc42_phase1_installdir + ############################################################################ + # Phase 3: Build llvmCore with newly built clang from phase 2. + c_compiler=$llvmCore_phase2_installdir/bin/clang + cxx_compiler=$llvmCore_phase2_installdir/bin/clang++ + echo "# Phase 3: Building llvmCore" + configure_llvmCore 3 $Flavor \ + $llvmCore_phase3_objdir $llvmCore_phase3_installdir + build_llvmCore 3 $Flavor \ + $llvmCore_phase3_objdir - echo "# Testing - built with llvmgcc42" - test_llvmCore 2 $Flavor $llvmCore_phase2_objdir + ############################################################################ + # Testing: Test phase 3 + echo "# Testing - built with clang" + test_llvmCore 3 $Flavor $llvmCore_phase3_objdir + + ############################################################################ + # Compare .o files between Phase2 and Phase3 and report which ones differ. + echo + echo "# Comparing Phase 2 and Phase 3 files" + for o in `find $llvmCore_phase2_objdir -name '*.o'` ; do + p3=`echo $o | sed -e 's,Phase2,Phase3,'` + if ! cmp --ignore-initial=16 $o $p3 > /dev/null 2>&1 ; then + echo "file `basename $o` differs between phase 2 and phase 3" + fi + done done ) 2>&1 | tee $LogDir/testing.$Release-rc$RC.log +set +e + # Woo hoo! echo "### Testing Finished ###" echo "### Logs: $LogDir" diff --git a/utils/unittest/CMakeLists.txt b/utils/unittest/CMakeLists.txt index 29218bb37c71..73491f0721d5 100644 --- a/utils/unittest/CMakeLists.txt +++ b/utils/unittest/CMakeLists.txt @@ -32,6 +32,7 @@ add_llvm_library(gtest googletest/gtest-death-test.cc googletest/gtest-filepath.cc googletest/gtest-port.cc + googletest/gtest-printers.cc googletest/gtest-test-part.cc googletest/gtest-typed-test.cc ) diff --git a/utils/unittest/googletest/README.LLVM b/utils/unittest/googletest/README.LLVM index d6e6f9872282..51340e9ceb0c 100644 --- a/utils/unittest/googletest/README.LLVM +++ b/utils/unittest/googletest/README.LLVM @@ -1,14 +1,14 @@ LLVM notes ---------- -This directory contains Google Test 1.5.0, with all elements removed except for +This directory contains Google Test 1.6.0, with all elements removed except for the actual source code, to minimize the addition to the LLVM distribution. Cleaned up as follows: # Remove all the unnecessary files and directories $ rm -f aclocal* CMakeLists.txt configure* Makefile* CHANGES CONTRIBUTORS README -$ rm -rf build-aux codegear fused-src m4 make msvc samples scripts test xcode +$ rm -rf build-aux cmake codegear fused-src m4 make msvc samples scripts test xcode $ rm -f `find . -name \*\.pump` # Move all the source files to the current directory @@ -21,6 +21,8 @@ $ mv *.h include/gtest/internal/ # Update paths to the included files $ perl -pi -e 's|^#include "src/|#include "gtest/internal/|' *.cc +$ rm -f gtest-all.cc gtest_main.cc + $ mv COPYING LICENSE.TXT diff --git a/utils/unittest/googletest/gtest-death-test.cc b/utils/unittest/googletest/gtest-death-test.cc index e4199de3dc47..65893851e2d3 100644 --- a/utils/unittest/googletest/gtest-death-test.cc +++ b/utils/unittest/googletest/gtest-death-test.cc @@ -31,31 +31,31 @@ // // This file implements death tests. -#include -#include +#include "gtest/gtest-death-test.h" +#include "gtest/internal/gtest-port.h" #if GTEST_HAS_DEATH_TEST -#if GTEST_OS_MAC -#include -#endif // GTEST_OS_MAC +# if GTEST_OS_MAC +# include +# endif // GTEST_OS_MAC -#include -#include -#include -#include +# include +# include +# include +# include -#if GTEST_OS_WINDOWS -#include -#else -#include -#include -#endif // GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS +# include +# else +# include +# include +# endif // GTEST_OS_WINDOWS #endif // GTEST_HAS_DEATH_TEST -#include -#include +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-string.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is @@ -113,14 +113,18 @@ ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { // ExitedWithCode function-call operator. bool ExitedWithCode::operator()(int exit_status) const { -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS + return exit_status == exit_code_; -#else + +# else + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; -#endif // GTEST_OS_WINDOWS + +# endif // GTEST_OS_WINDOWS } -#if !GTEST_OS_WINDOWS +# if !GTEST_OS_WINDOWS // KilledBySignal constructor. KilledBySignal::KilledBySignal(int signum) : signum_(signum) { } @@ -129,7 +133,7 @@ KilledBySignal::KilledBySignal(int signum) : signum_(signum) { bool KilledBySignal::operator()(int exit_status) const { return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; } -#endif // !GTEST_OS_WINDOWS +# endif // !GTEST_OS_WINDOWS namespace internal { @@ -139,20 +143,25 @@ namespace internal { // specified by wait(2). static String ExitSummary(int exit_code) { Message m; -#if GTEST_OS_WINDOWS + +# if GTEST_OS_WINDOWS + m << "Exited with exit status " << exit_code; -#else + +# else + if (WIFEXITED(exit_code)) { m << "Exited with exit status " << WEXITSTATUS(exit_code); } else if (WIFSIGNALED(exit_code)) { m << "Terminated by signal " << WTERMSIG(exit_code); } -#ifdef WCOREDUMP +# ifdef WCOREDUMP if (WCOREDUMP(exit_code)) { m << " (core dumped)"; } -#endif -#endif // GTEST_OS_WINDOWS +# endif +# endif // GTEST_OS_WINDOWS + return m.GetString(); } @@ -162,7 +171,7 @@ bool ExitedUnsuccessfully(int exit_status) { return !ExitedWithCode(0)(exit_status); } -#if !GTEST_OS_WINDOWS +# if !GTEST_OS_WINDOWS // Generates a textual failure message when a death test finds more than // one thread running, or cannot determine the number of threads, prior // to executing the given statement. It is the responsibility of the @@ -177,20 +186,24 @@ static String DeathTestThreadWarning(size_t thread_count) { msg << "detected " << thread_count << " threads."; return msg.GetString(); } -#endif // !GTEST_OS_WINDOWS +# endif // !GTEST_OS_WINDOWS // Flag characters for reporting a death test that did not die. static const char kDeathTestLived = 'L'; static const char kDeathTestReturned = 'R'; +static const char kDeathTestThrew = 'T'; static const char kDeathTestInternalError = 'I'; -// An enumeration describing all of the possible ways that a death test -// can conclude. DIED means that the process died while executing the -// test code; LIVED means that process lived beyond the end of the test -// code; and RETURNED means that the test statement attempted a "return," -// which is not allowed. IN_PROGRESS means the test has not yet -// concluded. -enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED }; +// An enumeration describing all of the possible ways that a death test can +// conclude. DIED means that the process died while executing the test +// code; LIVED means that process lived beyond the end of the test code; +// RETURNED means that the test statement attempted to execute a return +// statement, which is not allowed; THREW means that the test statement +// returned control by throwing an exception. IN_PROGRESS means the test +// has not yet concluded. +// TODO(vladl@google.com): Unify names and possibly values for +// AbortReason, DeathTestOutcome, and flag characters above. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; // Routine for aborting the program which is safe to call from an // exec-style death test child process, in which case the error @@ -212,13 +225,13 @@ void DeathTestAbort(const String& message) { } else { fprintf(stderr, "%s", message.c_str()); fflush(stderr); - abort(); + posix::Abort(); } } // A replacement for CHECK that calls DeathTestAbort if the assertion // fails. -#define GTEST_DEATH_TEST_CHECK_(expression) \ +# define GTEST_DEATH_TEST_CHECK_(expression) \ do { \ if (!::testing::internal::IsTrue(expression)) { \ DeathTestAbort(::testing::internal::String::Format( \ @@ -234,7 +247,7 @@ void DeathTestAbort(const String& message) { // evaluates the expression as long as it evaluates to -1 and sets // errno to EINTR. If the expression evaluates to -1 but errno is // something other than EINTR, DeathTestAbort is called. -#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ +# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ do { \ int gtest_retval; \ do { \ @@ -388,6 +401,9 @@ void DeathTestImpl::ReadAndInterpretStatusByte() { case kDeathTestReturned: set_outcome(RETURNED); break; + case kDeathTestThrew: + set_outcome(THREW); + break; case kDeathTestLived: set_outcome(LIVED); break; @@ -416,19 +432,46 @@ void DeathTestImpl::Abort(AbortReason reason) { // it finds any data in our pipe. So, here we write a single flag byte // to the pipe, then exit. const char status_ch = - reason == TEST_DID_NOT_DIE ? kDeathTestLived : kDeathTestReturned; + reason == TEST_DID_NOT_DIE ? kDeathTestLived : + reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); - GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(write_fd())); + // We are leaking the descriptor here because on some platforms (i.e., + // when built as Windows DLL), destructors of global objects will still + // run after calling _exit(). On such systems, write_fd_ will be + // indirectly closed from the destructor of UnitTestImpl, causing double + // close if it is also closed here. On debug configurations, double close + // may assert. As there are no in-process buffers to flush here, we are + // relying on the OS to close the descriptor after the process terminates + // when the destructors are not run. _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) } +// Returns an indented copy of stderr output for a death test. +// This makes distinguishing death test output lines from regular log lines +// much easier. +static ::std::string FormatDeathTestOutput(const ::std::string& output) { + ::std::string ret; + for (size_t at = 0; ; ) { + const size_t line_end = output.find('\n', at); + ret += "[ DEATH ] "; + if (line_end == ::std::string::npos) { + ret += output.substr(at); + break; + } + ret += output.substr(at, line_end + 1 - at); + at = line_end + 1; + } + return ret; +} + // Assesses the success or failure of a death test, using both private // members which have previously been set, and one argument: // // Private data members: // outcome: An enumeration describing how the death test -// concluded: DIED, LIVED, or RETURNED. The death test fails -// in the latter two cases. +// concluded: DIED, LIVED, THREW, or RETURNED. The death test +// fails in the latter three cases. // status: The exit status of the child process. On *nix, it is in the // in the format specified by wait(2). On Windows, this is the // value supplied to the ExitProcess() API or a numeric code @@ -457,11 +500,15 @@ bool DeathTestImpl::Passed(bool status_ok) { switch (outcome()) { case LIVED: buffer << " Result: failed to die.\n" - << " Error msg: " << error_message; + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case THREW: + buffer << " Result: threw an exception.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case RETURNED: buffer << " Result: illegal return in test statement.\n" - << " Error msg: " << error_message; + << " Error msg:\n" << FormatDeathTestOutput(error_message); break; case DIED: if (status_ok) { @@ -471,11 +518,12 @@ bool DeathTestImpl::Passed(bool status_ok) { } else { buffer << " Result: died but not with expected error.\n" << " Expected: " << regex()->pattern() << "\n" - << "Actual msg: " << error_message; + << "Actual msg:\n" << FormatDeathTestOutput(error_message); } } else { buffer << " Result: died but not with expected exit code:\n" - << " " << ExitSummary(status()) << "\n"; + << " " << ExitSummary(status()) << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); } break; case IN_PROGRESS: @@ -488,7 +536,7 @@ bool DeathTestImpl::Passed(bool status_ok) { return success; } -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS // WindowsDeathTest implements death tests on Windows. Due to the // specifics of starting new processes on Windows, death tests there are // always threadsafe, and Google Test considers the @@ -519,11 +567,11 @@ bool DeathTestImpl::Passed(bool status_ok) { // class WindowsDeathTest : public DeathTestImpl { public: - WindowsDeathTest(const char* statement, - const RE* regex, + WindowsDeathTest(const char* a_statement, + const RE* a_regex, const char* file, int line) - : DeathTestImpl(statement, regex), file_(file), line_(line) {} + : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} // All of these virtual functions are inherited from DeathTest. virtual int Wait(); @@ -580,12 +628,12 @@ int WindowsDeathTest::Wait() { GTEST_DEATH_TEST_CHECK_( WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), INFINITE)); - DWORD status; - GTEST_DEATH_TEST_CHECK_(::GetExitCodeProcess(child_handle_.Get(), &status) - != FALSE); + DWORD status_code; + GTEST_DEATH_TEST_CHECK_( + ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); child_handle_.Reset(); - set_status(static_cast(status)); - return this->status(); + set_status(static_cast(status_code)); + return status(); } // The AssumeRole process for a Windows death test. It creates a child @@ -684,7 +732,7 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() { set_spawned(true); return OVERSEE_TEST; } -#else // We are not on Windows. +# else // We are not on Windows. // ForkingDeathTest provides implementations for most of the abstract // methods of the DeathTest interface. Only the AssumeRole method is @@ -832,19 +880,19 @@ struct ExecDeathTestArgs { int close_fd; // File descriptor to close; the read end of a pipe }; -#if GTEST_OS_MAC +# if GTEST_OS_MAC inline char** GetEnviron() { // When Google Test is built as a framework on MacOS X, the environ variable // is unavailable. Apple's documentation (man environ) recommends using // _NSGetEnviron() instead. return *_NSGetEnviron(); } -#else +# else // Some POSIX platforms expect you to declare environ. extern "C" makes // it reside in the global namespace. extern "C" char** environ; inline char** GetEnviron() { return environ; } -#endif // GTEST_OS_MAC +# endif // GTEST_OS_MAC // The main function for a threadsafe-style death test child process. // This function is called in a clone()-ed process and thus must avoid @@ -884,6 +932,11 @@ static int ExecDeathTestChildMain(void* child_arg) { // This could be accomplished more elegantly by a single recursive // function, but we want to guard against the unlikely possibility of // a smart compiler optimizing the recursion away. +// +// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining +// StackLowerThanAddress into StackGrowsDown, which then doesn't give +// correct answer. +bool StackLowerThanAddress(const void* ptr) GTEST_NO_INLINE_; bool StackLowerThanAddress(const void* ptr) { int dummy; return &dummy < ptr; @@ -901,7 +954,7 @@ static pid_t ExecDeathTestFork(char* const* argv, int close_fd) { ExecDeathTestArgs args = { argv, close_fd }; pid_t child_pid = -1; -#if GTEST_HAS_CLONE +# if GTEST_HAS_CLONE const bool use_fork = GTEST_FLAG(death_test_use_fork); if (!use_fork) { @@ -918,9 +971,9 @@ static pid_t ExecDeathTestFork(char* const* argv, int close_fd) { GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); } -#else +# else const bool use_fork = true; -#endif // GTEST_HAS_CLONE +# endif // GTEST_HAS_CLONE if (use_fork && (child_pid = fork()) == 0) { ExecDeathTestChildMain(&args); @@ -981,7 +1034,7 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { return OVERSEE_TEST; } -#endif // !GTEST_OS_WINDOWS +# endif // !GTEST_OS_WINDOWS // Creates a concrete DeathTest-derived class that depends on the // --gtest_death_test_style flag, and sets the pointer pointed to @@ -1012,18 +1065,23 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, } } -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS + if (GTEST_FLAG(death_test_style) == "threadsafe" || GTEST_FLAG(death_test_style) == "fast") { *test = new WindowsDeathTest(statement, regex, file, line); } -#else + +# else + if (GTEST_FLAG(death_test_style) == "threadsafe") { *test = new ExecDeathTest(statement, regex, file, line); } else if (GTEST_FLAG(death_test_style) == "fast") { *test = new NoExecDeathTest(statement, regex); } -#endif // GTEST_OS_WINDOWS + +# endif // GTEST_OS_WINDOWS + else { // NOLINT - this is more readable than unbalanced brackets inside #if. DeathTest::set_last_death_test_message(String::Format( "Unknown death test style \"%s\" encountered", @@ -1054,7 +1112,7 @@ static void SplitString(const ::std::string& str, char delimiter, dest->swap(parsed); } -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS // Recreates the pipe and event handles from the provided parameters, // signals the event, and returns a file descriptor wrapped around the pipe // handle. This function is called in the child process only. @@ -1118,7 +1176,7 @@ int GetStatusFileDescriptor(unsigned int parent_process_id, return write_fd; } -#endif // GTEST_OS_WINDOWS +# endif // GTEST_OS_WINDOWS // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if @@ -1134,7 +1192,8 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); int write_fd = -1; -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS + unsigned int parent_process_id = 0; size_t write_handle_as_size_t = 0; size_t event_handle_as_size_t = 0; @@ -1152,7 +1211,8 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { write_fd = GetStatusFileDescriptor(parent_process_id, write_handle_as_size_t, event_handle_as_size_t); -#else +# else + if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index) @@ -1161,7 +1221,9 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { "Bad --gtest_internal_run_death_test flag: %s", GTEST_FLAG(internal_run_death_test).c_str())); } -#endif // GTEST_OS_WINDOWS + +# endif // GTEST_OS_WINDOWS + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); } diff --git a/utils/unittest/googletest/gtest-filepath.cc b/utils/unittest/googletest/gtest-filepath.cc index 8d1d67ec7b80..bc610094e118 100644 --- a/utils/unittest/googletest/gtest-filepath.cc +++ b/utils/unittest/googletest/gtest-filepath.cc @@ -29,35 +29,35 @@ // // Authors: keith.ray@gmail.com (Keith Ray) -#include -#include +#include "gtest/internal/gtest-filepath.h" +#include "gtest/internal/gtest-port.h" #include #if GTEST_OS_WINDOWS_MOBILE -#include +# include #elif GTEST_OS_WINDOWS -#include -#include -#elif GTEST_OS_SYMBIAN -// Symbian OpenC has PATH_MAX in sys/syslimits.h -#include +# include +# include +#elif GTEST_OS_SYMBIAN || GTEST_OS_NACL +// Symbian OpenC and NaCl have PATH_MAX in sys/syslimits.h +# include #else -#include -#include // Some Linux distributions define PATH_MAX here. +# include +# include // Some Linux distributions define PATH_MAX here. #endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS -#define GTEST_PATH_MAX_ _MAX_PATH +# define GTEST_PATH_MAX_ _MAX_PATH #elif defined(PATH_MAX) -#define GTEST_PATH_MAX_ PATH_MAX +# define GTEST_PATH_MAX_ PATH_MAX #elif defined(_XOPEN_PATH_MAX) -#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX #else -#define GTEST_PATH_MAX_ _POSIX_PATH_MAX +# define GTEST_PATH_MAX_ _POSIX_PATH_MAX #endif // GTEST_OS_WINDOWS -#include +#include "gtest/internal/gtest-string.h" namespace testing { namespace internal { @@ -71,16 +71,16 @@ const char kPathSeparator = '\\'; const char kAlternatePathSeparator = '/'; const char kPathSeparatorString[] = "\\"; const char kAlternatePathSeparatorString[] = "/"; -#if GTEST_OS_WINDOWS_MOBILE +# if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory. You should not use // the current directory in tests on Windows CE, but this at least // provides a reasonable fallback. const char kCurrentDirectoryString[] = "\\"; // Windows CE doesn't define INVALID_FILE_ATTRIBUTES const DWORD kInvalidFileAttributes = 0xffffffff; -#else +# else const char kCurrentDirectoryString[] = ".\\"; -#endif // GTEST_OS_WINDOWS_MOBILE +# endif // GTEST_OS_WINDOWS_MOBILE #else const char kPathSeparator = '/'; const char kPathSeparatorString[] = "/"; diff --git a/utils/unittest/googletest/gtest-port.cc b/utils/unittest/googletest/gtest-port.cc index 56095994cdf9..07e5bb3c0d6c 100644 --- a/utils/unittest/googletest/gtest-port.cc +++ b/utils/unittest/googletest/gtest-port.cc @@ -29,30 +29,32 @@ // // Author: wan@google.com (Zhanyong Wan) -#include +#include "gtest/internal/gtest-port.h" #include #include #include +#include #if GTEST_OS_WINDOWS_MOBILE -#include // For TerminateProcess() +# include // For TerminateProcess() #elif GTEST_OS_WINDOWS -#include -#include +# include +# include #else -#include +# include #endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_MAC -#include -#include -#include +# include +# include +# include #endif // GTEST_OS_MAC -#include -#include -#include +#include "gtest/gtest-spi.h" +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is @@ -180,20 +182,20 @@ bool IsInSet(char ch, const char* str) { // Returns true iff ch belongs to the given classification. Unlike // similar functions in , these aren't affected by the // current locale. -bool IsDigit(char ch) { return '0' <= ch && ch <= '9'; } -bool IsPunct(char ch) { +bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsAsciiPunct(char ch) { return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); } bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } -bool IsWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } -bool IsWordChar(char ch) { +bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsAsciiWordChar(char ch) { return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('0' <= ch && ch <= '9') || ch == '_'; } // Returns true iff "\\c" is a supported escape sequence. bool IsValidEscape(char c) { - return (IsPunct(c) || IsInSet(c, "dDfnrsStvwW")); + return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); } // Returns true iff the given atom (specified by escaped and pattern) @@ -201,19 +203,19 @@ bool IsValidEscape(char c) { bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { if (escaped) { // "\\p" where p is pattern_char. switch (pattern_char) { - case 'd': return IsDigit(ch); - case 'D': return !IsDigit(ch); + case 'd': return IsAsciiDigit(ch); + case 'D': return !IsAsciiDigit(ch); case 'f': return ch == '\f'; case 'n': return ch == '\n'; case 'r': return ch == '\r'; - case 's': return IsWhiteSpace(ch); - case 'S': return !IsWhiteSpace(ch); + case 's': return IsAsciiWhiteSpace(ch); + case 'S': return !IsAsciiWhiteSpace(ch); case 't': return ch == '\t'; case 'v': return ch == '\v'; - case 'w': return IsWordChar(ch); - case 'W': return !IsWordChar(ch); + case 'w': return IsAsciiWordChar(ch); + case 'W': return !IsAsciiWordChar(ch); } - return IsPunct(pattern_char) && pattern_char == ch; + return IsAsciiPunct(pattern_char) && pattern_char == ch; } return (pattern_char == '.' && ch != '\n') || pattern_char == ch; @@ -422,6 +424,38 @@ void RE::Init(const char* regex) { #endif // GTEST_USES_POSIX_RE +const char kUnknownFile[] = "unknown file"; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { + const char* const file_name = file == NULL ? kUnknownFile : file; + + if (line < 0) { + return String::Format("%s:", file_name).c_str(); + } +#ifdef _MSC_VER + return String::Format("%s(%d):", file_name, line).c_str(); +#else + return String::Format("%s:%d:", file_name, line).c_str(); +#endif // _MSC_VER +} + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +// Note that FormatCompilerIndependentFileLocation() does NOT append colon +// to the file location it produces, unlike FormatFileLocation(). +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( + const char* file, int line) { + const char* const file_name = file == NULL ? kUnknownFile : file; + + if (line < 0) + return file_name; + else + return String::Format("%s:%d", file_name, line).c_str(); +} + GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) : severity_(severity) { @@ -444,18 +478,19 @@ GTestLog::~GTestLog() { // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) #ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4996) +# pragma warning(push) +# pragma warning(disable: 4996) #endif // _MSC_VER -#if GTEST_HAS_STREAM_REDIRECTION_ +#if GTEST_HAS_STREAM_REDIRECTION // Object that captures an output stream (stdout/stderr). class CapturedStream { public: // The ctor redirects the stream to a temporary file. CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { -#if GTEST_OS_WINDOWS + +# if GTEST_OS_WINDOWS char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT @@ -470,14 +505,14 @@ class CapturedStream { GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " << temp_file_path; filename_ = temp_file_path; -#else +# else // There's no guarantee that a test has write access to the // current directory, so we create the temporary file in the /tmp // directory instead. char name_template[] = "/tmp/captured_stream.XXXXXX"; const int captured_fd = mkstemp(name_template); filename_ = name_template; -#endif // GTEST_OS_WINDOWS +# endif // GTEST_OS_WINDOWS fflush(NULL); dup2(captured_fd, fd_); close(captured_fd); @@ -546,9 +581,9 @@ String CapturedStream::ReadEntireFile(FILE* file) { return content; } -#ifdef _MSC_VER -#pragma warning(pop) -#endif // _MSC_VER +# ifdef _MSC_VER +# pragma warning(pop) +# endif // _MSC_VER static CapturedStream* g_captured_stderr = NULL; static CapturedStream* g_captured_stdout = NULL; @@ -588,7 +623,7 @@ String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } // Stops capturing stderr and returns the captured string. String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } -#endif // GTEST_HAS_STREAM_REDIRECTION_ +#endif // GTEST_HAS_STREAM_REDIRECTION #if GTEST_HAS_DEATH_TEST @@ -618,7 +653,7 @@ static String FlagToEnvVar(const char* flag) { Message env_var; for (size_t i = 0; i != full_flag.length(); i++) { - env_var << static_cast(toupper(full_flag.c_str()[i])); + env_var << ToUpper(full_flag.c_str()[i]); } return env_var.GetString(); diff --git a/utils/unittest/googletest/gtest-printers.cc b/utils/unittest/googletest/gtest-printers.cc new file mode 100644 index 000000000000..ed63c7b3b91d --- /dev/null +++ b/utils/unittest/googletest/gtest-printers.cc @@ -0,0 +1,356 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// It uses the << operator when possible, and prints the bytes in the +// object otherwise. A user can override its behavior for a class +// type Foo by defining either operator<<(::std::ostream&, const Foo&) +// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that +// defines Foo. + +#include "gtest/gtest-printers.h" +#include +#include +#include // NOLINT +#include +#include "gtest/internal/gtest-port.h" + +namespace testing { + +namespace { + +using ::std::ostream; + +#if GTEST_OS_WINDOWS_MOBILE // Windows CE does not define _snprintf_s. +# define snprintf _snprintf +#elif _MSC_VER >= 1400 // VC 8.0 and later deprecate snprintf and _snprintf. +# define snprintf _snprintf_s +#elif _MSC_VER +# define snprintf _snprintf +#endif // GTEST_OS_WINDOWS_MOBILE + +// Prints a segment of bytes in the given object. +void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, + size_t count, ostream* os) { + char text[5] = ""; + for (size_t i = 0; i != count; i++) { + const size_t j = start + i; + if (i != 0) { + // Organizes the bytes into groups of 2 for easy parsing by + // human. + if ((j % 2) == 0) + *os << ' '; + else + *os << '-'; + } + snprintf(text, sizeof(text), "%02X", obj_bytes[j]); + *os << text; + } +} + +// Prints the bytes in the given value to the given ostream. +void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, + ostream* os) { + // Tells the user how big the object is. + *os << count << "-byte object <"; + + const size_t kThreshold = 132; + const size_t kChunkSize = 64; + // If the object size is bigger than kThreshold, we'll have to omit + // some details by printing only the first and the last kChunkSize + // bytes. + // TODO(wan): let the user control the threshold using a flag. + if (count < kThreshold) { + PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); + } else { + PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); + *os << " ... "; + // Rounds up to 2-byte boundary. + const size_t resume_pos = (count - kChunkSize + 1)/2*2; + PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); + } + *os << ">"; +} + +} // namespace + +namespace internal2 { + +// Delegates to PrintBytesInObjectToImpl() to print the bytes in the +// given object. The delegation simplifies the implementation, which +// uses the << operator and thus is easier done outside of the +// ::testing::internal namespace, which contains a << operator that +// sometimes conflicts with the one in STL. +void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, + ostream* os) { + PrintBytesInObjectToImpl(obj_bytes, count, os); +} + +} // namespace internal2 + +namespace internal { + +// Depending on the value of a char (or wchar_t), we print it in one +// of three formats: +// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), +// - as a hexidecimal escape sequence (e.g. '\x7F'), or +// - as a special escape sequence (e.g. '\r', '\n'). +enum CharFormat { + kAsIs, + kHexEscape, + kSpecialEscape +}; + +// Returns true if c is a printable ASCII character. We test the +// value of c directly instead of calling isprint(), which is buggy on +// Windows Mobile. +inline bool IsPrintableAscii(wchar_t c) { + return 0x20 <= c && c <= 0x7E; +} + +// Prints a wide or narrow char c as a character literal without the +// quotes, escaping it when necessary; returns how c was formatted. +// The template argument UnsignedChar is the unsigned version of Char, +// which is the type of c. +template +static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { + switch (static_cast(c)) { + case L'\0': + *os << "\\0"; + break; + case L'\'': + *os << "\\'"; + break; + case L'\\': + *os << "\\\\"; + break; + case L'\a': + *os << "\\a"; + break; + case L'\b': + *os << "\\b"; + break; + case L'\f': + *os << "\\f"; + break; + case L'\n': + *os << "\\n"; + break; + case L'\r': + *os << "\\r"; + break; + case L'\t': + *os << "\\t"; + break; + case L'\v': + *os << "\\v"; + break; + default: + if (IsPrintableAscii(c)) { + *os << static_cast(c); + return kAsIs; + } else { + *os << String::Format("\\x%X", static_cast(c)); + return kHexEscape; + } + } + return kSpecialEscape; +} + +// Prints a char c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) { + switch (c) { + case L'\'': + *os << "'"; + return kAsIs; + case L'"': + *os << "\\\""; + return kSpecialEscape; + default: + return PrintAsCharLiteralTo(c, os); + } +} + +// Prints a char c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) { + return PrintAsWideStringLiteralTo(static_cast(c), os); +} + +// Prints a wide or narrow character c and its code. '\0' is printed +// as "'\\0'", other unprintable characters are also properly escaped +// using the standard C++ escape sequence. The template argument +// UnsignedChar is the unsigned version of Char, which is the type of c. +template +void PrintCharAndCodeTo(Char c, ostream* os) { + // First, print c as a literal in the most readable form we can find. + *os << ((sizeof(c) > 1) ? "L'" : "'"); + const CharFormat format = PrintAsCharLiteralTo(c, os); + *os << "'"; + + // To aid user debugging, we also print c's code in decimal, unless + // it's 0 (in which case c was printed as '\\0', making the code + // obvious). + if (c == 0) + return; + *os << " (" << String::Format("%d", c).c_str(); + + // For more convenience, we print c's code again in hexidecimal, + // unless c was already printed in the form '\x##' or the code is in + // [1, 9]. + if (format == kHexEscape || (1 <= c && c <= 9)) { + // Do nothing. + } else { + *os << String::Format(", 0x%X", + static_cast(c)).c_str(); + } + *os << ")"; +} + +void PrintTo(unsigned char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} +void PrintTo(signed char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} + +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its code. L'\0' is printed as "L'\\0'". +void PrintTo(wchar_t wc, ostream* os) { + PrintCharAndCodeTo(wc, os); +} + +// Prints the given array of characters to the ostream. +// The array starts at *begin, the length is len, it may include '\0' characters +// and may not be null-terminated. +static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) { + *os << "\""; + bool is_previous_hex = false; + for (size_t index = 0; index < len; ++index) { + const char cur = begin[index]; + if (is_previous_hex && IsXDigit(cur)) { + // Previous character is of '\x..' form and this character can be + // interpreted as another hexadecimal digit in its number. Break string to + // disambiguate. + *os << "\" \""; + } + is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape; + } + *os << "\""; +} + +// Prints a (const) char array of 'len' elements, starting at address 'begin'. +void UniversalPrintArray(const char* begin, size_t len, ostream* os) { + PrintCharsAsStringTo(begin, len, os); +} + +// Prints the given array of wide characters to the ostream. +// The array starts at *begin, the length is len, it may include L'\0' +// characters and may not be null-terminated. +static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len, + ostream* os) { + *os << "L\""; + bool is_previous_hex = false; + for (size_t index = 0; index < len; ++index) { + const wchar_t cur = begin[index]; + if (is_previous_hex && isascii(cur) && IsXDigit(static_cast(cur))) { + // Previous character is of '\x..' form and this character can be + // interpreted as another hexadecimal digit in its number. Break string to + // disambiguate. + *os << "\" L\""; + } + is_previous_hex = PrintAsWideStringLiteralTo(cur, os) == kHexEscape; + } + *os << "\""; +} + +// Prints the given C string to the ostream. +void PrintTo(const char* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, strlen(s), os); + } +} + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Prints the given wide C string to the ostream. +void PrintTo(const wchar_t* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintWideCharsAsStringTo(s, wcslen(s), os); + } +} +#endif // wchar_t is native + +// Prints a ::string object. +#if GTEST_HAS_GLOBAL_STRING +void PrintStringTo(const ::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +void PrintStringTo(const ::std::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} + +// Prints a ::wstring object. +#if GTEST_HAS_GLOBAL_WSTRING +void PrintWideStringTo(const ::wstring& s, ostream* os) { + PrintWideCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +void PrintWideStringTo(const ::std::wstring& s, ostream* os) { + PrintWideCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_STD_WSTRING + +} // namespace internal + +} // namespace testing diff --git a/utils/unittest/googletest/gtest-test-part.cc b/utils/unittest/googletest/gtest-test-part.cc index 8249afeb4c69..161278027d08 100644 --- a/utils/unittest/googletest/gtest-test-part.cc +++ b/utils/unittest/googletest/gtest-test-part.cc @@ -31,7 +31,7 @@ // // The Google C++ Testing Framework (Google Test) -#include +#include "gtest/gtest-test-part.h" // Indicates that this translation unit is part of Google Test's // implementation. It must come before gtest-internal-inl.h is diff --git a/utils/unittest/googletest/gtest-typed-test.cc b/utils/unittest/googletest/gtest-typed-test.cc index 3cc4b5de2aac..a5cc88f9205d 100644 --- a/utils/unittest/googletest/gtest-typed-test.cc +++ b/utils/unittest/googletest/gtest-typed-test.cc @@ -29,8 +29,8 @@ // // Author: wan@google.com (Zhanyong Wan) -#include -#include +#include "gtest/gtest-typed-test.h" +#include "gtest/gtest.h" namespace testing { namespace internal { @@ -40,7 +40,7 @@ namespace internal { // Skips to the first non-space char in str. Returns an empty string if str // contains only whitespace characters. static const char* SkipSpaces(const char* str) { - while (isspace(*str)) + while (IsSpace(*str)) str++; return str; } diff --git a/utils/unittest/googletest/gtest.cc b/utils/unittest/googletest/gtest.cc index 9aa54411497a..76244974115e 100644 --- a/utils/unittest/googletest/gtest.cc +++ b/utils/unittest/googletest/gtest.cc @@ -31,8 +31,8 @@ // // The Google C++ Testing Framework (Google Test) -#include -#include +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" #include #include @@ -43,7 +43,7 @@ #include #include -#include +#include // NOLINT #include #include @@ -51,72 +51,76 @@ // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). -#define GTEST_HAS_GETTIMEOFDAY_ 1 +# define GTEST_HAS_GETTIMEOFDAY_ 1 -#include -#include -#include +# include // NOLINT +# include // NOLINT +# include // NOLINT // Declares vsnprintf(). This header is not available on Windows. -#include -#include -#include -#include -#include -#include +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include #elif GTEST_OS_SYMBIAN -#define GTEST_HAS_GETTIMEOFDAY_ 1 -#include // NOLINT +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT #elif GTEST_OS_ZOS -#define GTEST_HAS_GETTIMEOFDAY_ 1 -#include // NOLINT +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT // On z/OS we additionally need strings.h for strcasecmp. -#include // NOLINT +# include // NOLINT #elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. -#include // NOLINT +# include // NOLINT #elif GTEST_OS_WINDOWS // We are on Windows proper. -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT -#if GTEST_OS_WINDOWS_MINGW +# if GTEST_OS_WINDOWS_MINGW // MinGW has gettimeofday() but not _ftime64(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). // TODO(kenton@google.com): There are other ways to get the time on // Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW // supports these. consider using them instead. -#define GTEST_HAS_GETTIMEOFDAY_ 1 -#include // NOLINT -#endif // GTEST_OS_WINDOWS_MINGW +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT +# endif // GTEST_OS_WINDOWS_MINGW // cpplint thinks that the header is already included, so we want to // silence it. -#include // NOLINT +# include // NOLINT #else // Assume other platforms have gettimeofday(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). -#define GTEST_HAS_GETTIMEOFDAY_ 1 +# define GTEST_HAS_GETTIMEOFDAY_ 1 // cpplint thinks that the header is already included, so we want to // silence it. -#include // NOLINT -#include // NOLINT +# include // NOLINT +# include // NOLINT #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS -#include +# include +#endif + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT #endif // Indicates that this translation unit is part of Google Test's @@ -129,7 +133,7 @@ #undef GTEST_IMPLEMENTATION_ #if GTEST_OS_WINDOWS -#define vsnprintf _vsnprintf +# define vsnprintf _vsnprintf #endif // GTEST_OS_WINDOWS namespace testing { @@ -187,7 +191,7 @@ GTEST_DEFINE_bool_( GTEST_DEFINE_bool_( catch_exceptions, - internal::BoolFromGTestEnv("catch_exceptions", false), + internal::BoolFromGTestEnv("catch_exceptions", true), "True iff " GTEST_NAME_ " should catch exceptions and treat them as test failures."); @@ -258,6 +262,13 @@ GTEST_DEFINE_int32_( "The maximum number of stack frames to print when an " "assertion fails. The valid range is 0 through 100, inclusive."); +GTEST_DEFINE_string_( + stream_result_to, + internal::StringFromGTestEnv("stream_result_to", ""), + "This flag specifies the host name and the port number on which to stream " + "test results. Example: \"localhost:555\". The flag is effective only on " + "Linux."); + GTEST_DEFINE_bool_( throw_on_failure, internal::BoolFromGTestEnv("throw_on_failure", false), @@ -490,20 +501,33 @@ bool UnitTestOptions::FilterMatchesTest(const String &test_case_name, !MatchesFilter(full_name, negative.c_str())); } -#if GTEST_OS_WINDOWS +#if GTEST_HAS_SEH // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. // This function is useful as an __except condition. int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { - // Google Test should handle an exception if: + // Google Test should handle a SEH exception if: // 1. the user wants it to, AND - // 2. this is not a breakpoint exception. - return (GTEST_FLAG(catch_exceptions) && - exception_code != EXCEPTION_BREAKPOINT) ? - EXCEPTION_EXECUTE_HANDLER : - EXCEPTION_CONTINUE_SEARCH; + // 2. this is not a breakpoint exception, AND + // 3. this is not a C++ exception (VC++ implements them via SEH, + // apparently). + // + // SEH exception code for C++ exceptions. + // (see http://support.microsoft.com/kb/185294 for more information). + const DWORD kCxxExceptionCode = 0xe06d7363; + + bool should_handle = true; + + if (!GTEST_FLAG(catch_exceptions)) + should_handle = false; + else if (exception_code == EXCEPTION_BREAKPOINT) + should_handle = false; + else if (exception_code == kCxxExceptionCode) + should_handle = false; + + return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; } -#endif // GTEST_OS_WINDOWS +#endif // GTEST_HAS_SEH } // namespace internal @@ -583,7 +607,7 @@ AssertionResult HasOneFailure(const char* /* results_expr */, const char* /* substr_expr */, const TestPartResultArray& results, TestPartResult::Type type, - const char* substr) { + const string& substr) { const String expected(type == TestPartResult::kFatalFailure ? "1 fatal failure" : "1 non-fatal failure"); @@ -594,23 +618,21 @@ AssertionResult HasOneFailure(const char* /* results_expr */, for (int i = 0; i < results.size(); i++) { msg << "\n" << results.GetTestPartResult(i); } - return AssertionFailure(msg); + return AssertionFailure() << msg; } const TestPartResult& r = results.GetTestPartResult(0); if (r.type() != type) { - msg << "Expected: " << expected << "\n" - << " Actual:\n" - << r; - return AssertionFailure(msg); + return AssertionFailure() << "Expected: " << expected << "\n" + << " Actual:\n" + << r; } - if (strstr(r.message(), substr) == NULL) { - msg << "Expected: " << expected << " containing \"" - << substr << "\"\n" - << " Actual:\n" - << r; - return AssertionFailure(msg); + if (strstr(r.message(), substr.c_str()) == NULL) { + return AssertionFailure() << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; } return AssertionSuccess(); @@ -622,7 +644,7 @@ AssertionResult HasOneFailure(const char* /* results_expr */, SingleFailureChecker:: SingleFailureChecker( const TestPartResultArray* results, TestPartResult::Type type, - const char* substr) + const string& substr) : results_(results), type_(type), substr_(substr) {} @@ -632,7 +654,7 @@ SingleFailureChecker:: SingleFailureChecker( // type and contains the given substring. If that's not the case, a // non-fatal failure will be generated. SingleFailureChecker::~SingleFailureChecker() { - EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_.c_str()); + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); } DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( @@ -764,25 +786,30 @@ TimeInMillis GetTimeInMillis() { return 0; #elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ __timeb64 now; -#ifdef _MSC_VER + +# ifdef _MSC_VER + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 // (deprecated function) there. // TODO(kenton@google.com): Use GetTickCount()? Or use // SystemTimeToFileTime() -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996. _ftime64(&now); -#pragma warning(pop) // Restores the warning state. -#else +# pragma warning(pop) // Restores the warning state. +# else + _ftime64(&now); -#endif // _MSC_VER + +# endif // _MSC_VER + return static_cast(now.time) * 1000 + now.millitm; #elif GTEST_HAS_GETTIMEOFDAY_ struct timeval now; gettimeofday(&now, NULL); return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; #else -#error "Don't know how to get the current time on your system." +# error "Don't know how to get the current time on your system." #endif } @@ -918,55 +945,13 @@ Message& Message::operator <<(const ::wstring& wstr) { } #endif // GTEST_HAS_GLOBAL_WSTRING -namespace internal { - -// Formats a value to be used in a failure message. - -// For a char value, we print it as a C++ char literal and as an -// unsigned integer (both in decimal and in hexadecimal). -String FormatForFailureMessage(char ch) { - const unsigned int ch_as_uint = ch; - // A String object cannot contain '\0', so we print "\\0" when ch is - // '\0'. - return String::Format("'%s' (%u, 0x%X)", - ch ? String::Format("%c", ch).c_str() : "\\0", - ch_as_uint, ch_as_uint); -} - -// For a wchar_t value, we print it as a C++ wchar_t literal and as an -// unsigned integer (both in decimal and in hexidecimal). -String FormatForFailureMessage(wchar_t wchar) { - // The C++ standard doesn't specify the exact size of the wchar_t - // type. It just says that it shall have the same size as another - // integral type, called its underlying type. - // - // Therefore, in order to print a wchar_t value in the numeric form, - // we first convert it to the largest integral type (UInt64) and - // then print the converted value. - // - // We use streaming to print the value as "%llu" doesn't work - // correctly with MSVC 7.1. - const UInt64 wchar_as_uint64 = wchar; - Message msg; - // A String object cannot contain '\0', so we print "\\0" when wchar is - // L'\0'. - char buffer[32]; // CodePointToUtf8 requires a buffer that big. - msg << "L'" - << (wchar ? CodePointToUtf8(static_cast(wchar), buffer) : "\\0") - << "' (" << wchar_as_uint64 << ", 0x" << ::std::setbase(16) - << wchar_as_uint64 << ")"; - return msg.GetString(); -} - -} // namespace internal - // AssertionResult constructors. // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult::AssertionResult(const AssertionResult& other) : success_(other.success_), message_(other.message_.get() != NULL ? - new internal::String(*other.message_) : - static_cast(NULL)) { + new ::std::string(*other.message_) : + static_cast< ::std::string*>(NULL)) { } // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. @@ -1029,7 +1014,7 @@ AssertionResult EqFailure(const char* expected_expression, msg << "\nWhich is: " << expected_value; } - return AssertionFailure(msg); + return AssertionFailure() << msg; } // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. @@ -1059,13 +1044,12 @@ AssertionResult DoubleNearPredFormat(const char* expr1, // TODO(wan): do not print the value of an expression if it's // already a literal. - Message msg; - msg << "The difference between " << expr1 << " and " << expr2 + return AssertionFailure() + << "The difference between " << expr1 << " and " << expr2 << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" << expr1 << " evaluates to " << val1 << ",\n" << expr2 << " evaluates to " << val2 << ", and\n" << abs_error_expr << " evaluates to " << abs_error << "."; - return AssertionFailure(msg); } @@ -1090,20 +1074,18 @@ AssertionResult FloatingPointLE(const char* expr1, // val2 is NaN, as the IEEE floating-point standard requires that // any predicate involving a NaN must return false. - StrStream val1_ss; + ::std::stringstream val1_ss; val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) << val1; - StrStream val2_ss; + ::std::stringstream val2_ss; val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) << val2; - Message msg; - msg << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" - << " Actual: " << StrStreamToString(&val1_ss) << " vs " - << StrStreamToString(&val2_ss); - - return AssertionFailure(msg); + return AssertionFailure() + << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StringStreamToString(&val1_ss) << " vs " + << StringStreamToString(&val2_ss); } } // namespace internal @@ -1150,11 +1132,10 @@ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ if (val1 op val2) {\ return AssertionSuccess();\ } else {\ - Message msg;\ - msg << "Expected: (" << expr1 << ") " #op " (" << expr2\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ << " vs " << FormatForComparisonFailureMessage(val2, val1);\ - return AssertionFailure(msg);\ }\ } @@ -1216,11 +1197,9 @@ AssertionResult CmpHelperSTRNE(const char* s1_expression, if (!String::CStringEquals(s1, s2)) { return AssertionSuccess(); } else { - Message msg; - msg << "Expected: (" << s1_expression << ") != (" - << s2_expression << "), actual: \"" - << s1 << "\" vs \"" << s2 << "\""; - return AssertionFailure(msg); + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; } } @@ -1232,11 +1211,10 @@ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, if (!String::CaseInsensitiveCStringEquals(s1, s2)) { return AssertionSuccess(); } else { - Message msg; - msg << "Expected: (" << s1_expression << ") != (" + return AssertionFailure() + << "Expected: (" << s1_expression << ") != (" << s2_expression << ") (ignoring case), actual: \"" << s1 << "\" vs \"" << s2 << "\""; - return AssertionFailure(msg); } } @@ -1285,13 +1263,12 @@ AssertionResult IsSubstringImpl( const bool is_wide_string = sizeof(needle[0]) > 1; const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; - return AssertionFailure( - Message() + return AssertionFailure() << "Value of: " << needle_expr << "\n" << " Actual: " << begin_string_quote << needle << "\"\n" << "Expected: " << (expected_to_be_substring ? "" : "not ") << "a substring of " << haystack_expr << "\n" - << "Which is: " << begin_string_quote << haystack << "\""); + << "Which is: " << begin_string_quote << haystack << "\""; } } // namespace @@ -1360,10 +1337,13 @@ namespace { AssertionResult HRESULTFailureHelper(const char* expr, const char* expected, long hr) { // NOLINT -#if GTEST_OS_WINDOWS_MOBILE +# if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't support FormatMessage. const char error_text[] = ""; -#else + +# else + // Looks up the human-readable system message for the HRESULT code // and since we're not passing any params to FormatMessage, we don't // want inserts expanded. @@ -1380,18 +1360,17 @@ AssertionResult HRESULTFailureHelper(const char* expr, kBufSize, // buf size NULL); // no arguments for inserts // Trims tailing white space (FormatMessage leaves a trailing cr-lf) - for (; message_length && isspace(error_text[message_length - 1]); + for (; message_length && IsSpace(error_text[message_length - 1]); --message_length) { error_text[message_length - 1] = '\0'; } -#endif // GTEST_OS_WINDOWS_MOBILE + +# endif // GTEST_OS_WINDOWS_MOBILE const String error_hex(String::Format("0x%08X ", hr)); - Message msg; - msg << "Expected: " << expr << " " << expected << ".\n" + return ::testing::AssertionFailure() + << "Expected: " << expr << " " << expected << ".\n" << " Actual: " << error_hex << error_text << "\n"; - - return ::testing::AssertionFailure(msg); } } // namespace @@ -1526,7 +1505,7 @@ String WideStringToUtf8(const wchar_t* str, int num_chars) { if (num_chars == -1) num_chars = static_cast(wcslen(str)); - StrStream stream; + ::std::stringstream stream; for (int i = 0; i < num_chars; ++i) { UInt32 unicode_code_point; @@ -1543,7 +1522,7 @@ String WideStringToUtf8(const wchar_t* str, int num_chars) { char buffer[32]; // CodePointToUtf8 requires a buffer this big. stream << CodePointToUtf8(unicode_code_point, buffer); } - return StrStreamToString(&stream); + return StringStreamToString(&stream); } // Converts a wide C string to a String using the UTF-8 encoding. @@ -1602,12 +1581,10 @@ AssertionResult CmpHelperSTRNE(const char* s1_expression, return AssertionSuccess(); } - Message msg; - msg << "Expected: (" << s1_expression << ") != (" - << s2_expression << "), actual: " - << String::ShowWideCStringQuoted(s1) - << " vs " << String::ShowWideCStringQuoted(s2); - return AssertionFailure(msg); + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << String::ShowWideCStringQuoted(s1) + << " vs " << String::ShowWideCStringQuoted(s2); } // Compares two C strings, ignoring case. Returns true iff they have @@ -1638,17 +1615,17 @@ bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { // current locale. bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) { - if ( lhs == NULL ) return rhs == NULL; + if (lhs == NULL) return rhs == NULL; - if ( rhs == NULL ) return false; + if (rhs == NULL) return false; #if GTEST_OS_WINDOWS return _wcsicmp(lhs, rhs) == 0; -#elif GTEST_OS_LINUX +#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID return wcscasecmp(lhs, rhs) == 0; #else - // Mac OS X and Cygwin don't define wcscasecmp. Other unknown OSes - // may not define it either. + // Android, Mac OS X and Cygwin don't define wcscasecmp. + // Other unknown OSes may not define it either. wint_t left, right; do { left = towlower(*lhs++); @@ -1730,10 +1707,12 @@ String String::Format(const char * format, ...) { // MSVC 8 deprecates vsnprintf(), so we want to suppress warning // 4996 (deprecated function) there. #ifdef _MSC_VER // We are using MSVC. -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4996) // Temporarily disables warning 4996. +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996. + const int size = vsnprintf(buffer, kBufferSize, format, args); -#pragma warning(pop) // Restores the warning state. + +# pragma warning(pop) // Restores the warning state. #else // We are not using MSVC. const int size = vsnprintf(buffer, kBufferSize, format, args); #endif // _MSC_VER @@ -1751,16 +1730,16 @@ String String::Format(const char * format, ...) { } } -// Converts the buffer in a StrStream to a String, converting NUL +// Converts the buffer in a stringstream to a String, converting NUL // bytes to "\\0" along the way. -String StrStreamToString(StrStream* ss) { +String StringStreamToString(::std::stringstream* ss) { const ::std::string& str = ss->str(); const char* const start = str.c_str(); const char* const end = start + str.length(); - // We need to use a helper StrStream to do this transformation + // We need to use a helper stringstream to do this transformation // because String doesn't support push_back(). - StrStream helper; + ::std::stringstream helper; for (const char* ch = start; ch != end; ++ch) { if (*ch == '\0') { helper << "\\0"; // Replaces NUL with "\\0"; @@ -1964,22 +1943,6 @@ void ReportFailureInUnknownLocation(TestPartResult::Type result_type, } // namespace internal -#if GTEST_HAS_SEH -// We are on Windows with SEH. - -// Adds an "exception thrown" fatal failure to the current test. -static void AddExceptionThrownFailure(DWORD exception_code, - const char* location) { - Message message; - message << "Exception thrown with code 0x" << std::setbase(16) << - exception_code << std::setbase(10) << " in " << location << "."; - - internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, - message.GetString()); -} - -#endif // GTEST_HAS_SEH - // Google Test requires all tests in the same test case to use the same test // fixture class. This function checks if the current test has the // same fixture class as the first test in the current test case. If @@ -1990,15 +1953,13 @@ bool Test::HasSameFixtureClass() { const TestCase* const test_case = impl->current_test_case(); // Info about the first test in the current test case. - const internal::TestInfoImpl* const first_test_info = - test_case->test_info_list()[0]->impl(); - const internal::TypeId first_fixture_id = first_test_info->fixture_class_id(); + const TestInfo* const first_test_info = test_case->test_info_list()[0]; + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; const char* const first_test_name = first_test_info->name(); // Info about the current test. - const internal::TestInfoImpl* const this_test_info = - impl->current_test_info()->impl(); - const internal::TypeId this_fixture_id = this_test_info->fixture_class_id(); + const TestInfo* const this_test_info = impl->current_test_info(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; const char* const this_test_name = this_test_info->name(); if (this_fixture_id != first_fixture_id) { @@ -2048,62 +2009,167 @@ bool Test::HasSameFixtureClass() { return true; } +#if GTEST_HAS_SEH + +// Adds an "exception thrown" fatal failure to the current test. This +// function returns its result via an output parameter pointer because VC++ +// prohibits creation of objects with destructors on stack in functions +// using __try (see error C2712). +static internal::String* FormatSehExceptionMessage(DWORD exception_code, + const char* location) { + Message message; + message << "SEH exception with code 0x" << std::setbase(16) << + exception_code << std::setbase(10) << " thrown in " << location << "."; + + return new internal::String(message.GetString()); +} + +#endif // GTEST_HAS_SEH + +#if GTEST_HAS_EXCEPTIONS + +// Adds an "exception thrown" fatal failure to the current test. +static internal::String FormatCxxExceptionMessage(const char* description, + const char* location) { + Message message; + if (description != NULL) { + message << "C++ exception with description \"" << description << "\""; + } else { + message << "Unknown C++ exception"; + } + message << " thrown in " << location << "."; + + return message.GetString(); +} + +static internal::String PrintTestPartResultToString( + const TestPartResult& test_part_result); + +// A failed Google Test assertion will throw an exception of this type when +// GTEST_FLAG(throw_on_failure) is true (if exceptions are enabled). We +// derive it from std::runtime_error, which is for errors presumably +// detectable only at run time. Since std::runtime_error inherits from +// std::exception, many testing frameworks know how to extract and print the +// message inside it. +class GoogleTestFailureException : public ::std::runtime_error { + public: + explicit GoogleTestFailureException(const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} +}; +#endif // GTEST_HAS_EXCEPTIONS + +namespace internal { +// We put these helper functions in the internal namespace as IBM's xlC +// compiler rejects the code if they were declared static. + +// Runs the given method and handles SEH exceptions it throws, when +// SEH is supported; returns the 0-value for type Result in case of an +// SEH exception. (Microsoft compilers cannot handle SEH and C++ +// exceptions in the same function. Therefore, we provide a separate +// wrapper function for handling SEH exceptions.) +template +Result HandleSehExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { +#if GTEST_HAS_SEH + __try { + return (object->*method)(); + } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT + GetExceptionCode())) { + // We create the exception message on the heap because VC++ prohibits + // creation of objects with destructors on stack in functions using __try + // (see error C2712). + internal::String* exception_message = FormatSehExceptionMessage( + GetExceptionCode(), location); + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + *exception_message); + delete exception_message; + return static_cast(0); + } +#else + (void)location; + return (object->*method)(); +#endif // GTEST_HAS_SEH +} + +// Runs the given method and catches and reports C++ and/or SEH-style +// exceptions, if they are supported; returns the 0-value for type +// Result in case of an SEH exception. +template +Result HandleExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { + // NOTE: The user code can affect the way in which Google Test handles + // exceptions by setting GTEST_FLAG(catch_exceptions), but only before + // RUN_ALL_TESTS() starts. It is technically possible to check the flag + // after the exception is caught and either report or re-throw the + // exception based on the flag's value: + // + // try { + // // Perform the test method. + // } catch (...) { + // if (GTEST_FLAG(catch_exceptions)) + // // Report the exception as failure. + // else + // throw; // Re-throws the original exception. + // } + // + // However, the purpose of this flag is to allow the program to drop into + // the debugger when the exception is thrown. On most platforms, once the + // control enters the catch block, the exception origin information is + // lost and the debugger will stop the program at the point of the + // re-throw in this function -- instead of at the point of the original + // throw statement in the code under test. For this reason, we perform + // the check early, sacrificing the ability to affect Google Test's + // exception handling in the method where the exception is thrown. + if (internal::GetUnitTestImpl()->catch_exceptions()) { +#if GTEST_HAS_EXCEPTIONS + try { + return HandleSehExceptionsInMethodIfSupported(object, method, location); + } catch (const GoogleTestFailureException&) { // NOLINT + // This exception doesn't originate in code under test. It makes no + // sense to report it as a test failure. + throw; + } catch (const std::exception& e) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(e.what(), location)); + } catch (...) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(NULL, location)); + } + return static_cast(0); +#else + return HandleSehExceptionsInMethodIfSupported(object, method, location); +#endif // GTEST_HAS_EXCEPTIONS + } else { + return (object->*method)(); + } +} + +} // namespace internal + // Runs the test and updates the test result. void Test::Run() { if (!HasSameFixtureClass()) return; internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); -#if GTEST_HAS_SEH - // Catch SEH-style exceptions. impl->os_stack_trace_getter()->UponLeavingGTest(); - __try { - SetUp(); - } __except(internal::UnitTestOptions::GTestShouldProcessSEH( - GetExceptionCode())) { - AddExceptionThrownFailure(GetExceptionCode(), "SetUp()"); - } - - // We will run the test only if SetUp() had no fatal failure. - if (!HasFatalFailure()) { - impl->os_stack_trace_getter()->UponLeavingGTest(); - __try { - TestBody(); - } __except(internal::UnitTestOptions::GTestShouldProcessSEH( - GetExceptionCode())) { - AddExceptionThrownFailure(GetExceptionCode(), "the test body"); - } - } - - // However, we want to clean up as much as possible. Hence we will - // always call TearDown(), even if SetUp() or the test body has - // failed. - impl->os_stack_trace_getter()->UponLeavingGTest(); - __try { - TearDown(); - } __except(internal::UnitTestOptions::GTestShouldProcessSEH( - GetExceptionCode())) { - AddExceptionThrownFailure(GetExceptionCode(), "TearDown()"); - } - -#else // We are on a compiler or platform that doesn't support SEH. - impl->os_stack_trace_getter()->UponLeavingGTest(); - SetUp(); - + internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); // We will run the test only if SetUp() was successful. if (!HasFatalFailure()) { impl->os_stack_trace_getter()->UponLeavingGTest(); - TestBody(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TestBody, "the test body"); } // However, we want to clean up as much as possible. Hence we will // always call TearDown(), even if SetUp() or the test body has // failed. impl->os_stack_trace_getter()->UponLeavingGTest(); - TearDown(); -#endif // GTEST_HAS_SEH + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TearDown, "TearDown()"); } - // Returns true iff the current test has a fatal failure. bool Test::HasFatalFailure() { return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); @@ -2118,22 +2184,28 @@ bool Test::HasNonfatalFailure() { // class TestInfo // Constructs a TestInfo object. It assumes ownership of the test factory -// object via impl_. +// object. +// TODO(vladl@google.com): Make a_test_case_name and a_name const string&'s +// to signify they cannot be NULLs. TestInfo::TestInfo(const char* a_test_case_name, const char* a_name, - const char* a_test_case_comment, - const char* a_comment, + const char* a_type_param, + const char* a_value_param, internal::TypeId fixture_class_id, - internal::TestFactoryBase* factory) { - impl_ = new internal::TestInfoImpl(this, a_test_case_name, a_name, - a_test_case_comment, a_comment, - fixture_class_id, factory); -} + internal::TestFactoryBase* factory) + : test_case_name_(a_test_case_name), + name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + value_param_(a_value_param ? new std::string(a_value_param) : NULL), + fixture_class_id_(fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory), + result_() {} // Destructs a TestInfo object. -TestInfo::~TestInfo() { - delete impl_; -} +TestInfo::~TestInfo() { delete factory_; } namespace internal { @@ -2144,10 +2216,10 @@ namespace internal { // // test_case_name: name of the test case // name: name of the test -// test_case_comment: a comment on the test case that will be included in -// the test output -// comment: a comment on the test that will be included in the -// test output +// type_param: the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param: text representation of the test's value parameter, +// or NULL if this is not a value-parameterized test. // fixture_class_id: ID of the test fixture class // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case @@ -2156,13 +2228,14 @@ namespace internal { // ownership of the factory object. TestInfo* MakeAndRegisterTestInfo( const char* test_case_name, const char* name, - const char* test_case_comment, const char* comment, + const char* type_param, + const char* value_param, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, TestFactoryBase* factory) { TestInfo* const test_info = - new TestInfo(test_case_name, name, test_case_comment, comment, + new TestInfo(test_case_name, name, type_param, value_param, fixture_class_id, factory); GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); return test_info; @@ -2189,41 +2262,6 @@ void ReportInvalidTestCaseType(const char* test_case_name, } // namespace internal -// Returns the test case name. -const char* TestInfo::test_case_name() const { - return impl_->test_case_name(); -} - -// Returns the test name. -const char* TestInfo::name() const { - return impl_->name(); -} - -// Returns the test case comment. -const char* TestInfo::test_case_comment() const { - return impl_->test_case_comment(); -} - -// Returns the test comment. -const char* TestInfo::comment() const { - return impl_->comment(); -} - -// Returns true if this test should run. -bool TestInfo::should_run() const { return impl_->should_run(); } - -// Returns true if this test matches the user-specified filter. -bool TestInfo::matches_filter() const { return impl_->matches_filter(); } - -// Returns the result of the test. -const TestResult* TestInfo::result() const { return impl_->result(); } - -// Increments the number of death tests encountered in this test so -// far. -int TestInfo::increment_death_test_count() { - return impl_->result()->increment_death_test_count(); -} - namespace internal { // This method expands all parameterized tests registered with macros TEST_P @@ -2238,70 +2276,54 @@ void UnitTestImpl::RegisterParameterizedTests() { #endif } +} // namespace internal + // Creates the test object, runs it, records its result, and then // deletes it. -void TestInfoImpl::Run() { +void TestInfo::Run() { if (!should_run_) return; // Tells UnitTest where to store test result. - UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_info(parent_); + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(this); TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); // Notifies the unit test event listeners that a test is about to start. - repeater->OnTestStart(*parent_); + repeater->OnTestStart(*this); - const TimeInMillis start = GetTimeInMillis(); + const TimeInMillis start = internal::GetTimeInMillis(); impl->os_stack_trace_getter()->UponLeavingGTest(); -#if GTEST_HAS_SEH - // Catch SEH-style exceptions. - Test* test = NULL; - - __try { - // Creates the test object. - test = factory_->CreateTest(); - } __except(internal::UnitTestOptions::GTestShouldProcessSEH( - GetExceptionCode())) { - AddExceptionThrownFailure(GetExceptionCode(), - "the test fixture's constructor"); - return; - } -#else // We are on a compiler or platform that doesn't support SEH. - - // TODO(wan): If test->Run() throws, test won't be deleted. This is - // not a problem now as we don't use exceptions. If we were to - // enable exceptions, we should revise the following to be - // exception-safe. // Creates the test object. - Test* test = factory_->CreateTest(); -#endif // GTEST_HAS_SEH + Test* const test = internal::HandleExceptionsInMethodIfSupported( + factory_, &internal::TestFactoryBase::CreateTest, + "the test fixture's constructor"); - // Runs the test only if the constructor of the test fixture didn't - // generate a fatal failure. - if (!Test::HasFatalFailure()) { + // Runs the test only if the test object was created and its + // constructor didn't generate a fatal failure. + if ((test != NULL) && !Test::HasFatalFailure()) { + // This doesn't throw as all user code that can throw are wrapped into + // exception handling code. test->Run(); } // Deletes the test object. impl->os_stack_trace_getter()->UponLeavingGTest(); - delete test; - test = NULL; + internal::HandleExceptionsInMethodIfSupported( + test, &Test::DeleteSelf_, "the test fixture's destructor"); - result_.set_elapsed_time(GetTimeInMillis() - start); + result_.set_elapsed_time(internal::GetTimeInMillis() - start); // Notifies the unit test event listener that a test has just finished. - repeater->OnTestEnd(*parent_); + repeater->OnTestEnd(*this); // Tells UnitTest to stop associating assertion results to this // test. impl->set_current_test_info(NULL); } -} // namespace internal - // class TestCase // Gets the number of successful tests in this test case. @@ -2333,13 +2355,15 @@ int TestCase::total_test_count() const { // Arguments: // // name: name of the test case +// a_type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case -TestCase::TestCase(const char* a_name, const char* a_comment, +TestCase::TestCase(const char* a_name, const char* a_type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) : name_(a_name), - comment_(a_comment), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), set_up_tc_(set_up_tc), tear_down_tc_(tear_down_tc), should_run_(false), @@ -2384,45 +2408,26 @@ void TestCase::Run() { repeater->OnTestCaseStart(*this); impl->os_stack_trace_getter()->UponLeavingGTest(); - set_up_tc_(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); const internal::TimeInMillis start = internal::GetTimeInMillis(); for (int i = 0; i < total_test_count(); i++) { - GetMutableTestInfo(i)->impl()->Run(); + GetMutableTestInfo(i)->Run(); } elapsed_time_ = internal::GetTimeInMillis() - start; impl->os_stack_trace_getter()->UponLeavingGTest(); - tear_down_tc_(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); + repeater->OnTestCaseEnd(*this); impl->set_current_test_case(NULL); } // Clears the results of all tests in this test case. void TestCase::ClearResult() { - ForEach(test_info_list_, internal::TestInfoImpl::ClearTestResult); -} - -// Returns true iff test passed. -bool TestCase::TestPassed(const TestInfo * test_info) { - const internal::TestInfoImpl* const impl = test_info->impl(); - return impl->should_run() && impl->result()->Passed(); -} - -// Returns true iff test failed. -bool TestCase::TestFailed(const TestInfo * test_info) { - const internal::TestInfoImpl* const impl = test_info->impl(); - return impl->should_run() && impl->result()->Failed(); -} - -// Returns true iff test is disabled. -bool TestCase::TestDisabled(const TestInfo * test_info) { - return test_info->impl()->is_disabled(); -} - -// Returns true if the given test should run. -bool TestCase::ShouldRunTest(const TestInfo *test_info) { - return test_info->impl()->should_run(); + ForEach(test_info_list_, TestInfo::ClearTestResult); } // Shuffles the tests in this test case. @@ -2475,9 +2480,9 @@ static const char * TestPartResultTypeToString(TestPartResult::Type type) { #else return "Failure\n"; #endif + default: + return "Unknown result type"; } - - return "Unknown result type"; } // Prints a TestPartResult to a String. @@ -2563,6 +2568,7 @@ bool ShouldUseColor(bool stdout_is_tty) { String::CStringEquals(term, "xterm") || String::CStringEquals(term, "xterm-color") || String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "screen") || String::CStringEquals(term, "linux") || String::CStringEquals(term, "cygwin"); return stdout_is_tty && term_supports_color; @@ -2628,6 +2634,23 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_end(args); } +void PrintFullTestCommentIfPresent(const TestInfo& test_info) { + const char* const type_param = test_info.type_param(); + const char* const value_param = test_info.value_param(); + + if (type_param != NULL || value_param != NULL) { + printf(", where "); + if (type_param != NULL) { + printf("TypeParam = %s", type_param); + if (value_param != NULL) + printf(" and "); + } + if (value_param != NULL) { + printf("GetParam() = %s", value_param); + } + } +} + // This class implements the TestEventListener interface. // // Class PrettyUnitTestResultPrinter is copyable. @@ -2675,9 +2698,10 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart( } if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); ColoredPrintf(COLOR_YELLOW, - "Note: This is test shard %s of %s.\n", - internal::posix::GetEnv(kTestShardIndex), + "Note: This is test shard %d of %s.\n", + static_cast(shard_index) + 1, internal::posix::GetEnv(kTestTotalShards)); } @@ -2707,10 +2731,10 @@ void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); ColoredPrintf(COLOR_GREEN, "[----------] "); printf("%s from %s", counts.c_str(), test_case_name_.c_str()); - if (test_case.comment()[0] == '\0') { + if (test_case.type_param() == NULL) { printf("\n"); } else { - printf(", where %s\n", test_case.comment()); + printf(", where TypeParam = %s\n", test_case.type_param()); } fflush(stdout); } @@ -2718,11 +2742,7 @@ void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { ColoredPrintf(COLOR_GREEN, "[ RUN ] "); PrintTestName(test_case_name_.c_str(), test_info.name()); - if (test_info.comment()[0] == '\0') { - printf("\n"); - } else { - printf(", where %s\n", test_info.comment()); - } + printf("\n"); fflush(stdout); } @@ -2745,6 +2765,9 @@ void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { ColoredPrintf(COLOR_RED, "[ FAILED ] "); } PrintTestName(test_case_name_.c_str(), test_info.name()); + if (test_info.result()->Failed()) + PrintFullTestCommentIfPresent(test_info); + if (GTEST_FLAG(print_time)) { printf(" (%s ms)\n", internal::StreamableToString( test_info.result()->elapsed_time()).c_str()); @@ -2793,21 +2816,14 @@ void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { } ColoredPrintf(COLOR_RED, "[ FAILED ] "); printf("%s.%s", test_case.name(), test_info.name()); - if (test_case.comment()[0] != '\0' || - test_info.comment()[0] != '\0') { - printf(", where %s", test_case.comment()); - if (test_case.comment()[0] != '\0' && - test_info.comment()[0] != '\0') { - printf(" and "); - } - } - printf("%s\n", test_info.comment()); + PrintFullTestCommentIfPresent(test_info); + printf("\n"); } } } - void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, - int /*iteration*/) { +void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { ColoredPrintf(COLOR_GREEN, "[==========] "); printf("%s from %s ran.", FormatTestCount(unit_test.test_to_run_count()).c_str(), @@ -2987,7 +3003,7 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener { static String EscapeXml(const char* str, bool is_attribute); // Returns the given string with all characters invalid in XML removed. - static String RemoveInvalidXmlCharacters(const char* str); + static string RemoveInvalidXmlCharacters(const string& str); // Convenience wrapper around EscapeXml when str is an attribute value. static String EscapeXmlAttribute(const char* str) { @@ -3121,17 +3137,14 @@ String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) { // Returns the given string with all characters invalid in XML removed. // Currently invalid characters are dropped from the string. An // alternative is to replace them with certain characters such as . or ?. -String XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const char* str) { - char* const output = new char[strlen(str) + 1]; - char* appender = output; - for (char ch = *str; ch != '\0'; ch = *++str) - if (IsValidXmlCharacter(ch)) - *appender++ = ch; - *appender = '\0'; +string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const string& str) { + string output; + output.reserve(str.size()); + for (string::const_iterator it = str.begin(); it != str.end(); ++it) + if (IsValidXmlCharacter(*it)) + output.push_back(*it); - String ret_value(output); - delete[] output; - return ret_value; + return output; } // The following routines generate an XML representation of a UnitTest @@ -3184,8 +3197,18 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, const TestInfo& test_info) { const TestResult& result = *test_info.result(); *stream << " "; - const String message = RemoveInvalidXmlCharacters(String::Format( - "%s:%d\n%s", - part.file_name(), part.line_number(), - part.message()).c_str()); - OutputXmlCDataSection(stream, message.c_str()); + const string location = internal::FormatCompilerIndependentFileLocation( + part.file_name(), part.line_number()); + const string message = location + "\n" + part.message(); + OutputXmlCDataSection(stream, + RemoveInvalidXmlCharacters(message).c_str()); *stream << "\n"; } } @@ -3230,9 +3253,9 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, "errors=\"0\" time=\"%s\">\n", FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str()); for (int i = 0; i < test_case.total_test_count(); ++i) { - StrStream stream; + ::std::stringstream stream; OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i)); - fprintf(out, "%s", StrStreamToString(&stream).c_str()); + fprintf(out, "%s", StringStreamToString(&stream).c_str()); } fprintf(out, " \n"); } @@ -3272,6 +3295,182 @@ String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( // End XmlUnitTestResultPrinter +#if GTEST_CAN_STREAM_RESULTS_ + +// Streams test results to the given port on the given host machine. +class StreamingListener : public EmptyTestEventListener { + public: + // Escapes '=', '&', '%', and '\n' characters in str as "%xx". + static string UrlEncode(const char* str); + + StreamingListener(const string& host, const string& port) + : sockfd_(-1), host_name_(host), port_num_(port) { + MakeConnection(); + Send("gtest_streaming_protocol_version=1.0\n"); + } + + virtual ~StreamingListener() { + if (sockfd_ != -1) + CloseConnection(); + } + + void OnTestProgramStart(const UnitTest& /* unit_test */) { + Send("event=TestProgramStart\n"); + } + + void OnTestProgramEnd(const UnitTest& unit_test) { + // Note that Google Test current only report elapsed time for each + // test iteration, not for the entire test program. + Send(String::Format("event=TestProgramEnd&passed=%d\n", + unit_test.Passed())); + + // Notify the streaming server to stop. + CloseConnection(); + } + + void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { + Send(String::Format("event=TestIterationStart&iteration=%d\n", + iteration)); + } + + void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { + Send(String::Format("event=TestIterationEnd&passed=%d&elapsed_time=%sms\n", + unit_test.Passed(), + StreamableToString(unit_test.elapsed_time()).c_str())); + } + + void OnTestCaseStart(const TestCase& test_case) { + Send(String::Format("event=TestCaseStart&name=%s\n", test_case.name())); + } + + void OnTestCaseEnd(const TestCase& test_case) { + Send(String::Format("event=TestCaseEnd&passed=%d&elapsed_time=%sms\n", + test_case.Passed(), + StreamableToString(test_case.elapsed_time()).c_str())); + } + + void OnTestStart(const TestInfo& test_info) { + Send(String::Format("event=TestStart&name=%s\n", test_info.name())); + } + + void OnTestEnd(const TestInfo& test_info) { + Send(String::Format( + "event=TestEnd&passed=%d&elapsed_time=%sms\n", + (test_info.result())->Passed(), + StreamableToString((test_info.result())->elapsed_time()).c_str())); + } + + void OnTestPartResult(const TestPartResult& test_part_result) { + const char* file_name = test_part_result.file_name(); + if (file_name == NULL) + file_name = ""; + Send(String::Format("event=TestPartResult&file=%s&line=%d&message=", + UrlEncode(file_name).c_str(), + test_part_result.line_number())); + Send(UrlEncode(test_part_result.message()) + "\n"); + } + + private: + // Creates a client socket and connects to the server. + void MakeConnection(); + + // Closes the socket. + void CloseConnection() { + GTEST_CHECK_(sockfd_ != -1) + << "CloseConnection() can be called only when there is a connection."; + + close(sockfd_); + sockfd_ = -1; + } + + // Sends a string to the socket. + void Send(const string& message) { + GTEST_CHECK_(sockfd_ != -1) + << "Send() can be called only when there is a connection."; + + const int len = static_cast(message.length()); + if (write(sockfd_, message.c_str(), len) != len) { + GTEST_LOG_(WARNING) + << "stream_result_to: failed to stream to " + << host_name_ << ":" << port_num_; + } + } + + int sockfd_; // socket file descriptor + const string host_name_; + const string port_num_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); +}; // class StreamingListener + +// Checks if str contains '=', '&', '%' or '\n' characters. If yes, +// replaces them by "%xx" where xx is their hexadecimal value. For +// example, replaces "=" with "%3D". This algorithm is O(strlen(str)) +// in both time and space -- important as the input str may contain an +// arbitrarily long test failure message and stack trace. +string StreamingListener::UrlEncode(const char* str) { + string result; + result.reserve(strlen(str) + 1); + for (char ch = *str; ch != '\0'; ch = *++str) { + switch (ch) { + case '%': + case '=': + case '&': + case '\n': + result.append(String::Format("%%%02x", static_cast(ch))); + break; + default: + result.push_back(ch); + break; + } + } + return result; +} + +void StreamingListener::MakeConnection() { + GTEST_CHECK_(sockfd_ == -1) + << "MakeConnection() can't be called when there is already a connection."; + + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. + hints.ai_socktype = SOCK_STREAM; + addrinfo* servinfo = NULL; + + // Use the getaddrinfo() to get a linked list of IP addresses for + // the given host name. + const int error_num = getaddrinfo( + host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); + if (error_num != 0) { + GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " + << gai_strerror(error_num); + } + + // Loop through all the results and connect to the first we can. + for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; + cur_addr = cur_addr->ai_next) { + sockfd_ = socket( + cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); + if (sockfd_ != -1) { + // Connect the client socket to the server socket. + if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { + close(sockfd_); + sockfd_ = -1; + } + } + } + + freeaddrinfo(servinfo); // all done with this structure + + if (sockfd_ == -1) { + GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " + << host_name_ << ":" << port_num_; + } +} + +// End of class Streaming Listener +#endif // GTEST_CAN_STREAM_RESULTS__ + // Class ScopedTrace // Pushes the given source file location and message onto a per-thread @@ -3512,19 +3711,6 @@ Environment* UnitTest::AddEnvironment(Environment* env) { return env; } -#if GTEST_HAS_EXCEPTIONS -// A failed Google Test assertion will throw an exception of this type -// when exceptions are enabled. We derive it from std::runtime_error, -// which is for errors presumably detectable only at run time. Since -// std::runtime_error inherits from std::exception, many testing -// frameworks know how to extract and print the message inside it. -class GoogleTestFailureException : public ::std::runtime_error { - public: - explicit GoogleTestFailureException(const TestPartResult& failure) - : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} -}; -#endif - // Adds a TestPartResult to the current TestResult object. All Google Test // assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call // this to report their results. The user code should use the @@ -3601,31 +3787,34 @@ void UnitTest::RecordPropertyForCurrentTest(const char* key, // We don't protect this under mutex_, as we only support calling it // from the main thread. int UnitTest::Run() { -#if GTEST_HAS_SEH - // Catch SEH-style exceptions. + // Captures the value of GTEST_FLAG(catch_exceptions). This value will be + // used for the duration of the program. + impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); +#if GTEST_HAS_SEH const bool in_death_test_child_process = internal::GTEST_FLAG(internal_run_death_test).length() > 0; // Either the user wants Google Test to catch exceptions thrown by the // tests or this is executing in the context of death test child // process. In either case the user does not want to see pop-up dialogs - // about crashes - they are expected.. - if (GTEST_FLAG(catch_exceptions) || in_death_test_child_process) { -#if !GTEST_OS_WINDOWS_MOBILE + // about crashes - they are expected. + if (impl()->catch_exceptions() || in_death_test_child_process) { + +# if !GTEST_OS_WINDOWS_MOBILE // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); -#endif // !GTEST_OS_WINDOWS_MOBILE +# endif // !GTEST_OS_WINDOWS_MOBILE -#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE +# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE // Death test children can be terminated with _abort(). On Windows, // _abort() can show a dialog with a warning message. This forces the // abort message to go to stderr instead. _set_error_mode(_OUT_TO_STDERR); -#endif +# endif -#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE +# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE // In the debug version, Visual Studio pops up a separate dialog // offering a choice to debug the aborted program. We need to suppress // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement @@ -3641,22 +3830,15 @@ int UnitTest::Run() { _set_abort_behavior( 0x0, // Clear the following flags: _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. -#endif +# endif + } - - __try { - return impl_->RunAllTests(); - } __except(internal::UnitTestOptions::GTestShouldProcessSEH( - GetExceptionCode())) { - printf("Exception thrown with code 0x%x.\nFAIL\n", GetExceptionCode()); - fflush(stdout); - return 1; - } - -#else // We are on a compiler or platform that doesn't support SEH. - - return impl_->RunAllTests(); #endif // GTEST_HAS_SEH + + return internal::HandleExceptionsInMethodIfSupported( + impl(), + &internal::UnitTestImpl::RunAllTests, + "auxiliary test code (environments or event listeners)") ? 0 : 1; } // Returns the working directory when the first TEST() or TEST_F() was @@ -3724,12 +3906,12 @@ namespace internal { UnitTestImpl::UnitTestImpl(UnitTest* parent) : parent_(parent), #ifdef _MSC_VER -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4355) // Temporarily disables warning 4355 +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4355) // Temporarily disables warning 4355 // (using this in initializer). default_global_test_part_result_reporter_(this), default_per_thread_test_part_result_reporter_(this), -#pragma warning(pop) // Restores the warning state again. +# pragma warning(pop) // Restores the warning state again. #else default_global_test_part_result_reporter_(this), default_per_thread_test_part_result_reporter_(this), @@ -3750,13 +3932,13 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) post_flag_parse_init_performed_(false), random_seed_(0), // Will be overridden by the flag before first use. random_(0), // Will be reseeded before first use. -#if GTEST_HAS_DEATH_TEST elapsed_time_(0), +#if GTEST_HAS_DEATH_TEST internal_run_death_test_flag_(NULL), - death_test_factory_(new DefaultDeathTestFactory) { -#else - elapsed_time_(0) { -#endif // GTEST_HAS_DEATH_TEST + death_test_factory_(new DefaultDeathTestFactory), +#endif + // Will be overridden by the flag before first use. + catch_exceptions_(false) { listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); } @@ -3793,6 +3975,25 @@ void UnitTestImpl::ConfigureXmlOutput() { } } +#if GTEST_CAN_STREAM_RESULTS_ +// Initializes event listeners for streaming test results in String form. +// Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureStreamingOutput() { + const string& target = GTEST_FLAG(stream_result_to); + if (!target.empty()) { + const size_t pos = target.find(':'); + if (pos != string::npos) { + listeners()->Append(new StreamingListener(target.substr(0, pos), + target.substr(pos+1))); + } else { + printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", + target.c_str()); + fflush(stdout); + } + } +} +#endif // GTEST_CAN_STREAM_RESULTS_ + // Performs initialization dependent upon flag values obtained in // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest @@ -3816,6 +4017,11 @@ void UnitTestImpl::PostFlagParsingInit() { // Configures listeners for XML output. This makes it possible for users // to shut down the default XML output before invoking RUN_ALL_TESTS. ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Configures listeners for streaming test results to the specified server. + ConfigureStreamingOutput(); +#endif // GTEST_CAN_STREAM_RESULTS_ } } @@ -3850,10 +4056,12 @@ class TestCaseNameIs { // Arguments: // // test_case_name: name of the test case +// type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, - const char* comment, + const char* type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc) { // Can we find a TestCase with the given name? @@ -3866,7 +4074,7 @@ TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, // No. Let's create one. TestCase* const new_test_case = - new TestCase(test_case_name, comment, set_up_tc, tear_down_tc); + new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); // Is this a death test case? if (internal::UnitTestOptions::MatchesFilter(String(test_case_name), @@ -3893,27 +4101,26 @@ static void SetUpEnvironment(Environment* env) { env->SetUp(); } static void TearDownEnvironment(Environment* env) { env->TearDown(); } // Runs all tests in this UnitTest object, prints the result, and -// returns 0 if all tests are successful, or 1 otherwise. If any -// exception is thrown during a test on Windows, this test is -// considered to be failed, but the rest of the tests will still be -// run. (We disable exceptions on Linux and Mac OS X, so the issue -// doesn't apply there.) +// returns true if all tests are successful. If any exception is +// thrown during a test, the test is considered to be failed, but the +// rest of the tests will still be run. +// // When parameterized tests are enabled, it expands and registers // parameterized tests first in RegisterParameterizedTests(). // All other functions called from RunAllTests() may safely assume that // parameterized tests are ready to be counted and run. -int UnitTestImpl::RunAllTests() { +bool UnitTestImpl::RunAllTests() { // Makes sure InitGoogleTest() was called. if (!GTestIsInitialized()) { printf("%s", "\nThis test program did NOT call ::testing::InitGoogleTest " "before calling RUN_ALL_TESTS(). Please fix it.\n"); - return 1; + return false; } // Do not run any test if the --help flag was specified. if (g_help_flag) - return 0; + return true; // Repeats the call to the post-flag parsing initialization in case the // user didn't call InitGoogleTest. @@ -3945,7 +4152,7 @@ int UnitTestImpl::RunAllTests() { if (GTEST_FLAG(list_tests)) { // This must be called *after* FilterTests() has been called. ListTestsMatchingFilter(); - return 0; + return true; } random_seed_ = GTEST_FLAG(shuffle) ? @@ -3964,7 +4171,9 @@ int UnitTestImpl::RunAllTests() { // Repeats forever if the repeat count is negative. const bool forever = repeat < 0; for (int i = 0; forever || i != repeat; i++) { - ClearResult(); + // We want to preserve failures generated by ad-hoc test + // assertions executed before RUN_ALL_TESTS(). + ClearNonAdHocTestResult(); const TimeInMillis start = GetTimeInMillis(); @@ -4029,8 +4238,7 @@ int UnitTestImpl::RunAllTests() { repeater->OnTestProgramEnd(*parent_); - // Returns 0 if all tests passed, or 1 other wise. - return failed ? 1 : 0; + return !failed; } // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file @@ -4104,7 +4312,7 @@ bool ShouldShard(const char* total_shards_env, // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error // and aborts. -Int32 Int32FromEnvOrDie(const char* const var, Int32 default_val) { +Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { const char* str_val = posix::GetEnv(var); if (str_val == NULL) { return default_val; @@ -4160,12 +4368,12 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { kDisableTestFilter) || internal::UnitTestOptions::MatchesFilter(test_name, kDisableTestFilter); - test_info->impl()->set_is_disabled(is_disabled); + test_info->is_disabled_ = is_disabled; const bool matches_filter = internal::UnitTestOptions::FilterMatchesTest(test_case_name, test_name); - test_info->impl()->set_matches_filter(matches_filter); + test_info->matches_filter_ = matches_filter; const bool is_runnable = (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && @@ -4179,7 +4387,7 @@ int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { num_runnable_tests += is_runnable; num_selected_tests += is_selected; - test_info->impl()->set_should_run(is_selected); + test_info->should_run_ = is_selected; test_case->set_should_run(test_case->should_run() || is_selected); } } @@ -4195,7 +4403,7 @@ void UnitTestImpl::ListTestsMatchingFilter() { for (size_t j = 0; j < test_case->test_info_list().size(); j++) { const TestInfo* const test_info = test_case->test_info_list()[j]; - if (test_info->matches_filter()) { + if (test_info->matches_filter_) { if (!printed_test_case_name) { printed_test_case_name = true; printf("%s.\n", test_case->name()); @@ -4235,7 +4443,7 @@ OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { // the TestResult for the ad hoc test if no test is running. TestResult* UnitTestImpl::current_test_result() { return current_test_info_ ? - current_test_info_->impl()->result() : &ad_hoc_test_result_; + &(current_test_info_->result_) : &ad_hoc_test_result_; } // Shuffles all test cases, and the tests within each test case, @@ -4264,32 +4472,6 @@ void UnitTestImpl::UnshuffleTests() { } } -// TestInfoImpl constructor. The new instance assumes ownership of the test -// factory object. -TestInfoImpl::TestInfoImpl(TestInfo* parent, - const char* a_test_case_name, - const char* a_name, - const char* a_test_case_comment, - const char* a_comment, - TypeId a_fixture_class_id, - internal::TestFactoryBase* factory) : - parent_(parent), - test_case_name_(String(a_test_case_name)), - name_(String(a_name)), - test_case_comment_(String(a_test_case_comment)), - comment_(String(a_comment)), - fixture_class_id_(a_fixture_class_id), - should_run_(false), - is_disabled_(false), - matches_filter_(false), - factory_(factory) { -} - -// TestInfoImpl destructor. -TestInfoImpl::~TestInfoImpl() { - delete factory_; -} - // Returns the current OS stack trace as a String. // // The maximum number of stack frames to be included is specified by @@ -4307,8 +4489,8 @@ String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); } -// Used by the GTEST_HIDE_UNREACHABLE_CODE_ macro to suppress unreachable -// code warnings. +// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to +// suppress unreachable code warnings. namespace { class ClassUniqueToAlwaysTrue {}; } @@ -4520,6 +4702,10 @@ static const char kColorEncodedHelpMessage[] = GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" " Generate an XML report in the given directory or with the given file\n" " name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +#if GTEST_CAN_STREAM_RESULTS_ +" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" +" Stream test results to the given server.\n" +#endif // GTEST_CAN_STREAM_RESULTS_ "\n" "Assertion Behavior:\n" #if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS @@ -4530,10 +4716,9 @@ static const char kColorEncodedHelpMessage[] = " Turn assertion failures into debugger break-points.\n" " @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" " Turn assertion failures into C++ exceptions.\n" -#if GTEST_OS_WINDOWS -" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions@D\n" -" Suppress pop-ups caused by exceptions.\n" -#endif // GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" +" Do not report exceptions as test failures. Instead, allow them\n" +" to crash the program or throw a pop-up (on Windows).\n" "\n" "Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " "the corresponding\n" @@ -4583,7 +4768,10 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || ParseInt32Flag(arg, kStackTraceDepthFlag, >EST_FLAG(stack_trace_depth)) || - ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)) + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, + >EST_FLAG(throw_on_failure)) ) { // Yes. Shift the remainder of the argv list left by one. Note // that argv has (*argc + 1) elements, the last one always being @@ -4641,10 +4829,12 @@ void InitGoogleTestImpl(int* argc, CharType** argv) { internal::g_executable_path = internal::StreamableToString(argv[0]); #if GTEST_HAS_DEATH_TEST + g_argvs.clear(); for (int i = 0; i != *argc; i++) { g_argvs.push_back(StreamableToString(argv[i])); } + #endif // GTEST_HAS_DEATH_TEST ParseGoogleTestFlagsOnly(argc, argv); diff --git a/utils/unittest/googletest/include/gtest/gtest-death-test.h b/utils/unittest/googletest/include/gtest/gtest-death-test.h index 121dc1fb5ac5..a27883f0a4dc 100644 --- a/utils/unittest/googletest/include/gtest/gtest-death-test.h +++ b/utils/unittest/googletest/include/gtest/gtest-death-test.h @@ -38,7 +38,7 @@ #ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ -#include +#include "gtest/internal/gtest-death-test-internal.h" namespace testing { @@ -154,24 +154,24 @@ GTEST_DECLARE_string_(death_test_style); // Asserts that a given statement causes the program to exit, with an // integer exit status that satisfies predicate, and emitting error output // that matches regex. -#define ASSERT_EXIT(statement, predicate, regex) \ - GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) +# define ASSERT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) // Like ASSERT_EXIT, but continues on to successive tests in the // test case, if any: -#define EXPECT_EXIT(statement, predicate, regex) \ - GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) +# define EXPECT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) // Asserts that a given statement causes the program to exit, either by // explicitly exiting with a nonzero exit code or being killed by a // signal, and emitting error output that matches regex. -#define ASSERT_DEATH(statement, regex) \ - ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) +# define ASSERT_DEATH(statement, regex) \ + ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Like ASSERT_DEATH, but continues on to successive tests in the // test case, if any: -#define EXPECT_DEATH(statement, regex) \ - EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) +# define EXPECT_DEATH(statement, regex) \ + EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: @@ -187,7 +187,7 @@ class GTEST_API_ ExitedWithCode { const int exit_code_; }; -#if !GTEST_OS_WINDOWS +# if !GTEST_OS_WINDOWS // Tests that an exit code describes an exit due to termination by a // given signal. class GTEST_API_ KilledBySignal { @@ -197,7 +197,7 @@ class GTEST_API_ KilledBySignal { private: const int signum_; }; -#endif // !GTEST_OS_WINDOWS +# endif // !GTEST_OS_WINDOWS // EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. // The death testing framework causes this to have interesting semantics, @@ -242,23 +242,23 @@ class GTEST_API_ KilledBySignal { // EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); // }, "death"); // -#ifdef NDEBUG +# ifdef NDEBUG -#define EXPECT_DEBUG_DEATH(statement, regex) \ +# define EXPECT_DEBUG_DEATH(statement, regex) \ do { statement; } while (::testing::internal::AlwaysFalse()) -#define ASSERT_DEBUG_DEATH(statement, regex) \ +# define ASSERT_DEBUG_DEATH(statement, regex) \ do { statement; } while (::testing::internal::AlwaysFalse()) -#else +# else -#define EXPECT_DEBUG_DEATH(statement, regex) \ +# define EXPECT_DEBUG_DEATH(statement, regex) \ EXPECT_DEATH(statement, regex) -#define ASSERT_DEBUG_DEATH(statement, regex) \ +# define ASSERT_DEBUG_DEATH(statement, regex) \ ASSERT_DEATH(statement, regex) -#endif // NDEBUG for EXPECT_DEBUG_DEATH +# endif // NDEBUG for EXPECT_DEBUG_DEATH #endif // GTEST_HAS_DEATH_TEST // EXPECT_DEATH_IF_SUPPORTED(statement, regex) and @@ -267,14 +267,14 @@ class GTEST_API_ KilledBySignal { // useful when you are combining death test assertions with normal test // assertions in one test. #if GTEST_HAS_DEATH_TEST -#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ EXPECT_DEATH(statement, regex) -#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ ASSERT_DEATH(statement, regex) #else -#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) -#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) #endif diff --git a/utils/unittest/googletest/include/gtest/gtest-message.h b/utils/unittest/googletest/include/gtest/gtest-message.h index f135b69427fe..9b7142f32076 100644 --- a/utils/unittest/googletest/include/gtest/gtest-message.h +++ b/utils/unittest/googletest/include/gtest/gtest-message.h @@ -48,8 +48,8 @@ #include -#include -#include +#include "gtest/internal/gtest-string.h" +#include "gtest/internal/gtest-internal.h" namespace testing { @@ -58,7 +58,7 @@ namespace testing { // Typical usage: // // 1. You stream a bunch of values to a Message object. -// It will remember the text in a StrStream. +// It will remember the text in a stringstream. // 2. Then you stream the Message object to an ostream. // This causes the text in the Message to be streamed // to the ostream. @@ -74,7 +74,7 @@ namespace testing { // Message is not intended to be inherited from. In particular, its // destructor is not virtual. // -// Note that StrStream behaves differently in gcc and in MSVC. You +// Note that stringstream behaves differently in gcc and in MSVC. You // can stream a NULL char pointer to it in the former, but not in the // latter (it causes an access violation if you do). The Message // class hides this difference by treating a NULL char pointer as @@ -87,27 +87,26 @@ class GTEST_API_ Message { public: // Constructs an empty Message. - // We allocate the StrStream separately because it otherwise each use of + // We allocate the stringstream separately because otherwise each use of // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's // stack frame leading to huge stack frames in some cases; gcc does not reuse // the stack space. - Message() : ss_(new internal::StrStream) { + Message() : ss_(new ::std::stringstream) { // By default, we want there to be enough precision when printing // a double to a Message. *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); } // Copy constructor. - Message(const Message& msg) : ss_(new internal::StrStream) { // NOLINT + Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT *ss_ << msg.GetString(); } // Constructs a Message from a C-string. - explicit Message(const char* str) : ss_(new internal::StrStream) { + explicit Message(const char* str) : ss_(new ::std::stringstream) { *ss_ << str; } - ~Message() { delete ss_; } #if GTEST_OS_SYMBIAN // Streams a value (either a pointer or not) to this object. template @@ -119,7 +118,7 @@ class GTEST_API_ Message { // Streams a non-pointer value to this object. template inline Message& operator <<(const T& val) { - ::GTestStreamToHelper(ss_, val); + ::GTestStreamToHelper(ss_.get(), val); return *this; } @@ -141,7 +140,7 @@ class GTEST_API_ Message { if (pointer == NULL) { *ss_ << "(null)"; } else { - ::GTestStreamToHelper(ss_, pointer); + ::GTestStreamToHelper(ss_.get(), pointer); } return *this; } @@ -189,10 +188,11 @@ class GTEST_API_ Message { // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. internal::String GetString() const { - return internal::StrStreamToString(ss_); + return internal::StringStreamToString(ss_.get()); } private: + #if GTEST_OS_SYMBIAN // These are needed as the Nokia Symbian Compiler cannot decide between // const T& and const T* in a function template. The Nokia compiler _can_ @@ -203,17 +203,17 @@ class GTEST_API_ Message { if (pointer == NULL) { *ss_ << "(null)"; } else { - ::GTestStreamToHelper(ss_, pointer); + ::GTestStreamToHelper(ss_.get(), pointer); } } template inline void StreamHelper(internal::false_type /*dummy*/, const T& value) { - ::GTestStreamToHelper(ss_, value); + ::GTestStreamToHelper(ss_.get(), value); } #endif // GTEST_OS_SYMBIAN // We'll hold the text streamed to this object here. - internal::StrStream* const ss_; + const internal::scoped_ptr< ::std::stringstream> ss_; // We declare (but don't implement) this to prevent the compiler // from implementing the assignment operator. diff --git a/utils/unittest/googletest/include/gtest/gtest-param-test.h b/utils/unittest/googletest/include/gtest/gtest-param-test.h index 3184d07ba0e3..b1f8bb961022 100644 --- a/utils/unittest/googletest/include/gtest/gtest-param-test.h +++ b/utils/unittest/googletest/include/gtest/gtest-param-test.h @@ -1,4 +1,6 @@ -// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! +// This file was GENERATED by command: +// pump.py gtest-param-test.h.pump +// DO NOT EDIT BY HAND!!! // Copyright 2008, Google Inc. // All rights reserved. @@ -48,10 +50,12 @@ #if 0 // To write value-parameterized tests, first you should define a fixture -// class. It must be derived from testing::TestWithParam, where T is -// the type of your parameter values. TestWithParam is itself derived -// from testing::Test. T can be any copyable type. If it's a raw pointer, -// you are responsible for managing the lifespan of the pointed values. +// class. It is usually derived from testing::TestWithParam (see below for +// another inheritance scheme that's sometimes useful in more complicated +// class hierarchies), where the type of your parameter values. +// TestWithParam is itself derived from testing::Test. T can be any +// copyable type. If it's a raw pointer, you are responsible for managing the +// lifespan of the pointed values. class FooTest : public ::testing::TestWithParam { // You can implement all the usual class fixture members here. @@ -146,20 +150,46 @@ INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); // In the future, we plan to publish the API for defining new parameter // generators. But for now this interface remains part of the internal // implementation and is subject to change. +// +// +// A parameterized test fixture must be derived from testing::Test and from +// testing::WithParamInterface, where T is the type of the parameter +// values. Inheriting from TestWithParam satisfies that requirement because +// TestWithParam inherits from both Test and WithParamInterface. In more +// complicated hierarchies, however, it is occasionally useful to inherit +// separately from Test and WithParamInterface. For example: + +class BaseTest : public ::testing::Test { + // You can inherit all the usual members for a non-parameterized test + // fixture here. +}; + +class DerivedTest : public BaseTest, public ::testing::WithParamInterface { + // The usual test fixture members go here too. +}; + +TEST_F(BaseTest, HasFoo) { + // This is an ordinary non-parameterized test. +} + +TEST_P(DerivedTest, DoesBlah) { + // GetParam works just the same here as if you inherit from TestWithParam. + EXPECT_TRUE(foo.Blah(GetParam())); +} #endif // 0 -#include +#include "gtest/internal/gtest-port.h" #if !GTEST_OS_SYMBIAN -#include +# include #endif // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. -#include -#include +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-param-util.h" #if GTEST_HAS_PARAM_TEST @@ -275,11 +305,10 @@ internal::ParamGenerator Range(T start, T end) { // template internal::ParamGenerator< - typename ::std::iterator_traits::value_type> ValuesIn( - ForwardIterator begin, - ForwardIterator end) { - typedef typename ::std::iterator_traits::value_type - ParamType; + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end) { + typedef typename ::testing::internal::IteratorTraits + ::value_type ParamType; return internal::ParamGenerator( new internal::ValuesInIteratorRangeGenerator(begin, end)); } @@ -1197,7 +1226,7 @@ inline internal::ParamGenerator Bool() { return Values(false, true); } -#if GTEST_HAS_COMBINE +# if GTEST_HAS_COMBINE // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. // @@ -1349,11 +1378,11 @@ internal::CartesianProductHolder10( g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); } -#endif // GTEST_HAS_COMBINE +# endif // GTEST_HAS_COMBINE -#define TEST_P(test_case_name, test_name) \ +# define TEST_P(test_case_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ : public test_case_name { \ public: \ @@ -1379,7 +1408,7 @@ internal::CartesianProductHolder10 \ gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ int gtest_##prefix##test_case_name##_dummy_ = \ diff --git a/utils/unittest/googletest/include/gtest/gtest-printers.h b/utils/unittest/googletest/include/gtest/gtest-printers.h new file mode 100644 index 000000000000..9cbab3ff4be7 --- /dev/null +++ b/utils/unittest/googletest/include/gtest/gtest-printers.h @@ -0,0 +1,796 @@ +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// A user can teach this function how to print a class type T by +// defining either operator<<() or PrintTo() in the namespace that +// defines T. More specifically, the FIRST defined function in the +// following list will be used (assuming T is defined in namespace +// foo): +// +// 1. foo::PrintTo(const T&, ostream*) +// 2. operator<<(ostream&, const T&) defined in either foo or the +// global namespace. +// +// If none of the above is defined, it will print the debug string of +// the value if it is a protocol buffer, or print the raw bytes in the +// value otherwise. +// +// To aid debugging: when T is a reference type, the address of the +// value is also printed; when T is a (const) char pointer, both the +// pointer value and the NUL-terminated string it points to are +// printed. +// +// We also provide some convenient wrappers: +// +// // Prints a value to a string. For a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// std::string ::testing::PrintToString(const T& value); +// +// // Prints a value tersely: for a reference type, the referenced +// // value (but not the address) is printed; for a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// void ::testing::internal::UniversalTersePrint(const T& value, ostream*); +// +// // Prints value using the type inferred by the compiler. The difference +// // from UniversalTersePrint() is that this function prints both the +// // pointer and the NUL-terminated string for a (const or not) char pointer. +// void ::testing::internal::UniversalPrint(const T& value, ostream*); +// +// // Prints the fields of a tuple tersely to a string vector, one +// // element for each field. Tuple support must be enabled in +// // gtest-port.h. +// std::vector UniversalTersePrintTupleFieldsToStrings( +// const Tuple& value); +// +// Known limitation: +// +// The print primitives print the elements of an STL-style container +// using the compiler-inferred type of *iter where iter is a +// const_iterator of the container. When const_iterator is an input +// iterator but not a forward iterator, this inferred type may not +// match value_type, and the print output may be incorrect. In +// practice, this is rarely a problem as for most containers +// const_iterator is a forward iterator. We'll fix this if there's an +// actual need for it. Note that this fix cannot rely on value_type +// being defined as many user-defined container types don't have +// value_type. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ + +#include // NOLINT +#include +#include +#include +#include +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-internal.h" + +namespace testing { + +// Definitions in the 'internal' and 'internal2' name spaces are +// subject to change without notice. DO NOT USE THEM IN USER CODE! +namespace internal2 { + +// Prints the given number of bytes in the given object to the given +// ostream. +GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, + size_t count, + ::std::ostream* os); + +// For selecting which printer to use when a given type has neither << +// nor PrintTo(). +enum TypeKind { + kProtobuf, // a protobuf type + kConvertibleToInteger, // a type implicitly convertible to BiggestInt + // (e.g. a named or unnamed enum type) + kOtherType // anything else +}; + +// TypeWithoutFormatter::PrintValue(value, os) is called +// by the universal printer to print a value of type T when neither +// operator<< nor PrintTo() is defined for T, where kTypeKind is the +// "kind" of T as defined by enum TypeKind. +template +class TypeWithoutFormatter { + public: + // This default version is called when kTypeKind is kOtherType. + static void PrintValue(const T& value, ::std::ostream* os) { + PrintBytesInObjectTo(reinterpret_cast(&value), + sizeof(value), os); + } +}; + +// We print a protobuf using its ShortDebugString() when the string +// doesn't exceed this many characters; otherwise we print it using +// DebugString() for better readability. +const size_t kProtobufOneLinerMaxLength = 50; + +template +class TypeWithoutFormatter { + public: + static void PrintValue(const T& value, ::std::ostream* os) { + const ::testing::internal::string short_str = value.ShortDebugString(); + const ::testing::internal::string pretty_str = + short_str.length() <= kProtobufOneLinerMaxLength ? + short_str : ("\n" + value.DebugString()); + *os << ("<" + pretty_str + ">"); + } +}; + +template +class TypeWithoutFormatter { + public: + // Since T has no << operator or PrintTo() but can be implicitly + // converted to BiggestInt, we print it as a BiggestInt. + // + // Most likely T is an enum type (either named or unnamed), in which + // case printing it as an integer is the desired behavior. In case + // T is not an enum, printing it as an integer is the best we can do + // given that it has no user-defined printer. + static void PrintValue(const T& value, ::std::ostream* os) { + const internal::BiggestInt kBigInt = value; + *os << kBigInt; + } +}; + +// Prints the given value to the given ostream. If the value is a +// protocol message, its debug string is printed; if it's an enum or +// of a type implicitly convertible to BiggestInt, it's printed as an +// integer; otherwise the bytes in the value are printed. This is +// what UniversalPrinter::Print() does when it knows nothing about +// type T and T has neither << operator nor PrintTo(). +// +// A user can override this behavior for a class type Foo by defining +// a << operator in the namespace where Foo is defined. +// +// We put this operator in namespace 'internal2' instead of 'internal' +// to simplify the implementation, as much code in 'internal' needs to +// use << in STL, which would conflict with our own << were it defined +// in 'internal'. +// +// Note that this operator<< takes a generic std::basic_ostream type instead of the more restricted std::ostream. If +// we define it to take an std::ostream instead, we'll get an +// "ambiguous overloads" compiler error when trying to print a type +// Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether +// operator<<(std::ostream&, const T&) or +// operator<<(std::basic_stream, const Foo&) is more +// specific. +template +::std::basic_ostream& operator<<( + ::std::basic_ostream& os, const T& x) { + TypeWithoutFormatter::value ? kProtobuf : + internal::ImplicitlyConvertible::value ? + kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); + return os; +} + +} // namespace internal2 +} // namespace testing + +// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up +// magic needed for implementing UniversalPrinter won't work. +namespace testing_internal { + +// Used to print a value that is not an STL-style container when the +// user doesn't define PrintTo() for it. +template +void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { + // With the following statement, during unqualified name lookup, + // testing::internal2::operator<< appears as if it was declared in + // the nearest enclosing namespace that contains both + // ::testing_internal and ::testing::internal2, i.e. the global + // namespace. For more details, refer to the C++ Standard section + // 7.3.4-1 [namespace.udir]. This allows us to fall back onto + // testing::internal2::operator<< in case T doesn't come with a << + // operator. + // + // We cannot write 'using ::testing::internal2::operator<<;', which + // gcc 3.3 fails to compile due to a compiler bug. + using namespace ::testing::internal2; // NOLINT + + // Assuming T is defined in namespace foo, in the next statement, + // the compiler will consider all of: + // + // 1. foo::operator<< (thanks to Koenig look-up), + // 2. ::operator<< (as the current namespace is enclosed in ::), + // 3. testing::internal2::operator<< (thanks to the using statement above). + // + // The operator<< whose type matches T best will be picked. + // + // We deliberately allow #2 to be a candidate, as sometimes it's + // impossible to define #1 (e.g. when foo is ::std, defining + // anything in it is undefined behavior unless you are a compiler + // vendor.). + *os << value; +} + +} // namespace testing_internal + +namespace testing { +namespace internal { + +// UniversalPrinter::Print(value, ostream_ptr) prints the given +// value to the given ostream. The caller must ensure that +// 'ostream_ptr' is not NULL, or the behavior is undefined. +// +// We define UniversalPrinter as a class template (as opposed to a +// function template), as we need to partially specialize it for +// reference types, which cannot be done with function templates. +template +class UniversalPrinter; + +template +void UniversalPrint(const T& value, ::std::ostream* os); + +// Used to print an STL-style container when the user doesn't define +// a PrintTo() for it. +template +void DefaultPrintTo(IsContainer /* dummy */, + false_type /* is not a pointer */, + const C& container, ::std::ostream* os) { + const size_t kMaxCount = 32; // The maximum number of elements to print. + *os << '{'; + size_t count = 0; + for (typename C::const_iterator it = container.begin(); + it != container.end(); ++it, ++count) { + if (count > 0) { + *os << ','; + if (count == kMaxCount) { // Enough has been printed. + *os << " ..."; + break; + } + } + *os << ' '; + // We cannot call PrintTo(*it, os) here as PrintTo() doesn't + // handle *it being a native array. + internal::UniversalPrint(*it, os); + } + + if (count > 0) { + *os << ' '; + } + *os << '}'; +} + +// Used to print a pointer that is neither a char pointer nor a member +// pointer, when the user doesn't define PrintTo() for it. (A member +// variable pointer or member function pointer doesn't really point to +// a location in the address space. Their representation is +// implementation-defined. Therefore they will be printed as raw +// bytes.) +template +void DefaultPrintTo(IsNotContainer /* dummy */, + true_type /* is a pointer */, + T* p, ::std::ostream* os) { + if (p == NULL) { + *os << "NULL"; + } else { + // C++ doesn't allow casting from a function pointer to any object + // pointer. + // + // IsTrue() silences warnings: "Condition is always true", + // "unreachable code". + if (IsTrue(ImplicitlyConvertible::value)) { + // T is not a function type. We just call << to print p, + // relying on ADL to pick up user-defined << for their pointer + // types, if any. + *os << p; + } else { + // T is a function type, so '*os << p' doesn't do what we want + // (it just prints p as bool). We want to print p as a const + // void*. However, we cannot cast it to const void* directly, + // even using reinterpret_cast, as earlier versions of gcc + // (e.g. 3.4.5) cannot compile the cast when p is a function + // pointer. Casting to UInt64 first solves the problem. + *os << reinterpret_cast( + reinterpret_cast(p)); + } + } +} + +// Used to print a non-container, non-pointer value when the user +// doesn't define PrintTo() for it. +template +void DefaultPrintTo(IsNotContainer /* dummy */, + false_type /* is not a pointer */, + const T& value, ::std::ostream* os) { + ::testing_internal::DefaultPrintNonContainerTo(value, os); +} + +// Prints the given value using the << operator if it has one; +// otherwise prints the bytes in it. This is what +// UniversalPrinter::Print() does when PrintTo() is not specialized +// or overloaded for type T. +// +// A user can override this behavior for a class type Foo by defining +// an overload of PrintTo() in the namespace where Foo is defined. We +// give the user this option as sometimes defining a << operator for +// Foo is not desirable (e.g. the coding style may prevent doing it, +// or there is already a << operator but it doesn't do what the user +// wants). +template +void PrintTo(const T& value, ::std::ostream* os) { + // DefaultPrintTo() is overloaded. The type of its first two + // arguments determine which version will be picked. If T is an + // STL-style container, the version for container will be called; if + // T is a pointer, the pointer version will be called; otherwise the + // generic version will be called. + // + // Note that we check for container types here, prior to we check + // for protocol message types in our operator<<. The rationale is: + // + // For protocol messages, we want to give people a chance to + // override Google Mock's format by defining a PrintTo() or + // operator<<. For STL containers, other formats can be + // incompatible with Google Mock's format for the container + // elements; therefore we check for container types here to ensure + // that our format is used. + // + // The second argument of DefaultPrintTo() is needed to bypass a bug + // in Symbian's C++ compiler that prevents it from picking the right + // overload between: + // + // PrintTo(const T& x, ...); + // PrintTo(T* x, ...); + DefaultPrintTo(IsContainerTest(0), is_pointer(), value, os); +} + +// The following list of PrintTo() overloads tells +// UniversalPrinter::Print() how to print standard types (built-in +// types, strings, plain arrays, and pointers). + +// Overloads for various char types. +GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); +GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); +inline void PrintTo(char c, ::std::ostream* os) { + // When printing a plain char, we always treat it as unsigned. This + // way, the output won't be affected by whether the compiler thinks + // char is signed or not. + PrintTo(static_cast(c), os); +} + +// Overloads for other simple built-in types. +inline void PrintTo(bool x, ::std::ostream* os) { + *os << (x ? "true" : "false"); +} + +// Overload for wchar_t type. +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its decimal code (except for L'\0'). +// The L'\0' char is printed as "L'\\0'". The decimal code is printed +// as signed integer when wchar_t is implemented by the compiler +// as a signed type and is printed as an unsigned integer when wchar_t +// is implemented as an unsigned type. +GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); + +// Overloads for C strings. +GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); +inline void PrintTo(char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} + +// signed/unsigned char is often used for representing binary data, so +// we print pointers to it as void* to be safe. +inline void PrintTo(const signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(const unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +inline void PrintTo(unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} + +// MSVC can be configured to define wchar_t as a typedef of unsigned +// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native +// type. When wchar_t is a typedef, defining an overload for const +// wchar_t* would cause unsigned short* be printed as a wide string, +// possibly causing invalid memory accesses. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Overloads for wide C strings +GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); +inline void PrintTo(wchar_t* s, ::std::ostream* os) { + PrintTo(ImplicitCast_(s), os); +} +#endif + +// Overload for C arrays. Multi-dimensional arrays are printed +// properly. + +// Prints the given number of elements in an array, without printing +// the curly braces. +template +void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { + UniversalPrint(a[0], os); + for (size_t i = 1; i != count; i++) { + *os << ", "; + UniversalPrint(a[i], os); + } +} + +// Overloads for ::string and ::std::string. +#if GTEST_HAS_GLOBAL_STRING +GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); +inline void PrintTo(const ::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); +inline void PrintTo(const ::std::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} + +// Overloads for ::wstring and ::std::wstring. +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_TR1_TUPLE +// Overload for ::std::tr1::tuple. Needed for printing function arguments, +// which are packed as tuples. + +// Helper function for printing a tuple. T must be instantiated with +// a tuple type. +template +void PrintTupleTo(const T& t, ::std::ostream* os); + +// Overloaded PrintTo() for tuples of various arities. We support +// tuples of up-to 10 fields. The following implementation works +// regardless of whether tr1::tuple is implemented using the +// non-standard variadic template feature or not. + +inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo(const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template +void PrintTo( + const ::std::tr1::tuple& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} +#endif // GTEST_HAS_TR1_TUPLE + +// Overload for std::pair. +template +void PrintTo(const ::std::pair& value, ::std::ostream* os) { + *os << '('; + // We cannot use UniversalPrint(value.first, os) here, as T1 may be + // a reference type. The same for printing value.second. + UniversalPrinter::Print(value.first, os); + *os << ", "; + UniversalPrinter::Print(value.second, os); + *os << ')'; +} + +// Implements printing a non-reference type T by letting the compiler +// pick the right overload of PrintTo() for T. +template +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4180) // Temporarily disables warning 4180. +#endif // _MSC_VER + + // Note: we deliberately don't call this PrintTo(), as that name + // conflicts with ::testing::internal::PrintTo in the body of the + // function. + static void Print(const T& value, ::std::ostream* os) { + // By default, ::testing::internal::PrintTo() is used for printing + // the value. + // + // Thanks to Koenig look-up, if T is a class and has its own + // PrintTo() function defined in its namespace, that function will + // be visible here. Since it is more specific than the generic ones + // in ::testing::internal, it will be picked by the compiler in the + // following statement - exactly what we want. + PrintTo(value, os); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif // _MSC_VER +}; + +// UniversalPrintArray(begin, len, os) prints an array of 'len' +// elements, starting at address 'begin'. +template +void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { + if (len == 0) { + *os << "{}"; + } else { + *os << "{ "; + const size_t kThreshold = 18; + const size_t kChunkSize = 8; + // If the array has more than kThreshold elements, we'll have to + // omit some details by printing only the first and the last + // kChunkSize elements. + // TODO(wan@google.com): let the user control the threshold using a flag. + if (len <= kThreshold) { + PrintRawArrayTo(begin, len, os); + } else { + PrintRawArrayTo(begin, kChunkSize, os); + *os << ", ..., "; + PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); + } + *os << " }"; + } +} +// This overload prints a (const) char array compactly. +GTEST_API_ void UniversalPrintArray(const char* begin, + size_t len, + ::std::ostream* os); + +// Implements printing an array type T[N]. +template +class UniversalPrinter { + public: + // Prints the given array, omitting some elements when there are too + // many. + static void Print(const T (&a)[N], ::std::ostream* os) { + UniversalPrintArray(a, N, os); + } +}; + +// Implements printing a reference type T&. +template +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4180) // Temporarily disables warning 4180. +#endif // _MSC_VER + + static void Print(const T& value, ::std::ostream* os) { + // Prints the address of the value. We use reinterpret_cast here + // as static_cast doesn't compile when T is a function type. + *os << "@" << reinterpret_cast(&value) << " "; + + // Then prints the value itself. + UniversalPrint(value, os); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif // _MSC_VER +}; + +// Prints a value tersely: for a reference type, the referenced value +// (but not the address) is printed; for a (const) char pointer, the +// NUL-terminated string (but not the pointer) is printed. +template +void UniversalTersePrint(const T& value, ::std::ostream* os) { + UniversalPrint(value, os); +} +inline void UniversalTersePrint(const char* str, ::std::ostream* os) { + if (str == NULL) { + *os << "NULL"; + } else { + UniversalPrint(string(str), os); + } +} +inline void UniversalTersePrint(char* str, ::std::ostream* os) { + UniversalTersePrint(static_cast(str), os); +} + +// Prints a value using the type inferred by the compiler. The +// difference between this and UniversalTersePrint() is that for a +// (const) char pointer, this prints both the pointer and the +// NUL-terminated string. +template +void UniversalPrint(const T& value, ::std::ostream* os) { + UniversalPrinter::Print(value, os); +} + +#if GTEST_HAS_TR1_TUPLE +typedef ::std::vector Strings; + +// This helper template allows PrintTo() for tuples and +// UniversalTersePrintTupleFieldsToStrings() to be defined by +// induction on the number of tuple fields. The idea is that +// TuplePrefixPrinter::PrintPrefixTo(t, os) prints the first N +// fields in tuple t, and can be defined in terms of +// TuplePrefixPrinter. + +// The inductive case. +template +struct TuplePrefixPrinter { + // Prints the first N fields of a tuple. + template + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { + TuplePrefixPrinter::PrintPrefixTo(t, os); + *os << ", "; + UniversalPrinter::type> + ::Print(::std::tr1::get(t), os); + } + + // Tersely prints the first N fields of a tuple to a string vector, + // one element for each field. + template + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { + TuplePrefixPrinter::TersePrintPrefixToStrings(t, strings); + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get(t), &ss); + strings->push_back(ss.str()); + } +}; + +// Base cases. +template <> +struct TuplePrefixPrinter<0> { + template + static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} + + template + static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} +}; +// We have to specialize the entire TuplePrefixPrinter<> class +// template here, even though the definition of +// TersePrintPrefixToStrings() is the same as the generic version, as +// Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't +// support specializing a method template of a class template. +template <> +struct TuplePrefixPrinter<1> { + template + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { + UniversalPrinter::type>:: + Print(::std::tr1::get<0>(t), os); + } + + template + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get<0>(t), &ss); + strings->push_back(ss.str()); + } +}; + +// Helper function for printing a tuple. T must be instantiated with +// a tuple type. +template +void PrintTupleTo(const T& t, ::std::ostream* os) { + *os << "("; + TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: + PrintPrefixTo(t, os); + *os << ")"; +} + +// Prints the fields of a tuple tersely to a string vector, one +// element for each field. See the comment before +// UniversalTersePrint() for how we define "tersely". +template +Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { + Strings result; + TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: + TersePrintPrefixToStrings(value, &result); + return result; +} +#endif // GTEST_HAS_TR1_TUPLE + +} // namespace internal + +template +::std::string PrintToString(const T& value) { + ::std::stringstream ss; + internal::UniversalTersePrint(value, &ss); + return ss.str(); +} + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ diff --git a/utils/unittest/googletest/include/gtest/gtest-spi.h b/utils/unittest/googletest/include/gtest/gtest-spi.h index c41da4844760..b226e5504895 100644 --- a/utils/unittest/googletest/include/gtest/gtest-spi.h +++ b/utils/unittest/googletest/include/gtest/gtest-spi.h @@ -35,7 +35,7 @@ #ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ #define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ -#include +#include "gtest/gtest.h" namespace testing { @@ -98,12 +98,12 @@ class GTEST_API_ SingleFailureChecker { // The constructor remembers the arguments. SingleFailureChecker(const TestPartResultArray* results, TestPartResult::Type type, - const char* substr); + const string& substr); ~SingleFailureChecker(); private: const TestPartResultArray* const results_; const TestPartResult::Type type_; - const String substr_; + const string substr_; GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); }; diff --git a/utils/unittest/googletest/include/gtest/gtest-test-part.h b/utils/unittest/googletest/include/gtest/gtest-test-part.h index f71475906763..8aeea14984e0 100644 --- a/utils/unittest/googletest/include/gtest/gtest-test-part.h +++ b/utils/unittest/googletest/include/gtest/gtest-test-part.h @@ -35,8 +35,8 @@ #include #include -#include -#include +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" namespace testing { diff --git a/utils/unittest/googletest/include/gtest/gtest-typed-test.h b/utils/unittest/googletest/include/gtest/gtest-typed-test.h index 1ec8eb8d3093..fe1e83b274bc 100644 --- a/utils/unittest/googletest/include/gtest/gtest-typed-test.h +++ b/utils/unittest/googletest/include/gtest/gtest-typed-test.h @@ -146,8 +146,8 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); #endif // 0 -#include -#include +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-type-util.h" // Implements typed tests. @@ -157,16 +157,16 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // // Expands to the name of the typedef for the type parameters of the // given test case. -#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ +# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ // The 'Types' template argument below must have spaces around it // since some compilers may choke on '>>' when passing a template // instance (e.g. Types) -#define TYPED_TEST_CASE(CaseName, Types) \ +# define TYPED_TEST_CASE(CaseName, Types) \ typedef ::testing::internal::TypeList< Types >::type \ GTEST_TYPE_PARAMS_(CaseName) -#define TYPED_TEST(CaseName, TestName) \ +# define TYPED_TEST(CaseName, TestName) \ template \ class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ : public CaseName { \ @@ -175,7 +175,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); typedef gtest_TypeParam_ TypeParam; \ virtual void TestBody(); \ }; \ - bool gtest_##CaseName##_##TestName##_registered_ = \ + bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::internal::TypeParameterizedTest< \ CaseName, \ ::testing::internal::TemplateSel< \ @@ -196,31 +196,31 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // Expands to the namespace name that the type-parameterized tests for // the given type-parameterized test case are defined in. The exact // name of the namespace is subject to change without notice. -#define GTEST_CASE_NAMESPACE_(TestCaseName) \ +# define GTEST_CASE_NAMESPACE_(TestCaseName) \ gtest_case_##TestCaseName##_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the name of the variable used to remember the names of // the defined tests in the given test case. -#define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ +# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ gtest_typed_test_case_p_state_##TestCaseName##_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. // // Expands to the name of the variable used to remember the names of // the registered tests in the given test case. -#define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ +# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ gtest_registered_test_names_##TestCaseName##_ // The variables defined in the type-parameterized test macros are // static as typically these macros are used in a .h file that can be // #included in multiple translation units linked together. -#define TYPED_TEST_CASE_P(CaseName) \ +# define TYPED_TEST_CASE_P(CaseName) \ static ::testing::internal::TypedTestCasePState \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) -#define TYPED_TEST_P(CaseName, TestName) \ +# define TYPED_TEST_P(CaseName, TestName) \ namespace GTEST_CASE_NAMESPACE_(CaseName) { \ template \ class TestName : public CaseName { \ @@ -229,14 +229,14 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); typedef gtest_TypeParam_ TypeParam; \ virtual void TestBody(); \ }; \ - static bool gtest_##TestName##_defined_ = \ + static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ __FILE__, __LINE__, #CaseName, #TestName); \ } \ template \ void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() -#define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ +# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ namespace GTEST_CASE_NAMESPACE_(CaseName) { \ typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ } \ @@ -247,8 +247,8 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // The 'Types' template argument below must have spaces around it // since some compilers may choke on '>>' when passing a template // instance (e.g. Types) -#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ - bool gtest_##Prefix##_##CaseName = \ +# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ + bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::internal::TypeParameterizedTestCase::type>::Register(\ diff --git a/utils/unittest/googletest/include/gtest/gtest.h b/utils/unittest/googletest/include/gtest/gtest.h index 5470082abd45..1734c4432e1c 100644 --- a/utils/unittest/googletest/include/gtest/gtest.h +++ b/utils/unittest/googletest/include/gtest/gtest.h @@ -54,14 +54,15 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" +#include "gtest/gtest-death-test.h" +#include "gtest/gtest-message.h" +#include "gtest/gtest-param-test.h" +#include "gtest/gtest-printers.h" +#include "gtest/gtest_prod.h" +#include "gtest/gtest-test-part.h" +#include "gtest/gtest-typed-test.h" // Depending on the platform, different string classes are available. // On Linux, in addition to ::std::string, Google also makes use of @@ -136,6 +137,11 @@ GTEST_DECLARE_int32_(stack_trace_depth); // non-zero code otherwise. GTEST_DECLARE_bool_(throw_on_failure); +// When this flag is set with a "host:port" string, on supported +// platforms test results are streamed to the specified port on +// the specified host machine. +GTEST_DECLARE_string_(stream_result_to); + // The upper limit for valid stack trace depths. const int kMaxStackTraceDepth = 100; @@ -147,7 +153,6 @@ class ExecDeathTest; class NoExecDeathTest; class FinalSuccessChecker; class GTestFlagSaver; -class TestInfoImpl; class TestResultAccessor; class TestEventListenersAccessor; class TestEventRepeater; @@ -155,8 +160,6 @@ class WindowsDeathTest; class UnitTestImpl* GetUnitTestImpl(); void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const String& message); -class PrettyUnitTestResultPrinter; -class XmlUnitTestResultPrinter; // Converts a streamable value to a String. A NULL pointer is // converted to "(null)". When the input value is a ::string, @@ -172,6 +175,14 @@ String StreamableToString(const T& streamable) { } // namespace internal +// The friend relationship of some of these classes is cyclic. +// If we don't forward declare them the compiler might confuse the classes +// in friendship clauses with same named classes on the scope. +class Test; +class TestCase; +class TestInfo; +class UnitTest; + // A class for indicating whether an assertion was successful. When // the assertion wasn't successful, the AssertionResult object // remembers a non-empty message that describes how it failed. @@ -270,20 +281,33 @@ class GTEST_API_ AssertionResult { // assertion's expectation). When nothing has been streamed into the // object, returns an empty string. const char* message() const { - return message_.get() != NULL && message_->c_str() != NULL ? - message_->c_str() : ""; + return message_.get() != NULL ? message_->c_str() : ""; } // TODO(vladl@google.com): Remove this after making sure no clients use it. // Deprecated; please use message() instead. const char* failure_message() const { return message(); } // Streams a custom failure message into this object. - template AssertionResult& operator<<(const T& value); + template AssertionResult& operator<<(const T& value) { + AppendMessage(Message() << value); + return *this; + } + + // Allows streaming basic output manipulators such as endl or flush into + // this object. + AssertionResult& operator<<( + ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { + AppendMessage(Message() << basic_manipulator); + return *this; + } private: - // No implementation - we want AssertionResult to be - // copy-constructible but not assignable. - void operator=(const AssertionResult& other); + // Appends the contents of message to message_. + void AppendMessage(const Message& a_message) { + if (message_.get() == NULL) + message_.reset(new ::std::string); + message_->append(a_message.GetString().c_str()); + } // Stores result of the assertion predicate. bool success_; @@ -291,19 +315,10 @@ class GTEST_API_ AssertionResult { // construct is not satisfied with the predicate's outcome. // Referenced via a pointer to avoid taking too much stack frame space // with test assertions. - internal::scoped_ptr message_; -}; // class AssertionResult + internal::scoped_ptr< ::std::string> message_; -// Streams a custom failure message into this object. -template -AssertionResult& AssertionResult::operator<<(const T& value) { - Message msg; - if (message_.get() != NULL) - msg << *message_; - msg << value; - message_.reset(new internal::String(msg.GetString())); - return *this; -} + GTEST_DISALLOW_ASSIGN_(AssertionResult); +}; // Makes a successful assertion result. GTEST_API_ AssertionResult AssertionSuccess(); @@ -340,7 +355,7 @@ GTEST_API_ AssertionResult AssertionFailure(const Message& msg); // Test is not copyable. class GTEST_API_ Test { public: - friend class internal::TestInfoImpl; + friend class TestInfo; // Defines types for pointers to functions that set up and tear down // a test case. @@ -417,6 +432,10 @@ class GTEST_API_ Test { // Sets up, executes, and tears down the test. void Run(); + // Deletes self. We deliberately pick an unusual name for this + // internal method to avoid clashing with names used in user TESTs. + void DeleteSelf_() { delete this; } + // Uses a GTestFlagSaver to save and restore all Google Test flags. const internal::GTestFlagSaver* const gtest_flag_saver_; @@ -531,7 +550,6 @@ class GTEST_API_ TestResult { friend class UnitTest; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::ExecDeathTest; - friend class internal::TestInfoImpl; friend class internal::TestResultAccessor; friend class internal::UnitTestImpl; friend class internal::WindowsDeathTest; @@ -611,16 +629,26 @@ class GTEST_API_ TestInfo { ~TestInfo(); // Returns the test case name. - const char* test_case_name() const; + const char* test_case_name() const { return test_case_name_.c_str(); } // Returns the test name. - const char* name() const; + const char* name() const { return name_.c_str(); } - // Returns the test case comment. - const char* test_case_comment() const; + // Returns the name of the parameter type, or NULL if this is not a typed + // or a type-parameterized test. + const char* type_param() const { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } - // Returns the test comment. - const char* comment() const; + // Returns the text representation of the value parameter, or NULL if this + // is not a value-parameterized test. + const char* value_param() const { + if (value_param_.get() != NULL) + return value_param_->c_str(); + return NULL; + } // Returns true if this test should run, that is if the test is not disabled // (or it is disabled but the also_run_disabled_tests flag has been specified) @@ -638,47 +666,70 @@ class GTEST_API_ TestInfo { // // For example, *A*:Foo.* is a filter that matches any string that // contains the character 'A' or starts with "Foo.". - bool should_run() const; + bool should_run() const { return should_run_; } // Returns the result of the test. - const TestResult* result() const; + const TestResult* result() const { return &result_; } private: + #if GTEST_HAS_DEATH_TEST friend class internal::DefaultDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST friend class Test; friend class TestCase; - friend class internal::TestInfoImpl; friend class internal::UnitTestImpl; friend TestInfo* internal::MakeAndRegisterTestInfo( const char* test_case_name, const char* name, - const char* test_case_comment, const char* comment, + const char* type_param, + const char* value_param, internal::TypeId fixture_class_id, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc, internal::TestFactoryBase* factory); - // Returns true if this test matches the user-specified filter. - bool matches_filter() const; - - // Increments the number of death tests encountered in this test so - // far. - int increment_death_test_count(); - - // Accessors for the implementation object. - internal::TestInfoImpl* impl() { return impl_; } - const internal::TestInfoImpl* impl() const { return impl_; } - // Constructs a TestInfo object. The newly constructed instance assumes // ownership of the factory object. TestInfo(const char* test_case_name, const char* name, - const char* test_case_comment, const char* comment, + const char* a_type_param, + const char* a_value_param, internal::TypeId fixture_class_id, internal::TestFactoryBase* factory); - // An opaque implementation object. - internal::TestInfoImpl* impl_; + // Increments the number of death tests encountered in this test so + // far. + int increment_death_test_count() { + return result_.increment_death_test_count(); + } + + // Creates the test object, runs it, records its result, and then + // deletes it. + void Run(); + + static void ClearTestResult(TestInfo* test_info) { + test_info->result_.Clear(); + } + + // These fields are immutable properties of the test. + const std::string test_case_name_; // Test case name + const std::string name_; // Test name + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr type_param_; + // Text representation of the value parameter, or NULL if this is not a + // value-parameterized test. + const internal::scoped_ptr value_param_; + const internal::TypeId fixture_class_id_; // ID of the test fixture class + bool should_run_; // True iff this test should run + bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. + internal::TestFactoryBase* const factory_; // The factory that creates + // the test object + + // This field is mutable and needs to be reset before running the + // test for the second time. + TestResult result_; GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); }; @@ -696,9 +747,11 @@ class GTEST_API_ TestCase { // Arguments: // // name: name of the test case + // a_type_param: the name of the test's type parameter, or NULL if + // this is not a type-parameterized test. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case - TestCase(const char* name, const char* comment, + TestCase(const char* name, const char* a_type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc); @@ -708,8 +761,13 @@ class GTEST_API_ TestCase { // Gets the name of the TestCase. const char* name() const { return name_.c_str(); } - // Returns the test case comment. - const char* comment() const { return comment_.c_str(); } + // Returns the name of the parameter type, or NULL if this is not a + // type-parameterized test case. + const char* type_param() const { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } // Returns true if any test in this test case should run. bool should_run() const { return should_run_; } @@ -776,17 +834,33 @@ class GTEST_API_ TestCase { // Runs every test in this TestCase. void Run(); + // Runs SetUpTestCase() for this TestCase. This wrapper is needed + // for catching exceptions thrown from SetUpTestCase(). + void RunSetUpTestCase() { (*set_up_tc_)(); } + + // Runs TearDownTestCase() for this TestCase. This wrapper is + // needed for catching exceptions thrown from TearDownTestCase(). + void RunTearDownTestCase() { (*tear_down_tc_)(); } + // Returns true iff test passed. - static bool TestPassed(const TestInfo * test_info); + static bool TestPassed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Passed(); + } // Returns true iff test failed. - static bool TestFailed(const TestInfo * test_info); + static bool TestFailed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Failed(); + } // Returns true iff test is disabled. - static bool TestDisabled(const TestInfo * test_info); + static bool TestDisabled(const TestInfo* test_info) { + return test_info->is_disabled_; + } // Returns true if the given test should run. - static bool ShouldRunTest(const TestInfo *test_info); + static bool ShouldRunTest(const TestInfo* test_info) { + return test_info->should_run(); + } // Shuffles the tests in this test case. void ShuffleTests(internal::Random* random); @@ -796,8 +870,9 @@ class GTEST_API_ TestCase { // Name of the test case. internal::String name_; - // Comment on the test case. - internal::String comment_; + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr type_param_; // The vector of TestInfos in their original order. It owns the // elements in the vector. std::vector test_info_list_; @@ -876,7 +951,7 @@ class TestEventListener { // Fired before the test starts. virtual void OnTestStart(const TestInfo& test_info) = 0; - // Fired after a failed assertion or a SUCCESS(). + // Fired after a failed assertion or a SUCCEED() invocation. virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; // Fired after the test ends. @@ -961,10 +1036,10 @@ class GTEST_API_ TestEventListeners { private: friend class TestCase; + friend class TestInfo; friend class internal::DefaultGlobalTestPartResultReporter; friend class internal::NoExecDeathTest; friend class internal::TestEventListenersAccessor; - friend class internal::TestInfoImpl; friend class internal::UnitTestImpl; // Returns repeater that broadcasts the TestEventListener events to all @@ -1206,30 +1281,6 @@ GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); namespace internal { -// These overloaded versions handle ::std::string and ::std::wstring. -GTEST_API_ inline String FormatForFailureMessage(const ::std::string& str) { - return (Message() << '"' << str << '"').GetString(); -} - -#if GTEST_HAS_STD_WSTRING -GTEST_API_ inline String FormatForFailureMessage(const ::std::wstring& wstr) { - return (Message() << "L\"" << wstr << '"').GetString(); -} -#endif // GTEST_HAS_STD_WSTRING - -// These overloaded versions handle ::string and ::wstring. -#if GTEST_HAS_GLOBAL_STRING -GTEST_API_ inline String FormatForFailureMessage(const ::string& str) { - return (Message() << '"' << str << '"').GetString(); -} -#endif // GTEST_HAS_GLOBAL_STRING - -#if GTEST_HAS_GLOBAL_WSTRING -GTEST_API_ inline String FormatForFailureMessage(const ::wstring& wstr) { - return (Message() << "L\"" << wstr << '"').GetString(); -} -#endif // GTEST_HAS_GLOBAL_WSTRING - // Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) // operand to be used in a failure message. The type (but not value) // of the other operand may affect the format. This allows us to @@ -1245,7 +1296,9 @@ GTEST_API_ inline String FormatForFailureMessage(const ::wstring& wstr) { template String FormatForComparisonFailureMessage(const T1& value, const T2& /* other_operand */) { - return FormatForFailureMessage(value); + // C++Builder compiles this incorrectly if the namespace isn't explicitly + // given. + return ::testing::PrintToString(value); } // The helper function for {ASSERT|EXPECT}_EQ. @@ -1255,8 +1308,8 @@ AssertionResult CmpHelperEQ(const char* expected_expression, const T1& expected, const T2& actual) { #ifdef _MSC_VER -#pragma warning(push) // Saves the current warning state. -#pragma warning(disable:4389) // Temporarily disables warning on +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4389) // Temporarily disables warning on // signed/unsigned mismatch. #pragma warning(disable:4805) // Temporarily disables warning on // unsafe mix of types @@ -1267,7 +1320,7 @@ AssertionResult CmpHelperEQ(const char* expected_expression, } #ifdef _MSC_VER -#pragma warning(pop) // Restores the warning state. +# pragma warning(pop) // Restores the warning state. #endif return EqFailure(expected_expression, @@ -1318,7 +1371,7 @@ class EqHelper { }; // This specialization is used when the first argument to ASSERT_EQ() -// is a null pointer literal. +// is a null pointer literal, like NULL, false, or 0. template <> class EqHelper { public: @@ -1327,24 +1380,38 @@ class EqHelper { // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or // EXPECT_EQ(false, a_bool). template - static AssertionResult Compare(const char* expected_expression, - const char* actual_expression, - const T1& expected, - const T2& actual) { + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual, + // The following line prevents this overload from being considered if T2 + // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) + // expands to Compare("", "", NULL, my_ptr), which requires a conversion + // to match the Secret* in the other overload, which would otherwise make + // this template match better. + typename EnableIf::value>::type* = 0) { return CmpHelperEQ(expected_expression, actual_expression, expected, actual); } - // This version will be picked when the second argument to - // ASSERT_EQ() is a pointer, e.g. ASSERT_EQ(NULL, a_pointer). - template - static AssertionResult Compare(const char* expected_expression, - const char* actual_expression, - const T1& /* expected */, - T2* actual) { + // This version will be picked when the second argument to ASSERT_EQ() is a + // pointer, e.g. ASSERT_EQ(NULL, a_pointer). + template + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + // We used to have a second template parameter instead of Secret*. That + // template parameter would deduce to 'long', making this a better match + // than the first overload even without the first overload's EnableIf. + // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to + // non-pointer argument" (even a deduced integral argument), so the old + // implementation caused warnings in user code. + Secret* /* expected (NULL) */, + T* actual) { // We already know that 'expected' is a null pointer. return CmpHelperEQ(expected_expression, actual_expression, - static_cast(NULL), actual); + static_cast(NULL), actual); } }; @@ -1365,11 +1432,10 @@ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ if (val1 op val2) {\ return AssertionSuccess();\ } else {\ - Message msg;\ - msg << "Expected: (" << expr1 << ") " #op " (" << expr2\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ << " vs " << FormatForComparisonFailureMessage(val2, val1);\ - return AssertionFailure(msg);\ }\ }\ GTEST_API_ AssertionResult CmpHelper##op_name(\ @@ -1497,18 +1563,18 @@ AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, return AssertionSuccess(); } - StrStream expected_ss; + ::std::stringstream expected_ss; expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) << expected; - StrStream actual_ss; + ::std::stringstream actual_ss; actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) << actual; return EqFailure(expected_expression, actual_expression, - StrStreamToString(&expected_ss), - StrStreamToString(&actual_ss), + StringStreamToString(&expected_ss), + StringStreamToString(&actual_ss), false); } @@ -1566,9 +1632,13 @@ class GTEST_API_ AssertHelper { } // namespace internal #if GTEST_HAS_PARAM_TEST -// The abstract base class that all value-parameterized tests inherit from. +// The pure interface class that all value-parameterized tests inherit from. +// A value-parameterized class must inherit from both ::testing::Test and +// ::testing::WithParamInterface. In most cases that just means inheriting +// from ::testing::TestWithParam, but more complicated test hierarchies +// may need to inherit from Test and WithParamInterface at different levels. // -// This class adds support for accessing the test parameter value via +// This interface has support for accessing the test parameter value via // the GetParam() method. // // Use it with one of the parameter generator defining functions, like Range(), @@ -1597,12 +1667,16 @@ class GTEST_API_ AssertHelper { // INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); template -class TestWithParam : public Test { +class WithParamInterface { public: typedef T ParamType; + virtual ~WithParamInterface() {} // The current parameter value. Is also available in the test fixture's - // constructor. + // constructor. This member function is non-static, even though it only + // references static data, to reduce the opportunity for incorrect uses + // like writing 'WithParamInterface::GetParam()' for a test that + // uses a fixture whose parameter type is int. const ParamType& GetParam() const { return *parameter_; } private: @@ -1615,12 +1689,19 @@ class TestWithParam : public Test { // Static value used for accessing parameter during a test lifetime. static const ParamType* parameter_; - // TestClass must be a subclass of TestWithParam. + // TestClass must be a subclass of WithParamInterface and Test. template friend class internal::ParameterizedTestFactory; }; template -const T* TestWithParam::parameter_ = NULL; +const T* WithParamInterface::parameter_ = NULL; + +// Most value-parameterized classes can ignore the existence of +// WithParamInterface, and can just inherit from ::testing::TestWithParam. + +template +class TestWithParam : public Test, public WithParamInterface { +}; #endif // GTEST_HAS_PARAM_TEST @@ -1652,13 +1733,19 @@ const T* TestWithParam::parameter_ = NULL; // Generates a nonfatal failure with a generic message. #define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") +// Generates a nonfatal failure at the given source file location with +// a generic message. +#define ADD_FAILURE_AT(file, line) \ + GTEST_MESSAGE_AT_(file, line, "Failed", \ + ::testing::TestPartResult::kNonFatalFailure) + // Generates a fatal failure with a generic message. #define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") // Define this macro to 1 to omit the definition of FAIL(), which is a // generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_FAIL -#define FAIL() GTEST_FAIL() +# define FAIL() GTEST_FAIL() #endif // Generates a success with a generic message. @@ -1667,7 +1754,7 @@ const T* TestWithParam::parameter_ = NULL; // Define this macro to 1 to omit the definition of SUCCEED(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_SUCCEED -#define SUCCEED() GTEST_SUCCEED() +# define SUCCEED() GTEST_SUCCEED() #endif // Macros for testing exceptions. @@ -1710,7 +1797,7 @@ const T* TestWithParam::parameter_ = NULL; // Includes the auto-generated header that implements a family of // generic predicate assertion macros. -#include +#include "gtest/gtest_pred_impl.h" // Macros for testing equalities and inequalities. // @@ -1773,21 +1860,48 @@ const T* TestWithParam::parameter_ = NULL; #define EXPECT_GT(val1, val2) \ EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) -#define ASSERT_EQ(expected, actual) \ +#define GTEST_ASSERT_EQ(expected, actual) \ ASSERT_PRED_FORMAT2(::testing::internal:: \ EqHelper::Compare, \ expected, actual) -#define ASSERT_NE(val1, val2) \ +#define GTEST_ASSERT_NE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) -#define ASSERT_LE(val1, val2) \ +#define GTEST_ASSERT_LE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) -#define ASSERT_LT(val1, val2) \ +#define GTEST_ASSERT_LT(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) -#define ASSERT_GE(val1, val2) \ +#define GTEST_ASSERT_GE(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) -#define ASSERT_GT(val1, val2) \ +#define GTEST_ASSERT_GT(val1, val2) \ ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) +// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of +// ASSERT_XY(), which clashes with some users' own code. + +#if !GTEST_DONT_DEFINE_ASSERT_EQ +# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_NE +# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LE +# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LT +# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GE +# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GT +# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) +#endif + // C String Comparisons. All tests treat NULL and any non-NULL string // as different. Two NULLs are equal. // @@ -1884,16 +1998,16 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, // expected result and the actual result with both a human-readable // string representation of the error, if available, as well as the // hex result code. -#define EXPECT_HRESULT_SUCCEEDED(expr) \ +# define EXPECT_HRESULT_SUCCEEDED(expr) \ EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) -#define ASSERT_HRESULT_SUCCEEDED(expr) \ +# define ASSERT_HRESULT_SUCCEEDED(expr) \ ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) -#define EXPECT_HRESULT_FAILED(expr) \ +# define EXPECT_HRESULT_FAILED(expr) \ EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) -#define ASSERT_HRESULT_FAILED(expr) \ +# define ASSERT_HRESULT_FAILED(expr) \ ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) #endif // GTEST_OS_WINDOWS @@ -1928,17 +2042,6 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ __FILE__, __LINE__, ::testing::Message() << (message)) -namespace internal { - -// This template is declared, but intentionally undefined. -template -struct StaticAssertTypeEqHelper; - -template -struct StaticAssertTypeEqHelper {}; - -} // namespace internal - // Compile-time assertion for type equality. // StaticAssertTypeEq() compiles iff type1 and type2 are // the same type. The value it returns is not interesting. @@ -1971,7 +2074,7 @@ struct StaticAssertTypeEqHelper {}; // to cause a compiler error. template bool StaticAssertTypeEq() { - internal::StaticAssertTypeEqHelper(); + (void)internal::StaticAssertTypeEqHelper(); return true; } @@ -2007,7 +2110,7 @@ bool StaticAssertTypeEq() { // Define this macro to 1 to omit the definition of TEST(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_TEST -#define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) +# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) #endif // Defines a test that uses a test fixture. diff --git a/utils/unittest/googletest/include/gtest/gtest_pred_impl.h b/utils/unittest/googletest/include/gtest/gtest_pred_impl.h index e1e2f8c4c887..3805f85bdb39 100644 --- a/utils/unittest/googletest/include/gtest/gtest_pred_impl.h +++ b/utils/unittest/googletest/include/gtest/gtest_pred_impl.h @@ -27,7 +27,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// This file is AUTOMATICALLY GENERATED on 10/02/2008 by command +// This file is AUTOMATICALLY GENERATED on 09/24/2010 by command // 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! // // Implements a family of generic predicate assertion macros. @@ -37,7 +37,7 @@ // Makes sure this header is not included before gtest.h. #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ -#error Do not include gtest_pred_impl.h directly. Include gtest.h instead. +# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. #endif // GTEST_INCLUDE_GTEST_GTEST_H_ // This header implements a family of generic predicate assertion @@ -90,11 +90,9 @@ AssertionResult AssertPred1Helper(const char* pred_text, const T1& v1) { if (pred(v1)) return AssertionSuccess(); - Message msg; - msg << pred_text << "(" - << e1 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1; - return AssertionFailure(msg); + return AssertionFailure() << pred_text << "(" + << e1 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. @@ -136,13 +134,11 @@ AssertionResult AssertPred2Helper(const char* pred_text, const T2& v2) { if (pred(v1, v2)) return AssertionSuccess(); - Message msg; - msg << pred_text << "(" - << e1 << ", " - << e2 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2; - return AssertionFailure(msg); + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. @@ -189,15 +185,13 @@ AssertionResult AssertPred3Helper(const char* pred_text, const T3& v3) { if (pred(v1, v2, v3)) return AssertionSuccess(); - Message msg; - msg << pred_text << "(" - << e1 << ", " - << e2 << ", " - << e3 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2 - << "\n" << e3 << " evaluates to " << v3; - return AssertionFailure(msg); + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. @@ -249,17 +243,15 @@ AssertionResult AssertPred4Helper(const char* pred_text, const T4& v4) { if (pred(v1, v2, v3, v4)) return AssertionSuccess(); - Message msg; - msg << pred_text << "(" - << e1 << ", " - << e2 << ", " - << e3 << ", " - << e4 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2 - << "\n" << e3 << " evaluates to " << v3 - << "\n" << e4 << " evaluates to " << v4; - return AssertionFailure(msg); + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. @@ -316,19 +308,17 @@ AssertionResult AssertPred5Helper(const char* pred_text, const T5& v5) { if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); - Message msg; - msg << pred_text << "(" - << e1 << ", " - << e2 << ", " - << e3 << ", " - << e4 << ", " - << e5 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2 - << "\n" << e3 << " evaluates to " << v3 - << "\n" << e4 << " evaluates to " << v4 - << "\n" << e5 << " evaluates to " << v5; - return AssertionFailure(msg); + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ", " + << e5 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4 + << "\n" << e5 << " evaluates to " << v5; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h b/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h index e4330848d4ea..1d9f83b652b5 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h @@ -37,7 +37,9 @@ #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ -#include +#include "gtest/internal/gtest-internal.h" + +#include namespace testing { namespace internal { @@ -96,8 +98,12 @@ class GTEST_API_ DeathTest { // test, then wait for it to complete. enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; - // An enumeration of the two reasons that a test might be aborted. - enum AbortReason { TEST_ENCOUNTERED_RETURN_STATEMENT, TEST_DID_NOT_DIE }; + // An enumeration of the three reasons that a test might be aborted. + enum AbortReason { + TEST_ENCOUNTERED_RETURN_STATEMENT, + TEST_THREW_EXCEPTION, + TEST_DID_NOT_DIE + }; // Assumes one of the above roles. virtual TestRole AssumeRole() = 0; @@ -149,9 +155,34 @@ class DefaultDeathTestFactory : public DeathTestFactory { // by a signal, or exited normally with a nonzero exit code. GTEST_API_ bool ExitedUnsuccessfully(int exit_status); +// Traps C++ exceptions escaping statement and reports them as test +// failures. Note that trapping SEH exceptions is not implemented here. +# if GTEST_HAS_EXCEPTIONS +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (const ::std::exception& gtest_exception) { \ + fprintf(\ + stderr, \ + "\n%s: Caught std::exception-derived exception escaping the " \ + "death test statement. Exception message: %s\n", \ + ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ + gtest_exception.what()); \ + fflush(stderr); \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } catch (...) { \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } + +# else +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) + +# endif + // This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, // ASSERT_EXIT*, and EXPECT_EXIT*. -#define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ +# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ const ::testing::internal::RE& gtest_regex = (regex); \ @@ -172,10 +203,12 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status); case ::testing::internal::DeathTest::EXECUTE_TEST: { \ ::testing::internal::DeathTest::ReturnSentinel \ gtest_sentinel(gtest_dt); \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ break; \ } \ + default: \ + break; \ } \ } \ } else \ @@ -254,7 +287,7 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); // statement unconditionally returns or throws. The Message constructor at // the end allows the syntax of streaming additional messages into the // macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. -#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ +# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::AlwaysTrue()) { \ GTEST_LOG_(WARNING) \ diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h b/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h index efbc176029fa..823c6bdc258a 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h @@ -40,7 +40,7 @@ #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ -#include +#include "gtest/internal/gtest-string.h" namespace testing { namespace internal { diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h b/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h index 855b21554afb..65a2101a4d81 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-internal-inl.h @@ -41,12 +41,12 @@ // part of Google Test's implementation; otherwise it's undefined. #if !GTEST_IMPLEMENTATION_ // A user is trying to include this from his code - just say no. -#error "gtest-internal-inl.h is part of Google Test's internal implementation." -#error "It must not be included except by Google Test itself." +# error "gtest-internal-inl.h is part of Google Test's internal implementation." +# error "It must not be included except by Google Test itself." #endif // GTEST_IMPLEMENTATION_ #ifndef _WIN32_WCE -#include +# include #endif // !_WIN32_WCE #include #include // For strtoll/_strtoul64/malloc/free. @@ -56,14 +56,14 @@ #include #include -#include +#include "gtest/internal/gtest-port.h" #if GTEST_OS_WINDOWS -#include // For DWORD. +# include // NOLINT #endif // GTEST_OS_WINDOWS -#include // NOLINT -#include +#include "gtest/gtest.h" // NOLINT +#include "gtest/gtest-spi.h" namespace testing { @@ -93,6 +93,7 @@ const char kRandomSeedFlag[] = "random_seed"; const char kRepeatFlag[] = "repeat"; const char kShuffleFlag[] = "shuffle"; const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kStreamResultToFlag[] = "stream_result_to"; const char kThrowOnFailureFlag[] = "throw_on_failure"; // A valid random seed must be in [1, kMaxRandomSeed]. @@ -165,6 +166,7 @@ class GTestFlagSaver { repeat_ = GTEST_FLAG(repeat); shuffle_ = GTEST_FLAG(shuffle); stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + stream_result_to_ = GTEST_FLAG(stream_result_to); throw_on_failure_ = GTEST_FLAG(throw_on_failure); } @@ -185,6 +187,7 @@ class GTestFlagSaver { GTEST_FLAG(repeat) = repeat_; GTEST_FLAG(shuffle) = shuffle_; GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(stream_result_to) = stream_result_to_; GTEST_FLAG(throw_on_failure) = throw_on_failure_; } private: @@ -205,6 +208,7 @@ class GTestFlagSaver { internal::Int32 repeat_; bool shuffle_; internal::Int32 stack_trace_depth_; + String stream_result_to_; bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; @@ -267,7 +271,14 @@ GTEST_API_ bool ShouldRunTestOnShard( // the given predicate. template inline int CountIf(const Container& c, Predicate predicate) { - return static_cast(std::count_if(c.begin(), c.end(), predicate)); + // Implemented as an explicit loop since std::count_if() in libCstd on + // Solaris has a non-standard signature. + int count = 0; + for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { + if (predicate(*it)) + ++count; + } + return count; } // Applies a function/functor to each element in the container. @@ -340,85 +351,6 @@ class TestPropertyKeyIs { String key_; }; -class TestInfoImpl { - public: - TestInfoImpl(TestInfo* parent, const char* test_case_name, - const char* name, const char* test_case_comment, - const char* comment, TypeId fixture_class_id, - internal::TestFactoryBase* factory); - ~TestInfoImpl(); - - // Returns true if this test should run. - bool should_run() const { return should_run_; } - - // Sets the should_run member. - void set_should_run(bool should) { should_run_ = should; } - - // Returns true if this test is disabled. Disabled tests are not run. - bool is_disabled() const { return is_disabled_; } - - // Sets the is_disabled member. - void set_is_disabled(bool is) { is_disabled_ = is; } - - // Returns true if this test matches the filter specified by the user. - bool matches_filter() const { return matches_filter_; } - - // Sets the matches_filter member. - void set_matches_filter(bool matches) { matches_filter_ = matches; } - - // Returns the test case name. - const char* test_case_name() const { return test_case_name_.c_str(); } - - // Returns the test name. - const char* name() const { return name_.c_str(); } - - // Returns the test case comment. - const char* test_case_comment() const { return test_case_comment_.c_str(); } - - // Returns the test comment. - const char* comment() const { return comment_.c_str(); } - - // Returns the ID of the test fixture class. - TypeId fixture_class_id() const { return fixture_class_id_; } - - // Returns the test result. - TestResult* result() { return &result_; } - const TestResult* result() const { return &result_; } - - // Creates the test object, runs it, records its result, and then - // deletes it. - void Run(); - - // Clears the test result. - void ClearResult() { result_.Clear(); } - - // Clears the test result in the given TestInfo object. - static void ClearTestResult(TestInfo * test_info) { - test_info->impl()->ClearResult(); - } - - private: - // These fields are immutable properties of the test. - TestInfo* const parent_; // The owner of this object - const String test_case_name_; // Test case name - const String name_; // Test name - const String test_case_comment_; // Test case comment - const String comment_; // Test comment - const TypeId fixture_class_id_; // ID of the test fixture class - bool should_run_; // True iff this test should run - bool is_disabled_; // True iff this test is disabled - bool matches_filter_; // True if this test matches the - // user-specified filter. - internal::TestFactoryBase* const factory_; // The factory that creates - // the test object - - // This field is mutable and needs to be reset before running the - // test for the second time. - TestResult result_; - - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfoImpl); -}; - // Class UnitTestOptions. // // This class contains functions for processing options the user @@ -682,10 +614,12 @@ class GTEST_API_ UnitTestImpl { // Arguments: // // test_case_name: name of the test case + // type_param: the name of the test's type parameter, or NULL if + // this is not a typed or a type-parameterized test. // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase* GetTestCase(const char* test_case_name, - const char* comment, + const char* type_param, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc); @@ -698,7 +632,7 @@ class GTEST_API_ UnitTestImpl { // test_info: the TestInfo object void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc, - TestInfo * test_info) { + TestInfo* test_info) { // In order to support thread-safe death tests, we need to // remember the original working directory when the test program // was first invoked. We cannot do this in RUN_ALL_TESTS(), as @@ -713,7 +647,7 @@ class GTEST_API_ UnitTestImpl { } GetTestCase(test_info->test_case_name(), - test_info->test_case_comment(), + test_info->type_param(), set_up_tc, tear_down_tc)->AddTestInfo(test_info); } @@ -739,24 +673,26 @@ class GTEST_API_ UnitTestImpl { } // Registers all parameterized tests defined using TEST_P and - // INSTANTIATE_TEST_P, creating regular tests for each test/parameter - // combination. This method can be called more then once; it has - // guards protecting from registering the tests more then once. - // If value-parameterized tests are disabled, RegisterParameterizedTests - // is present but does nothing. + // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has guards + // protecting from registering the tests more then once. If + // value-parameterized tests are disabled, RegisterParameterizedTests is + // present but does nothing. void RegisterParameterizedTests(); // Runs all tests in this UnitTest object, prints the result, and - // returns 0 if all tests are successful, or 1 otherwise. If any - // exception is thrown during a test on Windows, this test is - // considered to be failed, but the rest of the tests will still be - // run. (We disable exceptions on Linux and Mac OS X, so the issue - // doesn't apply there.) - int RunAllTests(); + // returns true if all tests are successful. If any exception is + // thrown during a test, this test is considered to be failed, but + // the rest of the tests will still be run. + bool RunAllTests(); - // Clears the results of all tests, including the ad hoc test. - void ClearResult() { + // Clears the results of all tests, except the ad hoc tests. + void ClearNonAdHocTestResult() { ForEach(test_cases_, TestCase::ClearTestCaseResult); + } + + // Clears the results of ad-hoc test assertions. + void ClearAdHocTestResult() { ad_hoc_test_result_.Clear(); } @@ -818,6 +754,12 @@ class GTEST_API_ UnitTestImpl { // UnitTestOptions. Must not be called before InitGoogleTest. void ConfigureXmlOutput(); +#if GTEST_CAN_STREAM_RESULTS_ + // Initializes the event listener for streaming test results to a socket. + // Must not be called before InitGoogleTest. + void ConfigureStreamingOutput(); +#endif + // Performs initialization dependent upon flag values obtained in // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest @@ -838,9 +780,17 @@ class GTEST_API_ UnitTestImpl { // Restores the test cases and tests to their order before the first shuffle. void UnshuffleTests(); + // Returns the value of GTEST_FLAG(catch_exceptions) at the moment + // UnitTest::Run() starts. + bool catch_exceptions() const { return catch_exceptions_; } + private: friend class ::testing::UnitTest; + // Used by UnitTest::Run() to capture the state of + // GTEST_FLAG(catch_exceptions) at the moment it starts. + void set_catch_exceptions(bool value) { catch_exceptions_ = value; } + // The UnitTest object that owns this implementation object. UnitTest* const parent_; @@ -943,6 +893,10 @@ class GTEST_API_ UnitTestImpl { // A per-thread stack of traces created by the SCOPED_TRACE() macro. internal::ThreadLocal > gtest_trace_stack_; + // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() + // starts. + bool catch_exceptions_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); }; // class UnitTestImpl @@ -952,14 +906,16 @@ inline UnitTestImpl* GetUnitTestImpl() { return UnitTest::GetInstance()->impl(); } +#if GTEST_USES_SIMPLE_RE + // Internal helper functions for implementing the simple regular // expression matcher. GTEST_API_ bool IsInSet(char ch, const char* str); -GTEST_API_ bool IsDigit(char ch); -GTEST_API_ bool IsPunct(char ch); +GTEST_API_ bool IsAsciiDigit(char ch); +GTEST_API_ bool IsAsciiPunct(char ch); GTEST_API_ bool IsRepeat(char ch); -GTEST_API_ bool IsWhiteSpace(char ch); -GTEST_API_ bool IsWordChar(char ch); +GTEST_API_ bool IsAsciiWhiteSpace(char ch); +GTEST_API_ bool IsAsciiWordChar(char ch); GTEST_API_ bool IsValidEscape(char ch); GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); GTEST_API_ bool ValidateRegex(const char* regex); @@ -968,6 +924,8 @@ GTEST_API_ bool MatchRepetitionAndRegexAtHead( bool escaped, char ch, char repeat, const char* regex, const char* str); GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); +#endif // GTEST_USES_SIMPLE_RE + // Parses the command line for Google Test flags, without initializing // other parts of Google Test. GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); @@ -977,9 +935,9 @@ GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); // Returns the message describing the last system error, regardless of the // platform. -String GetLastErrnoDescription(); +GTEST_API_ String GetLastErrnoDescription(); -#if GTEST_OS_WINDOWS +# if GTEST_OS_WINDOWS // Provides leak-safe Windows kernel handle ownership. class AutoHandle { public: @@ -1003,7 +961,7 @@ class AutoHandle { GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); }; -#endif // GTEST_OS_WINDOWS +# endif // GTEST_OS_WINDOWS // Attempts to parse a string into a positive integer pointed to by the // number parameter. Returns true if that is possible. @@ -1014,7 +972,7 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) { // Fail fast if the given string does not begin with a digit; // this bypasses strtoXXX's "optional leading whitespace and plus // or minus sign" semantics, which are undesirable here. - if (str.empty() || !isdigit(str[0])) { + if (str.empty() || !IsDigit(str[0])) { return false; } errno = 0; @@ -1022,14 +980,20 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) { char* end; // BiggestConvertible is the largest integer type that system-provided // string-to-number conversion routines can return. -#if GTEST_OS_WINDOWS && !defined(__GNUC__) + +# if GTEST_OS_WINDOWS && !defined(__GNUC__) + // MSVC and C++ Builder define __int64 instead of the standard long long. typedef unsigned __int64 BiggestConvertible; const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); -#else + +# else + typedef unsigned long long BiggestConvertible; // NOLINT const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); -#endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + +# endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + const bool parse_success = *end == '\0' && errno == 0; // TODO(vladl@google.com): Convert this to compile time assertion when it is diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-internal.h b/utils/unittest/googletest/include/gtest/internal/gtest-internal.h index 0b90132e7856..b198a3d97a2e 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-internal.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-internal.h @@ -37,13 +37,13 @@ #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ -#include +#include "gtest/internal/gtest-port.h" #if GTEST_OS_LINUX -#include -#include -#include -#include +# include +# include +# include +# include #endif // GTEST_OS_LINUX #include @@ -52,9 +52,9 @@ #include #include -#include -#include -#include +#include "gtest/internal/gtest-string.h" +#include "gtest/internal/gtest-filepath.h" +#include "gtest/internal/gtest-type-util.h" #include "llvm/Support/raw_os_ostream.h" @@ -117,9 +117,12 @@ inline void GTestStreamToHelper(std::ostream* os, const T& val) { cos << val; } +class ProtocolMessage; +namespace proto2 { class Message; } + namespace testing { -// Forward declaration of classes. +// Forward declarations. class AssertionResult; // Result of an assertion. class Message; // Represents a failure message. @@ -128,6 +131,9 @@ class TestInfo; // Information about a test. class TestPartResult; // Result of a test part. class UnitTest; // A collection of test cases. +template +::std::string PrintToString(const T& value); + namespace internal { struct TraceInfo; // Information about a trace point. @@ -170,9 +176,9 @@ char (&IsNullLiteralHelper(...))[2]; // NOLINT #ifdef GTEST_ELLIPSIS_NEEDS_POD_ // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). -#define GTEST_IS_NULL_LITERAL_(x) false +# define GTEST_IS_NULL_LITERAL_(x) false #else -#define GTEST_IS_NULL_LITERAL_(x) \ +# define GTEST_IS_NULL_LITERAL_(x) \ (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) #endif // GTEST_ELLIPSIS_NEEDS_POD_ @@ -209,72 +215,32 @@ class GTEST_API_ ScopedTrace { template String StreamableToString(const T& streamable); -// Formats a value to be used in a failure message. - -#ifdef GTEST_NEEDS_IS_POINTER_ - -// These are needed as the Nokia Symbian and IBM XL C/C++ compilers -// cannot decide between const T& and const T* in a function template. -// These compilers _can_ decide between class template specializations -// for T and T*, so a tr1::type_traits-like is_pointer works, and we -// can overload on that. - -// This overload makes sure that all pointers (including -// those to char or wchar_t) are printed as raw pointers. -template -inline String FormatValueForFailureMessage(internal::true_type /*dummy*/, - T* pointer) { - return StreamableToString(static_cast(pointer)); -} - -template -inline String FormatValueForFailureMessage(internal::false_type /*dummy*/, - const T& value) { - return StreamableToString(value); -} - -template -inline String FormatForFailureMessage(const T& value) { - return FormatValueForFailureMessage( - typename internal::is_pointer::type(), value); -} - +// The Symbian compiler has a bug that prevents it from selecting the +// correct overload of FormatForComparisonFailureMessage (see below) +// unless we pass the first argument by reference. If we do that, +// however, Visual Age C++ 10.1 generates a compiler error. Therefore +// we only apply the work-around for Symbian. +#if defined(__SYMBIAN32__) +# define GTEST_CREF_WORKAROUND_ const& #else +# define GTEST_CREF_WORKAROUND_ +#endif -// These are needed as the above solution using is_pointer has the -// limitation that T cannot be a type without external linkage, when -// compiled using MSVC. - -template -inline String FormatForFailureMessage(const T& value) { - return StreamableToString(value); -} - -// This overload makes sure that all pointers (including -// those to char or wchar_t) are printed as raw pointers. -template -inline String FormatForFailureMessage(T* pointer) { - return StreamableToString(static_cast(pointer)); -} - -#endif // GTEST_NEEDS_IS_POINTER_ - -// These overloaded versions handle narrow and wide characters. -GTEST_API_ String FormatForFailureMessage(char ch); -GTEST_API_ String FormatForFailureMessage(wchar_t wchar); - -// When this operand is a const char* or char*, and the other operand +// When this operand is a const char* or char*, if the other operand // is a ::std::string or ::string, we print this operand as a C string -// rather than a pointer. We do the same for wide strings. +// rather than a pointer (we do the same for wide strings); otherwise +// we print it as a pointer to be safe. // This internal macro is used to avoid duplicated code. #define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\ inline String FormatForComparisonFailureMessage(\ - operand2_type::value_type* str, const operand2_type& /*operand2*/) {\ + operand2_type::value_type* GTEST_CREF_WORKAROUND_ str, \ + const operand2_type& /*operand2*/) {\ return operand1_printer(str);\ }\ inline String FormatForComparisonFailureMessage(\ - const operand2_type::value_type* str, const operand2_type& /*operand2*/) {\ + const operand2_type::value_type* GTEST_CREF_WORKAROUND_ str, \ + const operand2_type& /*operand2*/) {\ return operand1_printer(str);\ } @@ -292,6 +258,24 @@ GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted) #undef GTEST_FORMAT_IMPL_ +// The next four overloads handle the case where the operand being +// printed is a char/wchar_t pointer and the other operand is not a +// string/wstring object. In such cases, we just print the operand as +// a pointer to be safe. +#define GTEST_FORMAT_CHAR_PTR_IMPL_(CharType) \ + template \ + String FormatForComparisonFailureMessage(CharType* GTEST_CREF_WORKAROUND_ p, \ + const T&) { \ + return PrintToString(static_cast(p)); \ + } + +GTEST_FORMAT_CHAR_PTR_IMPL_(char) +GTEST_FORMAT_CHAR_PTR_IMPL_(const char) +GTEST_FORMAT_CHAR_PTR_IMPL_(wchar_t) +GTEST_FORMAT_CHAR_PTR_IMPL_(const wchar_t) + +#undef GTEST_FORMAT_CHAR_PTR_IMPL_ + // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // @@ -578,20 +562,6 @@ GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, #endif // GTEST_OS_WINDOWS -// Formats a source file path and a line number as they would appear -// in a compiler error message. -inline String FormatFileLocation(const char* file, int line) { - const char* const file_name = file == NULL ? "unknown file" : file; - if (line < 0) { - return String::Format("%s:", file_name); - } -#ifdef _MSC_VER - return String::Format("%s(%d):", file_name, line); -#else - return String::Format("%s:%d:", file_name, line); -#endif // _MSC_VER -} - // Types of SetUpTestCase() and TearDownTestCase() functions. typedef void (*SetUpTestCaseFunc)(); typedef void (*TearDownTestCaseFunc)(); @@ -603,10 +573,10 @@ typedef void (*TearDownTestCaseFunc)(); // // test_case_name: name of the test case // name: name of the test -// test_case_comment: a comment on the test case that will be included in -// the test output -// comment: a comment on the test that will be included in the -// test output +// type_param the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param text representation of the test's value parameter, +// or NULL if this is not a type-parameterized test. // fixture_class_id: ID of the test fixture class // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case @@ -615,7 +585,8 @@ typedef void (*TearDownTestCaseFunc)(); // ownership of the factory object. GTEST_API_ TestInfo* MakeAndRegisterTestInfo( const char* test_case_name, const char* name, - const char* test_case_comment, const char* comment, + const char* type_param, + const char* value_param, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, @@ -624,7 +595,7 @@ GTEST_API_ TestInfo* MakeAndRegisterTestInfo( // If *pstr starts with the given prefix, modifies *pstr to be right // past the prefix and returns true; otherwise leaves *pstr unchanged // and returns false. None of pstr, *pstr, and prefix can be NULL. -bool SkipPrefix(const char* prefix, const char** pstr); +GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P @@ -667,7 +638,7 @@ inline const char* SkipComma(const char* str) { if (comma == NULL) { return NULL; } - while (isspace(*(++comma))) {} + while (IsSpace(*(++comma))) {} return comma; } @@ -704,8 +675,8 @@ class TypeParameterizedTest { String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/", case_name, index).c_str(), GetPrefixUntilComma(test_names).c_str(), - String::Format("TypeParam = %s", GetTypeName().c_str()).c_str(), - "", + GetTypeName().c_str(), + NULL, // No value parameter. GetTypeId(), TestClass::SetUpTestCase, TestClass::TearDownTestCase, @@ -782,6 +753,15 @@ GTEST_API_ bool AlwaysTrue(); // Always returns false. inline bool AlwaysFalse() { return !AlwaysTrue(); } +// Helper for suppressing false warning from Clang on a const char* +// variable declared in a conditional expression always being NULL in +// the else branch. +struct GTEST_API_ ConstCharPtr { + ConstCharPtr(const char* str) : value(str) {} + operator bool() const { return true; } + const char* value; +}; + // A simple Linear Congruential Generator for generating random // numbers with a uniform distribution. Unlike rand() and srand(), it // doesn't use global state (and therefore can't interfere with user @@ -804,13 +784,338 @@ class GTEST_API_ Random { GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); }; +// Defining a variable of type CompileAssertTypesEqual will cause a +// compiler error iff T1 and T2 are different types. +template +struct CompileAssertTypesEqual; + +template +struct CompileAssertTypesEqual { +}; + +// Removes the reference from a type if it is a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::remove_reference, which is not widely available yet. +template +struct RemoveReference { typedef T type; }; // NOLINT +template +struct RemoveReference { typedef T type; }; // NOLINT + +// A handy wrapper around RemoveReference that works when the argument +// T depends on template parameters. +#define GTEST_REMOVE_REFERENCE_(T) \ + typename ::testing::internal::RemoveReference::type + +// Removes const from a type if it is a const type, otherwise leaves +// it unchanged. This is the same as tr1::remove_const, which is not +// widely available yet. +template +struct RemoveConst { typedef T type; }; // NOLINT +template +struct RemoveConst { typedef T type; }; // NOLINT + +// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above +// definition to fail to remove the const in 'const int[3]' and 'const +// char[3][4]'. The following specialization works around the bug. +// However, it causes trouble with GCC and thus needs to be +// conditionally compiled. +#if defined(_MSC_VER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) +template +struct RemoveConst { + typedef typename RemoveConst::type type[N]; +}; +#endif + +// A handy wrapper around RemoveConst that works when the argument +// T depends on template parameters. +#define GTEST_REMOVE_CONST_(T) \ + typename ::testing::internal::RemoveConst::type + +// Turns const U&, U&, const U, and U all into U. +#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ + GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) + +// Adds reference to a type if it is not a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::add_reference, which is not widely available yet. +template +struct AddReference { typedef T& type; }; // NOLINT +template +struct AddReference { typedef T& type; }; // NOLINT + +// A handy wrapper around AddReference that works when the argument T +// depends on template parameters. +#define GTEST_ADD_REFERENCE_(T) \ + typename ::testing::internal::AddReference::type + +// Adds a reference to const on top of T as necessary. For example, +// it transforms +// +// char ==> const char& +// const char ==> const char& +// char& ==> const char& +// const char& ==> const char& +// +// The argument T must depend on some template parameters. +#define GTEST_REFERENCE_TO_CONST_(T) \ + GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) + +// ImplicitlyConvertible::value is a compile-time bool +// constant that's true iff type From can be implicitly converted to +// type To. +template +class ImplicitlyConvertible { + private: + // We need the following helper functions only for their types. + // They have no implementations. + + // MakeFrom() is an expression whose type is From. We cannot simply + // use From(), as the type From may not have a public default + // constructor. + static From MakeFrom(); + + // These two functions are overloaded. Given an expression + // Helper(x), the compiler will pick the first version if x can be + // implicitly converted to type To; otherwise it will pick the + // second version. + // + // The first version returns a value of size 1, and the second + // version returns a value of size 2. Therefore, by checking the + // size of Helper(x), which can be done at compile time, we can tell + // which version of Helper() is used, and hence whether x can be + // implicitly converted to type To. + static char Helper(To); + static char (&Helper(...))[2]; // NOLINT + + // We have to put the 'public' section after the 'private' section, + // or MSVC refuses to compile the code. + public: + // MSVC warns about implicitly converting from double to int for + // possible loss of data, so we need to temporarily disable the + // warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4244) // Temporarily disables warning 4244. + + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; +# pragma warning(pop) // Restores the warning state. +#elif defined(__BORLANDC__) + // C++Builder cannot use member overload resolution during template + // instantiation. The simplest workaround is to use its C++0x type traits + // functions (C++Builder 2009 and above only). + static const bool value = __is_convertible(From, To); +#else + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; +#endif // _MSV_VER +}; +template +const bool ImplicitlyConvertible::value; + +// IsAProtocolMessage::value is a compile-time bool constant that's +// true iff T is type ProtocolMessage, proto2::Message, or a subclass +// of those. +template +struct IsAProtocolMessage + : public bool_constant< + ImplicitlyConvertible::value || + ImplicitlyConvertible::value> { +}; + +// When the compiler sees expression IsContainerTest(0), if C is an +// STL-style container class, the first overload of IsContainerTest +// will be viable (since both C::iterator* and C::const_iterator* are +// valid types and NULL can be implicitly converted to them). It will +// be picked over the second overload as 'int' is a perfect match for +// the type of argument 0. If C::iterator or C::const_iterator is not +// a valid type, the first overload is not viable, and the second +// overload will be picked. Therefore, we can determine whether C is +// a container class by checking the type of IsContainerTest(0). +// The value of the expression is insignificant. +// +// Note that we look for both C::iterator and C::const_iterator. The +// reason is that C++ injects the name of a class as a member of the +// class itself (e.g. you can refer to class iterator as either +// 'iterator' or 'iterator::iterator'). If we look for C::iterator +// only, for example, we would mistakenly think that a class named +// iterator is an STL container. +// +// Also note that the simpler approach of overloading +// IsContainerTest(typename C::const_iterator*) and +// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. +typedef int IsContainer; +template +IsContainer IsContainerTest(int /* dummy */, + typename C::iterator* /* it */ = NULL, + typename C::const_iterator* /* const_it */ = NULL) { + return 0; +} + +typedef char IsNotContainer; +template +IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } + +// EnableIf::type is void when 'Cond' is true, and +// undefined when 'Cond' is false. To use SFINAE to make a function +// overload only apply when a particular expression is true, add +// "typename EnableIf::type* = 0" as the last parameter. +template struct EnableIf; +template<> struct EnableIf { typedef void type; }; // NOLINT + +// Utilities for native arrays. + +// ArrayEq() compares two k-dimensional native arrays using the +// elements' operator==, where k can be any integer >= 0. When k is +// 0, ArrayEq() degenerates into comparing a single pair of values. + +template +bool ArrayEq(const T* lhs, size_t size, const U* rhs); + +// This generic version is used when k is 0. +template +inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } + +// This overload is used when k >= 1. +template +inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { + return internal::ArrayEq(lhs, N, rhs); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous ArrayEq() function, arrays with different sizes would +// lead to different copies of the template code. +template +bool ArrayEq(const T* lhs, size_t size, const U* rhs) { + for (size_t i = 0; i != size; i++) { + if (!internal::ArrayEq(lhs[i], rhs[i])) + return false; + } + return true; +} + +// Finds the first element in the iterator range [begin, end) that +// equals elem. Element may be a native array type itself. +template +Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { + for (Iter it = begin; it != end; ++it) { + if (internal::ArrayEq(*it, elem)) + return it; + } + return end; +} + +// CopyArray() copies a k-dimensional native array using the elements' +// operator=, where k can be any integer >= 0. When k is 0, +// CopyArray() degenerates into copying a single value. + +template +void CopyArray(const T* from, size_t size, U* to); + +// This generic version is used when k is 0. +template +inline void CopyArray(const T& from, U* to) { *to = from; } + +// This overload is used when k >= 1. +template +inline void CopyArray(const T(&from)[N], U(*to)[N]) { + internal::CopyArray(from, N, *to); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous CopyArray() function, arrays with different sizes +// would lead to different copies of the template code. +template +void CopyArray(const T* from, size_t size, U* to) { + for (size_t i = 0; i != size; i++) { + internal::CopyArray(from[i], to + i); + } +} + +// The relation between an NativeArray object (see below) and the +// native array it represents. +enum RelationToSource { + kReference, // The NativeArray references the native array. + kCopy // The NativeArray makes a copy of the native array and + // owns the copy. +}; + +// Adapts a native array to a read-only STL-style container. Instead +// of the complete STL container concept, this adaptor only implements +// members useful for Google Mock's container matchers. New members +// should be added as needed. To simplify the implementation, we only +// support Element being a raw type (i.e. having no top-level const or +// reference modifier). It's the client's responsibility to satisfy +// this requirement. Element can be an array type itself (hence +// multi-dimensional arrays are supported). +template +class NativeArray { + public: + // STL-style container typedefs. + typedef Element value_type; + typedef Element* iterator; + typedef const Element* const_iterator; + + // Constructs from a native array. + NativeArray(const Element* array, size_t count, RelationToSource relation) { + Init(array, count, relation); + } + + // Copy constructor. + NativeArray(const NativeArray& rhs) { + Init(rhs.array_, rhs.size_, rhs.relation_to_source_); + } + + ~NativeArray() { + // Ensures that the user doesn't instantiate NativeArray with a + // const or reference type. + static_cast(StaticAssertTypeEqHelper()); + if (relation_to_source_ == kCopy) + delete[] array_; + } + + // STL-style container methods. + size_t size() const { return size_; } + const_iterator begin() const { return array_; } + const_iterator end() const { return array_ + size_; } + bool operator==(const NativeArray& rhs) const { + return size() == rhs.size() && + ArrayEq(begin(), size(), rhs.begin()); + } + + private: + // Initializes this object; makes a copy of the input array if + // 'relation' is kCopy. + void Init(const Element* array, size_t a_size, RelationToSource relation) { + if (relation == kReference) { + array_ = array; + } else { + Element* const copy = new Element[a_size]; + CopyArray(array, a_size, copy); + array_ = copy; + } + size_ = a_size; + relation_to_source_ = relation; + } + + const Element* array_; + size_t size_; + RelationToSource relation_to_source_; + + GTEST_DISALLOW_ASSIGN_(NativeArray); +}; + } // namespace internal } // namespace testing -#define GTEST_MESSAGE_(message, result_type) \ - ::testing::internal::AssertHelper(result_type, __FILE__, __LINE__, message) \ +#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ + ::testing::internal::AssertHelper(result_type, file, line, message) \ = ::testing::Message() +#define GTEST_MESSAGE_(message, result_type) \ + GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) + #define GTEST_FATAL_FAILURE_(message) \ return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) @@ -828,7 +1133,7 @@ class GTEST_API_ Random { #define GTEST_TEST_THROW_(statement, expected_exception, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (const char* gtest_msg = "") { \ + if (::testing::internal::ConstCharPtr gtest_msg = "") { \ bool gtest_caught_expected = false; \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ @@ -837,38 +1142,38 @@ class GTEST_API_ Random { gtest_caught_expected = true; \ } \ catch (...) { \ - gtest_msg = "Expected: " #statement " throws an exception of type " \ - #expected_exception ".\n Actual: it throws a different " \ - "type."; \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws a different type."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ } \ if (!gtest_caught_expected) { \ - gtest_msg = "Expected: " #statement " throws an exception of type " \ - #expected_exception ".\n Actual: it throws nothing."; \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws nothing."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ - fail(gtest_msg) + fail(gtest_msg.value) #define GTEST_TEST_NO_THROW_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (const char* gtest_msg = "") { \ + if (::testing::internal::AlwaysTrue()) { \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ } \ catch (...) { \ - gtest_msg = "Expected: " #statement " doesn't throw an exception.\n" \ - " Actual: it throws."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ - fail(gtest_msg) + fail("Expected: " #statement " doesn't throw an exception.\n" \ + " Actual: it throws.") #define GTEST_TEST_ANY_THROW_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (const char* gtest_msg = "") { \ + if (::testing::internal::AlwaysTrue()) { \ bool gtest_caught_any = false; \ try { \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ @@ -877,13 +1182,12 @@ class GTEST_API_ Random { gtest_caught_any = true; \ } \ if (!gtest_caught_any) { \ - gtest_msg = "Expected: " #statement " throws an exception.\n" \ - " Actual: it doesn't."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ - fail(gtest_msg) + fail("Expected: " #statement " throws an exception.\n" \ + " Actual: it doesn't.") // Implements Boolean test assertions such as EXPECT_TRUE. expression can be @@ -900,18 +1204,17 @@ class GTEST_API_ Random { #define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (const char* gtest_msg = "") { \ + if (::testing::internal::AlwaysTrue()) { \ ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ - gtest_msg = "Expected: " #statement " doesn't generate new fatal " \ - "failures in the current thread.\n" \ - " Actual: it does."; \ goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ } \ } else \ GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ - fail(gtest_msg) + fail("Expected: " #statement " doesn't generate new fatal " \ + "failures in the current thread.\n" \ + " Actual: it does.") // Expands to the name of the class that implements the given test. #define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ @@ -924,7 +1227,7 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ private:\ virtual void TestBody();\ - static ::testing::TestInfo* const test_info_;\ + static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ };\ @@ -932,7 +1235,7 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ ::test_info_ =\ ::testing::internal::MakeAndRegisterTestInfo(\ - #test_case_name, #test_name, "", "", \ + #test_case_name, #test_name, NULL, NULL, \ (parent_id), \ parent_class::SetUpTestCase, \ parent_class::TearDownTestCase, \ diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h b/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h index 2404ea882425..57147b4e8bef 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h @@ -71,7 +71,7 @@ #include #include -#include +#include "gtest/internal/gtest-port.h" namespace testing { namespace internal { @@ -172,16 +172,6 @@ class linked_ptr { T* get() const { return value_; } T* operator->() const { return value_; } T& operator*() const { return *value_; } - // Release ownership of the pointed object and returns it. - // Sole ownership by this linked_ptr object is required. - T* release() { - bool last = link_.depart(); - (void) last; - assert(last); - T* v = value_; - value_ = NULL; - return v; - } bool operator==(T* p) const { return value_ == p; } bool operator!=(T* p) const { return value_ != p; } diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h b/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h index ab4ab5662564..258267500ec1 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h @@ -1,4 +1,6 @@ -// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! +// This file was GENERATED by command: +// pump.py gtest-param-util-generated.h.pump +// DO NOT EDIT BY HAND!!! // Copyright 2008 Google Inc. // All Rights Reserved. @@ -47,8 +49,8 @@ // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. -#include -#include +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-port.h" #if GTEST_HAS_PARAM_TEST @@ -58,8 +60,8 @@ namespace testing { // include/gtest/gtest-param-test.h. template internal::ParamGenerator< - typename ::std::iterator_traits::value_type> ValuesIn( - ForwardIterator begin, ForwardIterator end); + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end); template internal::ParamGenerator ValuesIn(const T (&array)[N]); @@ -2826,7 +2828,7 @@ class ValueArray50 { const T50 v50_; }; -#if GTEST_HAS_COMBINE +# if GTEST_HAS_COMBINE // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Generates values from the Cartesian product of values produced @@ -4810,7 +4812,7 @@ CartesianProductHolder10(const Generator1& g1, const Generator2& g2, const Generator10 g10_; }; // class CartesianProductHolder10 -#endif // GTEST_HAS_COMBINE +# endif // GTEST_HAS_COMBINE } // namespace internal } // namespace testing diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h b/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h index 0cbb58c21b7b..0ef9718cf43a 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h @@ -41,9 +41,10 @@ // scripts/fuse_gtest.py depends on gtest's own header being #included // *unconditionally*. Therefore these #includes cannot be moved // inside #if GTEST_HAS_PARAM_TEST. -#include -#include -#include +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-linked_ptr.h" +#include "gtest/internal/gtest-port.h" +#include "gtest/gtest-printers.h" #if GTEST_HAS_PARAM_TEST @@ -171,7 +172,7 @@ class ParamGenerator { iterator end() const { return iterator(impl_->End()); } private: - ::testing::internal::linked_ptr > impl_; + linked_ptr > impl_; }; // Generates values from a range of two comparable values. Can be used to @@ -285,7 +286,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { public: Iterator(const ParamGeneratorInterface* base, typename ContainerType::const_iterator iterator) - : base_(base), iterator_(iterator) {} + : base_(base), iterator_(iterator) {} virtual ~Iterator() {} virtual const ParamGeneratorInterface* BaseGenerator() const { @@ -416,7 +417,7 @@ class ParameterizedTestCaseInfoBase { virtual ~ParameterizedTestCaseInfoBase() {} // Base part of test case name for display purposes. - virtual const String& GetTestCaseName() const = 0; + virtual const string& GetTestCaseName() const = 0; // Test case id to verify identity. virtual TypeId GetTestCaseTypeId() const = 0; // UnitTest class invokes this method to register tests in this @@ -453,7 +454,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { : test_case_name_(name) {} // Test case base name for display purposes. - virtual const String& GetTestCaseName() const { return test_case_name_; } + virtual const string& GetTestCaseName() const { return test_case_name_; } // Test case id to verify identity. virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } // TEST_P macro uses AddTestPattern() to record information @@ -471,7 +472,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { } // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information // about a generator. - int AddTestCaseInstantiation(const char* instantiation_name, + int AddTestCaseInstantiation(const string& instantiation_name, GeneratorCreationFunc* func, const char* /* file */, int /* line */) { @@ -490,26 +491,25 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { for (typename InstantiationContainer::iterator gen_it = instantiations_.begin(); gen_it != instantiations_.end(); ++gen_it) { - const String& instantiation_name = gen_it->first; + const string& instantiation_name = gen_it->first; ParamGenerator generator((*gen_it->second)()); Message test_case_name_stream; if ( !instantiation_name.empty() ) - test_case_name_stream << instantiation_name.c_str() << "/"; - test_case_name_stream << test_info->test_case_base_name.c_str(); + test_case_name_stream << instantiation_name << "/"; + test_case_name_stream << test_info->test_case_base_name; int i = 0; for (typename ParamGenerator::iterator param_it = generator.begin(); param_it != generator.end(); ++param_it, ++i) { Message test_name_stream; - test_name_stream << test_info->test_base_name.c_str() << "/" << i; - ::testing::internal::MakeAndRegisterTestInfo( + test_name_stream << test_info->test_base_name << "/" << i; + MakeAndRegisterTestInfo( test_case_name_stream.GetString().c_str(), test_name_stream.GetString().c_str(), - "", // test_case_comment - "", // comment; TODO(vladl@google.com): provide parameter value - // representation. + NULL, // No type parameter. + PrintToString(*param_it).c_str(), GetTestCaseTypeId(), TestCase::SetUpTestCase, TestCase::TearDownTestCase, @@ -530,17 +530,17 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { test_base_name(a_test_base_name), test_meta_factory(a_test_meta_factory) {} - const String test_case_base_name; - const String test_base_name; + const string test_case_base_name; + const string test_base_name; const scoped_ptr > test_meta_factory; }; typedef ::std::vector > TestInfoContainer; // Keeps pairs of // received from INSTANTIATE_TEST_CASE_P macros. - typedef ::std::vector > + typedef ::std::vector > InstantiationContainer; - const String test_case_name_; + const string test_case_name_; TestInfoContainer tests_; InstantiationContainer instantiations_; @@ -579,7 +579,7 @@ class ParameterizedTestCaseRegistry { // and terminate the program since we cannot guaranty correct // test case setup and tear-down in this case. ReportInvalidTestCaseType(test_case_name, file, line); - abort(); + posix::Abort(); } else { // At this point we are sure that the object we found is of the same // type we are looking for, so we downcast it to that type diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-port.h b/utils/unittest/googletest/include/gtest/internal/gtest-port.h index 3d076eb44c78..8ef5d7dd26a2 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-port.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-port.h @@ -50,6 +50,8 @@ // GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string // is/isn't available (some systems define // ::wstring, which is different to std::wstring). +// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular +// expressions are/aren't available. // GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that // is/isn't available. // GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't @@ -62,6 +64,10 @@ // GTEST_HAS_SEH - Define it to 1/0 to indicate whether the // compiler supports Microsoft's "Structured // Exception Handling". +// GTEST_HAS_STREAM_REDIRECTION +// - Define it to 1/0 to indicate whether the +// platform supports I/O stream redirection using +// dup() and dup2(). // GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google // Test's own tr1 tuple implementation should be // used. Unused when the user sets @@ -81,8 +87,11 @@ // GTEST_OS_AIX - IBM AIX // GTEST_OS_CYGWIN - Cygwin // GTEST_OS_HAIKU - Haiku +// GTEST_OS_HPUX - HP-UX // GTEST_OS_LINUX - Linux +// GTEST_OS_LINUX_ANDROID - Google Android // GTEST_OS_MAC - Mac OS X +// GTEST_OS_NACL - Google Native Client (NaCl) // GTEST_OS_SOLARIS - Sun Solaris // GTEST_OS_SYMBIAN - Symbian // GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) @@ -108,7 +117,9 @@ // GTEST_HAS_PARAM_TEST - value-parameterized tests // GTEST_HAS_TYPED_TEST - typed tests // GTEST_HAS_TYPED_TEST_P - type-parameterized tests -// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. +// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with +// GTEST_HAS_POSIX_RE (see above) which users can +// define themselves. // GTEST_USES_SIMPLE_RE - our own simple regex is used; // the above two are mutually exclusive. // GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). @@ -130,14 +141,17 @@ // // Template meta programming: // is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. +// IteratorTraits - partial implementation of std::iterator_traits, which +// is not available in libCstd when compiled with Sun C++. // // Smart pointers: // scoped_ptr - as in TR2. // // Regular expressions: // RE - a simple regular expression class using the POSIX -// Extended Regular Expression syntax. Not available on -// Windows. +// Extended Regular Expression syntax on UNIX-like +// platforms, or a reduced regular exception syntax on +// other platforms, including Windows. // // Logging: // GTEST_LOG_() - logs messages at the specified severity level. @@ -170,12 +184,14 @@ // Int32FromGTestEnv() - parses an Int32 environment variable. // StringFromGTestEnv() - parses a string environment variable. -#include // For ptrdiff_t +#include // for isspace, etc +#include // for ptrdiff_t #include #include #include #ifndef _WIN32_WCE -#include +# include +# include #endif // !_WIN32_WCE #include // NOLINT @@ -192,116 +208,140 @@ // Determines the version of gcc that is used to compile this. #ifdef __GNUC__ // 40302 means version 4.3.2. -#define GTEST_GCC_VER_ \ +# define GTEST_GCC_VER_ \ (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) #endif // __GNUC__ // Determines the platform on which Google Test is compiled. #ifdef __CYGWIN__ -#define GTEST_OS_CYGWIN 1 +# define GTEST_OS_CYGWIN 1 #elif defined __SYMBIAN32__ -#define GTEST_OS_SYMBIAN 1 +# define GTEST_OS_SYMBIAN 1 #elif defined _WIN32 -#define GTEST_OS_WINDOWS 1 -#ifdef _WIN32_WCE -#define GTEST_OS_WINDOWS_MOBILE 1 -#elif defined(__MINGW__) || defined(__MINGW32__) -#define GTEST_OS_WINDOWS_MINGW 1 -#else -#define GTEST_OS_WINDOWS_DESKTOP 1 -#endif // _WIN32_WCE +# define GTEST_OS_WINDOWS 1 +# ifdef _WIN32_WCE +# define GTEST_OS_WINDOWS_MOBILE 1 +# elif defined(__MINGW__) || defined(__MINGW32__) +# define GTEST_OS_WINDOWS_MINGW 1 +# else +# define GTEST_OS_WINDOWS_DESKTOP 1 +# endif // _WIN32_WCE #elif defined __APPLE__ -#define GTEST_OS_MAC 1 +# define GTEST_OS_MAC 1 #elif defined __linux__ -#define GTEST_OS_LINUX 1 +# define GTEST_OS_LINUX 1 +# ifdef ANDROID +# define GTEST_OS_LINUX_ANDROID 1 +# endif // ANDROID #elif defined __MVS__ -#define GTEST_OS_ZOS 1 +# define GTEST_OS_ZOS 1 #elif defined(__sun) && defined(__SVR4) -#define GTEST_OS_SOLARIS 1 +# define GTEST_OS_SOLARIS 1 #elif defined(_AIX) -#define GTEST_OS_AIX 1 +# define GTEST_OS_AIX 1 +#elif defined(__hpux) +# define GTEST_OS_HPUX 1 +#elif defined __native_client__ +# define GTEST_OS_NACL 1 #elif defined(__HAIKU__) -#define GTEST_OS_HAIKU 1 +# define GTEST_OS_HAIKU 1 #endif // __CYGWIN__ -#if GTEST_OS_CYGWIN || GTEST_OS_HAIKU || GTEST_OS_LINUX || GTEST_OS_MAC || \ - GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX +// Brings in definitions for functions used in the testing::internal::posix +// namespace (read, write, close, chdir, isatty, stat). We do not currently +// use them on Windows Mobile. +#if !GTEST_OS_WINDOWS +// This assumes that non-Windows OSes provide unistd.h. For OSes where this +// is not the case, we need to include headers that provide the functions +// mentioned above. +# include +# if !GTEST_OS_NACL +// TODO(vladl@google.com): Remove this condition when Native Client SDK adds +// strings.h (tracked in +// http://code.google.com/p/nativeclient/issues/detail?id=1175). +# include // Native Client doesn't provide strings.h. +# endif +#elif !GTEST_OS_WINDOWS_MOBILE +# include +# include +#endif + +// Defines this to true iff Google Test can use POSIX regular expressions. +#ifndef GTEST_HAS_POSIX_RE +# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) +#endif + +#if GTEST_HAS_POSIX_RE // On some platforms, needs someone to define size_t, and // won't compile otherwise. We can #include it here as we already // included , which is guaranteed to define size_t through // . -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT +# include // NOLINT -#define GTEST_USES_POSIX_RE 1 +# define GTEST_USES_POSIX_RE 1 #elif GTEST_OS_WINDOWS -#if !GTEST_OS_WINDOWS_MOBILE -#include // NOLINT -#include // NOLINT -#endif - // is not available on Windows. Use our own simple regex // implementation instead. -#define GTEST_USES_SIMPLE_RE 1 +# define GTEST_USES_SIMPLE_RE 1 #else // may not be available on this platform. Use our own // simple regex implementation instead. -#define GTEST_USES_SIMPLE_RE 1 +# define GTEST_USES_SIMPLE_RE 1 -#endif // GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC || - // GTEST_OS_SYMBIAN || GTEST_OS_SOLARIS || GTEST_OS_AIX +#endif // GTEST_HAS_POSIX_RE #ifndef GTEST_HAS_EXCEPTIONS // The user didn't tell us whether exceptions are enabled, so we need // to figure it out. -#if defined(_MSC_VER) || defined(__BORLANDC__) +# if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS // macro to enable exceptions, so we'll do the same. // Assumes that exceptions are enabled by default. -#ifndef _HAS_EXCEPTIONS -#define _HAS_EXCEPTIONS 1 -#endif // _HAS_EXCEPTIONS -#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS -#elif defined(__GNUC__) && __EXCEPTIONS +# ifndef _HAS_EXCEPTIONS +# define _HAS_EXCEPTIONS 1 +# endif // _HAS_EXCEPTIONS +# define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +# elif defined(__GNUC__) && __EXCEPTIONS // gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. -#define GTEST_HAS_EXCEPTIONS 1 -#elif defined(__SUNPRO_CC) +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__SUNPRO_CC) // Sun Pro CC supports exceptions. However, there is no compile-time way of // detecting whether they are enabled or not. Therefore, we assume that // they are enabled unless the user tells us otherwise. -#define GTEST_HAS_EXCEPTIONS 1 -#elif defined(__IBMCPP__) && __EXCEPTIONS +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__IBMCPP__) && __EXCEPTIONS // xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. -#define GTEST_HAS_EXCEPTIONS 1 -#else +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__HP_aCC) +// Exception handling is in effect by default in HP aCC compiler. It has to +// be turned of by +noeh compiler option if desired. +# define GTEST_HAS_EXCEPTIONS 1 +# else // For other compilers, we assume exceptions are disabled to be // conservative. -#define GTEST_HAS_EXCEPTIONS 0 -#endif // defined(_MSC_VER) || defined(__BORLANDC__) +# define GTEST_HAS_EXCEPTIONS 0 +# endif // defined(_MSC_VER) || defined(__BORLANDC__) #endif // GTEST_HAS_EXCEPTIONS #if !defined(GTEST_HAS_STD_STRING) // Even though we don't use this macro any longer, we keep it in case // some clients still depend on it. -#define GTEST_HAS_STD_STRING 1 +# define GTEST_HAS_STD_STRING 1 #elif !GTEST_HAS_STD_STRING // The user told us that ::std::string isn't available. -#error "Google Test cannot be used where ::std::string isn't available." +# error "Google Test cannot be used where ::std::string isn't available." #endif // !defined(GTEST_HAS_STD_STRING) #ifndef GTEST_HAS_GLOBAL_STRING // The user didn't tell us whether ::string is available, so we need // to figure it out. -#define GTEST_HAS_GLOBAL_STRING 0 +# define GTEST_HAS_GLOBAL_STRING 0 #endif // GTEST_HAS_GLOBAL_STRING @@ -311,18 +351,19 @@ // TODO(wan@google.com): uses autoconf to detect whether ::std::wstring // is available. -// Cygwin 1.5 and below doesn't support ::std::wstring. -// Cygwin 1.7 might add wstring support; this should be updated when clear. -// Solaris' libc++ doesn't support it either. +// Cygwin 1.7 and below doesn't support ::std::wstring. +// Solaris' libc++ doesn't support it either. Android has +// no support for it at least as recent as Froyo (2.2). // Minix currently doesn't support it either. -#define GTEST_HAS_STD_WSTRING (!(GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || GTEST_OS_HAIKU || defined(_MINIX))) +# define GTEST_HAS_STD_WSTRING \ + (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || GTEST_OS_HAIKU || defined(_MINIX))) #endif // GTEST_HAS_STD_WSTRING #ifndef GTEST_HAS_GLOBAL_WSTRING // The user didn't tell us whether ::wstring is available, so we need // to figure it out. -#define GTEST_HAS_GLOBAL_WSTRING \ +# define GTEST_HAS_GLOBAL_WSTRING \ (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) #endif // GTEST_HAS_GLOBAL_WSTRING @@ -331,46 +372,46 @@ // The user didn't tell us whether RTTI is enabled, so we need to // figure it out. -#ifdef _MSC_VER +# ifdef _MSC_VER -#ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. -#define GTEST_HAS_RTTI 1 -#else -#define GTEST_HAS_RTTI 0 -#endif +# ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif // Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. -#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) +# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) -#ifdef __GXX_RTTI -#define GTEST_HAS_RTTI 1 -#else -#define GTEST_HAS_RTTI 0 -#endif // __GXX_RTTI +# ifdef __GXX_RTTI +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif // __GXX_RTTI // Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if // both the typeid and dynamic_cast features are present. -#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) +# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) -#ifdef __RTTI_ALL__ -#define GTEST_HAS_RTTI 1 -#else -#define GTEST_HAS_RTTI 0 -#endif +# ifdef __RTTI_ALL__ +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif -#else +# else // For all other compilers, we assume RTTI is enabled. -#define GTEST_HAS_RTTI 1 +# define GTEST_HAS_RTTI 1 -#endif // _MSC_VER +# endif // _MSC_VER #endif // GTEST_HAS_RTTI // It's this header's responsibility to #include when RTTI // is enabled. #if GTEST_HAS_RTTI -#include +# include #endif // Determines whether Google Test can use the pthreads library. @@ -380,15 +421,24 @@ // // To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 // to your compiler flags. -#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC) +# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX) #endif // GTEST_HAS_PTHREAD +#if GTEST_HAS_PTHREAD +// gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is +// true. +# include // NOLINT + +// For timespec and nanosleep, used below. +# include // NOLINT +#endif + // Determines whether Google Test can use tr1/tuple. You can define // this macro to 0 to prevent Google Test from using tuple (any // feature depending on tuple with be disabled in this mode). #ifndef GTEST_HAS_TR1_TUPLE // The user didn't tell us not to do it, so we assume it's OK. -#define GTEST_HAS_TR1_TUPLE 1 +# define GTEST_HAS_TR1_TUPLE 1 #endif // GTEST_HAS_TR1_TUPLE // Determines whether Google Test's own tr1 tuple implementation @@ -403,13 +453,13 @@ // defining __GNUC__ and friends, but cannot compile GCC's tuple // implementation. MSVC 2008 (9.0) provides TR1 tuple in a 323 MB // Feature Pack download, which we cannot assume the user has. -#if (defined(__GNUC__) && !(defined(__CUDACC__) || defined(__clang__)) \ - && (GTEST_GCC_VER_ >= 40000)) \ +# if (defined(__GNUC__) && !(defined(__CUDACC__) || defined(__clang__)) \ + && (GTEST_GCC_VER_ >= 40000)) \ || _MSC_VER >= 1600 -#define GTEST_USE_OWN_TR1_TUPLE 0 -#else -#define GTEST_USE_OWN_TR1_TUPLE 1 -#endif +# define GTEST_USE_OWN_TR1_TUPLE 0 +# else +# define GTEST_USE_OWN_TR1_TUPLE 1 +# endif #endif // GTEST_USE_OWN_TR1_TUPLE @@ -418,47 +468,47 @@ // tr1/tuple. #if GTEST_HAS_TR1_TUPLE -#if GTEST_USE_OWN_TR1_TUPLE -#include -#elif GTEST_OS_SYMBIAN +# if GTEST_USE_OWN_TR1_TUPLE +# include "gtest/internal/gtest-tuple.h" +# elif GTEST_OS_SYMBIAN // On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to // use STLport's tuple implementation, which unfortunately doesn't // work as the copy of STLport distributed with Symbian is incomplete. // By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to // use its own tuple implementation. -#ifdef BOOST_HAS_TR1_TUPLE -#undef BOOST_HAS_TR1_TUPLE -#endif // BOOST_HAS_TR1_TUPLE +# ifdef BOOST_HAS_TR1_TUPLE +# undef BOOST_HAS_TR1_TUPLE +# endif // BOOST_HAS_TR1_TUPLE // This prevents , which defines // BOOST_HAS_TR1_TUPLE, from being #included by Boost's . -#define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED -#include +# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED +# include -#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) +# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) // GCC 4.0+ implements tr1/tuple in the header. This does // not conform to the TR1 spec, which requires the header to be . -#if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +# if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 // Until version 4.3.2, gcc has a bug that causes , // which is #included by , to not compile when RTTI is // disabled. _TR1_FUNCTIONAL is the header guard for // . Hence the following #define is a hack to prevent // from being included. -#define _TR1_FUNCTIONAL 1 -#include -#undef _TR1_FUNCTIONAL // Allows the user to #include +# define _TR1_FUNCTIONAL 1 +# include +# undef _TR1_FUNCTIONAL // Allows the user to #include // if he chooses to. -#else -#include // NOLINT -#endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +# else +# include // NOLINT +# endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 -#else +# else // If the compiler is not GCC 4.0+, we assume the user is using a // spec-conforming TR1 implementation. -#include // NOLINT -#endif // GTEST_USE_OWN_TR1_TUPLE +# include // NOLINT +# endif // GTEST_USE_OWN_TR1_TUPLE #endif // GTEST_HAS_TR1_TUPLE @@ -469,19 +519,25 @@ #ifndef GTEST_HAS_CLONE // The user didn't tell us, so we need to figure it out. -#if GTEST_OS_LINUX && !defined(__ia64__) -#define GTEST_HAS_CLONE 1 -#else -#define GTEST_HAS_CLONE 0 -#endif // GTEST_OS_LINUX && !defined(__ia64__) +# if GTEST_OS_LINUX && !defined(__ia64__) +# define GTEST_HAS_CLONE 1 +# else +# define GTEST_HAS_CLONE 0 +# endif // GTEST_OS_LINUX && !defined(__ia64__) #endif // GTEST_HAS_CLONE // Determines whether to support stream redirection. This is used to test // output correctness and to implement death tests. -#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN -#define GTEST_HAS_STREAM_REDIRECTION_ 1 -#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN +#ifndef GTEST_HAS_STREAM_REDIRECTION +// By default, we assume that stream redirection is supported on all +// platforms except known mobile ones. +# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN +# define GTEST_HAS_STREAM_REDIRECTION 0 +# else +# define GTEST_HAS_STREAM_REDIRECTION 1 +# endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN +#endif // GTEST_HAS_STREAM_REDIRECTION // Determines whether to support death tests. // Google Test does not support death tests for VC 7.1 and earlier as @@ -489,9 +545,9 @@ // pops up a dialog window that cannot be suppressed programmatically. #if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ - GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX) -#define GTEST_HAS_DEATH_TEST 1 -#include // NOLINT + GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX) +# define GTEST_HAS_DEATH_TEST 1 +# include // NOLINT #endif // We don't support MSVC 7.1 with exceptions disabled now. Therefore @@ -502,11 +558,11 @@ // Determines whether to support type-driven tests. // Typed tests need and variadic macros, which GCC, VC++ 8.0, -// Sun Pro CC, and IBM Visual Age support. +// Sun Pro CC, IBM Visual Age, and HP aCC support. #if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ - defined(__IBMCPP__) -#define GTEST_HAS_TYPED_TEST 1 -#define GTEST_HAS_TYPED_TEST_P 1 + defined(__IBMCPP__) || defined(__HP_aCC) +# define GTEST_HAS_TYPED_TEST 1 +# define GTEST_HAS_TYPED_TEST_P 1 #endif // Determines whether to support Combine(). This only makes sense when @@ -514,13 +570,18 @@ // work on Sun Studio since it doesn't understand templated conversion // operators. #if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) -#define GTEST_HAS_COMBINE 1 +# define GTEST_HAS_COMBINE 1 #endif // Determines whether the system compiler uses UTF-16 for encoding wide strings. #define GTEST_WIDE_STRING_USES_UTF16_ \ (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) +// Determines whether test results can be streamed to a socket. +#if GTEST_OS_LINUX +# define GTEST_CAN_STREAM_RESULTS_ 1 +#endif + // Defines some utility macros. // The GNU compiler emits a warning if nested "if" statements are followed by @@ -532,9 +593,9 @@ // // The "switch (0) case 0:" idiom is used to suppress this. #ifdef __INTEL_COMPILER -#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ #else -#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: // NOLINT +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT #endif // Use this annotation at the end of a struct/class definition to @@ -549,9 +610,9 @@ // Also use it after a variable or parameter declaration to tell the // compiler the variable/parameter does not have to be used. #if defined(__GNUC__) && !defined(COMPILER_ICC) -#define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) #else -#define GTEST_ATTRIBUTE_UNUSED_ +# define GTEST_ATTRIBUTE_UNUSED_ #endif // A macro to disallow operator= @@ -571,9 +632,9 @@ // // Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; #if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) -#define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) #else -#define GTEST_MUST_USE_RESULT_ +# define GTEST_MUST_USE_RESULT_ #endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC // Determine whether the compiler supports Microsoft's Structured Exception @@ -582,28 +643,35 @@ #ifndef GTEST_HAS_SEH // The user didn't tell us, so we need to figure it out. -#if defined(_MSC_VER) || defined(__BORLANDC__) +# if defined(_MSC_VER) || defined(__BORLANDC__) // These two compilers are known to support SEH. -#define GTEST_HAS_SEH 1 -#else +# define GTEST_HAS_SEH 1 +# else // Assume no SEH. -#define GTEST_HAS_SEH 0 -#endif +# define GTEST_HAS_SEH 0 +# endif #endif // GTEST_HAS_SEH #ifdef _MSC_VER -#if GTEST_LINKED_AS_SHARED_LIBRARY -#define GTEST_API_ __declspec(dllimport) -#elif GTEST_CREATE_SHARED_LIBRARY -#define GTEST_API_ __declspec(dllexport) -#endif +# if GTEST_LINKED_AS_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllimport) +# elif GTEST_CREATE_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllexport) +# endif #endif // _MSC_VER #ifndef GTEST_API_ -#define GTEST_API_ +# define GTEST_API_ +#endif + +#ifdef __GNUC__ +// Ask the compiler to never inline a given function. +# define GTEST_NO_INLINE_ __attribute__((noinline)) +#else +# define GTEST_NO_INLINE_ #endif namespace testing { @@ -614,7 +682,90 @@ namespace internal { class String; -typedef ::std::stringstream StrStream; +// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time +// expression is true. For example, you could use it to verify the +// size of a static array: +// +// GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, +// content_type_names_incorrect_size); +// +// or to make sure a struct is smaller than a certain size: +// +// GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large); +// +// The second argument to the macro is the name of the variable. If +// the expression is false, most compilers will issue a warning/error +// containing the name of the variable. + +template +struct CompileAssert { +}; + +#define GTEST_COMPILE_ASSERT_(expr, msg) \ + typedef ::testing::internal::CompileAssert<(bool(expr))> \ + msg[bool(expr) ? 1 : -1] + +// Implementation details of GTEST_COMPILE_ASSERT_: +// +// - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 +// elements (and thus is invalid) when the expression is false. +// +// - The simpler definition +// +// #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1] +// +// does not work, as gcc supports variable-length arrays whose sizes +// are determined at run-time (this is gcc's extension and not part +// of the C++ standard). As a result, gcc fails to reject the +// following code with the simple definition: +// +// int foo; +// GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is +// // not a compile-time constant. +// +// - By using the type CompileAssert<(bool(expr))>, we ensures that +// expr is a compile-time constant. (Template arguments must be +// determined at compile-time.) +// +// - The outter parentheses in CompileAssert<(bool(expr))> are necessary +// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written +// +// CompileAssert +// +// instead, these compilers will refuse to compile +// +// GTEST_COMPILE_ASSERT_(5 > 0, some_message); +// +// (They seem to think the ">" in "5 > 0" marks the end of the +// template argument list.) +// +// - The array size is (bool(expr) ? 1 : -1), instead of simply +// +// ((expr) ? 1 : -1). +// +// This is to avoid running into a bug in MS VC 7.1, which +// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. + +// StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h. +// +// This template is declared, but intentionally undefined. +template +struct StaticAssertTypeEqHelper; + +template +struct StaticAssertTypeEqHelper {}; + +#if GTEST_HAS_GLOBAL_STRING +typedef ::string string; +#else +typedef ::std::string string; +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING +typedef ::wstring wstring; +#elif GTEST_HAS_STD_WSTRING +typedef ::std::wstring wstring; +#endif // GTEST_HAS_GLOBAL_WSTRING // A helper for suppressing warnings on constant condition. It just // returns 'condition'. @@ -670,7 +821,9 @@ class GTEST_API_ RE { RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT #if GTEST_HAS_GLOBAL_STRING + RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT + #endif // GTEST_HAS_GLOBAL_STRING RE(const char* regex) { Init(regex); } // NOLINT @@ -694,12 +847,14 @@ class GTEST_API_ RE { } #if GTEST_HAS_GLOBAL_STRING + static bool FullMatch(const ::string& str, const RE& re) { return FullMatch(str.c_str(), re); } static bool PartialMatch(const ::string& str, const RE& re) { return PartialMatch(str.c_str(), re); } + #endif // GTEST_HAS_GLOBAL_STRING static bool FullMatch(const char* str, const RE& re); @@ -714,16 +869,31 @@ class GTEST_API_ RE { // files. const char* pattern_; bool is_valid_; + #if GTEST_USES_POSIX_RE + regex_t full_regex_; // For FullMatch(). regex_t partial_regex_; // For PartialMatch(). + #else // GTEST_USES_SIMPLE_RE + const char* full_pattern_; // For FullMatch(); + #endif GTEST_DISALLOW_ASSIGN_(RE); }; +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, + int line); + // Defines logging utilities: // GTEST_LOG_(severity) - logs messages at the specified severity level. The // message itself is streamed into the macro. @@ -795,6 +965,66 @@ inline void FlushInfoLog() { fflush(NULL); } // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // +// Use ImplicitCast_ as a safe version of static_cast for upcasting in +// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a +// const Foo*). When you use ImplicitCast_, the compiler checks that +// the cast is safe. Such explicit ImplicitCast_s are necessary in +// surprisingly many situations where C++ demands an exact type match +// instead of an argument type convertable to a target type. +// +// The syntax for using ImplicitCast_ is the same as for static_cast: +// +// ImplicitCast_(expr) +// +// ImplicitCast_ would have been part of the C++ standard library, +// but the proposal was submitted too late. It will probably make +// its way into the language in the future. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., implicit_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template +inline To ImplicitCast_(To x) { return x; } + +// When you upcast (that is, cast a pointer from type Foo to type +// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts +// always succeed. When you downcast (that is, cast a pointer from +// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because +// how do you know the pointer is really of type SubclassOfFoo? It +// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, +// when you downcast, you should use this macro. In debug mode, we +// use dynamic_cast<> to double-check the downcast is legal (we die +// if it's not). In normal mode, we do the efficient static_cast<> +// instead. Thus, it's important to test in debug mode to make sure +// the cast is legal! +// This is the only place in the code we should use dynamic_cast<>. +// In particular, you SHOULDN'T be using dynamic_cast<> in order to +// do RTTI (eg code like this: +// if (dynamic_cast(foo)) HandleASubclass1Object(foo); +// if (dynamic_cast(foo)) HandleASubclass2Object(foo); +// You should design the code some other way not to need this. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., down_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template // use like this: DownCast_(foo); +inline To DownCast_(From* f) { // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + if (false) { + const To to = NULL; + ::testing::internal::ImplicitCast_(to); + } + +#if GTEST_HAS_RTTI + // RTTI: debug mode only! + GTEST_CHECK_(f == NULL || dynamic_cast(f) != NULL); +#endif + return static_cast(f); +} + // Downcasts the pointer of type Base to Derived. // Derived must be a subclass of Base. The parameter MUST // point to a class of type Derived, not any subclass of it. @@ -810,7 +1040,7 @@ Derived* CheckedDowncastToActualType(Base* base) { #endif } -#if GTEST_HAS_STREAM_REDIRECTION_ +#if GTEST_HAS_STREAM_REDIRECTION // Defines the stderr capturer: // CaptureStdout - starts capturing stdout. @@ -823,7 +1053,7 @@ GTEST_API_ String GetCapturedStdout(); GTEST_API_ void CaptureStderr(); GTEST_API_ String GetCapturedStderr(); -#endif // GTEST_HAS_STREAM_REDIRECTION_ +#endif // GTEST_HAS_STREAM_REDIRECTION #if GTEST_HAS_DEATH_TEST @@ -957,10 +1187,6 @@ class ThreadWithParam : public ThreadWithParamBase { GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); }; -// gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is -// true. -#include - // MutexBase and Mutex implement mutex on pthreads-based platforms. They // are used in conjunction with class MutexLock: // @@ -1015,11 +1241,11 @@ class MutexBase { }; // Forward-declares a static mutex. -#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ extern ::testing::internal::MutexBase mutex // Defines and statically (i.e. at link time) initializes a static mutex. -#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 } // The Mutex class can only be used for mutexes created at runtime. It @@ -1166,7 +1392,7 @@ class ThreadLocal { GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); }; -#define GTEST_IS_THREADSAFE 1 +# define GTEST_IS_THREADSAFE 1 #else // GTEST_HAS_PTHREAD @@ -1181,10 +1407,10 @@ class Mutex { void AssertHeld() const {} }; -#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ extern ::testing::internal::Mutex mutex -#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex class GTestMutexLock { public: @@ -1208,7 +1434,7 @@ class ThreadLocal { // The above synchronization primitives have dummy implementations. // Therefore Google Test is not thread-safe. -#define GTEST_IS_THREADSAFE 0 +# define GTEST_IS_THREADSAFE 0 #endif // GTEST_HAS_PTHREAD @@ -1225,9 +1451,9 @@ GTEST_API_ size_t GetThreadCount(); #if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). -#define GTEST_ELLIPSIS_NEEDS_POD_ 1 +# define GTEST_ELLIPSIS_NEEDS_POD_ 1 #else -#define GTEST_CAN_COMPARE_NULL 1 +# define GTEST_CAN_COMPARE_NULL 1 #endif // The Nokia Symbian and IBM XL C/C++ compilers cannot decide between @@ -1235,7 +1461,7 @@ GTEST_API_ size_t GetThreadCount(); // _can_ decide between class template specializations for T and T*, // so a tr1::type_traits-like is_pointer works. #if defined(__SYMBIAN32__) || defined(__IBMCPP__) -#define GTEST_NEEDS_IS_POINTER_ 1 +# define GTEST_NEEDS_IS_POINTER_ 1 #endif template @@ -1254,17 +1480,68 @@ struct is_pointer : public false_type {}; template struct is_pointer : public true_type {}; +template +struct IteratorTraits { + typedef typename Iterator::value_type value_type; +}; + +template +struct IteratorTraits { + typedef T value_type; +}; + +template +struct IteratorTraits { + typedef T value_type; +}; + #if GTEST_OS_WINDOWS -#define GTEST_PATH_SEP_ "\\" -#define GTEST_HAS_ALT_PATH_SEP_ 1 +# define GTEST_PATH_SEP_ "\\" +# define GTEST_HAS_ALT_PATH_SEP_ 1 // The biggest signed integer type the compiler supports. typedef __int64 BiggestInt; #else -#define GTEST_PATH_SEP_ "/" -#define GTEST_HAS_ALT_PATH_SEP_ 0 +# define GTEST_PATH_SEP_ "/" +# define GTEST_HAS_ALT_PATH_SEP_ 0 typedef long long BiggestInt; // NOLINT #endif // GTEST_OS_WINDOWS +// Utilities for char. + +// isspace(int ch) and friends accept an unsigned char or EOF. char +// may be signed, depending on the compiler (or compiler flags). +// Therefore we need to cast a char to unsigned char before calling +// isspace(), etc. + +inline bool IsAlpha(char ch) { + return isalpha(static_cast(ch)) != 0; +} +inline bool IsAlNum(char ch) { + return isalnum(static_cast(ch)) != 0; +} +inline bool IsDigit(char ch) { + return isdigit(static_cast(ch)) != 0; +} +inline bool IsLower(char ch) { + return islower(static_cast(ch)) != 0; +} +inline bool IsSpace(char ch) { + return isspace(static_cast(ch)) != 0; +} +inline bool IsUpper(char ch) { + return isupper(static_cast(ch)) != 0; +} +inline bool IsXDigit(char ch) { + return isxdigit(static_cast(ch)) != 0; +} + +inline char ToLower(char ch) { + return static_cast(tolower(static_cast(ch))); +} +inline char ToUpper(char ch) { + return static_cast(toupper(static_cast(ch))); +} + // The testing::internal::posix namespace holds wrappers for common // POSIX functions. These wrappers hide the differences between // Windows/MSVC and POSIX systems. Since some compilers define these @@ -1279,36 +1556,36 @@ namespace posix { typedef struct _stat StatStruct; -#ifdef __BORLANDC__ +# ifdef __BORLANDC__ inline int IsATTY(int fd) { return isatty(fd); } inline int StrCaseCmp(const char* s1, const char* s2) { return stricmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } -#else // !__BORLANDC__ -#if GTEST_OS_WINDOWS_MOBILE +# else // !__BORLANDC__ +# if GTEST_OS_WINDOWS_MOBILE inline int IsATTY(int /* fd */) { return 0; } -#else +# else inline int IsATTY(int fd) { return _isatty(fd); } -#endif // GTEST_OS_WINDOWS_MOBILE +# endif // GTEST_OS_WINDOWS_MOBILE inline int StrCaseCmp(const char* s1, const char* s2) { return _stricmp(s1, s2); } inline char* StrDup(const char* src) { return _strdup(src); } -#endif // __BORLANDC__ +# endif // __BORLANDC__ -#if GTEST_OS_WINDOWS_MOBILE +# if GTEST_OS_WINDOWS_MOBILE inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } // Stat(), RmDir(), and IsDir() are not needed on Windows CE at this // time and thus not defined there. -#else +# else inline int FileNo(FILE* file) { return _fileno(file); } inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } inline int RmDir(const char* dir) { return _rmdir(dir); } inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; } -#endif // GTEST_OS_WINDOWS_MOBILE +# endif // GTEST_OS_WINDOWS_MOBILE #else @@ -1330,8 +1607,8 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } #ifdef _MSC_VER // Temporarily disable warning 4996 (deprecated function). -#pragma warning(push) -#pragma warning(disable:4996) +# pragma warning(push) +# pragma warning(disable:4996) #endif inline const char* StrNCpy(char* dest, const char* src, size_t n) { @@ -1380,7 +1657,7 @@ inline const char* GetEnv(const char* name) { } #ifdef _MSC_VER -#pragma warning(pop) // Restores the warning state. +# pragma warning(pop) // Restores the warning state. #endif #if GTEST_OS_WINDOWS_MOBILE @@ -1446,6 +1723,7 @@ class TypeWithSize<4> { template <> class TypeWithSize<8> { public: + #if GTEST_OS_WINDOWS typedef __int64 Int; typedef unsigned __int64 UInt; diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-string.h b/utils/unittest/googletest/include/gtest/internal/gtest-string.h index aff093dec8db..dc3a07be8802 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-string.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-string.h @@ -43,11 +43,11 @@ #ifdef __BORLANDC__ // string.h is not guaranteed to provide strcpy on C++ Builder. -#include +# include #endif #include -#include +#include "gtest/internal/gtest-port.h" #include @@ -296,7 +296,7 @@ class GTEST_API_ String { private: // Constructs a non-NULL String from the given content. This - // function can only be called when data_ has not been allocated. + // function can only be called when c_str_ has not been allocated. // ConstructNonNull(NULL, 0) results in an empty string (""). // ConstructNonNull(NULL, non_zero) is undefined behavior. void ConstructNonNull(const char* buffer, size_t a_length) { @@ -329,9 +329,9 @@ inline ::std::ostream& operator<<(::std::ostream& os, const String& str) { return os; } -// Gets the content of the StrStream's buffer as a String. Each '\0' +// Gets the content of the stringstream's buffer as a String. Each '\0' // character in the buffer is replaced with "\\0". -GTEST_API_ String StrStreamToString(StrStream* stream); +GTEST_API_ String StringStreamToString(::std::stringstream* stream); // Converts a streamable value to a String. A NULL pointer is // converted to "(null)". When the input value is a ::string, diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h b/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h index 16178fc07af1..d1af50e18835 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h @@ -44,9 +44,9 @@ // private as public. // Sun Studio versions < 12 also have the above bug. #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) -#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: #else -#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ template friend class tuple; \ private: #endif diff --git a/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h b/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h index 093eee6f0196..b7b01b0948ce 100644 --- a/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h +++ b/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h @@ -44,20 +44,52 @@ #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ -#include -#include - -#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-string.h" // #ifdef __GNUC__ is too general here. It is possible to use gcc without using // libstdc++ (which is where cxxabi.h comes from). -#ifdef __GLIBCXX__ -#include -#endif // __GLIBCXX__ +# ifdef __GLIBCXX__ +# include +# elif defined(__HP_aCC) +# include +# endif // __GLIBCXX__ namespace testing { namespace internal { +// GetTypeName() returns a human-readable name of type T. +// NB: This function is also used in Google Mock, so don't move it inside of +// the typed-test-only section below. +template +String GetTypeName() { +# if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +# if defined(__GLIBCXX__) || defined(__HP_aCC) + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. +# ifdef __GLIBCXX__ + using abi::__cxa_demangle; +# endif // __GLIBCXX__ + char* const readable_name = __cxa_demangle(name, 0, 0, &status); + const String name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +# else + return name; +# endif // __GLIBCXX__ || __HP_aCC + +# else + + return ""; + +# endif // GTEST_HAS_RTTI +} + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + // AssertyTypeEq::type is defined iff T1 and T2 are the same // type. This can be used as a compile-time assertion to ensure that // two types are equal. @@ -70,29 +102,6 @@ struct AssertTypeEq { typedef bool type; }; -// GetTypeName() returns a human-readable name of type T. -template -String GetTypeName() { -#if GTEST_HAS_RTTI - - const char* const name = typeid(T).name(); -#ifdef __GLIBCXX__ - int status = 0; - // gcc's implementation of typeid(T).name() mangles the type name, - // so we have to demangle it. - char* const readable_name = abi::__cxa_demangle(name, 0, 0, &status); - const String name_str(status == 0 ? readable_name : name); - free(readable_name); - return name_str; -#else - return name; -#endif // __GLIBCXX__ - -#else - return ""; -#endif // GTEST_HAS_RTTI -} - // A unique type used as the default value for the arguments of class // template Types. This allows us to simulate variadic templates // (e.g. Types, Type, and etc), which C++ doesn't @@ -1611,7 +1620,7 @@ struct Types class +# define GTEST_TEMPLATE_ template class // The template "selector" struct TemplateSel is used to // represent Tmpl, which must be a class template with one type @@ -1629,7 +1638,7 @@ struct TemplateSel { }; }; -#define GTEST_BIND_(TmplSel, T) \ +# define GTEST_BIND_(TmplSel, T) \ TmplSel::template Bind::type // A unique struct template used as the default value for the @@ -3313,9 +3322,9 @@ struct TypeList::type type; }; +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + } // namespace internal } // namespace testing -#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P - #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ diff --git a/utils/valgrind/x86_64-pc-linux-gnu.supp b/utils/valgrind/x86_64-pc-linux-gnu.supp index 3d15d7147014..fc863b85e291 100644 --- a/utils/valgrind/x86_64-pc-linux-gnu.supp +++ b/utils/valgrind/x86_64-pc-linux-gnu.supp @@ -51,3 +51,14 @@ obj:/lib/ld*.so } +{ + suppress optimized strcasecmp, to be fixed in valgrind 3.6.1 + Memcheck:Value8 + fun:__GI___strcasecmp_l +} + +{ + suppress optimized strcasecmp, to be fixed in valgrind 3.6.1 + Memcheck:Addr8 + fun:__GI___strcasecmp_l +} diff --git a/utils/vim/llvm.vim b/utils/vim/llvm.vim index 83e4c232dbe5..f35f855cab89 100644 --- a/utils/vim/llvm.vim +++ b/utils/vim/llvm.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: llvm " Maintainer: The LLVM team, http://llvm.org/ -" Version: $Revision: 114788 $ +" Version: $Revision: 137806 $ if version < 600 syntax clear @@ -51,7 +51,7 @@ syn keyword llvmKeyword volatile fastcc coldcc cc ccc syn keyword llvmKeyword x86_stdcallcc x86_fastcallcc syn keyword llvmKeyword ptx_kernel ptx_device syn keyword llvmKeyword signext zeroext inreg sret nounwind noreturn -syn keyword llvmKeyword nocapture byval nest readnone readonly noalias +syn keyword llvmKeyword nocapture byval nest readnone readonly noalias uwtable syn keyword llvmKeyword inlinehint noinline alwaysinline optsize ssp sspreq syn keyword llvmKeyword noredzone noimplicitfloat naked alignstack syn keyword llvmKeyword module asm align tail to diff --git a/utils/vim/tablegen.vim b/utils/vim/tablegen.vim index 11a4d80c49ca..fed619a07add 100644 --- a/utils/vim/tablegen.vim +++ b/utils/vim/tablegen.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: TableGen " Maintainer: The LLVM team, http://llvm.org/ -" Version: $Revision: 97271 $ +" Version: $Revision: 141378 $ if version < 600 syntax clear diff --git a/website/index.html b/website/index.html deleted file mode 100644 index c42855957e10..000000000000 --- a/website/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - LLVM Core Website - - - - -
    LLVM Core Web Site
    -

    This is just a place holder for now.

    - - - - -
    -
    - Valid CSS! - Valid HTML 4.01! - - LLVM Compiler Infrastructure
    - Last modified: $Date: 2007-07-09 01:04:31 -0700 (Mon, 09 Jul 2007) $ -
    -